#include "gtkmm2ext/cairo_widget.h"
#include "gtkmm2ext/gui_thread.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
static const char* has_cairo_widget_background_info = "has_cairo_widget_background_info";
bool CairoWidget::_flat_buttons = false;
bool CairoWidget::_widget_prelight = true;
-static void noop() { }
-sigc::slot<void> CairoWidget::focus_handler (sigc::ptr_fun (noop));
+sigc::slot<void,Gtk::Widget*> CairoWidget::focus_handler;
void CairoWidget::set_source_rgb_a( cairo_t* cr, Gdk::Color col, float a) //ToDo: this one and the Canvas version should be in a shared file (?)
{
float r = col.get_red_p ();
float g = col.get_green_p ();
float b = col.get_blue_p ();
-
+
cairo_set_source_rgba(cr, r, g, b, a);
}
bool
CairoWidget::on_button_press_event (GdkEventButton*)
{
- focus_handler();
+ focus_handler (this);
return false;
}
+
+#ifdef USE_TRACKS_CODE_FEATURES
+
+/* This is Tracks version of this method.
+
+ The use of get_visible_window() in this method is an abuse of the GDK/GTK
+ semantics. It can and may break on different GDK backends, and uses a
+ side-effect/unintended behaviour in GDK/GTK to try to accomplish something
+ which should be done differently. I (Paul) have confirmed this with the GTK
+ development team.
+
+ For this reason, this code is not acceptable for ordinary merging into the Ardour libraries.
+
+ Ardour Developers: you are not obligated to maintain the internals of this
+ implementation in the face of build-time environment changes (e.g. -D
+ defines etc).
+*/
+
+bool
+CairoWidget::on_expose_event (GdkEventExpose *ev)
+{
+ cairo_rectangle_t expose_area;
+ expose_area.width = ev->area.width;
+ expose_area.height = ev->area.height;
+
+#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
+ Cairo::RefPtr<Cairo::Context> cr;
+ if (get_visible_window ()) {
+ expose_area.x = 0;
+ expose_area.y = 0;
+ if (!_image_surface) {
+ _image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
+ }
+ cr = Cairo::Context::create (_image_surface);
+ } else {
+ expose_area.x = ev->area.x;
+ expose_area.y = ev->area.y;
+ cr = get_window()->create_cairo_context ();
+ }
+#else
+ expose_area.x = ev->area.x;
+ expose_area.y = ev->area.y;
+ Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context ();
+#endif
+
+ cr->rectangle (expose_area.x, expose_area.y, expose_area.width, expose_area.height);
+ cr->clip ();
+
+ /* paint expose area the color of the parent window bg
+ */
+
+ if (get_visible_window ()) {
+ Gdk::Color bg (get_parent_bg());
+ cr->rectangle (expose_area.x, expose_area.y, expose_area.width, expose_area.height);
+ cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
+ cr->fill ();
+ }
+
+ render (cr->cobj(), &expose_area);
+
+#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
+ if(get_visible_window ()) {
+ _image_surface->flush();
+ /* now blit our private surface back to the GDK one */
+
+ Cairo::RefPtr<Cairo::Context> cairo_context = get_window()->create_cairo_context ();
+
+ cairo_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+ cairo_context->clip ();
+ cairo_context->set_source (_image_surface, ev->area.x, ev->area.y);
+ cairo_context->set_operator (Cairo::OPERATOR_OVER);
+ cairo_context->paint ();
+ }
+#endif
+
+ Gtk::Widget* child = get_child ();
+
+ if (child) {
+ propagate_expose (*child, ev);
+ }
+
+ return true;
+}
+
+#else
+
+/* Ardour mainline: not using Tracks code features.
+
+ Tracks Developers: please do not modify this version of
+ ::on_expose_event(). The version used by Tracks is before the preceding
+ #else and contains hacks required for the Tracks GUI to work.
+*/
+
bool
CairoWidget::on_expose_event (GdkEventExpose *ev)
{
#endif
cr->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
- cr->clip_preserve ();
- /* paint expose area the color of the parent window bg
- */
-
- Gdk::Color bg (get_parent_bg());
-
- cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
- cr->fill ();
+ if (_need_bg) {
+ cr->clip_preserve ();
+
+ /* paint expose area the color of the parent window bg
+ */
+
+ Gdk::Color bg (get_parent_bg());
+
+ cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
+ cr->fill ();
+ } else {
+ std::cerr << get_name() << " skipped bg fill\n";
+ cr->clip ();
+ }
cairo_rectangle_t expose_area;
expose_area.x = ev->area.x;
return true;
}
+#endif
+
/** Marks the widget as dirty, so that render () will be called on
* the next GTK expose event.
*/
void
-CairoWidget::set_dirty ()
+CairoWidget::set_dirty (cairo_rectangle_t *area)
{
ENSURE_GUI_THREAD (*this, &CairoWidget::set_dirty);
- queue_draw ();
+ if (!area) {
+ queue_draw ();
+ } else {
+ queue_draw_area (area->x, area->y, area->width, area->height);
+ }
}
/** Handle a size allocation.
}
void
-CairoWidget::set_focus_handler (sigc::slot<void> s)
+CairoWidget::set_focus_handler (sigc::slot<void,Gtk::Widget*> s)
{
focus_handler = s;
}