diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-01-15 12:31:20 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-01-15 12:31:20 +1100 |
| commit | 7cdcd44e0ca10ebdc796638190ed1d9b45d99ef0 (patch) | |
| tree | 637b43848d17c9dbdc1688cb4733eb235f223e37 /src/ui/ui_fsm.cpp | |
| parent | 0e04eb918ec976017276306181282769d8896c83 (diff) | |
| download | tangara-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.cpp | 337 |
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 |
