summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam McPherson <willmcpherson2@gmail.com>2020-06-17 19:34:25 +1000
committerAndreas Kling <kling@serenityos.org>2020-06-18 16:42:37 +0200
commit34ee76984cb1f0dfb2977ac53a23cf640531aa68 (patch)
tree25443e41608f61f41327aad4ed46f3180b31c94f
parentee52572ca1bc382e6ccaf8e59e02db2b15157ac8 (diff)
downloadserenity-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.cpp49
-rw-r--r--Applications/Piano/KnobsWidget.h2
-rw-r--r--Applications/Piano/MainWidget.cpp31
-rw-r--r--Applications/Piano/MainWidget.h5
-rw-r--r--Applications/Piano/main.cpp3
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();