big rework of scrolling, horizontal part considered almost 100% done.

Many more changes than I would typically like in a single commit, but this was all very intertwined.
Vertical scrolling using track-stepping still to follow.
This commit is contained in:
Paul Davis 2014-03-20 13:29:29 -04:00
parent 01c6266909
commit 9df3157dfc
8 changed files with 280 additions and 256 deletions

View file

@ -313,10 +313,8 @@ Editor::Editor ()
bbt_beat_subdivision = 4; bbt_beat_subdivision = 4;
_visible_canvas_width = 0; _visible_canvas_width = 0;
_visible_canvas_height = 0; _visible_canvas_height = 0;
last_autoscroll_x = 0; autoscroll_horizontal_allowed = false;
last_autoscroll_y = 0; autoscroll_vertical_allowed = false;
autoscroll_active = false;
autoscroll_timeout_tag = -1;
logo_item = 0; logo_item = 0;
analysis_window = 0; analysis_window = 0;
@ -4291,35 +4289,45 @@ Editor::idle_visual_changer ()
pending_visual_change.idle_handler_id = -1; pending_visual_change.idle_handler_id = -1;
pending_visual_change.being_handled = true; pending_visual_change.being_handled = true;
VisualChange::Type p = pending_visual_change.pending; VisualChange vc = pending_visual_change;
pending_visual_change.pending = (VisualChange::Type) 0; pending_visual_change.pending = (VisualChange::Type) 0;
visual_changer (vc);
pending_visual_change.being_handled = false;
return 0; /* this is always a one-shot call */
}
void
Editor::visual_changer (const VisualChange& vc)
{
double const last_time_origin = horizontal_position (); double const last_time_origin = horizontal_position ();
if (vc.pending & VisualChange::ZoomLevel) {
if (p & VisualChange::ZoomLevel) { set_samples_per_pixel (vc.samples_per_pixel);
set_samples_per_pixel (pending_visual_change.samples_per_pixel);
compute_fixed_ruler_scale (); compute_fixed_ruler_scale ();
ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin; ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end; ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
compute_current_bbt_points (pending_visual_change.time_origin, pending_visual_change.time_origin + current_page_samples(), compute_current_bbt_points (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
current_bbt_points_begin, current_bbt_points_end); current_bbt_points_begin, current_bbt_points_end);
compute_bbt_ruler_scale (pending_visual_change.time_origin, pending_visual_change.time_origin + current_page_samples(), compute_bbt_ruler_scale (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
current_bbt_points_begin, current_bbt_points_end); current_bbt_points_begin, current_bbt_points_end);
update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end); update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
update_video_timeline(); update_video_timeline();
} }
if (p & VisualChange::TimeOrigin) { if (vc.pending & VisualChange::TimeOrigin) {
set_horizontal_position (pending_visual_change.time_origin / samples_per_pixel); set_horizontal_position (vc.time_origin / samples_per_pixel);
} }
if (p & VisualChange::YOrigin) { if (vc.pending & VisualChange::YOrigin) {
vertical_adjustment.set_value (pending_visual_change.y_origin); vertical_adjustment.set_value (vc.y_origin);
} }
if (last_time_origin == horizontal_position ()) { if (last_time_origin == horizontal_position ()) {
@ -4328,14 +4336,11 @@ Editor::idle_visual_changer ()
redisplay_tempo (true); redisplay_tempo (true);
} }
if (!(p & VisualChange::ZoomLevel)) { if (!(vc.pending & VisualChange::ZoomLevel)) {
update_video_timeline(); update_video_timeline();
} }
_summary->set_overlays_dirty (); _summary->set_overlays_dirty ();
pending_visual_change.being_handled = false;
return 0; /* this is always a one-shot call */
} }
struct EditorOrderTimeAxisSorter { struct EditorOrderTimeAxisSorter {

View file

@ -207,7 +207,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
account any scrolling offsets. account any scrolling offsets.
*/ */
framepos_t pixel_to_sample (double pixel) const { framepos_t pixel_to_sample_from_event (double pixel) const {
/* pixel can be less than zero when motion events /* pixel can be less than zero when motion events
are processed. since we've already run the world->canvas are processed. since we've already run the world->canvas
@ -222,6 +222,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
} }
} }
framepos_t pixel_to_sample (double pixel) const {
return pixel * samples_per_pixel;
}
double sample_to_pixel (framepos_t sample) const { double sample_to_pixel (framepos_t sample) const {
return sample / samples_per_pixel; return sample / samples_per_pixel;
} }
@ -408,7 +412,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
return _drags; return _drags;
} }
void maybe_autoscroll (bool, bool, bool, bool); void maybe_autoscroll (bool, bool, bool);
bool autoscroll_active() const;
Gdk::Cursor* get_canvas_cursor () const { return current_canvas_cursor; } Gdk::Cursor* get_canvas_cursor () const { return current_canvas_cursor; }
void set_canvas_cursor (Gdk::Cursor*, bool save=false); void set_canvas_cursor (Gdk::Cursor*, bool save=false);
@ -1022,6 +1027,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
static int _idle_visual_changer (void *arg); static int _idle_visual_changer (void *arg);
int idle_visual_changer (); int idle_visual_changer ();
void visual_changer (const VisualChange&);
void ensure_visual_change_idle_handler (); void ensure_visual_change_idle_handler ();
/* track views */ /* track views */
@ -1072,8 +1078,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtkmm2ext::ActionMap editor_action_map; Gtkmm2ext::ActionMap editor_action_map;
Gtkmm2ext::Bindings key_bindings; Gtkmm2ext::Bindings key_bindings;
int ensure_cursor (framepos_t* pos);
void cut_copy (Editing::CutCopyOp); void cut_copy (Editing::CutCopyOp);
bool can_cut_copy () const; bool can_cut_copy () const;
void cut_copy_points (Editing::CutCopyOp); void cut_copy_points (Editing::CutCopyOp);
@ -1722,22 +1726,15 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
/* autoscrolling */ /* autoscrolling */
bool autoscroll_active; sigc::connection autoscroll_connection;
int autoscroll_timeout_tag; bool autoscroll_horizontal_allowed;
int autoscroll_x; bool autoscroll_vertical_allowed;
int autoscroll_y;
int last_autoscroll_x;
int last_autoscroll_y;
uint32_t autoscroll_cnt; uint32_t autoscroll_cnt;
framecnt_t autoscroll_x_distance; Gtk::Widget* autoscroll_widget;
double autoscroll_y_distance; ArdourCanvas::Rect autoscroll_boundary;
bool _autoscroll_fudging;
int autoscroll_fudge_threshold () const;
static gint _autoscroll_canvas (void *);
bool autoscroll_canvas (); bool autoscroll_canvas ();
void start_canvas_autoscroll (int x, int y); void start_canvas_autoscroll (bool allow_horiz, bool allow_vert);
void stop_canvas_autoscroll (); void stop_canvas_autoscroll ();
/* trimming */ /* trimming */

View file

@ -450,245 +450,291 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
context->drag_finish (true, false, time); context->drag_finish (true, false, time);
} }
/** If the editor window is arranged such that the edge of the trackview is right up
* against the edge of the screen, autoscroll will not work very well. In this situation,
* we start autoscrolling some distance in from the right-hand-side of the screen edge;
* this is the distance at which that happens.
*/
int
Editor::autoscroll_fudge_threshold () const
{
return current_page_samples() / 6;
}
/** @param allow_horiz true to allow horizontal autoscroll, otherwise false. /** @param allow_horiz true to allow horizontal autoscroll, otherwise false.
* *
* @param allow_vert true to allow vertical autoscroll, otherwise false. * @param allow_vert true to allow vertical autoscroll, otherwise false.
* *
* @param moving_left true if we are moving left, so we only want to autoscroll on the left of the canvas,
* otherwise false, so we only want to autoscroll on the right of the canvas.
*
* @param moving_up true if we are moving up, so we only want to autoscroll at the top of the canvas,
* otherwise false, so we only want to autoscroll at the bottom of the canvas.
*/ */
void void
Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool moving_left, bool moving_up) Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers)
{ {
if (!Config->get_autoscroll_editor ()) { if (!Config->get_autoscroll_editor ()) {
return; return;
} }
bool startit = false; if (autoscroll_boundary.empty()) {
/* Work out the distance between the right hand edge of the trackview and the edge of ArdourCanvas::Rect scrolling_boundary;
the monitor that it is on. Gtk::Allocation alloc;
if (from_headers) {
alloc = controls_layout.get_allocation ();
} else {
alloc = _track_canvas_viewport->get_allocation ();
/* Increase the autoscroll area to include the rulers.
XXX this can go away once the two canvases are
unified.
*/ */
Glib::RefPtr<Gdk::Window> gdk_window = get_window (); Gdk::Rectangle timebars = time_canvas_event_box.get_allocation ();
Gdk::Rectangle window_rect; alloc.set_y (timebars.get_y());
gdk_window->get_frame_extents (window_rect); alloc.set_height (alloc.get_height() + timebars.get_height());
Glib::RefPtr<Gdk::Screen> screen = get_screen (); /* if there is no other widget on the right side of
Gdk::Rectangle root_rect; the canvas, reduce the effective width of
screen->get_root_window()->get_frame_extents (root_rect); the autoscroll boundary so that we start scrolling
before we hit the edge.
Gtk::Allocation editor_list = _the_notebook.get_allocation (); this helps when the window is slammed up against
the right edge of the screen, making it hard to
scroll effectively.
*/
framecnt_t distance = pixel_to_sample (root_rect.get_x() + root_rect.get_width() - window_rect.get_x() - window_rect.get_width()); if (alloc.get_width() > 10) {
if (_the_notebook.is_visible ()) { alloc.set_width (alloc.get_width() - 10);
distance += pixel_to_sample (editor_list.get_width());
}
/* Note whether we're fudging the autoscroll (see autoscroll_fudge_threshold) */
_autoscroll_fudging = (distance < autoscroll_fudge_threshold ());
/* ty is in canvas-coordinate space */
double const ty = _drags->current_pointer_y();
ArdourCanvas::Rect visible = _track_canvas->visible_area();
autoscroll_y = 0;
autoscroll_x = 0;
if (ty < visible.y0 && moving_up && allow_vert) {
autoscroll_y = -1;
startit = true;
} else if (ty > visible.y1 && !moving_up && allow_vert) {
autoscroll_y = 1;
startit = true;
}
framepos_t rightmost_frame = leftmost_frame + current_page_samples();
if (_autoscroll_fudging) {
rightmost_frame -= autoscroll_fudge_threshold ();
}
if (_drags->current_pointer_frame() > rightmost_frame && allow_horiz) {
if (rightmost_frame < max_framepos && !moving_left) {
autoscroll_x = 1;
startit = true;
}
} else if (_drags->current_pointer_frame() < leftmost_frame && allow_horiz) {
if (leftmost_frame > 0 && moving_left) {
autoscroll_x = -1;
startit = true;
} }
} }
if (autoscroll_active && ((autoscroll_x != last_autoscroll_x) || (autoscroll_y != last_autoscroll_y) || (autoscroll_x == 0 && autoscroll_y == 0))) { autoscroll_boundary = ArdourCanvas::Rect (alloc.get_x(), alloc.get_y(),
stop_canvas_autoscroll (); alloc.get_x() + alloc.get_width(),
alloc.get_y() + alloc.get_height());
} }
if (startit && autoscroll_timeout_tag < 0) { int x, y;
start_canvas_autoscroll (autoscroll_x, autoscroll_y); Gdk::ModifierType mask;
}
last_autoscroll_x = autoscroll_x; get_window()->get_pointer (x, y, mask);
last_autoscroll_y = autoscroll_y;
if (!autoscroll_boundary.contains (ArdourCanvas::Duple (x, y))) {
if (!autoscroll_active()) {
start_canvas_autoscroll (allow_horiz, allow_vert);
}
}
} }
gint bool
Editor::_autoscroll_canvas (void *arg) Editor::autoscroll_active () const
{ {
return ((Editor *) arg)->autoscroll_canvas (); return autoscroll_connection.connected ();
} }
bool bool
Editor::autoscroll_canvas () Editor::autoscroll_canvas ()
{ {
framepos_t new_frame; int x, y;
framepos_t limit = max_framepos - current_page_samples(); Gdk::ModifierType mask;
double new_pixel; frameoffset_t dx = 0;
double dy = 0;
bool no_stop = false;
if (autoscroll_x_distance != 0) { get_window()->get_pointer (x, y, mask);
if (autoscroll_x > 0) { VisualChange vc;
autoscroll_x_distance = (_drags->current_pointer_frame() - (leftmost_frame + current_page_samples())) / 3;
if (_autoscroll_fudging) {
autoscroll_x_distance += autoscroll_fudge_threshold () / 3;
}
} else if (autoscroll_x < 0) {
autoscroll_x_distance = (leftmost_frame - _drags->current_pointer_frame()) / 3;
} if (autoscroll_horizontal_allowed) {
framepos_t new_frame = leftmost_frame;
/* horizontal */
if (x > autoscroll_boundary.x1) {
/* bring it back into view */
dx = x - autoscroll_boundary.x1;
dx += 10 + (2 * (autoscroll_cnt/2));
dx = pixel_to_sample (dx);
if (leftmost_frame < max_framepos - dx) {
new_frame = leftmost_frame + dx;
} else {
new_frame = max_framepos;
} }
if (autoscroll_y_distance != 0) { no_stop = true;
if (autoscroll_y > 0) {
autoscroll_y_distance = (_drags->current_pointer_y() - _visible_canvas_height) / 3;
} else if (autoscroll_y < 0) {
autoscroll_y_distance = (vertical_adjustment.get_value () - _drags->current_pointer_y()) / 3; } else if (x < autoscroll_boundary.x0) {
}
}
if (autoscroll_x < 0) { dx = autoscroll_boundary.x0 - x;
if (leftmost_frame < autoscroll_x_distance) { dx += 10 + (2 * (autoscroll_cnt/2));
dx = pixel_to_sample (dx);
if (leftmost_frame >= dx) {
new_frame = leftmost_frame - dx;
} else {
new_frame = 0; new_frame = 0;
} else {
new_frame = leftmost_frame - autoscroll_x_distance;
}
} else if (autoscroll_x > 0) {
if (leftmost_frame > limit - autoscroll_x_distance) {
new_frame = limit;
} else {
new_frame = leftmost_frame + autoscroll_x_distance;
}
} else {
new_frame = leftmost_frame;
} }
double vertical_pos = vertical_adjustment.get_value(); no_stop = true;
if (autoscroll_y < 0) {
if (vertical_pos < autoscroll_y_distance) {
new_pixel = 0;
} else {
new_pixel = vertical_pos - autoscroll_y_distance;
}
} else if (autoscroll_y > 0) {
new_pixel = min (_full_canvas_height - _visible_canvas_height, min (_full_canvas_height, (vertical_adjustment.get_value() + autoscroll_y_distance)));
} else {
new_pixel = vertical_pos;
}
if ((new_frame == 0 || new_frame == limit) && (new_pixel == 0 || new_pixel == DBL_MAX)) {
/* we are done */
return false;
} }
if (new_frame != leftmost_frame) { if (new_frame != leftmost_frame) {
reset_x_origin (new_frame); vc.time_origin = new_frame;
vc.add (VisualChange::TimeOrigin);
}
}
if (autoscroll_vertical_allowed) {
const double vertical_pos = vertical_adjustment.get_value();
double new_pixel = vertical_pos;
/* vertical */
new_pixel = vertical_pos;
if (y < autoscroll_boundary.y0) {
/* scroll to make higher tracks visible */
const int step_size = _visible_canvas_height / 100;
dy = autoscroll_boundary.y0 - y;
dy += step_size + (step_size * (autoscroll_cnt/10));
if (vertical_pos > dy) {
new_pixel = vertical_pos - dy;
} else {
new_pixel = 0;
}
no_stop = true;
} else if (y > autoscroll_boundary.y1) {
/* scroll to make lower tracks visible */
const int step_size = _visible_canvas_height / 100;
dy = y - autoscroll_boundary.y1;
dy += step_size + (step_size * (autoscroll_cnt/10));
/* unlike horizontally, we never want to scroll past the lower edge of the full canvas as defined by all visible tracks
*/
new_pixel = min (_full_canvas_height - _visible_canvas_height, min (_full_canvas_height, vertical_pos + dy));
/* adjust dy to match */
dy = vertical_pos - new_pixel;
no_stop = true;
} }
if (new_pixel != vertical_pos) { if (new_pixel != vertical_pos) {
vertical_adjustment.set_value (new_pixel); vc.add (VisualChange::YOrigin);
vc.y_origin = new_pixel;
}
} }
/* fake an event. */ if (vc.pending) {
/* change horizontal & vertical position first */
visual_changer (vc);
/* now send a motion event to notify anyone who cares
that we have moved to a new location (because we scrolled)
*/
Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->_track_canvas->get_window();
gint x, y;
Gdk::ModifierType mask;
GdkEventMotion ev; GdkEventMotion ev;
canvas_window->get_pointer (x, y, mask);
ev.type = GDK_MOTION_NOTIFY; ev.type = GDK_MOTION_NOTIFY;
ev.state = Gdk::BUTTON1_MASK; ev.state = Gdk::BUTTON1_MASK;
/* the motion handler expects events in canvas coordinate space */ /* the motion handler expects events in canvas coordinate space */
ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (x, y));
/* first convert from Editor window coordinates to canvas
* window coordinates
*/
int cx;
int cy;
/* clamp x and y to remain within the visible area */
x = min (max ((ArdourCanvas::Coord) x, autoscroll_boundary.x0), autoscroll_boundary.x1);
y = min (max ((ArdourCanvas::Coord) y, autoscroll_boundary.y0), autoscroll_boundary.y1);
translate_coordinates (*_track_canvas_viewport, x, y, cx, cy);
ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (cx, cy));
ev.x = d.x; ev.x = d.x;
ev.y = d.y; ev.y = d.y;
motion_handler (0, (GdkEvent*) &ev, true); motion_handler (0, (GdkEvent*) &ev, true);
autoscroll_cnt++; } else if (no_stop) {
if (autoscroll_cnt == 1) { /* not changing visual state but pointer is outside the scrolling boundary
* so we still need to deliver a fake motion event
*/
/* connect the timeout so that we get called repeatedly */ GdkEventMotion ev;
autoscroll_timeout_tag = g_idle_add ( _autoscroll_canvas, this); ev.type = GDK_MOTION_NOTIFY;
ev.state = Gdk::BUTTON1_MASK;
/* the motion handler expects events in canvas coordinate space */
/* first convert from Editor window coordinates to canvas
* window coordinates
*/
int cx;
int cy;
/* clamp x and y to remain within the visible area */
x = min (max ((ArdourCanvas::Coord) x, autoscroll_boundary.x0), autoscroll_boundary.x1);
y = min (max ((ArdourCanvas::Coord) y, autoscroll_boundary.y0), autoscroll_boundary.y1);
translate_coordinates (*_track_canvas_viewport, x, y, cx, cy);
ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (cx, cy));
ev.x = d.x;
ev.y = d.y;
motion_handler (0, (GdkEvent*) &ev, true);
} else {
stop_canvas_autoscroll ();
autoscroll_boundary = ArdourCanvas::Rect();
return false; return false;
} }
return true; autoscroll_cnt++;
return true; /* call me again */
} }
void void
Editor::start_canvas_autoscroll (int dx, int dy) Editor::start_canvas_autoscroll (bool allow_horiz, bool allow_vert)
{ {
if (!_session || autoscroll_active) { if (!_session) {
return; return;
} }
stop_canvas_autoscroll (); stop_canvas_autoscroll ();
autoscroll_active = true;
autoscroll_x = dx;
autoscroll_y = dy;
autoscroll_x_distance = (framepos_t) floor (current_page_samples()/50.0);
autoscroll_y_distance = fabs ((double)dy * 5); /* pixels */
autoscroll_cnt = 0; autoscroll_cnt = 0;
autoscroll_horizontal_allowed = allow_horiz;
autoscroll_vertical_allowed = allow_vert;
/* do it right now, which will start the repeated callbacks */ /* do the first scroll right now
*/
autoscroll_canvas (); autoscroll_canvas ();
/* scroll again at very very roughly 30FPS */
autoscroll_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &Editor::autoscroll_canvas), 30);
} }
void void
Editor::stop_canvas_autoscroll () Editor::stop_canvas_autoscroll ()
{ {
if (autoscroll_timeout_tag >= 0) { autoscroll_connection.disconnect ();
g_source_remove (autoscroll_timeout_tag);
autoscroll_timeout_tag = -1;
}
autoscroll_active = false;
} }
bool bool
@ -750,8 +796,6 @@ Editor::set_horizontal_position (double p)
} }
update_video_timeline(); update_video_timeline();
HorizontalPositionChanged (); /* EMIT SIGNAL */
} }
void void

