diff options
author | David Robillard <d@drobilla.net> | 2014-12-23 13:46:53 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2014-12-23 13:47:59 -0500 |
commit | 62355de33a00e40c20b79d7db1ac2139fd042743 (patch) | |
tree | 252d1c251f57f8e5465bbff5a468af31a0da5f37 | |
parent | e00c579fb2e99e993a0ab84ff00ba3109f6b5f20 (diff) |
Fix cursor update on nested entry.
For example, if you're in a note and something about the mode changes, it's the
underlying region context that needs to change. So, seems we need a stack of
entry contexts to deal with this sort of thing.
Switching in/out of smart mode still doesn't update immediately because we
don't have the y-coordinate needed to update it.
-rw-r--r-- | gtk2_ardour/editor.cc | 5 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 22 | ||||
-rw-r--r-- | gtk2_ardour/editor_canvas.cc | 52 | ||||
-rw-r--r-- | gtk2_ardour/editor_mouse.cc | 17 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 14 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.h | 1 |
6 files changed, 77 insertions, 34 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 2b7182059b..e379bc2537 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -373,7 +373,6 @@ Editor::Editor () current_stepping_trackview = 0; entered_track = 0; entered_regionview = 0; - _entered_item_type = NoItem; entered_marker = 0; clear_entered_track = false; current_timefx = 0; @@ -2122,9 +2121,7 @@ Editor::set_edit_point_preference (EditPoint ep, bool force) edit_point_selector.set_text (str); } - if (_entered_item_type != NoItem) { - choose_canvas_cursor_on_entry (_entered_item_type); - } + update_all_enter_cursors(); if (!force && !changed) { return; diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index ba2060748b..fbf17354d8 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -459,6 +459,19 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void get_pointer_position (double &, double &) const; + /** Context for mouse entry (stored in a stack). */ + struct EnterContext { + ItemType item_type; + boost::shared_ptr<CursorContext> cursor_ctx; + }; + + /** Get the topmost enter context for the given item type. + * + * This is used to change the cursor associated with a given enter context, + * which may not be on the top of the stack. + */ + EnterContext* get_enter_context(ItemType type); + TimeAxisView* stepping_axis_view () { return _stepping_axis_view; } @@ -735,8 +748,14 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD Gdk::Cursor* which_track_cursor () const; Gdk::Cursor* which_mode_cursor () const; Gdk::Cursor* which_trim_cursor (bool left_side) const; + Gdk::Cursor* which_canvas_cursor (ItemType type) const; + + /** Push the appropriate enter/cursor context on item entry. */ void choose_canvas_cursor_on_entry (ItemType); + /** Update all enter cursors based on current settings. */ + void update_all_enter_cursors (); + ArdourCanvas::GtkCanvas* _track_canvas; ArdourCanvas::GtkCanvasViewport* _track_canvas_viewport; @@ -1098,7 +1117,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD framecnt_t cut_buffer_length; boost::shared_ptr<CursorContext> _press_cursor_ctx; ///< Button press cursor context - boost::shared_ptr<CursorContext> _enter_cursor_ctx; ///< Entered item cursor context boost::weak_ptr<ARDOUR::Trimmable> _trimmable; boost::weak_ptr<ARDOUR::Movable> _movable; @@ -1981,7 +1999,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD */ RegionView* entered_regionview; - ItemType _entered_item_type; + std::vector<EnterContext> _enter_stack; bool clear_entered_track; bool left_track_canvas (GdkEventCrossing*); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 03637ec7f6..c26f00603e 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -782,6 +782,17 @@ Editor::stop_canvas_autoscroll () autoscroll_connection.disconnect (); } +Editor::EnterContext* +Editor::get_enter_context(ItemType type) +{ + for (ssize_t i = _enter_stack.size() - 1; i >= 0; --i) { + if (_enter_stack[i].item_type == type) { + return &_enter_stack[i]; + } + } + return NULL; +} + bool Editor::left_track_canvas (GdkEventCrossing */*ev*/) { @@ -1165,16 +1176,10 @@ Editor::which_track_cursor () const return cursor; } -void -Editor::choose_canvas_cursor_on_entry (ItemType type) +Gdk::Cursor* +Editor::which_canvas_cursor(ItemType type) const { - Gdk::Cursor* cursor = 0; - - if (_drags->active()) { - return; - } - - cursor = which_mode_cursor (); + Gdk::Cursor* cursor = which_mode_cursor (); if ((mouse_mode == MouseObject || get_smart_mode ()) || mouse_mode == MouseContent) { @@ -1256,6 +1261,8 @@ Editor::choose_canvas_cursor_on_entry (ItemType type) case CrossfadeViewItem: cursor = _cursors->cross_hair; break; + case NoteItem: + cursor = _cursors->grabber_note; default: break; } @@ -1274,6 +1281,8 @@ Editor::choose_canvas_cursor_on_entry (ItemType type) case ControlPointItem: cursor = _cursors->fader; break; + case NoteItem: + cursor = _cursors->grabber_note; default: break; } @@ -1307,9 +1316,30 @@ Editor::choose_canvas_cursor_on_entry (ItemType type) break; } + return cursor; +} + +void +Editor::choose_canvas_cursor_on_entry (ItemType type) +{ + if (_drags->active()) { + return; + } + + Gdk::Cursor* cursor = which_canvas_cursor(type); + if (cursor) { - CursorContext::set(&_enter_cursor_ctx, *this, cursor); - _entered_item_type = type; + // Push a new enter context + const EnterContext ctx = { type, CursorContext::create(*this, cursor) }; + _enter_stack.push_back(ctx); + } +} + +void +Editor::update_all_enter_cursors () +{ + for (std::vector<EnterContext>::iterator i = _enter_stack.begin(); i != _enter_stack.end(); ++i) { + i->cursor_ctx->change(which_canvas_cursor(i->item_type)); } } diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index a799bf85af..6d73d32cc0 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -320,6 +320,8 @@ Editor::mouse_mode_toggled (MouseMode m) update_time_selection_display (); + update_all_enter_cursors (); + MouseModeChanged (); /* EMIT SIGNAL */ } @@ -1642,8 +1644,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type) bool is_start; bool ret = true; - _enter_cursor_ctx.reset(); - _entered_item_type = NoItem; + _enter_stack.pop_back(); switch (item_type) { case ControlPointItem: @@ -2314,9 +2315,10 @@ Editor::update_join_object_range_location (double 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 && _enter_cursor_ctx) { - _enter_cursor_ctx->change(which_track_cursor()); + + Editor::EnterContext* ctx = get_enter_context(RegionItem); + if (_join_object_range_state != old && ctx) { + ctx->cursor_ctx->change(which_track_cursor()); } } else if (entered_track) { @@ -2348,8 +2350,9 @@ Editor::update_join_object_range_location (double y) _join_object_range_state = JOIN_OBJECT_RANGE_OBJECT; } - if (_join_object_range_state != old && _enter_cursor_ctx) { - _enter_cursor_ctx->change(which_track_cursor()); + Editor::EnterContext* ctx = get_enter_context(StreamItem); + if (_join_object_range_state != old && ctx) { + ctx->cursor_ctx->change(which_track_cursor()); } } } diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 1d5f3098ce..45de3ff353 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -415,8 +415,6 @@ bool MidiRegionView::leave_notify (GdkEventCrossing*) { leave_internal(); - _note_cursor_ctx.reset(); - _press_cursor_ctx.reset(); _entered = false; return false; @@ -3143,7 +3141,6 @@ MidiRegionView::note_entered(NoteBase* ev) if (_mouse_state == SelectTouchDragging) { note_selected (ev, true); } else if (editor->current_mouse_mode() == MouseContent) { - CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->grabber_note); show_verbose_cursor (ev->note ()); } else if (editor->current_mouse_mode() == MouseDraw) { show_verbose_cursor (ev->note ()); @@ -3160,8 +3157,6 @@ MidiRegionView::note_left (NoteBase*) } editor->verbose_cursor()->hide (); - - _note_cursor_ctx.reset(); } void @@ -3212,13 +3207,14 @@ MidiRegionView::note_mouse_position (float x_fraction, float /*y_fraction*/, boo Editing::MouseMode mm = editor->current_mouse_mode(); bool trimmable = (mm == MouseContent || mm == MouseTimeFX || mm == MouseDraw); - if (can_set_cursor) { + Editor::EnterContext* ctx = editor->get_enter_context(NoteItem); + if (can_set_cursor && ctx) { if (trimmable && x_fraction > 0.0 && x_fraction < 0.2) { - CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->left_side_trim); + ctx->cursor_ctx->change(editor->cursors()->left_side_trim); } else if (trimmable && x_fraction >= 0.8 && x_fraction < 1.0) { - CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->right_side_trim); + ctx->cursor_ctx->change(editor->cursors()->right_side_trim); } else { - CursorContext::set(&_note_cursor_ctx, *editor, editor->cursors()->grabber_note); + ctx->cursor_ctx->change(editor->cursors()->grabber_note); } } } diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 2c81f51122..3cca6b9b81 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -497,7 +497,6 @@ private: PBD::ScopedConnection _mouse_mode_connection; - boost::shared_ptr<CursorContext> _note_cursor_ctx; boost::shared_ptr<CursorContext> _press_cursor_ctx; NotePlayer* _note_player; |