Towards packing CairoWidgets on ArdourCanvas.
authorRobin Gareus <robin@gareus.org>
Mon, 19 Dec 2016 12:36:42 +0000 (13:36 +0100)
committerRobin Gareus <robin@gareus.org>
Mon, 19 Dec 2016 12:36:42 +0000 (13:36 +0100)
libs/canvas/canvas/widget.h
libs/canvas/widget.cc
libs/gtkmm2ext/cairo_widget.cc
libs/gtkmm2ext/gtkmm2ext/cairo_widget.h

index 127862037c9fb27c71038364f8d0bc3347bcdbd4..c1f6dc1f36852679350b99eea00e0a5cd7271d12 100644 (file)
@@ -44,6 +44,8 @@ public:
 private:
        CairoWidget& _widget;
        bool event_proxy (GdkEvent*);
+       bool queue_draw ();
+       bool queue_resize ();
 };
 
 }
index 25541c1660abf8bbe349925e36a35130394d91c1..7293badb7ce5a7fb15f4b232c27f9395c690e391 100644 (file)
@@ -34,6 +34,9 @@ Widget::Widget (Canvas* c, CairoWidget& w)
        , _widget (w)
 {
        Event.connect (sigc::mem_fun (*this, &Widget::event_proxy));
+       w.set_canvas_widget ();
+       w.QueueDraw.connect (sigc::mem_fun(*this, &Widget::queue_draw));
+       w.QueueResize.connect (sigc::mem_fun(*this, &Widget::queue_resize));
 }
 
 Widget::Widget (Item* parent, CairoWidget& w)
@@ -41,6 +44,9 @@ Widget::Widget (Item* parent, CairoWidget& w)
        , _widget (w)
 {
        Event.connect (sigc::mem_fun (*this, &Widget::event_proxy));
+       w.set_canvas_widget ();
+       w.QueueDraw.connect (sigc::mem_fun(*this, &Widget::queue_draw));
+       w.QueueResize.connect (sigc::mem_fun(*this, &Widget::queue_resize));
 }
 
 bool
@@ -50,6 +56,22 @@ Widget::event_proxy (GdkEvent* ev)
        return _widget.event (ev);
 }
 
+bool
+Widget::queue_draw ()
+{
+       begin_visual_change ();
+       end_visual_change ();
+       return true;
+}
+
+bool
+Widget::queue_resize ()
+{
+       begin_change ();
+       end_change ();
+       return true;
+}
+
 void
 Widget::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
 {
index 8349a685fa4dc50340278298d7bb7c9a7a3197a3..229ffe8d3115c120c7cf05e109fd49b02abb3847 100644 (file)
@@ -48,15 +48,57 @@ CairoWidget::CairoWidget ()
        , _grabbed (false)
        , _name_proxy (this, X_("name"))
        , _current_parent (0)
+       , _canvas_widget (false)
 {
        _name_proxy.connect (sigc::mem_fun (*this, &CairoWidget::on_name_changed));
 }
 
 CairoWidget::~CairoWidget ()
 {
+       if (_canvas_widget) {
+               gtk_widget_set_realized (GTK_WIDGET(gobj()), false);
+       }
        if (_parent_style_change) _parent_style_change.disconnect();
 }
 
+void
+CairoWidget::set_canvas_widget ()
+{
+       assert (!_canvas_widget);
+       ensure_style ();
+       gtk_widget_set_realized (GTK_WIDGET(gobj()), true);
+       _canvas_widget = true;
+}
+
+int
+CairoWidget::get_width () const
+{
+       if (_canvas_widget) {
+               return _allocation.get_width ();
+       }
+       return Gtk::EventBox::get_width ();
+}
+
+int
+CairoWidget::get_height () const
+{
+       if (_canvas_widget) {
+               return _allocation.get_height ();
+       }
+       return Gtk::EventBox::get_height ();
+}
+
+void
+CairoWidget::size_allocate (Gtk::Allocation& alloc)
+{
+       if (_canvas_widget) {
+               memcpy (&_allocation, &alloc, sizeof(Gtk::Allocation));
+               return;
+       }
+       Gtk::EventBox::size_allocate (alloc);
+}
+
+
 bool
 CairoWidget::on_button_press_event (GdkEventButton*)
 {
@@ -241,17 +283,43 @@ CairoWidget::set_dirty (cairo_rectangle_t *area)
        if (!area) {
                queue_draw ();
        } else {
+               // TODO emit QueueDrawArea -> ArdourCanvas::Widget
+               if (QueueDraw ()) {
+                       return;
+               }
                queue_draw_area (area->x, area->y, area->width, area->height);
        }
 }
 
+void
+CairoWidget::queue_draw ()
+{
+       if (QueueDraw ()) {
+               return;
+       }
+       Gtk::EventBox::queue_draw ();
+}
+
+void
+CairoWidget::queue_resize ()
+{
+       if (QueueResize ()) {
+               return;
+       }
+       Gtk::EventBox::queue_resize ();
+}
+
 /** Handle a size allocation.
  *  @param alloc GTK allocation.
  */
 void
 CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
 {
-       Gtk::EventBox::on_size_allocate (alloc);
+       if (!_canvas_widget) {
+               Gtk::EventBox::on_size_allocate (alloc);
+       } else {
+               memcpy (&_allocation, &alloc, sizeof(Gtk::Allocation));
+       }
 
 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
        if (getenv("ARDOUR_IMAGE_SURFACE")) {
@@ -263,6 +331,9 @@ CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
        }
 #endif
 
+       if (_canvas_widget) {
+               return;
+       }
        set_dirty ();
 }
 
@@ -340,7 +411,7 @@ CairoWidget::set_active (bool yn)
 void
 CairoWidget::on_style_changed (const Glib::RefPtr<Gtk::Style>&)
 {
-       queue_draw();
+       set_dirty ();
 }
 
 void
@@ -356,7 +427,7 @@ CairoWidget::on_state_changed (Gtk::StateType)
                set_visual_state (Gtkmm2ext::VisualState (visual_state() & ~Gtkmm2ext::Insensitive));
        }
 
-       queue_draw ();
+       set_dirty ();
 }
 
 void
index 2588adcdcc8c4edb17d3097fcb9d3afe6e61dc2b..03afc48818ba1e5c24c3b6977e42cc6d9bb70cf9 100644 (file)
@@ -35,6 +35,15 @@ public:
        CairoWidget ();
        virtual ~CairoWidget ();
 
+       void set_canvas_widget ();
+
+       /* swizzle Gtk::Widget methods for Canvas::Widget */
+       void queue_draw ();
+       void queue_resize ();
+       int get_width () const;
+       int get_height () const;
+       void size_allocate (Gtk::Allocation&);
+
        void set_dirty (cairo_rectangle_t *area = 0);
 
        Gtkmm2ext::ActiveState active_state() const { return _active_state; }
@@ -65,6 +74,8 @@ public:
        void set_draw_background (bool yn);
 
        sigc::signal<void> StateChanged;
+       sigc::signal<bool> QueueDraw;
+       sigc::signal<bool> QueueResize;
 
        static void provide_background_for_cairo_widget (Gtk::Widget& w, const Gdk::Color& bg);
 
@@ -125,6 +136,8 @@ protected:
        Glib::SignalProxyProperty _name_proxy;
        sigc::connection _parent_style_change;
        Widget * _current_parent;
+       bool _canvas_widget;
+       Gdk::Rectangle _allocation;
 
 };