refactor rubberband drags to take a functor for the no-drag condition
Also move code for adding automation line control points into automation line, rather than in AutomationTimeAxisView (some work still required to finalize this)
This commit is contained in:
parent
e6c0fcf98f
commit
2afdeb519f
@ -1512,3 +1512,59 @@ AutomationLine::set_offset (timepos_t const & off)
|
||||
_offset = off;
|
||||
reset ();
|
||||
}
|
||||
|
||||
void
|
||||
AutomationLine::add (std::shared_ptr<AutomationControl> 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<Selectable*> 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<ARDOUR::AutomationList> (*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 ();
|
||||
}
|
||||
}
|
||||
|
@ -177,6 +177,8 @@ public:
|
||||
ARDOUR::ParameterDescriptor const & param() const { return _desc; }
|
||||
EditingContext& editing_context() const { return _editing_context; }
|
||||
|
||||
void add (std::shared_ptr<ARDOUR::AutomationControl>, GdkEvent*, Temporal::timepos_t const &, double y, bool with_guard_points);
|
||||
|
||||
protected:
|
||||
|
||||
std::string _name;
|
||||
|
@ -797,56 +797,7 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, timepos_t const &
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<AutomationList> 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<Selectable*> 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<ARDOUR::AutomationList> (*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
|
||||
|
@ -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 &);
|
||||
|
||||
|
@ -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<bool(GdkEvent*,timepos_t const &)> 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)
|
||||
|
@ -1286,7 +1286,7 @@ private:
|
||||
class RubberbandSelectDrag : public Drag
|
||||
{
|
||||
public:
|
||||
RubberbandSelectDrag (EditingContext&, ArdourCanvas::Item *);
|
||||
RubberbandSelectDrag (EditingContext&, ArdourCanvas::Item *, std::function<bool(GdkEvent*,Temporal::timepos_t const &)> 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<bool(GdkEvent*,Temporal::timepos_t const &)> 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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<ArdourCanvas::Rectangle*>(item), false, Temporal::BeatTime), event);
|
||||
@ -1653,8 +1653,3 @@ MidiCueEditor::selectable_owners()
|
||||
return std::list<SelectableOwner*> ();
|
||||
}
|
||||
|
||||
bool
|
||||
MidiCueEditor::rb_click (GdkEvent*, timepos_t const &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -100,8 +100,6 @@ class MidiCueEditor : public CueEditor
|
||||
|
||||
std::list<SelectableOwner*> 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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,8 @@ class MidiCueView : public MidiView
|
||||
std::list<SelectableOwner*> selectable_owners();
|
||||
MergeableLine* make_merger ();
|
||||
|
||||
bool automation_rb_click (GdkEvent*, Temporal::timepos_t const &);
|
||||
|
||||
protected:
|
||||
bool scroll (GdkEventScroll* ev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user