diff options
-rw-r--r-- | gtk2_ardour/editor_canvas.cc | 10 | ||||
-rw-r--r-- | libs/canvas/canvas.cc | 29 | ||||
-rw-r--r-- | libs/canvas/canvas/canvas.h | 6 |
3 files changed, 32 insertions, 13 deletions
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 0c08af5c11..eaf9c25598 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -66,12 +66,14 @@ 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); - hv_scroll_group = new ArdourCanvas::ScrollGroup (_track_canvas->root(), - ArdourCanvas::ScrollGroup::ScrollSensitivity (ArdourCanvas::ScrollGroup::ScrollsVertically| - ArdourCanvas::ScrollGroup::ScrollsHorizontally)); + ArdourCanvas::ScrollGroup* hsg; + + hv_scroll_group = hsg = new ArdourCanvas::ScrollGroup (_track_canvas->root(), + ArdourCanvas::ScrollGroup::ScrollSensitivity (ArdourCanvas::ScrollGroup::ScrollsVertically| + ArdourCanvas::ScrollGroup::ScrollsHorizontally)); CANVAS_DEBUG_NAME (hv_scroll_group, "canvas hv scroll"); + _track_canvas->add_scroller (*hsg); _verbose_cursor = new VerboseCursor (this); diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index aad614d906..f29bdba72c 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -33,6 +33,7 @@ #include "canvas/canvas.h" #include "canvas/debug.h" #include "canvas/line.h" +#include "canvas/scroll_group.h" using namespace std; using namespace ArdourCanvas; @@ -40,7 +41,6 @@ using namespace ArdourCanvas; /** Construct a new Canvas */ Canvas::Canvas () : _root (this) - , _global_scroll (true) { set_epoch (); } @@ -48,19 +48,29 @@ Canvas::Canvas () void Canvas::scroll_to (Coord x, Coord y) { - Duple d (x, y); - - _scroll_offset = d; + _scroll_offset = Duple (x, y); + + /* We do things this way because we do not want to recurse through + the canvas for every scroll. In the presence of large MIDI + tracks this means traversing item lists that include + thousands of items (notes). - _root.scroll_to (d); + This design limits us to moving only those items (groups, typically) + that should move in certain ways as we scroll. In other terms, it + becomes O(1) rather than O(N). + */ + + for (list<ScrollGroup*>::iterator i = scrollers.begin(); i != scrollers.end(); ++i) { + (*i)->scroll_to (_scroll_offset); + } pick_current_item (0); // no current mouse position } void -Canvas::set_global_scroll (bool yn) +Canvas::add_scroller (ScrollGroup& i) { - _global_scroll = yn; + scrollers.push_back (&i); } void @@ -602,6 +612,11 @@ GtkCanvas::item_going_away (Item* item, boost::optional<Rect> bounding_box) _focused_item = 0; } + ScrollGroup* sg = dynamic_cast<ScrollGroup*>(item); + if (sg) { + scrollers.remove (sg); + } + if (_current_item == item) { /* no need to send a leave event to this item, since it is going away */ diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h index 1e2a567d58..3f7d6fd519 100644 --- a/libs/canvas/canvas/canvas.h +++ b/libs/canvas/canvas/canvas.h @@ -43,6 +43,7 @@ namespace ArdourCanvas class Rect; class Group; +class ScrollGroup; /** The base class for our different types of canvas. * @@ -108,7 +109,7 @@ public: } void scroll_to (Coord x, Coord y); - void set_global_scroll (bool); + void add_scroller (ScrollGroup& i); virtual Rect visible_area () const = 0; @@ -125,10 +126,11 @@ protected: RootGroup _root; Duple _scroll_offset; - bool _global_scroll; virtual void pick_current_item (int state) = 0; virtual void pick_current_item (Duple const &, int state) = 0; + + std::list<ScrollGroup*> scrollers; }; /** A canvas which renders onto a GTK EventBox */ |