mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-13 10:06:33 +01:00
avoid recursing through the entire canvas when scrolling - only scroll explicitly identified ScrollGroups
This commit is contained in:
parent
a551181842
commit
c9f890bd7c
3 changed files with 32 additions and 13 deletions
|
|
@ -66,12 +66,14 @@ Editor::initialize_canvas ()
|
||||||
{
|
{
|
||||||
_track_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, vertical_adjustment);
|
_track_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, vertical_adjustment);
|
||||||
_track_canvas = _track_canvas_viewport->canvas ();
|
_track_canvas = _track_canvas_viewport->canvas ();
|
||||||
_track_canvas->set_global_scroll (false);
|
|
||||||
|
|
||||||
hv_scroll_group = new ArdourCanvas::ScrollGroup (_track_canvas->root(),
|
ArdourCanvas::ScrollGroup* hsg;
|
||||||
ArdourCanvas::ScrollGroup::ScrollSensitivity (ArdourCanvas::ScrollGroup::ScrollsVertically|
|
|
||||||
ArdourCanvas::ScrollGroup::ScrollsHorizontally));
|
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");
|
CANVAS_DEBUG_NAME (hv_scroll_group, "canvas hv scroll");
|
||||||
|
_track_canvas->add_scroller (*hsg);
|
||||||
|
|
||||||
_verbose_cursor = new VerboseCursor (this);
|
_verbose_cursor = new VerboseCursor (this);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include "canvas/canvas.h"
|
#include "canvas/canvas.h"
|
||||||
#include "canvas/debug.h"
|
#include "canvas/debug.h"
|
||||||
#include "canvas/line.h"
|
#include "canvas/line.h"
|
||||||
|
#include "canvas/scroll_group.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ArdourCanvas;
|
using namespace ArdourCanvas;
|
||||||
|
|
@ -40,7 +41,6 @@ using namespace ArdourCanvas;
|
||||||
/** Construct a new Canvas */
|
/** Construct a new Canvas */
|
||||||
Canvas::Canvas ()
|
Canvas::Canvas ()
|
||||||
: _root (this)
|
: _root (this)
|
||||||
, _global_scroll (true)
|
|
||||||
{
|
{
|
||||||
set_epoch ();
|
set_epoch ();
|
||||||
}
|
}
|
||||||
|
|
@ -48,19 +48,29 @@ Canvas::Canvas ()
|
||||||
void
|
void
|
||||||
Canvas::scroll_to (Coord x, Coord y)
|
Canvas::scroll_to (Coord x, Coord y)
|
||||||
{
|
{
|
||||||
Duple d (x, y);
|
_scroll_offset = Duple (x, y);
|
||||||
|
|
||||||
_scroll_offset = d;
|
/* 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
|
pick_current_item (0); // no current mouse position
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Canvas::set_global_scroll (bool yn)
|
Canvas::add_scroller (ScrollGroup& i)
|
||||||
{
|
{
|
||||||
_global_scroll = yn;
|
scrollers.push_back (&i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -602,6 +612,11 @@ GtkCanvas::item_going_away (Item* item, boost::optional<Rect> bounding_box)
|
||||||
_focused_item = 0;
|
_focused_item = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScrollGroup* sg = dynamic_cast<ScrollGroup*>(item);
|
||||||
|
if (sg) {
|
||||||
|
scrollers.remove (sg);
|
||||||
|
}
|
||||||
|
|
||||||
if (_current_item == item) {
|
if (_current_item == item) {
|
||||||
/* no need to send a leave event to this item, since it is going away
|
/* no need to send a leave event to this item, since it is going away
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ namespace ArdourCanvas
|
||||||
|
|
||||||
class Rect;
|
class Rect;
|
||||||
class Group;
|
class Group;
|
||||||
|
class ScrollGroup;
|
||||||
|
|
||||||
/** The base class for our different types of canvas.
|
/** The base class for our different types of canvas.
|
||||||
*
|
*
|
||||||
|
|
@ -108,7 +109,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_to (Coord x, Coord y);
|
void scroll_to (Coord x, Coord y);
|
||||||
void set_global_scroll (bool);
|
void add_scroller (ScrollGroup& i);
|
||||||
|
|
||||||
virtual Rect visible_area () const = 0;
|
virtual Rect visible_area () const = 0;
|
||||||
|
|
||||||
|
|
@ -125,10 +126,11 @@ protected:
|
||||||
RootGroup _root;
|
RootGroup _root;
|
||||||
|
|
||||||
Duple _scroll_offset;
|
Duple _scroll_offset;
|
||||||
bool _global_scroll;
|
|
||||||
|
|
||||||
virtual void pick_current_item (int state) = 0;
|
virtual void pick_current_item (int state) = 0;
|
||||||
virtual void pick_current_item (Duple const &, 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 */
|
/** A canvas which renders onto a GTK EventBox */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue