summaryrefslogtreecommitdiff
path: root/src/ui/ui_fsm.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-01-15 12:31:20 +1100
committerjacqueline <me@jacqueline.id.au>2024-01-15 12:31:20 +1100
commit7cdcd44e0ca10ebdc796638190ed1d9b45d99ef0 (patch)
tree637b43848d17c9dbdc1688cb4733eb235f223e37 /src/ui/ui_fsm.cpp
parent0e04eb918ec976017276306181282769d8896c83 (diff)
downloadtangara-fw-7cdcd44e0ca10ebdc796638190ed1d9b45d99ef0.tar.gz
Begin migration of remaining screens to Lua
Diffstat (limited to 'src/ui/ui_fsm.cpp')
-rw-r--r--src/ui/ui_fsm.cpp337
1 files changed, 123 insertions, 214 deletions
diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp
index 75327a58..adda1c18 100644
--- a/src/ui/ui_fsm.cpp
+++ b/src/ui/ui_fsm.cpp
@@ -33,15 +33,11 @@
#include "event_queue.hpp"
#include "gpios.hpp"
#include "lvgl_task.hpp"
-#include "modal_confirm.hpp"
-#include "modal_progress.hpp"
-#include "model_playback.hpp"
#include "nvs.hpp"
#include "property.hpp"
#include "relative_wheel.hpp"
#include "screen.hpp"
#include "screen_lua.hpp"
-#include "screen_settings.hpp"
#include "screen_splash.hpp"
#include "spiffs.hpp"
#include "storage.hpp"
@@ -66,13 +62,6 @@ std::shared_ptr<Screen> UiState::sCurrentScreen;
std::shared_ptr<Modal> UiState::sCurrentModal;
std::shared_ptr<lua::LuaThread> UiState::sLua;
-std::weak_ptr<screens::Bluetooth> UiState::bluetooth_screen_;
-
-models::Playback UiState::sPlaybackModel;
-models::TopBar UiState::sTopBarModel{{},
- UiState::sPlaybackModel.is_playing,
- UiState::sPlaybackModel.current_track};
-
static TimerHandle_t sAlertTimer;
static lv_obj_t* sAlertContainer;
@@ -80,6 +69,70 @@ static void alert_timer_callback(TimerHandle_t timer) {
events::Ui().Dispatch(internal::DismissAlerts{});
}
+lua::Property UiState::sBatteryPct{0};
+lua::Property UiState::sBatteryMv{0};
+lua::Property UiState::sBatteryCharging{false};
+
+lua::Property UiState::sBluetoothEnabled{false};
+lua::Property UiState::sBluetoothConnected{false};
+
+lua::Property UiState::sPlaybackPlaying{
+ false, [](const lua::LuaValue& val) {
+ bool current_val = std::get<bool>(sPlaybackPlaying.Get());
+ if (!std::holds_alternative<bool>(val)) {
+ return false;
+ }
+ bool new_val = std::get<bool>(val);
+ if (current_val != new_val) {
+ events::Audio().Dispatch(audio::TogglePlayPause{});
+ }
+ return true;
+ }};
+
+lua::Property UiState::sPlaybackTrack{0};
+lua::Property UiState::sPlaybackPosition{0};
+
+lua::Property UiState::sQueuePosition{0};
+lua::Property UiState::sQueueSize{0};
+lua::Property UiState::sQueueRepeat{false};
+lua::Property UiState::sQueueRandom{false};
+
+lua::Property UiState::sVolumeCurrentPct{
+ 0, [](const lua::LuaValue& val) {
+ events::Audio().Dispatch(audio::SetVolume{
+ .percent = {},
+ .db = 0,
+ });
+ return false;
+ }};
+lua::Property UiState::sVolumeCurrentDb{
+ 0, [](const lua::LuaValue& val) {
+ events::Audio().Dispatch(audio::SetVolume{
+ .percent = {},
+ .db = 0,
+ });
+ return false;
+ }};
+lua::Property UiState::sVolumeLeftBias{
+ 0, [](const lua::LuaValue& val) {
+ events::Audio().Dispatch(audio::SetVolumeBalance{
+ .left_bias = 0,
+ });
+ return false;
+ }};
+lua::Property UiState::sVolumeLimit{
+ 0, [](const lua::LuaValue& val) {
+ events::Audio().Dispatch(audio::SetVolumeLimit{
+ .new_limit = 0,
+ });
+ return false;
+ }};
+
+lua::Property UiState::sDisplayBrightness{0, [](const lua::LuaValue& val) {
+ sDisplay->SetBrightness(0);
+ return false;
+ }};
+
auto UiState::InitBootSplash(drivers::IGpios& gpios) -> bool {
// Init LVGL first, since the display driver registers itself with LVGL.
lv_init();
@@ -118,30 +171,59 @@ void UiState::react(const system_fsm::KeyLockChanged& ev) {
sInput->lock(ev.locking);
}
-void UiState::react(const system_fsm::BatteryStateChanged& ev) {
- sTopBarModel.battery_state.set(ev.new_state);
+void UiState::react(const internal::ControlSchemeChanged&) {
+ if (!sInput) {
+ return;
+ }
+ sInput->mode(sServices->nvs().PrimaryInput());
}
-void UiState::react(const audio::PlaybackStarted&) {}
-
-void UiState::react(const audio::PlaybackFinished&) {}
+void UiState::react(const internal::DismissAlerts&) {
+ lv_obj_clean(sAlertContainer);
+}
-void UiState::react(const audio::PlaybackUpdate& ev) {}
+void UiState::react(const system_fsm::BatteryStateChanged& ev) {
+ sBatteryPct.Update(static_cast<int>(ev.new_state.percent));
+ sBatteryMv.Update(static_cast<int>(ev.new_state.millivolts));
+}
void UiState::react(const audio::QueueUpdate&) {
auto& queue = sServices->track_queue();
- sPlaybackModel.current_track.set(queue.current());
-}
+ sQueueSize.Update(static_cast<int>(queue.totalSize()));
-void UiState::react(const internal::ControlSchemeChanged&) {
- if (!sInput) {
- return;
+ int current_pos = queue.currentPosition();
+ if (queue.current()) {
+ current_pos++;
}
- sInput->mode(sServices->nvs().PrimaryInput());
+ sQueuePosition.Update(current_pos);
+ sQueueRandom.Update(queue.random());
+ sQueueRepeat.Update(queue.repeat());
}
-void UiState::react(const internal::DismissAlerts&) {
- lv_obj_clean(sAlertContainer);
+void UiState::react(const audio::PlaybackStarted& ev) {
+ sPlaybackPlaying.Update(true);
+}
+
+void UiState::react(const audio::PlaybackUpdate& ev) {
+ sPlaybackTrack.Update(*ev.track);
+ sPlaybackPosition.Update(static_cast<int>(ev.seconds_elapsed));
+}
+
+void UiState::react(const audio::PlaybackFinished&) {
+ sPlaybackPlaying.Update(false);
+}
+
+void UiState::react(const audio::VolumeChanged& ev) {
+ sVolumeCurrentPct.Update(static_cast<int>(ev.percent));
+ sVolumeCurrentDb.Update(static_cast<int>(ev.db));
+}
+
+void UiState::react(const audio::VolumeBalanceChanged& ev) {
+ sVolumeLeftBias.Update(ev.left_bias);
+}
+
+void UiState::react(const audio::VolumeLimitChanged& ev) {
+ sVolumeLeftBias.Update(ev.new_limit);
}
namespace states {
@@ -185,57 +267,36 @@ void Lua::entry() {
alert_timer_callback);
sAlertContainer = lv_obj_create(sCurrentScreen->alert());
- auto bat =
- sServices->battery().State().value_or(battery::Battery::BatteryState{});
- battery_pct_ =
- std::make_shared<lua::Property>(static_cast<int>(bat.percent));
- battery_mv_ =
- std::make_shared<lua::Property>(static_cast<int>(bat.millivolts));
- battery_charging_ = std::make_shared<lua::Property>(bat.is_charging);
-
- bluetooth_en_ = std::make_shared<lua::Property>(false);
-
- queue_position_ = std::make_shared<lua::Property>(0);
- queue_size_ = std::make_shared<lua::Property>(0);
- queue_repeat_ = std::make_shared<lua::Property>(false);
- queue_random_ = std::make_shared<lua::Property>(false);
-
- playback_playing_ = std::make_shared<lua::Property>(
- false, [&](const lua::LuaValue& val) { return SetPlaying(val); });
- playback_track_ = std::make_shared<lua::Property>();
- playback_position_ = std::make_shared<lua::Property>();
-
- volume_current_pct_ = std::make_shared<lua::Property>(0);
- volume_current_db_ = std::make_shared<lua::Property>(0);
-
sLua.reset(lua::LuaThread::Start(*sServices, sCurrentScreen->content()));
sLua->bridge().AddPropertyModule("power",
{
- {"battery_pct", battery_pct_},
- {"battery_millivolts", battery_mv_},
- {"plugged_in", battery_charging_},
+ {"battery_pct", &sBatteryPct},
+ {"battery_millivolts", &sBatteryMv},
+ {"plugged_in", &sBatteryCharging},
});
sLua->bridge().AddPropertyModule("bluetooth",
{
- {"enabled", bluetooth_en_},
- {"connected", bluetooth_en_},
+ {"enabled", &sBluetoothEnabled},
+ {"connected", &sBluetoothConnected},
});
sLua->bridge().AddPropertyModule("playback",
{
- {"playing", playback_playing_},
- {"track", playback_track_},
- {"position", playback_position_},
+ {"playing", &sPlaybackPlaying},
+ {"track", &sPlaybackTrack},
+ {"position", &sPlaybackPosition},
});
sLua->bridge().AddPropertyModule("queue", {
- {"position", queue_position_},
- {"size", queue_size_},
- {"replay", queue_repeat_},
- {"random", queue_random_},
+ {"position", &sQueuePosition},
+ {"size", &sQueueSize},
+ {"replay", &sQueueRepeat},
+ {"random", &sQueueRandom},
});
sLua->bridge().AddPropertyModule("volume",
{
- {"current_pct", volume_current_pct_},
- {"current_db", volume_current_db_},
+ {"current_pct", &sVolumeCurrentPct},
+ {"current_db", &sVolumeCurrentDb},
+ {"left_bias", &sVolumeLeftBias},
+ {"limit_db", &sVolumeLimit},
});
sLua->bridge().AddPropertyModule(
@@ -288,18 +349,6 @@ auto Lua::PopLuaScreen(lua_State* s) -> int {
return 0;
}
-auto Lua::SetPlaying(const lua::LuaValue& val) -> bool {
- bool current_val = std::get<bool>(playback_playing_->Get());
- if (!std::holds_alternative<bool>(val)) {
- return false;
- }
- bool new_val = std::get<bool>(val);
- if (current_val != new_val) {
- events::Audio().Dispatch(audio::TogglePlayPause{});
- }
- return true;
-}
-
auto Lua::ShowAlert(lua_State* s) -> int {
if (!sCurrentScreen) {
return 0;
@@ -358,150 +407,10 @@ void Lua::react(const OnLuaError& err) {
ESP_LOGE("lua", "%s", err.message.c_str());
}
-void Lua::react(const internal::ShowSettingsPage& ev) {
- PushScreen(std::shared_ptr<Screen>(new screens::Settings(sTopBarModel)));
- transit<Browse>();
-}
-
-void Lua::react(const system_fsm::BatteryStateChanged& ev) {
- battery_pct_->Update(static_cast<int>(ev.new_state.percent));
- battery_mv_->Update(static_cast<int>(ev.new_state.millivolts));
-}
-
-void Lua::react(const audio::QueueUpdate&) {
- auto& queue = sServices->track_queue();
- queue_size_->Update(static_cast<int>(queue.totalSize()));
-
- int current_pos = queue.currentPosition();
- if (queue.current()) {
- current_pos++;
- }
- queue_position_->Update(current_pos);
- queue_random_->Update(queue.random());
- queue_repeat_->Update(queue.repeat());
-}
-
-void Lua::react(const audio::PlaybackStarted& ev) {
- playback_playing_->Update(true);
-}
-
-void Lua::react(const audio::PlaybackUpdate& ev) {
- playback_track_->Update(*ev.track);
- playback_position_->Update(static_cast<int>(ev.seconds_elapsed));
-}
-
-void Lua::react(const audio::PlaybackFinished&) {
- playback_playing_->Update(false);
-}
-
-void Lua::react(const audio::VolumeChanged& ev) {
- volume_current_pct_->Update(static_cast<int>(ev.percent));
- volume_current_db_->Update(static_cast<int>(ev.db));
-}
-
void Lua::react(const internal::BackPressed& ev) {
PopLuaScreen(sLua->state());
}
-void Browse::entry() {}
-
-void Browse::react(const internal::ShowSettingsPage& ev) {
- std::shared_ptr<Screen> screen;
- std::shared_ptr<screens::Bluetooth> bt_screen;
- switch (ev.page) {
- case internal::ShowSettingsPage::Page::kRoot:
- screen.reset(new screens::Settings(sTopBarModel));
- break;
- case internal::ShowSettingsPage::Page::kBluetooth:
- bt_screen = std::make_shared<screens::Bluetooth>(
- sTopBarModel, sServices->bluetooth(), sServices->nvs());
- screen = bt_screen;
- bluetooth_screen_ = bt_screen;
- break;
- case internal::ShowSettingsPage::Page::kHeadphones:
- screen.reset(new screens::Headphones(sTopBarModel, sServices->nvs()));
- break;
- case internal::ShowSettingsPage::Page::kAppearance:
- screen.reset(
- new screens::Appearance(sTopBarModel, sServices->nvs(), *sDisplay));
- break;
- case internal::ShowSettingsPage::Page::kInput:
- screen.reset(new screens::InputMethod(sTopBarModel, sServices->nvs()));
- break;
- case internal::ShowSettingsPage::Page::kStorage:
- screen.reset(new screens::Storage(sTopBarModel));
- break;
- case internal::ShowSettingsPage::Page::kFirmwareUpdate:
- screen.reset(
- new screens::FirmwareUpdate(sTopBarModel, sServices->samd()));
- break;
- case internal::ShowSettingsPage::Page::kAbout:
- screen.reset(new screens::About(sTopBarModel));
- break;
- }
- if (screen) {
- PushScreen(screen);
- }
-}
-
-void Browse::react(const internal::BackPressed& ev) {
- if (PopScreen() == 0) {
- transit<Lua>();
- }
-}
-
-void Browse::react(const system_fsm::BluetoothDevicesChanged&) {
- auto bt = bluetooth_screen_.lock();
- if (bt) {
- bt->RefreshDevicesList();
- }
-}
-
-void Browse::react(const internal::ReindexDatabase& ev) {
- transit<Indexing>();
-}
-
-static std::shared_ptr<modals::Progress> sIndexProgress;
-
-void Indexing::entry() {
- sIndexProgress.reset(new modals::Progress(sCurrentScreen.get(), "Indexing",
- "Preparing database"));
- sCurrentModal = sIndexProgress;
- auto db = sServices->database().lock();
- if (!db) {
- // TODO: Hmm.
- return;
- }
- sServices->bg_worker().Dispatch<void>([=]() { db->updateIndexes(); });
-}
-
-void Indexing::exit() {
- sCurrentModal.reset();
- sIndexProgress.reset();
-}
-
-void Indexing::react(const database::event::UpdateStarted&) {}
-
-void Indexing::react(const database::event::UpdateProgress& ev) {
- std::ostringstream str;
- switch (ev.stage) {
- case database::event::UpdateProgress::Stage::kVerifyingExistingTracks:
- sIndexProgress->title("Verifying");
- str << "Tracks checked: " << ev.val;
- sIndexProgress->subtitle(str.str().c_str());
- break;
- case database::event::UpdateProgress::Stage::kScanningForNewTracks:
- sIndexProgress->title("Scanning");
- str << "Files checked: " << ev.val;
- sIndexProgress->subtitle(str.str().c_str());
- break;
- }
-}
-
-void Indexing::react(const database::event::UpdateFinished&) {
- transit<Browse>();
-}
-
} // namespace states
} // namespace ui