diff options
author | William McPherson <willmcpherson2@gmail.com> | 2020-06-17 19:34:25 +1000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-18 16:42:37 +0200 |
commit | 34ee76984cb1f0dfb2977ac53a23cf640531aa68 (patch) | |
tree | 25443e41608f61f41327aad4ed46f3180b31c94f | |
parent | ee52572ca1bc382e6ccaf8e59e02db2b15157ac8 (diff) | |
download | serenity-34ee76984cb1f0dfb2977ac53a23cf640531aa68.zip |
Piano: Expose multi-track functionality
This commit adds some actions for creating and cycling through tracks.
set_octave_and_ensure_note_change() was refactored to allow switching
tracks to implement the same behaviour.
KnobsWidget is getting pretty bad.
-rw-r--r-- | Applications/Piano/KnobsWidget.cpp | 49 | ||||
-rw-r--r-- | Applications/Piano/KnobsWidget.h | 2 | ||||
-rw-r--r-- | Applications/Piano/MainWidget.cpp | 31 | ||||
-rw-r--r-- | Applications/Piano/MainWidget.h | 5 | ||||
-rw-r--r-- | Applications/Piano/main.cpp | 3 |
5 files changed, 69 insertions, 21 deletions
diff --git a/Applications/Piano/KnobsWidget.cpp b/Applications/Piano/KnobsWidget.cpp index 0296124bf1..e0ab8898df 100644 --- a/Applications/Piano/KnobsWidget.cpp +++ b/Applications/Piano/KnobsWidget.cpp @@ -32,6 +32,12 @@ #include <LibGUI/Label.h> #include <LibGUI/Slider.h> +constexpr int max_attack = 1000; +constexpr int max_decay = 1000; +constexpr int max_sustain = 1000; +constexpr int max_release = 1000; +constexpr int max_delay = 8; + KnobsWidget::KnobsWidget(TrackManager& track_manager, MainWidget& main_widget) : m_track_manager(track_manager) , m_main_widget(main_widget) @@ -76,7 +82,7 @@ KnobsWidget::KnobsWidget(TrackManager& track_manager, MainWidget& main_widget) m_octave_knob->set_value((octave_max - 1) - (m_track_manager.octave() - 1)); m_octave_knob->on_value_changed = [this](int value) { int new_octave = octave_max - value; - if (m_change_octave) + if (m_change_underlying) m_main_widget.set_octave_and_ensure_note_change(new_octave == m_track_manager.octave() + 1 ? Up : Down); ASSERT(new_octave == m_track_manager.octave()); m_octave_value->set_text(String::number(new_octave)); @@ -88,66 +94,67 @@ KnobsWidget::KnobsWidget(TrackManager& track_manager, MainWidget& main_widget) m_wave_knob->set_value(last_wave - m_track_manager.current_track().wave()); m_wave_knob->on_value_changed = [this](int value) { int new_wave = last_wave - value; - m_track_manager.current_track().set_wave(new_wave); + if (m_change_underlying) + m_track_manager.current_track().set_wave(new_wave); ASSERT(new_wave == m_track_manager.current_track().wave()); m_wave_value->set_text(wave_strings[new_wave]); }; - constexpr int max_attack = 1000; m_attack_knob = m_knobs_container->add<GUI::VerticalSlider>(); m_attack_knob->set_range(0, max_attack); m_attack_knob->set_value(max_attack - m_track_manager.current_track().attack()); m_attack_knob->set_step(100); m_attack_knob->on_value_changed = [this](int value) { int new_attack = max_attack - value; - m_track_manager.current_track().set_attack(new_attack); + if (m_change_underlying) + m_track_manager.current_track().set_attack(new_attack); ASSERT(new_attack == m_track_manager.current_track().attack()); m_attack_value->set_text(String::number(new_attack)); }; - constexpr int max_decay = 1000; m_decay_knob = m_knobs_container->add<GUI::VerticalSlider>(); m_decay_knob->set_range(0, max_decay); m_decay_knob->set_value(max_decay - m_track_manager.current_track().decay()); m_decay_knob->set_step(100); m_decay_knob->on_value_changed = [this](int value) { int new_decay = max_decay - value; - m_track_manager.current_track().set_decay(new_decay); + if (m_change_underlying) + m_track_manager.current_track().set_decay(new_decay); ASSERT(new_decay == m_track_manager.current_track().decay()); m_decay_value->set_text(String::number(new_decay)); }; - constexpr int max_sustain = 1000; m_sustain_knob = m_knobs_container->add<GUI::VerticalSlider>(); m_sustain_knob->set_range(0, max_sustain); m_sustain_knob->set_value(max_sustain - m_track_manager.current_track().sustain()); m_sustain_knob->set_step(100); m_sustain_knob->on_value_changed = [this](int value) { int new_sustain = max_sustain - value; - m_track_manager.current_track().set_sustain(new_sustain); + if (m_change_underlying) + m_track_manager.current_track().set_sustain(new_sustain); ASSERT(new_sustain == m_track_manager.current_track().sustain()); m_sustain_value->set_text(String::number(new_sustain)); }; - constexpr int max_release = 1000; m_release_knob = m_knobs_container->add<GUI::VerticalSlider>(); m_release_knob->set_range(0, max_release); m_release_knob->set_value(max_release - m_track_manager.current_track().release()); m_release_knob->set_step(100); m_release_knob->on_value_changed = [this](int value) { int new_release = max_release - value; - m_track_manager.current_track().set_release(new_release); + if (m_change_underlying) + m_track_manager.current_track().set_release(new_release); ASSERT(new_release == m_track_manager.current_track().release()); m_release_value->set_text(String::number(new_release)); }; - constexpr int max_delay = 8; m_delay_knob = m_knobs_container->add<GUI::VerticalSlider>(); m_delay_knob->set_range(0, max_delay); m_delay_knob->set_value(max_delay - m_track_manager.current_track().delay()); m_delay_knob->on_value_changed = [this](int value) { int new_delay = max_delay - value; - m_track_manager.current_track().set_delay(new_delay); + if (m_change_underlying) + m_track_manager.current_track().set_delay(new_delay); ASSERT(new_delay == m_track_manager.current_track().delay()); m_delay_value->set_text(String::number(new_delay)); }; @@ -161,10 +168,18 @@ void KnobsWidget::update_knobs() { m_wave_knob->set_value(last_wave - m_track_manager.current_track().wave()); - // FIXME: This is needed because when the slider is changed directly, it - // needs to change the octave, but if the octave was changed elsewhere, we - // need to change the slider without changing the octave. - m_change_octave = false; + // FIXME: This is needed because when the slider is changed normally, we + // need to change the underlying value, but if the keyboard was used, we + // need to change the slider without changing the underlying value. + m_change_underlying = false; + m_octave_knob->set_value(octave_max - m_track_manager.octave()); - m_change_octave = true; + m_wave_knob->set_value(last_wave - m_track_manager.current_track().wave()); + m_attack_knob->set_value(max_attack - m_track_manager.current_track().attack()); + m_decay_knob->set_value(max_decay - m_track_manager.current_track().decay()); + m_sustain_knob->set_value(max_sustain - m_track_manager.current_track().sustain()); + m_release_knob->set_value(max_release - m_track_manager.current_track().release()); + m_delay_knob->set_value(max_delay - m_track_manager.current_track().delay()); + + m_change_underlying = true; } diff --git a/Applications/Piano/KnobsWidget.h b/Applications/Piano/KnobsWidget.h index f7623df3dc..d5abea5be0 100644 --- a/Applications/Piano/KnobsWidget.h +++ b/Applications/Piano/KnobsWidget.h @@ -72,5 +72,5 @@ private: RefPtr<GUI::Slider> m_release_knob; RefPtr<GUI::Slider> m_delay_knob; - bool m_change_octave { true }; + bool m_change_underlying { true }; }; diff --git a/Applications/Piano/MainWidget.cpp b/Applications/Piano/MainWidget.cpp index 207954738c..11209fe9d8 100644 --- a/Applications/Piano/MainWidget.cpp +++ b/Applications/Piano/MainWidget.cpp @@ -32,7 +32,9 @@ #include "SamplerWidget.h" #include "TrackManager.h" #include "WaveWidget.h" +#include <LibGUI/Action.h> #include <LibGUI/BoxLayout.h> +#include <LibGUI/Menu.h> #include <LibGUI/TabWidget.h> MainWidget::MainWidget(TrackManager& track_manager) @@ -73,6 +75,21 @@ MainWidget::~MainWidget() { } +void MainWidget::add_actions(GUI::Menu& menu) +{ + menu.add_action(GUI::Action::create("Add track", { Mod_Ctrl, Key_T }, [&](auto&) { + m_track_manager.add_track(); + })); + + menu.add_action(GUI::Action::create("Next track", { Mod_Ctrl, Key_N }, [&](auto&) { + turn_off_pressed_keys(); + m_track_manager.next_track(); + turn_on_pressed_keys(); + + m_knobs_widget->update_knobs(); + })); +} + // FIXME: There are some unnecessary calls to update() throughout this program, // which are an easy target for optimization. @@ -125,21 +142,29 @@ void MainWidget::special_key_action(int key_code) } } -void MainWidget::set_octave_and_ensure_note_change(Direction direction) +void MainWidget::turn_off_pressed_keys() { m_keys_widget->set_key(m_keys_widget->mouse_note(), Off); for (int i = 0; i < key_code_count; ++i) { if (m_keys_pressed[i]) note_key_action(i, Off); } +} - m_track_manager.set_octave(direction); - +void MainWidget::turn_on_pressed_keys() +{ m_keys_widget->set_key(m_keys_widget->mouse_note(), On); for (int i = 0; i < key_code_count; ++i) { if (m_keys_pressed[i]) note_key_action(i, On); } +} + +void MainWidget::set_octave_and_ensure_note_change(Direction direction) +{ + turn_off_pressed_keys(); + m_track_manager.set_octave(direction); + turn_on_pressed_keys(); m_knobs_widget->update_knobs(); m_keys_widget->update(); diff --git a/Applications/Piano/MainWidget.h b/Applications/Piano/MainWidget.h index 6a2a543675..75166fa7dd 100644 --- a/Applications/Piano/MainWidget.h +++ b/Applications/Piano/MainWidget.h @@ -42,6 +42,8 @@ class MainWidget final : public GUI::Widget { public: virtual ~MainWidget() override; + void add_actions(GUI::Menu&); + void set_octave_and_ensure_note_change(Direction); private: @@ -54,6 +56,9 @@ private: void note_key_action(int key_code, Switch); void special_key_action(int key_code); + void turn_off_pressed_keys(); + void turn_on_pressed_keys(); + TrackManager& m_track_manager; RefPtr<WaveWidget> m_wave_widget; diff --git a/Applications/Piano/main.cpp b/Applications/Piano/main.cpp index 0310a29de3..b48afdcc50 100644 --- a/Applications/Piano/main.cpp +++ b/Applications/Piano/main.cpp @@ -117,6 +117,9 @@ int main(int argc, char** argv) GUI::AboutDialog::show("Piano", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-piano.png"), window); })); + auto& edit_menu = menubar->add_menu("Edit"); + main_widget.add_actions(edit_menu); + app.set_menubar(move(menubar)); return app.exec(); |