diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index f00f0f2f8b..b87b44af14 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -1512,3 +1512,59 @@ AutomationLine::set_offset (timepos_t const & off) _offset = off; reset (); } + +void +AutomationLine::add (std::shared_ptr control, GdkEvent* event, timepos_t const & pos, double y, bool with_guard_points) +{ + if (alist->in_write_pass()) { + /* do not allow the GUI to add automation events during an + automation write pass. + */ + return; + } + + timepos_t when (pos); + Session* session (_editing_context.session()); + + _editing_context.snap_to_with_modifier (when, event); + + if (UIConfiguration::instance().get_new_automation_points_on_lane() || control->list()->size () == 0) { + if (control->list()->size () == 0) { + y = control->get_value (); + } else { + y = control->list()->eval (when); + } + } else { + double x = 0; + grab_item().canvas_to_item (x, y); + /* compute vertical fractional position */ + y = 1.0 - (y / height()); + /* map using line */ + view_to_model_coord_y (y); + } + + XMLNode& before = alist->get_state(); + std::list results; + + if (alist->editor_add (when, y, with_guard_points)) { + + if (control->automation_state () == ARDOUR::Off) { +#warning paul make this work again .. call back to ATV or similar + // set_automation_state (ARDOUR::Play); + } + + if (UIConfiguration::instance().get_automation_edit_cancels_auto_hide () && control == session->recently_touched_controllable ()) { + RouteTimeAxisView::signal_ctrl_touched (false); + } + + XMLNode& after = alist->get_state(); + _editing_context.begin_reversible_command (_("add automation event")); + _editing_context.add_command (new MementoCommand (*alist.get (), &before, &after)); + + get_selectables (when, when, 0.0, 1.0, results); + _editing_context.get_selection ().set (results); + + _editing_context.commit_reversible_command (); + session->set_dirty (); + } +} diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index 62781abc70..aa16f88add 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -177,6 +177,8 @@ public: ARDOUR::ParameterDescriptor const & param() const { return _desc; } EditingContext& editing_context() const { return _editing_context; } + void add (std::shared_ptr, GdkEvent*, Temporal::timepos_t const &, double y, bool with_guard_points); + protected: std::string _name; diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index c48bc7511a..5f033e1ca4 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -797,56 +797,7 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, timepos_t const & return; } - std::shared_ptr list = _line->the_list (); - - if (list->in_write_pass()) { - /* do not allow the GUI to add automation events during an - automation write pass. - */ - return; - } - - timepos_t when (pos); - _editor.snap_to_with_modifier (when, event); - - if (UIConfiguration::instance().get_new_automation_points_on_lane() || _control->list()->size () == 0) { - if (_control->list()->size () == 0) { - y = _control->get_value (); - } else { - y = _control->list()->eval (when); - } - } else { - double x = 0; - _line->grab_item().canvas_to_item (x, y); - /* compute vertical fractional position */ - y = 1.0 - (y / _line->height()); - /* map using line */ - _line->view_to_model_coord_y (y); - } - - XMLNode& before = list->get_state(); - std::list results; - - if (list->editor_add (when, y, with_guard_points)) { - - if (_control->automation_state () == ARDOUR::Off) { - set_automation_state (ARDOUR::Play); - } - - if (UIConfiguration::instance().get_automation_edit_cancels_auto_hide () && _control == _session->recently_touched_controllable ()) { - RouteTimeAxisView::signal_ctrl_touched (false); - } - - XMLNode& after = list->get_state(); - _editor.begin_reversible_command (_("add automation event")); - _session->add_command (new MementoCommand (*list.get (), &before, &after)); - - _line->get_selectables (when, when, 0.0, 1.0, results); - _editor.get_selection ().set (results); - - _editor.commit_reversible_command (); - _session->set_dirty (); - } + _line->add (_control, event, pos, y, with_guard_points); } bool diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index 5202561b53..6487ca6367 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -421,8 +421,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider */ void redo (uint32_t n = 1) { do_redo (n); } - virtual bool rb_click (GdkEvent*, Temporal::timepos_t const &) = 0; - virtual void history_changed() = 0; static void update_undo_redo_actions (PBD::UndoHistory const &); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 570efaee97..bd30be3e2e 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -5163,9 +5163,10 @@ FeatureLineDrag::aborted (bool) //_line->reset (); } -RubberbandSelectDrag::RubberbandSelectDrag (EditingContext& ec, ArdourCanvas::Item* i) +RubberbandSelectDrag::RubberbandSelectDrag (EditingContext& ec, ArdourCanvas::Item* i, std::function cf) : Drag (ec, i, ec.time_domain (), ec.get_trackview_group()) , _vertical_only (false) + , click_functor (cf) { DEBUG_TRACE (DEBUG::Drags, "New RubberbandSelectDrag\n"); } @@ -5308,7 +5309,7 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred) } else { /* just a click */ - bool do_deselect = editing_context.rb_click (event, grab_time()); + bool do_deselect = click_functor (event, grab_time()); /* do not deselect if Primary or Tertiary (toggle-select or * extend-select are pressed. @@ -5324,6 +5325,35 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred) editing_context.rubberband_rect->hide (); } +void +RubberbandSelectDrag::select_things (int button_state, timepos_t const& x1, timepos_t const& x2, double y1, double y2, bool drag_in_progress) +{ + if (drag_in_progress) { + /* We just want to select things at the end of the drag, not during it */ + return; + } + + SelectionOperation op = ArdourKeyboard::selection_type (button_state); + + editing_context.begin_reversible_selection_op (X_("rubberband selection")); + editing_context.select_all_within (x1, x2.decrement (), y1, y2, editing_context.selectable_owners(), op, false); + editing_context.commit_reversible_selection_op (); +} + +void +RubberbandSelectDrag::deselect_things () +{ + editing_context.begin_reversible_selection_op (X_("Clear Selection (rubberband)")); + + editing_context.get_selection().clear_tracks (); + editing_context.get_selection().clear_regions (); + editing_context.get_selection().clear_points (); + editing_context.get_selection().clear_lines (); + editing_context.get_selection().clear_midi_notes (); + + editing_context.commit_reversible_selection_op (); +} + void RubberbandSelectDrag::aborted (bool) { @@ -6727,7 +6757,7 @@ PatchChangeDrag::setup_pointer_offset () } MidiRubberbandSelectDrag::MidiRubberbandSelectDrag (EditingContext& ec, MidiView* mv) - : RubberbandSelectDrag (ec, mv->drag_group ()) + : RubberbandSelectDrag (ec, mv->drag_group (), [](GdkEvent*,timepos_t const&) { return true; }) , _midi_view (mv) { } @@ -6747,7 +6777,7 @@ MidiRubberbandSelectDrag::deselect_things () } MidiVerticalSelectDrag::MidiVerticalSelectDrag (EditingContext& ec, MidiView* mv) - : RubberbandSelectDrag (ec, mv->drag_group ()) + : RubberbandSelectDrag (ec, mv->drag_group (), [](GdkEvent*,timepos_t const &) { return true; }) , _midi_view (mv) { _vertical_only = true; @@ -6772,40 +6802,6 @@ MidiVerticalSelectDrag::deselect_things () /* XXX */ } -EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (EditingContext& e, ArdourCanvas::Item* i) - : RubberbandSelectDrag (e, i) -{ -} - -void -EditorRubberbandSelectDrag::select_things (int button_state, timepos_t const& x1, timepos_t const& x2, double y1, double y2, bool drag_in_progress) -{ - if (drag_in_progress) { - /* We just want to select things at the end of the drag, not during it */ - return; - } - - SelectionOperation op = ArdourKeyboard::selection_type (button_state); - - editing_context.begin_reversible_selection_op (X_("rubberband selection")); - editing_context.select_all_within (x1, x2.decrement (), y1, y2, editing_context.selectable_owners(), op, false); - editing_context.commit_reversible_selection_op (); -} - -void -EditorRubberbandSelectDrag::deselect_things () -{ - editing_context.begin_reversible_selection_op (X_("Clear Selection (rubberband)")); - - editing_context.get_selection().clear_tracks (); - editing_context.get_selection().clear_regions (); - editing_context.get_selection().clear_points (); - editing_context.get_selection().clear_lines (); - editing_context.get_selection().clear_midi_notes (); - - editing_context.commit_reversible_selection_op (); -} - NoteCreateDrag::NoteCreateDrag (EditingContext& ec, ArdourCanvas::Item* i, MidiView* mv) : Drag (ec, i, Temporal::BeatTime, ec.get_trackview_group()) , _midi_view (mv) diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 641dc26dc4..373b3c6d47 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1286,7 +1286,7 @@ private: class RubberbandSelectDrag : public Drag { public: - RubberbandSelectDrag (EditingContext&, ArdourCanvas::Item *); + RubberbandSelectDrag (EditingContext&, ArdourCanvas::Item *, std::function click_functor); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); @@ -1307,35 +1307,24 @@ public: * @param y2 The bottom of the rectangle in trackview coordinates. * @param drag_in_progress true if the drag is currently happening. */ - virtual void select_things (int button_state, Temporal::timepos_t const & x1, Temporal::timepos_t const & x2, double y1, double y2, bool drag_in_progress) = 0; - - virtual void deselect_things () = 0; + virtual void select_things (int button_state, Temporal::timepos_t const & x1, Temporal::timepos_t const & x2, double y1, double y2, bool drag_in_progress); + virtual void deselect_things (); protected: bool _vertical_only; -}; - -/** A general editor RubberbandSelectDrag (for regions, automation points etc.) */ -class EditorRubberbandSelectDrag : public RubberbandSelectDrag -{ -public: - EditorRubberbandSelectDrag (EditingContext&, ArdourCanvas::Item *); - - void select_things (int, Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, bool); - void deselect_things (); - private: + std::function click_functor; }; /** A RubberbandSelectDrag for selecting MIDI notes */ class MidiRubberbandSelectDrag : public RubberbandSelectDrag { -public: + public: MidiRubberbandSelectDrag (EditingContext&, MidiView *); void select_things (int, Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, bool); void deselect_things (); -private: + private: MidiView* _midi_view; }; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 700f2322d3..14238d2bcc 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -865,19 +865,19 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case StreamItem: /* in the past, we created a new midi region here, but perhaps that is best left to the Draw mode */ /* .. now we allow for rubberband selection (region gain) */ - _drags->set (new EditorRubberbandSelectDrag (*this, item), event); + _drags->set (new RubberbandSelectDrag (*this, item, [&](GdkEvent* ev, timepos_t const & pos) { return this->rb_click (ev, pos); }), event); return true; break; case AutomationTrackItem: /* rubberband drag to select automation points */ - _drags->set (new EditorRubberbandSelectDrag (*this, item), event); + _drags->set (new RubberbandSelectDrag (*this, item, [&](GdkEvent* ev, timepos_t const & pos) { return this->rb_click (ev, pos); }), event); return true; break; case RegionItem: /* rubberband drag to select region gain points */ - _drags->set (new EditorRubberbandSelectDrag (*this, item), event); + _drags->set (new RubberbandSelectDrag (*this, item, [&](GdkEvent* ev, timepos_t const & pos) { return this->rb_click (ev, pos); }), event); return true; break; @@ -890,7 +890,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) && event->type == GDK_BUTTON_PRESS) { - _drags->set (new EditorRubberbandSelectDrag (*this, get_trackview_group()), event); + _drags->set (new RubberbandSelectDrag (*this, get_trackview_group(), [&](GdkEvent* ev, timepos_t const & pos) { return this->rb_click (ev, pos); }), event); } else if (event->type == GDK_BUTTON_PRESS) { @@ -1004,7 +1004,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case StreamItem: - _drags->set (new EditorRubberbandSelectDrag (*this, item), event); + _drags->set (new RubberbandSelectDrag (*this, item, [&](GdkEvent* ev, timepos_t const & pos) { return this->rb_click (ev, pos); }), event); return true; case AutomationTrackItem: @@ -1032,7 +1032,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT } } else { /* rubberband drag to select automation points */ - _drags->set (new EditorRubberbandSelectDrag (*this, item), event); + _drags->set (new RubberbandSelectDrag (*this, item, [&](GdkEvent* ev, timepos_t const & pos) { return this->rb_click (ev, pos); }), event); } break; } diff --git a/gtk2_ardour/midi_cue_editor.cc b/gtk2_ardour/midi_cue_editor.cc index f0c0c73264..3efa590564 100644 --- a/gtk2_ardour/midi_cue_editor.cc +++ b/gtk2_ardour/midi_cue_editor.cc @@ -549,7 +549,7 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event switch (mouse_mode) { case Editing::MouseContent: /* rubberband drag to select automation points */ - _drags->set (new EditorRubberbandSelectDrag (*this, item), event); + _drags->set (new RubberbandSelectDrag (*this, item, [&](GdkEvent* ev, timepos_t const & pos) { return view->automation_rb_click (ev, pos); }), event); break; case Editing::MouseDraw: _drags->set (new AutomationDrawDrag (*this, nullptr, *static_cast(item), false, Temporal::BeatTime), event); @@ -1653,8 +1653,3 @@ MidiCueEditor::selectable_owners() return std::list (); } -bool -MidiCueEditor::rb_click (GdkEvent*, timepos_t const &) -{ - return false; -} diff --git a/gtk2_ardour/midi_cue_editor.h b/gtk2_ardour/midi_cue_editor.h index 0f8b6006d0..b09b9d3c88 100644 --- a/gtk2_ardour/midi_cue_editor.h +++ b/gtk2_ardour/midi_cue_editor.h @@ -100,8 +100,6 @@ class MidiCueEditor : public CueEditor std::list selectable_owners(); - bool rb_click (GdkEvent*, Temporal::timepos_t const &); - Gdk::Cursor* which_track_cursor () const; Gdk::Cursor* which_mode_cursor () const; Gdk::Cursor* which_trim_cursor (bool left_side) const; diff --git a/gtk2_ardour/midi_cue_view.cc b/gtk2_ardour/midi_cue_view.cc index d25b9b521a..08b9c36d55 100644 --- a/gtk2_ardour/midi_cue_view.cc +++ b/gtk2_ardour/midi_cue_view.cc @@ -309,3 +309,11 @@ MidiCueView::make_merger () [this](Temporal::timepos_t const& t) { return t; }, nullptr, nullptr); } + +bool +MidiCueView::automation_rb_click (GdkEvent* event, Temporal::timepos_t const & pos) +{ + automation_line->add (automation_control, event, pos, 0.5, true); + return false; +} + diff --git a/gtk2_ardour/midi_cue_view.h b/gtk2_ardour/midi_cue_view.h index 612fbd7b6c..a4ab5afea8 100644 --- a/gtk2_ardour/midi_cue_view.h +++ b/gtk2_ardour/midi_cue_view.h @@ -59,6 +59,8 @@ class MidiCueView : public MidiView std::list selectable_owners(); MergeableLine* make_merger (); + bool automation_rb_click (GdkEvent*, Temporal::timepos_t const &); + protected: bool scroll (GdkEventScroll* ev);