mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-04-19 14:40:57 -04:00
Fixed layout in meditation app, so it now renders as it should. Also small fix for MP is included (EGD-7848).
154 lines
4.9 KiB
C++
154 lines
4.9 KiB
C++
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "Style.hpp"
|
|
#include "TimerProperty.hpp"
|
|
|
|
#include <i18n/i18n.hpp>
|
|
#include <Utils.hpp>
|
|
|
|
using namespace gui;
|
|
|
|
TimerProperty::TimerProperty(Item *parent, const uint32_t x, const uint32_t y, const uint32_t w, const uint32_t h)
|
|
: Rect(parent, x, y, w, h)
|
|
{
|
|
build();
|
|
}
|
|
|
|
void TimerProperty::build()
|
|
{
|
|
namespace timerStyle = style::meditation::timer;
|
|
|
|
const Point boxCenter(getX() + (getWidth() / 2), getY() + (getHeight() / 2));
|
|
Circle::ShapeParams params;
|
|
params.setCenterPoint(boxCenter)
|
|
.setRadius(timerStyle::Radius)
|
|
.setBorderColor(timerStyle::BorderColor)
|
|
.setFocusBorderColor(timerStyle::BorderColor)
|
|
.setPenWidth(timerStyle::PenWidth)
|
|
.setFocusPenWidth(timerStyle::FocusPenWidth);
|
|
circle = new Circle(this, params);
|
|
|
|
centerBody = new VBox(this, 0, 0, 2 * timerStyle::Radius, 2 * timerStyle::Radius);
|
|
centerBody->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
|
|
centerBody->setMinimumSize(2 * timerStyle::Radius, 2 * timerStyle::Radius);
|
|
centerBody->setEdges(RectangleEdge::None);
|
|
centerBody->activeItem = false;
|
|
|
|
timeLabel = new Label(centerBody);
|
|
timeLabel->setMargins(gui::Margins(0, timerStyle::setterValueLabel::TopMargin, 0, 0));
|
|
timeLabel->setEdges(RectangleEdge::None);
|
|
timeLabel->setMinimumSize(timerStyle::setterValueLabel::Width, timerStyle::setterValueLabel::Height);
|
|
timeLabel->setFont(style::window::font::supersizemelight);
|
|
timeLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
|
|
timeLabel->setPenWidth(timerStyle::PenWidth);
|
|
timeLabel->setText(std::to_string(static_cast<int>(state.getTime().count())));
|
|
|
|
divRect = new Rect(centerBody, 0, 0, timerStyle::setterValueLabel::BottomLineWidth, 1);
|
|
divRect->setPenWidth(timerStyle::setterValueLabel::BottomLinePen);
|
|
|
|
timeUnitLabel = new Label(centerBody);
|
|
timeUnitLabel->setMinimumSize(timerStyle::setterUnitLabel::Width, timerStyle::setterUnitLabel::Height);
|
|
timeUnitLabel->setMargins(gui::Margins(0, timerStyle::setterUnitLabel::TopMargin, 0, 0));
|
|
timeUnitLabel->setFont(style::window::font::verysmall);
|
|
timeUnitLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
|
|
timeUnitLabel->setEdges(RectangleEdge::None);
|
|
timeUnitLabel->setText(utils::translate("app_meditation_minutes"));
|
|
|
|
centerBody->resizeItems();
|
|
}
|
|
|
|
bool TimerProperty::onFocus(bool isFocused)
|
|
{
|
|
circle->setFocus(isFocused);
|
|
if (isFocused) {
|
|
divRect->setEdges(RectangleEdge::Top);
|
|
}
|
|
else {
|
|
divRect->setEdges(RectangleEdge::None);
|
|
}
|
|
state.onFocus();
|
|
return true;
|
|
}
|
|
|
|
bool TimerProperty::onInput(const InputEvent &inputEvent)
|
|
{
|
|
bool handled = false;
|
|
if (inputEvent.isShortRelease()) {
|
|
if (inputEvent.isDigit()) {
|
|
state.putNumericValue(inputEvent.numericValue());
|
|
handled = true;
|
|
}
|
|
else if (inputEvent.is(KeyCode::KEY_LEFT)) {
|
|
state.decrement();
|
|
handled = true;
|
|
}
|
|
else if (inputEvent.is(KeyCode::KEY_RIGHT)) {
|
|
state.increment();
|
|
handled = true;
|
|
}
|
|
else {
|
|
state.onFocus();
|
|
}
|
|
setMeditationTime();
|
|
}
|
|
return handled;
|
|
}
|
|
|
|
void TimerProperty::setMeditationTime()
|
|
{
|
|
const auto meditationTime = static_cast<int>(state.getTime().count());
|
|
timeLabel->setText(utils::to_string(meditationTime));
|
|
if (meditationTime == 1) {
|
|
timeUnitLabel->setText(utils::translate("app_meditation_minute"));
|
|
}
|
|
else {
|
|
timeUnitLabel->setText(utils::translate("app_meditation_minutes"));
|
|
}
|
|
}
|
|
|
|
std::chrono::minutes TimerProperty::getTime() noexcept
|
|
{
|
|
state.checkBounds();
|
|
return state.getTime();
|
|
}
|
|
|
|
void TimerProperty::State::checkBounds() noexcept
|
|
{
|
|
timeInMinutes = std::clamp(timeInMinutes, minimalValue, maximalValue);
|
|
resetValueOnNumeric = true;
|
|
}
|
|
|
|
void TimerProperty::State::putNumericValue(int digit) noexcept
|
|
{
|
|
if (resetValueOnNumeric) {
|
|
timeInMinutes = 0;
|
|
resetValueOnNumeric = false;
|
|
}
|
|
timeInMinutes = 10 * timeInMinutes + digit;
|
|
if (timeInMinutes >= 10 * (counterMaxDigits - 1)) {
|
|
resetValueOnNumeric = true;
|
|
}
|
|
}
|
|
|
|
void TimerProperty::State::increment() noexcept
|
|
{
|
|
auto it = std::upper_bound(std::begin(timeArr), std::end(timeArr), timeInMinutes);
|
|
if (it == std::end(timeArr)) {
|
|
it--;
|
|
}
|
|
timeInMinutes = *it;
|
|
resetValueOnNumeric = true;
|
|
}
|
|
|
|
void TimerProperty::State::decrement() noexcept
|
|
{
|
|
auto it =
|
|
std::upper_bound(std::rbegin(timeArr), std::rend(timeArr), timeInMinutes, [](int a, int b) { return a > b; });
|
|
if (it == std::rend(timeArr)) {
|
|
it--;
|
|
}
|
|
timeInMinutes = *it;
|
|
resetValueOnNumeric = true;
|
|
}
|