diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-09-28 08:29:55 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-09-28 08:29:55 +1000 |
| commit | f09ba5ffd53bf7d28e0dc516c00a8f69ca7efae9 (patch) | |
| tree | affce5567186d8944686afd824bf4ee4f7ee4d2d /src/ui/include | |
| parent | f168bfab7698f28492c7693263525945a26cbcc8 (diff) | |
| download | tangara-fw-f09ba5ffd53bf7d28e0dc516c00a8f69ca7efae9.tar.gz | |
Use bindey for databinding instead of hand rolling ui updates
Diffstat (limited to 'src/ui/include')
| -rw-r--r-- | src/ui/include/event_binding.hpp | 30 | ||||
| -rw-r--r-- | src/ui/include/model_playback.hpp | 26 | ||||
| -rw-r--r-- | src/ui/include/screen.hpp | 14 | ||||
| -rw-r--r-- | src/ui/include/screen_playing.hpp | 33 | ||||
| -rw-r--r-- | src/ui/include/ui_fsm.hpp | 23 |
5 files changed, 95 insertions, 31 deletions
diff --git a/src/ui/include/event_binding.hpp b/src/ui/include/event_binding.hpp new file mode 100644 index 00000000..19514db4 --- /dev/null +++ b/src/ui/include/event_binding.hpp @@ -0,0 +1,30 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include <cstdint> + +#include "lvgl.h" + +#include "core/lv_event.h" +#include "core/lv_obj.h" +#include "nod/nod.hpp" + +namespace ui { + +class EventBinding { + public: + EventBinding(lv_obj_t* obj, lv_event_code_t ev); + + auto signal() -> nod::signal<void(lv_obj_t*)>& { return signal_; } + + private: + lv_obj_t* obj_; + nod::signal<void(lv_obj_t*)> signal_; +}; + +} // namespace ui diff --git a/src/ui/include/model_playback.hpp b/src/ui/include/model_playback.hpp new file mode 100644 index 00000000..f932dcfd --- /dev/null +++ b/src/ui/include/model_playback.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include "bindey/property.h" + +#include "track.hpp" + +namespace ui { +namespace models { + +struct Playback { + bindey::property<bool> is_playing; + bindey::property<std::optional<database::TrackId>> current_track; + bindey::property<std::vector<database::TrackId>> upcoming_tracks; + + bindey::property<uint32_t> current_track_position; + bindey::property<uint32_t> current_track_duration; +}; + +} // namespace models +} // namespace ui
\ No newline at end of file diff --git a/src/ui/include/screen.hpp b/src/ui/include/screen.hpp index 76251a72..ac7b19f8 100644 --- a/src/ui/include/screen.hpp +++ b/src/ui/include/screen.hpp @@ -8,11 +8,15 @@ #include <memory> #include <optional> +#include <vector> +#include "bindey/binding.h" #include "core/lv_group.h" #include "core/lv_obj.h" #include "core/lv_obj_tree.h" +#include "event_binding.hpp" #include "lvgl.h" +#include "nod/nod.hpp" #include "widget_top_bar.hpp" namespace ui { @@ -51,6 +55,16 @@ class Screen { auto CreateTopBar(lv_obj_t* parent, const widgets::TopBar::Configuration&) -> widgets::TopBar*; + std::pmr::vector<bindey::scoped_binding> data_bindings_; + std::pmr::vector<std::unique_ptr<EventBinding>> event_bindings_; + + template <typename T> + auto lv_bind(lv_obj_t* obj, lv_event_code_t ev, T fn) -> void { + auto binding = std::make_unique<EventBinding>(obj, ev); + binding->signal().connect(fn); + event_bindings_.push_back(std::move(binding)); + } + lv_obj_t* const root_; lv_obj_t* content_; lv_obj_t* modal_content_; diff --git a/src/ui/include/screen_playing.hpp b/src/ui/include/screen_playing.hpp index 2e29130c..fff9cc35 100644 --- a/src/ui/include/screen_playing.hpp +++ b/src/ui/include/screen_playing.hpp @@ -11,10 +11,13 @@ #include <memory> #include <vector> +#include "bindey/property.h" +#include "esp_log.h" #include "lvgl.h" #include "database.hpp" #include "future_fetcher.hpp" +#include "model_playback.hpp" #include "screen.hpp" #include "track.hpp" #include "track_queue.hpp" @@ -28,48 +31,36 @@ namespace screens { */ class Playing : public Screen { public: - explicit Playing(std::weak_ptr<database::Database> db, + explicit Playing(models::Playback& playback_model, + std::weak_ptr<database::Database> db, audio::TrackQueue& queue); ~Playing(); auto Tick() -> void override; - // Callbacks invoked by the UI state machine in response to audio events. - - auto OnTrackUpdate() -> void; - auto OnPlaybackUpdate(uint32_t, uint32_t) -> void; - auto OnQueueUpdate() -> void; - auto OnFocusAboveFold() -> void; auto OnFocusBelowFold() -> void; + Playing(const Playing&) = delete; + Playing& operator=(const Playing&) = delete; + private: auto control_button(lv_obj_t* parent, char* icon) -> lv_obj_t*; auto next_up_label(lv_obj_t* parent, const std::pmr::string& text) -> lv_obj_t*; - auto BindTrack(const database::Track& track) -> void; - auto ApplyNextUp(const std::vector<database::Track>& tracks) -> void; - std::weak_ptr<database::Database> db_; audio::TrackQueue& queue_; - std::optional<database::Track> track_; - std::vector<database::Track> next_tracks_; + bindey::property<std::shared_ptr<database::Track>> current_track_; + bindey::property<std::vector<std::shared_ptr<database::Track>>> next_tracks_; - std::unique_ptr<database::FutureFetcher<std::optional<database::Track>>> + std::unique_ptr<database::FutureFetcher<std::shared_ptr<database::Track>>> new_track_; std::unique_ptr< - database::FutureFetcher<std::vector<std::optional<database::Track>>>> + database::FutureFetcher<std::vector<std::shared_ptr<database::Track>>>> new_next_tracks_; - lv_obj_t* artist_label_; - lv_obj_t* album_label_; - lv_obj_t* title_label_; - - lv_obj_t* scrubber_; - lv_obj_t* play_pause_control_; - lv_obj_t* next_up_header_; lv_obj_t* next_up_label_; lv_obj_t* next_up_hint_; diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp index 9980dac6..cb3e651c 100644 --- a/src/ui/include/ui_fsm.hpp +++ b/src/ui/include/ui_fsm.hpp @@ -7,13 +7,16 @@ #pragma once #include <stdint.h> +#include <sys/_stdint.h> #include <memory> #include <stack> #include "audio_events.hpp" #include "battery.hpp" +#include "bindey/property.h" #include "gpios.hpp" #include "lvgl_task.hpp" +#include "model_playback.hpp" #include "nvs.hpp" #include "relative_wheel.hpp" #include "screen_playing.hpp" @@ -27,6 +30,7 @@ #include "storage.hpp" #include "system_events.hpp" #include "touchwheel.hpp" +#include "track.hpp" #include "track_queue.hpp" #include "ui_events.hpp" #include "wheel_encoder.hpp" @@ -49,11 +53,11 @@ class UiState : public tinyfsm::Fsm<UiState> { /* Fallback event handler. Does nothing. */ void react(const tinyfsm::Event& ev) {} - virtual void react(const system_fsm::BatteryStateChanged&); - virtual void react(const audio::PlaybackStarted&); - virtual void react(const audio::PlaybackFinished&); - virtual void react(const audio::PlaybackUpdate&) {} - virtual void react(const audio::QueueUpdate&) {} + void react(const system_fsm::BatteryStateChanged&); + void react(const audio::PlaybackStarted&); + void react(const audio::PlaybackFinished&); + void react(const audio::PlaybackUpdate&); + void react(const audio::QueueUpdate&); virtual void react(const system_fsm::KeyLockChanged&); @@ -88,6 +92,10 @@ class UiState : public tinyfsm::Fsm<UiState> { static std::stack<std::shared_ptr<Screen>> sScreens; static std::shared_ptr<Screen> sCurrentScreen; static std::shared_ptr<Modal> sCurrentModal; + + static models::Playback sPlaybackModel; + + static bindey::property<battery::Battery::BatteryState> sPropBatteryState; }; namespace states { @@ -96,7 +104,6 @@ class Splash : public UiState { public: void exit() override; void react(const system_fsm::BootComplete&) override; - void react(const system_fsm::BatteryStateChanged&) override{}; using UiState::react; }; @@ -140,10 +147,6 @@ class Playing : public UiState { void react(const internal::BackPressed&) override; - void react(const audio::PlaybackStarted&) override; - void react(const audio::PlaybackUpdate&) override; - void react(const audio::PlaybackFinished&) override; - void react(const audio::QueueUpdate&) override; using UiState::react; }; |
