add ctrl-drag on tempo bar/ruler to adjust tempo more directly
This commit is contained in:
parent
ef07fb601a
commit
fdd634f530
|
@ -2493,6 +2493,7 @@ private:
|
||||||
friend class BBTRulerDrag;
|
friend class BBTRulerDrag;
|
||||||
friend class MeterMarkerDrag;
|
friend class MeterMarkerDrag;
|
||||||
friend class TempoMarkerDrag;
|
friend class TempoMarkerDrag;
|
||||||
|
friend class TempoCurveDrag;
|
||||||
friend class TempoTwistDrag;
|
friend class TempoTwistDrag;
|
||||||
friend class TempoEndDrag;
|
friend class TempoEndDrag;
|
||||||
friend class CursorDrag;
|
friend class CursorDrag;
|
||||||
|
|
|
@ -3530,6 +3530,83 @@ MeterMarkerDrag::aborted (bool moved)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TempoCurveDrag::TempoCurveDrag (Editor* e, ArdourCanvas::Item* i)
|
||||||
|
: Drag (e, i, Temporal::BeatTime)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TempoCurveDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
|
{
|
||||||
|
Drag::start_grab (event, cursor);
|
||||||
|
/* setup thread-local tempo map ptr as a writable copy */
|
||||||
|
map = _editor->begin_tempo_map_edit ();
|
||||||
|
TempoCurve* tc = reinterpret_cast<TempoCurve*> (_item->get_data (X_("tempo curve")));
|
||||||
|
if (!tc) {
|
||||||
|
point = const_cast<TempoPoint*> (&map->tempo_at (raw_grab_time()));
|
||||||
|
} else {
|
||||||
|
point = const_cast<TempoPoint*> (&tc->tempo());
|
||||||
|
}
|
||||||
|
initial_bpm = point->note_types_per_minute();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TempoCurveDrag::motion (GdkEvent* event, bool first_move)
|
||||||
|
{
|
||||||
|
if (first_move) {
|
||||||
|
/* get current state */
|
||||||
|
_before_state = &map->get_state();
|
||||||
|
_editor->begin_reversible_command (_("change tempo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
double new_bpm = std::max (1.5, initial_bpm - ((current_pointer_x() - grab_x()) / 5.0));
|
||||||
|
stringstream strs;
|
||||||
|
Temporal::Tempo new_tempo (new_bpm, point->note_type());
|
||||||
|
map->change_tempo (*point, new_tempo);
|
||||||
|
strs << "Tempo: " << fixed << setprecision(3) << new_bpm;
|
||||||
|
show_verbose_cursor_text (strs.str());
|
||||||
|
|
||||||
|
_editor->mid_tempo_change ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TempoCurveDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||||
|
{
|
||||||
|
if (!movement_occurred) {
|
||||||
|
/* reset the per-thread tempo map ptr back to the current
|
||||||
|
* official version
|
||||||
|
*/
|
||||||
|
|
||||||
|
_editor->abort_tempo_map_edit ();
|
||||||
|
|
||||||
|
if (was_double_click()) {
|
||||||
|
// XXX would be nice to do this
|
||||||
|
// _editor->edit_tempo_marker (*_marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* push the current state of our writable map copy */
|
||||||
|
|
||||||
|
TempoMap::update (map);
|
||||||
|
XMLNode &after = map->get_state();
|
||||||
|
|
||||||
|
_editor->session()->add_command (new Temporal::TempoCommand (_("change tempo"), _before_state, &after));
|
||||||
|
_editor->commit_reversible_command ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TempoCurveDrag::aborted (bool moved)
|
||||||
|
{
|
||||||
|
/* reset the per-thread tempo map ptr back to the current
|
||||||
|
* official version
|
||||||
|
*/
|
||||||
|
|
||||||
|
_editor->abort_tempo_map_edit ();
|
||||||
|
}
|
||||||
|
|
||||||
TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i)
|
TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i)
|
||||||
: Drag (e, i, Temporal::BeatTime)
|
: Drag (e, i, Temporal::BeatTime)
|
||||||
, _grab_bpm (120.0, 4.0)
|
, _grab_bpm (120.0, 4.0)
|
||||||
|
|
|
@ -76,6 +76,7 @@ class MidiRegionView;
|
||||||
class MeterMarker;
|
class MeterMarker;
|
||||||
class ArdourMarker;
|
class ArdourMarker;
|
||||||
class TempoMarker;
|
class TempoMarker;
|
||||||
|
class TempoCurve;
|
||||||
class ControlPoint;
|
class ControlPoint;
|
||||||
class AudioRegionView;
|
class AudioRegionView;
|
||||||
class AutomationLine;
|
class AutomationLine;
|
||||||
|
@ -860,6 +861,24 @@ private:
|
||||||
XMLNode* before_state;
|
XMLNode* before_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Tempo curve drag */
|
||||||
|
class TempoCurveDrag : public Drag
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TempoCurveDrag (Editor*, ArdourCanvas::Item*);
|
||||||
|
|
||||||
|
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||||
|
void motion (GdkEvent *, bool);
|
||||||
|
void finished (GdkEvent *, bool);
|
||||||
|
void aborted (bool);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Temporal::TempoPoint* point;
|
||||||
|
double initial_bpm;
|
||||||
|
Temporal::TempoMap::WritableSharedPtr map;
|
||||||
|
XMLNode* _before_state;
|
||||||
|
};
|
||||||
|
|
||||||
/** Tempo marker drag */
|
/** Tempo marker drag */
|
||||||
class TempoMarkerDrag : public Drag
|
class TempoMarkerDrag : public Drag
|
||||||
{
|
{
|
||||||
|
|
|
@ -816,9 +816,14 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MarkerBarItem:
|
|
||||||
case TempoBarItem:
|
case TempoBarItem:
|
||||||
case TempoCurveItem:
|
case TempoCurveItem:
|
||||||
|
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
|
||||||
|
_drags->set (new TempoCurveDrag (this, item), event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/* fallthru */
|
||||||
|
case MarkerBarItem:
|
||||||
case MeterBarItem:
|
case MeterBarItem:
|
||||||
case TimecodeRulerItem:
|
case TimecodeRulerItem:
|
||||||
case SamplesRulerItem:
|
case SamplesRulerItem:
|
||||||
|
|
|
@ -99,13 +99,14 @@ TempoCurve::TempoCurve (PublicEditor& ed, ArdourCanvas::Item& parent, guint32 rg
|
||||||
* make sure they can both be used to lookup this object.
|
* make sure they can both be used to lookup this object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_curve->set_data ("tempo curve", this);
|
_curve->set_data (X_("tempo curve"), this);
|
||||||
|
|
||||||
if (handle_events) {
|
if (handle_events) {
|
||||||
//group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_marker_event), group, this));
|
// group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_marker_event), group, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_curve_event), _curve, this));
|
group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_curve_event), _curve, this));
|
||||||
|
_curve->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_curve_event), _curve, this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user