~aleteoryx/muditaos

ref: a261a132a6950a36999d8f5b7614bfb3f4830b06 muditaos/module-apps/application-meditation/widgets/TimerSetter.cpp -rw-r--r-- 4.1 KiB
a261a132 — Piotr Tanski [EGD-4554] Set the limit of a note text to 4'000 characters. (#1123) 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TimerSetter.hpp"
#include <application-meditation/data/Style.hpp>

using namespace gui;

TimerSetter::TimerSetter(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 TimerSetter::build()
{
    const Point boxCenter(getX() + (getWidth() / 2), getY() + (getHeight() / 2));

    namespace timerStyle = style::meditation::timer;
    Circle::ShapeParams params;
    params.setCenterPoint(boxCenter)
        .setRadius(timerStyle::Radius)
        .setBorderColor(timerStyle::BorderColor)
        .setFocusBorderColor(timerStyle::BorderColorOnFocused)
        .setPenWidth(timerStyle::PenWidth)
        .setFocusPenWidth(timerStyle::PenWidth);
    circle = new Circle(this, params);

    namespace timerStyle = style::meditation::timer;
    timeLabel            = new Label(this,
                          timerStyle::setterValueLabel::X,
                          timerStyle::setterValueLabel::Y,
                          timerStyle::setterValueLabel::Width,
                          timerStyle::setterValueLabel::Height);
    timeLabel->setEdges(RectangleEdge::None);
    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())));

    timeUnitLabel = new Label(this,
                              timerStyle::setterUnitLabel::X,
                              timerStyle::setterUnitLabel::Y,
                              timerStyle::setterUnitLabel::Width,
                              timerStyle::setterUnitLabel::Height);
    timeUnitLabel->setFont(style::window::font::verysmall);
    timeUnitLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
    timeUnitLabel->setText("MINUTES");
    timeUnitLabel->setEdges(RectangleEdge::None);
}

bool TimerSetter::onFocus(bool isFocused)
{
    circle->setFocus(isFocused);
    if (isFocused) {
        timeLabel->setEdges(RectangleEdge::Bottom);
    }
    else {
        timeLabel->setEdges(RectangleEdge::None);
    }
    state.onFocus();
    return true;
}

bool TimerSetter::onInput(const InputEvent &inputEvent)
{
    if (inputEvent.isShortPress()) {
        bool handled = false;
        if (0 <= gui::toNumeric(inputEvent.keyCode) && gui::toNumeric(inputEvent.keyCode) <= 9) {
            state.putNumericValue(gui::toNumeric(inputEvent.keyCode));
            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();
        }
        timeLabel->setText(std::to_string(static_cast<int>(state.getTime().count())));
        if (handled) {
            return true;
        }
    }
    return false;
}

std::chrono::seconds TimerSetter::getTime() noexcept
{
    state.checkBounds();
    return state.getTime();
}

void TimerSetter::State::checkBounds() noexcept
{
    timeInMinutes       = std::clamp(timeInMinutes, minimalValue, maximalValue);
    resetValueOnNumeric = true;
}

void TimerSetter::State::putNumericValue(int digit) noexcept
{
    if (resetValueOnNumeric) {
        timeInMinutes       = 0;
        resetValueOnNumeric = false;
    }
    timeInMinutes = 10 * timeInMinutes + digit;
    if (timeInMinutes >= minimalValue) {
        resetValueOnNumeric = true;
    }
}

void TimerSetter::State::increment() noexcept
{
    timeInMinutes       = (timeInMinutes / defaultIncrementValue + 1) * defaultIncrementValue;
    resetValueOnNumeric = true;
    checkBounds();
}

void TimerSetter::State::decrement() noexcept
{
    timeInMinutes       = ((timeInMinutes - 1) / defaultIncrementValue) * defaultIncrementValue;
    resetValueOnNumeric = true;
    checkBounds();
}