tweak behavior and naming of tempo-map drags:

* correctly handle clicks on the immediate right or left of a beat line
* prefer Mid-Twist and End-Stretch terminology over Twist and Linear
* static-tempo vs ramped-tempo is orthogonal to mid- and end- drags (TODO)
This commit is contained in:
Ben Loftis 2023-05-04 09:33:08 -05:00
parent 912f9e5ea3
commit a258b82ce9
4 changed files with 68 additions and 44 deletions

View File

@ -2547,8 +2547,7 @@ private:
friend class RegionMoveDrag;
friend class TrimDrag;
friend class MappingTwistDrag;
friend class MappingLinearDrag;
friend class MappingStretchDrag;
friend class MappingEndDrag;
friend class MeterMarkerDrag;
friend class BBTMarkerDrag;
friend class TempoMarkerDrag;

View File

@ -3476,7 +3476,7 @@ BBTMarkerDrag::aborted (bool moved)
/******************************************************************************/
MappingLinearDrag::MappingLinearDrag (Editor* e, ArdourCanvas::Item* i, Temporal::TempoMap::WritableSharedPtr& wmap, TempoPoint& tp, TempoPoint& ap, XMLNode& before)
MappingEndDrag::MappingEndDrag (Editor* e, ArdourCanvas::Item* i, Temporal::TempoMap::WritableSharedPtr& wmap, TempoPoint& tp, TempoPoint& ap, XMLNode& before)
: Drag (e, i, Temporal::BeatTime)
, _tempo (tp)
, _after (ap)
@ -3485,12 +3485,12 @@ MappingLinearDrag::MappingLinearDrag (Editor* e, ArdourCanvas::Item* i, Temporal
, _before_state (&before)
, _drag_valid (true)
{
DEBUG_TRACE (DEBUG::Drags, "New MappingLinearDrag\n");
DEBUG_TRACE (DEBUG::Drags, "New MappingEndDrag\n");
}
void
MappingLinearDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
MappingEndDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
{
Drag::start_grab (event, cursor);
@ -3509,7 +3509,7 @@ MappingLinearDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
}
void
MappingLinearDrag::setup_pointer_offset ()
MappingEndDrag::setup_pointer_offset ()
{
Beats grab_qn = max (Beats(), raw_grab_time().beats());
@ -3524,7 +3524,7 @@ MappingLinearDrag::setup_pointer_offset ()
}
void
MappingLinearDrag::motion (GdkEvent* event, bool first_move)
MappingEndDrag::motion (GdkEvent* event, bool first_move)
{
if (!_drag_valid) {
return;
@ -3554,7 +3554,7 @@ MappingLinearDrag::motion (GdkEvent* event, bool first_move)
}
void
MappingLinearDrag::finished (GdkEvent* event, bool movement_occurred)
MappingEndDrag::finished (GdkEvent* event, bool movement_occurred)
{
if (!_drag_valid) {
aborted (false);
@ -3576,7 +3576,7 @@ MappingLinearDrag::finished (GdkEvent* event, bool movement_occurred)
}
void
MappingLinearDrag::aborted (bool /* moved */)
MappingEndDrag::aborted (bool /* moved */)
{
_editor->abort_reversible_command ();
_editor->abort_tempo_mapping ();
@ -3600,7 +3600,8 @@ MappingTwistDrag::MappingTwistDrag (Editor* e, ArdourCanvas::Item* i, Temporal::
, _drag_valid (true)
{
DEBUG_TRACE (DEBUG::Drags, "New MappingTwistDrag\n");
initial_npm = focus.note_types_per_minute ();
initial_focus_npm = focus.note_types_per_minute ();
initial_pre_npm = prv.note_types_per_minute ();
}
void
@ -3630,13 +3631,15 @@ MappingTwistDrag::motion (GdkEvent* event, bool first_move)
if (_drags->current_pointer_x() < last_pointer_x()) {
if (direction < 0.) {
direction = 1.;
initial_npm += delta;
initial_focus_npm += delta;
initial_pre_npm += delta;
delta = 0.;
}
} else {
if (direction >= 0.) {
direction = -1.;
initial_npm += delta;
initial_focus_npm += delta;
initial_pre_npm += delta;
delta = 0.;
}
}
@ -3657,7 +3660,12 @@ MappingTwistDrag::motion (GdkEvent* event, bool first_move)
delta += scaling_factor * pixel_distance;
std::cerr << "pixels " << pixel_distance << " spp " << spp << " SF " << scaling_factor << " delta = " << delta << std::endl;
map->twist_tempi (prev, focus, next, initial_npm + delta);
bool do_a_ramp = true; // @ben
if (do_a_ramp) {
map->ramped_twist_tempi (prev, focus, next, initial_pre_npm + delta);
} else {
map->linear_twist_tempi (prev, focus, next, initial_focus_npm + delta);
}
_editor->mid_tempo_change (Editor::MappingChanged);
}

View File

@ -912,10 +912,10 @@ private:
XMLNode* _before_state;
};
class MappingLinearDrag : public Drag
class MappingEndDrag : public Drag
{
public:
MappingLinearDrag (Editor *, ArdourCanvas::Item *, Temporal::TempoMap::WritableSharedPtr&, Temporal::TempoPoint&, Temporal::TempoPoint& after, XMLNode& before_state);
MappingEndDrag (Editor *, ArdourCanvas::Item *, Temporal::TempoMap::WritableSharedPtr&, Temporal::TempoPoint&, Temporal::TempoPoint& after, XMLNode& before_state);
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);
@ -975,7 +975,8 @@ private:
double direction;
double delta;
double initial_npm;
double initial_focus_npm;
double initial_pre_npm;
XMLNode* _before_state;
bool _drag_valid;

View File

@ -2924,6 +2924,13 @@ Editor::get_pointer_position (double& x, double& y) const
void
Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
{
/* In a departure from convention, this event is not handled by a widget
* 'on' the ruler-bar, like a tempo marker, but is instead handled by the
* mapping-bar widget itself. The intent is for the user to feel that they
* are manipulating the 'beat and bar grid' which may or may not have tempo
* markers already assigned at the point under the mouse.
*/
if (item != mapping_bar) {
return;
}
@ -2935,9 +2942,9 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
Temporal::TempoMap::WritableSharedPtr map = begin_tempo_mapping ();
/* Decide between a tempo twist drag, which we do if the
* pointer is between two tempo markers, and a tempo stretch
* drag, which we do if the pointer is after the last tempo
/* Decide between a mid-twist, which we do if the
* pointer is between two tempo markers, and an end-stretch,
* which we do if the pointer is after the last tempo
* marker before the end of the map or a BBT Marker.
*/
@ -2952,17 +2959,38 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
TempoPoint* before;
TempoPoint* focus;
bool stretch = false;
bool at_end = false;
if (!after || dynamic_cast<MusicTimePoint*>(after)) {
stretch = true;
at_end = true;
}
BBT_Argument bbt = map->bbt_at (pointer_time);
bbt = BBT_Argument (bbt.reference(), bbt.round_to_beat ());
if (tempo.bbt() != bbt) {
/* BBT_Argument is meter-agnostic so we need to use the map's meter to resolve bar boundaries */
const Meter& m = map->meter_at (pointer_time);
if (bbt.beats > m.divisions_per_bar()){
bbt.beats = 1;
bbt.bars++;
}
if (tempo.bbt() == bbt) {
std::cerr << "we are on the RIGHT side of an EXISTING tempo marker" << bbt << " == " << tempo.bbt() << "\n";
before = const_cast<TempoPoint*> (map->previous_tempo (tempo));
focus = &tempo;
} else if ((after && after->bbt() == bbt )) {
std::cerr << "we are on the LEFT side of an EXISTING tempo marker" << bbt << " == " << after->bbt() << "\n";
before = const_cast<TempoPoint*> (&tempo);
focus = after;
after = const_cast<TempoPoint*> (map->next_tempo (*focus));
if (!after) {
at_end = true; //but it's the last one, so we're operating on the last
}
} else {
std::cerr << "ADD TEMPO MARKER " << bbt << " != " << tempo.bbt() << "\n";
/* Add a new tempo marker at the nearest beat point
@ -2978,32 +3006,20 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
reset_tempo_marks ();
map->dump (std::cerr);
} else {
std::cerr << "USE TEMPO MARKER\n";
before = const_cast<TempoPoint*> (map->previous_tempo (tempo));
if (!before) {
delete before_state;
return;
}
focus = &tempo;
}
/* Reversible commands start here, must be ended/aborted in drag */
if (stretch) {
begin_reversible_command (_("map tempo/stretch"));
std::cerr << "STRETCH\n";
_drags->set (new MappingLinearDrag (this, item, map, tempo, *focus, *before_state), event);
if (at_end) {
begin_reversible_command (_("tempo mapping: end-stretch"));
std::cerr << "END STRETCH\n";
_drags->set (new MappingEndDrag (this, item, map, tempo, *focus, *before_state), event);
return;
}
std::cerr << "TWIST\n";
begin_reversible_command (_("map tempo/twist"));
_drags->set (new MappingTwistDrag (this, item, map, *before, *focus, *after, *before_state), event);
if (before && focus && after) {
std::cerr << "TWIST\n";
begin_reversible_command (_("tempo mapping: mid-twist"));
_drags->set (new MappingTwistDrag (this, item, map, *before, *focus, *after, *before_state), event);
}
}