mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-04-19 06:30:46 -04:00
166 lines
5.9 KiB
C++
166 lines
5.9 KiB
C++
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "IntervalBox.hpp"
|
|
|
|
#include "application-meditation/data/Style.hpp"
|
|
#include "Style.hpp"
|
|
#include "TimerProperty.hpp"
|
|
#include "InputEvent.hpp"
|
|
|
|
#include <module-utils/i18n/i18n.hpp>
|
|
#include <cassert>
|
|
|
|
using namespace gui;
|
|
|
|
namespace
|
|
{
|
|
using minutes = std::chrono::minutes;
|
|
const static std::vector<minutes> chimeIntervals{
|
|
minutes{0}, minutes{2}, minutes{5}, minutes{10}, minutes{15}, minutes{30}};
|
|
} // namespace
|
|
|
|
IntervalBox::IntervalBox(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h, TimerProperty *timerSetter)
|
|
: BoxLayout(parent, x, y, w, h), timerSetter(timerSetter)
|
|
{
|
|
assert(timerSetter);
|
|
build();
|
|
}
|
|
|
|
void IntervalBox::build()
|
|
{
|
|
namespace boxStyle = style::meditation::intervalBox;
|
|
|
|
auto topLabel = new Label(this,
|
|
boxStyle::topLabel::X,
|
|
boxStyle::topLabel::Y,
|
|
boxStyle::topLabel::Width,
|
|
boxStyle::topLabel::Height,
|
|
utils::localize.get("app_meditation_interval_chime"));
|
|
topLabel->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));
|
|
topLabel->setFont(style::window::font::verysmall);
|
|
topLabel->setEdges(RectangleEdge::None);
|
|
|
|
bottomLabel = new Label(this,
|
|
boxStyle::bottomLabel::X,
|
|
boxStyle::bottomLabel::Y,
|
|
boxStyle::bottomLabel::Width,
|
|
boxStyle::bottomLabel::Height);
|
|
bottomLabel->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
bottomLabel->setFont(style::window::font::small);
|
|
bottomLabel->setEdges(RectangleEdge::Bottom);
|
|
bottomLabel->setPenWidth(style::window::default_border_rect_no_focus);
|
|
|
|
leftSwitchArrow = new gui::Image(bottomLabel,
|
|
boxStyle::arrow::LeftX,
|
|
boxStyle::arrow::Y,
|
|
boxStyle::arrow::Width,
|
|
boxStyle::arrow::Height,
|
|
"left_label_arrow");
|
|
rightSwitchArrow = new gui::Image(bottomLabel,
|
|
boxStyle::arrow::RightX,
|
|
boxStyle::arrow::Y,
|
|
boxStyle::arrow::Width,
|
|
boxStyle::arrow::Height,
|
|
"right_label_arrow");
|
|
|
|
|
|
updateIntervals(ChimeIntervalList::Direction::Next);
|
|
leftSwitchArrow->setVisible(false);
|
|
rightSwitchArrow->setVisible(false);
|
|
}
|
|
|
|
bool IntervalBox::onFocus(bool state)
|
|
{
|
|
if (state) {
|
|
rescaleIntervals();
|
|
bottomLabel->setPenWidth(style::window::default_border_focus_w);
|
|
bottomLabel->setFont(style::window::font::smallbold);
|
|
}
|
|
else {
|
|
bottomLabel->setPenWidth(style::window::default_border_rect_no_focus);
|
|
bottomLabel->setFont(style::window::font::small);
|
|
}
|
|
auto currentMeditationTime = timerSetter->getTime();
|
|
leftSwitchArrow->setVisible(state &&
|
|
chimeIntervals.hasNext(ChimeIntervalList::Direction::Previous, currentMeditationTime));
|
|
rightSwitchArrow->setVisible(state &&
|
|
chimeIntervals.hasNext(ChimeIntervalList::Direction::Next, currentMeditationTime));
|
|
return true;
|
|
}
|
|
|
|
bool IntervalBox::onInput(const InputEvent &inputEvent)
|
|
{
|
|
if (inputEvent.isShortPress()) {
|
|
if (inputEvent.is(KeyCode::KEY_LEFT)) {
|
|
updateIntervals(ChimeIntervalList::Direction::Previous);
|
|
return true;
|
|
}
|
|
else if (inputEvent.is(KeyCode::KEY_RIGHT)) {
|
|
updateIntervals(ChimeIntervalList::Direction::Next);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void IntervalBox::updateIntervals(ChimeIntervalList::Direction direction)
|
|
{
|
|
auto currentMeditationTime = timerSetter->getTime();
|
|
if (!chimeIntervals.moveToNext(direction, currentMeditationTime)) {
|
|
return;
|
|
}
|
|
intervalValue = chimeIntervals.getCurrent();
|
|
bottomLabel->setText(ChimeIntervalList::toPrintableInterval(intervalValue));
|
|
|
|
leftSwitchArrow->setVisible(chimeIntervals.hasNext(ChimeIntervalList::Direction::Previous, currentMeditationTime));
|
|
rightSwitchArrow->setVisible(chimeIntervals.hasNext(ChimeIntervalList::Direction::Next, currentMeditationTime));
|
|
}
|
|
|
|
void IntervalBox::rescaleIntervals()
|
|
{
|
|
while (intervalValue >= timerSetter->getTime() && intervalValue != minutes{0}) {
|
|
updateIntervals(ChimeIntervalList::Direction::Previous);
|
|
}
|
|
}
|
|
|
|
IntervalBox::ChimeIntervalList::ChimeIntervalList() : intervals(::chimeIntervals), current(intervals.begin())
|
|
{}
|
|
|
|
bool IntervalBox::ChimeIntervalList::moveToNext(Direction direction, std::chrono::minutes meditationTime) noexcept
|
|
{
|
|
if (!hasNext(direction, meditationTime)) {
|
|
return false;
|
|
}
|
|
if (direction == Direction::Next) {
|
|
current++;
|
|
}
|
|
else {
|
|
current--;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool IntervalBox::ChimeIntervalList::hasNext(Direction direction, std::chrono::minutes meditationTime) const noexcept
|
|
{
|
|
if (direction == Direction::Previous) {
|
|
return current != intervals.begin();
|
|
}
|
|
auto result = std::next(current) != intervals.end();
|
|
if (result) {
|
|
result = *std::next(current) < meditationTime;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::string IntervalBox::ChimeIntervalList::toPrintableInterval(std::chrono::minutes value)
|
|
{
|
|
if (value.count() == 0) {
|
|
return utils::localize.get("app_meditation_interval_none");
|
|
}
|
|
const std::string toReplace = "%0";
|
|
std::string temp = utils::localize.get("app_meditation_interval_every_x_minutes");
|
|
temp.replace(temp.find(toReplace), toReplace.size(), std::to_string(static_cast<int>(value.count())));
|
|
return temp;
|
|
}
|