summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-06-18 10:24:59 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-06-18 10:24:59 -0400
commitbecf857f48dd021307fca75082d29b95b4ffd539 (patch)
treefe37e5e7834ac36bf77e92438e6046873ae26a2d
parent47efeb9f21c936cf2767ea3099e3fe711ff80334 (diff)
a whole slew of changes related to centralizing and rationalizing cursor management.
Debugging output left in place to help address the reports that will come in as people test this more
-rw-r--r--gtk2_ardour/audio_region_view.cc4
-rw-r--r--gtk2_ardour/editor.cc19
-rw-r--r--gtk2_ardour/editor.h18
-rw-r--r--gtk2_ardour/editor_canvas.cc369
-rw-r--r--gtk2_ardour/editor_canvas_events.cc51
-rw-r--r--gtk2_ardour/editor_items.h1
-rw-r--r--gtk2_ardour/editor_mouse.cc518
-rw-r--r--gtk2_ardour/enums.cc1
-rw-r--r--gtk2_ardour/public_editor.h1
-rw-r--r--gtk2_ardour/time_axis_view_item.h1
-rw-r--r--libs/canvas/canvas.cc1
11 files changed, 497 insertions, 487 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 9c21a9403d..38dcc5c386 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -407,7 +407,7 @@ AudioRegionView::reset_width_dependent_items (double pixel_width)
RegionView::reset_width_dependent_items(pixel_width);
assert(_pixel_width == pixel_width);
- if (pixel_width <= 6.0 || _height < 5.0 || !trackview.session()->config.get_show_region_fades()) {
+ if (pixel_width <= 20.0 || _height < 5.0 || !trackview.session()->config.get_show_region_fades()) {
if (fade_in_handle) { fade_in_handle->hide(); }
if (fade_out_handle) { fade_out_handle->hide(); }
if (fade_in_trim_handle) { fade_in_trim_handle->hide(); }
@@ -1144,6 +1144,8 @@ AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/)
wave->set_samples_per_pixel (samples_per_pixel);
wave->set_show_zero_line (true);
wave->set_clip_level (Config->get_waveform_clip_level ());
+
+ wave->Event.connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_wave_view_event), wave, this));
switch (Config->get_waveform_shape()) {
case Rectified:
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 638c000d2e..e0e11e3f49 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -743,7 +743,6 @@ Editor::Editor ()
_popup_region_menu_item = 0;
_show_marker_lines = false;
- _over_region_trim_target = false;
/* Button bindings */
@@ -794,7 +793,7 @@ Editor::add_toplevel_controls (Container& cont)
bool
Editor::get_smart_mode () const
{
- return ( (current_mouse_mode() == Editing::MouseObject) && smart_mode_action->get_active() );
+ return ((current_mouse_mode() == Editing::MouseObject) && smart_mode_action->get_active());
}
void
@@ -819,8 +818,6 @@ Editor::catch_vanishing_regionview (RegionView *rv)
if (!_all_region_actions_sensitized) {
sensitize_all_region_actions (true);
}
-
- _over_region_trim_target = false;
}
void
@@ -834,7 +831,9 @@ Editor::set_entered_regionview (RegionView* rv)
entered_regionview->exited ();
}
- if ((entered_regionview = rv) != 0) {
+ entered_regionview = rv;
+
+ if (entered_regionview != 0) {
entered_regionview->entered (internal_editing ());
}
@@ -853,7 +852,9 @@ Editor::set_entered_track (TimeAxisView* tav)
entered_track->exited ();
}
- if ((entered_track = tav) != 0) {
+ entered_track = tav;
+
+ if (entered_track) {
entered_track->entered ();
}
}
@@ -2010,7 +2011,7 @@ Editor::set_edit_point_preference (EditPoint ep, bool force)
edit_point_selector.set_text (str);
}
- set_canvas_cursor ();
+ reset_canvas_cursor ();
if (!force && !changed) {
return;
@@ -2416,7 +2417,7 @@ Editor::get_state ()
* in stacked or expanded region display mode, otherwise 0.
*/
std::pair<TimeAxisView *, double>
-Editor::trackview_by_y_position (double y, bool trackview_relative_offset)
+Editor::trackview_by_y_position (double y, bool trackview_relative_offset) const
{
if (!trackview_relative_offset) {
y -= _trackview_group->canvas_origin().y;
@@ -2426,7 +2427,7 @@ Editor::trackview_by_y_position (double y, bool trackview_relative_offset)
return std::make_pair ( (TimeAxisView *) 0, 0);
}
- for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+ for (TrackViewList::const_iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
std::pair<TimeAxisView*, double> const r = (*iter)->covers_y_position (y);
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 9e78181dcf..6606f26b93 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -535,7 +535,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
JoinObjectRangeState _join_object_range_state;
- void update_join_object_range_location (double, double);
+ void update_join_object_range_location (double);
boost::optional<int> pre_notebook_shrink_pane_width;
@@ -703,8 +703,12 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
std::stack<Gdk::Cursor*> _cursor_stack;
Gdk::Cursor* current_canvas_cursor;
- Gdk::Cursor* which_grabber_cursor ();
- void set_canvas_cursor ();
+ Gdk::Cursor* which_grabber_cursor () const;
+ Gdk::Cursor* which_region_cursor () const;
+ Gdk::Cursor* which_mode_cursor () const;
+ Gdk::Cursor* which_trim_cursor (bool left_side) const;
+ bool reset_canvas_cursor ();
+ void choose_canvas_cursor_on_entry (GdkEventCrossing*, ItemType);
ArdourCanvas::GtkCanvas* _track_canvas;
ArdourCanvas::GtkCanvasViewport* _track_canvas_viewport;
@@ -1041,7 +1045,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
/* track views */
TrackViewList track_views;
- std::pair<TimeAxisView*, double> trackview_by_y_position (double, bool trackview_relative_offset = true);
+ std::pair<TimeAxisView*, double> trackview_by_y_position (double, bool trackview_relative_offset = true) const;
RouteTimeAxisView* axis_view_from_route (boost::shared_ptr<ARDOUR::Route>) const;
TrackViewList get_tracks_for_range_action () const;
@@ -1402,6 +1406,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
bool canvas_fade_out_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*, bool trim = false);
bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
+ bool canvas_wave_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
bool canvas_frame_handle_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
@@ -1439,9 +1444,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
friend class EditorRouteGroups;
friend class EditorRegions;
- /** true if the mouse is over a place where region trim can happen */
- bool _over_region_trim_target;
-
/* non-public event handlers */
bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*);
@@ -2059,8 +2061,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtk::MenuItem& action_menu_item (std::string const &);
void action_pre_activated (Glib::RefPtr<Gtk::Action> const &);
- void set_canvas_cursor_for_region_view (double, RegionView *);
-
MouseCursors* _cursors;
void follow_mixer_selection ();
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 8ad2abdfad..73bc7d1884 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -35,6 +35,7 @@
#include "canvas/debug.h"
#include "ardour_ui.h"
+#include "automation_time_axis.h"
#include "editor.h"
#include "global_signals.h"
#include "editing.h"
@@ -926,6 +927,52 @@ Editor::horizontal_position () const
return sample_to_pixel (leftmost_frame);
}
+bool
+Editor::track_canvas_key_press (GdkEventKey*)
+{
+ /* XXX: event does not report the modifier key pressed down, AFAICS, so use the Keyboard object instead */
+ if (mouse_mode == Editing::MouseZoom && Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
+ set_canvas_cursor (_cursors->zoom_out, true);
+ }
+
+ return false;
+}
+
+bool
+Editor::track_canvas_key_release (GdkEventKey*)
+{
+ if (mouse_mode == Editing::MouseZoom && !Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
+ set_canvas_cursor (_cursors->zoom_in, true);
+ }
+
+ return false;
+}
+
+double
+Editor::clamp_verbose_cursor_x (double x)
+{
+ if (x < 0) {
+ x = 0;
+ } else {
+ x = min (_visible_canvas_width - 200.0, x);
+ }
+ return x;
+}
+
+double
+Editor::clamp_verbose_cursor_y (double y)
+{
+ y = max (0.0, y);
+ y = min (_visible_canvas_height - 50, y);
+ return y;
+}
+
+ArdourCanvas::GtkCanvasViewport*
+Editor::get_track_canvas() const
+{
+ return _track_canvas_viewport;
+}
+
void
Editor::set_canvas_cursor (Gdk::Cursor* cursor, bool save)
{
@@ -959,48 +1006,318 @@ Editor::pop_canvas_cursor ()
}
}
-bool
-Editor::track_canvas_key_press (GdkEventKey*)
+Gdk::Cursor*
+Editor::which_grabber_cursor () const
{
- /* XXX: event does not report the modifier key pressed down, AFAICS, so use the Keyboard object instead */
- if (mouse_mode == Editing::MouseZoom && Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
- set_canvas_cursor (_cursors->zoom_out, true);
+ Gdk::Cursor* c = _cursors->grabber;
+
+ if (_internal_editing) {
+ switch (mouse_mode) {
+ case MouseDraw:
+ c = _cursors->midi_pencil;
+ break;
+
+ case MouseObject:
+ c = _cursors->grabber_note;
+ break;
+
+ case MouseTimeFX:
+ c = _cursors->midi_resize;
+ break;
+
+ case MouseRange:
+ c = _cursors->grabber_note;
+ break;
+
+ default:
+ break;
+ }
+
+ } else {
+
+ switch (_edit_point) {
+ case EditAtMouse:
+ c = _cursors->grabber_edit_point;
+ break;
+ default:
+ boost::shared_ptr<Movable> m = _movable.lock();
+ if (m && m->locked()) {
+ c = _cursors->speaker;
+ }
+ break;
+ }
}
- return false;
+ return c;
}
-bool
-Editor::track_canvas_key_release (GdkEventKey*)
+Gdk::Cursor*
+Editor::which_trim_cursor (bool left) const
{
- if (mouse_mode == Editing::MouseZoom && !Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
- set_canvas_cursor (_cursors->zoom_in, true);
+ if (!entered_regionview) {
+ return 0;
}
- return false;
+ Trimmable::CanTrim ct = entered_regionview->region()->can_trim ();
+
+ if (left) {
+
+ if (ct & Trimmable::FrontTrimEarlier) {
+ return _cursors->left_side_trim;
+ } else {
+ return _cursors->left_side_trim_right_only;
+ }
+ } else {
+ if (ct & Trimmable::EndTrimLater) {
+ return _cursors->right_side_trim;
+ } else {
+ return _cursors->right_side_trim_left_only;
+ }
+ }
}
-double
-Editor::clamp_verbose_cursor_x (double x)
+Gdk::Cursor*
+Editor::which_mode_cursor () const
{
- if (x < 0) {
- x = 0;
- } else {
- x = min (_visible_canvas_width - 200.0, x);
+ Gdk::Cursor* mode_cursor = 0;
+
+ switch (mouse_mode) {
+ case MouseRange:
+ mode_cursor = _cursors->selector;
+ if (_internal_editing) {
+ mode_cursor = which_grabber_cursor();
+ }
+ break;
+
+ case MouseObject:
+ /* don't use mode cursor, pick a grabber cursor based on the item */
+ break;
+
+ case MouseDraw:
+ mode_cursor = _cursors->midi_pencil;
+ break;
+
+ case MouseGain:
+ mode_cursor = _cursors->cross_hair;
+ break;
+
+ case MouseZoom:
+ if (Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
+ mode_cursor = _cursors->zoom_out;
+ } else {
+ mode_cursor = _cursors->zoom_in;
+ }
+ break;
+
+ case MouseTimeFX:
+ mode_cursor = _cursors->time_fx; // just use playhead
+ break;
+
+ case MouseAudition:
+ mode_cursor = _cursors->speaker;
+ break;
}
- return x;
+
+ /* up-down cursor as a cue that automation can be dragged up and down when in join object/range mode */
+ if (!_internal_editing && get_smart_mode() ) {
+
+ double x, y;
+ get_pointer_position (x, y);
+
+ if (x >= 0 && y >= 0) {
+
+ vector<ArdourCanvas::Item const *> items;
+
+ /* Note how we choose a specific scroll group to get
+ * items from. This could be problematic.
+ */
+
+ hv_scroll_group->add_items_at_point (ArdourCanvas::Duple (x,y), items);
+
+ // first item will be the upper most
+
+ if (!items.empty()) {
+ const ArdourCanvas::Item* i = items.front();
+
+ if (i && i->parent() && i->parent()->get_data (X_("timeselection"))) {
+ pair<TimeAxisView*, int> tvp = trackview_by_y_position (_last_motion_y);
+ if (dynamic_cast<AutomationTimeAxisView*> (tvp.first)) {
+ mode_cursor = _cursors->up_down;
+ }
+ }
+ }
+ }
+ }
+
+ return mode_cursor;
}
-double
-Editor::clamp_verbose_cursor_y (double y)
+Gdk::Cursor*
+Editor::which_region_cursor () const
{
- y = max (0.0, y);
- y = min (_visible_canvas_height - 50, y);
- return y;
+ Gdk::Cursor* cursor = 0;
+
+ assert (mouse_mode == MouseObject || get_smart_mode());
+
+ if (!_internal_editing) {
+ switch (_join_object_range_state) {
+ case JOIN_OBJECT_RANGE_NONE:
+ case JOIN_OBJECT_RANGE_OBJECT:
+ cursor = which_grabber_cursor ();
+ cerr << "region use grabber\n";
+ break;
+ case JOIN_OBJECT_RANGE_RANGE:
+ cursor = _cursors->selector;
+ cerr << "region use selector\n";
+ break;
+ }
+ }
+
+ return cursor;
}
-ArdourCanvas::GtkCanvasViewport*
-Editor::get_track_canvas() const
+bool
+Editor::reset_canvas_cursor ()
{
- return _track_canvas_viewport;
+ if (!is_drawable()) {
+ return false;
+ }
+
+ Gdk::Cursor* cursor = which_mode_cursor ();
+
+ if (cursor) {
+ set_canvas_cursor (cursor);
+ return true;
+ }
+
+ return false;
+}
+
+void
+Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType type)
+{
+ Gdk::Cursor* cursor = 0;
+
+ cerr << "entered new item type " << enum_2_string (type) << endl;
+
+ if (_drags->active()) {
+ return;
+ }
+
+ cursor = which_mode_cursor ();
+
+ if (mouse_mode == MouseObject || get_smart_mode ()) {
+
+ /* find correct cursor to use in object/smart mode */
+
+ switch (type) {
+ case RegionItem:
+ case RegionViewNameHighlight:
+ case RegionViewName:
+ case WaveItem:
+ cursor = which_region_cursor ();
+ break;
+ case PlayheadCursorItem:
+ switch (_edit_point) {
+ case EditAtMouse:
+ cursor = _cursors->grabber_edit_point;
+ break;
+ default:
+ cursor = _cursors->grabber;
+ break;
+ }
+ break;
+ case SelectionItem:
+ cursor = _cursors->selector;
+ break;
+ case ControlPointItem:
+ cursor = _cursors->fader;
+ break;
+ case GainLineItem:
+ cursor = _cursors->fader;
+ break;
+ case AutomationLineItem:
+ cursor = _cursors->cross_hair;
+ break;
+ case StartSelectionTrimItem:
+ break;
+ case EndSelectionTrimItem:
+ break;
+ case AutomationTrackItem:
+ cursor = _cursors->cross_hair;
+ break;
+ case FadeInItem:
+ cursor = _cursors->fade_in;
+ break;
+ case FadeInHandleItem:
+ cursor = _cursors->fade_in;
+ break;
+ case FadeInTrimHandleItem:
+ cursor = _cursors->fade_in;
+ break;
+ case FadeOutItem:
+ cursor = _cursors->fade_out;
+ break;
+ case FadeOutHandleItem:
+ cursor = _cursors->fade_out;
+ break;
+ case FadeOutTrimHandleItem:
+ cursor = _cursors->fade_out;
+ break;
+ case NoteItem:
+ cursor = which_grabber_cursor();
+ break;
+ case FeatureLineItem:
+ cursor = _cursors->cross_hair;
+ break;
+ case LeftFrameHandle:
+ cursor = which_trim_cursor (true);
+ break;
+ case RightFrameHandle:
+ cursor = which_trim_cursor (false);
+ break;
+ case StartCrossFadeItem:
+ cursor = _cursors->fade_in;
+ break;
+ case EndCrossFadeItem:
+ cursor = _cursors->fade_out;
+ break;
+ case CrossfadeViewItem:
+ cursor = _cursors->cross_hair;
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (type) {
+ /* These items use the timebar cursor at all times */
+ case TimecodeRulerItem:
+ case MinsecRulerItem:
+ case BBTRulerItem:
+ case SamplesRulerItem:
+ cursor = _cursors->timebar;
+ break;
+
+ /* These items use the grabber cursor at all times */
+ case MeterMarkerItem:
+ case TempoMarkerItem:
+ case MeterBarItem:
+ case TempoBarItem:
+ case MarkerItem:
+ case MarkerBarItem:
+ case RangeMarkerBarItem:
+ case CdMarkerBarItem:
+ case VideoBarItem:
+ case TransportMarkerBarItem:
+ cursor = which_grabber_cursor();
+ break;
+
+ default:
+ break;
+ }
+
+ if (cursor) {
+ set_canvas_cursor (cursor, false);
+ }
}
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index 2f4fe40bcd..4eeb323e9e 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -278,16 +278,14 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg
break;
case GDK_ENTER_NOTIFY:
- if (event->crossing.detail != GDK_NOTIFY_INFERIOR) {
- set_entered_regionview (rv);
- ret = true;
- }
+ set_entered_regionview (rv);
+ ret = enter_handler (item, event, RegionItem);
break;
case GDK_LEAVE_NOTIFY:
if (event->crossing.detail != GDK_NOTIFY_INFERIOR) {
set_entered_regionview (0);
- ret = true;
+ ret = leave_handler (item, event, RegionItem);
}
break;
@@ -299,6 +297,42 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg
}
bool
+Editor::canvas_wave_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
+{
+ /* we only care about enter events here, required for mouse/cursor
+ * tracking. there is a non-linear (non-child/non-parent) relationship
+ * between various components of a regionview and so when we leave one
+ * of them (e.g. a trim handle) and enter another (e.g. the waveview)
+ * no other items get notified. enter/leave handling does not propagate
+ * in the same way as other events, so we need to catch this because
+ * entering (and leaving) the waveview is equivalent to
+ * entering/leaving the regionview (which is why it is passed in as a
+ * third argument).
+ *
+ * And in fact, we really only care about enter events.
+ */
+
+ bool ret = false;
+
+ if (!rv->sensitive ()) {
+ return false;
+ }
+
+ switch (event->type) {
+ case GDK_ENTER_NOTIFY:
+ set_entered_regionview (rv);
+ ret = enter_handler (item, event, WaveItem);
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+
+bool
Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
{
bool ret = FALSE;
@@ -324,11 +358,14 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou
case GDK_ENTER_NOTIFY:
set_entered_track (tv);
- ret = true;
+ ret = enter_handler (item, event, StreamItem);
break;
case GDK_LEAVE_NOTIFY:
- set_entered_track (0);
+ if (event->crossing.detail != GDK_NOTIFY_INFERIOR) {
+ set_entered_track (0);
+ }
+ ret = leave_handler (item, event, StreamItem);
break;
default:
diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h
index 211b0d0212..ce9de4bc12 100644
--- a/gtk2_ardour/editor_items.h
+++ b/gtk2_ardour/editor_items.h
@@ -23,6 +23,7 @@
enum ItemType {
RegionItem,
StreamItem,
+ WaveItem,
PlayheadCursorItem,
MarkerItem,
MarkerBarItem,
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 8f84d5f602..6eedcf5bb7 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -185,51 +185,6 @@ Editor::canvas_event_sample (GdkEvent const * event, double* pcx, double* pcy) c
return pixel_to_sample_from_event (x);
}
-Gdk::Cursor*
-Editor::which_grabber_cursor ()
-{
- Gdk::Cursor* c = _cursors->grabber;
-
- if (_internal_editing) {
- switch (mouse_mode) {
- case MouseDraw:
- c = _cursors->midi_pencil;
- break;
-
- case MouseObject:
- c = _cursors->grabber_note;
- break;
-
- case MouseTimeFX:
- c = _cursors->midi_resize;
- break;
-
- case MouseRange:
- c = _cursors->grabber_note;
- break;
-
- default:
- break;
- }
-
- } else {
-
- switch (_edit_point) {
- case EditAtMouse:
- c = _cursors->grabber_edit_point;
- break;
- default:
- boost::shared_ptr<Movable> m = _movable.lock();
- if (m && m->locked()) {
- c = _cursors->speaker;
- }
- break;
- }
- }
-
- return c;
-}
-
void
Editor::set_current_trimmable (boost::shared_ptr<Trimmable> t)
{
@@ -237,7 +192,6 @@ Editor::set_current_trimmable (boost::shared_ptr<Trimmable> t)
if (!st || st == t) {
_trimmable = t;
- set_canvas_cursor ();
}
}
@@ -248,95 +202,7 @@ Editor::set_current_movable (boost::shared_ptr<Movable> m)
if (!sm || sm != m) {
_movable = m;
- set_canvas_cursor ();
- }
-}
-
-void
-Editor::set_canvas_cursor ()
-{
- switch (mouse_mode) {
- case MouseRange:
- current_canvas_cursor = _cursors->selector;
- if (_internal_editing) {
- current_canvas_cursor = which_grabber_cursor();
- }
- break;
-
- case MouseObject:
- current_canvas_cursor = which_grabber_cursor();
- break;
-
- case MouseDraw:
- current_canvas_cursor = _cursors->midi_pencil;
- break;
-
- case MouseGain:
- current_canvas_cursor = _cursors->cross_hair;
- break;
-
- case MouseZoom:
- if (Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
- current_canvas_cursor = _cursors->zoom_out;
- } else {
- current_canvas_cursor = _cursors->zoom_in;
- }
- break;
-
- case MouseTimeFX:
- current_canvas_cursor = _cursors->time_fx; // just use playhead
- break;
-
- case MouseAudition:
- current_canvas_cursor = _cursors->speaker;
- break;
- }
-
- if (!_internal_editing) {
- switch (_join_object_range_state) {
- case JOIN_OBJECT_RANGE_NONE:
- break;
- case JOIN_OBJECT_RANGE_OBJECT:
- current_canvas_cursor = which_grabber_cursor ();
- break;
- case JOIN_OBJECT_RANGE_RANGE:
- current_canvas_cursor = _cursors->selector;
- break;
- }
}
-
- /* up-down cursor as a cue that automation can be dragged up and down when in join object/range mode */
- if (!_internal_editing && get_smart_mode() ) {
-
- double x, y;
- get_pointer_position (x, y);
-
- if (x >= 0 && y >= 0) {
-
- vector<ArdourCanvas::Item const *> items;
-
- /* Note how we choose a specific scroll group to get
- * items from. This could be problematic.
- */
-
- hv_scroll_group->add_items_at_point (ArdourCanvas::Duple (x,y), items);
-
- // first item will be the upper most
-
- if (!items.empty()) {
- const ArdourCanvas::Item* i = items.front();
-
- if (i && i->parent() && i->parent()->get_data (X_("timeselection"))) {
- pair<TimeAxisView*, int> tvp = trackview_by_y_position (_last_motion_y);
- if (dynamic_cast<AutomationTimeAxisView*> (tvp.first)) {
- current_canvas_cursor = _cursors->up_down;
- }
- }
- }
- }
- }
-
- set_canvas_cursor (current_canvas_cursor, true);
}
void
@@ -499,7 +365,7 @@ Editor::mouse_mode_toggled (MouseMode m)
}
*/
- set_canvas_cursor ();
+ reset_canvas_cursor ();
set_gain_envelope_visibility ();
update_time_selection_display ();
@@ -1247,7 +1113,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
scrub_reverse_distance = 0;
last_scrub_x = event->button.x;
scrubbing_direction = 0;
- set_canvas_cursor (_cursors->transparent);
+ push_canvas_cursor (_cursors->transparent);
return true;
break;
@@ -1777,7 +1643,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
break;
case MouseAudition:
- set_canvas_cursor (current_canvas_cursor);
+ pop_canvas_cursor ();
if (scrubbing_direction == 0) {
/* no drag, just a click */
switch (item_type) {
@@ -1858,6 +1724,15 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
double fraction;
bool ret = true;
+ /* by the time we reach here, entered_regionview and entered trackview
+ * will have already been set as appropriate. Things are done this
+ * way because this method isn't passed a pointer to a variable type of
+ * thing that is entered (which may or may not be canvas item).
+ * (e.g. the actual entered regionview)
+ */
+
+ choose_canvas_cursor_on_entry (&event->crossing, item_type);
+
switch (item_type) {
case ControlPointItem:
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
@@ -1873,10 +1748,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
fraction = 1.0 - (cp->get_y() / cp->line().height());
- if (is_drawable() && !_drags->active ()) {
- set_canvas_cursor (_cursors->fader);
- }
-
_verbose_cursor->set (cp->line().get_verbose_cursor_string (fraction), at_x, at_y);
_verbose_cursor->show ();
}
@@ -1888,9 +1759,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
if (line) {
line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredGainLine());
}
- if (is_drawable()) {
- set_canvas_cursor (_cursors->fader);
- }
}
break;
@@ -1900,112 +1768,14 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
if (line) {
line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredAutomationLine());
}
- if (is_drawable()) {
- set_canvas_cursor (_cursors->fader);
- }
- }
- break;
-
- case RegionViewNameHighlight:
- if (is_drawable() && effective_mouse_mode() == MouseObject && entered_regionview) {
- set_canvas_cursor_for_region_view (event->crossing.x, entered_regionview);
- _over_region_trim_target = true;
- }
- break;
-
- case LeftFrameHandle:
- case RightFrameHandle:
- if (is_drawable() && effective_mouse_mode() == MouseObject && !internal_editing() && entered_regionview) {
- set_canvas_cursor_for_region_view (event->crossing.x, entered_regionview);
}
break;
- case RegionItem:
- switch (effective_mouse_mode()) {
- case MouseRange:
- set_canvas_cursor (_cursors->selector);
- break;
- default:
- set_canvas_cursor (which_grabber_cursor());
- break;
- }
- break;
-
- case StartSelectionTrimItem:
- if (is_drawable()) {
- set_canvas_cursor (_cursors->left_side_trim);
- }
- break;
- case EndSelectionTrimItem:
- if (is_drawable()) {
- set_canvas_cursor (_cursors->right_side_trim);
- }
- break;
-
- case PlayheadCursorItem:
- if (is_drawable()) {
- switch (_edit_point) {
- case EditAtMouse:
- set_canvas_cursor (_cursors->grabber_edit_point);
- break;
- default:
- set_canvas_cursor (_cursors->grabber);
- break;
- }
- }
- break;
-
-
- case RegionViewName:
-
- /* when the name is not an active item, the entire name highlight is for trimming */
-
- if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) {
- if (mouse_mode == MouseObject && is_drawable()) {
- set_canvas_cursor_for_region_view (event->crossing.x, entered_regionview);
- _over_region_trim_target = true;
- }
- }
- break;
-
-
case AutomationTrackItem:
- if (is_drawable()) {
- Gdk::Cursor *cursor;
- switch (mouse_mode) {
- case MouseRange:
- cursor = _cursors->selector;
- break;
- case MouseZoom:
- cursor = _cursors->zoom_in;
- break;
- default:
- cursor = _cursors->cross_hair;
- break;
- }
-
- set_canvas_cursor (cursor);
-
- AutomationTimeAxisView* atv;
- if ((atv = static_cast<AutomationTimeAxisView*>(item->get_data ("trackview"))) != 0) {
- clear_entered_track = false;
- set_entered_track (atv);
- }
- }
- break;
-
- case MarkerBarItem:
- case RangeMarkerBarItem:
- case TransportMarkerBarItem:
- case CdMarkerBarItem:
- case MeterBarItem:
- case TempoBarItem:
- case TimecodeRulerItem:
- case SamplesRulerItem:
- case MinsecRulerItem:
- case BBTRulerItem:
- if (is_drawable()) {
- set_canvas_cursor (_cursors->timebar);
+ AutomationTimeAxisView* atv;
+ if ((atv = static_cast<AutomationTimeAxisView*>(item->get_data ("trackview"))) != 0) {
+ clear_entered_track = false;
+ set_entered_track (atv);
}
break;
@@ -2018,9 +1788,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
// fall through
case MeterMarkerItem:
case TempoMarkerItem:
- if (is_drawable()) {
- set_canvas_cursor (_cursors->timebar);
- }
break;
case FadeInHandleItem:
@@ -2030,7 +1797,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
if (rect) {
RegionView* rv = static_cast<RegionView*>(item->get_data ("regionview"));
rect->set_fill_color (rv->get_fill_color());
- set_canvas_cursor (_cursors->fade_in);
}
}
break;
@@ -2042,7 +1808,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
if (rect) {
RegionView* rv = static_cast<RegionView*>(item->get_data ("regionview"));
rect->set_fill_color (rv->get_fill_color ());
- set_canvas_cursor (_cursors->fade_out);
}
}
break;
@@ -2055,16 +1820,13 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
break;
case SelectionItem:
- if ( get_smart_mode() ) {
- set_canvas_cursor ();
- }
break;
default:
break;
}
- /* second pass to handle entered track status in a comprehensible way.
+ /* third pass to handle entered track status in a comprehensible way.
*/
switch (item_type) {
@@ -2080,7 +1842,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
break;
default:
- set_entered_track (0);
+
break;
}
@@ -2098,27 +1860,9 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
switch (item_type) {
case ControlPointItem:
- if (is_drawable()) {
- set_canvas_cursor (current_canvas_cursor);
- }
-
_verbose_cursor->hide ();
break;
- case RegionViewNameHighlight:
- case LeftFrameHandle:
- case RightFrameHandle:
- case StartSelectionTrimItem:
- case EndSelectionTrimItem:
- case PlayheadCursorItem:
-
- _over_region_trim_target = false;
-
- if (is_drawable()) {
- set_canvas_cursor (current_canvas_cursor);
- }
- break;
-
case GainLineItem:
case AutomationLineItem:
al = reinterpret_cast<AutomationLine*> (item->get_data ("line"));
@@ -2128,35 +1872,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
line->set_outline_color (al->get_line_color());
}
}
- if (is_drawable()) {
- set_canvas_cursor (current_canvas_cursor);
- }
- break;
-
- case RegionViewName:
- /* see enter_handler() for notes */
- _over_region_trim_target = false;
-
- if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) {
- if (is_drawable() && mouse_mode == MouseObject) {
- set_canvas_cursor (current_canvas_cursor);
- }
- }
- break;
-
- case RangeMarkerBarItem:
- case TransportMarkerBarItem:
- case CdMarkerBarItem:
- case MeterBarItem:
- case TempoBarItem:
- case MarkerBarItem:
- case TimecodeRulerItem:
- case SamplesRulerItem:
- case MinsecRulerItem:
- case BBTRulerItem:
- if (is_drawable()) {
- set_canvas_cursor (current_canvas_cursor);
- }
break;
case MarkerItem:
@@ -2170,39 +1885,29 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
// fall through
case MeterMarkerItem:
case TempoMarkerItem:
-
- if (is_drawable()) {
- set_canvas_cursor (current_canvas_cursor);
- }
-
break;
case FadeInTrimHandleItem:
case FadeOutTrimHandleItem:
case FadeInHandleItem:
case FadeOutHandleItem:
- {
- ArdourCanvas::Rectangle *rect = dynamic_cast<ArdourCanvas::Rectangle *> (item);
- if (rect) {
- rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_InactiveFadeHandle());
- }
+ {
+ ArdourCanvas::Rectangle *rect = dynamic_cast<ArdourCanvas::Rectangle *> (item);
+ if (rect) {
+ rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_InactiveFadeHandle());
}
- set_canvas_cursor (current_canvas_cursor);
- break;
+ }
+ break;
case AutomationTrackItem:
- if (is_drawable()) {
- set_canvas_cursor (current_canvas_cursor);
- clear_entered_track = true;
- Glib::signal_idle().connect (sigc::mem_fun(*this, &Editor::left_automation_track));
- }
break;
+
case FeatureLineItem:
- {
- ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
- line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_ZeroLine());
- }
- break;
+ {
+ ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
+ line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_ZeroLine());
+ }
+ break;
default:
break;
@@ -2211,16 +1916,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
return ret;
}
-gint
-Editor::left_automation_track ()
-{
- if (clear_entered_track) {
- set_entered_track (0);
- clear_entered_track = false;
- }
- return false;
-}
-
void
Editor::scrub (framepos_t frame, double current_x)
{
@@ -2331,16 +2026,7 @@ Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from
return true;
}
- JoinObjectRangeState const old = _join_object_range_state;
- update_join_object_range_location (event->motion.x, event->motion.y);
-
- if (!_internal_editing && _join_object_range_state != old) {
- set_canvas_cursor ();
- }
-
- if (!_internal_editing && _over_region_trim_target) {
- set_canvas_cursor_for_region_view (event->motion.x, entered_regionview);
- }
+ update_join_object_range_location (event->motion.y);
bool handled = false;
if (_drags->active ()) {
@@ -2427,19 +2113,19 @@ Editor::edit_notes (TimeAxisViewItem& tavi)
if (s.empty ()) {
return;
}
-
+
EditNoteDialog* d = new EditNoteDialog (&(*s.begin())->region_view(), s);
- d->show_all ();
+ d->show_all ();
ensure_float (*d);
- d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &Editor::note_edit_done), d));
+ d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &Editor::note_edit_done), d));
}
void
Editor::note_edit_done (int r, EditNoteDialog* d)
{
- d->done (r);
- delete d;
+ d->done (r);
+ delete d;
}
void
@@ -2509,7 +2195,7 @@ Editor::collect_new_region_view (RegionView* rv)
void
Editor::collect_and_select_new_region_view (RegionView* rv)
{
- selection->add(rv);
+ selection->add(rv);
latest_regionviews.push_back (rv);
}
@@ -2527,7 +2213,7 @@ Editor::cancel_selection ()
void
Editor::cancel_time_selection ()
{
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(*i)->hide_selection ();
}
selection->time.clear ();
@@ -2831,15 +2517,15 @@ Editor::set_internal_edit (bool yn)
}
_internal_editing = yn;
-
+
if (yn) {
- pre_internal_mouse_mode = mouse_mode;
+ pre_internal_mouse_mode = mouse_mode;
pre_internal_snap_type = _snap_type;
pre_internal_snap_mode = _snap_mode;
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
- (*i)->enter_internal_edit_mode ();
- }
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ (*i)->enter_internal_edit_mode ();
+ }
set_snap_to (internal_snap_type);
set_snap_mode (internal_snap_mode);
@@ -2849,62 +2535,71 @@ Editor::set_internal_edit (bool yn)
internal_snap_mode = _snap_mode;
internal_snap_type = _snap_type;
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
- (*i)->leave_internal_edit_mode ();
- }
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ (*i)->leave_internal_edit_mode ();
+ }
- if (mouse_mode == MouseDraw && pre_internal_mouse_mode != MouseDraw) {
- /* we were drawing .. flip back to something sensible */
- set_mouse_mode (pre_internal_mouse_mode);
- }
+ if (mouse_mode == MouseDraw && pre_internal_mouse_mode != MouseDraw) {
+ /* we were drawing .. flip back to something sensible */
+ set_mouse_mode (pre_internal_mouse_mode);
+ }
set_snap_to (pre_internal_snap_type);
set_snap_mode (pre_internal_snap_mode);
}
-
- set_canvas_cursor ();
+
+ reset_canvas_cursor ();
}
-/** Update _join_object_range_state which indicate whether we are over the top or bottom half of a region view,
- * used by the `join object/range' tool mode. Coordinates in canvas space.
+/** Update _join_object_range_state which indicate whether we are over the top
+ * or bottom half of a route view, used by the `join object/range' tool
+ * mode. Coordinates in canvas space.
*/
void
-Editor::update_join_object_range_location (double /*x*/, double y)
+Editor::update_join_object_range_location (double y)
{
- /* XXX: actually, this decides based on whether the mouse is in the top
- or bottom half of a the waveform part RouteTimeAxisView;
-
- Note that entered_{track,regionview} is not always setup (e.g. if
- the mouse is over a TimeSelection), and to get a Region
- that we're over requires searching the playlist.
- */
-
- if ( !get_smart_mode() ) {
+ if (_internal_editing || !get_smart_mode()) {
_join_object_range_state = JOIN_OBJECT_RANGE_NONE;
return;
}
+ JoinObjectRangeState const old = _join_object_range_state;
+
if (mouse_mode == MouseObject) {
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
} else if (mouse_mode == MouseRange) {
_join_object_range_state = JOIN_OBJECT_RANGE_RANGE;
}
- /* XXX: maybe we should make entered_track work in all cases, rather than resorting to this */
- pair<TimeAxisView*, int> tvp = trackview_by_y_position (y, false);
+ cerr << "Entered RV = " << entered_regionview << " track = " << entered_track << endl;
- if (tvp.first) {
+ if (entered_regionview) {
- RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
- if (rtv) {
-
- double cx = 0;
- double cy = y;
- rtv->canvas_display()->canvas_to_item (cx, cy);
+ ArdourCanvas::Duple const item_space = entered_regionview->get_canvas_group()->canvas_to_item (ArdourCanvas::Duple (0, y));
+ double const c = item_space.y / entered_regionview->height();
+
+ _join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT;
+
+ if (_join_object_range_state != old) {
+ set_canvas_cursor (which_region_cursor ());
+ }
- double const c = cy / (rtv->view()->child_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
+ } else if (entered_track) {
- _join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT;
+ RouteTimeAxisView* entered_route_view = dynamic_cast<RouteTimeAxisView*> (entered_track);
+
+ if (entered_route_view) {
+ /* track/bus ... but not in a region ... use range mode */
+ _join_object_range_state = JOIN_OBJECT_RANGE_RANGE;
+ if (_join_object_range_state != old) {
+ set_canvas_cursor (which_region_cursor ());
+ }
+ } else {
+ /* Other kinds of tracks use object mode */
+ _join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
+ if (_join_object_range_state != old) {
+ set_canvas_cursor (which_region_cursor ());
+ }
}
}
}
@@ -2930,51 +2625,6 @@ Editor::remove_midi_note (ArdourCanvas::Item* item, GdkEvent *)
e->region_view().delete_note (e->note ());
}
-void
-Editor::set_canvas_cursor_for_region_view (double x, RegionView* rv)
-{
- /* XXX: this check should not be necessary */
- if (rv == 0) {
- return;
- }
-
- ArdourCanvas::Group* g = rv->get_canvas_group ();
- ArdourCanvas::Group* p = g->parent ();
-
- /* Compute x in region view parent coordinates */
- double dy = 0;
- p->canvas_to_item (x, dy);
-
- boost::optional<ArdourCanvas::Rect> item_bbox = g->bounding_box ();
- assert (item_bbox);
- ArdourCanvas::Rect parent_bbox = g->item_to_parent (item_bbox.get ());
-
- /* First or last 10% of region is used for trimming, if the whole
- region is wider than 20 pixels at the current zoom level.
- */
-
- double const w = parent_bbox.width();
-
- if (w > 20.0 && x >= parent_bbox.x0 && x < parent_bbox.x1) {
-
- Trimmable::CanTrim ct = rv->region()->can_trim ();
-
- if (((x - parent_bbox.x0) / w) < 0.10) {
- if (ct & Trimmable::FrontTrimEarlier) {
- set_canvas_cursor (_cursors->left_side_trim, true);
- } else {
- set_canvas_cursor (_cursors->left_side_trim_right_only, true);
- }
- } else if (((parent_bbox.x1 - x) / w) < 0.10) {
- if (ct & Trimmable::EndTrimLater) {
- set_canvas_cursor (_cursors->right_side_trim, true);
- } else {
- set_canvas_cursor (_cursors->right_side_trim_left_only, true);
- }
- }
- }
-}
-
/** Obtain the pointer position in canvas coordinates */
void
Editor::get_pointer_position (double& x, double& y) const
diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc
index 867a21dde2..d2f0f23284 100644
--- a/gtk2_ardour/enums.cc
+++ b/gtk2_ardour/enums.cc
@@ -135,6 +135,7 @@ setup_gtk_ardour_enums ()
REGISTER (zoom_focus);
REGISTER_ENUM (RegionItem);
+ REGISTER_ENUM (WaveItem);
REGISTER_ENUM (StreamItem);
REGISTER_ENUM (PlayheadCursorItem);
REGISTER_ENUM (MarkerItem);
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index af66415a65..a0f5e74ef9 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -331,6 +331,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual bool canvas_fade_out_event (GdkEvent* event, ArdourCanvas::Item*, AudioRegionView*) = 0;
virtual bool canvas_fade_out_handle_event (GdkEvent* event, ArdourCanvas::Item*, AudioRegionView*, bool) = 0;
virtual bool canvas_region_view_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
+ virtual bool canvas_wave_view_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
virtual bool canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
virtual bool canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
virtual bool canvas_region_view_name_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0;
diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h
index 3536baa222..04072d1a8e 100644
--- a/gtk2_ardour/time_axis_view_item.h
+++ b/gtk2_ardour/time_axis_view_item.h
@@ -71,6 +71,7 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList
TimeAxisView& get_time_axis_view () const;
void set_name_text(const std::string&);
virtual void set_height(double h);
+ virtual double height() const { return _height; }
void set_y (double);
void set_color (uint32_t);
void set_name_text_color ();
diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc
index 3d4f9e0c5d..574304e7dd 100644
--- a/libs/canvas/canvas.cc
+++ b/libs/canvas/canvas.cc
@@ -487,7 +487,6 @@ GtkCanvas::deliver_enter_leave (Duple const & point, int state)
enter_detail = GDK_NOTIFY_INFERIOR;
leave_detail = GDK_NOTIFY_ANCESTOR;
-
} else if (_new_current_item->is_descendant_of (*_current_item)) {
/* move from ancestor to descendant (X: "_new_current_item is
* an inferior ("child") of _current_item")