summaryrefslogtreecommitdiff
path: root/Userland/Applications/Piano
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Applications/Piano')
-rw-r--r--Userland/Applications/Piano/MainWidget.cpp23
-rw-r--r--Userland/Applications/Piano/MainWidget.h6
-rw-r--r--Userland/Applications/Piano/PlayerWidget.cpp9
-rw-r--r--Userland/Applications/Piano/PlayerWidget.h8
-rw-r--r--Userland/Applications/Piano/RollWidget.cpp3
-rw-r--r--Userland/Applications/Piano/TrackControlsWidget.cpp52
-rw-r--r--Userland/Applications/Piano/TrackControlsWidget.h24
-rw-r--r--Userland/Applications/Piano/TrackManager.h2
8 files changed, 86 insertions, 41 deletions
diff --git a/Userland/Applications/Piano/MainWidget.cpp b/Userland/Applications/Piano/MainWidget.cpp
index 02b3741ddf..a2ade38d62 100644
--- a/Userland/Applications/Piano/MainWidget.cpp
+++ b/Userland/Applications/Piano/MainWidget.cpp
@@ -18,6 +18,7 @@
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Menu.h>
#include <LibGUI/Slider.h>
+#include <LibGUI/StackWidget.h>
#include <LibGUI/TabWidget.h>
ErrorOr<NonnullRefPtr<MainWidget>> MainWidget::try_create(TrackManager& manager, AudioPlayerLoop& loop)
@@ -47,7 +48,7 @@ ErrorOr<void> MainWidget::initialize()
m_roll_widget->set_fixed_height(300);
(void)TRY(m_tab_widget->try_add_tab<SamplerWidget>("Sampler"_short_string, m_track_manager));
- m_player_widget = TRY(try_add<PlayerWidget>(m_track_manager, m_audio_loop));
+ m_player_widget = TRY(try_add<PlayerWidget>(m_track_manager, *this, m_audio_loop));
m_keys_and_knobs_container = TRY(try_add<GUI::Widget>());
TRY(m_keys_and_knobs_container->try_set_layout<GUI::HorizontalBoxLayout>(GUI::Margins {}, 2));
@@ -78,7 +79,11 @@ ErrorOr<void> MainWidget::initialize()
m_octave_value->set_text(String::number(new_octave).release_value_but_fixme_should_propagate_errors());
};
- m_knobs_widget = TRY(m_keys_and_knobs_container->try_add<TrackControlsWidget>(m_track_manager, *this));
+ m_knobs_widget = TRY(m_keys_and_knobs_container->try_add<GUI::StackWidget>());
+ for (auto track : m_track_manager.tracks())
+ TRY(m_track_controls.try_append(TRY(m_knobs_widget->try_add<TrackControlsWidget>(TRY(track->try_make_weak_ptr())))));
+
+ update_selected_track();
m_roll_widget->set_keys_widget(m_keys_widget);
@@ -100,6 +105,20 @@ ErrorOr<void> MainWidget::add_track_actions(GUI::Menu& menu)
return {};
}
+void MainWidget::update_selected_track()
+{
+ if (static_cast<size_t>(m_track_manager.track_count()) > m_track_controls.size())
+ MUST(add_controls_for_current_track());
+ m_knobs_widget->set_active_widget(m_track_controls.at(m_track_manager.current_track_index()).ptr());
+}
+
+ErrorOr<void> MainWidget::add_controls_for_current_track()
+{
+ auto track = m_track_manager.current_track();
+ TRY(m_track_controls.try_append(TRY(m_knobs_widget->try_add<TrackControlsWidget>(TRY(track->try_make_weak_ptr())))));
+ return {};
+}
+
// FIXME: There are some unnecessary calls to update() throughout this program,
// which are an easy target for optimization.
diff --git a/Userland/Applications/Piano/MainWidget.h b/Userland/Applications/Piano/MainWidget.h
index 197198b16a..b79bb86377 100644
--- a/Userland/Applications/Piano/MainWidget.h
+++ b/Userland/Applications/Piano/MainWidget.h
@@ -11,6 +11,7 @@
#include "Music.h"
#include <LibDSP/Keyboard.h>
+#include <LibGUI/StackWidget.h>
#include <LibGUI/Widget.h>
class AudioPlayerLoop;
@@ -32,6 +33,8 @@ public:
void change_octave_via_keys(DSP::Keyboard::Direction);
void set_octave_via_slider(int octave);
+ void update_selected_track();
+ ErrorOr<void> add_controls_for_current_track();
private:
explicit MainWidget(TrackManager&, AudioPlayerLoop&);
@@ -57,7 +60,8 @@ private:
RefPtr<GUI::TabWidget> m_tab_widget;
RefPtr<GUI::Widget> m_keys_and_knobs_container;
RefPtr<KeysWidget> m_keys_widget;
- RefPtr<TrackControlsWidget> m_knobs_widget;
+ RefPtr<GUI::StackWidget> m_knobs_widget;
+ Vector<NonnullRefPtr<TrackControlsWidget>> m_track_controls;
RefPtr<PlayerWidget> m_player_widget;
RefPtr<GUI::Widget> m_octave_container;
diff --git a/Userland/Applications/Piano/PlayerWidget.cpp b/Userland/Applications/Piano/PlayerWidget.cpp
index 44dfeca6f7..d5afb4f8f0 100644
--- a/Userland/Applications/Piano/PlayerWidget.cpp
+++ b/Userland/Applications/Piano/PlayerWidget.cpp
@@ -8,6 +8,7 @@
#include "PlayerWidget.h"
#include "AudioPlayerLoop.h"
+#include "MainWidget.h"
#include "Music.h"
#include "TrackManager.h"
#include <LibGUI/BoxLayout.h>
@@ -16,9 +17,9 @@
#include <LibGUI/ItemListModel.h>
#include <LibGUI/Label.h>
-ErrorOr<NonnullRefPtr<PlayerWidget>> PlayerWidget::create(TrackManager& manager, AudioPlayerLoop& loop)
+ErrorOr<NonnullRefPtr<PlayerWidget>> PlayerWidget::try_create(TrackManager& manager, MainWidget& main_widget, AudioPlayerLoop& loop)
{
- auto widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) PlayerWidget(manager, loop)));
+ auto widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) PlayerWidget(manager, main_widget, loop)));
widget->m_play_icon = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/play.png"sv));
widget->m_pause_icon = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/pause.png"sv));
@@ -31,8 +32,9 @@ ErrorOr<NonnullRefPtr<PlayerWidget>> PlayerWidget::create(TrackManager& manager,
return widget;
}
-PlayerWidget::PlayerWidget(TrackManager& manager, AudioPlayerLoop& loop)
+PlayerWidget::PlayerWidget(TrackManager& manager, MainWidget& main_widget, AudioPlayerLoop& loop)
: m_track_manager(manager)
+ , m_main_widget(main_widget)
, m_audio_loop(loop)
{
}
@@ -54,6 +56,7 @@ ErrorOr<void> PlayerWidget::initialize()
m_track_dropdown->set_selected_index(0);
m_track_dropdown->on_change = [this]([[maybe_unused]] auto name, GUI::ModelIndex model_index) {
m_track_manager.set_current_track(static_cast<size_t>(model_index.row()));
+ m_main_widget.update_selected_track();
};
m_add_track_button = TRY(try_add<GUI::Button>());
diff --git a/Userland/Applications/Piano/PlayerWidget.h b/Userland/Applications/Piano/PlayerWidget.h
index d252eb1489..072484b495 100644
--- a/Userland/Applications/Piano/PlayerWidget.h
+++ b/Userland/Applications/Piano/PlayerWidget.h
@@ -11,11 +11,12 @@
class AudioPlayerLoop;
class TrackManager;
+class MainWidget;
class PlayerWidget final : public GUI::Toolbar {
- C_OBJECT(PlayerWidget)
+ C_OBJECT_ABSTRACT(PlayerWidget)
public:
- static ErrorOr<NonnullRefPtr<PlayerWidget>> create(TrackManager&, AudioPlayerLoop&);
+ static ErrorOr<NonnullRefPtr<PlayerWidget>> try_create(TrackManager&, MainWidget&, AudioPlayerLoop&);
virtual ~PlayerWidget() override = default;
void add_track();
@@ -23,11 +24,12 @@ public:
void toggle_paused();
private:
- explicit PlayerWidget(TrackManager&, AudioPlayerLoop&);
+ explicit PlayerWidget(TrackManager&, MainWidget&, AudioPlayerLoop&);
ErrorOr<void> initialize();
TrackManager& m_track_manager;
+ MainWidget& m_main_widget;
AudioPlayerLoop& m_audio_loop;
Vector<DeprecatedString> m_track_number_choices;
diff --git a/Userland/Applications/Piano/RollWidget.cpp b/Userland/Applications/Piano/RollWidget.cpp
index fa7c1db56b..e48e23cff3 100644
--- a/Userland/Applications/Piano/RollWidget.cpp
+++ b/Userland/Applications/Piano/RollWidget.cpp
@@ -8,6 +8,7 @@
*/
#include "RollWidget.h"
+#include "LibDSP/Music.h"
#include "TrackManager.h"
#include <AK/IntegralMath.h>
#include <LibGUI/Event.h>
@@ -127,7 +128,7 @@ void RollWidget::paint_event(GUI::PaintEvent& event)
int distance_to_next_x = next_x_pos - x_pos;
Gfx::IntRect rect(x_pos, y_pos, distance_to_next_x, note_height);
- if (m_track_manager.keyboard()->is_pressed(note))
+ if (static_cast<size_t>(note) < DSP::note_frequencies.size() && m_track_manager.keyboard()->is_pressed(note))
painter.fill_rect(rect, note_pressed_color.with_alpha(128));
}
}
diff --git a/Userland/Applications/Piano/TrackControlsWidget.cpp b/Userland/Applications/Piano/TrackControlsWidget.cpp
index 8479559e31..b7ccfe5286 100644
--- a/Userland/Applications/Piano/TrackControlsWidget.cpp
+++ b/Userland/Applications/Piano/TrackControlsWidget.cpp
@@ -7,28 +7,46 @@
*/
#include "TrackControlsWidget.h"
-#include "MainWidget.h"
#include "ProcessorParameterWidget/ParameterWidget.h"
-#include "TrackManager.h"
-#include <LibDSP/ProcessorParameter.h>
#include <LibGUI/BoxLayout.h>
-#include <LibGUI/Label.h>
-#include <LibGfx/Orientation.h>
+#include <LibGUI/Frame.h>
+#include <LibGUI/GroupBox.h>
+#include <LibGUI/Widget.h>
-TrackControlsWidget::TrackControlsWidget(TrackManager& track_manager, MainWidget& main_widget)
- : m_track_manager(track_manager)
- , m_main_widget(main_widget)
+TrackControlsWidget::TrackControlsWidget(WeakPtr<DSP::Track> track)
+ : m_track(move(track))
{
- set_layout<GUI::HorizontalBoxLayout>();
- set_preferred_width(GUI::SpecialDimension::Grow);
- set_fill_with_background_color(true);
+}
+
+ErrorOr<NonnullRefPtr<TrackControlsWidget>> TrackControlsWidget::try_create(WeakPtr<DSP::Track> track)
+{
+ auto widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) TrackControlsWidget(move(track))));
+
+ TRY(widget->try_set_layout<GUI::HorizontalBoxLayout>());
+ widget->set_preferred_width(GUI::SpecialDimension::Grow);
+ widget->set_fill_with_background_color(true);
+
+ auto mastering_parameters = TRY(widget->try_add<GUI::GroupBox>());
+ TRY(mastering_parameters->try_set_layout<GUI::HorizontalBoxLayout>());
+
+ auto strong_track = widget->m_track.value();
+
+ for (auto& parameter : strong_track->track_mastering()->parameters())
+ (void)TRY(mastering_parameters->try_add<ProcessorParameterWidget>(parameter));
+
+ TRY(widget->m_processor_groups.try_append(mastering_parameters));
+
+ TRY(widget->add_spacer());
+
+ for (auto& processor : strong_track->processor_chain()) {
+ auto processor_parameters = TRY(widget->try_add<GUI::GroupBox>());
+ TRY(processor_parameters->try_set_layout<GUI::HorizontalBoxLayout>());
- for (auto& parameter : m_track_manager.current_track()->track_mastering()->parameters())
- m_parameter_widgets.append(add<ProcessorParameterWidget>(parameter));
+ for (auto& parameter : processor->parameters())
+ (void)TRY(processor_parameters->try_add<ProcessorParameterWidget>(parameter));
- for (auto& parameter : m_track_manager.current_track()->synth()->parameters())
- m_parameter_widgets.append(add<ProcessorParameterWidget>(parameter));
+ TRY(widget->m_processor_groups.try_append(processor_parameters));
+ }
- for (auto& parameter : m_track_manager.current_track()->delay()->parameters())
- m_parameter_widgets.append(add<ProcessorParameterWidget>(parameter));
+ return widget;
}
diff --git a/Userland/Applications/Piano/TrackControlsWidget.h b/Userland/Applications/Piano/TrackControlsWidget.h
index 3cb370d83c..b130b52cbc 100644
--- a/Userland/Applications/Piano/TrackControlsWidget.h
+++ b/Userland/Applications/Piano/TrackControlsWidget.h
@@ -9,25 +9,21 @@
#pragma once
#include "ProcessorParameterWidget/ParameterWidget.h"
-#include <LibDSP/ProcessorParameter.h>
-#include <LibDSP/Synthesizers.h>
-#include <LibGUI/Frame.h>
-#include <LibGUI/Label.h>
-#include <LibGUI/Widget.h>
-
-class TrackManager;
-class MainWidget;
+#include <AK/Vector.h>
+#include <AK/WeakPtr.h>
+#include <LibDSP/Track.h>
+#include <LibGUI/Forward.h>
class TrackControlsWidget final : public GUI::Frame {
- C_OBJECT(TrackControlsWidget)
+ C_OBJECT_ABSTRACT(TrackControlsWidget)
public:
virtual ~TrackControlsWidget() override = default;
-private:
- TrackControlsWidget(TrackManager&, MainWidget&);
+ static ErrorOr<NonnullRefPtr<TrackControlsWidget>> try_create(WeakPtr<DSP::Track>);
- TrackManager& m_track_manager;
- MainWidget& m_main_widget;
+private:
+ TrackControlsWidget(WeakPtr<DSP::Track>);
- Vector<NonnullRefPtr<ProcessorParameterWidget>> m_parameter_widgets;
+ WeakPtr<DSP::Track> m_track;
+ Vector<NonnullRefPtr<GUI::GroupBox>> m_processor_groups;
};
diff --git a/Userland/Applications/Piano/TrackManager.h b/Userland/Applications/Piano/TrackManager.h
index a077d92457..8abffa0bf2 100644
--- a/Userland/Applications/Piano/TrackManager.h
+++ b/Userland/Applications/Piano/TrackManager.h
@@ -28,11 +28,13 @@ public:
NonnullRefPtr<DSP::NoteTrack> current_track() { return *m_tracks[m_current_track]; }
size_t track_count() { return m_tracks.size(); };
+ size_t current_track_index() const { return m_current_track; }
void set_current_track(size_t track_index)
{
VERIFY(track_index < track_count());
m_current_track = track_index;
}
+ Span<NonnullRefPtr<DSP::NoteTrack>> tracks() { return m_tracks.span(); }
NonnullRefPtr<DSP::Transport> transport() const { return m_transport; }
NonnullRefPtr<DSP::Keyboard> keyboard() const { return m_keyboard; }