From b7a32af3a037f9fa70cf54f992314f68279c1204 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Wed, 16 Jan 2019 23:10:16 +0100 Subject: [PATCH] Blink the lock light if dragging the speed slider when locked. --- futatabi/behringer_cmd_pl1.midimapping | 1 + futatabi/futatabi_midi_mapping.proto | 1 + futatabi/mainwindow.cpp | 14 +++++++++++++- futatabi/mainwindow.h | 6 ++++++ futatabi/midi_mapper.cpp | 4 +++- futatabi/midi_mapper.h | 11 +++++++++-- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/futatabi/behringer_cmd_pl1.midimapping b/futatabi/behringer_cmd_pl1.midimapping index c2ff473..23da40b 100644 --- a/futatabi/behringer_cmd_pl1.midimapping +++ b/futatabi/behringer_cmd_pl1.midimapping @@ -43,3 +43,4 @@ master_speed: { controller_number: 128 } # Master speed lock is mapped to lock. toggle_lock: { note_number: 25 } locked: { note_number: 25 } +locked_blinking: { note_number: 25 velocity: 2 } diff --git a/futatabi/futatabi_midi_mapping.proto b/futatabi/futatabi_midi_mapping.proto index 0487b96..31b731e 100644 --- a/futatabi/futatabi_midi_mapping.proto +++ b/futatabi/futatabi_midi_mapping.proto @@ -48,6 +48,7 @@ message MIDIMappingProto { optional MIDIButtonProto toggle_lock = 36; optional int32 toggle_lock_bank = 37; optional MIDILightProto locked = 38; + optional MIDILightProto locked_blinking = 39; optional MIDIButtonProto cue_in = 27; optional int32 cue_in_bank = 28; diff --git a/futatabi/mainwindow.cpp b/futatabi/mainwindow.cpp index 77b1cfe..23a286b 100644 --- a/futatabi/mainwindow.cpp +++ b/futatabi/mainwindow.cpp @@ -222,6 +222,10 @@ MainWindow::MainWindow() connect(defer_timeout, &QTimer::timeout, this, &MainWindow::defer_timer_expired); ui->undo_action->setEnabled(true); + lock_blink_timeout = new QTimer(this); + lock_blink_timeout->setSingleShot(true); + connect(lock_blink_timeout, &QTimer::timeout, this, &MainWindow::lock_blink_timer_expired); + connect(ui->clip_list->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::clip_list_selection_changed); enable_or_disable_queue_button(); @@ -592,6 +596,11 @@ void MainWindow::save_settings() db.store_settings(settings); } +void MainWindow::lock_blink_timer_expired() +{ + midi_mapper.set_locked(MIDIMapper::LightState(ui->speed_lock_btn->isChecked())); // Presumably On, or the timer should have been canceled. +} + void MainWindow::play_clicked() { if (playlist_clips->empty()) @@ -639,7 +648,8 @@ void MainWindow::speed_lock_clicked() // TODO: Make for a less abrupt transition if we're not already at 100%. ui->speed_slider->setValue(100); // Also actually sets the master speed and updates the label. ui->speed_slider->setEnabled(!ui->speed_lock_btn->isChecked()); - midi_mapper.set_locked(ui->speed_lock_btn->isChecked()); + midi_mapper.set_locked(MIDIMapper::LightState(ui->speed_lock_btn->isChecked())); + lock_blink_timeout->stop(); } void MainWindow::live_player_done() @@ -1257,6 +1267,8 @@ void MainWindow::set_master_speed(float speed) post_to_main_thread([this, speed] { if (ui->speed_lock_btn->isChecked()) { + midi_mapper.set_locked(MIDIMapper::Blinking); + lock_blink_timeout->start(1000); return; } diff --git a/futatabi/mainwindow.h b/futatabi/mainwindow.h index 469cb0e..d88baba 100644 --- a/futatabi/mainwindow.h +++ b/futatabi/mainwindow.h @@ -100,6 +100,10 @@ private: // NOTE: The undo stack always has the current state on top. std::deque undo_stack, redo_stack; + // If we need to blink the lock light, we do so for only a second. + // This timer signals that we should end it. + QTimer *lock_blink_timeout; + // Before a change that should be deferred (see above), currently_deferring_model_changes // must be set to true, and current_change_id must be given contents describing what's // changed to avoid accidental grouping. @@ -147,6 +151,8 @@ private: void state_changed(const StateProto &state); // Called post-filtering. void save_settings(); + void lock_blink_timer_expired(); + enum Rounding { FIRST_AT_OR_AFTER, LAST_BEFORE }; void preview_single_frame(int64_t pts, unsigned stream_idx, Rounding rounding); diff --git a/futatabi/midi_mapper.cpp b/futatabi/midi_mapper.cpp index 849c72c..061dd2d 100644 --- a/futatabi/midi_mapper.cpp +++ b/futatabi/midi_mapper.cpp @@ -231,8 +231,10 @@ void MIDIMapper::update_lights_lock_held() if (play_enabled_light) { activate_mapped_light(*mapping_proto, MIDIMappingProto::kPlayEnabledFieldNumber, &active_lights); } - if (locked_light) { + if (locked_light == On) { activate_mapped_light(*mapping_proto, MIDIMappingProto::kLockedFieldNumber, &active_lights); + } else if (locked_light == Blinking) { + activate_mapped_light(*mapping_proto, MIDIMappingProto::kLockedBlinkingFieldNumber, &active_lights); } if (current_highlighted_camera >= 0 && current_highlighted_camera < mapping_proto->camera_size()) { const CameraMIDIMappingProto &camera = mapping_proto->camera(current_highlighted_camera); diff --git a/futatabi/midi_mapper.h b/futatabi/midi_mapper.h index fd16089..abaadaf 100644 --- a/futatabi/midi_mapper.h +++ b/futatabi/midi_mapper.h @@ -45,6 +45,13 @@ public: class MIDIMapper : public MIDIReceiver { public: + // Converts conveniently from a bool. + enum LightState { + Off = 0, + On = 1, + Blinking = 2 + }; + MIDIMapper(ControllerReceiver *receiver); virtual ~MIDIMapper(); void set_midi_mapping(const MIDIMappingProto &new_mapping); @@ -68,7 +75,7 @@ public: play_enabled_light = enabled; refresh_lights(); } - void set_locked(bool locked) { + void set_locked(LightState locked) { locked_light = locked; refresh_lights(); } @@ -102,7 +109,7 @@ private: std::atomic preview_enabled_light{false}; std::atomic queue_enabled_light{false}; std::atomic play_enabled_light{false}; - std::atomic locked_light{true}; + std::atomic locked_light{On}; std::atomic current_highlighted_camera{-1}; MIDIDevice midi_device; -- 2.39.2