*/
+#if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
+#define OPTIONAL_CAIRO_IMAGE_SURFACE
+#endif
+
/** @file canvas/canvas.cc
* @brief Implementation of the main canvas classes.
*/
Duple
Canvas::window_to_canvas (Duple const & d) const
{
- /* Find the scroll group that covers d (a window coordinate). Scroll groups are only allowed
- * as children of the root group, so we just scan its first level
- * children and see what we can find.
- */
-
- std::list<Item*> const& root_children (_root.items());
+ ScrollGroup* best_group = 0;
ScrollGroup* sg = 0;
/* if the coordinates are negative, clamp to zero and find the item
in_window.y = 0;
}
- for (std::list<Item*>::const_reverse_iterator i = root_children.rbegin(); i != root_children.rend(); ++i) {
- if (((sg = dynamic_cast<ScrollGroup*>(*i)) != 0) && sg->covers_window (in_window)) {
- break;
+ for (list<ScrollGroup*>::const_iterator s = scrollers.begin(); s != scrollers.end(); ++s) {
+
+ if ((*s)->covers_window (in_window)) {
+ sg = *s;
+
+ /* XXX January 22nd 2015: leaving this in place for now
+ * but I think it fixes a bug that really should be
+ * fixed in a different way (and will be) by my next
+ * commit. But it may still be relevant.
+ */
+
+ /* If scroll groups overlap, choose the one with the highest sensitivity,
+ that is, choose an HV scroll group over an H or V
+ only group.
+ */
+ if (!best_group || sg->sensitivity() > best_group->sensitivity()) {
+ best_group = sg;
+ if (sg->sensitivity() == (ScrollGroup::ScrollsVertically | ScrollGroup::ScrollsHorizontally)) {
+ /* Can't do any better than this. */
+ break;
+ }
+ }
}
}
- if (sg) {
- return d.translate (sg->scroll_offset());
+ if (best_group) {
+ return d.translate (best_group->scroll_offset());
}
return d;
break;
}
}
-
if (sg) {
wd = d.translate (-sg->scroll_offset());
, _new_current_item (0)
, _grabbed_item (0)
, _focused_item (0)
+ , _single_exposure (1)
, current_tooltip_item (0)
, tooltip_window (0)
{
GtkCanvas::on_size_allocate (Gtk::Allocation& a)
{
EventBox::on_size_allocate (a);
-#ifdef USE_CAIRO_IMAGE_SURFACE
+#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
+ if (getenv("ARDOUR_IMAGE_SURFACE")) {
+#endif
+#if defined USE_CAIRO_IMAGE_SURFACE || defined OPTIONAL_CAIRO_IMAGE_SURFACE
/* allocate an image surface as large as the canvas itself */
canvas_image.clear ();
canvas_image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, a.get_width(), a.get_height());
#endif
+#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
+ }
+#endif
}
/** Handler for GDK expose events.
bool
GtkCanvas::on_expose_event (GdkEventExpose* ev)
{
-#ifdef USE_CAIRO_IMAGE_SURFACE
+#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
+ Cairo::RefPtr<Cairo::Context> draw_context;
+ Cairo::RefPtr<Cairo::Context> window_context;
+ if (getenv("ARDOUR_IMAGE_SURFACE")) {
+ if (!canvas_image) {
+ canvas_image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
+ }
+ draw_context = Cairo::Context::create (canvas_image);
+ window_context = get_window()->create_cairo_context ();
+ } else {
+ draw_context = get_window()->create_cairo_context ();
+ }
+#elif defined USE_CAIRO_IMAGE_SURFACE
if (!canvas_image) {
canvas_image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
}
draw_context->fill ();
/* render canvas */
-
- render (Rect (ev->area.x, ev->area.y, ev->area.x + ev->area.width, ev->area.y + ev->area.height), draw_context);
+ if ( _single_exposure ) {
+
+ render (Rect (ev->area.x, ev->area.y, ev->area.x + ev->area.width, ev->area.y + ev->area.height), draw_context);
-#ifdef USE_CAIRO_IMAGE_SURFACE
+ } else {
+ GdkRectangle* rects;
+ gint nrects;
+
+ gdk_region_get_rectangles (ev->region, &rects, &nrects);
+ for (gint n = 0; n < nrects; ++n) {
+ draw_context->set_identity_matrix(); //reset the cairo matrix, just in case someone left it transformed after drawing ( cough )
+ render (Rect (rects[n].x, rects[n].y, rects[n].x + rects[n].width, rects[n].y + rects[n].height), draw_context);
+ }
+ g_free (rects);
+ }
+
+#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
+ if (getenv("ARDOUR_IMAGE_SURFACE")) {
+#endif
+#if defined USE_CAIRO_IMAGE_SURFACE || defined OPTIONAL_CAIRO_IMAGE_SURFACE
/* now blit our private surface back to the GDK one */
window_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
window_context->set_operator (Cairo::OPERATOR_SOURCE);
window_context->paint ();
#endif
+#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
+ }
+#endif
return true;
}
tooltip_label = manage (new Gtk::Label);
tooltip_label->show ();
tooltip_window->add (*tooltip_label);
- tooltip_window->set_border_width (6);
+ tooltip_window->set_border_width (1);
tooltip_window->set_name ("tooltip");
}
* to get it away from the pointer.
*/
- tooltip_window_origin.x += 20;
+ tooltip_window_origin.x += 30;
+ tooltip_window_origin.y += 45;
/* move the tooltip window into position */
if (tooltip_window) {
tooltip_window->hide ();
+
+ // Delete the tooltip window so it'll get re-created
+ // (i.e. properly re-sized) on the next usage.
+ delete tooltip_window;
+ tooltip_window = NULL;
}
}