From e1fb7fe9fc797058680fe0f7eb3af352db586e0b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 25 Sep 2016 10:50:03 -0500 Subject: working canvas meter code --- libs/surfaces/push2/meter.cc | 93 ++++++++++++++++++++++++++------------------ libs/surfaces/push2/meter.h | 22 ++++------- 2 files changed, 63 insertions(+), 52 deletions(-) (limited to 'libs/surfaces') diff --git a/libs/surfaces/push2/meter.cc b/libs/surfaces/push2/meter.cc index 02ceba85ea..7744168f05 100644 --- a/libs/surfaces/push2/meter.cc +++ b/libs/surfaces/push2/meter.cc @@ -28,12 +28,13 @@ #include #include +#include #include "canvas/canvas.h" -#include "meter.h" +#include "canvas/utils.h" +#include "canvas/colors.h" -#define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; } -#define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; } +#include "meter.h" using namespace Glib; using namespace Gtkmm2ext; @@ -112,13 +113,13 @@ Meter::Meter (Item* parent, long hold, unsigned long dimen, Orientation o, int l if (orientation == Vertical) { pixheight = len; pixwidth = dimen; - fgpattern = request_vertical_meter(pixwidth + 2, pixheight + 2, _clr, _stp, _styleflags); - bgpattern = request_vertical_background (pixwidth + 2, pixheight + 2, _bgc, false); + fgpattern = vertical_meter_pattern (pixwidth + 2, pixheight + 2, _clr, _stp, _styleflags); + bgpattern = vertical_background (pixwidth + 2, pixheight + 2, _bgc, false); } else { pixheight = dimen; pixwidth = len; - fgpattern = request_horizontal_meter(pixwidth + 2, pixheight + 2, _clr, _stp, _styleflags); - bgpattern = request_horizontal_background (pixwidth + 2, pixheight + 2, _bgc, false); + fgpattern = horizontal_meter_pattern (pixwidth + 2, pixheight + 2, _clr, _stp, _styleflags); + bgpattern = horizontal_background (pixwidth + 2, pixheight + 2, _bgc, false); } pixrect.width = pixwidth; @@ -347,7 +348,7 @@ Meter::generate_meter_background (int width, int height, int *clr, bool shade, b } Cairo::RefPtr -Meter::request_vertical_meter (int width, int height, int *clr, float *stp, int styleflags) +Meter::vertical_meter_pattern (int width, int height, int *clr, float *stp, int styleflags) { height = max(height, min_pattern_metric_size); height = min(height, max_pattern_metric_size); @@ -364,15 +365,14 @@ Meter::request_vertical_meter (int width, int height, int *clr, float *stp, int } // TODO flush pattern cache if it gets too large - Cairo::RefPtr p = generate_meter_pattern ( - width, height, clr, stp, styleflags, false); + Cairo::RefPtr p = generate_meter_pattern (width, height, clr, stp, styleflags, false); vm_pattern_cache[key] = p; return p; } Cairo::RefPtr -Meter::request_vertical_background (int width, int height, int *bgc, bool shade) +Meter::vertical_background (int width, int height, int *bgc, bool shade) { height = max(height, min_pattern_metric_size); height = min(height, max_pattern_metric_size); @@ -380,20 +380,20 @@ Meter::request_vertical_background (int width, int height, int *bgc, bool shade) const PatternBgMapKey key (width, height, bgc[0], bgc[1], shade); PatternBgMap::iterator i; + if ((i = vb_pattern_cache.find (key)) != vb_pattern_cache.end()) { return i->second; } // TODO flush pattern cache if it gets too large - Cairo::RefPtr p = generate_meter_background ( - width, height, bgc, shade, false); + Cairo::RefPtr p = generate_meter_background (width, height, bgc, shade, false); vb_pattern_cache[key] = p; return p; } Cairo::RefPtr -Meter::request_horizontal_meter (int width, int height, int *clr, float *stp, int styleflags) +Meter::horizontal_meter_pattern (int width, int height, int *clr, float *stp, int styleflags) { width = max(width, min_pattern_metric_size); width = min(width, max_pattern_metric_size); @@ -410,16 +410,14 @@ Meter::request_horizontal_meter (int width, int height, int *clr, float *stp, in } // TODO flush pattern cache if it gets too large - Cairo::RefPtr p = generate_meter_pattern ( - height, width, clr, stp, styleflags, true); + Cairo::RefPtr p = generate_meter_pattern (height, width, clr, stp, styleflags, true); hm_pattern_cache[key] = p; return p; } Cairo::RefPtr -Meter::request_horizontal_background( - int width, int height, int *bgc, bool shade) +Meter::horizontal_background (int width, int height, int *bgc, bool shade) { width = max(width, min_pattern_metric_size); width = min(width, max_pattern_metric_size); @@ -432,8 +430,7 @@ Meter::request_horizontal_background( } // TODO flush pattern cache if it gets too large - Cairo::RefPtr p = generate_meter_background ( - height, width, bgc, shade, true); + Cairo::RefPtr p = generate_meter_background (height, width, bgc, shade, true); hb_pattern_cache[key] = p; @@ -493,6 +490,11 @@ Meter::vertical_expose (ArdourCanvas::Rect const & area, Cairo::RefPtrtranslate (origin.x, origin.y); + Cairo::RefPtr r1 = Cairo::Region::create (area_r); r1->intersect (background); @@ -542,6 +544,8 @@ Meter::vertical_expose (ArdourCanvas::Rect const & area, Cairo::RefPtrtranslate (-origin.x, -origin.y); } void @@ -551,48 +555,61 @@ Meter::horizontal_expose (ArdourCanvas::Rect const & area, Cairo::RefPtrset_source_rgb (0, 0, 0); // black rounded_rectangle (context, 0, 0, pixwidth + 2, pixheight + 2, 2); context->stroke (); + /* horizontal meter extends from left to right. Compute the right edge */ right_of_meter = (gint) floor (pixwidth * current_level); - /* reset the height & origin of the rect that needs to show the pixbuf - */ - + /* reset the width the rect that needs to show the pattern of the meter */ pixrect.width = right_of_meter; + /* compute a rect for the part of the meter that is all background */ background.x = 1 + right_of_meter; background.y = 1; background.width = pixwidth - right_of_meter; background.height = pixheight; - Cairo::RefPtr r1 = Cairo::Region::create (area_r); - r1->intersect (background); + /* translate so that item coordinates match window coordinates */ + Duple origin (0, 0); + origin = item_to_window (origin); + context->translate (origin.x, origin.y); - if (!r1->empty()) { - Cairo::RectangleInt i (r1->get_extents ()); - context->rectangle (i.x, i.y, i.width, i.height); + Cairo::RefPtr r; + + r = Cairo::Region::create (area_r); + r->intersect (background); + + if (!r->empty()) { + /* draw the background part */ + Cairo::RectangleInt i (r->get_extents ()); context->set_source (bgpattern); + context->rectangle (i.x, i.y, i.width, i.height); context->fill (); + } - Cairo::RefPtr r2 = Cairo::Region::create (area_r); - r2->intersect (pixrect); + r = Cairo::Region::create (area_r); + r->intersect (pixrect); - if (!r2->empty()) { - // draw the part of the meter image that we need. the area we draw is bounded "in reverse" (top->bottom) - Cairo::RectangleInt i (r2->get_extents ()); - cerr << "h-render-fg: " << i.x << ", " << i.y << ' ' << i.width << " + " << i.height << endl; - context->rectangle (i.x, i.y, i.width, i.height); + if (!r->empty()) { + // draw the part of the meter image that we need. + Cairo::RectangleInt i (r->get_extents ()); + Duple d (i.x, i.y); context->set_source (fgpattern); + context->rectangle (i.x, i.y, i.width, i.height); context->fill (); } @@ -622,6 +639,8 @@ Meter::horizontal_expose (ArdourCanvas::Rect const & area, Cairo::RefPtrtranslate (-origin.x, -origin.y); } void @@ -827,9 +846,9 @@ Meter::set_highlight (bool onoff) } highlight = onoff; if (orientation == Vertical) { - bgpattern = request_vertical_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, highlight); + bgpattern = vertical_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, highlight); } else { - bgpattern = request_horizontal_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, highlight); + bgpattern = horizontal_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, highlight); } redraw (); } diff --git a/libs/surfaces/push2/meter.h b/libs/surfaces/push2/meter.h index 40129a3f63..720baacf6c 100644 --- a/libs/surfaces/push2/meter.h +++ b/libs/surfaces/push2/meter.h @@ -87,8 +87,6 @@ class Meter : public ArdourCanvas::Item { Orientation orientation; mutable Cairo::RectangleInt pixrect; mutable Cairo::RectangleInt last_peak_rect; - gint request_width; - gint request_height; unsigned long hold_cnt; unsigned long hold_state; bool bright_hold; @@ -105,19 +103,13 @@ class Meter : public ArdourCanvas::Item { static bool no_rgba_overlay; - static Cairo::RefPtr generate_meter_pattern ( - int, int, int *, float *, int, bool); - static Cairo::RefPtr request_vertical_meter ( - int, int, int *, float *, int); - static Cairo::RefPtr request_horizontal_meter ( - int, int, int *, float *, int); - - static Cairo::RefPtr generate_meter_background ( - int, int, int *, bool, bool); - static Cairo::RefPtr request_vertical_background ( - int, int, int *, bool); - static Cairo::RefPtr request_horizontal_background ( - int, int, int *, bool); + static Cairo::RefPtr generate_meter_pattern (int, int, int *, float *, int, bool); + static Cairo::RefPtr vertical_meter_pattern (int, int, int *, float *, int); + static Cairo::RefPtr horizontal_meter_pattern (int, int, int *, float *, int); + + static Cairo::RefPtr generate_meter_background (int, int, int *, bool, bool); + static Cairo::RefPtr vertical_background (int, int, int *, bool); + static Cairo::RefPtr horizontal_background (int, int, int *, bool); struct Pattern10MapKey { Pattern10MapKey ( -- cgit v1.2.3