Allow CairoWidget to be backed by NSGLView
authorRobin Gareus <robin@gareus.org>
Mon, 20 Mar 2017 04:19:38 +0000 (05:19 +0100)
committerRobin Gareus <robin@gareus.org>
Mon, 20 Mar 2017 04:19:38 +0000 (05:19 +0100)
libs/gtkmm2ext/cairo_widget.cc
libs/gtkmm2ext/gtkmm2ext/cairo_widget.h

index 229ffe8d3115c120c7cf05e109fd49b02abb3847..ca46d1aecffbf0c240988283f96b73b1b3b7be2c 100644 (file)
 
 #include "gtkmm2ext/cairo_widget.h"
 #include "gtkmm2ext/gui_thread.h"
+#include "gtkmm2ext/rgb_macros.h"
+
+#ifdef __APPLE__
+#include <gdk/gdk.h>
+#include "gtkmm2ext/nsglview.h"
+#endif
 
 #include "pbd/i18n.h"
 
@@ -49,6 +55,7 @@ CairoWidget::CairoWidget ()
        , _name_proxy (this, X_("name"))
        , _current_parent (0)
        , _canvas_widget (false)
+       , _nsglview (0)
 {
        _name_proxy.connect (sigc::mem_fun (*this, &CairoWidget::on_name_changed));
 }
@@ -64,12 +71,26 @@ CairoWidget::~CairoWidget ()
 void
 CairoWidget::set_canvas_widget ()
 {
+       assert (!_nsglview);
        assert (!_canvas_widget);
        ensure_style ();
        gtk_widget_set_realized (GTK_WIDGET(gobj()), true);
        _canvas_widget = true;
 }
 
+void
+CairoWidget::use_nsglview ()
+{
+       assert (!_nsglview);
+       assert (!_canvas_widget);
+       assert (!is_realized());
+#ifdef ARDOUR_CANVAS_NSVIEW_TAG // patched gdkquartz.h
+# ifndef __ppc__ // would need to flip RGBA <> RGBA
+       _nsglview = Gtkmm2ext::nsglview_create (this);
+#endif
+#endif
+}
+
 int
 CairoWidget::get_width () const
 {
@@ -106,6 +127,16 @@ CairoWidget::on_button_press_event (GdkEventButton*)
        return false;
 }
 
+uint32_t
+CairoWidget::background_color ()
+{
+       if (_need_bg) {
+               Gdk::Color bg (get_parent_bg());
+               return RGBA_TO_UINT (bg.get_red() / 255, bg.get_green() / 255, bg.get_blue() / 255, 255);
+       } else {
+               return 0;
+       }
+}
 
 #ifdef USE_TRACKS_CODE_FEATURES
 
@@ -202,6 +233,12 @@ CairoWidget::on_expose_event (GdkEventExpose *ev)
 bool
 CairoWidget::on_expose_event (GdkEventExpose *ev)
 {
+#ifdef __APPLE__
+       if (_nsglview) {
+               Gtkmm2ext::nsglview_queue_draw (_nsglview, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+               return true;
+       }
+#endif
 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
        Cairo::RefPtr<Cairo::Context> cr;
        if (getenv("ARDOUR_IMAGE_SURFACE")) {
@@ -334,6 +371,16 @@ CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
        if (_canvas_widget) {
                return;
        }
+#ifdef __APPLE__
+       if (_nsglview) {
+               gint xx, yy;
+               gtk_widget_translate_coordinates(
+                               GTK_WIDGET(gobj()),
+                               GTK_WIDGET(get_toplevel()->gobj()),
+                               0, 0, &xx, &yy);
+               Gtkmm2ext::nsglview_resize (_nsglview, xx, yy, alloc.get_width(), alloc.get_height());
+       }
+#endif
        set_dirty ();
 }
 
@@ -414,6 +461,17 @@ CairoWidget::on_style_changed (const Glib::RefPtr<Gtk::Style>&)
        set_dirty ();
 }
 
+void
+CairoWidget::on_realize ()
+{
+       Gtk::EventBox::on_realize();
+#ifdef __APPLE__
+       if (_nsglview) {
+               Gtkmm2ext::nsglview_overlay (_nsglview, get_window()->gobj());
+       }
+#endif
+}
+
 void
 CairoWidget::on_state_changed (Gtk::StateType)
 {
index 03afc48818ba1e5c24c3b6977e42cc6d9bb70cf9..ad14c8ca2aaae8b9fe4711c2e08cc2a1434cb4a3 100644 (file)
 #include <gtkmm/eventbox.h>
 
 #include "gtkmm2ext/visibility.h"
+#include "gtkmm2ext/cairo_canvas.h"
 #include "gtkmm2ext/widget_state.h"
 
 /** A parent class for widgets that are rendered using Cairo.
  */
 
-class LIBGTKMM2EXT_API CairoWidget : public Gtk::EventBox
+class LIBGTKMM2EXT_API CairoWidget : public Gtk::EventBox, public Gtkmm2ext::CairoCanvas
 {
 public:
        CairoWidget ();
        virtual ~CairoWidget ();
 
        void set_canvas_widget ();
+       void use_nsglview ();
 
        /* swizzle Gtk::Widget methods for Canvas::Widget */
        void queue_draw ();
@@ -81,6 +83,12 @@ public:
 
        virtual void render (cairo_t *, cairo_rectangle_t*) = 0;
 
+       virtual void render (Cairo::RefPtr<Cairo::Context> const & ctx, cairo_rectangle_t* r) {
+               render (ctx->cobj(), r);
+       }
+
+       uint32_t background_color ();
+
        static void set_flat_buttons (bool yn);
        static bool flat_buttons() { return _flat_buttons; }
 
@@ -112,6 +120,7 @@ protected:
        void on_size_allocate (Gtk::Allocation &);
        void on_state_changed (Gtk::StateType);
        void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
+       void on_realize ();
        bool on_button_press_event (GdkEventButton*);
        Gdk::Color get_parent_bg ();
 
@@ -137,6 +146,7 @@ protected:
        sigc::connection _parent_style_change;
        Widget * _current_parent;
        bool _canvas_widget;
+       void* _nsglview;
        Gdk::Rectangle _allocation;
 
 };