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.
This commit is contained in:
Jose Flores 2021-12-04 22:42:35 -06:00 committed by Andreas Kling
parent 2b47e1233b
commit 65df30d00c
Notes: sideshowbarker 2024-07-17 22:58:08 +09:00
7 changed files with 78 additions and 9 deletions

View File

@ -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();

View File

@ -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);

View File

@ -11,6 +11,9 @@
#include "TrackManager.h"
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Button.h>
#include <LibGUI/ComboBox.h>
#include <LibGUI/ItemListModel.h>
#include <LibGUI/Label.h>
PlayerWidget::PlayerWidget(TrackManager& manager, AudioPlayerLoop& loop)
: m_track_manager(manager)
@ -18,11 +21,45 @@ PlayerWidget::PlayerWidget(TrackManager& manager, AudioPlayerLoop& loop)
{
set_layout<GUI::HorizontalBoxLayout>();
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<GUI::Label> label = add<GUI::Label>("Track");
label->set_max_width(75);
m_track_dropdown = add<GUI::ComboBox>();
m_track_dropdown->set_max_width(75);
m_track_dropdown->set_model(*GUI::ItemListModel<String>::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<GUI::Button>();
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<GUI::Button>();
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<GUI::Button>();
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());
}

View File

@ -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<String> m_track_number_choices;
RefPtr<Gfx::Bitmap> m_play_icon;
RefPtr<Gfx::Bitmap> m_pause_icon;
RefPtr<Gfx::Bitmap> m_back_icon;
RefPtr<Gfx::Bitmap> m_next_icon;
RefPtr<Gfx::Bitmap> m_add_track_icon;
RefPtr<Gfx::Bitmap> m_next_track_icon;
RefPtr<GUI::ComboBox> m_track_dropdown;
RefPtr<GUI::Button> m_play_button;
RefPtr<GUI::Button> m_back_button;
RefPtr<GUI::Button> m_next_button;
RefPtr<GUI::Button> m_add_track_button;
RefPtr<GUI::Button> m_next_track_button;
};

View File

@ -90,8 +90,11 @@ void TrackManager::add_track()
m_tracks.append(make<Track>(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;
}

View File

@ -27,6 +27,12 @@ public:
Span<const Sample> 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<NonnullOwnPtr<Track>> m_tracks;

View File

@ -73,7 +73,7 @@ ErrorOr<int> 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));