mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
Fix automation range drag and implement for MIDI.
Range select rect sticks around now after switching to the draw tool, but disappears if a note selection is made. Not sure if draw is really the most appropriate tool here (particularly if we ever implement actual pencil-like drawing); edit contents seems more appropriate but that would probably cause more selection issues, so here we are.
This commit is contained in:
parent
88e6995b14
commit
d39d4c1c11
3 changed files with 63 additions and 41 deletions
|
|
@ -47,6 +47,7 @@
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "audio_region_view.h"
|
#include "audio_region_view.h"
|
||||||
|
#include "automation_region_view.h"
|
||||||
#include "midi_region_view.h"
|
#include "midi_region_view.h"
|
||||||
#include "ardour_ui.h"
|
#include "ardour_ui.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
|
|
@ -4849,24 +4850,36 @@ NoteDrag::aborted (bool)
|
||||||
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView* atv, list<AudioRange> const & r)
|
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView* atv, list<AudioRange> const & r)
|
||||||
: Drag (editor, atv->base_item ())
|
: Drag (editor, atv->base_item ())
|
||||||
, _ranges (r)
|
, _ranges (r)
|
||||||
|
, _y_origin (atv->y_position())
|
||||||
, _nothing_to_drag (false)
|
, _nothing_to_drag (false)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
|
||||||
y_origin = atv->y_position();
|
|
||||||
setup (atv->lines ());
|
setup (atv->lines ());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Make an AutomationRangeDrag for region gain lines */
|
/** Make an AutomationRangeDrag for region gain lines or MIDI controller regions */
|
||||||
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AudioRegionView* rv, list<AudioRange> const & r)
|
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list<AudioRange> const & r)
|
||||||
: Drag (editor, rv->get_canvas_group ())
|
: Drag (editor, rv->get_canvas_group ())
|
||||||
, _ranges (r)
|
, _ranges (r)
|
||||||
|
, _y_origin (rv->get_time_axis_view().y_position())
|
||||||
, _nothing_to_drag (false)
|
, _nothing_to_drag (false)
|
||||||
|
, _integral (false)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
|
||||||
|
|
||||||
list<boost::shared_ptr<AutomationLine> > lines;
|
list<boost::shared_ptr<AutomationLine> > lines;
|
||||||
lines.push_back (rv->get_gain_line ());
|
|
||||||
y_origin = rv->get_time_axis_view().y_position();
|
AudioRegionView* audio_view;
|
||||||
|
AutomationRegionView* automation_view;
|
||||||
|
if ((audio_view = dynamic_cast<AudioRegionView*>(rv))) {
|
||||||
|
lines.push_back (audio_view->get_gain_line ());
|
||||||
|
} else if ((automation_view = dynamic_cast<AutomationRegionView*>(rv))) {
|
||||||
|
lines.push_back (automation_view->line ());
|
||||||
|
_integral = true;
|
||||||
|
} else {
|
||||||
|
error << _("Automation range drag created for invalid region type") << endmsg;
|
||||||
|
}
|
||||||
|
|
||||||
setup (lines);
|
setup (lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4911,7 +4924,14 @@ AutomationRangeDrag::setup (list<boost::shared_ptr<AutomationLine> > const & lin
|
||||||
double
|
double
|
||||||
AutomationRangeDrag::y_fraction (boost::shared_ptr<AutomationLine> line, double global_y) const
|
AutomationRangeDrag::y_fraction (boost::shared_ptr<AutomationLine> line, double global_y) const
|
||||||
{
|
{
|
||||||
return 1.0 - ((global_y - y_origin) / line->height());
|
return 1.0 - ((global_y - _y_origin) / line->height());
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
AutomationRangeDrag::value (boost::shared_ptr<AutomationList> list, double x) const
|
||||||
|
{
|
||||||
|
const double v = list->eval(x);
|
||||||
|
return _integral ? rint(v) : v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -4962,8 +4982,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
double const p = j->line->time_converter().from (i->start - j->line->time_converter().origin_b ());
|
double const p = j->line->time_converter().from (i->start - j->line->time_converter().origin_b ());
|
||||||
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
|
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
|
||||||
|
|
||||||
the_list->editor_add (p, the_list->eval (p));
|
the_list->editor_add (p, value (the_list, p));
|
||||||
the_list->editor_add (q, the_list->eval (q));
|
the_list->editor_add (q, value (the_list, q));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* same thing for the end */
|
/* same thing for the end */
|
||||||
|
|
@ -4988,8 +5008,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
double const p = j->line->time_converter().from (b - j->line->time_converter().origin_b ());
|
double const p = j->line->time_converter().from (b - j->line->time_converter().origin_b ());
|
||||||
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
|
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
|
||||||
|
|
||||||
the_list->editor_add (p, the_list->eval (p));
|
the_list->editor_add (p, value (the_list, p));
|
||||||
the_list->editor_add (q, the_list->eval (q));
|
the_list->editor_add (q, value (the_list, q));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1041,7 +1041,7 @@ class AutomationRangeDrag : public Drag
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list<ARDOUR::AudioRange> const &);
|
AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list<ARDOUR::AudioRange> const &);
|
||||||
AutomationRangeDrag (Editor *, AudioRegionView *, std::list<ARDOUR::AudioRange> const &);
|
AutomationRangeDrag (Editor *, RegionView *, std::list<ARDOUR::AudioRange> const &);
|
||||||
|
|
||||||
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||||
void motion (GdkEvent *, bool);
|
void motion (GdkEvent *, bool);
|
||||||
|
|
@ -1054,7 +1054,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup (std::list<boost::shared_ptr<AutomationLine> > const &);
|
void setup (std::list<boost::shared_ptr<AutomationLine> > const &);
|
||||||
double y_fraction (boost::shared_ptr<AutomationLine>, double global_y_position) const;
|
double y_fraction (boost::shared_ptr<AutomationLine>, double global_y_position) const;
|
||||||
|
double value (boost::shared_ptr<ARDOUR::AutomationList> list, double x) const;
|
||||||
|
|
||||||
std::list<ARDOUR::AudioRange> _ranges;
|
std::list<ARDOUR::AudioRange> _ranges;
|
||||||
|
|
||||||
|
|
@ -1068,8 +1069,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::list<Line> _lines;
|
std::list<Line> _lines;
|
||||||
double y_origin;
|
double _y_origin;
|
||||||
bool _nothing_to_drag;
|
bool _nothing_to_drag;
|
||||||
|
bool _integral;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Drag of one edge of an xfade
|
/** Drag of one edge of an xfade
|
||||||
|
|
|
||||||
|
|
@ -336,29 +336,28 @@ void
|
||||||
Editor::update_time_selection_display ()
|
Editor::update_time_selection_display ()
|
||||||
{
|
{
|
||||||
switch (mouse_mode) {
|
switch (mouse_mode) {
|
||||||
case MouseRange:
|
case MouseRange:
|
||||||
selection->clear_objects ();
|
selection->clear_objects ();
|
||||||
selection->ClearMidiNoteSelection(); //signal
|
selection->ClearMidiNoteSelection (); /* EMIT SIGNAL */
|
||||||
break;
|
break;
|
||||||
case MouseObject:
|
case MouseObject:
|
||||||
selection->clear_objects ();
|
selection->clear_objects ();
|
||||||
selection->clear_time ();
|
selection->clear_time ();
|
||||||
selection->clear_tracks ();
|
selection->clear_tracks ();
|
||||||
selection->ClearMidiNoteSelection(); //signal
|
selection->ClearMidiNoteSelection (); /* EMIT SIGNAL */
|
||||||
break;
|
break;
|
||||||
case MouseContent:
|
case MouseDraw:
|
||||||
case MouseDraw:
|
/* Clear top level objects, but not time or tracks, since that
|
||||||
//if we go into internal editing, clear everything in the outside world
|
woulddestroy the range selection rectangle, which we need to stick
|
||||||
selection->clear_objects ();
|
around for AutomationRangeDrag. */
|
||||||
selection->clear_time ();
|
selection->clear_objects ();
|
||||||
selection->clear_tracks ();
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
/* Clear everything. */
|
||||||
//clear everything
|
selection->clear_objects ();
|
||||||
selection->clear_objects ();
|
selection->clear_time ();
|
||||||
selection->clear_time ();
|
selection->clear_tracks ();
|
||||||
selection->clear_tracks ();
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -920,12 +919,13 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
|
|
||||||
case SelectionItem:
|
case SelectionItem:
|
||||||
{
|
{
|
||||||
AudioRegionView* arv = dynamic_cast<AudioRegionView *> (clicked_regionview);
|
if (dynamic_cast<AudioRegionView*>(clicked_regionview) ||
|
||||||
if (arv) {
|
dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
|
||||||
_drags->set (new AutomationRangeDrag (this, arv, selection->time), event, _cursors->up_down);
|
_drags->set (new AutomationRangeDrag (this, clicked_regionview, selection->time),
|
||||||
|
event, _cursors->up_down);
|
||||||
} else {
|
} else {
|
||||||
double const y = event->button.y;
|
double const y = event->button.y;
|
||||||
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
|
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y, false);
|
||||||
if (tvp.first) {
|
if (tvp.first) {
|
||||||
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
|
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
|
||||||
if ( atv) {
|
if ( atv) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue