diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2014-05-18 12:22:23 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2014-06-03 16:09:06 -0400 |
commit | 97109672c784f9b78617ed9bef72c046a55aa25c (patch) | |
tree | f41be112c548a60e0e9a3fc4f903633dae0c5882 | |
parent | ee6c483d18790a5447b95c7c71ab410d0d778132 (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.cc | 12 | ||||
-rw-r--r-- | gtk2_ardour/editor_markers.cc | 17 | ||||
-rw-r--r-- | gtk2_ardour/tempo_lines.cc | 2 | ||||
-rw-r--r-- | libs/canvas/canvas.cc | 36 | ||||
-rw-r--r-- | libs/canvas/canvas/canvas.h | 6 | ||||
-rw-r--r-- | libs/canvas/canvas/group.h | 4 | ||||
-rw-r--r-- | libs/canvas/canvas/item.h | 24 | ||||
-rw-r--r-- | libs/canvas/group.cc | 10 | ||||
-rw-r--r-- | libs/canvas/item.cc | 67 | ||||
-rw-r--r-- | libs/canvas/line.cc | 2 | ||||
-rw-r--r-- | libs/canvas/poly_line.cc | 2 |
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) { |