13
0

allow dragging in MIDI automation line in cue editor

Note: once this is cleaned up and checked with respect to snap and more,
the same should be done for MidiRegionView
This commit is contained in:
Paul Davis 2024-10-07 16:28:54 -06:00
parent 4b8c51574d
commit b8fb779fa7
10 changed files with 87 additions and 66 deletions

View File

@ -63,11 +63,11 @@ class PublicEditor;
class EditorAutomationLine : public AutomationLine
{
public:
EditorAutomationLine (const std::string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
std::shared_ptr<ARDOUR::AutomationList> al,
const ARDOUR::ParameterDescriptor& desc);
EditorAutomationLine (const std::string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
std::shared_ptr<ARDOUR::AutomationList> al,
const ARDOUR::ParameterDescriptor& desc);
virtual ~EditorAutomationLine ();

View File

@ -101,7 +101,7 @@ MergeableLine::merge_drawn_line (EditingContext& e, Session& s, Evoral::ControlL
XMLNode& after = list->get_state();
e.begin_reversible_command (_("draw automation"));
s.add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
e.add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
_line->end_draw_merge ();

View File

@ -26,7 +26,7 @@
#include "ardour/types.h"
class EditorAutomationLine;
class AutomationLine;
class RouteTimeAxisView;
class EditingContext;
@ -38,7 +38,7 @@ class AutomationControl;
class MergeableLine
{
public:
MergeableLine (std::shared_ptr<EditorAutomationLine> l, std::shared_ptr<ARDOUR::AutomationControl> c,
MergeableLine (std::shared_ptr<AutomationLine> l, std::shared_ptr<ARDOUR::AutomationControl> c,
std::function<Temporal::timepos_t(Temporal::timepos_t const &)> tf,
std::function<void(ARDOUR::AutoState)> asc,
std::function<void()> ctc)
@ -53,7 +53,7 @@ class MergeableLine
void merge_drawn_line (EditingContext& e, ARDOUR::Session& s, Evoral::ControlList::OrderedPoints& points, bool thin);
private:
std::shared_ptr<EditorAutomationLine> _line;
std::shared_ptr<AutomationLine> _line;
std::shared_ptr<ARDOUR::AutomationControl> _control;
std::function<Temporal::timepos_t(Temporal::timepos_t const &)> time_filter;
std::function<void(ARDOUR::AutoState)> automation_state_callback;

View File

@ -29,7 +29,7 @@ MidiCueAutomationLine::MidiCueAutomationLine (const std::string&
ArdourCanvas::Rectangle* drag_base,
std::shared_ptr<ARDOUR::AutomationList> al,
const ARDOUR::ParameterDescriptor& desc)
: AutomationLine (name, ec, parent, drag_base, al, desc)
: AutomationLine (name, ec, parent, drag_base, al, desc)
{
_drag_base->set_data ("line", this);
_drag_base->Event.connect (sigc::mem_fun (*this, &MidiCueAutomationLine::base_event_handler));

View File

@ -510,9 +510,9 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event
{
NoteBase* note = nullptr;
if (mouse_mode == Editing::MouseContent) {
switch (item_type) {
case NoteItem:
switch (item_type) {
case NoteItem:
if (mouse_mode == Editing::MouseContent) {
/* Existing note: allow trimming/motion */
if ((note = reinterpret_cast<NoteBase*> (item->get_data ("notebase")))) {
if (note->big_enough_to_trim() && note->mouse_near_ends()) {
@ -523,47 +523,51 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event
_drags->set (nd, event);
}
}
return true;
case ControlPointItem:
_drags->set (new ControlPointDrag (*this, item), event);
return true;
break;
case VelocityItem:
_drags->set (new LollipopDrag (*this, item), event);
return true;
break;
case VelocityBaseItem:
_drags->set (new VelocityLineDrag (*this, *static_cast<ArdourCanvas::Rectangle*>(item), false, Temporal::BeatTime), event);
return true;
break;
case AutomationTrackItem:
switch (mouse_mode) {
case Editing::MouseContent:
/* rubberband drag to select automation points */
// _drags->set (new EditorRubberbandSelectDrag (*this, item), event);
break;
case Editing::MouseDraw:
_drags->set (new AutomationDrawDrag (*this, nullptr, *static_cast<ArdourCanvas::Rectangle*>(item), false, Temporal::BeatTime), event);
break;
default:
break;
}
return true;
break;
case EditorAutomationLineItem: {
ARDOUR::SelectionOperation op = ArdourKeyboard::selection_type (event->button.state);
select_automation_line (&event->button, item, op);
return true;
}
return true;
case ControlPointItem:
if (mouse_mode == Editing::MouseContent) {
_drags->set (new ControlPointDrag (*this, item), event);
}
return true;
break;
case VelocityItem:
if (mouse_mode == Editing::MouseContent) {
_drags->set (new LollipopDrag (*this, item), event);
}
return true;
break;
case VelocityBaseItem:
_drags->set (new VelocityLineDrag (*this, *static_cast<ArdourCanvas::Rectangle*>(item), false, Temporal::BeatTime), event);
return true;
break;
case AutomationTrackItem:
switch (mouse_mode) {
case Editing::MouseContent:
/* rubberband drag to select automation points */
_drags->set (new EditorRubberbandSelectDrag (*this, item), event);
break;
case Editing::MouseDraw:
_drags->set (new AutomationDrawDrag (*this, nullptr, *static_cast<ArdourCanvas::Rectangle*>(item), false, Temporal::BeatTime), event);
break;
default:
break;
}
return true;
break;
case EditorAutomationLineItem: {
ARDOUR::SelectionOperation op = ArdourKeyboard::selection_type (event->button.state);
select_automation_line (&event->button, item, op);
return true;
}
default:
break;
}
return false;

View File

@ -29,6 +29,7 @@
#include "editor_drag.h"
#include "hit.h"
#include "keyboard.h"
#include "mergeable_line.h"
#include "midi_cue_automation_line.h"
#include "midi_cue_view.h"
#include "midi_cue_velocity.h"
@ -48,7 +49,6 @@ MidiCueView::MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt,
MidiViewBackground& bg,
uint32_t basic_color)
: MidiView (mt, parent, ec, bg, basic_color)
, automation_line (nullptr)
, velocity_base (nullptr)
, velocity_display (nullptr)
, _slot_index (slot_index)
@ -72,6 +72,7 @@ MidiCueView::MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt,
automation_group = new ArdourCanvas::Rectangle (&parent);
CANVAS_DEBUG_NAME (automation_group, "cue automation group");
automation_group->set_fill_color (UIConfiguration::instance().color ("midi automation track fill"));
automation_group->set_data ("linemerger", this);
velocity_base = new ArdourCanvas::Rectangle (&parent);
CANVAS_DEBUG_NAME (velocity_base, "cue velocity base");
@ -249,10 +250,8 @@ MidiCueView::show_automation (Evoral::Parameter const & param)
// return;
// }
if (automation_line) {
delete automation_line;
automation_line = nullptr;
}
automation_line.reset ();
automation_control.reset ();
std::shared_ptr<AutomationControl> control;
@ -274,18 +273,17 @@ MidiCueView::show_automation (Evoral::Parameter const & param)
*/
std::shared_ptr<Evoral::Control> control = _midi_region->model()->control (param, true);
std::shared_ptr<AutomationControl> ac = std::dynamic_pointer_cast<AutomationControl> (control);
automation_control = std::dynamic_pointer_cast<AutomationControl> (control);
if (ac) {
automation_line = new MidiCueAutomationLine ("whatevs",
_editing_context,
*automation_group,
automation_group,
ac->alist(),
ac->desc());
if (automation_control) {
automation_line.reset (new MidiCueAutomationLine ("whatevs",
_editing_context,
*automation_group,
automation_group,
automation_control->alist(),
automation_control->desc()));
automation_line->set_height (automation_group->get().height());
}
break;
}
@ -299,7 +297,15 @@ MidiCueView::selectable_owners()
{
std::list<SelectableOwner*> sl;
if (automation_line) {
sl.push_back (automation_line);
sl.push_back (automation_line.get());
}
return sl;
}
MergeableLine*
MidiCueView::make_merger ()
{
return new MergeableLine (automation_line, automation_control,
[this](Temporal::timepos_t const& t) { return t; },
nullptr, nullptr);
}

View File

@ -57,12 +57,14 @@ class MidiCueView : public MidiView
ArdourCanvas::Item* drag_group() const;
std::list<SelectableOwner*> selectable_owners();
MergeableLine* make_merger ();
protected:
bool scroll (GdkEventScroll* ev);
ArdourCanvas::Rectangle* automation_group;
MidiCueAutomationLine* automation_line;
std::shared_ptr<MidiCueAutomationLine> automation_line;
std::shared_ptr<ARDOUR::AutomationControl> automation_control;
ArdourCanvas::Rectangle* velocity_base;
VelocityDisplay* velocity_display;

View File

@ -756,3 +756,9 @@ MidiRegionView::set_visibility_note_range (MidiViewBackground::VisibleNoteRange
{
dynamic_cast<MidiTimeAxisView*>(&trackview)->set_visibility_note_range (vnr, from_selection);
}
MergeableLine*
MidiRegionView::make_merger ()
{
return nullptr;
}

View File

@ -132,6 +132,8 @@ public:
void set_visibility_note_range (MidiViewBackground::VisibleNoteRange, bool);
MergeableLine* make_merger ();
protected:
void reset_width_dependent_items (double pixel_width);
void parameter_changed (std::string const & p);

View File

@ -43,6 +43,7 @@
#include "time_axis_view_item.h"
#include "editor_automation_line.h"
#include "enums.h"
#include "line_merger.h"
namespace ARDOUR {
class MidiRegion;
@ -75,7 +76,7 @@ class VelocityGhostRegion;
class EditingContext;
class PasteContext;
class MidiView : public virtual sigc::trackable
class MidiView : public virtual sigc::trackable, public LineMerger
{
public:
typedef Evoral::Note<Temporal::Beats> NoteType;