X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fcanvas%2Fcanvas.h;h=d1521593cd8c07b5dd23edf1f2a7e4d86cba8a18;hb=30b087ab3d28f1585987fa3f6ae006562ae192e3;hp=a764e6ee8a142c8cb8048c78d99ec37ac4e69578;hpb=ef56948d4acaa55f76ca6bde3eba3faec168ffdb;p=ardour.git diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h index a764e6ee8a..d1521593cd 100644 --- a/libs/canvas/canvas/canvas.h +++ b/libs/canvas/canvas/canvas.h @@ -34,8 +34,9 @@ #include "pbd/signals.h" -#include "canvas/visibility.h" +#include "gtkmm2ext/cairo_canvas.h" +#include "canvas/visibility.h" #include "canvas/root_group.h" namespace Gtk { @@ -43,6 +44,10 @@ namespace Gtk { class Label; } +namespace Pango { + class Context; +} + namespace ArdourCanvas { struct Rect; @@ -59,7 +64,7 @@ class ScrollGroup; * of screen pixels, with an origin of (0, 0) at the top left. x increases * rightwards and y increases downwards. */ - + class LIBCANVAS_API Canvas { public: @@ -82,42 +87,48 @@ public: void render (Rect const &, Cairo::RefPtr const &) const; + void prepare_for_render (Rect const &) const; + + gint64 get_last_render_start_timestamp () const { return _last_render_start_timestamp; } + + gint64 get_microseconds_since_render_start () const; + /** @return root group */ Item* root () { return &_root; } - void set_background_color (ArdourCanvas::Color); - ArdourCanvas::Color background_color() const { return _bg_color; } + void set_background_color (Gtkmm2ext::Color); + Gtkmm2ext::Color background_color() const { return _bg_color; } /** Called when an item is being destroyed */ - virtual void item_going_away (Item *, boost::optional) {} - void item_shown_or_hidden (Item *); + virtual void item_going_away (Item *, Rect) {} + virtual void item_shown_or_hidden (Item *); void item_visual_property_changed (Item*); - void item_changed (Item *, boost::optional); - void item_moved (Item *, boost::optional); + void item_changed (Item *, Rect); + void item_moved (Item *, Rect); - Duple canvas_to_window (Duple const&, bool rounded = true) const; - Duple window_to_canvas (Duple const&) const; + Duple canvas_to_window (Duple const&, bool rounded = true) const; + Duple window_to_canvas (Duple const&) const; - void canvas_to_window (Coord cx, Coord cy, Coord& wx, Coord& wy) { + void canvas_to_window (Coord cx, Coord cy, Coord& wx, Coord& wy) { Duple d = canvas_to_window (Duple (cx, cy)); wx = d.x; wy = d.y; - } + } - void window_to_canvas (Coord wx, Coord wy, Coord& cx, Coord& cy) { + void window_to_canvas (Coord wx, Coord wy, Coord& cx, Coord& cy) { Duple d = window_to_canvas (Duple (wx, wy)); cx = d.x; cy = d.y; - } + } - void scroll_to (Coord x, Coord y); + void scroll_to (Coord x, Coord y); void add_scroller (ScrollGroup& i); - - virtual Rect visible_area () const = 0; - virtual Coord width () const = 0; - virtual Coord height () const = 0; + + virtual Rect visible_area () const = 0; + virtual Coord width () const = 0; + virtual Coord height () const = 0; /** Store the coordinates of the mouse pointer in window coordinates in @param winpos. Return true if the position was within the window, @@ -130,17 +141,19 @@ public: */ sigc::signal MouseMotion; + sigc::signal PreRender; + /** Ensures that the position given by @param winpos (in window coordinates) is within the current window area, possibly reduced by @param border. */ Duple clamp_to_window (Duple const& winpos, Duple border = Duple()); - void zoomed(); - - std::string indent() const; - std::string render_indent() const; - void dump (std::ostream&) const; + void zoomed(); + + std::string indent() const; + std::string render_indent() const; + void dump (std::ostream&) const; /** Ask the canvas to pick the current item again, and generate an enter event for it. @@ -153,25 +166,32 @@ public: /** Set the timeout used to display tooltips, in milliseconds */ static void set_tooltip_timeout (uint32_t msecs); - + + virtual Glib::RefPtr get_pango_context() = 0; + protected: - Root _root; - Color _bg_color; + Root _root; + Gtkmm2ext::Color _bg_color; + + mutable gint64 _last_render_start_timestamp; static uint32_t tooltip_timeout_msecs; void queue_draw_item_area (Item *, Rect); - virtual void pick_current_item (int state) = 0; - virtual void pick_current_item (Duple const &, int state) = 0; + virtual void pick_current_item (int state) = 0; + virtual void pick_current_item (Duple const &, int state) = 0; std::list scrollers; }; /** A canvas which renders onto a GTK EventBox */ -class LIBCANVAS_API GtkCanvas : public Canvas, public Gtk::EventBox +class LIBCANVAS_API GtkCanvas : public Canvas, public Gtk::EventBox, public Gtkmm2ext::CairoCanvas { public: GtkCanvas (); + ~GtkCanvas () { _in_dtor = true ; } + + void use_nsglview (); void request_redraw (Rect const &); void request_size (Duple); @@ -186,44 +206,71 @@ public: bool get_mouse_position (Duple& winpos) const; + void set_single_exposure (bool s) { _single_exposure = s; } + bool single_exposure () { return _single_exposure; } + void re_enter (); void start_tooltip_timeout (Item*); void stop_tooltip_timeout (); + void queue_draw (); + void queue_draw_area (int x, int y, int width, int height); + + Glib::RefPtr get_pango_context(); + + void render (Cairo::RefPtr const & ctx, cairo_rectangle_t* r) + { + ArdourCanvas::Rect rect (r->x, r->y, r->width + r->x, r->height + r->y); + Canvas::render (rect, ctx); + } + + void prepare_for_render () const; + + uint32_t background_color() { return Canvas::background_color (); } + protected: void on_size_allocate (Gtk::Allocation&); bool on_scroll_event (GdkEventScroll *); bool on_expose_event (GdkEventExpose *); + bool on_key_press_event (GdkEventKey *); + bool on_key_release_event (GdkEventKey *); bool on_button_press_event (GdkEventButton *); bool on_button_release_event (GdkEventButton* event); bool on_motion_notify_event (GdkEventMotion *); - bool on_enter_notify_event (GdkEventCrossing*); - bool on_leave_notify_event (GdkEventCrossing*); - + bool on_enter_notify_event (GdkEventCrossing*); + bool on_leave_notify_event (GdkEventCrossing*); + void on_map(); + void on_unmap(); + + void on_realize (); + bool button_handler (GdkEventButton *); bool motion_notify_handler (GdkEventMotion *); - bool deliver_event (GdkEvent *); - void deliver_enter_leave (Duple const & point, int state); - - void pick_current_item (int state); - void pick_current_item (Duple const &, int state); + bool deliver_event (GdkEvent *); + void deliver_enter_leave (Duple const & point, int state); + + void pick_current_item (int state); + void pick_current_item (Duple const &, int state); private: - void item_going_away (Item *, boost::optional); + void item_going_away (Item *, Rect); + void item_shown_or_hidden (Item *); bool send_leave_event (Item const *, double, double) const; Cairo::RefPtr canvas_image; - /** Item currently chosen for event delivery based on pointer position */ - Item * _current_item; - /** Item pending as _current_item */ - Item * _new_current_item; + /** Item currently chosen for event delivery based on pointer position */ + Item * _current_item; + /** Item pending as _current_item */ + Item * _new_current_item; /** the item that is currently grabbed, or 0 */ Item * _grabbed_item; /** the item that currently has key focus or 0 */ Item * _focused_item; + bool _single_exposure; + sigc::connection tooltip_timeout_connection; Item* current_tooltip_item; Gtk::Window* tooltip_window; @@ -231,10 +278,14 @@ private: bool show_tooltip (); void hide_tooltip (); bool really_start_tooltip_timeout (); + + bool _in_dtor; + + void* _nsglview; }; /** A GTK::Alignment with a GtkCanvas inside it plus some Gtk::Adjustments for - * scrolling. + * scrolling. * * This provides a GtkCanvas that can be scrolled. It does NOT implement the * Gtk::Scrollable interface. @@ -255,10 +306,10 @@ protected: private: /** our GtkCanvas */ GtkCanvas _canvas; - Gtk::Adjustment& hadjustment; - Gtk::Adjustment& vadjustment; + Gtk::Adjustment& hadjustment; + Gtk::Adjustment& vadjustment; - void scrolled (); + void scrolled (); }; }