Files
MuditaOS/module-apps/application-meditation/widgets/IntervalBox.cpp
jimmorrisson 14918dc4f9 [EGD-4925] Change new filesystem handling implementation in module-gui. (#1193)
Due to vfs deprecation there is need to remove all vfs calls from code. This PR covers module gui. There are some modifications in other modules included which are necessary because of build system issues.
2020-12-16 15:23:11 +01:00

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 <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;
}