From c9f890bd7c3377d86030e98f002d85acd66f0997 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 21 May 2014 10:25:28 -0400 Subject: avoid recursing through the entire canvas when scrolling - only scroll explicitly identified ScrollGroups --- libs/canvas/canvas.cc | 29 ++++++++++++++++++++++------- libs/canvas/canvas/canvas.h | 6 ++++-- 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'libs/canvas') 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::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 bounding_box) _focused_item = 0; } + ScrollGroup* sg = dynamic_cast(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 scrollers; }; /** A canvas which renders onto a GTK EventBox */ -- cgit v1.2.3