diff options
author | Robin Gareus <robin@gareus.org> | 2013-07-03 23:39:47 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2013-07-10 15:27:07 +0200 |
commit | 571b2d70e9f6e7799f74bd3eec90835101fddbe6 (patch) | |
tree | 0a3bcf7a2550dd65f2448962ef3a148005d181a5 /libs | |
parent | 447e736139f61dbc8697fbd7a19a5fd3cb7d1609 (diff) |
refactor level-meter widget: 5x2 stops meter colors
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gtkmm2ext/fastmeter.cc | 181 | ||||
-rw-r--r-- | libs/gtkmm2ext/gtkmm2ext/fastmeter.h | 63 |
2 files changed, 174 insertions, 70 deletions
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 }; |