View file

@ -361,16 +361,16 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
if (event->motion.state & Gdk::BUTTON1_MASK || event->motion.state & Gdk::BUTTON2_MASK) { if (event->motion.state & Gdk::BUTTON1_MASK || event->motion.state & Gdk::BUTTON2_MASK) {
if (!from_autoscroll) { if (!from_autoscroll) {
bool const moving_left = _drags->current_pointer_x() < _last_pointer_x; _editor->maybe_autoscroll (true, allow_vertical_autoscroll (), false);
bool const moving_up = _drags->current_pointer_y() < _last_pointer_y;
_editor->maybe_autoscroll (true, allow_vertical_autoscroll (), moving_left, moving_up);
} }
if (!_editor->autoscroll_active() || from_autoscroll) {
motion (event, _move_threshold_passed != old_move_threshold_passed); motion (event, _move_threshold_passed != old_move_threshold_passed);
_last_pointer_x = _drags->current_pointer_x (); _last_pointer_x = _drags->current_pointer_x ();
_last_pointer_y = _drags->current_pointer_y (); _last_pointer_y = _drags->current_pointer_y ();
_last_pointer_frame = adjusted_current_frame (event); _last_pointer_frame = adjusted_current_frame (event);
}
return true; return true;
} }

View file

@ -179,12 +179,12 @@ Editor::canvas_event_sample (GdkEvent const * event, double* pcx, double* pcy) c
*pcy = y; *pcy = y;
} }
/* note that pixel_to_sample() never returns less than zero, so even if the pixel /* note that pixel_to_sample_from_event() never returns less than zero, so even if the pixel
position is negative (as can be the case with motion events in particular), position is negative (as can be the case with motion events in particular),
the frame location is always positive. the frame location is always positive.
*/ */
return pixel_to_sample (x); return pixel_to_sample_from_event (x);
} }
Gdk::Cursor* Gdk::Cursor*

