summaryrefslogtreecommitdiff
path: root/src/ui/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/include')
-rw-r--r--src/ui/include/event_binding.hpp30
-rw-r--r--src/ui/include/model_playback.hpp26
-rw-r--r--src/ui/include/screen.hpp14
-rw-r--r--src/ui/include/screen_playing.hpp33
-rw-r--r--src/ui/include/ui_fsm.hpp23
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;
};