_stp[2] = stp2;
_stp[3] = stp3;
- pixrect.x = 1;
- pixrect.y = 1;
-
if (!len) {
len = 250;
}
bgpattern = horizontal_background (pixwidth + 2, pixheight + 2, _bgc, false);
}
- pixrect.width = pixwidth;
pixrect.height = pixheight;
+ pixrect.x = 1;
+
+ if (orientation == Vertical) {
+ pixrect.width = pixwidth;
+ pixrect.y = pixheight; /* bottom of meter, so essentially "show zero" */
+ } else {
+ pixrect.width = 0; /* right of meter, so essentially "show zero" */
+ pixrect.y = 1;
+ }
}
void
Meter::compute_bounding_box () const
{
if (!_canvas) {
- _bounding_box = boost::optional<Rect> ();
+ _bounding_box = Rect ();
_bounding_box_dirty = false;
return;
}
Cairo::RectangleInt background;
Cairo::RectangleInt area_r;
- area_r.x = area.x0;
- area_r.y = area.y0;
- area_r.width = area.width();
- area_r.height = area.height();
+ /* convert expose area back to item coordinate space */
+ Rect area2 = window_to_item (area);
+
+ area_r.x = area2.x0;
+ area_r.y = area2.y0;
+ area_r.width = area2.width();
+ area_r.height = area2.height();
context->set_source_rgb (0, 0, 0); // black
rounded_rectangle (context, 0, 0, pixwidth + 2, pixheight + 2, 2);
top_of_meter = (gint) floor (pixheight * current_level);
- /* reset the height & origin of the rect that needs to show the pixbuf
+ /* reset the height & origin of the rect that needs to show the meter pattern
*/
-
pixrect.height = top_of_meter;
+
+ /* X/cairo coordinates; y grows down so y origin of pixrect (pattern
+ fill area) is the TOP of the pattern area, which we compute like this:
+
+ - start at 1
+ - go to bottom of meter (pixheight)
+ - back up by current meter height (top_of_meter)
+ */
pixrect.y = 1 + pixheight - top_of_meter;
background.x = 1;
if (!r1->empty()) {
Cairo::RectangleInt i (r1->get_extents ());
- context->rectangle (i.x, i.y, i.width, i.height);
context->set_source (bgpattern);
+ context->rectangle (i.x, i.y, i.width, i.height);
context->fill ();
}
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 ());
- context->rectangle (i.x, i.y, i.width, i.height);
context->set_source (fgpattern);
+ context->rectangle (i.x, i.y, i.width, i.height);
context->fill ();
}
/* convert expose area back to item coordinate space */
Rect area2 = window_to_item (area);
-
/* create a Cairo object so that we can use intersect and Region */
area_r.x = area2.x0;
area_r.y = area2.y0;
}
if (orientation == Vertical) {
- //queue_vertical_redraw (old_level);
+ queue_vertical_redraw (old_level);
} else {
- //queue_horizontal_redraw (old_level);
+ queue_horizontal_redraw (old_level);
}
-
- redraw ();
}
void
{
Cairo::RectangleInt rect;
- gint new_top = (gint) floor (pixheight * current_level);
+ gint new_height = (gint) floor (pixheight * current_level);
+
+ /* this is the nominal area that needs to be filled by the meter
+ * pattern
+ */
rect.x = 1;
rect.width = pixwidth;
- rect.height = new_top;
- rect.y = 1 + pixheight - new_top;
+
+ /* compute new top of meter (rect.y) by starting at one (border
+ * offset), go down the full height of the meter (X/Cairo coordinates
+ * grow down) to get to the bottom coordinate, then back up by the
+ * height of the patterned area.
+ */
+ rect.y = 1 + pixheight - new_height;
+ /* remember: height extends DOWN thanks to X/Cairo */
+ rect.height = new_height;
+
+ /* now lets optimize redrawing by figuring out which part needs to be
+ actually redrawn (i.e. re-use the last drawn state).
+ */
if (current_level > old_level) {
- /* colored/pixbuf got larger, just draw the new section */
- /* rect.y stays where it is because of X coordinates */
- /* height of invalidated area is between new.y (smaller) and old.y
- (larger).
- X coordinates just make my brain hurt.
+ /* filled area got taller, just draw the new section */
+
+ /* rect.y (new y origin) is smaller or equal to pixrect.y (old
+ * y origin) because the top of the meter is higher (X/Cairo:
+ * coordinates grow down).
+ *
+ * Leave rect.y alone, and recompute the height to be just the
+ * difference between the new bottom and the top of the previous
+ * pattern area.
+ *
+ * The old pattern area extended DOWN from pixrect.y to
+ * pixrect.y + pixrect.height.
+ *
+ * The new pattern area extends DOWN from rect.y to
+ * rect.y + rect.height
+ *
+ * The area needing to be drawn is the difference between the
+ * old top (pixrect.y) and the new top (rect.y)
*/
rect.height = pixrect.y - rect.y;
} else {