summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/editor_canvas.cc10
-rw-r--r--libs/canvas/canvas.cc29
-rw-r--r--libs/canvas/canvas/canvas.h6
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 */