mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-01 10:28:52 -05:00
151 lines
5.0 KiB
C++
151 lines
5.0 KiB
C++
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "DateSetSpinner.hpp"
|
|
|
|
#include <FontManager.hpp>
|
|
#include <RawFont.hpp>
|
|
#include <gui/widgets/ImageBox.hpp>
|
|
#include <gui/widgets/text/Label.hpp>
|
|
#include <time/time_locale.hpp>
|
|
|
|
namespace gui
|
|
{
|
|
namespace
|
|
{
|
|
constexpr std::uint8_t step = 1;
|
|
constexpr std::uint8_t dayMin = 1;
|
|
constexpr std::uint8_t dayMax = 31;
|
|
constexpr std::uint8_t monthMin = 1;
|
|
constexpr std::uint8_t monthMax = 12;
|
|
constexpr auto fontName = style::window::font::supersizeme;
|
|
|
|
void setFont(TextFixedSize *elem, const std::string &fontName)
|
|
{
|
|
elem->setFont(fontName);
|
|
elem->setMinimumHeightToFitText();
|
|
elem->setMinimumWidthToFitText();
|
|
elem->setText(elem->getText());
|
|
}
|
|
} // namespace
|
|
|
|
DateSetSpinner::DateSetSpinner(
|
|
Item *parent, Type type, TextFixedSize *title, Length x, Length y, Length w, Length h)
|
|
: HBox(parent, x, y, w, h), type{type}, title{title}
|
|
{
|
|
setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
setEdges(RectangleEdge::None);
|
|
|
|
switch (type) {
|
|
case Type::year:
|
|
attachDateField(
|
|
year,
|
|
U16IntegerSpinnerFixed::range{utils::time::Locale::min_years, utils::time::Locale::max_years, step});
|
|
year->onValueChanged = [this](auto) { updateDate(); };
|
|
setFocusItem(year);
|
|
break;
|
|
case Type::month:
|
|
attachDateField(dayMonth, U8IntegerSpinnerFixed::range{monthMin, monthMax, step});
|
|
dayMonth->onValueChanged = [this](auto) { updateDate(); };
|
|
setFocusItem(dayMonth);
|
|
break;
|
|
case Type::day:
|
|
attachDateField(dayMonth, U8IntegerSpinnerFixed::range{dayMin, dayMax, step});
|
|
dayMonth->onValueChanged = [this](auto) { updateDate(); };
|
|
setFocusItem(dayMonth);
|
|
break;
|
|
}
|
|
|
|
resizeItems();
|
|
applySizeRestrictions();
|
|
}
|
|
|
|
date::year_month_day DateSetSpinner::getDate() const
|
|
{
|
|
return date;
|
|
}
|
|
|
|
void DateSetSpinner::setDate(const date::year_month_day date)
|
|
{
|
|
this->date = date;
|
|
switch (type) {
|
|
case Type::year:
|
|
year->set_value(static_cast<int>(date.year()));
|
|
break;
|
|
case Type::month:
|
|
dayMonth->set_value(static_cast<unsigned>(date.month()));
|
|
break;
|
|
case Type::day:
|
|
const auto lastDayInMonth =
|
|
static_cast<unsigned>((date::year(date.year()) / date::month(date.month()) / date::last).day());
|
|
const auto day = static_cast<unsigned>(date.day());
|
|
dayMonth->set_range({dayMin, static_cast<std::uint8_t>(lastDayInMonth), step});
|
|
dayMonth->set_value(std::min(day, lastDayInMonth));
|
|
break;
|
|
}
|
|
applySizeRestrictions();
|
|
}
|
|
|
|
void DateSetSpinner::updateDate()
|
|
{
|
|
switch (type) {
|
|
case Type::year:
|
|
date = date::year(year->get_value()) / date::month(date.month()) / date::day(date.day());
|
|
break;
|
|
case Type::month:
|
|
date = date::year(date.year()) / date::month(dayMonth->get_value()) / date::day(date.day());
|
|
break;
|
|
case Type::day:
|
|
date = date::year(date.year()) / date::month(date.month()) / date::day(dayMonth->get_value());
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DateSetSpinner::applySizeRestrictions()
|
|
{
|
|
if (year != nullptr) {
|
|
year->setMinimumWidthToFitText();
|
|
}
|
|
if (dayMonth != nullptr) {
|
|
dayMonth->setMinimumWidthToFitText();
|
|
}
|
|
|
|
setMinimumSize(getWidgetMinimumAreaWidth(), getFontHeight(fontName));
|
|
setMaximumWidth(widgetMaximumArea.w);
|
|
|
|
HBox::informContentChanged();
|
|
}
|
|
|
|
std::uint32_t DateSetSpinner::getWidgetMinimumAreaWidth() const
|
|
{
|
|
return (type == Type::year) ? year->widgetMinimumArea.w : dayMonth->widgetMinimumArea.w;
|
|
}
|
|
|
|
std::uint16_t DateSetSpinner::getFontHeight(const std::string &fontName) const
|
|
{
|
|
const auto font = FontManager::getInstance().getFont(fontName);
|
|
return font->info.line_height;
|
|
}
|
|
|
|
template <typename Spinner>
|
|
void DateSetSpinner::attachDateField(Spinner *&field, typename Spinner::range &&range)
|
|
{
|
|
field = new Spinner(std::move(range), Boundaries::Continuous);
|
|
setFont(field, fontName);
|
|
field->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
field->setEdges(RectangleEdge::None);
|
|
field->setPenFocusWidth(0);
|
|
field->set_value(0);
|
|
addWidget(field);
|
|
}
|
|
|
|
bool DateSetSpinner::onInput(const InputEvent &inputEvent)
|
|
{
|
|
if (auto ret = this->focusItem->onInput(inputEvent)) {
|
|
applySizeRestrictions();
|
|
return ret;
|
|
}
|
|
return false;
|
|
}
|
|
} /* namespace gui */
|