From 2f16d230025c3173cfbecc58b38d6a52b6b0f5f2 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 5 Jul 2023 20:09:03 +1000 Subject: [PATCH] Start on wiring up playback screen to real data --- src/database/include/track.hpp | 1 + src/ui/include/screen_playing.hpp | 7 +++++++ src/ui/include/ui_fsm.hpp | 13 ++++++++++++- src/ui/screen_playing.cpp | 28 +++++++++++++++++++++++----- src/ui/ui_fsm.cpp | 17 +++++++++++------ 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/database/include/track.hpp b/src/database/include/track.hpp index e3f94db4..87fae9b9 100644 --- a/src/database/include/track.hpp +++ b/src/database/include/track.hpp @@ -50,6 +50,7 @@ enum class Tag { kAlbum = 2, kAlbumTrack = 3, kGenre = 4, + kDuration = 5, }; /* diff --git a/src/ui/include/screen_playing.hpp b/src/ui/include/screen_playing.hpp index 3eae32a7..5ccfe391 100644 --- a/src/ui/include/screen_playing.hpp +++ b/src/ui/include/screen_playing.hpp @@ -6,12 +6,15 @@ #pragma once +#include #include +#include #include "lvgl.h" #include "database.hpp" #include "screen.hpp" +#include "track.hpp" namespace ui { namespace screens { @@ -23,6 +26,9 @@ class Playing : public Screen { auto BindTrack(database::Track t) -> void; + auto UpdateTime(uint32_t) -> void; + auto UpdateNextUp(std::vector tracks) -> void; + private: database::Track track_; @@ -34,6 +40,7 @@ class Playing : public Screen { lv_obj_t* play_pause_control_; lv_obj_t* next_up_container_; + std::vector next_tracks_; }; } // namespace screens diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp index 32275fab..cd1ec492 100644 --- a/src/ui/include/ui_fsm.hpp +++ b/src/ui/include/ui_fsm.hpp @@ -9,7 +9,9 @@ #include #include +#include "audio_events.hpp" #include "relative_wheel.hpp" +#include "screen_playing.hpp" #include "tinyfsm.hpp" #include "display.hpp" @@ -37,6 +39,8 @@ class UiState : public tinyfsm::Fsm { /* Fallback event handler. Does nothing. */ void react(const tinyfsm::Event& ev) {} + virtual void react(const audio::PlaybackUpdate){}; + virtual void react(const system_fsm::KeyLockChanged&){}; virtual void react(const internal::RecordSelected&){}; @@ -57,6 +61,7 @@ class UiState : public tinyfsm::Fsm { static std::stack> sScreens; static std::shared_ptr sCurrentScreen; + static std::unique_ptr sPlayingScreen; }; namespace states { @@ -68,7 +73,7 @@ class Splash : public UiState { using UiState::react; }; -class Interactive : public UiState { +class Browse : public UiState { void entry() override; void react(const internal::RecordSelected&) override; @@ -78,6 +83,12 @@ class Interactive : public UiState { void react(const system_fsm::StorageMounted&) override; }; +class Playing : public UiState { + void entry() override; + + void react(const audio::PlaybackUpdate) override; +}; + class FatalError : public UiState {}; } // namespace states diff --git a/src/ui/screen_playing.cpp b/src/ui/screen_playing.cpp index 1ac8ad5a..39f6b04d 100644 --- a/src/ui/screen_playing.cpp +++ b/src/ui/screen_playing.cpp @@ -7,6 +7,7 @@ #include "screen_playing.hpp" #include "core/lv_obj.h" +#include "core/lv_obj_tree.h" #include "esp_log.h" #include "extra/layouts/flex/lv_flex.h" #include "extra/layouts/grid/lv_grid.h" @@ -130,11 +131,6 @@ Playing::Playing(database::Track track) : track_(track) { lv_obj_set_flex_align(next_up_container_, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_END); - lv_group_add_obj(group_, next_up_label(root_, "Song 2")); - lv_group_add_obj(group_, next_up_label(root_, "Song 3")); - lv_group_add_obj( - group_, next_up_label(root_, "Another song that has a very long name")); - BindTrack(track); } @@ -148,6 +144,28 @@ auto Playing::BindTrack(database::Track t) -> void { lv_label_set_text(album_label_, t.tags().at(database::Tag::kAlbum).value_or("").c_str()); lv_label_set_text(title_label_, t.TitleOrFilename().c_str()); + + // TODO. + lv_bar_set_range(scrubber_, 0, 0); + lv_bar_set_value(scrubber_, 0, LV_ANIM_OFF); +} + +auto Playing::UpdateTime(uint32_t time) -> void { + lv_bar_set_value(scrubber_, time, LV_ANIM_OFF); +} + +auto Playing::UpdateNextUp(std::vector tracks) -> void { + // TODO(jacqueline): Do a proper diff to maintain selection. + int children = lv_obj_get_child_cnt(next_up_container_); + while (children > 0) { + lv_obj_del(lv_obj_get_child(next_up_container_, 0)); + children--; + } + + next_tracks_ = tracks; + for (const auto &track : next_tracks_) { + lv_group_add_obj(group_, next_up_label(next_up_container_, track.TitleOrFilename())); + } } } // namespace screens diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp index 58b1f641..13658c37 100644 --- a/src/ui/ui_fsm.cpp +++ b/src/ui/ui_fsm.cpp @@ -34,6 +34,7 @@ std::weak_ptr UiState::sDb; std::stack> UiState::sScreens; std::shared_ptr UiState::sCurrentScreen; +std::unique_ptr UiState::sPlayingScreen; auto UiState::Init(drivers::IGpios* gpio_expander) -> bool { sIGpios = gpio_expander; @@ -78,16 +79,16 @@ void Splash::exit() { } void Splash::react(const system_fsm::BootComplete& ev) { - transit(); + transit(); } -void Interactive::entry() {} +void Browse::entry() {} -void Interactive::react(const system_fsm::KeyLockChanged& ev) { +void Browse::react(const system_fsm::KeyLockChanged& ev) { sDisplay->SetDisplayOn(ev.falling); } -void Interactive::react(const system_fsm::StorageMounted& ev) { +void Browse::react(const system_fsm::StorageMounted& ev) { sDb = ev.db; auto db = ev.db.lock(); if (!db) { @@ -97,7 +98,7 @@ void Interactive::react(const system_fsm::StorageMounted& ev) { PushScreen(std::make_shared(db->GetIndexes())); } -void Interactive::react(const internal::RecordSelected& ev) { +void Browse::react(const internal::RecordSelected& ev) { auto db = sDb.lock(); if (!db) { return; @@ -125,7 +126,7 @@ void Interactive::react(const internal::RecordSelected& ev) { } } -void Interactive::react(const internal::IndexSelected& ev) { +void Browse::react(const internal::IndexSelected& ev) { auto db = sDb.lock(); if (!db) { return; @@ -137,6 +138,10 @@ void Interactive::react(const internal::IndexSelected& ev) { std::move(query))); } +void Playing::react(const audio::PlaybackUpdate ev) { + sPlayingScreen->UpdateTime(ev.seconds_elapsed); +} + } // namespace states } // namespace ui