initial refactoring of freehand line drawing

This sets the state to use it with MIDI CC and region gain.

class names LineMerger and MergeableLine need revisiting
This commit is contained in:
Paul Davis 2023-09-29 09:39:07 -06:00
parent 2b2112e303
commit 944fcf251d
5 changed files with 25 additions and 71 deletions

View File

@ -58,6 +58,7 @@
#include "automation_streamview.h"
#include "ghostregion.h"
#include "gui_thread.h"
#include "mergeable_line.h"
#include "route_time_axis.h"
#include "automation_line.h"
#include "paste_context.h"
@ -84,7 +85,6 @@ using namespace Editing;
Pango::FontDescription AutomationTimeAxisView::name_font;
bool AutomationTimeAxisView::have_name_font = false;
/** \a a the automatable object this time axis is to display data for.
* For route/track automation (e.g. gain) pass the route for both \r and \a.
* For route child (e.g. plugin) automation, pass the child for \a.
@ -789,73 +789,6 @@ AutomationTimeAxisView::build_display_menu ()
}
}
void
AutomationTimeAxisView::merge_drawn_line (Evoral::ControlList::OrderedPoints& points, bool thin)
{
if (points.empty()) {
return;
}
if (!_line) {
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;
}
XMLNode& before = list->get_state();
std::list<Selectable*> results;
Temporal::timepos_t earliest = points.front().when;
Temporal::timepos_t latest = points.back().when;
if (earliest > latest) {
swap (earliest, latest);
}
/* Convert each point's "value" from geometric coordinate space to
* value space for the control
*/
for (auto & dp : points) {
/* compute vertical fractional position */
dp.value = 1.0 - (dp.value / _line->height());
/* map using line */
_line->view_to_model_coord_y (dp.value);
}
list->freeze ();
list->editor_add_ordered (points, false);
if (thin) {
list->thin (Config->get_automation_thinning_factor());
}
list->thaw ();
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 (_("draw automation"));
_session->add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
_line->get_selectables (earliest, latest, 0.0, 1.0, results);
_editor.get_selection ().set (results);
_editor.commit_reversible_command ();
_session->set_dirty ();
}
void
AutomationTimeAxisView::add_automation_event (GdkEvent* event, timepos_t const & pos, double y, bool with_guard_points)
{
@ -1348,3 +1281,10 @@ AutomationTimeAxisView::set_selected_regionviews (RegionSelection& rs)
}
}
}
MergeableLine*
AutomationTimeAxisView::make_merger ()
{
return new MergeableLine (_line, _control, boost::bind (&AutomationTimeAxisView::set_automation_state, this, _1), boost::bind (RouteTimeAxisView::signal_ctrl_touched, false));
}

View File

@ -40,6 +40,7 @@
#include "widgets/ardour_button.h"
#include "widgets/ardour_dropdown.h"
#include "line_merger.h"
#include "time_axis_view.h"
#include "automation_controller.h"
@ -60,7 +61,7 @@ class AutomationStreamView;
class AutomationController;
class ItemCounts;
class AutomationTimeAxisView : public TimeAxisView
class AutomationTimeAxisView : public TimeAxisView, public LineMerger
{
public:
AutomationTimeAxisView (ARDOUR::Session*,
@ -147,7 +148,7 @@ public:
void set_selected_regionviews (RegionSelection&);
void merge_drawn_line (Evoral::ControlList::OrderedPoints&, bool thin);
MergeableLine* make_merger ();
protected:
/* Note that for MIDI controller "automation" (in regions), all of these

View File

@ -68,6 +68,7 @@
#include "editor_drag.h"
#include "gui_thread.h"
#include "keyboard.h"
#include "mergeable_line.h"
#include "midi_region_view.h"
#include "midi_selection.h"
#include "midi_time_axis.h"
@ -7456,13 +7457,16 @@ AutomationDrawDrag::finished (GdkEvent* event, bool motion_occured)
}
AutomationTimeAxisView* atv = static_cast<AutomationTimeAxisView*>(base_rect.get_data ("trackview"));
if (!atv) {
return;
}
FreehandLineDrag<Evoral::ControlList::OrderedPoints,Evoral::ControlList::OrderedPoint>::finished (event, motion_occured);
atv->merge_drawn_line (drawn_points, !did_snap);
MergeableLine* ml = atv->make_merger ();
ml->merge_drawn_line (*_editor, *_editor->session(), drawn_points, !did_snap);
delete ml;
}
/*****************/

View File

@ -1385,6 +1385,14 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
_drags->set (new RegionCreateDrag (this, item, clicked_axisview), event);
}
return true;
case RegionItem: {
RegionView* rv;
if ((rv = dynamic_cast<RegionView*> (clicked_regionview))) {
ArdourCanvas::Rectangle* r = static_cast <ArdourCanvas::Rectangle*> (rv->get_canvas_frame());
_drags->set (new AutomationDrawDrag (this, *r, Temporal::AudioTime), event);
}
}
break;
default:
break;

View File

@ -152,6 +152,7 @@ gtk2_ardour_sources = [
'main.cc',
'main_clock.cc',
'marker.cc',
'mergeable_line.cc',
'midi_automation_line.cc',
'midi_channel_dialog.cc',
'midi_channel_selector.cc',