summaryrefslogtreecommitdiff
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
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
-rw-r--r--gtk2_ardour/editor_canvas.cc12
-rw-r--r--gtk2_ardour/editor_markers.cc17
-rw-r--r--gtk2_ardour/tempo_lines.cc2
-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
11 files changed, 144 insertions, 38 deletions
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 1736da96cb..2b491e7974 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -65,10 +65,8 @@ Editor::initialize_canvas ()
{
_track_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, vertical_adjustment);
_track_canvas = _track_canvas_viewport->canvas ();
+ //_track_canvas->set_global_scroll (false);
- _time_bars_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, unused_adjustment);
- _time_bars_canvas = _time_bars_canvas_viewport->canvas ();
-
_verbose_cursor = new VerboseCursor (this);
/* on the bottom, an image */
@@ -100,7 +98,15 @@ Editor::initialize_canvas ()
CANVAS_DEBUG_NAME (time_line_group, "time line group");
_trackview_group = new ArdourCanvas::Group (_track_canvas->root());
+ //_trackview_group->set_scroll_sensitivity (ArdourCanvas::Group::ScrollSensitivity (ArdourCanvas::Group::ScrollsVertically|ArdourCanvas::Group::ScrollsHorizontally));
CANVAS_DEBUG_NAME (_trackview_group, "Canvas TrackViews");
+
+
+ /* TIME BAR CANVAS */
+
+ _time_bars_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, unused_adjustment);
+ _time_bars_canvas = _time_bars_canvas_viewport->canvas ();
+
_region_motion_group = new ArdourCanvas::Group (_trackview_group);
CANVAS_DEBUG_NAME (_region_motion_group, "Canvas Region Motion");
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index 3cf3ef83b7..371feaff58 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -1465,16 +1465,23 @@ Editor::update_punch_range_view ()
Location* tpl;
if ((_session->config.get_punch_in() || _session->config.get_punch_out()) && ((tpl = transport_punch_location()) != 0)) {
- ArdourCanvas::Rect const v = _track_canvas->visible_area ();
+ double pixel_start;
+ double pixel_end;
+
if (_session->config.get_punch_in()) {
- transport_punch_range_rect->set_x0 (sample_to_pixel (tpl->start()));
- transport_punch_range_rect->set_x1 (_session->config.get_punch_out() ? sample_to_pixel (tpl->end()) : sample_to_pixel (max_framepos));
+ pixel_start = sample_to_pixel (tpl->start());
+ } else {
+ pixel_start = 0;
+ }
+ if (_session->config.get_punch_out()) {
+ pixel_end = sample_to_pixel (tpl->end());
} else {
- transport_punch_range_rect->set_x0 (0);
- transport_punch_range_rect->set_x1 (_session->config.get_punch_out() ? sample_to_pixel (tpl->end()) : v.width ());
+ pixel_end = sample_to_pixel (max_framepos);
}
+ transport_punch_range_rect->set_x0 (pixel_start);
+ transport_punch_range_rect->set_x1 (pixel_end);
transport_punch_range_rect->show();
} else {
diff --git a/gtk2_ardour/tempo_lines.cc b/gtk2_ardour/tempo_lines.cc
index 828a4cc82b..917e141313 100644
--- a/gtk2_ardour/tempo_lines.cc
+++ b/gtk2_ardour/tempo_lines.cc
@@ -65,7 +65,7 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
const ARDOUR::TempoMap::BBTPointList::const_iterator& end)
{
ARDOUR::TempoMap::BBTPointList::const_iterator i;
- ArdourCanvas::Rect const visible = _canvas.visible_area ();
+ ArdourCanvas::Rect const visible = _group->window_to_item (_canvas.visible_area ());
double beat_density;
uint32_t beats = 0;
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) {