summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2013-07-03 23:39:47 +0200
committerRobin Gareus <robin@gareus.org>2013-07-10 15:27:07 +0200
commit571b2d70e9f6e7799f74bd3eec90835101fddbe6 (patch)
tree0a3bcf7a2550dd65f2448962ef3a148005d181a5
parent447e736139f61dbc8697fbd7a19a5fd3cb7d1609 (diff)
refactor level-meter widget: 5x2 stops meter colors
-rw-r--r--gtk2_ardour/level_meter.cc4
-rw-r--r--libs/gtkmm2ext/fastmeter.cc181
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/fastmeter.h63
3 files changed, 175 insertions, 73 deletions
diff --git a/gtk2_ardour/level_meter.cc b/gtk2_ardour/level_meter.cc
index b7739c9165..1c4a26a0c5 100644
--- a/gtk2_ardour/level_meter.cc
+++ b/gtk2_ardour/level_meter.cc
@@ -196,10 +196,8 @@ LevelMeter::setup_meters (int len, int initial_width, int thin_width)
if (meters[n].width != width || meters[n].length != len || color_changed) {
delete meters[n].meter;
meters[n].meter = new FastMeter ((uint32_t) floor (Config->get_meter_hold()), width, FastMeter::Vertical, len,
- b, m, t, c,
+ b, b, m, m, t, t, c, c, c, c,
ARDOUR_UI::config()->canvasvar_MeterBackgroundBot.get(),
- ARDOUR_UI::config()->canvasvar_MeterBackgroundMid.get(),
- ARDOUR_UI::config()->canvasvar_MeterBackgroundMid.get(),
ARDOUR_UI::config()->canvasvar_MeterBackgroundTop.get()
);
meters[n].width = width;
diff --git a/libs/gtkmm2ext/fastmeter.cc b/libs/gtkmm2ext/fastmeter.cc
index f55f5ba712..367747b78a 100644
--- a/libs/gtkmm2ext/fastmeter.cc
+++ b/libs/gtkmm2ext/fastmeter.cc
@@ -38,11 +38,13 @@ using namespace std;
int FastMeter::min_pattern_metric_size = 10;
int FastMeter::max_pattern_metric_size = 1024;
-FastMeter::PatternMap FastMeter::v_pattern_cache;
+FastMeter::Pattern10Map FastMeter::vm_pattern_cache;
+FastMeter::PatternBgMap FastMeter::vb_pattern_cache;
FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
int clr0, int clr1, int clr2, int clr3,
- int bgc0, int bgc1, int bgc2, int bgc3)
+ int clr4, int clr5, int clr6, int clr7,
+ int clr8, int clr9, int bgc0, int bgc1)
{
orientation = o;
hold_cnt = hold;
@@ -52,15 +54,25 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
current_level = 0;
last_peak_rect.width = 0;
last_peak_rect.height = 0;
- _clr0 = clr0;
- _clr1 = clr1;
- _clr2 = clr2;
- _clr3 = clr3;
- _bgc0 = bgc0;
- _bgc1 = bgc1;
- _bgc2 = bgc2;
- _bgc3 = bgc3;
+ _clr[0] = clr0;
+ _clr[1] = clr1;
+ _clr[2] = clr2;
+ _clr[3] = clr3;
+ _clr[4] = clr4;
+ _clr[5] = clr5;
+ _clr[6] = clr6;
+ _clr[7] = clr7;
+ _clr[8] = clr8;
+ _clr[9] = clr9;
+
+ _bgc[0] = bgc0;
+ _bgc[1] = bgc1;
+
+ _stp[0] = 55.0; // log_meter(-18);
+ _stp[1] = 77.5; // log_meter(-9);
+ _stp[2] = 92.5; // log_meter(-3);
+ _stp[2] = 95.0; // log_meter(-2);
set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK);
@@ -70,8 +82,8 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
if (!len) {
len = 250;
}
- fgpattern = request_vertical_meter(dimen, len, clr0, clr1, clr2, clr3);
- bgpattern = request_vertical_meter(dimen, len, _bgc0, _bgc1, _bgc2, _bgc3);
+ fgpattern = request_vertical_meter(dimen, len, _clr, _stp);
+ bgpattern = request_vertical_background (dimen, len, _bgc);
pixheight = len;
pixwidth = dimen;
@@ -82,36 +94,17 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
request_height= pixrect.height + 2;
}
+FastMeter::~FastMeter ()
+{
+}
+
Cairo::RefPtr<Cairo::Pattern>
FastMeter::generate_meter_pattern (
- int width, int height, int clr0, int clr1, int clr2, int clr3)
+ int width, int height, int *clr, float *stp)
{
- guint8 r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3,a;
-
- /*
- The knee is the hard transition point (e.g. at 0dB where the colors
- change dramatically to make clipping apparent). Thus there are two
- gradients in the pattern, the "normal range" and the "clip range", which
- are separated at the knee point.
-
- clr0: color at bottom of normal range gradient
- clr1: color at top of normal range gradient
- clr2: color at bottom of clip range gradient
- clr3: color at top of clip range gradient
- */
+ guint8 r,g,b,a;
+ int knee;
- UINT_TO_RGBA (clr0, &r0, &g0, &b0, &a);
- UINT_TO_RGBA (clr1, &r1, &g1, &b1, &a);
- UINT_TO_RGBA (clr2, &r2, &g2, &b2, &a);
- UINT_TO_RGBA (clr3, &r3, &g3, &b3, &a);
-
- // fake log calculation copied from log_meter.h
- // actual calculation:
- // log_meter(0.0f) =
- // def = (0.0f + 20.0f) * 2.5f + 50f
- // return def / 115.0f
-
- const int knee = (int)floor((float)height * 100.0f / 115.0f);
cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, width, height);
/*
@@ -119,21 +112,76 @@ FastMeter::generate_meter_pattern (
knee-based positions by using (1.0 - y)
*/
- // Clip range top
+ UINT_TO_RGBA (clr[9], &r, &g, &b, &a); // top/clip
cairo_pattern_add_color_stop_rgb (pat, 0.0,
- r3/255.0, g3/255.0, b3/255.0);
+ r/255.0, g/255.0, b/255.0);
- // Clip range bottom
+ knee = (int)floor((float)height * 100.0f / 115.0f); // -0dB
+
+ UINT_TO_RGBA (clr[8], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
- r2/255.0, g2/255.0, b2/255.0);
+ r/255.0, g/255.0, b/255.0);
- // Normal range top (double-stop at knee)
+ UINT_TO_RGBA (clr[7], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
+ r/255.0, g/255.0, b/255.0);
+
+ knee = (int)floor((float)height * stp[2]/ 115.0f); // -3dB || -2dB
+
+ UINT_TO_RGBA (clr[6], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[5], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
+ r/255.0, g/255.0, b/255.0);
+
+ knee = (int)floor((float)height * stp[1] / 115.0f); // -9dB
+
+ UINT_TO_RGBA (clr[4], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[3], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
+ r/255.0, g/255.0, b/255.0);
+
+ knee = (int)floor((float)height * stp[0] / 115.0f); // -18dB
+
+ UINT_TO_RGBA (clr[2], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[1], &r, &g, &b, &a);
+ cairo_pattern_add_color_stop_rgb (pat, 1.0 - (knee/(double)height),
+ r/255.0, g/255.0, b/255.0);
+
+ UINT_TO_RGBA (clr[0], &r, &g, &b, &a); // bottom
+ cairo_pattern_add_color_stop_rgb (pat, 1.0,
+ r/255.0, g/255.0, b/255.0);
+
+ Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
+
+ return p;
+}
+
+
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::generate_meter_background (
+ int width, int height, int *clr)
+{
+ guint8 r0,g0,b0,r1,g1,b1,a;
+
+ cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, width, height);
+
+ UINT_TO_RGBA (clr[0], &r0, &g0, &b0, &a);
+ UINT_TO_RGBA (clr[1], &r1, &g1, &b1, &a);
+
+ cairo_pattern_add_color_stop_rgb (pat, 0.0,
r1/255.0, g1/255.0, b1/255.0);
- // Normal range bottom
cairo_pattern_add_color_stop_rgb (pat, 1.0,
- r0/255.0, g0/255.0, b0/255.0); // top
+ r0/255.0, g0/255.0, b0/255.0);
Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
@@ -142,30 +190,53 @@ FastMeter::generate_meter_pattern (
Cairo::RefPtr<Cairo::Pattern>
FastMeter::request_vertical_meter(
- int width, int height, int clr0, int clr1, int clr2, int clr3)
+ int width, int height, int *clr, float *stp)
{
if (height < min_pattern_metric_size)
height = min_pattern_metric_size;
if (height > max_pattern_metric_size)
height = max_pattern_metric_size;
- const PatternMapKey key (width, height, clr0, clr1, clr2, clr3);
- PatternMap::iterator i;
- if ((i = v_pattern_cache.find (key)) != v_pattern_cache.end()) {
+ const Pattern10MapKey key (width, height,
+ stp[0], stp[1], stp[2],
+ clr[0], clr[1], clr[2], clr[3],
+ clr[4], clr[5], clr[6], clr[7],
+ clr[8], clr[9]);
+ Pattern10Map::iterator i;
+ if ((i = vm_pattern_cache.find (key)) != vm_pattern_cache.end()) {
return i->second;
}
Cairo::RefPtr<Cairo::Pattern> p = generate_meter_pattern (
- width, height, clr0, clr1, clr2, clr3);
- v_pattern_cache[key] = p;
+ width, height, clr, stp);
+ vm_pattern_cache[key] = p;
return p;
}
-FastMeter::~FastMeter ()
+Cairo::RefPtr<Cairo::Pattern>
+FastMeter::request_vertical_background(
+ int width, int height, int *bgc)
{
+ if (height < min_pattern_metric_size)
+ height = min_pattern_metric_size;
+ if (height > max_pattern_metric_size)
+ height = max_pattern_metric_size;
+
+ const PatternBgMapKey key (width, height, bgc[0], bgc[1]);
+ PatternBgMap::iterator i;
+ if ((i = vb_pattern_cache.find (key)) != vb_pattern_cache.end()) {
+ return i->second;
+ }
+
+ Cairo::RefPtr<Cairo::Pattern> p = generate_meter_background (
+ width, height, bgc);
+ vb_pattern_cache[key] = p;
+
+ return p;
}
+
void
FastMeter::set_hold_count (long val)
{
@@ -207,10 +278,8 @@ FastMeter::on_size_allocate (Gtk::Allocation &alloc)
}
if (pixheight != h) {
- fgpattern = request_vertical_meter (
- request_width, h, _clr0, _clr1, _clr2, _clr3);
- bgpattern = request_vertical_meter (
- request_width, h, _bgc0, _bgc1, _bgc2, _bgc3);
+ fgpattern = request_vertical_meter (request_width, h, _clr, _stp);
+ bgpattern = request_vertical_background (request_width, h, _bgc);
pixheight = h - 2;
pixwidth = request_width - 2;
}
diff --git a/libs/gtkmm2ext/gtkmm2ext/fastmeter.h b/libs/gtkmm2ext/gtkmm2ext/fastmeter.h
index 49076fa73a..c0b380ed1b 100644
--- a/libs/gtkmm2ext/gtkmm2ext/fastmeter.h
+++ b/libs/gtkmm2ext/gtkmm2ext/fastmeter.h
@@ -37,8 +37,12 @@ class FastMeter : public Gtk::DrawingArea {
};
FastMeter (long hold_cnt, unsigned long width, Orientation, int len=0,
- int clr0=0x00ff00, int clr1=0xffff00, int clr2=0xffaa00, int clr3=0xff0000,
- int bgc0=0x111111ff, int bgc1=0x333333ff, int bgc2=0x333333ff, int bgc3=0x444444ff
+ int clr0=0x008800ff, int clr1=0x008800ff,
+ int clr2=0x00ff00ff, int clr3=0x00ff00ff,
+ int clr4=0x80ff00ff, int clr5=0x80ff00ff,
+ int clr6=0xffaa00ff, int clr7=0xffaa00ff,
+ int clr8=0xff0000ff, int clr9=0xff0000ff,
+ int bgc0=0x333333ff, int bgc1=0x444444ff
);
virtual ~FastMeter ();
@@ -63,8 +67,10 @@ private:
Cairo::RefPtr<Cairo::Pattern> bgpattern;
gint pixheight;
gint pixwidth;
- int _clr0, _clr1, _clr2, _clr3;
- int _bgc0, _bgc1, _bgc2, _bgc3;
+
+ float _stp[3];
+ int _clr[10];
+ int _bgc[2];
Orientation orientation;
GdkRectangle pixrect;
@@ -82,24 +88,53 @@ private:
void queue_vertical_redraw (const Glib::RefPtr<Gdk::Window>&, float);
static Cairo::RefPtr<Cairo::Pattern> generate_meter_pattern (
- int w, int h, int clr0, int clr1, int clr2, int clr3);
+ int w, int h, int *clr, float *stp);
static Cairo::RefPtr<Cairo::Pattern> request_vertical_meter (
- int w, int h, int clr0, int clr1, int clr2, int clr3);
+ int w, int h, int *clr, float *stp);
+
+ static Cairo::RefPtr<Cairo::Pattern> generate_meter_background (
+ int w, int h, int *bgc);
+ static Cairo::RefPtr<Cairo::Pattern> request_vertical_background (
+ int w, int h, int *bgc);
+
+ struct Pattern10MapKey {
+ Pattern10MapKey (
+ int w, int h,
+ float stp0, float stp1, float stp2,
+ int c0, int c1, int c2, int c3,
+ int c4, int c5, int c6, int c7,
+ int c8, int c9
+ )
+ : dim(w, h)
+ , stp(stp0, stp1, stp2)
+ , cols(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9)
+ {}
+ inline bool operator<(const Pattern10MapKey& rhs) const {
+ return (dim < rhs.dim)
+ || (dim == rhs.dim && stp < rhs.stp)
+ || (dim == rhs.dim && stp == rhs.stp && cols < rhs.cols);
+ }
+ boost::tuple<int, int> dim;
+ boost::tuple<float, float, float> stp;
+ boost::tuple<int, int, int, int, int, int, int, int, int, int> cols;
+ };
+ typedef std::map<Pattern10MapKey, Cairo::RefPtr<Cairo::Pattern> > Pattern10Map;
- struct PatternMapKey {
- PatternMapKey (int w, int h, int c0, int c1, int c2, int c3)
+ struct PatternBgMapKey {
+ PatternBgMapKey (int w, int h, int c0, int c1)
: dim(w, h)
- , cols(c0, c1, c2, c3)
+ , cols(c0, c1)
{}
- inline bool operator<(const PatternMapKey& rhs) const {
+ inline bool operator<(const PatternBgMapKey& rhs) const {
return (dim < rhs.dim) || (dim == rhs.dim && cols < rhs.cols);
}
- boost::tuple<int, int> dim; // width, height
- boost::tuple<int, int, int, int> cols; // c0, c1, c2, c3
+ boost::tuple<int, int> dim;
+ boost::tuple<int, int> cols;
};
- typedef std::map<PatternMapKey, Cairo::RefPtr<Cairo::Pattern> > PatternMap;
+ typedef std::map<PatternBgMapKey, Cairo::RefPtr<Cairo::Pattern> > PatternBgMap;
- static PatternMap v_pattern_cache;
+ static Pattern10Map vm_pattern_cache;
+ static PatternBgMap vb_pattern_cache;
static int min_pattern_metric_size; // min dimension for axis that displays the meter level
static int max_pattern_metric_size; // max dimension for axis that displays the meter level
};