From 65df30d00c1356054df197205ac1544603406250 Mon Sep 17 00:00:00 2001 From: Jose Flores Date: Sat, 4 Dec 2021 22:42:35 -0600 Subject: [PATCH] Piano: Add track controls to the player widget Adds the ability to add a track and cycle through the tracks from player widget. Also displays the current track being played or edited in a dropdown that allows for quick track selection. --- Userland/Applications/Piano/MainWidget.cpp | 6 +-- Userland/Applications/Piano/MainWidget.h | 2 +- Userland/Applications/Piano/PlayerWidget.cpp | 51 ++++++++++++++++++++ Userland/Applications/Piano/PlayerWidget.h | 9 ++++ Userland/Applications/Piano/TrackManager.cpp | 9 ++-- Userland/Applications/Piano/TrackManager.h | 8 ++- Userland/Applications/Piano/main.cpp | 2 +- 7 files changed, 78 insertions(+), 9 deletions(-) diff --git a/Userland/Applications/Piano/MainWidget.cpp b/Userland/Applications/Piano/MainWidget.cpp index 8e7a1a4bd2..571a86de98 100644 --- a/Userland/Applications/Piano/MainWidget.cpp +++ b/Userland/Applications/Piano/MainWidget.cpp @@ -56,15 +56,15 @@ MainWidget::~MainWidget() { } -void MainWidget::add_actions(GUI::Menu& menu) +void MainWidget::add_track_actions(GUI::Menu& menu) { menu.add_action(GUI::Action::create("&Add Track", { Mod_Ctrl, Key_T }, [&](auto&) { - m_track_manager.add_track(); + m_player_widget->add_track(); })); menu.add_action(GUI::Action::create("&Next Track", { Mod_Ctrl, Key_N }, [&](auto&) { turn_off_pressed_keys(); - m_track_manager.next_track(); + m_player_widget->next_track(); turn_on_pressed_keys(); m_knobs_widget->update_knobs(); diff --git a/Userland/Applications/Piano/MainWidget.h b/Userland/Applications/Piano/MainWidget.h index e40c8ff87c..e71a8572c0 100644 --- a/Userland/Applications/Piano/MainWidget.h +++ b/Userland/Applications/Piano/MainWidget.h @@ -25,7 +25,7 @@ class MainWidget final : public GUI::Widget { public: virtual ~MainWidget() override; - void add_actions(GUI::Menu&); + void add_track_actions(GUI::Menu&); void set_octave_and_ensure_note_change(Direction); void set_octave_and_ensure_note_change(int); diff --git a/Userland/Applications/Piano/PlayerWidget.cpp b/Userland/Applications/Piano/PlayerWidget.cpp index e8f931bd14..50201e9747 100644 --- a/Userland/Applications/Piano/PlayerWidget.cpp +++ b/Userland/Applications/Piano/PlayerWidget.cpp @@ -11,6 +11,9 @@ #include "TrackManager.h" #include #include +#include +#include +#include PlayerWidget::PlayerWidget(TrackManager& manager, AudioPlayerLoop& loop) : m_track_manager(manager) @@ -18,11 +21,45 @@ PlayerWidget::PlayerWidget(TrackManager& manager, AudioPlayerLoop& loop) { set_layout(); set_fill_with_background_color(true); + m_track_number_choices.append("1"); m_play_icon = Gfx::Bitmap::try_load_from_file("/res/icons/16x16/play.png").release_value_but_fixme_should_propagate_errors(); m_pause_icon = Gfx::Bitmap::try_load_from_file("/res/icons/16x16/pause.png").release_value_but_fixme_should_propagate_errors(); m_back_icon = Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-back.png").release_value_but_fixme_should_propagate_errors(); // Go back a note m_next_icon = Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-forward.png").release_value_but_fixme_should_propagate_errors(); // Advance a note + m_add_track_icon = Gfx::Bitmap::try_load_from_file("/res/icons/16x16/plus.png").release_value_but_fixme_should_propagate_errors(); + m_next_track_icon = Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-last.png").release_value_but_fixme_should_propagate_errors(); + + RefPtr label = add("Track"); + label->set_max_width(75); + + m_track_dropdown = add(); + m_track_dropdown->set_max_width(75); + m_track_dropdown->set_model(*GUI::ItemListModel::create(m_track_number_choices)); + m_track_dropdown->set_only_allow_values_from_model(true); + m_track_dropdown->set_model_column(0); + 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(model_index.row()); + }; + + m_add_track_button = add(); + m_add_track_button->set_icon(*m_add_track_icon); + m_add_track_button->set_fixed_width(30); + m_add_track_button->set_tooltip("Add Track"); + m_add_track_button->set_focus_policy(GUI::FocusPolicy::NoFocus); + m_add_track_button->on_click = [this](unsigned) { + add_track(); + }; + + m_next_track_button = add(); + m_next_track_button->set_icon(*m_next_track_icon); + m_next_track_button->set_fixed_width(30); + m_next_track_button->set_tooltip("Next Track"); + m_next_track_button->set_focus_policy(GUI::FocusPolicy::NoFocus); + m_next_track_button->on_click = [this](unsigned) { + next_track(); + }; m_play_button = add(); m_play_button->set_icon(*m_pause_icon); @@ -61,3 +98,17 @@ PlayerWidget::PlayerWidget(TrackManager& manager, AudioPlayerLoop& loop) PlayerWidget::~PlayerWidget() { } + +void PlayerWidget::add_track() +{ + m_track_manager.add_track(); + auto latest_track_count = m_track_manager.track_count(); + auto latest_track_string = String::number(latest_track_count); + m_track_number_choices.append(latest_track_string); + m_track_dropdown->set_selected_index(latest_track_count - 1); +} + +void PlayerWidget::next_track() +{ + m_track_dropdown->set_selected_index(m_track_manager.next_track_index()); +} diff --git a/Userland/Applications/Piano/PlayerWidget.h b/Userland/Applications/Piano/PlayerWidget.h index 3152578b30..19a6198392 100644 --- a/Userland/Applications/Piano/PlayerWidget.h +++ b/Userland/Applications/Piano/PlayerWidget.h @@ -16,18 +16,27 @@ class PlayerWidget final : public GUI::Toolbar { public: virtual ~PlayerWidget() override; + void add_track(); + void next_track(); + private: explicit PlayerWidget(TrackManager&, AudioPlayerLoop&); TrackManager& m_track_manager; AudioPlayerLoop& m_audio_loop; + Vector m_track_number_choices; RefPtr m_play_icon; RefPtr m_pause_icon; RefPtr m_back_icon; RefPtr m_next_icon; + RefPtr m_add_track_icon; + RefPtr m_next_track_icon; + RefPtr m_track_dropdown; RefPtr m_play_button; RefPtr m_back_button; RefPtr m_next_button; + RefPtr m_add_track_button; + RefPtr m_next_track_button; }; diff --git a/Userland/Applications/Piano/TrackManager.cpp b/Userland/Applications/Piano/TrackManager.cpp index 5e2537c77f..705af0f56b 100644 --- a/Userland/Applications/Piano/TrackManager.cpp +++ b/Userland/Applications/Piano/TrackManager.cpp @@ -90,8 +90,11 @@ void TrackManager::add_track() m_tracks.append(make(m_time)); } -void TrackManager::next_track() +int TrackManager::next_track_index() { - if (++m_current_track >= m_tracks.size()) - m_current_track = 0; + auto next_track_index = m_current_track + 1; + if (next_track_index >= m_tracks.size()) + return 0; + else + return next_track_index; } diff --git a/Userland/Applications/Piano/TrackManager.h b/Userland/Applications/Piano/TrackManager.h index 08893cc22f..4b315ea118 100644 --- a/Userland/Applications/Piano/TrackManager.h +++ b/Userland/Applications/Piano/TrackManager.h @@ -27,6 +27,12 @@ public: Span buffer() const { return m_current_front_buffer; } int octave() const { return m_octave; } int octave_base() const { return (m_octave - octave_min) * 12; } + int track_count() { return m_tracks.size(); }; + void set_current_track(size_t track_index) + { + VERIFY((int)track_index < track_count()); + m_current_track = track_index; + } int time() const { return m_time; } void time_forward(int amount); @@ -38,7 +44,7 @@ public: void set_octave(Direction); void set_octave(int octave); void add_track(); - void next_track(); + int next_track_index(); private: Vector> m_tracks; diff --git a/Userland/Applications/Piano/main.cpp b/Userland/Applications/Piano/main.cpp index c5927129da..c9433d71ba 100644 --- a/Userland/Applications/Piano/main.cpp +++ b/Userland/Applications/Piano/main.cpp @@ -73,7 +73,7 @@ ErrorOr serenity_main(Main::Arguments arguments) })); auto& edit_menu = window->add_menu("&Edit"); - main_widget.add_actions(edit_menu); + main_widget.add_track_actions(edit_menu); auto& help_menu = window->add_menu("&Help"); help_menu.add_action(GUI::CommonActions::make_about_action("Piano", app_icon, window));