From f09ba5ffd53bf7d28e0dc516c00a8f69ca7efae9 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 28 Sep 2023 08:29:55 +1000 Subject: Use bindey for databinding instead of hand rolling ui updates --- src/ui/include/event_binding.hpp | 30 ++++++++++++++++++++++++++++++ src/ui/include/model_playback.hpp | 26 ++++++++++++++++++++++++++ src/ui/include/screen.hpp | 14 ++++++++++++++ src/ui/include/screen_playing.hpp | 33 ++++++++++++--------------------- src/ui/include/ui_fsm.hpp | 23 +++++++++++++---------- 5 files changed, 95 insertions(+), 31 deletions(-) create mode 100644 src/ui/include/event_binding.hpp create mode 100644 src/ui/include/model_playback.hpp (limited to 'src/ui/include') 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 + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include + +#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& { return signal_; } + + private: + lv_obj_t* obj_; + nod::signal 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 + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include "bindey/property.h" + +#include "track.hpp" + +namespace ui { +namespace models { + +struct Playback { + bindey::property is_playing; + bindey::property> current_track; + bindey::property> upcoming_tracks; + + bindey::property current_track_position; + bindey::property 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 #include +#include +#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 data_bindings_; + std::pmr::vector> event_bindings_; + + template + auto lv_bind(lv_obj_t* obj, lv_event_code_t ev, T fn) -> void { + auto binding = std::make_unique(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 #include +#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 db, + explicit Playing(models::Playback& playback_model, + std::weak_ptr 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& tracks) -> void; - std::weak_ptr db_; audio::TrackQueue& queue_; - std::optional track_; - std::vector next_tracks_; + bindey::property> current_track_; + bindey::property>> next_tracks_; - std::unique_ptr>> + std::unique_ptr>> new_track_; std::unique_ptr< - database::FutureFetcher>>> + database::FutureFetcher>>> 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 +#include #include #include #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 { /* 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 { static std::stack> sScreens; static std::shared_ptr sCurrentScreen; static std::shared_ptr sCurrentModal; + + static models::Playback sPlaybackModel; + + static bindey::property 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; }; -- cgit v1.2.3