Files
system-control/firmware/components/insa/src/ui/ClockScreenSaver.cpp
Peter Siegmund 08b0e04584 implement new light mode (off/day/night/simulation)
missing:
- fully connect it to the ui
- setup duration in light settings

Signed-off-by: Peter Siegmund <developer@mars3142.org>
2025-09-29 23:15:06 +02:00

132 lines
3.3 KiB
C++

#include "ui/ClockScreenSaver.h"
#include "simulator.h"
#include <cstring>
#include <ctime>
ClockScreenSaver::ClockScreenSaver(menu_options_t *options)
: Widget(options->u8g2), m_options(options), m_moveTimer(0), m_posX(0), m_posY(0), m_velocityX(X_VELOCITY),
m_velocityY(Y_VELOCITY), m_textWidth(0), m_textHeight(0)
{
initPosition();
}
void ClockScreenSaver::initPosition()
{
// Start in the center of the screen
updateTextDimensions();
m_posX = (u8g2->width - m_textWidth) / 2;
m_posY = (u8g2->height - m_textHeight) / 2;
// Set initial velocity
m_velocityX = X_VELOCITY;
m_velocityY = Y_VELOCITY;
}
void ClockScreenSaver::updateTextDimensions()
{
char timeBuffer[32];
getCurrentTimeString(timeBuffer, sizeof(timeBuffer));
// Set font (use a large font for better visibility)
u8g2_SetFont(u8g2, FONT);
// Calculate text dimensions
m_textWidth = u8g2_GetStrWidth(u8g2, timeBuffer);
m_textHeight = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2);
}
void ClockScreenSaver::getCurrentTimeString(char *buffer, size_t bufferSize) const
{
char *simulated_time = get_time();
if (simulated_time != nullptr)
{
strncpy(buffer, simulated_time, bufferSize);
}
else
{
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
// Format time as HH:MM:SS
strftime(buffer, bufferSize, "%H:%M:%S", timeinfo);
}
}
void ClockScreenSaver::Update(const uint64_t dt)
{
m_moveTimer += dt;
// Move the clock position at regular intervals
if (m_moveTimer > MOVE_INTERVAL)
{
m_moveTimer = 0;
// Update text dimensions (in case time format changes)
updateTextDimensions();
// Update position
m_posX += m_velocityX;
m_posY += m_velocityY;
// Check for collisions with screen boundaries
checkBoundaryCollision();
}
}
void ClockScreenSaver::checkBoundaryCollision()
{
// Check horizontal boundaries
if (m_posX <= TEXT_PADDING)
{
m_posX = TEXT_PADDING;
m_velocityX = X_VELOCITY; // Bounce right
}
else if (m_posX + m_textWidth >= u8g2->width - TEXT_PADDING)
{
m_posX = u8g2->width - m_textWidth - TEXT_PADDING;
m_velocityX = -X_VELOCITY; // Bounce left
}
// Check vertical boundaries
if (m_posY <= TEXT_PADDING + m_textHeight)
{
m_posY = TEXT_PADDING + m_textHeight;
m_velocityY = Y_VELOCITY; // Bounce down
}
else if (m_posY >= u8g2->height - TEXT_PADDING)
{
m_posY = u8g2->height - TEXT_PADDING;
m_velocityY = -Y_VELOCITY; // Bounce up
}
}
void ClockScreenSaver::Render()
{
// Clear screen with a black background
u8g2_SetDrawColor(u8g2, 0);
u8g2_DrawBox(u8g2, 0, 0, u8g2->width, u8g2->height);
u8g2_SetDrawColor(u8g2, 1);
// Get current time
char timeBuffer[32];
getCurrentTimeString(timeBuffer, sizeof(timeBuffer));
// Set font
u8g2_SetFont(u8g2, FONT);
// Draw the time at current position
u8g2_DrawStr(u8g2, m_posX, m_posY, timeBuffer);
}
void ClockScreenSaver::OnButtonClicked(ButtonType button)
{
// Exit screensaver on any button press
if (m_options && m_options->popScreen)
{
m_options->popScreen();
}
}