summaryrefslogtreecommitdiff
path: root/libs/canvas
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-06-03 15:57:56 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-06-03 16:13:12 -0400
commite0533e9dd7df504236892fe0d8693e7ad9a6a278 (patch)
tree43d6f88e7d8cec6acf9db9965ec6536f2349a1c0 /libs/canvas
parentd4989ed9cedcfbff48f6131c595691005283a435 (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.cc65
-rw-r--r--libs/canvas/canvas/canvas.h3
-rw-r--r--libs/canvas/canvas/item.h4
-rw-r--r--libs/canvas/canvas/scroll_group.h3
-rw-r--r--libs/canvas/item.cc14
-rw-r--r--libs/canvas/scroll_group.cc26
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);
+}