View file

@ -303,8 +303,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual void get_equivalent_regions (RegionView* rv, std::vector<RegionView*>&, PBD::PropertyID) const = 0; virtual void get_equivalent_regions (RegionView* rv, std::vector<RegionView*>&, PBD::PropertyID) const = 0;
sigc::signal<void> ZoomChanged; sigc::signal<void> ZoomChanged;
/** Emitted when the horizontal position of the editor view changes */
sigc::signal<void> HorizontalPositionChanged;
sigc::signal<void> Realized; sigc::signal<void> Realized;
sigc::signal<void,framepos_t> UpdateAllTransportClocks; sigc::signal<void,framepos_t> UpdateAllTransportClocks;
@ -382,8 +380,9 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual Gtkmm2ext::TearOff* tools_tearoff () const = 0; virtual Gtkmm2ext::TearOff* tools_tearoff () const = 0;
virtual DragManager* drags () const = 0; virtual DragManager* drags () const = 0;
virtual void maybe_autoscroll (bool, bool, bool, bool) = 0; virtual void maybe_autoscroll (bool, bool, bool from_headers) = 0;
virtual void stop_canvas_autoscroll () = 0; virtual void stop_canvas_autoscroll () = 0;
virtual bool autoscroll_active() const = 0;
virtual MouseCursors const * cursors () const = 0; virtual MouseCursors const * cursors () const = 0;
virtual VerboseCursor * verbose_cursor () const = 0; virtual VerboseCursor * verbose_cursor () const = 0;

