mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-01 02:19:00 -05:00
In the settings, the user can choose a clock face with quotes. A dedicated clock face includes information about the time, alarm settings, quote and author of the quote.
258 lines
7.9 KiB
C++
258 lines
7.9 KiB
C++
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "TimeSetSpinner.hpp"
|
|
|
|
#include <FontManager.hpp>
|
|
#include <RawFont.hpp>
|
|
#include <gui/widgets/ImageBox.hpp>
|
|
#include <gui/widgets/text/Label.hpp>
|
|
|
|
namespace
|
|
{
|
|
constexpr auto hourMin = 0;
|
|
constexpr auto hourMax = 23;
|
|
constexpr auto hourStep = 1;
|
|
constexpr auto minuteMin = 0;
|
|
constexpr auto minuteMax = 59;
|
|
constexpr auto minuteStep = 1;
|
|
} // namespace
|
|
|
|
namespace gui
|
|
{
|
|
TimeSetSpinner::TimeSetSpinner(Item *parent) : TimeSetSpinner(parent, 0, 0, 0, 0)
|
|
{}
|
|
|
|
TimeSetSpinner::TimeSetSpinner(Item *parent, Length x, Length y, Length w, Length h) : HBox(parent, x, y, w, h)
|
|
{
|
|
setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
setEdges(RectangleEdge::None);
|
|
|
|
hour = new U8IntegerSpinner(U8IntegerSpinner::range{hourMin, hourMax, hourStep}, Boundaries::Continuous);
|
|
updateFont(hour, noFocusFontName);
|
|
|
|
hour->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
|
|
hour->setEdges(RectangleEdge::None);
|
|
hour->setPenFocusWidth(style::time_set_spinner::focus::size);
|
|
hour->set_value(0);
|
|
|
|
addWidget(hour);
|
|
|
|
colon = new ImageBox(this, 0, 0, 0, 0, new Image(getColonImage(noFocusFontName)));
|
|
colon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
colon->setMargins(getColonMargins(noFocusFontName));
|
|
colon->setEdges(RectangleEdge::None);
|
|
colon->activeItem = false;
|
|
|
|
minute = new U8IntegerSpinnerFixed(U8IntegerSpinnerFixed::range{minuteMin, minuteMax, minuteStep},
|
|
Boundaries::Continuous);
|
|
updateFont(minute, noFocusFontName);
|
|
minute->setPenFocusWidth(style::time_set_spinner::focus::size);
|
|
|
|
minute->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
|
|
minute->setEdges(RectangleEdge::None);
|
|
minute->set_value(0);
|
|
addWidget(minute);
|
|
|
|
resizeItems();
|
|
|
|
focusChangedCallback = [&](Item &) {
|
|
if (editMode != EditMode::Edit) {
|
|
setFocusItem(nullptr);
|
|
return false;
|
|
}
|
|
|
|
updateFocus(lastFocus != nullptr ? lastFocus : hour);
|
|
return true;
|
|
};
|
|
if (editMode == EditMode::Edit) {
|
|
updateFocus(hour);
|
|
}
|
|
}
|
|
|
|
auto TimeSetSpinner::onInput(const InputEvent &inputEvent) -> bool
|
|
{
|
|
if (editMode != EditMode::Edit) {
|
|
return false;
|
|
}
|
|
|
|
if (auto ret = this->focusItem->onInput(inputEvent)) {
|
|
applySizeRestrictions();
|
|
return ret;
|
|
}
|
|
|
|
if (inputEvent.isShortRelease()) {
|
|
switch (inputEvent.getKeyCode()) {
|
|
case KeyCode::KEY_ENTER:
|
|
return handleEnterKey();
|
|
case KeyCode::KEY_RF:
|
|
return handleRightFunctionKey();
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
uint16_t TimeSetSpinner::getFontHeight(const std::string &fontName) const noexcept
|
|
{
|
|
const RawFont *font = FontManager::getInstance().getFont(fontName);
|
|
return font->info.line_height;
|
|
}
|
|
|
|
auto TimeSetSpinner::handleEnterKey() -> bool
|
|
{
|
|
if (focusItem == hour) {
|
|
updateFocus(minute);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
auto TimeSetSpinner::handleRightFunctionKey() -> bool
|
|
{
|
|
if (focusItem == minute) {
|
|
updateFocus(hour);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
auto TimeSetSpinner::setTime(std::time_t time) noexcept -> void
|
|
{
|
|
const auto t = std::localtime(&time);
|
|
setHour(t->tm_hour);
|
|
setMinute(t->tm_min);
|
|
applySizeRestrictions();
|
|
}
|
|
|
|
auto TimeSetSpinner::setTime(int hourValue, int minuteValue) noexcept -> void
|
|
{
|
|
setHour(hourValue);
|
|
setMinute(minuteValue);
|
|
applySizeRestrictions();
|
|
}
|
|
|
|
auto TimeSetSpinner::setHour(int value) noexcept -> void
|
|
{
|
|
hour->set_value(value);
|
|
}
|
|
|
|
auto TimeSetSpinner::setMinute(int value) noexcept -> void
|
|
{
|
|
minute->set_value(value);
|
|
}
|
|
|
|
auto TimeSetSpinner::setFont(const std::string &newFontName) noexcept -> void
|
|
{
|
|
setFont(newFontName, newFontName);
|
|
}
|
|
|
|
auto TimeSetSpinner::setFont(std::string newFocusFontName, std::string newNoFocusFontName) noexcept -> void
|
|
{
|
|
focusFontName = std::move(newFocusFontName);
|
|
noFocusFontName = std::move(newNoFocusFontName);
|
|
|
|
updateFont(hour, noFocusFontName);
|
|
updateFont(minute, noFocusFontName);
|
|
|
|
colon->setImage(getColonImage(noFocusFontName));
|
|
colon->setMargins(getColonMargins(noFocusFontName));
|
|
colon->fitBoxToImage();
|
|
|
|
setMinimumSize(hour->widgetMinimumArea.w + colon->widgetMinimumArea.w +
|
|
colon->getMargins().getSumInAxis(Axis::X) + minute->widgetMinimumArea.w,
|
|
getFontHeight(noFocusFontName));
|
|
resizeItems();
|
|
}
|
|
|
|
auto TimeSetSpinner::updateFont(TextFixedSize *elem, const std::string &fontName) noexcept -> void
|
|
{
|
|
elem->setFont(fontName);
|
|
elem->setMinimumHeightToFitText();
|
|
elem->setMinimumWidthToFitText();
|
|
|
|
elem->setText(elem->getText());
|
|
}
|
|
|
|
auto TimeSetSpinner::setEditMode(EditMode editMode) noexcept -> void
|
|
{
|
|
this->editMode = editMode;
|
|
if (editMode == EditMode::Edit) {
|
|
updateFocus(hour);
|
|
}
|
|
else {
|
|
setFocusItem(nullptr);
|
|
}
|
|
}
|
|
|
|
auto TimeSetSpinner::getHour() const noexcept -> int
|
|
{
|
|
return hour->value();
|
|
}
|
|
|
|
auto TimeSetSpinner::getMinute() const noexcept -> int
|
|
{
|
|
return minute->value();
|
|
}
|
|
|
|
void TimeSetSpinner::updateFocus(Item *newFocus)
|
|
{
|
|
if (focus) {
|
|
setFocusItem(newFocus);
|
|
lastFocus = newFocus;
|
|
|
|
if (minute->focus) {
|
|
updateFont(minute, focusFontName);
|
|
updateFont(hour, noFocusFontName);
|
|
}
|
|
else if (hour->focus) {
|
|
updateFont(hour, focusFontName);
|
|
updateFont(minute, noFocusFontName);
|
|
}
|
|
}
|
|
else {
|
|
updateFont(hour, noFocusFontName);
|
|
updateFont(minute, noFocusFontName);
|
|
setFocusItem(nullptr);
|
|
}
|
|
|
|
applySizeRestrictions();
|
|
}
|
|
|
|
auto TimeSetSpinner::setHourRange(std::uint32_t min, std::uint32_t max) -> void
|
|
{
|
|
hour->set_range(
|
|
U8IntegerSpinner::range{static_cast<std::uint8_t>(min), static_cast<std::uint8_t>(max), hourStep});
|
|
}
|
|
|
|
auto TimeSetSpinner::getColonImage(const std::string &colonFont) const noexcept -> std::string
|
|
{
|
|
return colonFontMap.find(colonFont)->second;
|
|
}
|
|
|
|
auto TimeSetSpinner::getColonMargins(const std::string &colonFont) const noexcept -> Margins
|
|
{
|
|
const auto colonMargins = colonMarginsMap.find(colonFont);
|
|
if (colonMargins == colonMarginsMap.end()) {
|
|
LOG_ERROR("Missing margins map entry for font '%s', update margins map! Fallback value (zero) will be set.",
|
|
colonFont.c_str());
|
|
return Margins();
|
|
}
|
|
return colonMargins->second;
|
|
}
|
|
|
|
auto TimeSetSpinner::applySizeRestrictions() -> void
|
|
{
|
|
hour->setMinimumWidthToFitText();
|
|
minute->setMinimumWidthToFitText();
|
|
|
|
setMinimumSize(hour->widgetMinimumArea.w + colon->widgetMinimumArea.w +
|
|
colon->getMargins().getSumInAxis(Axis::X) + minute->widgetMinimumArea.w,
|
|
getFontHeight(noFocusFontName));
|
|
setMaximumWidth(widgetMinimumArea.w);
|
|
|
|
HBox::informContentChanged();
|
|
}
|
|
} /* namespace gui */
|