// 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 "InputEvent.hpp" #include #include using namespace gui; namespace { using minutes = std::chrono::minutes; const static std::vector chimeIntervals{ minutes{0}, minutes{2}, minutes{5}, minutes{10}, minutes{15}, minutes{30}}; } // namespace IntervalBox::IntervalBox(Item *parent, const uint32_t x, const uint32_t y, const uint32_t w, const uint32_t h) : BoxLayout(parent, x, y, w, h) { build(); } void IntervalBox::build() { namespace boxStyle = style::meditation::intervalBox; Label *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); 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"); leftSwitchArrow->setVisible(false); rightSwitchArrow->setVisible(false); updateIntervals(ChimeIntervalList::Direction::Next); } bool IntervalBox::onFocus(bool state) { if (state) { bottomLabel->setFont(style::window::font::smallbold); } else { bottomLabel->setFont(style::window::font::small); } leftSwitchArrow->setVisible(state && showLeftArrowOnFocus); rightSwitchArrow->setVisible(state && showRightArrowOnFocus); 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) { if (!chimeIntervals.moveToNext(direction)) { return; } intervalValue = chimeIntervals.getCurrent(); bottomLabel->setText(ChimeIntervalList::toPrintableInterval(intervalValue)); showLeftArrowOnFocus = chimeIntervals.hasNext(ChimeIntervalList::Direction::Previous); showRightArrowOnFocus = chimeIntervals.hasNext(ChimeIntervalList::Direction::Next); leftSwitchArrow->setVisible(showLeftArrowOnFocus); rightSwitchArrow->setVisible(showRightArrowOnFocus); } IntervalBox::ChimeIntervalList::ChimeIntervalList() : intervals(::chimeIntervals), current(intervals.begin()) {} bool IntervalBox::ChimeIntervalList::moveToNext(Direction direction) noexcept { if (!hasNext(direction)) { return false; } if (direction == Direction::Next) { current++; } else { current--; } return true; } bool IntervalBox::ChimeIntervalList::hasNext(Direction direction) const noexcept { if (direction == Direction::Next) { return std::next(current) != intervals.end(); } return current != intervals.begin(); } 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(value.count()))); return temp; }