rework handling of scroll and drag on AudioClock by using timepos_t rather than samples

This commit is contained in:
Paul Davis 2021-03-17 17:26:33 -06:00
parent 0ab2308523
commit 3a94b45b23
2 changed files with 35 additions and 42 deletions

View file

@ -674,7 +674,7 @@ AudioClock::parse_as_timecode_distance (const std::string& str)
sscanf (str.c_str(), "%" PRId32, &samples); sscanf (str.c_str(), "%" PRId32, &samples);
ret = llrint ((samples/(float)fps) * sr); ret = llrint ((samples/(float)fps) * sr);
break; break;
case 3: case 3:
sscanf (str.c_str(), "%1" PRId32 "%" PRId32, &secs, &samples); sscanf (str.c_str(), "%1" PRId32 "%" PRId32, &secs, &samples);
ret = (secs * sr) + llrint ((samples/(float)fps) * sr); ret = (secs * sr) + llrint ((samples/(float)fps) * sr);
@ -1777,34 +1777,32 @@ AudioClock::on_scroll_event (GdkEventScroll *ev)
} }
Field f = index_to_field (index); Field f = index_to_field (index);
samplepos_t samples = 0; timepos_t step;
switch (ev->direction) { switch (ev->direction) {
#warning NUTEMPO THIS SHOULD BE REVISITED FOR BeatTime
case GDK_SCROLL_UP: case GDK_SCROLL_UP:
samples = get_sample_step (f, current_time(), 1); step = get_incremental_step (f, current_time(), 1);
if (samples != 0) { if (!step.zero()) {
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
samples *= 10; step *= 10;
} }
AudioClock::set (current_time() + timepos_t (samples), true); AudioClock::set (current_time() + step, true);
ValueChanged (); /* EMIT_SIGNAL */ ValueChanged (); /* EMIT_SIGNAL */
} }
break; break;
case GDK_SCROLL_DOWN: case GDK_SCROLL_DOWN:
samples = get_sample_step (f, current_time(), -1); step = get_incremental_step (f, current_time(), -1);
if (samples != 0) { if (!step.zero()) {
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
samples *= 10; step *= 10;
} }
if (!_negative_allowed && current_time().samples() < samples) { if (!_negative_allowed && current_time() < step) {
AudioClock::set (timepos_t (), true); AudioClock::set (timepos_t (), true);
} else { } else {
AudioClock::set (current_time().earlier (timepos_t (samples)), true); AudioClock::set (current_time().earlier (step), true);
} }
ValueChanged (); /* EMIT_SIGNAL */ ValueChanged (); /* EMIT_SIGNAL */
@ -1846,15 +1844,15 @@ AudioClock::on_motion_notify_event (GdkEventMotion *ev)
if (floor (drag_accum) != 0) { if (floor (drag_accum) != 0) {
samplepos_t samples; timepos_t step;
timepos_t pos; timepos_t pos;
int dir; int dir;
dir = (drag_accum < 0 ? 1:-1); dir = (drag_accum < 0 ? 1:-1);
pos = current_time(); pos = current_time();
samples = get_sample_step (drag_field, pos, dir); step = get_incremental_step (drag_field, pos, dir);
if (samples != 0 && timepos_t (samples * drag_accum) < current_time()) { if (!step.zero() && timepos_t (step * drag_accum) < current_time()) {
AudioClock::set (timepos_t (pos.earlier (timepos_t ((samplecnt_t) floor (drag_accum * samples)))), false); // minus because up is negative in GTK AudioClock::set (pos.earlier (step * drag_accum), false); // minus/earlier because up is negative in GTK
} else { } else {
AudioClock::set (timepos_t () , false); AudioClock::set (timepos_t () , false);
} }
@ -1866,70 +1864,65 @@ AudioClock::on_motion_notify_event (GdkEventMotion *ev)
return true; return true;
} }
samplepos_t timepos_t
AudioClock::get_sample_step (Field field, timepos_t const & pos, int dir) AudioClock::get_incremental_step (Field field, timepos_t const & pos, int dir)
{ {
samplecnt_t f = 0; timepos_t f;
Temporal::BBT_Time BBT; Temporal::BBT_Time BBT;
switch (field) { switch (field) {
case Timecode_Hours: case Timecode_Hours:
f = (samplecnt_t) floor (3600.0 * _session->sample_rate()); f = timepos_t (floor (3600.0 * _session->sample_rate()));
break; break;
case Timecode_Minutes: case Timecode_Minutes:
f = (samplecnt_t) floor (60.0 * _session->sample_rate()); f = timepos_t (floor (60.0 * _session->sample_rate()));
break; break;
case Timecode_Seconds: case Timecode_Seconds:
f = _session->sample_rate(); f = timepos_t (_session->sample_rate());
break; break;
case Timecode_frames: case Timecode_frames:
f = (samplecnt_t) floor (_session->sample_rate() / _session->timecode_frames_per_second()); f = timepos_t (floor (_session->sample_rate() / _session->timecode_frames_per_second()));
break; break;
case S_Samples: case S_Samples:
f = 1; f = timepos_t (1);
break; break;
case SS_Seconds: case SS_Seconds:
f = (samplecnt_t) _session->sample_rate(); f = timepos_t (_session->sample_rate());
break; break;
case SS_Deciseconds: case SS_Deciseconds:
f = (samplecnt_t) _session->sample_rate() / 10.f; f = timepos_t (_session->sample_rate() / 10.f);
break; break;
case MS_Hours: case MS_Hours:
f = (samplecnt_t) floor (3600.0 * _session->sample_rate()); f = timepos_t (floor (3600.0 * _session->sample_rate()));
break; break;
case MS_Minutes: case MS_Minutes:
f = (samplecnt_t) floor (60.0 * _session->sample_rate()); f = timepos_t (floor (60.0 * _session->sample_rate()));
break; break;
case MS_Seconds: case MS_Seconds:
f = (samplecnt_t) _session->sample_rate(); f = timepos_t (_session->sample_rate());
break; break;
case MS_Milliseconds: case MS_Milliseconds:
f = (samplecnt_t) floor (_session->sample_rate() / 1000.0); f = timepos_t (floor (_session->sample_rate() / 1000.0));
break; break;
case Bars: case Bars:
BBT.bars = 1; BBT.bars = 1;
BBT.beats = 0; BBT.beats = 0;
BBT.ticks = 0; BBT.ticks = 0;
f = TempoMap::use()->bbt_duration_at (pos,BBT).samples(); f = TempoMap::use()->bbt_duration_at (pos,BBT);
break; break;
case Beats: case Beats:
BBT.bars = 0; f = timepos_t (Temporal::Beats (1, 0));
BBT.beats = 1;
BBT.ticks = 0;
f = TempoMap::use()->bbt_duration_at(pos,BBT).samples();
break; break;
case Ticks: case Ticks:
BBT.bars = 0; f = timepos_t (Temporal::Beats (0, 1));
BBT.beats = 0;
BBT.ticks = 1;
f = TempoMap::use()->bbt_duration_at(pos,BBT).samples();
break; break;
default: default:
error << string_compose (_("programming error: %1"), "attempt to get samples from non-text field!") << endmsg; error << string_compose (_("programming error: %1"), "attempt to get samples from non-text field!") << endmsg;
f = 0; f = timepos_t (0);
break; break;
} }

View file

@ -230,7 +230,7 @@ class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr
void set_clock_dimensions (Gtk::Requisition&); void set_clock_dimensions (Gtk::Requisition&);
samplepos_t get_sample_step (Field, Temporal::timepos_t const & pos = Temporal::timepos_t (), int dir = 1); Temporal::timepos_t get_incremental_step (Field, Temporal::timepos_t const & pos = Temporal::timepos_t (), int dir = 1);
bool timecode_validate_edit (const std::string&); bool timecode_validate_edit (const std::string&);
bool bbt_validate_edit (std::string&); bool bbt_validate_edit (std::string&);