diff options
Diffstat (limited to 'Userland/Applications/Piano')
-rw-r--r-- | Userland/Applications/Piano/MainWidget.cpp | 23 | ||||
-rw-r--r-- | Userland/Applications/Piano/MainWidget.h | 6 | ||||
-rw-r--r-- | Userland/Applications/Piano/PlayerWidget.cpp | 9 | ||||
-rw-r--r-- | Userland/Applications/Piano/PlayerWidget.h | 8 | ||||
-rw-r--r-- | Userland/Applications/Piano/RollWidget.cpp | 3 | ||||
-rw-r--r-- | Userland/Applications/Piano/TrackControlsWidget.cpp | 52 | ||||
-rw-r--r-- | Userland/Applications/Piano/TrackControlsWidget.h | 24 | ||||
-rw-r--r-- | Userland/Applications/Piano/TrackManager.h | 2 |
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; } |