View file

@ -370,32 +370,11 @@ TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
* are pretending that the drag is taking place over the canvas * are pretending that the drag is taking place over the canvas
* (which perhaps in the glorious future, when track headers * (which perhaps in the glorious future, when track headers
* and the canvas are unified, will actually be true.) * and the canvas are unified, will actually be true.)
*
* First, translate the event coordinates into the canvas
* coordinate space that DragManager::motion_handler is
* expecting (this requires translation into the *window*
* coordinates for the track canvas window, and then conversion
* from window to canvas coordinate spaces).
*
* Then fake a DragManager motion event so that when
* maybe_autoscroll asks DragManager for the current pointer
* position it will get the correct answers.
*/ */
int tx, ty; _editor.maybe_autoscroll (false, true, true);
controls_ebox.translate_coordinates (*_editor.get_track_canvas(), ev->x, ev->y, tx, ty);
/* x-axis of track headers is not shared with the canvas, but /* now schedule the actual TAV resize */
the y-axis is, so we we can get a valid translation here.
*/
Duple canvas_coord = _editor.get_track_canvas()->canvas()->window_to_canvas (Duple (tx, ty));
ev->y = (int) floor (canvas_coord.y);
_editor.drags()->motion_handler ((GdkEvent *) ev, false);
_editor.maybe_autoscroll (false, true, false, ev->y_root < _resize_drag_start);
/* now do the actual TAV resize */
int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start); int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
_editor.add_to_idle_resize (this, delta); _editor.add_to_idle_resize (this, delta);
_resize_drag_start = ev->y_root; _resize_drag_start = ev->y_root;

View file

@ -402,7 +402,7 @@ Curve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
context->restore (); context->restore ();
} }
#if 0 #if 1
/* add points */ /* add points */
setup_fill_context (context); setup_fill_context (context);