#include "SetTimeActivity.h" #include #include #include #include #include #include "CrossPointSettings.h" #include "MappedInputManager.h" #include "components/UITheme.h" #include "fontIds.h" void SetTimeActivity::onEnter() { Activity::onEnter(); // Initialize from current system time if it's been set (year > 2000) time_t now = time(nullptr); struct tm* t = localtime(&now); if (t != nullptr && t->tm_year > 100) { hour = t->tm_hour; minute = t->tm_min; } else { hour = 12; minute = 0; } selectedField = 0; requestUpdate(); } void SetTimeActivity::onExit() { Activity::onExit(); } void SetTimeActivity::loop() { // Back button: discard and exit if (mappedInput.wasPressed(MappedInputManager::Button::Back)) { finish(); return; } // Confirm button: apply time and exit if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) { applyTime(); finish(); return; } // Left/Right: switch between hour and minute fields if (mappedInput.wasPressed(MappedInputManager::Button::Left)) { selectedField = 0; requestUpdate(); return; } if (mappedInput.wasPressed(MappedInputManager::Button::Right)) { selectedField = 1; requestUpdate(); return; } // Up/Down: increment/decrement the selected field if (mappedInput.wasPressed(MappedInputManager::Button::Up)) { if (selectedField == 0) { hour = (hour + 1) % 24; } else { minute = (minute + 1) % 60; } requestUpdate(); return; } if (mappedInput.wasPressed(MappedInputManager::Button::Down)) { if (selectedField == 0) { hour = (hour + 23) % 24; } else { minute = (minute + 59) % 60; } requestUpdate(); return; } } void SetTimeActivity::render(RenderLock&&) { renderer.clearScreen(); const auto pageWidth = renderer.getScreenWidth(); const int lineHeight12 = renderer.getLineHeight(UI_12_FONT_ID); // Title renderer.drawCenteredText(UI_12_FONT_ID, 20, tr(STR_SET_TIME), true, EpdFontFamily::BOLD); // Format hour and minute strings char hourStr[4]; char minuteStr[4]; snprintf(hourStr, sizeof(hourStr), "%02d", hour); snprintf(minuteStr, sizeof(minuteStr), "%02d", minute); const int colonWidth = renderer.getTextWidth(UI_12_FONT_ID, " : "); const int digitWidth = renderer.getTextWidth(UI_12_FONT_ID, "00"); const int totalWidth = digitWidth * 2 + colonWidth; const int startX = (pageWidth - totalWidth) / 2; const int timeY = 80; // Draw selection highlight behind the selected field constexpr int highlightPad = 6; if (selectedField == 0) { renderer.fillRoundedRect(startX - highlightPad, timeY - 4, digitWidth + highlightPad * 2, lineHeight12 + 8, 6, Color::LightGray); } else { renderer.fillRoundedRect(startX + digitWidth + colonWidth - highlightPad, timeY - 4, digitWidth + highlightPad * 2, lineHeight12 + 8, 6, Color::LightGray); } // Draw the time digits and colon renderer.drawText(UI_12_FONT_ID, startX, timeY, hourStr, true); renderer.drawText(UI_12_FONT_ID, startX + digitWidth, timeY, " : ", true); renderer.drawText(UI_12_FONT_ID, startX + digitWidth + colonWidth, timeY, minuteStr, true); // Draw up/down arrows above and below the selected field const int arrowX = (selectedField == 0) ? startX + digitWidth / 2 : startX + digitWidth + colonWidth + digitWidth / 2; const int arrowUpY = timeY - 20; const int arrowDownY = timeY + lineHeight12 + 12; // Up arrow (simple triangle using lines) constexpr int arrowSize = 6; for (int row = 0; row < arrowSize; row++) { renderer.drawLine(arrowX - row, arrowUpY + row, arrowX + row, arrowUpY + row); } // Down arrow for (int row = 0; row < arrowSize; row++) { renderer.drawLine(arrowX - row, arrowDownY + arrowSize - 1 - row, arrowX + row, arrowDownY + arrowSize - 1 - row); } // Button hints const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SAVE), tr(STR_DIR_UP), tr(STR_DIR_DOWN)); GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); } void SetTimeActivity::applyTime() { time_t now = time(nullptr); struct tm newTime = {}; struct tm* current = localtime(&now); if (current != nullptr && current->tm_year > 100) { newTime = *current; } else { // If time was never set, use a reasonable date (2025-01-01) newTime.tm_year = 125; // years since 1900 newTime.tm_mon = 0; newTime.tm_mday = 1; } newTime.tm_hour = hour; newTime.tm_min = minute; newTime.tm_sec = 0; time_t newEpoch = mktime(&newTime); struct timeval tv = {.tv_sec = newEpoch, .tv_usec = 0}; settimeofday(&tv, nullptr); }