diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2014-06-03 15:57:56 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2014-06-03 16:13:12 -0400 |
commit | e0533e9dd7df504236892fe0d8693e7ad9a6a278 (patch) | |
tree | 43d6f88e7d8cec6acf9db9965ec6536f2349a1c0 /libs/canvas | |
parent | d4989ed9cedcfbff48f6131c595691005283a435 (diff) |
more profound changes to canvas scrolling, in particular find appropriate ScrollGroup for Canvas::{window,canvas}_to_{canvas,window}()
Diffstat (limited to 'libs/canvas')
-rw-r--r-- | libs/canvas/canvas.cc | 65 | ||||
-rw-r--r-- | libs/canvas/canvas/canvas.h | 3 | ||||
-rw-r--r-- | libs/canvas/canvas/item.h | 4 | ||||
-rw-r--r-- | libs/canvas/canvas/scroll_group.h | 3 | ||||
-rw-r--r-- | libs/canvas/item.cc | 14 | ||||
-rw-r--r-- | libs/canvas/scroll_group.cc | 26 |
6 files changed, 89 insertions, 26 deletions
diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index e6feca6416..8638344966 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -207,46 +207,63 @@ Canvas::item_changed (Item* item, boost::optional<Rect> pre_change_bounding_box) 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* sg = 0; + + for (std::list<Item*>::const_iterator i = root_children.begin(); i != root_children.end(); ++i) { + if (((sg = dynamic_cast<ScrollGroup*>(*i)) != 0) && sg->covers_window (d)) { + break; + } + } + + if (sg) { + return d.translate (sg->scroll_offset()); + } + + /* fallback to global canvas offset ... it would be nice to remove this */ + return d.translate (_scroll_offset); } Duple Canvas::canvas_to_window (Duple const & d, bool rounded) const { - Duple wd = d.translate (-_scroll_offset); + /* Find the scroll group that covers d (a canvas 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. + */ - /* Note that this intentionally almost always returns integer coordinates */ + std::list<Item*> const& root_children (_root.items()); + ScrollGroup* sg = 0; + Duple wd; - if (rounded) { - wd.x = round (wd.x); - wd.y = round (wd.y); + for (std::list<Item*>::const_iterator i = root_children.begin(); i != root_children.end(); ++i) { + if (((sg = dynamic_cast<ScrollGroup*>(*i)) != 0) && sg->covers_canvas (d)) { + break; + } } + - return wd; -} - -Rect -Canvas::window_to_canvas (Rect const & r) const -{ - return r.translate (Duple (_scroll_offset.x, _scroll_offset.y)); -} - -Rect -Canvas::canvas_to_window (Rect const & r, bool rounded) const -{ - Rect wr = r.translate (Duple (-_scroll_offset.x, -_scroll_offset.y)); + if (sg) { + wd = d.translate (-sg->scroll_offset()); + } else { + wd = d.translate (-_scroll_offset); + } /* Note that this intentionally almost always returns integer coordinates */ if (rounded) { - wr.x0 = round (wr.x0); - wr.x1 = round (wr.x1); - wr.y0 = round (wr.y0); - wr.y1 = round (wr.y1); + wd.x = round (wd.x); + wd.y = round (wd.y); } - return wr; -} + return wd; +} /** Called when an item has moved. * @param item Item that has moved. diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h index 1f801c3f00..187a773104 100644 --- a/libs/canvas/canvas/canvas.h +++ b/libs/canvas/canvas/canvas.h @@ -90,8 +90,7 @@ public: void item_moved (Item *, boost::optional<Rect>); virtual Cairo::RefPtr<Cairo::Context> context () = 0; - Rect canvas_to_window (Rect const&, bool rounded = true) const; - Rect window_to_canvas (Rect const&) const; + Duple canvas_to_window (Duple const&, bool rounded = true) const; Duple window_to_canvas (Duple const&) const; diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h index fd41ddd4c5..5483c5124c 100644 --- a/libs/canvas/canvas/item.h +++ b/libs/canvas/canvas/item.h @@ -129,6 +129,10 @@ public: return _position; } + Duple window_origin() const; + + ScrollGroup* scroll_parent() const { return _scroll_parent; } + boost::optional<Rect> bounding_box () const; Coord height() const; Coord width() const; diff --git a/libs/canvas/canvas/scroll_group.h b/libs/canvas/canvas/scroll_group.h index 2df491e93b..d33e9b9080 100644 --- a/libs/canvas/canvas/scroll_group.h +++ b/libs/canvas/canvas/scroll_group.h @@ -37,6 +37,9 @@ class LIBCANVAS_API ScrollGroup : public Group void scroll_to (Duple const& d); Duple scroll_offset() const { return _scroll_offset; } + bool covers_canvas (Duple const& d) const; + bool covers_window (Duple const& d) const; + private: ScrollSensitivity _scroll_sensitivity; Duple _scroll_offset; diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc index 3b13a12ca8..ddc05a817a 100644 --- a/libs/canvas/item.cc +++ b/libs/canvas/item.cc @@ -82,6 +82,20 @@ Item::~Item () } } +Duple +Item::window_origin () const +{ + /* This is slightly subtle. Our _position is in the coordinate space of + our parent. So to find out where that is in window coordinates, we + have to ask our parent. + */ + if (_parent) { + return _parent->item_to_window (_position); + } else { + return _parent->item_to_window (Duple (0,0)); + } +} + ArdourCanvas::Rect Item::item_to_parent (ArdourCanvas::Rect const & r) const { diff --git a/libs/canvas/scroll_group.cc b/libs/canvas/scroll_group.cc index 76bca50aee..615be8007c 100644 --- a/libs/canvas/scroll_group.cc +++ b/libs/canvas/scroll_group.cc @@ -49,3 +49,29 @@ ScrollGroup::scroll_to (Duple const& d) _scroll_offset.y = d.y; } } + +bool +ScrollGroup::covers_canvas (Duple const& d) const +{ + boost::optional<Rect> r = bounding_box (); + + if (!r) { + return false; + } + + return r->contains (d); +} + +bool +ScrollGroup::covers_window (Duple const& d) const +{ + boost::optional<Rect> r = bounding_box (); + + if (!r) { + return false; + } + + Rect w = r->translate (-_scroll_offset); + + return w.contains (d); +} |