From f425a974d6f06d07aa91609240d188b28eed654f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 4 Feb 2024 21:21:00 -0700 Subject: [PATCH] the continuing co-evolution of Editor,EditingContext & MidiCueEditor --- gtk2_ardour/cue_editor.cc | 16 ------- gtk2_ardour/cue_editor.h | 3 -- gtk2_ardour/cursor_context.cc | 3 +- gtk2_ardour/editing_context.cc | 81 +++++++++++++++++++++++++++++++++- gtk2_ardour/editing_context.h | 27 +++++++++--- gtk2_ardour/editor.cc | 5 +-- gtk2_ardour/editor.h | 15 +------ gtk2_ardour/editor_canvas.cc | 80 ++++----------------------------- gtk2_ardour/editor_drag.cc | 2 +- gtk2_ardour/midi_cue_editor.cc | 48 +++++++++++++------- gtk2_ardour/midi_cue_editor.h | 5 +++ gtk2_ardour/midi_view.cc | 16 +++++-- gtk2_ardour/public_editor.h | 2 - 13 files changed, 163 insertions(+), 140 deletions(-) diff --git a/gtk2_ardour/cue_editor.cc b/gtk2_ardour/cue_editor.cc index 1f76afaaff..6f9159bb9f 100644 --- a/gtk2_ardour/cue_editor.cc +++ b/gtk2_ardour/cue_editor.cc @@ -190,22 +190,6 @@ CueEditor::step_mouse_mode (bool next) } -void -CueEditor::set_canvas_cursor (Gdk::Cursor*) -{ -} - -size_t -CueEditor::push_canvas_cursor (Gdk::Cursor*) -{ - return 0; -} - -void -CueEditor::pop_canvas_cursor () -{ -} - void CueEditor::reset_x_origin_to_follow_playhead () { diff --git a/gtk2_ardour/cue_editor.h b/gtk2_ardour/cue_editor.h index 88639c3044..b16f198dd4 100644 --- a/gtk2_ardour/cue_editor.h +++ b/gtk2_ardour/cue_editor.h @@ -98,9 +98,6 @@ class CueEditor : public EditingContext void end_local_tempo_map (std::shared_ptr); protected: - void set_canvas_cursor (Gdk::Cursor*); - size_t push_canvas_cursor (Gdk::Cursor*); - void pop_canvas_cursor (); void reset_x_origin_to_follow_playhead (); }; diff --git a/gtk2_ardour/cursor_context.cc b/gtk2_ardour/cursor_context.cc index 57f83367e7..3fe52a57b0 100644 --- a/gtk2_ardour/cursor_context.cc +++ b/gtk2_ardour/cursor_context.cc @@ -24,7 +24,8 @@ CursorContext::CursorContext(EditingContext& ec, Gdk::Cursor* cursor) : editing_context(ec) , _index (editing_context.push_canvas_cursor(cursor)) -{} +{ +} CursorContext::~CursorContext() { diff --git a/gtk2_ardour/editing_context.cc b/gtk2_ardour/editing_context.cc index 385370493f..356aee8964 100644 --- a/gtk2_ardour/editing_context.cc +++ b/gtk2_ardour/editing_context.cc @@ -61,6 +61,7 @@ Gtkmm2ext::Bindings* EditingContext::button_bindings = nullptr; Glib::RefPtr EditingContext::_midi_actions; std::queue EditingContext::ec_stack; std::vector EditingContext::grid_type_strings; +MouseCursors* EditingContext::_cursors = nullptr; static const gchar *_grid_type_strings[] = { N_("No Grid"), @@ -106,7 +107,6 @@ EditingContext::EditingContext () , selection (new Selection (this, true)) , cut_buffer (new Selection (this, false)) , _selection_memento (new SelectionMemento()) - , _cursors (nullptr) , _verbose_cursor (nullptr) , samples_per_pixel (2048) , zoom_focus (ZoomFocusPlayhead) @@ -116,6 +116,8 @@ EditingContext::EditingContext () , _visible_canvas_width (0) , _visible_canvas_height (0) , quantize_dialog (nullptr) + , vertical_adjustment (0.0, 0.0, 10.0, 400.0) + , horizontal_adjustment (0.0, 0.0, 1e16) { if (!button_bindings) { button_bindings = new Bindings ("editor-mouse"); @@ -131,6 +133,12 @@ EditingContext::EditingContext () if (grid_type_strings.empty()) { grid_type_strings = I18N (_grid_type_strings); } + + if (!_cursors) { + _cursors = new MouseCursors; + _cursors->set_cursor_set (UIConfiguration::instance().get_icon_set()); + std::cerr << "Set cursor set to " << UIConfiguration::instance().get_icon_set() << std::endl; + } } EditingContext::~EditingContext() @@ -1978,3 +1986,74 @@ EditingContext::pop_editing_context () { ec_stack.pop (); } + +double +EditingContext::horizontal_position () const +{ + return sample_to_pixel (_leftmost_sample); +} + +void +EditingContext::set_horizontal_position (double p) +{ + p = std::max (0., p); + + std::cerr << "new hp: " << p << std::endl; + horizontal_adjustment.set_value (p); + + _leftmost_sample = (samplepos_t) floor (p * samples_per_pixel); +} + +Gdk::Cursor* +EditingContext::get_canvas_cursor () const +{ + /* The top of the cursor stack is always the currently visible cursor. */ + return _cursor_stack.back(); +} + +void +EditingContext::set_canvas_cursor (Gdk::Cursor* cursor) +{ + Glib::RefPtr win = get_canvas_viewport()->get_window(); + + if (win && !_cursors->is_invalid (cursor)) { + /* glibmm 2.4 doesn't allow null cursor pointer because it uses + a Gdk::Cursor& as the argument to Gdk::Window::set_cursor(). + But a null pointer just means "use parent window cursor", + and so should be allowed. Gtkmm 3.x has fixed this API. + + For now, drop down and use C API + */ + gdk_window_set_cursor (win->gobj(), cursor ? cursor->gobj() : 0); + } +} + +size_t +EditingContext::push_canvas_cursor (Gdk::Cursor* cursor) +{ + if (!_cursors->is_invalid (cursor)) { + _cursor_stack.push_back (cursor); + set_canvas_cursor (cursor); + } + return _cursor_stack.size() - 1; +} + +void +EditingContext::pop_canvas_cursor () +{ + while (true) { + if (_cursor_stack.size() <= 1) { + PBD::error << "attempt to pop default cursor" << endmsg; + return; + } + + _cursor_stack.pop_back(); + if (_cursor_stack.back()) { + /* Popped to an existing cursor, we're done. Otherwise, the + context that created this cursor has been destroyed, so we need + to skip to the next down the stack. */ + set_canvas_cursor (_cursor_stack.back()); + return; + } + } +} diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index bca30ed5de..b521d5105b 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -295,8 +295,8 @@ public: /** @return Whether the current mouse mode is an "internal" editing mode. */ virtual bool internal_editing() const = 0; - virtual Gdk::Cursor* get_canvas_cursor () const = 0; - virtual MouseCursors const* cursors () const { + virtual Gdk::Cursor* get_canvas_cursor () const; + static MouseCursors const* cursors () { return _cursors; } virtual VerboseCursor* verbose_cursor () const { @@ -333,15 +333,23 @@ public: bool typed_event (ArdourCanvas::Item*, GdkEvent*, ItemType); + void set_horizontal_position (double); + double horizontal_position () const; + + virtual samplecnt_t current_page_samples() const = 0; + + virtual ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const = 0; + virtual ArdourCanvas::Canvas* get_canvas() const = 0; + protected: static Glib::RefPtr _midi_actions; /* Cursor stuff. Do not use directly, use via CursorContext. */ friend class CursorContext; std::vector _cursor_stack; - virtual void set_canvas_cursor (Gdk::Cursor*) = 0; - virtual size_t push_canvas_cursor (Gdk::Cursor*) = 0; - virtual void pop_canvas_cursor () = 0; + virtual void set_canvas_cursor (Gdk::Cursor*); + virtual size_t push_canvas_cursor (Gdk::Cursor*); + virtual void pop_canvas_cursor (); Editing::GridType pre_internal_grid_type; Editing::SnapMode pre_internal_snap_mode; @@ -397,7 +405,6 @@ public: virtual void mark_region_boundary_cache_dirty () {} virtual void update_tempo_based_rulers () {}; virtual void show_rulers_for_grid () {}; - virtual samplecnt_t current_page_samples() const = 0; samplepos_t _leftmost_sample; @@ -417,7 +424,7 @@ public: std::list before; /* used in *_reversible_command */ - MouseCursors* _cursors; + static MouseCursors* _cursors; VerboseCursor* _verbose_cursor; @@ -505,8 +512,14 @@ public: static void push_editing_context (EditingContext*); static void pop_editing_context (); + /** the adjustment that controls the overall editing vertical scroll position */ + friend class EditorSummary; + Gtk::Adjustment vertical_adjustment; + Gtk::Adjustment horizontal_adjustment; + private: static std::queue ec_stack; + }; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index dbbd64d774..34fafd8738 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -305,8 +305,6 @@ Editor::Editor () , videotl_group (0) , _region_boundary_cache_dirty (true) , edit_packer (4, 4, true) - , vertical_adjustment (0.0, 0.0, 10.0, 400.0) - , horizontal_adjustment (0.0, 0.0, 1e16) , unused_adjustment (0.0, 0.0, 10.0, 400.0) , controls_layout (unused_adjustment, vertical_adjustment) , _scroll_callbacks (0) @@ -4464,9 +4462,8 @@ Editor::on_samples_per_pixel_changed () ZoomChanged (); /* EMIT_SIGNAL */ - ArdourCanvas::GtkCanvasViewport* c; + ArdourCanvas::GtkCanvasViewport* c = get_canvas_viewport (); - c = get_track_canvas(); if (c) { c->canvas()->zoomed (); } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 136b659309..10974873e6 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -452,8 +452,6 @@ public: void set_current_trimmable (std::shared_ptr); void set_current_movable (std::shared_ptr); - Gdk::Cursor* get_canvas_cursor () const; - double clamp_verbose_cursor_x (double); double clamp_verbose_cursor_y (double); @@ -481,7 +479,8 @@ public: ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; } ArdourCanvas::Container* get_drag_motion_group () const { return _drag_motion_group; } - ArdourCanvas::GtkCanvasViewport* get_track_canvas () const; + ArdourCanvas::GtkCanvasViewport* get_canvas_viewport () const; + ArdourCanvas::Canvas* get_canvas () const; void override_visible_track_count (); @@ -780,10 +779,6 @@ private: Gtk::HBox global_hpacker; Gtk::VBox global_vpacker; - void set_canvas_cursor (Gdk::Cursor* cursor); - size_t push_canvas_cursor (Gdk::Cursor*); - void pop_canvas_cursor (); - Gdk::Cursor* which_track_cursor () const; Gdk::Cursor* which_mode_cursor () const; Gdk::Cursor* which_trim_cursor (bool left_side) const; @@ -1021,10 +1016,6 @@ private: Gtk::Table edit_packer; - /** the adjustment that controls the overall editor vertical scroll position */ - Gtk::Adjustment vertical_adjustment; - Gtk::Adjustment horizontal_adjustment; - Gtk::Adjustment unused_adjustment; // yes, really; Gtk::Layout constructor requires refs Gtk::Layout controls_layout; bool control_layout_scroll (GdkEventScroll* ev); @@ -1071,8 +1062,6 @@ private: sigc::connection control_scroll_connection; void tie_vertical_scrolling (); - void set_horizontal_position (double); - double horizontal_position () const; struct VisualChange { enum Type { diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 3fd702ac6d..18d81c2122 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -1004,14 +1004,6 @@ Editor::tie_vertical_scrolling () _group_tabs->set_offset (vertical_adjustment.get_value ()); } -void -Editor::set_horizontal_position (double p) -{ - horizontal_adjustment.set_value (p); - - _leftmost_sample = (samplepos_t) floor (p * samples_per_pixel); -} - void Editor::color_handler() { @@ -1077,10 +1069,16 @@ Editor::color_handler() */ } -double -Editor::horizontal_position () const +ArdourCanvas::GtkCanvasViewport* +Editor::get_canvas_viewport() const { - return sample_to_pixel (_leftmost_sample); + return _track_canvas_viewport; +} + +ArdourCanvas::Canvas* +Editor::get_canvas() const +{ + return _track_canvas_viewport->canvas(); } bool @@ -1114,66 +1112,6 @@ Editor::clamp_verbose_cursor_y (double y) return y; } -ArdourCanvas::GtkCanvasViewport* -Editor::get_track_canvas() const -{ - return _track_canvas_viewport; -} - -Gdk::Cursor* -Editor::get_canvas_cursor () const -{ - /* The top of the cursor stack is always the currently visible cursor. */ - return _cursor_stack.back(); -} - -void -Editor::set_canvas_cursor (Gdk::Cursor* cursor) -{ - Glib::RefPtr win = _track_canvas->get_window(); - - if (win && !_cursors->is_invalid (cursor)) { - /* glibmm 2.4 doesn't allow null cursor pointer because it uses - a Gdk::Cursor& as the argument to Gdk::Window::set_cursor(). - But a null pointer just means "use parent window cursor", - and so should be allowed. Gtkmm 3.x has fixed this API. - - For now, drop down and use C API - */ - gdk_window_set_cursor (win->gobj(), cursor ? cursor->gobj() : 0); - } -} - -size_t -Editor::push_canvas_cursor (Gdk::Cursor* cursor) -{ - if (!_cursors->is_invalid (cursor)) { - _cursor_stack.push_back (cursor); - set_canvas_cursor (cursor); - } - return _cursor_stack.size() - 1; -} - -void -Editor::pop_canvas_cursor () -{ - while (true) { - if (_cursor_stack.size() <= 1) { - PBD::error << "attempt to pop default cursor" << endmsg; - return; - } - - _cursor_stack.pop_back(); - if (_cursor_stack.back()) { - /* Popped to an existing cursor, we're done. Otherwise, the - context that created this cursor has been destroyed, so we need - to skip to the next down the stack. */ - set_canvas_cursor (_cursor_stack.back()); - return; - } - } -} - Gdk::Cursor* Editor::which_trim_cursor (bool left) const { diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index e7e96f7b57..30b4d19a24 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -7091,7 +7091,7 @@ RegionCutDrag::motion (GdkEvent* event, bool) void RegionCutDrag::finished (GdkEvent* event, bool) { - _editor.get_track_canvas ()->canvas ()->re_enter (); + _editor.get_canvas()->re_enter (); timepos_t pos (_drags->current_pointer_time ()); editing_context.snap_to_with_modifier (pos, event); diff --git a/gtk2_ardour/midi_cue_editor.cc b/gtk2_ardour/midi_cue_editor.cc index 15571d9def..a3cac8678c 100644 --- a/gtk2_ardour/midi_cue_editor.cc +++ b/gtk2_ardour/midi_cue_editor.cc @@ -52,7 +52,7 @@ MidiCueEditor::MidiCueEditor() , vertical_adjustment (0.0, 0.0, 10.0, 400.0) , horizontal_adjustment (0.0, 0.0, 1e16) , view (nullptr) - , mouse_mode (Editing::MouseDraw) + , mouse_mode (Editing::MouseContent) , bbt_metric (*this) { build_canvas (); @@ -70,6 +70,29 @@ MidiCueEditor::~MidiCueEditor () { } +ArdourCanvas::GtkCanvasViewport* +MidiCueEditor::get_canvas_viewport() const +{ + return _canvas_viewport; +} + +ArdourCanvas::Canvas* +MidiCueEditor::get_canvas() const +{ + return _canvas; +} + +bool +MidiCueEditor::canvas_event (GdkEvent* ev) +{ + if (view) { + return view->canvas_event (ev); + } + + return false; +} + + void MidiCueEditor::build_canvas () { @@ -77,6 +100,7 @@ MidiCueEditor::build_canvas () _canvas = _canvas_viewport->canvas (); _canvas->set_background_color (UIConfiguration::instance().color ("arrange base")); + _canvas->signal_event().connect (sigc::mem_fun (*this, &MidiCueEditor::canvas_event)); dynamic_cast(_canvas)->use_nsglview (UIConfiguration::instance().get_nsgl_view_mode () == NSGLHiRes); /* scroll group for items that should not automatically scroll @@ -84,23 +108,19 @@ MidiCueEditor::build_canvas () */ no_scroll_group = new ArdourCanvas::Container (_canvas->root()); - ArdourCanvas::ScrollGroup* hsg; - ArdourCanvas::ScrollGroup* hg; - ArdourCanvas::ScrollGroup* cg; - - h_scroll_group = hg = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally); + h_scroll_group = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally); CANVAS_DEBUG_NAME (h_scroll_group, "canvas h scroll"); - _canvas->add_scroller (*hg); + _canvas->add_scroller (*h_scroll_group); - hv_scroll_group = hsg = new ArdourCanvas::ScrollGroup (_canvas->root(), + hv_scroll_group = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollSensitivity (ArdourCanvas::ScrollGroup::ScrollsVertically| ArdourCanvas::ScrollGroup::ScrollsHorizontally)); CANVAS_DEBUG_NAME (hv_scroll_group, "cue canvas hv scroll"); - _canvas->add_scroller (*hsg); + _canvas->add_scroller (*hv_scroll_group); - cursor_scroll_group = cg = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally); + cursor_scroll_group = new ArdourCanvas::ScrollGroup (_canvas->root(), ArdourCanvas::ScrollGroup::ScrollsHorizontally); CANVAS_DEBUG_NAME (cursor_scroll_group, "cue canvas cursor scroll"); - _canvas->add_scroller (*cg); + _canvas->add_scroller (*cursor_scroll_group); /*a group to hold global rects like punch/loop indicators */ global_rect_group = new ArdourCanvas::Container (hv_scroll_group); @@ -187,12 +207,6 @@ MidiCueEditor::canvas_allocate (Gtk::Allocation alloc) _visible_canvas_height = alloc.get_height(); bg->set_size (alloc.get_width(), alloc.get_height()); - std::cerr << "bg is " << bg->width() << std::endl; - - if (view) { - ArdourCanvas::Rect r (0., timebar_height * n_timebars, ArdourCanvas::COORD_MAX, alloc.get_height() - (timebar_height * n_timebars)); - view->set_size (r); - } } timepos_t diff --git a/gtk2_ardour/midi_cue_editor.h b/gtk2_ardour/midi_cue_editor.h index 4688ff5844..06f4d729c1 100644 --- a/gtk2_ardour/midi_cue_editor.h +++ b/gtk2_ardour/midi_cue_editor.h @@ -79,6 +79,9 @@ class MidiCueEditor : public CueEditor double timebar_height; size_t n_timebars; + ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const; + ArdourCanvas::Canvas* get_canvas() const; + protected: Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start, Temporal::RoundMode direction, @@ -157,6 +160,8 @@ class MidiCueEditor : public CueEditor }; BBTMetric bbt_metric; + + bool canvas_event (GdkEvent*); }; diff --git a/gtk2_ardour/midi_view.cc b/gtk2_ardour/midi_view.cc index 284e9bdc08..612b05f1d8 100644 --- a/gtk2_ardour/midi_view.cc +++ b/gtk2_ardour/midi_view.cc @@ -555,6 +555,8 @@ MidiView::motion (GdkEventMotion* ev) bool MidiView::scroll (GdkEventScroll* ev) { + std::cerr << "scroll\n"; + if (_editing_context.drags()->active()) { return false; } @@ -598,11 +600,17 @@ MidiView::scroll (GdkEventScroll* ev) set_note_range (min (127, _midi_context.lowest_note() - step), max (0, _midi_context.highest_note() - step)); } return true; - case GDK_SCROLL_LEFT: - break; - case GDK_SCROLL_RIGHT: - + case GDK_SCROLL_LEFT: + std::cerr << "left minus\n"; + _editing_context.set_horizontal_position (_editing_context.horizontal_position() - 20.0); + break; + + case GDK_SCROLL_RIGHT: + std::cerr << "right plus\n"; + _editing_context.set_horizontal_position (_editing_context.horizontal_position() + 20.0); + break; + default: break; } diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index d2086274b2..c59d29b812 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -410,8 +410,6 @@ public: virtual ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const = 0; virtual ArdourCanvas::Container* get_drag_motion_group () const = 0; - virtual ArdourCanvas::GtkCanvasViewport* get_track_canvas() const = 0; - virtual void set_current_trimmable (std::shared_ptr) = 0; virtual void set_current_movable (std::shared_ptr) = 0;