summaryrefslogtreecommitdiff
path: root/gtk2_ardour
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 /gtk2_ardour
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
Diffstat (limited to 'gtk2_ardour')
-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
10 files changed, 497 insertions, 486 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 ();