Kiosk: apply schedule engine in playback and add System Settings toggle
ScrollerPage now resolves the active Block from ScheduleManager (reusing the existing stream-switch path), honoring dynamicAudio true/false and falling back to local selection for gaps, no schedule, or toggle off. Adds a 'Schedule' On/Off entry (default On) in System Settings persisted in config.yaml, and config plumbing (proclamation.schedule_enabled). All on-device schedule times remain 12h AM/PM.
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
#include "schedule_toggle_page.h"
|
||||
#include "app_state.h"
|
||||
#include "config/app_config.h"
|
||||
#include "logical_size.h"
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
void ScheduleTogglePage::onPush(AppState& state)
|
||||
{
|
||||
state_ = &state;
|
||||
TTF_Init();
|
||||
createFonts();
|
||||
enabled_ = state.config.get().proclamation.schedule_enabled;
|
||||
statusMessage_ = "Press ENTER to turn the Schedule on or off";
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::onResume(AppState& state)
|
||||
{
|
||||
state_ = &state;
|
||||
createFonts();
|
||||
enabled_ = state.config.get().proclamation.schedule_enabled;
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::onPause(AppState& state)
|
||||
{
|
||||
state.keybinds.unbindAll();
|
||||
destroyFonts();
|
||||
destroyTextures();
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::onPop(AppState& state)
|
||||
{
|
||||
destroyFonts();
|
||||
destroyTextures();
|
||||
TTF_Quit();
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::createFonts()
|
||||
{
|
||||
destroyFonts();
|
||||
fontTitle_ = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 52);
|
||||
fontHeader_ = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 28);
|
||||
fontBody_ = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 32);
|
||||
fontSmall_ = TTF_OpenFont("assets/fonts/Roboto-Regular.ttf", 22);
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::destroyFonts()
|
||||
{
|
||||
if (fontTitle_) { TTF_CloseFont(fontTitle_); fontTitle_ = nullptr; }
|
||||
if (fontHeader_) { TTF_CloseFont(fontHeader_); fontHeader_ = nullptr; }
|
||||
if (fontBody_) { TTF_CloseFont(fontBody_); fontBody_ = nullptr; }
|
||||
if (fontSmall_) { TTF_CloseFont(fontSmall_); fontSmall_ = nullptr; }
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::destroyTextures()
|
||||
{
|
||||
titleText_.destroy();
|
||||
stateText_.destroy();
|
||||
statusText_.destroy();
|
||||
hintText_.destroy();
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::toggle()
|
||||
{
|
||||
if (!state_) return;
|
||||
const bool next = !enabled_;
|
||||
const bool ok = state_->config.update([next](radiantwave::config::AppConfig& cfg) {
|
||||
cfg.proclamation.schedule_enabled = next;
|
||||
});
|
||||
if (ok) {
|
||||
enabled_ = next;
|
||||
statusMessage_ = enabled_ ? "Schedule enabled" : "Schedule disabled";
|
||||
// Push the new state to the engine and nudge a refresh. While off the
|
||||
// engine takes no action but keeps its cache updating.
|
||||
state_->scheduleManager.setEnabled(enabled_);
|
||||
state_->scheduleManager.requestRefresh();
|
||||
} else {
|
||||
statusMessage_ = "Failed to save";
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::handleEvent(const SDL_Event& event)
|
||||
{
|
||||
if (!state_) return;
|
||||
if (event.type == SDL_EVENT_KEY_DOWN) {
|
||||
SDL_Keycode key = event.key.key;
|
||||
if (key == SDLK_RETURN || key == SDLK_KP_ENTER) {
|
||||
toggle();
|
||||
} else if (key == SDLK_ESCAPE) {
|
||||
state_->pages.pop(*state_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::update(float dt)
|
||||
{
|
||||
}
|
||||
|
||||
void ScheduleTogglePage::render(SDL_Renderer* renderer)
|
||||
{
|
||||
int winW, winH;
|
||||
radiantwave::getLayoutSize(renderer, &winW, &winH);
|
||||
float fw = static_cast<float>(winW);
|
||||
float fh = static_cast<float>(winH);
|
||||
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 20, 20, 30, 255);
|
||||
SDL_FRect bgRect{0, 0, fw, fh};
|
||||
SDL_RenderFillRect(renderer, &bgRect);
|
||||
|
||||
if (!fontTitle_ || !fontHeader_ || !fontBody_ || !fontSmall_) return;
|
||||
|
||||
SDL_Color white = {255, 255, 255, 255};
|
||||
SDL_Color green = {110, 220, 130, 255};
|
||||
SDL_Color gray = {180, 180, 180, 255};
|
||||
|
||||
float currentY = 40.0f;
|
||||
|
||||
titleText_.ensure(renderer, fontTitle_, "Schedule", white);
|
||||
if (titleText_.texture) {
|
||||
float x = (fw - titleText_.width) / 2.0f;
|
||||
SDL_FRect dst{x, currentY, titleText_.width, titleText_.height};
|
||||
SDL_RenderTexture(renderer, titleText_.texture, nullptr, &dst);
|
||||
currentY += titleText_.height + 50.0f;
|
||||
}
|
||||
|
||||
std::string value = enabled_ ? "On" : "Off";
|
||||
stateText_.ensure(renderer, fontBody_, "Schedule: " + value,
|
||||
enabled_ ? green : gray);
|
||||
if (stateText_.texture) {
|
||||
float x = (fw - stateText_.width) / 2.0f;
|
||||
SDL_FRect dst{x, currentY, stateText_.width, stateText_.height};
|
||||
SDL_RenderTexture(renderer, stateText_.texture, nullptr, &dst);
|
||||
currentY += stateText_.height + 40.0f;
|
||||
}
|
||||
|
||||
if (!statusMessage_.empty()) {
|
||||
statusText_.ensure(renderer, fontHeader_, statusMessage_, gray);
|
||||
if (statusText_.texture) {
|
||||
float x = (fw - statusText_.width) / 2.0f;
|
||||
SDL_FRect dst{x, currentY, statusText_.width, statusText_.height};
|
||||
SDL_RenderTexture(renderer, statusText_.texture, nullptr, &dst);
|
||||
}
|
||||
}
|
||||
|
||||
hintText_.ensure(renderer, fontSmall_,
|
||||
"[ENTER] Toggle [ESC] Back", gray);
|
||||
if (hintText_.texture) {
|
||||
float x = (fw - hintText_.width) / 2.0f;
|
||||
SDL_FRect dst{x, fh - 40.0f, hintText_.width, hintText_.height};
|
||||
SDL_RenderTexture(renderer, hintText_.texture, nullptr, &dst);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user