mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-07-19 20:44:44 -04:00
[EGD-7792] Meditation timer interval widget replacement
Meditation timer interval widget replacement.
This commit is contained in:
committed by
Przemysław Brudny
parent
53a51e866d
commit
810a8dc1c3
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#include "NewEditAlarmModel.hpp"
|
||||
@@ -30,7 +30,7 @@ namespace app::alarmClock
|
||||
|
||||
unsigned int NewEditAlarmModel::getMinimalItemSpaceRequired() const
|
||||
{
|
||||
return style::alarmClock::window::item::options::h;
|
||||
return style::text_spinner_label::h;
|
||||
}
|
||||
|
||||
void NewEditAlarmModel::requestRecords(uint32_t offset, uint32_t limit)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#pragma once
|
||||
@@ -40,14 +40,6 @@ namespace style::alarmClock
|
||||
inline constexpr auto marginBot = 20;
|
||||
inline constexpr auto separator = 30;
|
||||
} // namespace time
|
||||
|
||||
namespace options
|
||||
{
|
||||
inline constexpr auto spinner_h = 40;
|
||||
inline constexpr auto label_h = 27;
|
||||
inline constexpr auto h = spinner_h + label_h;
|
||||
} // namespace options
|
||||
|
||||
} // namespace item
|
||||
|
||||
} // namespace window
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#include "AlarmOptionsItem.hpp"
|
||||
@@ -11,27 +11,12 @@ namespace gui
|
||||
{
|
||||
AlarmOptionsItem::AlarmOptionsItem(const std::string &description, const std::vector<UTF8> &options)
|
||||
{
|
||||
setMinimumSize(style::listview::item_width_with_without_scroll, style::alarmClock::window::item::options::h);
|
||||
setMinimumSize(style::listview::item_width_with_without_scroll, style::text_spinner_label::h);
|
||||
|
||||
setEdges(RectangleEdge::None);
|
||||
setMargins(gui::Margins(style::widgets::leftMargin, style::margins::large, 0, 0));
|
||||
|
||||
vBox = new gui::VBox(this, 0, 0, 0, 0);
|
||||
vBox->setEdges(gui::RectangleEdge::None);
|
||||
vBox->activeItem = false;
|
||||
|
||||
descriptionLabel = new gui::Label(vBox, 0, 0, 0, 0);
|
||||
descriptionLabel->setMinimumSize(style::window::default_body_width,
|
||||
style::alarmClock::window::item::options::label_h);
|
||||
descriptionLabel->setEdges(gui::RectangleEdge::None);
|
||||
descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
|
||||
descriptionLabel->setFont(style::window::font::small);
|
||||
descriptionLabel->activeItem = false;
|
||||
descriptionLabel->setText(description);
|
||||
|
||||
optionSpinner = new gui::TextSpinnerBox(vBox, options, Boundaries::Continuous);
|
||||
optionSpinner->setMinimumSize(style::window::default_body_width,
|
||||
style::alarmClock::window::item::options::spinner_h);
|
||||
optionSpinner = new gui::TextSpinnerBoxWithLabel(this, description, options, Boundaries::Continuous);
|
||||
|
||||
focusChangedCallback = [&](gui::Item &item) {
|
||||
setFocusItem(focus ? optionSpinner : nullptr);
|
||||
@@ -41,7 +26,7 @@ namespace gui
|
||||
inputCallback = [&](Item &item, const InputEvent &event) { return optionSpinner->onInput(event); };
|
||||
|
||||
dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
|
||||
vBox->setArea({0, 0, newDim.w, newDim.h});
|
||||
optionSpinner->setArea({0, 0, newDim.w, newDim.h});
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#pragma once
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <Label.hpp>
|
||||
#include <BoxLayout.hpp>
|
||||
#include <widgets/TextSpinnerBox.hpp>
|
||||
#include <widgets/TextSpinnerBoxWithLabel.hpp>
|
||||
|
||||
namespace gui
|
||||
{
|
||||
@@ -17,11 +17,7 @@ namespace gui
|
||||
explicit AlarmOptionsItem(const std::string &description, const std::vector<UTF8> &options = {});
|
||||
|
||||
protected:
|
||||
gui::TextSpinnerBox *optionSpinner = nullptr;
|
||||
|
||||
private:
|
||||
gui::VBox *vBox = nullptr;
|
||||
gui::Label *descriptionLabel = nullptr;
|
||||
gui::TextSpinnerBoxWithLabel *optionSpinner = nullptr;
|
||||
};
|
||||
|
||||
} /* namespace gui */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#pragma once
|
||||
@@ -43,7 +43,7 @@ namespace callAppStyle
|
||||
inline constexpr auto x = 60U;
|
||||
inline constexpr auto y = 254U;
|
||||
inline constexpr auto w = style::window_width - 2 * x;
|
||||
inline constexpr auto h = 20U;
|
||||
inline constexpr auto h = 40U;
|
||||
} // namespace numberDescriptionLabel
|
||||
|
||||
namespace icon
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace gui
|
||||
numberDescriptionLabel::h);
|
||||
numberDescriptionLabel->setFont(style::window::font::mediumlight);
|
||||
numberDescriptionLabel->setAlignment(
|
||||
gui::Alignment{gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center});
|
||||
gui::Alignment{gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top});
|
||||
numberDescriptionLabel->setEdges(RectangleEdge::None);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,33 +50,6 @@ namespace style::meditation
|
||||
constexpr auto X = style::window::default_left_margin;
|
||||
constexpr auto Y = style::meditation::timer::Y + 2 * style::meditation::timer::Radius + VerticalWidgetGap;
|
||||
constexpr auto Width = style::window::default_body_width;
|
||||
constexpr auto Height = 60;
|
||||
|
||||
namespace topLabel
|
||||
{
|
||||
constexpr auto X = 0;
|
||||
constexpr auto Y = 0;
|
||||
constexpr auto Width = intervalBox::Width;
|
||||
constexpr auto Height = intervalBox::Height / 2;
|
||||
} // namespace topLabel
|
||||
|
||||
namespace bottomLabel
|
||||
{
|
||||
constexpr auto X = 0;
|
||||
constexpr auto Y = topLabel::Y + topLabel::Height;
|
||||
constexpr auto Width = intervalBox::Width;
|
||||
constexpr auto Height = intervalBox::Height / 2;
|
||||
} // namespace bottomLabel
|
||||
|
||||
namespace arrow
|
||||
{
|
||||
constexpr auto Y = 10;
|
||||
constexpr auto Width = 15;
|
||||
constexpr auto Height = intervalBox::Height / 2;
|
||||
constexpr auto LeftX = 0;
|
||||
constexpr auto RightX = intervalBox::Width - arrow::Width;
|
||||
} // namespace arrow
|
||||
|
||||
} // namespace intervalBox
|
||||
|
||||
namespace itemList
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#include "IntervalBox.hpp"
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
} // 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)
|
||||
: HBox(parent, x, y, w, h), timerSetter(timerSetter)
|
||||
{
|
||||
assert(timerSetter);
|
||||
build();
|
||||
@@ -28,136 +28,74 @@ IntervalBox::IntervalBox(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint3
|
||||
|
||||
void IntervalBox::build()
|
||||
{
|
||||
namespace boxStyle = style::meditation::intervalBox;
|
||||
chimeSpinner = new gui::TextSpinnerBoxWithLabel(
|
||||
this, utils::translate("app_meditation_interval_chime"), {}, Boundaries::Continuous);
|
||||
chimeSpinner->setMinimumSize(widgetArea.w, widgetArea.h);
|
||||
updateIntervals();
|
||||
|
||||
auto topLabel = new Label(this,
|
||||
boxStyle::topLabel::X,
|
||||
boxStyle::topLabel::Y,
|
||||
boxStyle::topLabel::Width,
|
||||
boxStyle::topLabel::Height,
|
||||
utils::translate("app_meditation_interval_chime"));
|
||||
topLabel->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));
|
||||
topLabel->setFont(style::window::font::small);
|
||||
topLabel->setEdges(RectangleEdge::None);
|
||||
resizeItems();
|
||||
|
||||
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,
|
||||
"arrow_left_20px_W_M");
|
||||
rightSwitchArrow = new gui::Image(bottomLabel,
|
||||
boxStyle::arrow::RightX,
|
||||
boxStyle::arrow::Y,
|
||||
boxStyle::arrow::Width,
|
||||
boxStyle::arrow::Height,
|
||||
"arrow_right_20px_W_M");
|
||||
|
||||
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.isShortRelease()) {
|
||||
if (inputEvent.is(KeyCode::KEY_LEFT)) {
|
||||
updateIntervals(ChimeIntervalList::Direction::Previous);
|
||||
return true;
|
||||
focusChangedCallback = [&](gui::Item &item) {
|
||||
if (focus) {
|
||||
updateIntervals();
|
||||
}
|
||||
else if (inputEvent.is(KeyCode::KEY_RIGHT)) {
|
||||
updateIntervals(ChimeIntervalList::Direction::Next);
|
||||
return true;
|
||||
setFocusItem(focus ? chimeSpinner : nullptr);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
void IntervalBox::updateIntervals()
|
||||
{
|
||||
auto setTime = timerSetter->getTime();
|
||||
|
||||
std::vector<UTF8> chimeOptions;
|
||||
for (auto chime : chimeIntervals) {
|
||||
if (chime < setTime) {
|
||||
chimeOptions.push_back(intervalToString(chime));
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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));
|
||||
auto currentInterval = chimeSpinner->getCurrentValue();
|
||||
chimeSpinner->setData(chimeOptions);
|
||||
|
||||
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);
|
||||
if (stringToInterval(currentInterval) < setTime) {
|
||||
chimeSpinner->setCurrentValue(currentInterval);
|
||||
}
|
||||
}
|
||||
|
||||
IntervalBox::ChimeIntervalList::ChimeIntervalList() : intervals(::chimeIntervals), current(intervals.begin())
|
||||
{}
|
||||
|
||||
bool IntervalBox::ChimeIntervalList::moveToNext(Direction direction, std::chrono::minutes meditationTime) noexcept
|
||||
std::chrono::seconds IntervalBox::getIntervalValue() noexcept
|
||||
{
|
||||
if (!hasNext(direction, meditationTime)) {
|
||||
return false;
|
||||
}
|
||||
if (direction == Direction::Next) {
|
||||
current++;
|
||||
if (stringToInterval(chimeSpinner->getCurrentValue()) < timerSetter->getTime()) {
|
||||
return std::chrono::seconds{stringToInterval(chimeSpinner->getCurrentValue())};
|
||||
}
|
||||
else {
|
||||
current--;
|
||||
return std::chrono::seconds{0};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntervalBox::ChimeIntervalList::hasNext(Direction direction, std::chrono::minutes meditationTime) const noexcept
|
||||
std::string IntervalBox::intervalToString(std::chrono::minutes time)
|
||||
{
|
||||
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) {
|
||||
if (time.count() == 0) {
|
||||
return utils::translate("app_meditation_interval_none");
|
||||
}
|
||||
const std::string toReplace = "%0";
|
||||
std::string temp = utils::translate("app_meditation_interval_every_x_minutes");
|
||||
temp.replace(temp.find(toReplace), toReplace.size(), std::to_string(static_cast<int>(value.count())));
|
||||
return temp;
|
||||
std::string description = utils::translate("app_meditation_interval_every_x_minutes");
|
||||
description.replace(description.find(toReplace), toReplace.size(), std::to_string(static_cast<int>(time.count())));
|
||||
return description;
|
||||
}
|
||||
|
||||
std::chrono::minutes IntervalBox::stringToInterval(const std::string &description)
|
||||
{
|
||||
if (description == utils::translate("app_meditation_interval_none")) {
|
||||
return std::chrono::minutes(0);
|
||||
}
|
||||
|
||||
auto number = description;
|
||||
number.erase(std::remove_if(number.begin(), number.end(), [](char c) { return !isdigit(c, std::locale()); }),
|
||||
number.end());
|
||||
|
||||
return std::chrono::minutes(std::atoi(number.c_str()));
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <gui/widgets/BoxLayout.hpp>
|
||||
#include <gui/widgets/Image.hpp>
|
||||
#include <gui/widgets/text/Label.hpp>
|
||||
#include <apps-common/widgets/TextSpinnerBoxWithLabel.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <chrono>
|
||||
@@ -14,52 +15,21 @@ namespace gui
|
||||
{
|
||||
class TimerProperty;
|
||||
|
||||
class IntervalBox : public BoxLayout
|
||||
class IntervalBox : public HBox
|
||||
{
|
||||
class ChimeIntervalList
|
||||
{
|
||||
std::vector<std::chrono::minutes> intervals;
|
||||
std::vector<std::chrono::minutes>::const_iterator current;
|
||||
|
||||
public:
|
||||
enum class Direction
|
||||
{
|
||||
Next,
|
||||
Previous
|
||||
};
|
||||
|
||||
ChimeIntervalList();
|
||||
|
||||
[[nodiscard]] std::chrono::minutes getCurrent() const noexcept
|
||||
{
|
||||
return *current;
|
||||
}
|
||||
|
||||
bool moveToNext(Direction dir, std::chrono::minutes meditationTime) noexcept;
|
||||
[[nodiscard]] bool hasNext(Direction dir, std::chrono::minutes meditationTime) const noexcept;
|
||||
|
||||
[[nodiscard]] static std::string toPrintableInterval(std::chrono::minutes time);
|
||||
} chimeIntervals;
|
||||
|
||||
TimerProperty *timerSetter = nullptr;
|
||||
Label *bottomLabel = nullptr;
|
||||
Image *leftSwitchArrow = nullptr;
|
||||
Image *rightSwitchArrow = nullptr;
|
||||
|
||||
std::chrono::minutes intervalValue{0};
|
||||
TimerProperty *timerSetter = nullptr;
|
||||
TextSpinnerBoxWithLabel *chimeSpinner = nullptr;
|
||||
|
||||
void build();
|
||||
void updateIntervals(ChimeIntervalList::Direction dir);
|
||||
void updateIntervals();
|
||||
[[nodiscard]] std::string intervalToString(std::chrono::minutes time);
|
||||
[[nodiscard]] std::chrono::minutes stringToInterval(const std::string &description);
|
||||
|
||||
void rescaleIntervals();
|
||||
|
||||
public:
|
||||
IntervalBox(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h, TimerProperty *timerSetter);
|
||||
|
||||
bool onFocus(bool isFocused) final;
|
||||
bool onInput(const InputEvent &inputEvent) final;
|
||||
[[nodiscard]] std::chrono::seconds getIntervalValue() const noexcept
|
||||
{
|
||||
return std::chrono::seconds{intervalValue};
|
||||
}
|
||||
[[nodiscard]] std::chrono::seconds getIntervalValue() noexcept;
|
||||
};
|
||||
} // namespace gui
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#include "ApplicationMeditation.hpp"
|
||||
@@ -51,7 +51,7 @@ namespace gui
|
||||
style::meditation::intervalBox::X,
|
||||
style::meditation::intervalBox::Y,
|
||||
style::meditation::intervalBox::Width,
|
||||
style::meditation::intervalBox::Height,
|
||||
style::text_spinner_label::h,
|
||||
timeSetter);
|
||||
intervalBox->setEdges(RectangleEdge::None);
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ target_sources(apps-common
|
||||
widgets/ModesBox.cpp
|
||||
widgets/SpinBox.cpp
|
||||
widgets/TextSpinnerBox.cpp
|
||||
widgets/TextSpinnerBoxWithLabel.cpp
|
||||
widgets/TextWithIconsWidget.cpp
|
||||
widgets/TimeSetSpinner.cpp
|
||||
widgets/AlarmSetSpinner.cpp
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#include "TextSpinnerBox.hpp"
|
||||
@@ -27,12 +27,18 @@ namespace gui
|
||||
inputCallback = [&](Item &item, const InputEvent &event) { return spinner->onInput(event); };
|
||||
|
||||
focusChangedCallback = [&](gui::Item &item) {
|
||||
if (focus) {
|
||||
if (focus && !spinner->isSingle()) {
|
||||
leftArrow->setVisible(true);
|
||||
rightArrow->setVisible(true);
|
||||
spinner->setFont(style::window::font::mediumbold);
|
||||
setPenWidth(style::window::default_border_focus_w);
|
||||
}
|
||||
else if (focus && spinner->isSingle()) {
|
||||
leftArrow->setVisible(false);
|
||||
rightArrow->setVisible(false);
|
||||
spinner->setFont(style::window::font::mediumbold);
|
||||
setPenWidth(style::window::default_border_focus_w);
|
||||
}
|
||||
else {
|
||||
leftArrow->setVisible(false);
|
||||
rightArrow->setVisible(false);
|
||||
|
||||
46
module-apps/apps-common/widgets/TextSpinnerBoxWithLabel.cpp
Normal file
46
module-apps/apps-common/widgets/TextSpinnerBoxWithLabel.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#include "TextSpinnerBoxWithLabel.hpp"
|
||||
|
||||
namespace gui
|
||||
{
|
||||
TextSpinnerBoxWithLabel::TextSpinnerBoxWithLabel(Item *parent,
|
||||
const std::string &description,
|
||||
const std::vector<UTF8> &data,
|
||||
Boundaries boundaries)
|
||||
: VBox(parent)
|
||||
{
|
||||
setEdges(RectangleEdge::None);
|
||||
descriptionLabel = new gui::Label(this, 0, 0, 0, 0);
|
||||
descriptionLabel->setMinimumSize(style::window::default_body_width, style::text_spinner_label::label_h);
|
||||
descriptionLabel->setEdges(gui::RectangleEdge::None);
|
||||
descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
|
||||
descriptionLabel->setFont(style::window::font::small);
|
||||
descriptionLabel->activeItem = false;
|
||||
descriptionLabel->setText(description);
|
||||
|
||||
optionSpinner = new gui::TextSpinnerBox(this, data, boundaries);
|
||||
optionSpinner->setMinimumSize(style::window::default_body_width, style::text_spinner_label::spinner_h);
|
||||
|
||||
focusChangedCallback = [&](gui::Item &item) {
|
||||
setFocusItem(focus ? optionSpinner : nullptr);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
void TextSpinnerBoxWithLabel::setData(const std::vector<UTF8> &data)
|
||||
{
|
||||
optionSpinner->setData(data);
|
||||
}
|
||||
|
||||
UTF8 TextSpinnerBoxWithLabel::getCurrentValue() const noexcept
|
||||
{
|
||||
return optionSpinner->getCurrentValue();
|
||||
}
|
||||
|
||||
void TextSpinnerBoxWithLabel::setCurrentValue(UTF8 val)
|
||||
{
|
||||
optionSpinner->setCurrentValue(val);
|
||||
}
|
||||
} // namespace gui
|
||||
37
module-apps/apps-common/widgets/TextSpinnerBoxWithLabel.hpp
Normal file
37
module-apps/apps-common/widgets/TextSpinnerBoxWithLabel.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Label.hpp>
|
||||
#include <BoxLayout.hpp>
|
||||
#include <widgets/TextSpinnerBox.hpp>
|
||||
|
||||
namespace style::text_spinner_label
|
||||
{
|
||||
inline constexpr auto spinner_h = 40;
|
||||
inline constexpr auto label_h = 27;
|
||||
inline constexpr auto h = spinner_h + label_h;
|
||||
} // namespace style::text_spinner_label
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class TextSpinnerBoxWithLabel : public VBox
|
||||
{
|
||||
public:
|
||||
TextSpinnerBoxWithLabel(Item *parent,
|
||||
const std::string &description,
|
||||
const std::vector<UTF8> &data,
|
||||
Boundaries boundaries);
|
||||
|
||||
void setData(const std::vector<UTF8> &data);
|
||||
[[nodiscard]] UTF8 getCurrentValue() const noexcept;
|
||||
void setCurrentValue(UTF8 val);
|
||||
|
||||
protected:
|
||||
gui::TextSpinnerBox *optionSpinner = nullptr;
|
||||
|
||||
private:
|
||||
gui::Label *descriptionLabel = nullptr;
|
||||
};
|
||||
} // namespace gui
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#pragma once
|
||||
@@ -27,6 +27,7 @@ namespace gui
|
||||
void setFocusEdges(RectangleEdge edges);
|
||||
bool onInput(const InputEvent &inputEvent) override;
|
||||
bool onFocus(bool state) override;
|
||||
[[nodiscard]] bool isSingle() const;
|
||||
[[nodiscard]] bool isAtMin() const;
|
||||
[[nodiscard]] bool isAtMax() const;
|
||||
|
||||
@@ -144,6 +145,10 @@ namespace gui
|
||||
onValueChanged(getCurrentValue());
|
||||
}
|
||||
}
|
||||
template <typename Policy> bool GenericSpinner<Policy>::isSingle() const
|
||||
{
|
||||
return policy.isSingle();
|
||||
}
|
||||
template <typename Policy> bool GenericSpinner<Policy>::isAtMin() const
|
||||
{
|
||||
return policy.isAtMin();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
||||
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
||||
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
||||
|
||||
#pragma once
|
||||
@@ -85,6 +85,10 @@ namespace gui
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSingle() const
|
||||
{
|
||||
return range.size() == 1;
|
||||
}
|
||||
[[nodiscard]] bool isAtMin() const
|
||||
{
|
||||
return pos == 0;
|
||||
@@ -291,7 +295,10 @@ namespace gui
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSingle() const
|
||||
{
|
||||
return range.size() == 1;
|
||||
}
|
||||
[[nodiscard]] bool isAtMin() const
|
||||
{
|
||||
return pos == 0;
|
||||
|
||||
Reference in New Issue
Block a user