summaryrefslogtreecommitdiff
path: root/libs/canvas
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-05-18 12:22:23 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-06-03 16:09:06 -0400
commit97109672c784f9b78617ed9bef72c046a55aa25c (patch)
treef41be112c548a60e0e9a3fc4f903633dae0c5882 /libs/canvas
parentee6c483d18790a5447b95c7c71ab410d0d778132 (diff)
initial redesign of canvas scrolling to facilitate independent x- and y-axis scrolling of specific groups within the canvas.
This commit should cause no change in behaviour, but contains all the code and changes necessary for the next step
Diffstat (limited to 'libs/canvas')
-rw-r--r--libs/canvas/canvas.cc36
-rw-r--r--libs/canvas/canvas/canvas.h6
-rw-r--r--libs/canvas/canvas/group.h4
-rw-r--r--libs/canvas/canvas/item.h24
-rw-r--r--libs/canvas/group.cc10
-rw-r--r--libs/canvas/item.cc67
-rw-r--r--libs/canvas/line.cc2
-rw-r--r--libs/canvas/poly_line.cc2
8 files changed, 122 insertions, 29 deletions
diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc
index ceaa366c35..8d4c1b8858 100644
--- a/libs/canvas/canvas.cc
+++ b/libs/canvas/canvas.cc
@@ -40,8 +40,7 @@ using namespace ArdourCanvas;
/** Construct a new Canvas */
Canvas::Canvas ()
: _root (this)
- , _scroll_offset_x (0)
- , _scroll_offset_y (0)
+ , _global_scroll (true)
{
set_epoch ();
}
@@ -49,13 +48,24 @@ Canvas::Canvas ()
void
Canvas::scroll_to (Coord x, Coord y)
{
- _scroll_offset_x = x;
- _scroll_offset_y = y;
+ Duple d (x, y);
+
+ if (_global_scroll) {
+ _scroll_offset = d;
+ }
+
+ //_root.scroll_to (d);
pick_current_item (0); // no current mouse position
}
void
+Canvas::set_global_scroll (bool yn)
+{
+ _global_scroll = yn;
+}
+
+void
Canvas::zoomed ()
{
pick_current_item (0); // no current mouse position
@@ -71,9 +81,9 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
#ifdef CANVAS_DEBUG
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
cerr << this << " RENDER: " << area << endl;
- //cerr << "CANVAS @ " << this << endl;
- //dump (cerr);
- //cerr << "-------------------------\n";
+ cerr << "CANVAS @ " << this << endl;
+ dump (cerr);
+ cerr << "-------------------------\n";
}
#endif
@@ -189,13 +199,13 @@ Canvas::item_changed (Item* item, boost::optional<Rect> pre_change_bounding_box)
Duple
Canvas::window_to_canvas (Duple const & d) const
{
- return d.translate (Duple (_scroll_offset_x, _scroll_offset_y));
+ return d.translate (Duple (_scroll_offset.x, _scroll_offset.y));
}
Duple
Canvas::canvas_to_window (Duple const & d, bool rounded) const
{
- Duple wd = d.translate (Duple (-_scroll_offset_x, -_scroll_offset_y));
+ Duple wd = d.translate (Duple (-_scroll_offset.x, -_scroll_offset.y));
/* Note that this intentionally almost always returns integer coordinates */
if (rounded) {
@@ -209,13 +219,13 @@ Canvas::canvas_to_window (Duple const & d, bool rounded) const
Rect
Canvas::window_to_canvas (Rect const & r) const
{
- return r.translate (Duple (_scroll_offset_x, _scroll_offset_y));
+ 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));
+ Rect wr = r.translate (Duple (-_scroll_offset.x, -_scroll_offset.y));
/* Note that this intentionally almost always returns integer coordinates */
@@ -802,8 +812,8 @@ GtkCanvas::unfocus (Item* item)
Rect
GtkCanvas::visible_area () const
{
- Distance const xo = _scroll_offset_x;
- Distance const yo = _scroll_offset_y;
+ Distance const xo = _scroll_offset.x;
+ Distance const yo = _scroll_offset.y;
return Rect (xo, yo, xo + get_allocation().get_width (), yo + get_allocation().get_height ());
}
diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h
index b15c2f4d54..1e2a567d58 100644
--- a/libs/canvas/canvas/canvas.h
+++ b/libs/canvas/canvas/canvas.h
@@ -108,6 +108,8 @@ public:
}
void scroll_to (Coord x, Coord y);
+ void set_global_scroll (bool);
+
virtual Rect visible_area () const = 0;
void zoomed();
@@ -122,8 +124,8 @@ protected:
/** our root group */
RootGroup _root;
- Coord _scroll_offset_x;
- Coord _scroll_offset_y;
+ Duple _scroll_offset;
+ bool _global_scroll;
virtual void pick_current_item (int state) = 0;
virtual void pick_current_item (Duple const &, int state) = 0;
diff --git a/libs/canvas/canvas/group.h b/libs/canvas/canvas/group.h
index 94aabfded6..a9150e7d09 100644
--- a/libs/canvas/canvas/group.h
+++ b/libs/canvas/canvas/group.h
@@ -51,7 +51,9 @@ public:
void raise_child (Item *, int);
void lower_child_to_bottom (Item *);
void child_changed ();
-
+
+ void scroll_to (Duple const& d);
+
void add_items_at_point (Duple, std::vector<Item const *> &) const;
void dump (std::ostream&) const;
diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h
index d7d4ba7254..429df33894 100644
--- a/libs/canvas/canvas/item.h
+++ b/libs/canvas/canvas/item.h
@@ -112,6 +112,17 @@ public:
void set_y_position (Coord);
void move (Duple);
+ enum ScrollSensitivity {
+ ScrollsVertically = 0x1,
+ ScrollsHorizontally = 0x2
+ };
+
+ void set_scroll_sensitivity (ScrollSensitivity s);
+ ScrollSensitivity scroll_sensitivity () const { return _scroll_sensitivity; }
+
+ virtual void scroll_to (Duple const& d);
+ Duple scroll_offset() const { return _scroll_offset; }
+
/** @return Position of this item in the parent's coordinates */
Duple position () const {
return _position;
@@ -125,21 +136,18 @@ public:
Rect item_to_parent (Rect const &) const;
Duple parent_to_item (Duple const &) const;
Rect parent_to_item (Rect const &) const;
- /* XXX: it's a pity these aren't the same form as item_to_parent etc.,
+
+ /* XXX: it's a pity these two aren't the same form as item_to_parent etc.,
but it makes a bit of a mess in the rest of the code if they are not.
*/
-
void canvas_to_item (Coord &, Coord &) const;
- Duple canvas_to_item (Duple const &) const;
void item_to_canvas (Coord &, Coord &) const;
- Rect item_to_canvas (Rect const &) const;
- Rect canvas_to_item (Rect const &) const;
- Duple item_to_canvas (Duple const &) const;
Duple item_to_window (Duple const&, bool rounded = true) const;
Duple window_to_item (Duple const&) const;
Rect item_to_window (Rect const&) const;
-
+ Rect window_to_item (Rect const&) const;
+
void raise_to_top ();
void raise (int);
void lower_to_bottom ();
@@ -240,6 +248,8 @@ private:
void init ();
bool _ignore_events;
+ ScrollSensitivity _scroll_sensitivity;
+ Duple _scroll_offset;
};
extern LIBCANVAS_API std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);
diff --git a/libs/canvas/group.cc b/libs/canvas/group.cc
index fbe252a17c..b6df3dfee6 100644
--- a/libs/canvas/group.cc
+++ b/libs/canvas/group.cc
@@ -148,6 +148,16 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
}
void
+Group::scroll_to (Duple const& d)
+{
+ Item::scroll_to (d);
+
+ for (list<Item*>::iterator i = _items.begin(); i != _items.end(); ) {
+ (*i)->scroll_to (d);
+ }
+}
+
+void
Group::compute_bounding_box () const
{
Rect bbox;
diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc
index 674daa4275..7a55e9604f 100644
--- a/libs/canvas/item.cc
+++ b/libs/canvas/item.cc
@@ -35,6 +35,7 @@ using namespace ArdourCanvas;
Item::Item (Canvas* canvas)
: _canvas (canvas)
, _parent (0)
+ , _scroll_sensitivity (ScrollSensitivity (0))
{
init ();
}
@@ -42,6 +43,7 @@ Item::Item (Canvas* canvas)
Item::Item (Group* parent)
: _canvas (parent->canvas ())
, _parent (parent)
+ , _scroll_sensitivity (ScrollSensitivity (0))
{
init ();
}
@@ -50,6 +52,7 @@ Item::Item (Group* parent, Duple position)
: _canvas (parent->canvas())
, _parent (parent)
, _position (position)
+ , _scroll_sensitivity (ScrollSensitivity (0))
{
init ();
}
@@ -79,6 +82,24 @@ Item::~Item ()
}
}
+void
+Item::scroll_to (Duple const& d)
+{
+ if (_scroll_sensitivity & ScrollsVertically) {
+ _scroll_offset.y = d.y;
+ }
+
+ if (_scroll_sensitivity & ScrollsHorizontally) {
+ _scroll_offset.x = d.x;
+ }
+}
+
+void
+Item::set_scroll_sensitivity (ScrollSensitivity s)
+{
+ _scroll_sensitivity = s;
+}
+
ArdourCanvas::Rect
Item::item_to_parent (ArdourCanvas::Rect const & r) const
{
@@ -162,19 +183,57 @@ Item::canvas_to_item (Coord& x, Coord& y) const
Duple
Item::item_to_window (ArdourCanvas::Duple const & d, bool rounded) const
{
- return _canvas->canvas_to_window (item_to_canvas (d), rounded);
+ Item const * i = this;
+ Duple offset;
+
+ while (i) {
+ offset = offset.translate (i->scroll_offset());
+ i = i->parent();
+ }
+
+ return _canvas->canvas_to_window (d.translate (offset), rounded);
}
Duple
Item::window_to_item (ArdourCanvas::Duple const & d) const
{
- return _canvas->window_to_canvas (canvas_to_item (d));
+ Item const * i = this;
+ Duple offset;
+
+ while (i) {
+ offset = offset.translate (-i->scroll_offset());
+ i = i->parent();
+ }
+
+ return _canvas->window_to_canvas (d.translate (offset));
}
ArdourCanvas::Rect
Item::item_to_window (ArdourCanvas::Rect const & r) const
{
- return _canvas->canvas_to_window (item_to_canvas (r));
+ Item const * i = this;
+ Duple offset;
+
+ while (i) {
+ offset = offset.translate (i->scroll_offset());
+ i = i->parent();
+ }
+
+ return _canvas->canvas_to_window (item_to_canvas (r.translate (offset)));
+}
+
+ArdourCanvas::Rect
+Item::window_to_item (ArdourCanvas::Rect const & r) const
+{
+ Item const * i = this;
+ Duple offset;
+
+ while (i) {
+ offset = offset.translate (-i->scroll_offset());
+ i = i->parent();
+ }
+
+ return canvas_to_item (_canvas->window_to_canvas (r).translate (offset));
}
/** Set the position of this item in the parent's coordinates */
@@ -517,7 +576,7 @@ Item::dump (ostream& o) const
boost::optional<ArdourCanvas::Rect> bb = bounding_box();
o << _canvas->indent() << whatami() << ' ' << this << " Visible ? " << _visible;
- o << " @ " << position();
+ o << " @ " << position() << " scrolled-to " << _scroll_offset;
#ifdef CANVAS_DEBUG
if (!name.empty()) {
diff --git a/libs/canvas/line.cc b/libs/canvas/line.cc
index 8f04e2b278..33ec41fc3d 100644
--- a/libs/canvas/line.cc
+++ b/libs/canvas/line.cc
@@ -180,7 +180,7 @@ Line::covers (Duple const & point) const
double t;
Duple a (_points[0]);
Duple b (_points[1]);
- const Rect visible (_canvas->visible_area());
+ const Rect visible (window_to_item (_canvas->visible_area()));
/*
Clamp the line endpoints to the visible area of the canvas. If we do
diff --git a/libs/canvas/poly_line.cc b/libs/canvas/poly_line.cc
index ae6d15a8fd..f8a847c3b6 100644
--- a/libs/canvas/poly_line.cc
+++ b/libs/canvas/poly_line.cc
@@ -59,7 +59,7 @@ PolyLine::covers (Duple const & point) const
/* repeat for each line segment */
- const Rect visible (_canvas->visible_area());
+ const Rect visible (window_to_item (_canvas->visible_area()));
for (i = 1, j = 0; i < npoints; ++i, ++j) {