M image/assets/lang/Deutsch.json => image/assets/lang/Deutsch.json +1 -2
@@ 678,10 678,9 @@
"app_bell_settings_factory_reset": "Zurücksetzen",
"app_bell_settings_display_factory_reset_confirmation": "Zurücksetzen?",
"app_bell_meditation_timer": "Meditation",
- "app_bell_meditation_interval_chime": "Intervallschall",
+ "app_bell_meditation_chime_interval": "Intervallschall",
"app_bell_meditation_progress": "Meditation",
"app_bell_meditation_interval_none": "kein",
- "app_bell_meditation_interval_every_x_minutes": "jede %0",
"app_bell_meditation_put_down_and_wait": "<text>Legen Sie Mudita Harmony<br>ab und warten Sie auf den Gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Danke für<br>die Sitzung</text>"
}
M image/assets/lang/English.json => image/assets/lang/English.json +11 -2
@@ 83,6 83,10 @@
"common_minutes_lower": "minutes",
"common_minutes_lower_genitive": "minutes",
"common_minute_short": "min",
+ "common_second_lower": "second",
+ "common_seconds_lower": "seconds",
+ "common_seconds_lower_genitive": "seconds",
+ "common_second_short": "sec",
"common_paused": "Paused",
"common_text_copy": "Copy text",
"common_text_paste": "Paste text",
@@ 610,10 614,15 @@
"app_bellmain_settings": "Settings",
"app_bellmain_main_window_title": "Mudita Harmony",
"app_bell_meditation_timer": "Meditation",
- "app_bell_meditation_interval_chime": "Interval chime",
+ "app_bell_meditation_settings": "Settings",
+ "app_bell_meditation_start": "Meditate now",
+ "app_bell_meditation_statistics": "Statistics",
+ "app_bell_meditation_chime_volume": "Chime volume",
+ "app_bell_meditation_chime_interval": "Chime interval",
+ "app_bell_meditation_chime_interval_bottom": "of the meditation",
+ "app_bell_meditation_start_delay": "Start delay",
"app_bell_meditation_progress": "Meditation timer",
"app_bell_meditation_interval_none": "None",
- "app_bell_meditation_interval_every_x_minutes": "every %0",
"app_bell_meditation_put_down_and_wait": "<text>Put down Mudita Harmony<br>and wait for the gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Thank you for<br>the session</text>",
"app_bell_onboarding_welcome_message": "<text>Mudita Harmony<br/>is switched OFF</text>",
M image/assets/lang/Espanol.json => image/assets/lang/Espanol.json +1 -2
@@ 678,10 678,9 @@
"app_bell_settings_factory_reset": "Restablecer",
"app_bell_settings_display_factory_reset_confirmation": "<text>¿Restablecer la configuración?</text>",
"app_bell_meditation_timer": "Meditación",
- "app_bell_meditation_interval_chime": "Intervalo",
+ "app_bell_meditation_chime_interval": "Intervalo",
"app_bell_meditation_progress": "Meditación",
"app_bell_meditation_interval_none": "Ninguno",
- "app_bell_meditation_interval_every_x_minutes": "cada %0",
"app_bell_meditation_put_down_and_wait": "<text>Posicione Mudita Harmony<br>y espere el gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Gracias<br>por la sesión</text>"
}
M image/assets/lang/Francais.json => image/assets/lang/Francais.json +1 -2
@@ 648,10 648,9 @@
"app_bell_settings_factory_reset": "Réinitialisation",
"app_bell_settings_display_factory_reset_confirmation": "<text>Rétablir<br></br>la configuration ?</text>",
"app_bell_meditation_timer": "Méditation",
- "app_bell_meditation_interval_chime": "gong intervalle",
+ "app_bell_meditation_chime_interval": "gong intervalle",
"app_bell_meditation_progress": "Méditation",
"app_bell_meditation_interval_none": "Aucune",
- "app_bell_meditation_interval_every_x_minutes": "toutes les %0",
"app_bell_meditation_put_down_and_wait": "<text>Posez Mudita Harmony<br>et attendez le gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Merci<br>pour cette session</text>"
}
M image/assets/lang/Polski.json => image/assets/lang/Polski.json +7 -3
@@ 80,6 80,10 @@
"common_minutes_lower": "minuty",
"common_minutes_lower_genitive": "minut",
"common_minute_short": "min",
+ "common_second_lower": "sekunda",
+ "common_seconds_lower": "sekundy",
+ "common_seconds_lower_genitive": "sekund",
+ "common_second_short": "sec",
"common_paused": "Pauza",
"common_text_copy": "Kopiuj tekst",
"common_text_paste": "Wklej tekst",
@@ 691,10 695,10 @@
"app_bell_settings_about_info_title": "Instrukcja i informacje dot. certyfikacji",
"app_bell_settings_about_info_text": "www.mudita.com",
"app_bell_meditation_timer": "Medytacja",
- "app_bell_meditation_interval_chime": "Dzwonek interwału",
+ "app_bell_meditation_chime_interval": "Dzwonek interwału",
"app_bell_meditation_progress": "Medytacja",
"app_bell_meditation_interval_none": "Brak",
- "app_bell_meditation_interval_every_x_minutes": "co %0",
"app_bell_meditation_put_down_and_wait": "<text>Odłóż Mudita Harmony<br>i czekaj na gong</text>",
- "app_bell_meditation_thank_you_for_session": "<text>Dziękujemy<br>za sesję</text>"
+ "app_bell_meditation_thank_you_for_session": "<text>Dziękujemy<br>za sesję</text>",
+ "app_bell_meditation_statistics": "Statystyki"
}
M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +0 -2
@@ 79,9 79,7 @@ target_sources(apps-common
models/SongsRepository.hpp
models/SongsModelInterface.hpp
- widgets/spinners/GenericSpinner.hpp
widgets/spinners/ItemSpinner.hpp
- widgets/spinners/SpinnerPolicies.hpp
widgets/spinners/Spinners.hpp
)
M module-apps/apps-common/widgets/TextSpinnerBox.cpp => module-apps/apps-common/widgets/TextSpinnerBox.cpp +7 -7
@@ 5,7 5,7 @@
namespace gui
{
- TextSpinnerBox::TextSpinnerBox(Item *parent, const std::vector<UTF8> &data, Boundaries boundaries) : HBox(parent)
+ TextSpinnerBox::TextSpinnerBox(Item *parent, std::vector<UTF8> data, Boundaries boundaries) : HBox(parent)
{
setEdges(RectangleEdge::Bottom);
@@ 13,7 13,7 @@ namespace gui
leftArrow->setMinimumSizeToFitImage();
leftArrow->setVisible(false);
- spinner = new UTF8Spinner(data, Boundaries::Continuous, Orientation::Horizontal);
+ spinner = new StringSpinner(std::move(data), boundaries, Orientation::Horizontal);
spinner->setFont(style::window::font::medium);
spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
spinner->setEdges(RectangleEdge::All);
@@ 27,13 27,13 @@ namespace gui
inputCallback = [&](Item &item, const InputEvent &event) { return spinner->onInput(event); };
focusChangedCallback = [&](gui::Item &item) {
- if (focus && !spinner->isSingle()) {
+ if (focus && spinner->size() != 1) {
leftArrow->setVisible(true);
rightArrow->setVisible(true);
spinner->setFont(style::window::font::mediumbold);
setPenWidth(style::window::default_border_focus_w);
}
- else if (focus && spinner->isSingle()) {
+ else if (focus && spinner->size() == 1) {
leftArrow->setVisible(false);
rightArrow->setVisible(false);
spinner->setFont(style::window::font::mediumbold);
@@ 58,16 58,16 @@ namespace gui
void TextSpinnerBox::setData(const std::vector<UTF8> &data)
{
- spinner->setRange(data);
+ spinner->set_range(data);
}
UTF8 TextSpinnerBox::getCurrentValue() const noexcept
{
- return spinner->getCurrentValue();
+ return spinner->value();
}
void TextSpinnerBox::setCurrentValue(UTF8 val)
{
- spinner->setCurrentValue(val);
+ spinner->set_value(val);
}
} // namespace gui
M module-apps/apps-common/widgets/TextSpinnerBox.hpp => module-apps/apps-common/widgets/TextSpinnerBox.hpp +4 -4
@@ 14,14 14,14 @@ namespace gui
class TextSpinnerBox : public HBox
{
public:
- TextSpinnerBox(Item *parent, const std::vector<UTF8> &data, Boundaries boundaries);
+ TextSpinnerBox(Item *parent, std::vector<UTF8> data, Boundaries boundaries);
void setData(const std::vector<UTF8> &data);
[[nodiscard]] UTF8 getCurrentValue() const noexcept;
void setCurrentValue(UTF8 val);
private:
- UTF8Spinner *spinner = nullptr;
- ImageBox *leftArrow = nullptr;
- ImageBox *rightArrow = nullptr;
+ StringSpinner *spinner = nullptr;
+ ImageBox *leftArrow = nullptr;
+ ImageBox *rightArrow = nullptr;
};
} // namespace gui
M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp +6 -6
@@ 24,8 24,8 @@ namespace gui
timeSetSpinner->setFont(focusFontName, noFocusFontName);
timeSetSpinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
- auto textRange = UTF8Spinner::Range{time::Locale::getAM(), time::Locale::getPM()};
- fmt = new UTF8Spinner(textRange, Boundaries::Continuous);
+ auto textRange = StringSpinner::range{time::Locale::getAM(), time::Locale::getPM()};
+ fmt = new StringSpinner(textRange, Boundaries::Continuous);
updateFmtFont(noFocusFontName);
fmt->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
fmt->setMargins(getFmtMargins(noFocusFontName));
@@ 74,10 74,10 @@ namespace gui
if (timeFormat != newFormat) {
timeSetSpinner->setHour(date::make12(hours).count());
if (date::is_pm(hours)) {
- fmt->setCurrentValue(time::Locale::getPM());
+ fmt->set_value(time::Locale::getPM());
}
else {
- fmt->setCurrentValue(time::Locale::getAM());
+ fmt->set_value(time::Locale::getAM());
}
}
@@ 215,7 215,7 @@ namespace gui
auto TimeSetFmtSpinner::isPM() const noexcept -> bool
{
- return fmt->getCurrentValue() == utils::time::Locale::getPM().c_str();
+ return fmt->value() == utils::time::Locale::getPM().c_str();
}
auto TimeSetFmtSpinner::getTimeFormat() const noexcept -> utils::time::Locale::TimeFormat
@@ 234,7 234,7 @@ namespace gui
const auto hours = std::chrono::hours{t->tm_hour};
const auto time12H = date::make12(hours);
const auto isPM = date::is_pm(hours);
- fmt->setCurrentValue(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
+ fmt->set_value(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
timeSetSpinner->setTime(time12H.count(), t->tm_min);
}
}
M module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp +1 -1
@@ 76,7 76,7 @@ namespace gui
void handleContentChanged() override;
TimeSetSpinner *timeSetSpinner = nullptr;
- UTF8Spinner *fmt = nullptr;
+ StringSpinner *fmt = nullptr;
EditMode editMode = EditMode::Edit;
std::string focusFontName = style::window::font::supersizeme;
std::string noFocusFontName = style::window::font::supersizemelight;
M module-apps/apps-common/widgets/TimeSetSpinner.cpp => module-apps/apps-common/widgets/TimeSetSpinner.cpp +10 -9
@@ 26,13 26,13 @@ namespace gui
setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
setEdges(RectangleEdge::None);
- hour = new UIntegerSpinner(UIntegerSpinner::Range{hourMin, hourMax, hourStep}, Boundaries::Continuous);
+ hour = new UIntegerSpinner(UIntegerSpinner::range{hourMin, hourMax, hourStep}, Boundaries::Continuous);
updateFont(hour, noFocusFontName);
hour->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
hour->setEdges(RectangleEdge::None);
hour->setPenFocusWidth(style::time_set_spinner::focus::size);
- hour->setCurrentValue(0);
+ hour->set_value(0);
addWidget(hour);
@@ 42,14 42,14 @@ namespace gui
colon->setEdges(RectangleEdge::None);
colon->activeItem = false;
- minute = new UIntegerSpinnerFixed(UIntegerSpinnerFixed::Range{minuteMin, minuteMax, minuteStep},
+ minute = new UIntegerSpinnerFixed(UIntegerSpinnerFixed::range{minuteMin, minuteMax, minuteStep},
Boundaries::Continuous);
updateFont(minute, noFocusFontName);
minute->setPenFocusWidth(style::time_set_spinner::focus::size);
minute->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
minute->setEdges(RectangleEdge::None);
- minute->setCurrentValue(0);
+ minute->set_value(0);
addWidget(minute);
resizeItems();
@@ 133,12 133,12 @@ namespace gui
auto TimeSetSpinner::setHour(int value) noexcept -> void
{
- hour->setCurrentValue(value);
+ hour->set_value(value);
}
auto TimeSetSpinner::setMinute(int value) noexcept -> void
{
- minute->setCurrentValue(value);
+ minute->set_value(value);
}
auto TimeSetSpinner::setFont(const std::string &newFontName) noexcept -> void
@@ 186,12 186,12 @@ namespace gui
auto TimeSetSpinner::getHour() const noexcept -> int
{
- return hour->getCurrentValue();
+ return hour->value();
}
auto TimeSetSpinner::getMinute() const noexcept -> int
{
- return minute->getCurrentValue();
+ return minute->value();
}
void TimeSetSpinner::updateFocus(Item *newFocus)
@@ 220,7 220,8 @@ namespace gui
auto TimeSetSpinner::setHourRange(std::uint32_t min, std::uint32_t max) -> void
{
- hour->setRange(UIntegerSpinner::Range{min, max, hourStep});
+ hour->set_range(
+ UIntegerSpinner::range{static_cast<std::uint8_t>(min), static_cast<std::uint8_t>(max), hourStep});
}
auto TimeSetSpinner::getColonImage(const std::string &colonFont) const noexcept -> std::string
D module-apps/apps-common/widgets/spinners/GenericSpinner.hpp => module-apps/apps-common/widgets/spinners/GenericSpinner.hpp +0 -160
@@ 1,160 0,0 @@
-// 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 "SpinnerPolicies.hpp"
-#include <widgets/text/TextFixedSize.hpp>
-
-namespace gui
-{
- template <typename Policy> class GenericSpinner : public TextFixedSize
- {
- public:
- using Range = typename Policy::Range;
- using Type = typename Policy::Type;
-
- using OnValueChanged = std::function<void(const Type &&)>;
-
- explicit GenericSpinner(Range range,
- Boundaries boundaries = Boundaries::Continuous,
- Orientation orientation = Orientation::Vertical);
-
- [[nodiscard]] Type getCurrentValue() const noexcept;
- void setCurrentValue(Type val);
- void setRange(Range range);
-
- 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;
-
- OnValueChanged onValueChanged;
-
- private:
- void stepNext();
- void stepPrevious();
- bool isPreviousEvent(const InputEvent &inputEvent);
- bool isNextEvent(const InputEvent &inputEvent);
- void update();
- void invoke();
-
- Policy policy;
- RectangleEdge focusEdges = RectangleEdge::Bottom;
- Orientation orientation = Orientation::Vertical;
- };
-
- template <typename ValuePolicy>
- GenericSpinner<ValuePolicy>::GenericSpinner(GenericSpinner::Range range,
- Boundaries boundaries,
- Orientation orientation)
- : policy{range, boundaries}, orientation(orientation)
- {
- setEditMode(EditMode::Browse);
- drawUnderline(false);
- update();
- }
-
- template <typename ValuePolicy> void GenericSpinner<ValuePolicy>::setFocusEdges(RectangleEdge edges)
- {
- focusEdges = edges;
- }
-
- template <typename Policy> void GenericSpinner<Policy>::setRange(Range range)
- {
- policy.updateRange(range);
- update();
- }
-
- template <typename ValuePolicy> void GenericSpinner<ValuePolicy>::setCurrentValue(const Type val)
- {
- policy.set(val);
- update();
- }
-
- template <typename Policy>
- typename GenericSpinner<Policy>::Type GenericSpinner<Policy>::getCurrentValue() const noexcept
- {
- return policy.get();
- }
-
- template <typename ValuePolicy> bool GenericSpinner<ValuePolicy>::isPreviousEvent(const InputEvent &inputEvent)
- {
- return (orientation == Orientation::Vertical && inputEvent.is(KeyCode::KEY_DOWN)) ||
- (orientation == Orientation::Horizontal && inputEvent.is(KeyCode::KEY_LEFT));
- }
-
- template <typename ValuePolicy> bool GenericSpinner<ValuePolicy>::isNextEvent(const InputEvent &inputEvent)
- {
- return (orientation == Orientation::Vertical && inputEvent.is(KeyCode::KEY_UP)) ||
- (orientation == Orientation::Horizontal && inputEvent.is(KeyCode::KEY_RIGHT));
- }
-
- template <typename ValuePolicy> bool GenericSpinner<ValuePolicy>::onInput(const InputEvent &inputEvent)
- {
- if (inputEvent.isShortRelease()) {
- if (isPreviousEvent(inputEvent)) {
- stepPrevious();
- return true;
- }
- else if (isNextEvent(inputEvent)) {
- stepNext();
- return true;
- }
- }
- return false;
- }
-
- template <typename ValuePolicy> bool GenericSpinner<ValuePolicy>::onFocus(bool state)
- {
- if (focus) {
- setEdges(focusEdges);
- }
- else {
- setEdges(RectangleEdge::None);
- }
- showCursor(state);
- return true;
- }
-
- template <typename Policy> void GenericSpinner<Policy>::stepNext()
- {
- if (policy.next()) {
- update();
- invoke();
- }
- }
-
- template <typename Policy> void GenericSpinner<Policy>::stepPrevious()
- {
- if (policy.previous()) {
- update();
- invoke();
- }
- }
-
- template <typename Policy> void GenericSpinner<Policy>::update()
- {
- setText(policy.str());
- }
- template <typename Policy> void GenericSpinner<Policy>::invoke()
- {
- if (onValueChanged) {
- onValueChanged(getCurrentValue());
- }
- }
- template <typename Policy> bool GenericSpinner<Policy>::isSingle() const
- {
- return policy.isSingle();
- }
- template <typename Policy> bool GenericSpinner<Policy>::isAtMin() const
- {
- return policy.isAtMin();
- }
- template <typename Policy> bool GenericSpinner<Policy>::isAtMax() const
- {
- return policy.isAtMax();
- }
-} // namespace gui
M module-apps/apps-common/widgets/spinners/ItemSpinner.hpp => module-apps/apps-common/widgets/spinners/ItemSpinner.hpp +49 -38
@@ 3,27 3,27 @@
#pragma once
-#include "SpinnerPolicies.hpp"
#include <Item.hpp>
+#include <InputEvent.hpp>
namespace gui
{
- template <typename Policy> class ItemSpinner : public Item
+ template <typename Container> class ItemSpinner : public Item
{
public:
- using Range = typename Policy::Range;
- using Type = typename Policy::Type;
+ using range = typename Container::range;
+ using value_type = typename Container::value_type;
- using OnValueChanged = std::function<void(const Type &&)>;
+ using OnValueChanged = std::function<void(const value_type &&)>;
explicit ItemSpinner(Item *parent,
- Range range,
+ range range,
Boundaries boundaries = Boundaries::Continuous,
Orientation orientation = Orientation::Vertical);
- [[nodiscard]] Type getCurrentValue() const noexcept;
- void setCurrentValue(Type val);
- void setRange(Range range);
+ [[nodiscard]] value_type getCurrentValue() const noexcept;
+ void setCurrentValue(value_type val);
+ void setRange(range range);
void setFocusEdges(RectangleEdge edges);
bool onInput(const InputEvent &inputEvent) override;
@@ 33,6 33,16 @@ namespace gui
OnValueChanged onValueChanged;
private:
+ inline typename Container::Boundaries convert_boundaries(gui::Boundaries boundaries)
+ {
+ switch (boundaries) {
+ case gui::Boundaries::Fixed:
+ return Container::Boundaries::Fixed;
+ case gui::Boundaries::Continuous:
+ return Container::Boundaries::Continuous;
+ }
+ return Container::Boundaries::Fixed;
+ }
void stepNext();
void stepPrevious();
bool isPreviousEvent(const InputEvent &inputEvent);
@@ 40,18 50,18 @@ namespace gui
void update();
void invoke();
- Policy policy;
+ Container container;
RectangleEdge focusEdges = RectangleEdge::Bottom;
Orientation orientation = Orientation::Vertical;
gui::Item *currentLayout = nullptr;
};
- template <typename ValuePolicy>
- ItemSpinner<ValuePolicy>::ItemSpinner(Item *parent,
- ItemSpinner::Range range,
- Boundaries boundaries,
- Orientation orientation)
- : Item(), policy{range, boundaries}, orientation(orientation)
+ template <typename Container>
+ ItemSpinner<Container>::ItemSpinner(Item *parent,
+ ItemSpinner::range range,
+ Boundaries boundaries,
+ Orientation orientation)
+ : Item(), container{range, convert_boundaries(boundaries)}, orientation(orientation)
{
this->parent = parent;
if (parent != nullptr) {
@@ 59,41 69,42 @@ namespace gui
}
}
- template <typename ValuePolicy> void ItemSpinner<ValuePolicy>::setFocusEdges(RectangleEdge edges)
+ template <typename Container> void ItemSpinner<Container>::setFocusEdges(RectangleEdge edges)
{
focusEdges = edges;
}
- template <typename Policy> void ItemSpinner<Policy>::setRange(Range range)
+ template <typename Container> void ItemSpinner<Container>::setRange(range range)
{
- policy.updateRange(range);
+ container.updateRange(range);
update();
}
- template <typename ValuePolicy> void ItemSpinner<ValuePolicy>::setCurrentValue(const Type val)
+ template <typename Container> void ItemSpinner<Container>::setCurrentValue(const value_type val)
{
- policy.set(val);
+ container.set(val);
update();
}
- template <typename Policy> typename ItemSpinner<Policy>::Type ItemSpinner<Policy>::getCurrentValue() const noexcept
+ template <typename Container>
+ typename ItemSpinner<Container>::value_type ItemSpinner<Container>::getCurrentValue() const noexcept
{
- return policy.get();
+ return container.get();
}
- template <typename ValuePolicy> bool ItemSpinner<ValuePolicy>::isPreviousEvent(const InputEvent &inputEvent)
+ template <typename Container> bool ItemSpinner<Container>::isPreviousEvent(const InputEvent &inputEvent)
{
return (orientation == Orientation::Vertical && inputEvent.is(KeyCode::KEY_DOWN)) ||
(orientation == Orientation::Horizontal && inputEvent.is(KeyCode::KEY_LEFT));
}
- template <typename ValuePolicy> bool ItemSpinner<ValuePolicy>::isNextEvent(const InputEvent &inputEvent)
+ template <typename Container> bool ItemSpinner<Container>::isNextEvent(const InputEvent &inputEvent)
{
return (orientation == Orientation::Vertical && inputEvent.is(KeyCode::KEY_UP)) ||
(orientation == Orientation::Horizontal && inputEvent.is(KeyCode::KEY_RIGHT));
}
- template <typename ValuePolicy> bool ItemSpinner<ValuePolicy>::onInput(const InputEvent &inputEvent)
+ template <typename Container> bool ItemSpinner<Container>::onInput(const InputEvent &inputEvent)
{
if (inputEvent.isShortRelease()) {
if (isPreviousEvent(inputEvent)) {
@@ 108,43 119,43 @@ namespace gui
return false;
}
- template <typename Policy> void ItemSpinner<Policy>::stepNext()
+ template <typename Container> void ItemSpinner<Container>::stepNext()
{
- if (policy.next()) {
+ if (container.next()) {
update();
invoke();
}
}
- template <typename Policy> void ItemSpinner<Policy>::stepPrevious()
+ template <typename Container> void ItemSpinner<Container>::stepPrevious()
{
- if (policy.previous()) {
+ if (container.previous()) {
update();
invoke();
}
}
- template <typename Policy> void ItemSpinner<Policy>::update()
+ template <typename Container> void ItemSpinner<Container>::update()
{
- if (currentLayout) {
+ if (currentLayout != nullptr) {
this->removeWidget(currentLayout);
}
- currentLayout = policy.get();
+ currentLayout = container.get();
this->addWidget(currentLayout);
informContentChanged();
}
- template <typename Policy> void ItemSpinner<Policy>::invoke()
+ template <typename Container> void ItemSpinner<Container>::invoke()
{
if (onValueChanged) {
onValueChanged(getCurrentValue());
}
}
- template <typename Policy> bool ItemSpinner<Policy>::isAtMin() const
+ template <typename Container> bool ItemSpinner<Container>::isAtMin() const
{
- return policy.isAtMin();
+ return container.is_min();
}
- template <typename Policy> bool ItemSpinner<Policy>::isAtMax() const
+ template <typename Container> bool ItemSpinner<Container>::isAtMax() const
{
- return policy.isAtMax();
+ return container.is_max();
}
} // namespace gui
A module-apps/apps-common/widgets/spinners/Model.hpp => module-apps/apps-common/widgets/spinners/Model.hpp +212 -0
@@ 0,0 1,212 @@
+// 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 <vector>
+#include <string>
+#include <type_traits>
+
+/// Generic elements container.
+/// By default, the container will choose the most optimal way of elements storage.
+/// Fundamental types(ints, float, doubles, chars) are stored as simple variables. Compound types are stored in
+/// std::vector.
+/// Sometimes it is necessary to force the latter way of storing values even for fundamental types. For
+/// instance, the user might want to store a fixed list of integers to iterate. In that case, set the force parameter to
+/// true.
+template <class ElementType, bool force = false, typename = void> class Model
+{
+ public:
+ enum class Boundaries
+ {
+ Fixed, /// Stop scrolling upon reaching last/first element
+ Continuous /// Jump to beginning/end upon reaching last/first element
+ };
+ using range = std::vector<ElementType>;
+ using value_type = ElementType;
+
+ Model(range &&r, Boundaries boundaries) : elements{std::move(r)}, it{elements.begin()}, boundaries{boundaries}
+ {}
+
+ Model(const range &r, Boundaries boundaries) : elements{r}, it{elements.begin()}, boundaries{boundaries}
+ {}
+
+ ElementType get() const
+ {
+ return it == elements.end() ? ElementType{} : *it;
+ }
+
+ void set(ElementType val)
+ {
+ const auto e = std::find_if(elements.begin(), elements.end(), [&val](const auto &i) { return i == val; });
+ if (e != elements.end()) {
+ it = e;
+ }
+ }
+
+ bool next()
+ {
+ bool ret{true};
+ if (std::next(it) == elements.end()) {
+ if (boundaries == Boundaries::Continuous) {
+ it = elements.begin();
+ }
+ else {
+ ret = false;
+ }
+ }
+ else {
+ it = std::next(it);
+ }
+ return ret;
+ }
+
+ bool previous()
+ {
+ bool ret{true};
+ if (it == elements.begin()) {
+ if (boundaries == Boundaries::Continuous) {
+ it = std::prev(elements.end());
+ }
+ else {
+ ret = false;
+ }
+ }
+ else {
+ it = std::prev(it);
+ }
+ return ret;
+ }
+
+ void set_range(range newRange)
+ {
+ if (elements != newRange) {
+ elements = newRange;
+ it = elements.begin();
+ }
+ }
+
+ [[nodiscard]] size_t size() const
+ {
+ return elements.size();
+ }
+
+ [[nodiscard]] bool is_min() const
+ {
+ return it == elements.begin();
+ }
+
+ [[nodiscard]] bool is_max() const
+ {
+ return std::next(it) == elements.end();
+ }
+
+ private:
+ range elements;
+ typename range::iterator it = elements.end();
+ const Boundaries boundaries{};
+};
+
+template <typename ElementType, bool force>
+class Model<ElementType, force, std::enable_if_t<std::is_fundamental_v<ElementType> and not force>>
+{
+ struct details
+ {
+ struct range
+ {
+ ElementType min{};
+ ElementType max{};
+ ElementType step{};
+
+ bool operator!=(const range &oth) const
+ {
+ return min != oth.min || max != oth.max || step != oth.step;
+ }
+ };
+ };
+
+ public:
+ enum class Boundaries
+ {
+ Fixed,
+ Continuous
+ };
+ using range = typename details::range;
+ using value_type = ElementType;
+
+ Model(range &&elements, Boundaries boundaries)
+ : elements{std::move(elements)}, value{elements.min}, boundaries{boundaries}
+ {}
+
+ Model(range &elements, Boundaries boundaries) : elements{elements}, value{elements.min}, boundaries{boundaries}
+ {}
+
+ ElementType get() const
+ {
+ return value;
+ }
+
+ void set(ElementType val)
+ {
+ value = val;
+ }
+
+ bool next()
+ {
+ bool ret{true};
+ if (value >= elements.max) {
+ if (boundaries == Boundaries::Continuous) {
+ value = elements.min;
+ }
+ else {
+ value = elements.max;
+ ret = false;
+ }
+ }
+ else {
+ value += elements.step;
+ }
+ return ret;
+ }
+
+ bool previous()
+ {
+ bool ret{true};
+ if (value <= elements.min) {
+ if (boundaries == Boundaries::Continuous) {
+ value = elements.max;
+ }
+ else {
+ value = elements.min;
+ ret = false;
+ }
+ }
+ else {
+ value -= elements.step;
+ }
+ return ret;
+ }
+
+ void set_range(range newRange)
+ {
+ if (elements != newRange) {
+ elements = newRange;
+ value = elements.min;
+ }
+ }
+
+ [[nodiscard]] bool is_min() const
+ {
+ return value == elements.min;
+ }
+
+ [[nodiscard]] bool is_max() const
+ {
+ return value == elements.max;
+ }
+
+ private:
+ range elements;
+ ElementType value{};
+ const Boundaries boundaries{};
+};
D module-apps/apps-common/widgets/spinners/SpinnerContents.hpp => module-apps/apps-common/widgets/spinners/SpinnerContents.hpp +0 -58
@@ 1,58 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include <optional>
-
-namespace gui
-{
- template <typename ValueT, typename StringT> class NumWithString
- {
- public:
- NumWithString() = default;
-
- NumWithString(ValueT value, StringT string) : value{value}, string{string}
- {}
-
- explicit NumWithString(StringT string) : string{string}
- {}
- explicit NumWithString(ValueT value) : value{value}
- {}
-
- bool operator==(const NumWithString &oth) const
- {
- return oth.toStr() == toStr();
- }
-
- operator StringT() const
- {
- return toStr();
- }
-
- std::optional<ValueT> getValue() const
- {
- return value;
- }
-
- std::optional<StringT> getSuffix() const
- {
- return string;
- }
-
- private:
- StringT toStr() const
- {
- StringT retStr;
- if (value) {
- retStr += std::to_string(*value) + " ";
- }
- if (string) {
- retStr += *string;
- }
- return retStr;
- }
- std::optional<ValueT> value;
- std::optional<StringT> string;
- };
-} // namespace gui
D module-apps/apps-common/widgets/spinners/SpinnerPolicies.hpp => module-apps/apps-common/widgets/spinners/SpinnerPolicies.hpp +0 -410
@@ 1,410 0,0 @@
-// 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 <gui/Common.hpp>
-
-#include <vector>
-#include <cstdint>
-#include <iomanip>
-#include <utf8/UTF8.hpp>
-
-namespace gui
-{
- template <typename ValType> class StringPolicy
- {
- public:
- using Range = std::vector<ValType>;
- using Type = ValType;
-
- StringPolicy(Range range, Boundaries boundaries) : range{range}, boundaries{boundaries}
- {}
-
- ValType get() const
- {
- return pos < range.size() ? range[pos] : ValType{};
- }
-
- UTF8 str() const
- {
- return pos < range.size() ? range[pos] : UTF8{};
- }
-
- void set(ValType val)
- {
- for (auto i = 0U; i < range.size(); i++) {
- if (range[i] == val) {
- pos = i;
- break;
- }
- }
- }
-
- bool next()
- {
- bool ret{true};
- if (pos >= upRange()) {
- if (boundaries == Boundaries::Continuous) {
- pos = 0;
- }
- else {
- pos = upRange();
- ret = false;
- }
- }
- else {
- pos++;
- }
- return ret;
- }
-
- bool previous()
- {
- bool ret{true};
- if (pos <= 0) {
- if (boundaries == Boundaries::Continuous) {
- pos = upRange();
- }
- else {
- pos = 0;
- ret = false;
- }
- }
- else {
- pos--;
- }
- return ret;
- }
-
- void updateRange(Range newRange)
- {
- if (range != newRange) {
- range = newRange;
- pos = 0;
- }
- }
-
- [[nodiscard]] bool isSingle() const
- {
- return range.size() == 1;
- }
- [[nodiscard]] bool isAtMin() const
- {
- return pos == 0;
- }
- [[nodiscard]] bool isAtMax() const
- {
- return pos == upRange();
- }
-
- private:
- std::uint32_t upRange() const
- {
- return range.size() - 1;
- }
-
- Range range;
- std::uint32_t pos{};
- const Boundaries boundaries{};
- };
-
- template <typename ValType> class WidgetPolicy
- {
- public:
- using Range = std::vector<ValType>;
- using Type = ValType;
-
- WidgetPolicy(Range range, Boundaries boundaries) : range{range}, boundaries{boundaries}
- {}
-
- ValType get() const
- {
- return pos < range.size() ? range[pos] : ValType{};
- }
-
- void set(ValType val)
- {
- for (auto i = 0U; i < range.size(); i++) {
- if (range[i] == val) {
- pos = i;
- break;
- }
- }
- }
-
- bool next()
- {
- bool ret{true};
- if (pos >= upRange()) {
- if (boundaries == Boundaries::Continuous) {
- pos = 0;
- }
- else {
- pos = upRange();
- ret = false;
- }
- }
- else {
- pos++;
- }
- return ret;
- }
-
- bool previous()
- {
- bool ret{true};
- if (pos <= 0) {
- if (boundaries == Boundaries::Continuous) {
- pos = upRange();
- }
- else {
- pos = 0;
- ret = false;
- }
- }
- else {
- pos--;
- }
- return ret;
- }
-
- void updateRange(Range newRange)
- {
- if (range != newRange) {
- range = newRange;
- pos = 0;
- }
- }
-
- [[nodiscard]] bool isAtMin() const
- {
- return pos == 0;
- }
- [[nodiscard]] bool isAtMax() const
- {
- return pos == upRange();
- }
-
- private:
- std::uint32_t upRange() const
- {
- return range.size() - 1;
- }
-
- Range range;
- std::uint32_t pos{};
- const Boundaries boundaries{};
- };
-
- template <typename ValType> class DefaultNumericFormatter
- {
- public:
- std::string operator()(const ValType val) const
- {
- return std::to_string(val);
- }
- };
-
- template <typename ValType, int Width> class FixedSizeFormatter
- {
- public:
- std::string operator()(const ValType val) const
- {
- std::stringstream outStream;
- outStream << std::setw(Width) << std::setfill('0') << val;
- return outStream.str();
- }
- };
-
- template <typename ValType, typename Formatter = DefaultNumericFormatter<ValType>> class NumericPolicy
- {
- struct RangeImpl
- {
- ValType min;
- ValType max;
- ValType step;
- bool operator!=(const RangeImpl &oth) const
- {
- return min != oth.min || max != oth.max || step != oth.step;
- }
- };
-
- public:
- using Range = RangeImpl;
- using Type = ValType;
-
- NumericPolicy(Range range, Boundaries boundaries) : range{range}, boundaries{boundaries}
- {}
-
- ValType get() const
- {
- return currentValue;
- }
-
- UTF8 str() const
- {
- return Formatter{}(currentValue);
- }
-
- void set(ValType val)
- {
- currentValue = val;
- }
-
- bool next()
- {
- bool ret{true};
- if (currentValue >= range.max) {
- if (boundaries == Boundaries::Continuous) {
- currentValue = range.min;
- }
- else {
- currentValue = range.max;
- ret = false;
- }
- }
- else {
- currentValue += range.step;
- }
- return ret;
- }
-
- bool previous()
- {
- bool ret{true};
- if (currentValue <= range.min) {
- if (boundaries == Boundaries::Continuous) {
- currentValue = range.max;
- }
- else {
- currentValue = range.min;
- ret = false;
- }
- }
- else {
- currentValue -= range.step;
- }
- return ret;
- }
-
- void updateRange(Range newRange)
- {
- if (range != newRange) {
- range = newRange;
- currentValue = 0;
- }
- }
-
- [[nodiscard]] bool isAtMin() const
- {
- return currentValue == range.min;
- }
- [[nodiscard]] bool isAtMax() const
- {
- return currentValue == range.max;
- }
-
- private:
- Range range;
- ValType currentValue{};
- const Boundaries boundaries{};
- };
-
- template <typename ValType, typename RepresentationType = UTF8> class ModelDelegatePolicy
- {
- public:
- using Range = std::vector<ValType>;
- using Type = ValType;
-
- ModelDelegatePolicy(Range range, Boundaries boundaries) : range{range}, boundaries{boundaries}
- {}
-
- Type get() const
- {
- return pos < range.size() ? range[pos] : Type{};
- }
-
- UTF8 str() const
- {
- return pos < range.size() ? RepresentationType{range[pos]} : RepresentationType{};
- }
-
- void set(ValType val)
- {
- for (auto i = 0U; i < range.size(); i++) {
- if (range[i] == val) {
- pos = i;
- break;
- }
- }
- }
-
- bool next()
- {
- bool ret{true};
- if (pos >= upRange()) {
- if (boundaries == Boundaries::Continuous) {
- pos = 0;
- }
- else {
- pos = upRange();
- ret = false;
- }
- }
- else {
- pos++;
- }
- return ret;
- }
-
- bool previous()
- {
- bool ret{true};
- if (pos <= 0) {
- if (boundaries == Boundaries::Continuous) {
- pos = upRange();
- }
- else {
- pos = 0;
- ret = false;
- }
- }
- else {
- pos--;
- }
- return ret;
- }
-
- void updateRange(Range newRange)
- {
- if (range != newRange) {
- range = newRange;
- pos = 0;
- }
- }
- [[nodiscard]] bool isSingle() const
- {
- return range.size() == 1;
- }
- [[nodiscard]] bool isAtMin() const
- {
- return pos == 0;
- }
- [[nodiscard]] bool isAtMax() const
- {
- return pos == upRange();
- }
-
- private:
- std::uint32_t upRange() const
- {
- return range.size() - 1;
- }
-
- Range range;
- std::uint32_t pos{};
- const Boundaries boundaries{};
- };
-
-} // namespace gui
M module-apps/apps-common/widgets/spinners/Spinners.hpp => module-apps/apps-common/widgets/spinners/Spinners.hpp +22 -7
@@ 3,16 3,31 @@
#pragma once
-#include "GenericSpinner.hpp"
+#include "ItemSpinner.hpp"
+
+#include "Model.hpp"
+#include "StringOutputSpinner.hpp"
#include "ItemSpinner.hpp"
namespace gui
{
- using UTF8Spinner = GenericSpinner<StringPolicy<UTF8>>;
- using UIntegerSpinner = GenericSpinner<NumericPolicy<std::uint32_t>>;
- using UIntegerSpinnerFixed = GenericSpinner<NumericPolicy<std::uint32_t, FixedSizeFormatter<std::uint32_t, 2>>>;
- using IntegerSpinner = GenericSpinner<NumericPolicy<std::int32_t>>;
- using WidgetSpinner = ItemSpinner<WidgetPolicy<Item *>>;
+ template <typename ValType, size_t Width> struct FixedIntegerFormatter
+ {
+ std::string operator()(const ValType val) const
+ {
+ std::stringstream outStream;
+ outStream << std::setw(Width) << std::setfill('0') << val;
+ return outStream.str();
+ }
+ };
+
+ using StringContainer = Model<UTF8>;
+ using UINT8Container = Model<std::uint8_t>;
+
+ using StringSpinner = StringOutputSpinner<StringContainer>;
+ using UIntegerSpinner = StringOutputSpinner<UINT8Container>;
+ using UIntegerSpinnerFixed = StringOutputSpinner<UINT8Container, FixedIntegerFormatter<std::uint32_t, 2>>;
+ using WidgetSpinner = ItemSpinner<Model<Item *>>;
+ template <typename T> using UIntegerSpinnerWithFormatter = StringOutputSpinner<UINT8Container, T>;
- template <typename ModelType> using ModelDelegateSpinner = GenericSpinner<ModelDelegatePolicy<ModelType>>;
} // namespace gui
A module-apps/apps-common/widgets/spinners/StringOutputSpinner.hpp => module-apps/apps-common/widgets/spinners/StringOutputSpinner.hpp +237 -0
@@ 0,0 1,237 @@
+// 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 <widgets/text/TextFixedSize.hpp>
+
+#include <string>
+#include <type_traits>
+
+namespace details
+{
+ template <typename T, typename = void> struct container_data
+ {
+ using value = T;
+ };
+
+ template <typename T> struct container_data<T, std::enable_if_t<not std::is_fundamental_v<T>>>
+ {
+ using value = typename T::value_type;
+ };
+
+ template <class T> using container_data_v = typename container_data<T>::value;
+
+} // namespace details
+
+namespace gui
+{
+ // This spinner operates on container elements and transforms the current container into a string.
+ // For the containers of types that are convertible to strings like std::string, integer, floating-point integers,
+ // there is no need to provide the custom formatter. However, it is possible to pass a formatter if a user wants to
+ // perform custom formatting. It is not possible to use a formatter when using container of std::string.
+ template <typename Container, typename Formatter = void> class StringOutputSpinner : public TextFixedSize
+ {
+ public:
+ using range = typename Container::range;
+ using value_type = details::container_data_v<Container>;
+
+ explicit StringOutputSpinner(Container &&container, Orientation orientation = Orientation::Vertical)
+ : container{std::move(container)}, orientation{orientation}
+ {
+ init();
+ }
+
+ explicit StringOutputSpinner(range &range,
+ Boundaries boundaries = Boundaries::Fixed,
+ Orientation orientation = Orientation::Vertical)
+ : container{range, convert_boundaries(boundaries)}, orientation{orientation}
+ {
+ init();
+ }
+
+ explicit StringOutputSpinner(range &&range,
+ Boundaries boundaries = Boundaries::Fixed,
+ Orientation orientation = Orientation::Vertical)
+ : container{std::move(range), convert_boundaries(boundaries)}, orientation{orientation}
+ {
+ init();
+ }
+
+ using OnValueChanged = std::function<void(const value_type &)>;
+ void setFocusEdges(RectangleEdge edges);
+ bool onInput(const InputEvent &inputEvent) override;
+ bool onFocus(bool state) override;
+ [[nodiscard]] size_t size() const;
+ [[nodiscard]] bool is_min() const;
+ [[nodiscard]] bool is_max() const;
+
+ OnValueChanged onValueChanged;
+
+ void set_range(const range &range);
+ void set_value(const value_type &value);
+ [[nodiscard]] auto value() const noexcept;
+
+ private:
+ inline typename Container::Boundaries convert_boundaries(gui::Boundaries boundaries)
+ {
+ switch (boundaries) {
+ case gui::Boundaries::Fixed:
+ return Container::Boundaries::Fixed;
+ case gui::Boundaries::Continuous:
+ return Container::Boundaries::Continuous;
+ }
+ return Container::Boundaries::Fixed;
+ }
+ void init();
+ [[nodiscard]] std::string value_as_str() const noexcept;
+ void next();
+ void previous();
+ bool is_previous_event(const InputEvent &inputEvent);
+ bool is_next_event(const InputEvent &inputEvent);
+ void update();
+ void invoke();
+
+ static constexpr bool is_string =
+ std::is_same_v<value_type, std::string> or std::is_convertible_v<value_type, std::string>;
+ static constexpr bool is_fundamental = std::is_fundamental_v<value_type>;
+ static constexpr bool is_formatter_defined = not std::is_same_v<Formatter, void>;
+
+ Container container;
+ RectangleEdge focusEdges = RectangleEdge::Bottom;
+ Orientation orientation = Orientation::Vertical;
+ };
+
+ template <typename Container, typename Formatter>
+ auto StringOutputSpinner<Container, Formatter>::value() const noexcept
+ {
+ return container.get();
+ }
+
+ template <typename Container, typename Formatter>
+ std::string StringOutputSpinner<Container, Formatter>::value_as_str() const noexcept
+ {
+ if constexpr (is_string) {
+ return container.get();
+ }
+ else if constexpr (is_fundamental and not is_formatter_defined) {
+ return std::to_string(container.get());
+ }
+ else {
+ return Formatter{}(container.get());
+ }
+ }
+
+ template <typename Container, typename Formatter>
+ void StringOutputSpinner<Container, Formatter>::setFocusEdges(RectangleEdge edges)
+ {
+ focusEdges = edges;
+ }
+
+ template <typename Container, typename Formatter>
+ bool StringOutputSpinner<Container, Formatter>::onInput(const InputEvent &inputEvent)
+ {
+ if (inputEvent.isShortRelease()) {
+ if (is_previous_event(inputEvent)) {
+ previous();
+ return true;
+ }
+ else if (is_next_event(inputEvent)) {
+ next();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <typename Container, typename Formatter>
+ bool StringOutputSpinner<Container, Formatter>::onFocus(bool state)
+ {
+ if (focus) {
+ setEdges(focusEdges);
+ }
+ else {
+ setEdges(RectangleEdge::None);
+ }
+ showCursor(state);
+ return true;
+ }
+
+ template <typename Container, typename Formatter> size_t StringOutputSpinner<Container, Formatter>::size() const
+ {
+ return container.size();
+ }
+
+ template <typename Container, typename Formatter> bool StringOutputSpinner<Container, Formatter>::is_min() const
+ {
+ return container.is_min();
+ }
+
+ template <typename Container, typename Formatter> bool StringOutputSpinner<Container, Formatter>::is_max() const
+ {
+ return container.is_max();
+ }
+
+ template <typename Container, typename Formatter>
+ void StringOutputSpinner<Container, Formatter>::set_value(const value_type &value)
+ {
+ container.set(value);
+ update();
+ }
+
+ template <typename Container, typename Formatter>
+ void StringOutputSpinner<Container, Formatter>::set_range(const range &range)
+ {
+ container.set_range(range);
+ update();
+ }
+
+ template <typename Container, typename Formatter> void StringOutputSpinner<Container, Formatter>::next()
+ {
+ if (container.next()) {
+ update();
+ invoke();
+ }
+ }
+
+ template <typename Container, typename Formatter> void StringOutputSpinner<Container, Formatter>::previous()
+ {
+ if (container.previous()) {
+ update();
+ invoke();
+ }
+ }
+ template <typename Container, typename Formatter> void StringOutputSpinner<Container, Formatter>::update()
+ {
+ setText(value_as_str());
+ }
+
+ template <typename Container, typename Formatter> void StringOutputSpinner<Container, Formatter>::invoke()
+ {
+ if (onValueChanged) {
+ onValueChanged(value());
+ }
+ }
+
+ template <typename Container, typename Formatter>
+ bool StringOutputSpinner<Container, Formatter>::is_previous_event(const InputEvent &inputEvent)
+ {
+ return (orientation == Orientation::Vertical && inputEvent.is(KeyCode::KEY_DOWN)) ||
+ (orientation == Orientation::Horizontal && inputEvent.is(KeyCode::KEY_LEFT));
+ }
+
+ template <typename Container, typename Formatter>
+ bool StringOutputSpinner<Container, Formatter>::is_next_event(const InputEvent &inputEvent)
+ {
+ return (orientation == Orientation::Vertical && inputEvent.is(KeyCode::KEY_UP)) ||
+ (orientation == Orientation::Horizontal && inputEvent.is(KeyCode::KEY_RIGHT));
+ }
+
+ template <typename Container, typename Formatter> void StringOutputSpinner<Container, Formatter>::init()
+ {
+ setEditMode(EditMode::Browse);
+ drawUnderline(false);
+ update();
+ }
+
+} // namespace gui
M module-apps/tests/CMakeLists.txt => module-apps/tests/CMakeLists.txt +1 -0
@@ 5,6 5,7 @@ add_catch2_executable(
test-CallbackStorage.cpp
test-PhoneModesPolicies.cpp
tests-BluetoothSettingsModel.cpp
+ test-Model.cpp
LIBS
module-apps
)
A module-apps/tests/test-Model.cpp => module-apps/tests/test-Model.cpp +199 -0
@@ 0,0 1,199 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <catch2/catch.hpp>
+
+#include <apps-common/widgets/spinners/Model.hpp>
+
+TEST_CASE("Model")
+{
+ SECTION("Empty")
+ {
+ using UINT8Model = Model<std::uint8_t>;
+
+ auto container = UINT8Model{{}, UINT8Model::Boundaries::Fixed};
+
+ REQUIRE(container.get() == 0);
+ }
+
+ SECTION("Force underlying structure")
+ {
+ using ForcedContainer = Model<std::uint8_t, true>;
+
+ auto container = ForcedContainer{{5, 10, 2, 30, 25}, ForcedContainer::Boundaries::Fixed};
+
+ REQUIRE(container.get() == 5);
+ container.set(25);
+ REQUIRE(container.get() == 25);
+ container.set(2);
+ REQUIRE(container.get() == 2);
+ }
+
+ SECTION("Fundamental types")
+ {
+ using UINT8Model = Model<std::uint8_t>;
+ auto range = UINT8Model::range{0, 10, 1};
+ const auto boundaries = UINT8Model::Boundaries::Fixed;
+ SECTION("set")
+ {
+ auto container = UINT8Model{range, boundaries};
+
+ REQUIRE(container.get() == 0);
+ container.set(5);
+ REQUIRE(container.get() == 5);
+ }
+
+ SECTION("check step")
+ {
+ auto container = UINT8Model{UINT8Model::range{0, 6, 3}, boundaries};
+
+ REQUIRE(container.get() == 0);
+ container.next();
+ REQUIRE(container.get() == 3);
+ container.previous();
+ REQUIRE(container.get() == 0);
+ }
+
+ SECTION("Check boundaries")
+ {
+ SECTION("Fixed")
+ {
+ auto container = UINT8Model{range, boundaries};
+
+ REQUIRE(container.get() == 0);
+ container.previous();
+ REQUIRE(container.get() == 0);
+
+ container.set(10);
+ REQUIRE(container.get() == 10);
+ container.next();
+ REQUIRE(container.get() == 10);
+ }
+
+ SECTION("Continuous")
+ {
+ auto container = UINT8Model{range, UINT8Model::Boundaries::Continuous};
+
+ REQUIRE(container.get() == 0);
+ container.previous();
+ REQUIRE(container.get() == 10);
+
+ container.set(10);
+ REQUIRE(container.get() == 10);
+ container.next();
+ REQUIRE(container.get() == 0);
+ }
+ }
+
+ SECTION("is_min/is_max")
+ {
+ auto container = UINT8Model{range, boundaries};
+
+ REQUIRE(container.is_min());
+ REQUIRE_FALSE(container.is_max());
+
+ container.next();
+ REQUIRE_FALSE(container.is_min());
+ REQUIRE_FALSE(container.is_max());
+
+ container.set(10);
+ REQUIRE_FALSE(container.is_min());
+ REQUIRE(container.is_max());
+ }
+
+ SECTION("set_range")
+ {
+ auto container = UINT8Model{range, boundaries};
+
+ REQUIRE(container.get() == 0);
+
+ container.set_range(UINT8Model::range{1, 3, 1});
+ REQUIRE(container.get() == 1);
+ }
+ }
+
+ SECTION("Complex types")
+ {
+ using ComplexContainer = Model<std::string>;
+ const auto one = "one";
+ const auto two = "two";
+ const auto three = "three";
+ auto range = ComplexContainer::range{one, two, three};
+ const auto boundaries = ComplexContainer::Boundaries::Fixed;
+ SECTION("set")
+ {
+
+ auto container = ComplexContainer{range, boundaries};
+
+ REQUIRE(container.get() == one);
+ container.set(two);
+ REQUIRE(container.get() == two);
+ }
+
+ SECTION("check step")
+ {
+ auto container = ComplexContainer{range, boundaries};
+
+ REQUIRE(container.get() == one);
+ container.next();
+ REQUIRE(container.get() == two);
+ }
+
+ SECTION("Check boundaries")
+ {
+ SECTION("Fixed")
+ {
+ auto container = ComplexContainer{range, boundaries};
+
+ REQUIRE(container.get() == one);
+ container.previous();
+ REQUIRE(container.get() == one);
+
+ container.set(three);
+ REQUIRE(container.get() == three);
+ container.next();
+ REQUIRE(container.get() == three);
+ }
+
+ SECTION("Continuous")
+ {
+ auto container = ComplexContainer{range, ComplexContainer::Boundaries::Continuous};
+
+ REQUIRE(container.get() == one);
+ container.previous();
+ REQUIRE(container.get() == three);
+
+ container.set(three);
+ REQUIRE(container.get() == three);
+ container.next();
+ REQUIRE(container.get() == one);
+ }
+ }
+
+ SECTION("is_min/is_max")
+ {
+ auto container = ComplexContainer{range, boundaries};
+
+ REQUIRE(container.is_min());
+ REQUIRE_FALSE(container.is_max());
+
+ container.next();
+ REQUIRE_FALSE(container.is_min());
+ REQUIRE_FALSE(container.is_max());
+
+ container.set(three);
+ REQUIRE_FALSE(container.is_min());
+ REQUIRE(container.is_max());
+ }
+
+ SECTION("set_range")
+ {
+ auto container = ComplexContainer{range, boundaries};
+
+ REQUIRE(container.get() == one);
+
+ container.set_range(ComplexContainer::range{"two", "three", "four"});
+ REQUIRE(container.get() == two);
+ }
+ }
+}
M module-bsp/board/rt1051/bsp/audio/CodecMAX98090.hpp => module-bsp/board/rt1051/bsp/audio/CodecMAX98090.hpp +4 -2
@@ 8,6 8,8 @@
#include "drivers/i2c/DriverI2C.hpp"
#include <cstdint>
+#include <cstdint>
+
class CodecParamsMAX98090 : public CodecParams
{
public:
@@ 66,8 68,8 @@ class CodecParamsMAX98090 : public CodecParams
bool micBiasEnable = false;
std::uint8_t playbackPathGain = 0;
std::uint8_t playbackPathAtten = 0;
- InputPath inputPath = InputPath::None;
- OutputPath outputPath = OutputPath::None;
+ InputPath inputPath = InputPath::None;
+ OutputPath outputPath = OutputPath::None;
};
class CodecMAX98090 : public Codec
M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +2 -3
@@ 9,7 9,7 @@
#include <application-bell-background-sounds/ApplicationBellBackgroundSounds.hpp>
#include <application-bell-bedtime/ApplicationBellBedtime.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>
-#include <application-bell-meditation-timer/ApplicationBellMeditationTimer.hpp>
+#include <application-bell-meditation-timer/MeditationTimer.hpp>
#include <application-bell-settings/ApplicationBellSettings.hpp>
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>
@@ 113,8 113,7 @@ int main()
app::CreateLauncher<app::ApplicationBellOnBoarding>(app::applicationBellOnBoardingName));
applications.push_back(
app::CreateLauncher<app::ApplicationBellBackgroundSounds>(app::applicationBellBackgroundSoundsName));
- applications.push_back(
- app::CreateLauncher<app::ApplicationBellMeditationTimer>(app::applicationBellMeditationTimerName));
+ applications.push_back(app::CreateLauncher<app::MeditationTimer>(app::MeditationTimer::defaultName));
// start application manager
return sysmgr->RunSystemService(
std::make_shared<app::manager::ApplicationManager>(
M products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsTimerSelectWindow.cpp => products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsTimerSelectWindow.cpp +6 -6
@@ 86,20 86,20 @@ namespace gui
{
auto range = presenter->getTimerValuesRange();
- spinner = new UTF8Spinner(toUTF8Range(range), Boundaries::Fixed);
+ spinner = new StringSpinner(toUTF8Range(range), Boundaries::Fixed);
spinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
spinner->setFont(bgSoundsStyle::timerValueFont);
spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
spinner->setEdges(RectangleEdge::None);
spinner->setFocusEdges(RectangleEdge::None);
auto currentValue = timerValueToUTF8(presenter->getCurrentTimerValue());
- spinner->setCurrentValue(std::move(currentValue));
+ spinner->set_value(std::move(currentValue));
spinner->onValueChanged = [this](const auto &) {
- body->setMinMaxArrowsVisibility(spinner->isAtMin(), spinner->isAtMax());
+ body->setMinMaxArrowsVisibility(spinner->is_min(), spinner->is_max());
updateBottomDescription();
};
body->getCenterBox()->addWidget(spinner);
- body->setMinMaxArrowsVisibility(spinner->isAtMin(), spinner->isAtMax());
+ body->setMinMaxArrowsVisibility(spinner->is_min(), spinner->is_max());
}
void BGSoundsTimerSelectWindow::createBottomDescription()
@@ 117,7 117,7 @@ namespace gui
}
void BGSoundsTimerSelectWindow::updateBottomDescription()
{
- const auto currentVal = spinner->getCurrentValue();
+ const auto currentVal = spinner->value();
bottomDescription->setText(utils::language::getCorrectMinutesNumeralForm(UTF8ToTimerValue(currentVal).count()));
const bool isDescriptionVisible = UTF8ToTimerValue(currentVal) != offValue;
@@ 158,7 158,7 @@ namespace gui
return true;
}
if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
- auto currentValue = UTF8ToTimerValue(spinner->getCurrentValue());
+ auto currentValue = UTF8ToTimerValue(spinner->value());
presenter->setTimerValue(currentValue);
auto audioSwitchData = std::make_unique<BGSoundsSwitchData>(std::move(audioContext));
M products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsTimerSelectWindow.hpp => products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsTimerSelectWindow.hpp +1 -1
@@ 18,7 18,7 @@ namespace gui
{
std::unique_ptr<app::bgSounds::BGSoundsTimerSelectContract::Presenter> presenter;
BellBaseLayout *body = nullptr;
- UTF8Spinner *spinner = nullptr;
+ StringSpinner *spinner = nullptr;
Text *bottomDescription = nullptr;
std::unique_ptr<BGSoundsAudioContext> audioContext;
M products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsVolumeWindow.cpp => products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsVolumeWindow.cpp +6 -6
@@ 36,19 36,19 @@ namespace gui
topMessage->drawUnderline(false);
auto data = presenter->getVolumeData();
- spinner = new UIntegerSpinner({static_cast<UIntegerSpinner::Type>(data.min),
- static_cast<UIntegerSpinner::Type>(data.max),
- static_cast<UIntegerSpinner::Type>(data.step)},
+ spinner = new UIntegerSpinner({static_cast<UIntegerSpinner::value_type>(data.min),
+ static_cast<UIntegerSpinner::value_type>(data.max),
+ static_cast<UIntegerSpinner::value_type>(data.step)},
Boundaries::Fixed);
spinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::center_layout_h);
spinner->setFont(bgSoundsStyle::valumeValueFont);
spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
spinner->setFocusEdges(RectangleEdge::None);
- spinner->setCurrentValue(static_cast<UIntegerSpinner::Type>(presenter->getVolume()));
+ spinner->set_value(static_cast<UIntegerSpinner::value_type>(presenter->getVolume()));
body->getCenterBox()->addWidget(spinner);
spinner->onValueChanged = [this](const auto &value) { presenter->setVolume(value); };
- body->setMinMaxArrowsVisibility(spinner->getCurrentValue() == data.min, spinner->getCurrentValue() == data.max);
+ body->setMinMaxArrowsVisibility(spinner->value() == data.min, spinner->value() == data.max);
setFocusItem(body);
body->resize();
@@ 63,7 63,7 @@ namespace gui
resetTimer();
auto data = presenter->getVolumeData();
const auto ret = body->onInput(inputEvent);
- const auto selectedVal = spinner->getCurrentValue();
+ const auto selectedVal = spinner->value();
body->setMinMaxArrowsVisibility(selectedVal == data.min, selectedVal == data.max);
return ret;
}
M products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp +2 -2
@@ 7,7 7,7 @@
#include <application-bell-background-sounds/ApplicationBellBackgroundSounds.hpp>
#include <application-bell-bedtime/ApplicationBellBedtime.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>
-#include <application-bell-meditation-timer/ApplicationBellMeditationTimer.hpp>
+#include <application-bell-meditation-timer/MeditationTimer.hpp>
#include <application-bell-settings/ApplicationBellSettings.hpp>
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>
@@ 49,7 49,7 @@ namespace gui
addAppMenu(utils::translate("app_bellmain_alarm"), app::applicationBellAlarmName);
addAppMenu(utils::translate("app_bellmain_power_nap"), app::applicationBellPowerNapName);
addAppMenu(utils::translate("app_bellmain_background_sounds"), app::applicationBellBackgroundSoundsName);
- addAppMenu(utils::translate("app_bellmain_meditation_timer"), app::applicationBellMeditationTimerName);
+ addAppMenu(utils::translate("app_bellmain_meditation_timer"), app::MeditationTimer::defaultName);
addAppMenu(utils::translate("app_bellmain_bedtime"), app::applicationBellBedtimeName);
addAppMenu(utils::translate("app_bellmain_settings"), app::applicationBellSettingsName);
M products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt => products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt +11 -6
@@ 18,18 18,24 @@ target_include_directories(application-bell-meditation-timer
target_sources(application-bell-meditation-timer
PRIVATE
- ApplicationBellMeditationTimer.cpp
- presenter/IntervalChimePresenter.cpp
+ MeditationTimer.cpp
+ models/ChimeInterval.cpp
+ models/ChimeVolume.cpp
+ models/StartDelay.cpp
presenter/MeditationProgressPresenter.cpp
presenter/MeditationTimerPresenter.cpp
presenter/ReadyGoingPresenter.cpp
- presenter/SessionEndedPresenter.cpp
- windows/IntervalChimeWindow.cpp
+ presenter/SessionEndedPresenter.cpp
+ presenter/SettingsPresenter.cpp
+ presenter/StatisticsPresenter.cpp
+ windows/MeditationMainWindow.cpp
windows/MeditationRunningWindow.cpp
windows/MeditationTimerWindow.cpp
windows/ReadyGoingWindow.cpp
+ windows/SettingsWindow.cpp
+ windows/StatisticsWindow.cpp
PUBLIC
- include/application-bell-meditation-timer/ApplicationBellMeditationTimer.hpp
+ include/application-bell-meditation-timer/MeditationTimer.hpp
)
target_link_libraries(application-bell-meditation-timer
@@ 38,7 44,6 @@ target_link_libraries(application-bell-meditation-timer
bell::audio
bell::app-common
bell::app-main
- bellgui
service-appmgr
service-time
PUBLIC
R products/BellHybrid/apps/application-bell-meditation-timer/ApplicationBellMeditationTimer.cpp => products/BellHybrid/apps/application-bell-meditation-timer/MeditationTimer.cpp +50 -23
@@ 1,11 1,21 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "ApplicationBellMeditationTimer.hpp"
-#include "windows/IntervalChimeWindow.hpp"
+#include "MeditationTimer.hpp"
+#include "MeditationCommon.hpp"
+#include "windows/MeditationMainWindow.hpp"
#include "windows/MeditationRunningWindow.hpp"
#include "windows/MeditationTimerWindow.hpp"
#include "windows/ReadyGoingWindow.hpp"
+#include "windows/SettingsWindow.hpp"
+#include "windows/StatisticsWindow.hpp"
+
+#include "models/ChimeVolume.hpp"
+#include "models/StartDelay.hpp"
+#include "models/ChimeInterval.hpp"
+
+#include "presenter/SettingsPresenter.hpp"
+#include "presenter/StatisticsPresenter.hpp"
#include <common/models/TimeModel.hpp>
#include <common/windows/BellFinishedWindow.hpp>
@@ 13,48 23,65 @@
namespace app
{
- ApplicationBellMeditationTimer::ApplicationBellMeditationTimer(std::string name,
- std::string parent,
- StatusIndicators statusIndicators,
- StartInBackground startInBackground,
- uint32_t stackDepth)
+ MeditationTimer::MeditationTimer(std::string name,
+ std::string parent,
+ StatusIndicators statusIndicators,
+ StartInBackground startInBackground,
+ uint32_t stackDepth)
: Application(std::move(name), std::move(parent), statusIndicators, startInBackground, stackDepth)
{}
- ApplicationBellMeditationTimer::~ApplicationBellMeditationTimer() = default;
-
- sys::ReturnCodes ApplicationBellMeditationTimer::InitHandler()
+ sys::ReturnCodes MeditationTimer::InitHandler()
{
auto ret = Application::InitHandler();
if (ret != sys::ReturnCodes::Success) {
return ret;
}
+ chimeIntervalModel = std::make_unique<meditation::models::ChimeInterval>(this);
+ chimeVolumeModel = std::make_unique<meditation::models::ChimeVolume>(this);
+ startDelayModel = std::make_unique<meditation::models::StartDelay>(this);
+
createUserInterface();
return sys::ReturnCodes::Success;
}
- void ApplicationBellMeditationTimer::createUserInterface()
+ void MeditationTimer::createUserInterface()
{
- windowsFactory.attach(gui::name::window::main_window, [this](ApplicationCommon *app, const std::string &name) {
- auto presenter = std::make_unique<app::meditation::MeditationTimerPresenter>(app, settings.get());
- return std::make_unique<gui::MeditationTimerWindow>(app, std::move(presenter));
+ windowsFactory.attach(
+ meditation::MeditationMainWindow::defaultName, [this](ApplicationCommon *app, const std::string &name) {
+ auto presenter = std::make_unique<app::meditation::MeditationTimerPresenter>(app, settings.get());
+ return std::make_unique<meditation::MeditationMainWindow>(app);
+ });
+
+ windowsFactory.attach(meditation::SettingsWindow::name,
+ [this](ApplicationCommon *app, const std::string &name) {
+ auto presenter = std::make_unique<app::meditation::SettingsPresenter>(
+ app, *chimeIntervalModel, *chimeVolumeModel, *startDelayModel);
+ return std::make_unique<meditation::SettingsWindow>(app, std::move(presenter));
+ });
+
+ windowsFactory.attach(meditation::StatisticsWindow::name, [](ApplicationCommon *app, const std::string &name) {
+ auto presenter = std::make_unique<app::meditation::StatisticsPresenter>();
+ return std::make_unique<meditation::StatisticsWindow>(app, std::move(presenter));
});
+
windowsFactory.attach(
- gui::name::window::intervalChime, [this](ApplicationCommon *app, const std::string &name) {
- auto presenter = std::make_unique<app::meditation::IntervalChimePresenter>(app, settings.get());
- return std::make_unique<gui::IntervalChimeWindow>(app, std::move(presenter));
+ meditation::MeditationTimerWindow::name, [this](ApplicationCommon *app, const std::string &name) {
+ auto presenter = std::make_unique<app::meditation::MeditationTimerPresenter>(app, settings.get());
+ return std::make_unique<meditation::MeditationTimerWindow>(app, std::move(presenter));
});
- windowsFactory.attach(gui::name::window::readyGoing, [](ApplicationCommon *app, const std::string &name) {
- auto presenter = std::make_unique<app::meditation::ReadyGoingPresenter>(app);
+
+ windowsFactory.attach(meditation::windows::readyGoing, [this](ApplicationCommon *app, const std::string &name) {
+ auto presenter = std::make_unique<app::meditation::ReadyGoingPresenter>(app, *startDelayModel);
return std::make_unique<gui::ReadyGoingWindow>(app, std::move(presenter));
});
- windowsFactory.attach(gui::name::window::meditationProgress,
+ windowsFactory.attach(meditation::windows::meditationProgress,
[this](ApplicationCommon *app, const std::string &name) {
auto timeModel = std::make_unique<app::TimeModel>();
auto presenter = std::make_unique<app::meditation::MeditationProgressPresenter>(
- app, settings.get(), std::move(timeModel));
+ app, settings.get(), std::move(timeModel), *chimeIntervalModel);
return std::make_unique<gui::MeditationRunningWindow>(app, std::move(presenter));
});
windowsFactory.attach(gui::window::session_paused::sessionPaused,
@@ 73,8 100,7 @@ namespace app
gui::popup::ID::BedtimeNotification});
}
- sys::MessagePointer ApplicationBellMeditationTimer::DataReceivedHandler(sys::DataMessage *msgl,
- sys::ResponseMessage *resp)
+ sys::MessagePointer MeditationTimer::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
{
auto retMsg = Application::DataReceivedHandler(msgl);
if (auto response = dynamic_cast<sys::ResponseMessage *>(retMsg.get());
@@ 84,4 110,5 @@ namespace app
return handleAsyncResponse(resp);
}
+ MeditationTimer::~MeditationTimer() = default;
} // namespace app
A products/BellHybrid/apps/application-bell-meditation-timer/data/Contract.hpp => products/BellHybrid/apps/application-bell-meditation-timer/data/Contract.hpp +27 -0
@@ 0,0 1,27 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <apps-common/BasePresenter.hpp>
+#include <widgets/ListItemProvider.hpp>
+
+namespace app::meditation::contract
+{
+ class View
+ {
+ public:
+ virtual ~View() noexcept = default;
+ };
+
+ class Presenter : public BasePresenter<View>
+ {
+ public:
+ virtual ~Presenter() noexcept = default;
+ virtual auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> = 0;
+ virtual void loadData() = 0;
+ virtual void saveData() = 0;
+ virtual void eraseProviderData() = 0;
+ virtual void handleEnter() = 0;
+ };
+} // namespace app::meditation::contract
M products/BellHybrid/apps/application-bell-meditation-timer/data/MeditationCommon.hpp => products/BellHybrid/apps/application-bell-meditation-timer/data/MeditationCommon.hpp +7 -1
@@ 5,6 5,12 @@
namespace app::meditation
{
+ namespace windows
+ {
+ static constexpr auto meditationProgress = "MeditationProgress";
+ static constexpr auto readyGoing = "MeditationReadyGoing";
+ static constexpr auto sessionEnded = "MeditationSessionEnded";
+ }; // namespace windows
+
constexpr auto meditationDBRecordName = "MeditationTimer";
- constexpr auto intervalDBRecordName = "IntervalChime";
} // namespace app::meditation
R products/BellHybrid/apps/application-bell-meditation-timer/include/application-bell-meditation-timer/ApplicationBellMeditationTimer.hpp => products/BellHybrid/apps/application-bell-meditation-timer/include/application-bell-meditation-timer/MeditationTimer.hpp +20 -17
@@ 5,28 5,26 @@
#include <Application.hpp>
-namespace gui::name::window
+namespace app::meditation::models
{
- inline constexpr auto intervalChime = "IntervalChimeWindow";
- inline constexpr auto meditationProgress = "MeditationProgressWindow";
- inline constexpr auto meditationTimer = "MeditationTimerWindow";
- inline constexpr auto readyGoing = "ReadyGoingWindow";
- inline constexpr auto sessionEnded = "SessionEndedWindow";
-} // namespace gui::name::window
+ class ChimeInterval;
+ class ChimeVolume;
+ class StartDelay;
+} // namespace app::meditation::models
namespace app
{
- inline constexpr auto applicationBellMeditationTimerName = "ApplicationBellMeditationTimer";
-
- class ApplicationBellMeditationTimer : public Application
+ class MeditationTimer : public Application
{
public:
- ApplicationBellMeditationTimer(std::string name = applicationBellMeditationTimerName,
- std::string parent = "",
- StatusIndicators statusIndicators = StatusIndicators{},
- StartInBackground startInBackground = {false},
- uint32_t stackDepth = 4096 * 2);
- ~ApplicationBellMeditationTimer();
+ static constexpr auto defaultName = "ApplicationMeditationTimer";
+
+ explicit MeditationTimer(std::string name = defaultName,
+ std::string parent = "",
+ StatusIndicators statusIndicators = StatusIndicators{},
+ StartInBackground startInBackground = {false},
+ uint32_t stackDepth = 4096 * 2);
+ ~MeditationTimer();
sys::ReturnCodes InitHandler() override;
@@ 40,9 38,14 @@ namespace app
{
return sys::ReturnCodes::Success;
}
+
+ private:
+ std::unique_ptr<app::meditation::models::ChimeInterval> chimeIntervalModel;
+ std::unique_ptr<app::meditation::models::ChimeVolume> chimeVolumeModel;
+ std::unique_ptr<app::meditation::models::StartDelay> startDelayModel;
};
- template <> struct ManifestTraits<ApplicationBellMeditationTimer>
+ template <> struct ManifestTraits<MeditationTimer>
{
static auto GetManifest() -> manager::ApplicationManifest
{
A products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeInterval.cpp => products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeInterval.cpp +40 -0
@@ 0,0 1,40 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ChimeInterval.hpp"
+#include <Utils.hpp>
+
+namespace
+{
+ constexpr auto chime_interval_db = "chime_interval";
+
+ /// Fraction numbers are stored using "n/d" format.
+ app::list_items::FractionData to_fraction_data(const std::string &str)
+ {
+ const std::string delimiter = "/";
+ std::string nominator = str.substr(0, str.find(delimiter));
+ std::string denominator = str.substr(str.find(delimiter) + 1);
+ return {utils::getNumericValue<int>(nominator), utils::getNumericValue<int>(denominator)};
+ }
+ std::string from_fraction_data(const app::list_items::FractionData &data)
+ {
+ return std::to_string(data.nominator) + "/" + std::to_string(data.denominator);
+ }
+} // namespace
+
+namespace app::meditation::models
+{
+ void ChimeInterval::setValue(app::list_items::FractionData value)
+ {
+ settings.setValue(chime_interval_db, from_fraction_data(value));
+ }
+ app::list_items::FractionData ChimeInterval::getValue() const
+ {
+ const auto value = settings.getValue(chime_interval_db);
+ if (value.empty()) {
+ /// If not found, return 1/1 which corresponds to 'OFF'
+ return {1, 1};
+ }
+ return to_fraction_data(value);
+ }
+} // namespace app::meditation::models
A products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeInterval.hpp => products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeInterval.hpp +19 -0
@@ 0,0 1,19 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <common/models/SettingsModel.hpp>
+#include <common/widgets/list_items/Fraction.hpp>
+
+namespace app::meditation::models
+{
+ class ChimeInterval : public gui::SettingsModel<list_items::FractionData>
+ {
+ public:
+ using SettingsModel::SettingsModel;
+
+ void setValue(list_items::FractionData value) override;
+ list_items::FractionData getValue() const override;
+ };
+} // namespace app::meditation::models
A products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeVolume.cpp => products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeVolume.cpp +18 -0
@@ 0,0 1,18 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ChimeVolume.hpp"
+
+namespace app::meditation::models
+{
+
+ void ChimeVolume::setValue(std::uint8_t value)
+ {
+ /// Dummy implementation.
+ }
+ std::uint8_t ChimeVolume::getValue() const
+ {
+ /// Dummy implementation
+ return 5;
+ }
+} // namespace app::meditation::models
A products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeVolume.hpp => products/BellHybrid/apps/application-bell-meditation-timer/models/ChimeVolume.hpp +18 -0
@@ 0,0 1,18 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <common/models/SettingsModel.hpp>
+
+namespace app::meditation::models
+{
+ class ChimeVolume : public gui::SettingsModel<std::uint8_t>
+ {
+ public:
+ using SettingsModel::SettingsModel;
+
+ void setValue(std::uint8_t value) override;
+ std::uint8_t getValue() const override;
+ };
+} // namespace app::meditation::models
A products/BellHybrid/apps/application-bell-meditation-timer/models/StartDelay.cpp => products/BellHybrid/apps/application-bell-meditation-timer/models/StartDelay.cpp +27 -0
@@ 0,0 1,27 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "StartDelay.hpp"
+#include <Utils.hpp>
+
+namespace
+{
+ constexpr auto start_delay_db = "start_delay";
+} // namespace
+
+namespace app::meditation::models
+{
+
+ void StartDelay::setValue(std::uint8_t value)
+ {
+ settings.setValue(start_delay_db, std::to_string(value));
+ }
+ std::uint8_t StartDelay::getValue() const
+ {
+ const auto value = settings.getValue(start_delay_db);
+ if (value.empty()) {
+ return 0;
+ }
+ return utils::getNumericValue<std::uint32_t>(value);
+ }
+} // namespace app::meditation::models
A products/BellHybrid/apps/application-bell-meditation-timer/models/StartDelay.hpp => products/BellHybrid/apps/application-bell-meditation-timer/models/StartDelay.hpp +18 -0
@@ 0,0 1,18 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <common/models/SettingsModel.hpp>
+
+namespace app::meditation::models
+{
+ class StartDelay : public gui::SettingsModel<std::uint8_t>
+ {
+ public:
+ using SettingsModel::SettingsModel;
+
+ void setValue(std::uint8_t value) override;
+ std::uint8_t getValue() const override;
+ };
+} // namespace app::meditation::models
D products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.cpp +0 -104
@@ 1,104 0,0 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "ApplicationBellMeditationTimer.hpp"
-#include "IntervalChimePresenter.hpp"
-#include "MeditationCommon.hpp"
-#include "MeditationStyle.hpp"
-
-#include <service-db/Settings.hpp>
-
-namespace app::meditation
-{
- constexpr auto intervalsList = {1, 2, 5, 10, 15, 30};
-
- IntervalChimePresenter::IntervalChimePresenter(app::ApplicationCommon *app, settings::Settings *settings)
- : app{app}, settings{settings}
- {
- initIntervalOptions();
- }
-
- std::vector<std::string> IntervalChimePresenter::getIntervals() const
- {
- std::vector<std::string> intervalNames;
- for (auto const &option : intervalOptions) {
- intervalNames.push_back(option.second);
- }
- return intervalNames;
- }
-
- std::string IntervalChimePresenter::getCurrentInterval() const
- {
- const auto value = settings->getValue(intervalDBRecordName, settings::SettingsScope::AppLocal);
- for (auto const &option : intervalOptions) {
- if (utils::to_string(option.first.count()) == value) {
- return option.second;
- }
- }
- // If not found, return "None"
- return intervalOptions.at(0).second;
- }
-
- std::string IntervalChimePresenter::getTimeUnitName(std::string value)
- {
- using namespace app::meditationStyle::mtStyle::list;
- for (auto const &option : intervalOptions) {
- if (option.second == value) {
- if (option.first == std::chrono::minutes{0}) {
- return "";
- }
- else if (option.first == std::chrono::minutes{1}) {
- return utils::translate(timeUnitSingular);
- }
- else if (option.first == std::chrono::minutes{2}) {
- return utils::translate(timeUnitPlural);
- }
- else {
- return utils::translate(timeUnitGenitive);
- }
- }
- }
- return "";
- }
-
- void IntervalChimePresenter::activate(std::string value)
- {
- for (auto const &option : intervalOptions) {
- if (option.second == value) {
- settings->setValue(
- intervalDBRecordName, utils::to_string(option.first.count()), settings::SettingsScope::AppLocal);
- reinterpret_cast<app::Application *>(app)->suspendIdleTimer();
- app->switchWindow(gui::name::window::readyGoing);
- break;
- }
- }
- }
-
- void IntervalChimePresenter::initIntervalOptions()
- {
- intervalOptions.push_back({std::chrono::minutes{0}, utils::translate("app_bell_meditation_interval_none")});
-
- const auto duration =
- utils::getNumericValue<int>(settings->getValue(meditationDBRecordName, settings::SettingsScope::AppLocal));
- if (duration == 1) {
- settings->setValue(intervalDBRecordName, utils::to_string(0), settings::SettingsScope::AppLocal);
- reinterpret_cast<app::Application *>(app)->suspendIdleTimer();
- app->switchWindow(gui::name::window::readyGoing);
- return;
- }
-
- for (const auto &interval : intervalsList) {
- if (interval < duration) {
- intervalOptions.push_back({std::chrono::minutes{interval}, getIntervalString(interval)});
- }
- }
- }
-
- std::string IntervalChimePresenter::getIntervalString(std::uint32_t value)
- {
- const std::string toReplace = "%0";
- std::string temp = utils::translate("app_bell_meditation_interval_every_x_minutes");
- temp.replace(temp.find(toReplace), toReplace.size(), std::to_string(value));
- return temp;
- }
-} // namespace app::meditation
D products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.hpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/IntervalChimePresenter.hpp +0 -54
@@ 1,54 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include <apps-common/ApplicationCommon.hpp>
-#include <apps-common/BasePresenter.hpp>
-
-namespace app
-{
- class ApplicationCommon;
-}
-
-namespace app::meditation
-{
- class IntervalChimeContract
- {
- public:
- class View
- {
- public:
- virtual ~View() = default;
- };
-
- class Presenter : public BasePresenter<IntervalChimeContract::View>
- {
- public:
- virtual ~Presenter() noexcept = default;
- virtual std::vector<std::string> getIntervals() const = 0;
- virtual std::string getCurrentInterval() const = 0;
- virtual std::string getTimeUnitName(std::string value) = 0;
- virtual void activate(std::string value) = 0;
- };
- };
-
- class IntervalChimePresenter : public IntervalChimeContract::Presenter
- {
- public:
- IntervalChimePresenter(app::ApplicationCommon *app, settings::Settings *settings);
-
- std::vector<std::string> getIntervals() const override;
- std::string getCurrentInterval() const override;
- std::string getTimeUnitName(std::string value) override;
- void activate(std::string value) override;
-
- private:
- app::ApplicationCommon *app = nullptr;
- settings::Settings *settings = nullptr;
- std::vector<std::pair<std::chrono::minutes, const std::string>> intervalOptions;
-
- void initIntervalOptions();
- std::string getIntervalString(std::uint32_t value);
- };
-} // namespace app::meditation
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationProgressPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationProgressPresenter.cpp +14 -7
@@ 1,32 1,39 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "ApplicationBellMeditationTimer.hpp"
+#include "MeditationTimer.hpp"
#include "MeditationCommon.hpp"
#include "MeditationProgressPresenter.hpp"
+#include "models/ChimeInterval.hpp"
#include <common/models/TimeModel.hpp>
#include <common/windows/BellFinishedWindow.hpp>
#include <common/windows/SessionPausedWindow.hpp>
-#include <service-appmgr/Controller.hpp>
#include <service-db/Settings.hpp>
namespace
{
constexpr std::chrono::minutes emptyValue{0};
+
+ std::chrono::seconds to_interval(const double ratio, std::chrono::minutes total_duration)
+ {
+ const long interval = std::chrono::seconds{total_duration}.count() * ratio;
+ return std::chrono::seconds{interval};
+ }
} // namespace
namespace app::meditation
{
MeditationProgressPresenter::MeditationProgressPresenter(app::ApplicationCommon *app,
settings::Settings *settings,
- std::unique_ptr<AbstractTimeModel> timeModel)
- : app{app}, settings{settings}, timeModel{std::move(timeModel)}
+ std::unique_ptr<AbstractTimeModel> timeModel,
+ models::ChimeInterval &chimeIntervalModel)
+ : app{app}, settings{settings}, timeModel{std::move(timeModel)}, chimeIntervalModel{chimeIntervalModel}
{
duration = std::chrono::minutes{
utils::getNumericValue<int>(settings->getValue(meditationDBRecordName, settings::SettingsScope::AppLocal))};
- interval = std::chrono::minutes{
- utils::getNumericValue<int>(settings->getValue(intervalDBRecordName, settings::SettingsScope::AppLocal))};
+
+ interval = to_interval(chimeIntervalModel.getValue().to_double(), duration);
}
void MeditationProgressPresenter::setTimer(std::unique_ptr<app::TimerWithCallbacks> &&_timer)
@@ 46,7 53,7 @@ namespace app::meditation
void MeditationProgressPresenter::start()
{
reinterpret_cast<app::Application *>(app)->suspendIdleTimer();
- timer->reset(std::chrono::seconds(duration), std::chrono::seconds(interval));
+ timer->reset(std::chrono::seconds(duration), interval);
timer->start();
}
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationProgressPresenter.hpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationProgressPresenter.hpp +9 -2
@@ 28,6 28,11 @@ namespace settings
namespace app::meditation
{
+ namespace models
+ {
+ class ChimeInterval;
+ } // namespace models
+
class MeditationProgressContract
{
public:
@@ 62,8 67,9 @@ namespace app::meditation
settings::Settings *settings = nullptr;
std::unique_ptr<app::TimerWithCallbacks> timer;
std::unique_ptr<AbstractTimeModel> timeModel;
+ models::ChimeInterval &chimeIntervalModel;
std::chrono::minutes duration;
- std::chrono::minutes interval;
+ std::chrono::seconds interval;
static constexpr auto endWindowTimeout = std::chrono::seconds{5};
@@ 73,7 79,8 @@ namespace app::meditation
public:
MeditationProgressPresenter(app::ApplicationCommon *app,
settings::Settings *settings,
- std::unique_ptr<AbstractTimeModel> timeModel);
+ std::unique_ptr<AbstractTimeModel> timeModel,
+ models::ChimeInterval &chimeIntervalModel);
void setTimer(std::unique_ptr<app::TimerWithCallbacks> &&_timer) override;
void handleUpdateTimeEvent() override;
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationTimerPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationTimerPresenter.cpp +7 -7
@@ 1,7 1,7 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "ApplicationBellMeditationTimer.hpp"
+#include "MeditationTimer.hpp"
#include "MeditationCommon.hpp"
#include "MeditationStyle.hpp"
#include "MeditationTimerPresenter.hpp"
@@ 23,25 23,25 @@ namespace app::meditation
: app{app}, settings{settings}
{}
- std::uint32_t MeditationTimerPresenter::getMinValue()
+ std::uint8_t MeditationTimerPresenter::getMinValue()
{
return spinnerMin;
}
- std::uint32_t MeditationTimerPresenter::getMaxValue()
+ std::uint8_t MeditationTimerPresenter::getMaxValue()
{
return spinnerMax;
}
- std::uint32_t MeditationTimerPresenter::getStepValue()
+ std::uint8_t MeditationTimerPresenter::getStepValue()
{
return spinnerStep;
}
- std::uint32_t MeditationTimerPresenter::getCurrentValue()
+ std::uint8_t MeditationTimerPresenter::getCurrentValue()
{
const auto value = settings->getValue(meditationDBRecordName, settings::SettingsScope::AppLocal);
- auto defTimer = utils::getNumericValue<std::uint32_t>(value);
+ auto defTimer = utils::getNumericValue<std::uint8_t>(value);
if (defTimer == emptyValue) {
defTimer = defaultValue;
}
@@ 65,6 65,6 @@ namespace app::meditation
void MeditationTimerPresenter::activate(std::uint32_t value)
{
settings->setValue(meditationDBRecordName, utils::to_string(value), settings::SettingsScope::AppLocal);
- app->switchWindow(gui::name::window::intervalChime);
+ app->switchWindow(windows::readyGoing);
}
} // namespace app::meditation
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationTimerPresenter.hpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationTimerPresenter.hpp +8 -8
@@ 31,10 31,10 @@ namespace app::meditation
{
public:
virtual ~Presenter() noexcept = default;
- virtual std::uint32_t getMinValue() = 0;
- virtual std::uint32_t getMaxValue() = 0;
- virtual std::uint32_t getStepValue() = 0;
- virtual std::uint32_t getCurrentValue() = 0;
+ virtual std::uint8_t getMinValue() = 0;
+ virtual std::uint8_t getMaxValue() = 0;
+ virtual std::uint8_t getStepValue() = 0;
+ virtual std::uint8_t getCurrentValue() = 0;
virtual std::string getTimeUnitName(std::uint32_t value) = 0;
virtual void activate(std::uint32_t value) = 0;
};
@@ 45,10 45,10 @@ namespace app::meditation
public:
MeditationTimerPresenter(app::ApplicationCommon *app, settings::Settings *settings);
- std::uint32_t getMinValue() override;
- std::uint32_t getMaxValue() override;
- std::uint32_t getStepValue() override;
- std::uint32_t getCurrentValue() override;
+ std::uint8_t getMinValue() override;
+ std::uint8_t getMaxValue() override;
+ std::uint8_t getStepValue() override;
+ std::uint8_t getCurrentValue() override;
std::string getTimeUnitName(std::uint32_t value) override;
void activate(std::uint32_t value) override;
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/ReadyGoingPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/ReadyGoingPresenter.cpp +10 -3
@@ 1,16 1,23 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "ApplicationBellMeditationTimer.hpp"
+#include "MeditationTimer.hpp"
+#include "MeditationCommon.hpp"
#include "ReadyGoingPresenter.hpp"
+#include "models/StartDelay.hpp"
namespace app::meditation
{
- ReadyGoingPresenter::ReadyGoingPresenter(app::ApplicationCommon *app) : app{app}
+ ReadyGoingPresenter::ReadyGoingPresenter(app::ApplicationCommon *app, const models::StartDelay &startDelayModel)
+ : app{app}, startDelayModel{startDelayModel}
{}
void ReadyGoingPresenter::activate()
{
- app->switchWindow(gui::name::window::meditationProgress);
+ app->switchWindow(windows::meditationProgress);
+ }
+ std::chrono::seconds ReadyGoingPresenter::getStartDelay()
+ {
+ return std::chrono::seconds{startDelayModel.getValue()};
}
} // namespace app::meditation
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/ReadyGoingPresenter.hpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/ReadyGoingPresenter.hpp +10 -2
@@ 13,6 13,11 @@ namespace app
namespace app::meditation
{
+ namespace models
+ {
+ class StartDelay;
+ } // namespace models
+
class ReadyGoingPresenterContract
{
public:
@@ 24,16 29,19 @@ namespace app::meditation
class Presenter : public BasePresenter<ReadyGoingPresenterContract::View>
{
public:
- virtual void activate() = 0;
+ virtual void activate() = 0;
+ virtual std::chrono::seconds getStartDelay() = 0;
};
};
class ReadyGoingPresenter : public ReadyGoingPresenterContract::Presenter
{
app::ApplicationCommon *app{};
+ const models::StartDelay &startDelayModel;
void activate() override;
+ std::chrono::seconds getStartDelay() override;
public:
- explicit ReadyGoingPresenter(app::ApplicationCommon *app);
+ ReadyGoingPresenter(app::ApplicationCommon *app, const models::StartDelay &startDelayModel);
};
} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.cpp +117 -0
@@ 0,0 1,117 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "SettingsPresenter.hpp"
+#include "MeditationMainWindow.hpp"
+
+#include "models/ChimeInterval.hpp"
+#include "models/ChimeVolume.hpp"
+#include "models/StartDelay.hpp"
+
+#include <ApplicationCommon.hpp>
+#include <common/widgets/list_items/Fraction.hpp>
+#include <common/widgets/list_items/Numeric.hpp>
+#include <common/windows/BellFinishedWindow.hpp>
+#include <common/LanguageUtils.hpp>
+#include <apps-common/InternalModel.hpp>
+#include <apps-common/widgets/spinners/Spinners.hpp>
+
+namespace app::list_items
+{
+ struct StartDelayFormatter
+ {
+ public:
+ StartDelayFormatter() : none(utils::translate("app_bell_meditation_interval_none"))
+ {}
+ std::string operator()(std::uint8_t value) const
+ {
+ return value == 0 ? none : std::to_string(value);
+ }
+
+ private:
+ std::string none;
+ };
+
+ using StartDelaySpinner = gui::UIntegerSpinnerWithFormatter<StartDelayFormatter>;
+ class StartDelay : public app::list_items::details::ListItemBase<StartDelaySpinner>
+ {
+ public:
+ StartDelay(spinner_type::range &&range,
+ gui::AbstractSettingsModel<spinner_type::value_type> &model,
+ const std::string &topDescription = "",
+ const std::string &bottomDescription = "")
+ : app::list_items::details::ListItemBase<spinner_type>(
+ std::move(range), model, topDescription, bottomDescription)
+ {}
+
+ private:
+ void control_bottom_description(const spinner_type::value_type &value) final
+ {
+ bottomText->setVisible(value != 0);
+ bottomText->setRichText(utils::language::getCorrectSecondsNumeralForm(value));
+ }
+ };
+
+} // namespace app::list_items
+
+namespace app::meditation
+{
+ using namespace gui;
+ SettingsPresenter::SettingsPresenter(app::ApplicationCommon *app,
+ models::ChimeInterval &chimeIntervalModel,
+ models::ChimeVolume &chimeVolumeModel,
+ models::StartDelay &startDelayModel)
+ : application{app}, chimeIntervalModel{chimeIntervalModel}, chimeVolumeModel{chimeVolumeModel},
+ startDelayModel{startDelayModel}
+ {
+ auto chimeInterval =
+ new list_items::Fraction{list_items::Fraction::spinner_type::range{{1, 1}, {1, 2}, {1, 3}, {1, 4}},
+ chimeIntervalModel,
+ utils::translate("app_bell_meditation_chime_interval"),
+ utils::translate("app_bell_meditation_chime_interval_bottom")};
+
+ auto startDelay = new list_items::StartDelay{list_items::StartDelay::spinner_type::range{0, 60, 1},
+ startDelayModel,
+ utils::translate("app_bell_meditation_start_delay"),
+ utils::translate("common_second_lower")};
+
+ auto chimeVolume = new list_items::Numeric{list_items::Numeric::spinner_type::range{1, 10, 1},
+ chimeVolumeModel,
+ utils::translate("app_bell_meditation_chime_volume")};
+
+ listItemsProvider =
+ std::make_shared<BellListItemProvider>(BellListItemProvider::Items{startDelay, chimeInterval, chimeVolume});
+
+ for (auto &item : listItemsProvider->getListItems()) {
+ item->setValue();
+ }
+ }
+ void SettingsPresenter::loadData()
+ {
+ for (auto &item : listItemsProvider->getListItems()) {
+ item->setValue();
+ }
+ }
+ void SettingsPresenter::saveData()
+ {
+ for (auto &item : listItemsProvider->getListItems()) {
+ item->getValue();
+ }
+ }
+ auto SettingsPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>
+ {
+ return listItemsProvider;
+ }
+ void SettingsPresenter::eraseProviderData()
+ {
+ listItemsProvider->clearData();
+ }
+ void SettingsPresenter::handleEnter()
+ {
+ saveData();
+ application->switchWindow(
+ window::bell_finished::defaultName,
+ BellFinishedWindowData::Factory::create("circle_success_big", MeditationMainWindow::defaultName));
+ }
+
+} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.hpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.hpp +44 -0
@@ 0,0 1,44 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "data/Contract.hpp"
+#include <common/BellListItemProvider.hpp>
+#include <memory>
+
+namespace app
+{
+ class ApplicationCommon;
+}
+
+namespace app::meditation
+{
+ namespace models
+ {
+ class ChimeInterval;
+ class ChimeVolume;
+ class StartDelay;
+ } // namespace models
+
+ class SettingsPresenter : public contract::Presenter
+ {
+ public:
+ SettingsPresenter(app::ApplicationCommon *app,
+ models::ChimeInterval &chimeIntervalModel,
+ models::ChimeVolume &chimeVolumeModel,
+ models::StartDelay &startDelayModel);
+ void loadData() override;
+ void saveData() override;
+ auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
+ void eraseProviderData() override;
+ void handleEnter() override;
+
+ private:
+ ApplicationCommon *application{};
+ models::ChimeInterval &chimeIntervalModel;
+ models::ChimeVolume &chimeVolumeModel;
+ models::StartDelay &startDelayModel;
+ std::shared_ptr<BellListItemProvider> listItemsProvider;
+ };
+} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/presenter/StatisticsPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/StatisticsPresenter.cpp +22 -0
@@ 0,0 1,22 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "StatisticsPresenter.hpp"
+
+namespace app::meditation
+{
+ StatisticsPresenter::StatisticsPresenter()
+ {}
+ void StatisticsPresenter::eraseProviderData()
+ {}
+ void StatisticsPresenter::loadData()
+ {}
+ void StatisticsPresenter::saveData()
+ {}
+ auto StatisticsPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>
+ {
+ return std::shared_ptr<gui::ListItemProvider>();
+ }
+ void StatisticsPresenter::handleEnter()
+ {}
+} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/presenter/StatisticsPresenter.hpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/StatisticsPresenter.hpp +23 -0
@@ 0,0 1,23 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "data/Contract.hpp"
+#include <memory>
+
+namespace app::meditation
+{
+ class StatisticsPresenter : public contract::Presenter
+ {
+ public:
+ StatisticsPresenter();
+ auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
+ void loadData() override;
+ void saveData() override;
+ void eraseProviderData() override;
+ void handleEnter() override;
+
+ private:
+ };
+} // namespace app::meditation
D products/BellHybrid/apps/application-bell-meditation-timer/windows/IntervalChimeWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/IntervalChimeWindow.cpp +0 -83
@@ 1,83 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "ApplicationBellMeditationTimer.hpp"
-#include "IntervalChimeWindow.hpp"
-#include "MeditationStyle.hpp"
-
-namespace gui
-{
- IntervalChimeWindow::IntervalChimeWindow(
- app::ApplicationCommon *app,
- std::unique_ptr<app::meditation::IntervalChimeContract::Presenter> &&windowPresenter)
- : AppWindow(app, gui::name::window::intervalChime), presenter{std::move(windowPresenter)}
- {
- presenter->attach(this);
- buildInterface();
- }
-
- void IntervalChimeWindow::buildInterface()
- {
- AppWindow::buildInterface();
-
- statusBar->setVisible(false);
- header->setTitleVisibility(false);
- navBar->setVisible(false);
-
- body = new BellBaseLayout(this, 0, 0, style::window_width, style::window_height, true);
-
- auto topMessage = new TextFixedSize(body->firstBox);
- topMessage->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::outer_layouts_h);
- topMessage->setFont(style::window::font::largelight);
- topMessage->setEdges(gui::RectangleEdge::None);
- topMessage->activeItem = false;
- topMessage->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
- topMessage->setText(utils::translate("app_bell_meditation_interval_chime"));
- topMessage->drawUnderline(false);
-
- auto titles = presenter->getIntervals();
- spinner = new UTF8Spinner({titles.begin(), titles.end()}, Boundaries::Fixed);
- spinner->onValueChanged = [this](const auto val) { this->onValueChanged(val); };
- spinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
- spinner->setFont(app::meditationStyle::icStyle::text::font);
- spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
- spinner->setFocusEdges(RectangleEdge::None);
- body->getCenterBox()->addWidget(spinner);
-
- auto currentValue = presenter->getCurrentInterval();
- spinner->setCurrentValue(currentValue);
- body->setMinMaxArrowsVisibility(currentValue == titles.front(), currentValue == titles.back());
-
- bottomDescription = new Label(body->lastBox);
- bottomDescription->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::outer_layouts_h);
- bottomDescription->setFont(app::meditationStyle::icStyle::minute::font);
- bottomDescription->setEdges(RectangleEdge::None);
- bottomDescription->activeItem = false;
- bottomDescription->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
- bottomDescription->setText(presenter->getTimeUnitName(spinner->getCurrentValue()));
-
- setFocusItem(spinner);
- body->resize();
- }
-
- bool IntervalChimeWindow::onInput(const gui::InputEvent &inputEvent)
- {
- if (spinner->onInput(inputEvent)) {
- return true;
- }
-
- if (inputEvent.isShortRelease(gui::KeyCode::KEY_ENTER)) {
- presenter->activate(spinner->getCurrentValue());
- return true;
- }
-
- return AppWindow::onInput(inputEvent);
- }
-
- void IntervalChimeWindow::onValueChanged(const std::string currentValue)
- {
- auto titles = presenter->getIntervals();
- body->setMinMaxArrowsVisibility(currentValue == titles.front(), currentValue == titles.back());
- bottomDescription->setText(presenter->getTimeUnitName(spinner->getCurrentValue()));
- }
-} // namespace gui
D products/BellHybrid/apps/application-bell-meditation-timer/windows/IntervalChimeWindow.hpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/IntervalChimeWindow.hpp +0 -36
@@ 1,36 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include <apps-common/widgets/spinners/Spinners.hpp>
-#include <widgets/BellBaseLayout.hpp>
-
-#include <Application.hpp>
-#include <AppWindow.hpp>
-#include <InputEvent.hpp>
-
-#include "IntervalChimePresenter.hpp"
-
-namespace gui
-{
- class IntervalChimeWindow : public AppWindow, public app::meditation::IntervalChimeContract::View
- {
- public:
- explicit IntervalChimeWindow(
- app::ApplicationCommon *app,
- std::unique_ptr<app::meditation::IntervalChimeContract::Presenter> &&windowPresenter);
-
- // virtual methods
- void buildInterface() override;
- bool onInput(const gui::InputEvent &inputEvent) override;
-
- void onValueChanged(const std::string currentValue);
-
- private:
- std::unique_ptr<app::meditation::IntervalChimeContract::Presenter> presenter;
- BellBaseLayout *body{};
- UTF8Spinner *spinner{};
- Label *bottomDescription{};
- };
-} // namespace gui
A products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationMainWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationMainWindow.cpp +58 -0
@@ 0,0 1,58 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "MeditationMainWindow.hpp"
+
+#include "SettingsWindow.hpp"
+#include "StatisticsWindow.hpp"
+#include "MeditationTimerWindow.hpp"
+
+#include <apps-common/messages/DialogMetadataMessage.hpp>
+#include <common/options/OptionBellMenu.hpp>
+#include <service-appmgr/messages/SwitchRequest.hpp>
+
+namespace app::meditation
+{
+ using namespace gui;
+ MeditationMainWindow::MeditationMainWindow(app::ApplicationCommon *app)
+ : BellOptionWindow(app, gui::name::window::main_window)
+ {
+ addOptions(settingsOptionsList());
+ setListTitle(utils::translate("app_bell_meditation_timer"));
+ }
+
+ std::list<Option> MeditationMainWindow::settingsOptionsList()
+ {
+ using ActivatedCallback = std::function<bool(gui::Item &)>;
+ using Callback = std::function<ActivatedCallback(const std::string &window)>;
+
+ auto defaultCallback = [this](const std::string &window) {
+ return [window, this](gui::Item &) {
+ if (window.empty()) {
+ return false;
+ }
+ application->switchWindow(window);
+ return true;
+ };
+ };
+
+ std::list<gui::Option> settingsOptionList;
+ auto addWinSettings = [&](const UTF8 &name, const std::string &window, Callback &&callback) {
+ settingsOptionList.emplace_back(std::make_unique<gui::option::OptionBellMenu>(
+ name,
+ callback(window),
+ [=](gui::Item &item) {
+ // put focus change callback here
+ return true;
+ },
+ this));
+ };
+
+ addWinSettings(utils::translate("app_bell_meditation_start"), MeditationTimerWindow::name, defaultCallback);
+ addWinSettings(utils::translate("app_bell_meditation_settings"), SettingsWindow::name, defaultCallback);
+ addWinSettings(utils::translate("app_bell_meditation_statistics"), StatisticsWindow::name, defaultCallback);
+
+ return settingsOptionList;
+ }
+
+} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationMainWindow.hpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationMainWindow.hpp +20 -0
@@ 0,0 1,20 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <common/options/BellOptionWindow.hpp>
+
+namespace app::meditation
+{
+ class MeditationMainWindow : public gui::BellOptionWindow
+ {
+ public:
+ static constexpr auto defaultName = gui::name::window::main_window;
+ explicit MeditationMainWindow(app::ApplicationCommon *app);
+
+ private:
+ std::list<gui::Option> settingsOptionsList();
+ };
+
+} // namespace app::meditation
M products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationRunningWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationRunningWindow.cpp +3 -2
@@ 1,7 1,8 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "ApplicationBellMeditationTimer.hpp"
+#include "MeditationTimer.hpp"
+#include "MeditationCommon.hpp"
#include "MeditationRunningWindow.hpp"
#include "MeditationStyle.hpp"
@@ 64,7 65,7 @@ namespace gui
MeditationRunningWindow::MeditationRunningWindow(
app::ApplicationCommon *app,
std::unique_ptr<app::meditation::MeditationProgressContract::Presenter> &&windowPresenter)
- : AppWindow(app, gui::name::window::meditationProgress), presenter{std::move(windowPresenter)}
+ : AppWindow(app, app::meditation::windows::meditationProgress), presenter{std::move(windowPresenter)}
{
presenter->attach(this);
buildInterface();
M products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationTimerWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationTimerWindow.cpp +12 -10
@@ 1,16 1,18 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "ApplicationBellMeditationTimer.hpp"
+#include "MeditationTimer.hpp"
+#include "MeditationCommon.hpp"
#include "MeditationStyle.hpp"
#include "MeditationTimerWindow.hpp"
-namespace gui
+namespace app::meditation
{
+ using namespace gui;
MeditationTimerWindow::MeditationTimerWindow(
app::ApplicationCommon *app,
std::unique_ptr<app::meditation::MeditationTimerContract::Presenter> &&windowPresenter)
- : AppWindow(app, gui::name::window::meditationTimer), presenter{std::move(windowPresenter)}
+ : AppWindow(app, name), presenter{std::move(windowPresenter)}
{
presenter->attach(this);
buildInterface();
@@ 36,8 38,8 @@ namespace gui
topMessage->drawUnderline(false);
spinner = new UIntegerSpinner(
- UIntegerSpinner::Range{presenter->getMinValue(), presenter->getMaxValue(), presenter->getStepValue()},
- Boundaries::Fixed);
+ UIntegerSpinner::range{presenter->getMinValue(), presenter->getMaxValue(), presenter->getStepValue()},
+ gui::Boundaries::Fixed);
spinner->onValueChanged = [this](const auto val) { this->onValueChanged(val); };
spinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
spinner->setFont(app::meditationStyle::mtStyle::text::font);
@@ 47,7 49,7 @@ namespace gui
body->getCenterBox()->addWidget(spinner);
auto currentValue = presenter->getCurrentValue();
- spinner->setCurrentValue(currentValue);
+ spinner->set_value(currentValue);
body->setMinMaxArrowsVisibility(currentValue == presenter->getMinValue(),
currentValue == presenter->getMaxValue());
@@ 57,7 59,7 @@ namespace gui
bottomDescription->setEdges(RectangleEdge::None);
bottomDescription->activeItem = false;
bottomDescription->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
- bottomDescription->setText(presenter->getTimeUnitName(spinner->getCurrentValue()));
+ bottomDescription->setText(presenter->getTimeUnitName(spinner->value()));
setFocusItem(spinner);
body->resize();
@@ 70,7 72,7 @@ namespace gui
}
if (inputEvent.isShortRelease(gui::KeyCode::KEY_ENTER)) {
- presenter->activate(spinner->getCurrentValue());
+ presenter->activate(spinner->value());
return true;
}
@@ 81,6 83,6 @@ namespace gui
{
body->setMinMaxArrowsVisibility(currentValue == presenter->getMinValue(),
currentValue == presenter->getMaxValue());
- bottomDescription->setText(presenter->getTimeUnitName(spinner->getCurrentValue()));
+ bottomDescription->setText(presenter->getTimeUnitName(spinner->value()));
}
-} // namespace gui
+} // namespace app::meditation
M products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationTimerWindow.hpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/MeditationTimerWindow.hpp +7 -6
@@ 12,11 12,12 @@
#include "MeditationTimerPresenter.hpp"
-namespace gui
+namespace app::meditation
{
- class MeditationTimerWindow : public AppWindow, public app::meditation::MeditationTimerContract::View
+ class MeditationTimerWindow : public gui::AppWindow, public app::meditation::MeditationTimerContract::View
{
public:
+ static constexpr auto name = "MeditationTimerWindow";
explicit MeditationTimerWindow(
app::ApplicationCommon *app,
std::unique_ptr<app::meditation::MeditationTimerContract::Presenter> &&windowPresenter);
@@ 29,8 30,8 @@ namespace gui
private:
std::unique_ptr<app::meditation::MeditationTimerContract::Presenter> presenter;
- BellBaseLayout *body{};
- UIntegerSpinner *spinner{};
- Label *bottomDescription{};
+ gui::BellBaseLayout *body{};
+ gui::UIntegerSpinner *spinner{};
+ gui::Label *bottomDescription{};
};
-} // namespace gui
+} // namespace app::meditation
M products/BellHybrid/apps/application-bell-meditation-timer/windows/ReadyGoingWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/ReadyGoingWindow.cpp +8 -8
@@ 1,22 1,22 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "ApplicationBellMeditationTimer.hpp"
+#include "MeditationTimer.hpp"
+#include "MeditationCommon.hpp"
#include "MeditationStyle.hpp"
#include "ReadyGoingWindow.hpp"
-namespace
-{
- constexpr inline auto defaultTimeout = std::chrono::seconds{10};
-}
-
namespace gui
{
ReadyGoingWindow::ReadyGoingWindow(
app::ApplicationCommon *app,
std::shared_ptr<app::meditation::ReadyGoingPresenterContract::Presenter> winPresenter)
- : WindowWithTimer(app, gui::name::window::readyGoing, defaultTimeout), presenter{std::move(winPresenter)}
+ : WindowWithTimer(app, app::meditation::windows::readyGoing), presenter{std::move(winPresenter)}
{
+ const auto startDelay = presenter->getStartDelay();
+ /// Even if the start delay is set to 0, give 'ReadyGoingWindow` 1s to display its contents
+ resetTimer(startDelay == std::chrono::seconds{0} ? std::chrono::seconds{1} : startDelay);
+
buildInterface();
timerCallback = [this](Item &, sys::Timer &) {
@@ 44,7 44,7 @@ namespace gui
}
}
- bool ReadyGoingWindow::onInput(const InputEvent &inputEvent)
+ bool ReadyGoingWindow::onInput(const InputEvent &)
{
return true;
}
A products/BellHybrid/apps/application-bell-meditation-timer/windows/SettingsWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/SettingsWindow.cpp +67 -0
@@ 0,0 1,67 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "SettingsWindow.hpp"
+
+#include <common/data/StyleCommon.hpp>
+#include <apps-common/ApplicationCommon.hpp>
+#include <module-gui/gui/input/InputEvent.hpp>
+#include <module-gui/gui/widgets/SideListView.hpp>
+
+namespace app::meditation
+{
+ using namespace gui;
+ SettingsWindow::SettingsWindow(app::ApplicationCommon *app,
+ std::unique_ptr<app::meditation::contract::Presenter> presenter)
+ : AppWindow(app, name), presenter{std::move(presenter)}
+ {
+ this->presenter->attach(this);
+ buildInterface();
+ }
+
+ void SettingsWindow::rebuild()
+ {
+ erase();
+ buildInterface();
+ }
+
+ void SettingsWindow::buildInterface()
+ {
+ AppWindow::buildInterface();
+ statusBar->setVisible(false);
+ header->setTitleVisibility(false);
+ navBar->setVisible(false);
+
+ sideListView = new gui::SideListView(
+ this, 0U, 0U, this->getWidth(), this->getHeight(), presenter->getPagesProvider(), PageBarType::None);
+ sideListView->setEdges(RectangleEdge::None);
+
+ sideListView->rebuildList(listview::RebuildType::Full);
+
+ setFocusItem(sideListView);
+ }
+
+ void SettingsWindow::onBeforeShow(gui::ShowMode, gui::SwitchData *)
+ {
+ presenter->loadData();
+ setFocusItem(sideListView);
+ }
+
+ bool SettingsWindow::onInput(const gui::InputEvent &inputEvent)
+ {
+ if (sideListView->onInput(inputEvent)) {
+ return true;
+ }
+ if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
+ presenter->handleEnter();
+ return true;
+ }
+
+ return AppWindow::onInput(inputEvent);
+ }
+
+ void SettingsWindow::onClose(CloseReason)
+ {
+ presenter->eraseProviderData();
+ }
+} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/windows/SettingsWindow.hpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/SettingsWindow.hpp +33 -0
@@ 0,0 1,33 @@
+// 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 "Contract.hpp"
+
+#include <apps-common/windows/AppWindow.hpp>
+
+namespace gui
+{
+ class SideListView;
+}
+
+namespace app::meditation
+{
+ class SettingsWindow : public gui::AppWindow, public app::meditation::contract::View
+ {
+ public:
+ static constexpr auto name = "MeditationSettingsWindow";
+ SettingsWindow(app::ApplicationCommon *app, std::unique_ptr<app::meditation::contract::Presenter> presenter);
+
+ void buildInterface() override;
+ void onBeforeShow(gui::ShowMode mode, gui::SwitchData *data) override;
+ void onClose(CloseReason reason) override;
+ bool onInput(const gui::InputEvent &inputEvent) override;
+ void rebuild() override;
+
+ private:
+ gui::SideListView *sideListView{};
+ std::unique_ptr<app::meditation::contract::Presenter> presenter;
+ };
+} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/windows/StatisticsWindow.cpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/StatisticsWindow.cpp +62 -0
@@ 0,0 1,62 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "StatisticsWindow.hpp"
+
+#include "MeditationMainWindow.hpp"
+
+#include <common/windows/BellFinishedWindow.hpp>
+#include <common/data/StyleCommon.hpp>
+#include <apps-common/ApplicationCommon.hpp>
+#include <module-gui/gui/input/InputEvent.hpp>
+#include <module-gui/gui/widgets/SideListView.hpp>
+#include <apps-common/InternalModel.hpp>
+
+namespace app::meditation
+{
+ using namespace gui;
+ StatisticsWindow::StatisticsWindow(app::ApplicationCommon *app,
+ std::unique_ptr<app::meditation::contract::Presenter> presenter)
+ : AppWindow(app, name), presenter{std::move(presenter)}
+ {
+ this->presenter->attach(this);
+ buildInterface();
+ }
+
+ void StatisticsWindow::rebuild()
+ {
+ erase();
+ buildInterface();
+ }
+
+ void StatisticsWindow::buildInterface()
+ {
+ AppWindow::buildInterface();
+ statusBar->setVisible(false);
+ header->setTitleVisibility(false);
+ navBar->setVisible(false);
+ }
+
+ void StatisticsWindow::onBeforeShow(gui::ShowMode mode, gui::SwitchData *data)
+ {
+ setFocusItem(sideListView);
+ }
+
+ bool StatisticsWindow::onInput(const gui::InputEvent &inputEvent)
+ {
+ if (sideListView->onInput(inputEvent)) {
+ return true;
+ }
+ if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
+ presenter->handleEnter();
+ return true;
+ }
+
+ return AppWindow::onInput(inputEvent);
+ }
+
+ void StatisticsWindow::onClose(CloseReason reason)
+ {
+ presenter->eraseProviderData();
+ }
+} // namespace app::meditation
A products/BellHybrid/apps/application-bell-meditation-timer/windows/StatisticsWindow.hpp => products/BellHybrid/apps/application-bell-meditation-timer/windows/StatisticsWindow.hpp +33 -0
@@ 0,0 1,33 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "Contract.hpp"
+
+#include <apps-common/windows/AppWindow.hpp>
+
+namespace gui
+{
+ class SideListView;
+}
+
+namespace app::meditation
+{
+ class StatisticsWindow : public gui::AppWindow, public app::meditation::contract::View
+ {
+ public:
+ static constexpr auto name = "MeditationStatisticsWindow";
+ StatisticsWindow(app::ApplicationCommon *app, std::unique_ptr<app::meditation::contract::Presenter> presenter);
+
+ void buildInterface() override;
+ void onBeforeShow(gui::ShowMode mode, gui::SwitchData *data) override;
+ void onClose(CloseReason reason) override;
+ bool onInput(const gui::InputEvent &inputEvent) override;
+ void rebuild() override;
+
+ private:
+ gui::SideListView *sideListView{};
+ std::unique_ptr<app::meditation::contract::Presenter> presenter;
+ };
+} // namespace app::meditation
M products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp => products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp +5 -5
@@ 27,7 27,7 @@ namespace gui
void PowerNapListItem::createSpinner()
{
- spinner = new UIntegerSpinner(UIntegerSpinner::Range{spinnerMin, spinnerMax, spinnerStep}, Boundaries::Fixed);
+ spinner = new UIntegerSpinner(UIntegerSpinner::range{spinnerMin, spinnerMax, spinnerStep}, Boundaries::Fixed);
spinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
spinner->setFont(powerNapStyle::napPeriodFont);
spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
@@ 65,7 65,7 @@ namespace gui
inputCallback = [&](Item &, const InputEvent &inputEvent) -> bool {
if (body->onInput(inputEvent)) {
- setBottomDescribtionText(utils::language::getCorrectMinutesNumeralForm(spinner->getCurrentValue()));
+ setBottomDescribtionText(utils::language::getCorrectMinutesNumeralForm(spinner->value()));
return true;
}
return false;
@@ 74,13 74,13 @@ namespace gui
int PowerNapListItem::getSpinnerValue() const noexcept
{
- return spinner->getCurrentValue();
+ return spinner->value();
}
void PowerNapListItem::setSpinnerValue(int value)
{
- spinner->setCurrentValue(value);
- setBottomDescribtionText(utils::language::getCorrectMinutesNumeralForm(spinner->getCurrentValue()));
+ spinner->set_value(value);
+ setBottomDescribtionText(utils::language::getCorrectMinutesNumeralForm(spinner->value()));
onValueChanged(value);
}
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +1 -1
@@ 128,7 128,7 @@ namespace app
std::make_unique<SoundsRepository>(alarms::paths::getBedtimeReminderChimesDir());
auto provider = std::make_shared<bell_settings::BedtimeSettingsListItemProvider>(
bedtimeModel, soundsRepository->getSongTitles());
- auto presenter = std::make_unique<bell_settings::BedtimeSettingsPresenter>(
+ auto presenter = std::make_unique<bell_settings::SettingsPresenter>(
provider, bedtimeModel, *audioModel, std::move(soundsRepository));
return std::make_unique<gui::BellSettingsBedtimeToneWindow>(app, std::move(presenter));
});
M products/BellHybrid/apps/application-bell-settings/models/FrontlightListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/FrontlightListItemProvider.cpp +12 -11
@@ 4,7 4,8 @@
#include "FrontlightListItemProvider.hpp"
#include <common/models/FrontlightModel.hpp>
#include <gui/widgets/ListViewEngine.hpp>
-#include <common/widgets/ListItems.hpp>
+#include <common/widgets/list_items/Text.hpp>
+#include <common/widgets/list_items/Numeric.hpp>
namespace app::bell_settings
{
@@ 16,11 17,11 @@ namespace app::bell_settings
constexpr auto itemCount = 2U;
internalData.reserve(itemCount);
- auto brightness =
- new gui::NumListItem(model.getBrightnessModel(),
- gui::UIntegerSpinner::Range{brightnessMin, brightnessMax, brightnessStep},
- utils::translate("app_bell_settings_frontlight_top_message"));
- brightness->setOnValueChanged([this](const auto val) {
+ auto brightness = new list_items::Numeric(
+ list_items::Numeric::spinner_type::range{brightnessMin, brightnessMax, brightnessStep},
+ model.getBrightnessModel(),
+ utils::translate("app_bell_settings_frontlight_top_message"));
+ brightness->set_on_value_change_cb([this](const auto val) {
model.setStatus(true);
model.setBrightness(val);
});
@@ 29,12 30,12 @@ namespace app::bell_settings
const auto modeAutoStr = utils::translate("app_bell_settings_frontlight_mode_auto");
const auto modeOnDemandsStr = utils::translate("app_bell_settings_frontlight_mode_on_demand");
- auto mode = new gui::UTF8ListItem(model.getModeModel(),
- gui::UTF8Spinner::Range{modeOnDemandsStr, modeAutoStr},
- utils::translate("app_bell_settings_frontlight_mode_top_message"));
+ auto mode = new list_items::Text(list_items::Text::spinner_type ::range{modeOnDemandsStr, modeAutoStr},
+ model.getModeModel(),
+ utils::translate("app_bell_settings_frontlight_mode_top_message"));
mode->onExit = [this, mode, modeAutoStr]() {
- model.setMode(mode->getCurrentValue() == modeAutoStr ? screen_light_control::ScreenLightMode::Automatic
- : screen_light_control::ScreenLightMode::Manual);
+ model.setMode(mode->value() == modeAutoStr ? screen_light_control::ScreenLightMode::Automatic
+ : screen_light_control::ScreenLightMode::Manual);
};
internalData.emplace_back(mode);
}
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp +15 -12
@@ 4,6 4,8 @@
#include "BellSettingsStyle.hpp"
#include "AlarmSettingsListItemProvider.hpp"
#include <common/widgets/ListItems.hpp>
+#include <common/widgets/list_items/Text.hpp>
+#include <common/widgets/list_items/Numeric.hpp>
#include <apps-common/ApplicationCommon.hpp>
namespace app::bell_settings
@@ 22,22 24,22 @@ namespace app::bell_settings
constexpr auto itemCount = 4U;
internalData.reserve(itemCount);
- auto alarmTone = new UTF8ListItem(model.getAlarmTone(),
- std::move(alarmTonesRange),
- utils::translate("app_bell_settings_alarm_settings_tone"));
- alarmTone->setOnValueChanged([this](const UTF8 &val) {
+ auto alarmTone = new list_items::Text(std::move(alarmTonesRange),
+ model.getAlarmTone(),
+ utils::translate("app_bell_settings_alarm_settings_tone"));
+ alarmTone->set_on_value_change_cb([this](const auto &val) {
if (onToneChange) {
onToneChange(val);
}
});
alarmTone->onEnter = [this, alarmTone]() {
if (onToneEnter) {
- onToneEnter(alarmTone->getCurrentValue());
+ onToneEnter(alarmTone->value());
}
};
alarmTone->onExit = [this, alarmTone]() {
if (onToneExit) {
- onToneExit(alarmTone->getCurrentValue());
+ onToneExit(alarmTone->value());
}
};
internalData.emplace_back(alarmTone);
@@ 45,22 47,23 @@ namespace app::bell_settings
constexpr auto volumeStep = 1U;
constexpr auto volumeMin = 1U;
constexpr auto volumeMax = 10U;
- auto alarmVolume = new NumListItem(model.getAlarmVolume(),
- UIntegerSpinner::Range{volumeMin, volumeMax, volumeStep},
- utils::translate("app_bell_settings_alarm_settings_volume"));
- alarmVolume->setOnValueChanged([this](const UIntegerSpinner::Type &val) {
+ auto alarmVolume =
+ new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
+ model.getAlarmVolume(),
+ utils::translate("app_bell_settings_alarm_settings_volume"));
+ alarmVolume->set_on_value_change_cb([this](const auto &val) {
if (onVolumeChange) {
onVolumeChange(val);
}
});
alarmVolume->onEnter = [this, alarmTone]() {
if (onVolumeEnter) {
- onVolumeEnter(alarmTone->getCurrentValue());
+ onVolumeEnter(alarmTone->value());
}
};
alarmVolume->onExit = [this, alarmVolume]() {
if (onVolumeExit) {
- onVolumeExit(alarmVolume->getCurrentValue());
+ onVolumeExit(alarmVolume->value());
}
};
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp +15 -13
@@ 3,7 3,8 @@
#include "BedtimeSettingsListItemProvider.hpp"
#include "BellSettingsStyle.hpp"
-#include <common/widgets/ListItems.hpp>
+#include <common/widgets/list_items/Numeric.hpp>
+#include <common/widgets/list_items/Text.hpp>
#include <apps-common/ApplicationCommon.hpp>
#include <gui/widgets/ListViewEngine.hpp>
@@ 23,32 24,33 @@ namespace app::bell_settings
constexpr auto itemCount = 2U;
internalData.reserve(itemCount);
- auto chimeTone = new UTF8ListItem(model.get()->getBedtimeTone(),
- std::move(chimeToneRange),
- utils::translate("app_bell_settings_bedtime_settings_tone"));
- chimeTone->setOnValueChanged([this](const UTF8 &val) {
+ auto chimeTone = new list_items::Text(std::move(chimeToneRange),
+ model->getBedtimeTone(),
+ utils::translate("app_bell_settings_bedtime_settings_tone"));
+ chimeTone->set_on_value_change_cb([this](const auto &val) {
if (onToneChange) {
onToneChange(val);
}
});
chimeTone->onEnter = [this, chimeTone]() {
if (onToneEnter) {
- onToneEnter(chimeTone->getCurrentValue());
+ onToneEnter(chimeTone->value());
}
};
chimeTone->onExit = [this, chimeTone]() {
if (onToneExit) {
- onToneExit(chimeTone->getCurrentValue());
+ onToneExit(chimeTone->value());
}
};
internalData.emplace_back(chimeTone);
constexpr auto volumeStep = 1U;
constexpr auto volumeMin = 1U;
constexpr auto volumeMax = 10U;
- auto volume = new NumListItem(model.get()->getBedtimeVolume(),
- UIntegerSpinner::Range{volumeMin, volumeMax, volumeStep},
- utils::translate("app_bell_settings_bedtime_settings_volume"));
- volume->setOnValueChanged([this](const UIntegerSpinner::Type &val) {
+ auto volume =
+ new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
+ model->getBedtimeVolume(),
+ utils::translate("app_bell_settings_bedtime_settings_volume"));
+ volume->set_on_value_change_cb([this](const auto &val) {
if (onVolumeChange) {
onVolumeChange(val);
}
@@ 56,13 58,13 @@ namespace app::bell_settings
volume->onEnter = [this, chimeTone]() {
if (onVolumeEnter) {
- onVolumeEnter(chimeTone->getCurrentValue());
+ onVolumeEnter(chimeTone->value());
}
};
volume->onExit = [this, volume]() {
if (onVolumeExit) {
- onVolumeExit(volume->getCurrentValue());
+ onVolumeExit(volume->value());
}
};
internalData.emplace_back(volume);
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp +24 -29
@@ 2,7 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "PrewakeUpListItemProvider.hpp"
+#include <common/widgets/list_items/NumberWithSuffix.hpp>
+#include <common/widgets/list_items/Numeric.hpp>
#include <common/widgets/ListItems.hpp>
+#include <common/widgets/list_items/Text.hpp>
#include <apps-common/ApplicationCommon.hpp>
#include <gui/widgets/ListViewEngine.hpp>
#include <utility>
@@ 23,20 26,15 @@ namespace app::bell_settings
constexpr auto itemCount = 4U;
internalData.reserve(itemCount);
- const UTF8 minStr = utils::translate("common_minute_short");
- const auto chimeDurationRange = NumWithStringListItem::NumWithStringSpinner::Range{
- NumWithStringListItem::Value{utils::translate("app_settings_toggle_off")},
- NumWithStringListItem::Value{5, minStr},
- NumWithStringListItem::Value{10, minStr},
- NumWithStringListItem::Value{15, minStr}};
- auto chimeDuration = new NumWithStringListItem(
+ const std::string minStr = utils::translate("common_minute_short");
+ auto chimeDuration = new list_items::NumberWithSuffix(
+ list_items::NumberWithSuffix::spinner_type::range{0, 5, 10, 15},
model.getChimeDuration(),
- chimeDurationRange,
utils::translate("app_bell_settings_alarm_settings_prewake_up_chime_top_description"),
utils::translate("app_bell_settings_alarm_settings_prewake_up_chime_bottom_description"));
chimeDuration->onProceed = [chimeDuration, this]() {
- if (chimeDuration->isOff()) {
+ if (chimeDuration->value() == 0) {
constexpr auto lightDurationListIndex = 3U;
list->rebuildList(gui::listview::RebuildType::OnOffset, lightDurationListIndex);
return true;
@@ 46,22 44,23 @@ namespace app::bell_settings
internalData.emplace_back(chimeDuration);
- auto chimeTone = new UTF8ListItem(model.getChimeTone(),
- std::move(chimeToneRange),
- utils::translate("app_bell_settings_alarm_settings_prewake_up_chime_tone"));
- chimeTone->setOnValueChanged([this](const UTF8 &val) {
+ auto chimeTone =
+ new list_items::Text(std::move(chimeToneRange),
+ model.getChimeTone(),
+ utils::translate("app_bell_settings_alarm_settings_prewake_up_chime_tone"));
+ chimeTone->set_on_value_change_cb([this](const auto &val) {
if (onToneChange) {
onToneChange(val);
}
});
chimeTone->onEnter = [this, chimeTone]() {
if (onToneEnter) {
- onToneEnter(chimeTone->getCurrentValue());
+ onToneEnter(chimeTone->value());
}
};
chimeTone->onExit = [this, chimeTone]() {
if (onToneExit) {
- onToneExit(chimeTone->getCurrentValue());
+ onToneExit(chimeTone->value());
}
};
internalData.emplace_back(chimeTone);
@@ 69,10 68,11 @@ namespace app::bell_settings
constexpr auto volumeStep = 1U;
constexpr auto volumeMin = 1U;
constexpr auto volumeMax = 10U;
- auto volume = new NumListItem(model.getChimeVolume(),
- UIntegerSpinner::Range{volumeMin, volumeMax, volumeStep},
- utils::translate("app_bell_settings_alarm_settings_prewake_up_chime_volume"));
- volume->setOnValueChanged([this](const UIntegerSpinner::Type &val) {
+ auto volume =
+ new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
+ model.getChimeVolume(),
+ utils::translate("app_bell_settings_alarm_settings_prewake_up_chime_volume"));
+ volume->set_on_value_change_cb([this](const auto &val) {
if (onVolumeChange) {
onVolumeChange(val);
}
@@ 80,30 80,25 @@ namespace app::bell_settings
volume->onEnter = [this, chimeTone]() {
if (onVolumeEnter) {
- onVolumeEnter(chimeTone->getCurrentValue());
+ onVolumeEnter(chimeTone->value());
}
};
volume->onExit = [this, volume]() {
if (onVolumeExit) {
- onVolumeExit(volume->getCurrentValue());
+ onVolumeExit(volume->value());
}
};
internalData.emplace_back(volume);
- const auto lightDurationRange = NumWithStringListItem::NumWithStringSpinner::Range{
- NumWithStringListItem::Value{utils::translate("app_settings_toggle_off")},
- NumWithStringListItem::Value{5, minStr},
- NumWithStringListItem::Value{10, minStr},
- NumWithStringListItem::Value{15, minStr}};
- auto lightDuration = new NumWithStringListItem(
+ auto lightDuration = new list_items::NumberWithSuffix(
+ list_items::NumberWithSuffix::spinner_type::range{0, 5, 10, 15},
model.getLightDuration(),
- lightDurationRange,
utils::translate("app_bell_settings_alarm_settings_prewake_up_light_top_description"),
utils::translate("app_bell_settings_alarm_settings_prewake_up_light_bottom_description"));
lightDuration->onReturn = [chimeDuration, this]() {
- if (chimeDuration->isOff()) {
+ if (chimeDuration->value() == 0) {
list->rebuildList(gui::listview::RebuildType::OnOffset, 0);
return true;
}
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp +41 -42
@@ 2,6 2,9 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "SnoozeListItemProvider.hpp"
+#include <common/widgets/list_items/NumberWithSuffix.hpp>
+#include <common/widgets/list_items/Numeric.hpp>
+#include <common/widgets/list_items/Text.hpp>
#include <common/widgets/ListItems.hpp>
#include <common/LanguageUtils.hpp>
@@ 12,41 15,37 @@ namespace app::bell_settings
{
using namespace gui;
- NumWithStringListItem::NumWithStringSpinner::Range getDefaultChimeIntervalRange()
+ list_items::NumberWithSuffix::spinner_type::range getDefaultChimeIntervalRange()
{
- const UTF8 minStr = utils::translate("common_minute_short");
- return {
- NumWithStringListItem::Value{utils::translate("app_settings_toggle_off")},
- NumWithStringListItem::Value{1, minStr},
- NumWithStringListItem::Value{2, minStr},
- NumWithStringListItem::Value{3, minStr},
- NumWithStringListItem::Value{5, minStr},
- };
+ return {0, 1, 2, 3, 5};
}
- NumWithStringListItem::NumWithStringSpinner::Range transformChimeIntervalsRange(const std::uint32_t chimeLength)
+ list_items::NumberWithSuffix::spinner_type::range transformChimeIntervalsRange(const std::uint32_t chimeLength)
{
auto chimeIntervals = getDefaultChimeIntervalRange();
chimeIntervals.erase(std::remove_if(chimeIntervals.begin(),
chimeIntervals.end(),
[chimeLength](const auto &e) {
- return e.getValue() && (e.getValue().value() >= chimeLength);
+ if (e == chimeLength) {
+ return true;
+ }
+ return e and ((chimeLength % e) != 0);
}),
chimeIntervals.end());
return chimeIntervals;
}
- std::optional<NumWithStringListItem::Value> calculateCurrentChimeIntervalValue(
- const NumWithStringListItem::NumWithStringSpinner::Range &range,
- const NumWithStringListItem::Value &chimeInterval)
+ std::optional<list_items::NumberWithSuffix::spinner_type::value_type> calculateCurrentChimeIntervalValue(
+ const list_items::NumberWithSuffix::spinner_type::range &range,
+ const list_items::NumberWithSuffix::spinner_type::value_type &chimeInterval)
{
if (range.size() == 1) {
return {};
}
- if (chimeInterval.getValue() && (chimeInterval.getValue().value() >= range.back().getValue().value())) {
+ if (chimeInterval >= range.back()) {
return range.back();
}
else {
@@ 58,7 57,7 @@ namespace app::bell_settings
std::vector<UTF8> chimeTonesRange)
: model{model}
{
- buildListItems(chimeTonesRange);
+ buildListItems(std::move(chimeTonesRange));
}
void SnoozeListItemProvider::buildListItems(std::vector<UTF8> chimeTonesRange)
@@ 76,13 75,13 @@ namespace app::bell_settings
auto chimeLengthBottomDescription =
utils::language::getCorrectMinutesNumeralForm(model.getSnoozeLength().getValue());
- ;
- auto chimeLength = new NumListItem(model.getSnoozeLength(),
- UIntegerSpinner::Range{snoozeLengthMin, snoozeLengthMax, snoozeLengthStep},
- utils::translate("app_bell_settings_alarm_settings_snooze_length"),
- chimeLengthBottomDescription);
+ auto chimeLength = new list_items::Numeric(
+ list_items::Numeric::spinner_type::range{snoozeLengthMin, snoozeLengthMax, snoozeLengthStep},
+ model.getSnoozeLength(),
+ utils::translate("app_bell_settings_alarm_settings_snooze_length"),
+ chimeLengthBottomDescription);
- chimeLength->setOnValueChanged([chimeLength](const std::uint32_t &val) {
+ chimeLength->set_on_value_change_cb([chimeLength](const auto &val) {
chimeLength->setBottomDescribtionText(utils::language::getCorrectMinutesNumeralForm(val));
});
@@ 94,9 93,9 @@ namespace app::bell_settings
internalData.emplace_back(chimeLength);
- auto chimeInterval = new NumWithStringListItem(
- model.getSnoozeChimeInterval(),
+ auto chimeInterval = new list_items::NumberWithSuffix(
getDefaultChimeIntervalRange(),
+ model.getSnoozeChimeInterval(),
utils::translate("app_bell_settings_alarm_settings_snooze_chime_interval"),
utils::translate("app_bell_settings_alarm_settings_snooze_chime_interval_bot_desc"));
chimeLength->setValue();
@@ 105,16 104,15 @@ namespace app::bell_settings
chimeInterval->onEnter = [chimeInterval, chimeLength, this]() {
if (chimeLength != nullptr) {
- const auto currentChimeLength = chimeLength->getCurrentValue();
- const auto currentChimeInterval = chimeInterval->getCurrentValue();
+ const auto currentChimeLength = chimeLength->value();
+ const auto currentChimeInterval = chimeInterval->value();
const auto calculatedRange = transformChimeIntervalsRange(currentChimeLength);
const auto calculatedChimeInterval =
calculateCurrentChimeIntervalValue(calculatedRange, currentChimeInterval);
if (calculatedChimeInterval) {
- chimeInterval->getSpinner()->setRange(calculatedRange);
- chimeInterval->getSpinner()->setCurrentValue(calculatedChimeInterval.value());
- chimeInterval->setArrowsVisibility();
+ chimeInterval->set_range(calculatedRange);
+ chimeInterval->set_value(calculatedChimeInterval.value());
}
else {
this->onExit();
@@ 123,26 121,27 @@ namespace app::bell_settings
return false;
};
- auto snoozeChimeTone = new UTF8ListItem(model.getSnoozeChimeTone(),
- std::move(chimeTonesRange),
- utils::translate("app_bell_settings_alarm_settings_snooze_chime_tone"));
- snoozeChimeTone->setOnValueChanged([this](const UTF8 &val) {
+ auto snoozeChimeTone =
+ new list_items::Text(std::move(chimeTonesRange),
+ model.getSnoozeChimeTone(),
+ utils::translate("app_bell_settings_alarm_settings_snooze_chime_tone"));
+ snoozeChimeTone->set_on_value_change_cb([this](const auto &val) {
if (onToneChange) {
onToneChange(val);
}
});
snoozeChimeTone->onEnter = [this, snoozeChimeTone, chimeInterval]() {
- if (chimeInterval->isOff()) {
+ if (chimeInterval->value() == 0) {
this->onExit();
return;
}
if (onToneEnter) {
- onToneEnter(snoozeChimeTone->getCurrentValue());
+ onToneEnter(snoozeChimeTone->value());
}
};
snoozeChimeTone->onExit = [this, snoozeChimeTone]() {
if (onToneExit) {
- onToneExit(snoozeChimeTone->getCurrentValue());
+ onToneExit(snoozeChimeTone->value());
}
};
internalData.emplace_back(snoozeChimeTone);
@@ 151,10 150,10 @@ namespace app::bell_settings
constexpr auto volumeMin = 1U;
constexpr auto volumeMax = 10U;
auto snoozeChimeVolume =
- new NumListItem(model.getSnoozeChimeVolume(),
- UIntegerSpinner::Range{volumeMin, volumeMax, volumeStep},
- utils::translate("app_bell_settings_alarm_settings_snooze_chime_volume"));
- snoozeChimeVolume->setOnValueChanged([this](const UIntegerSpinner::Type &val) {
+ new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
+ model.getSnoozeChimeVolume(),
+ utils::translate("app_bell_settings_alarm_settings_snooze_chime_volume"));
+ snoozeChimeVolume->set_on_value_change_cb([this](const auto &val) {
if (onVolumeChange) {
onVolumeChange(val);
}
@@ 162,13 161,13 @@ namespace app::bell_settings
snoozeChimeVolume->onEnter = [this, snoozeChimeTone]() {
if (onVolumeEnter) {
- onVolumeEnter(snoozeChimeTone->getCurrentValue());
+ onVolumeEnter(snoozeChimeTone->value());
}
};
snoozeChimeVolume->onExit = [this, snoozeChimeVolume]() {
if (onVolumeExit) {
- onVolumeExit(snoozeChimeVolume->getCurrentValue());
+ onVolumeExit(snoozeChimeVolume->value());
}
};
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeSettingsModel.cpp +2 -3
@@ 3,7 3,6 @@
#include <models/alarm_settings/SnoozeSettingsModel.hpp>
-#include <apps-common/ApplicationCommon.hpp>
#include <db/SystemSettings.hpp>
namespace
@@ 47,7 46,7 @@ namespace app::bell_settings
std::uint8_t SnoozeLengthModel::getValue() const
{
- return get_helper<std::uint8_t>(settings, bell::settings::Snooze::length).value_or(0);
+ return get_helper<std::uint32_t>(settings, bell::settings::Snooze::length).value_or(0);
}
void SnoozeChimeIntervalModel::setValue(std::uint8_t value)
@@ 58,7 57,7 @@ namespace app::bell_settings
std::uint8_t SnoozeChimeIntervalModel::getValue() const
{
- return get_helper<std::uint8_t>(settings, bell::settings::Snooze::interval).value_or(0);
+ return get_helper<std::uint32_t>(settings, bell::settings::Snooze::interval).value_or(0);
}
void SnoozeChimeToneModel::setValue(UTF8 value)
M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp +10 -10
@@ 5,10 5,10 @@
namespace app::bell_settings
{
- BedtimeSettingsPresenter::BedtimeSettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
- std::shared_ptr<AbstractBedtimeModel> model,
- AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository)
+ SettingsPresenter::SettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
+ std::shared_ptr<AbstractBedtimeModel> model,
+ AbstractAudioModel &audioModel,
+ std::unique_ptr<AbstractSoundsRepository> soundsRepository)
: provider(std::move(provider)),
model(std::move(model)), audioModel{audioModel}, soundsRepository{std::move(soundsRepository)}
{
@@ 35,35 35,35 @@ namespace app::bell_settings
};
}
- auto BedtimeSettingsPresenter::saveData() -> void
+ auto SettingsPresenter::saveData() -> void
{
for (const auto &item : provider->getListItems()) {
item->getValue();
}
}
- auto BedtimeSettingsPresenter::loadData() -> void
+ auto SettingsPresenter::loadData() -> void
{
for (const auto &item : provider->getListItems()) {
item->setValue();
}
}
- auto BedtimeSettingsPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>
+ auto SettingsPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>
{
return provider;
}
- void BedtimeSettingsPresenter::eraseProviderData()
+ void SettingsPresenter::eraseProviderData()
{
provider->clearData();
}
- void BedtimeSettingsPresenter::stopSound()
+ void SettingsPresenter::stopSound()
{
this->audioModel.stopPlayedByThis({});
}
- void BedtimeSettingsPresenter::exitWithoutSave()
+ void SettingsPresenter::exitWithoutSave()
{
model->getBedtimeVolume().restoreDefault();
}
M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.hpp +5 -5
@@ 39,13 39,13 @@ namespace app::bell_settings
};
};
- class BedtimeSettingsPresenter : public BedtimeSettingsWindowContract::Presenter
+ class SettingsPresenter : public BedtimeSettingsWindowContract::Presenter
{
public:
- BedtimeSettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
- std::shared_ptr<AbstractBedtimeModel> model,
- AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository);
+ SettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
+ std::shared_ptr<AbstractBedtimeModel> model,
+ AbstractAudioModel &audioModel,
+ std::unique_ptr<AbstractSoundsRepository> soundsRepository);
auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
auto saveData() -> void override;
M products/BellHybrid/apps/application-bell-settings/widgets/TemperatureUnitListItem.cpp => products/BellHybrid/apps/application-bell-settings/widgets/TemperatureUnitListItem.cpp +5 -6
@@ 15,14 15,14 @@ namespace gui
setEdges(RectangleEdge::None);
setFocusItem(body);
- temperatureUnit = new UTF8Spinner(
+ temperatureUnit = new StringSpinner(
{utils::temperature::celsiusDegreeSymbol, utils::temperature::fahrenheitDegreeSymbol}, Boundaries::Fixed);
temperatureUnit->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
temperatureUnit->setFont(bell_settings_style::time_fmt_set_list_item::font);
temperatureUnit->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
temperatureUnit->setFocusEdges(RectangleEdge::None);
temperatureUnit->onValueChanged = [this](const auto &) {
- body->setMinMaxArrowsVisibility(temperatureUnit->isAtMin(), temperatureUnit->isAtMax());
+ body->setMinMaxArrowsVisibility(temperatureUnit->is_min(), temperatureUnit->is_max());
};
body->getCenterBox()->addWidget(temperatureUnit);
@@ 44,13 44,12 @@ namespace gui
auto TemperatureUnitListItem::getUnitAsStr() const noexcept -> UTF8
{
- return temperatureUnit->getCurrentValue();
+ return temperatureUnit->value();
}
auto TemperatureUnitListItem::setUnit(const utils::temperature::Temperature::Unit unit) -> void
{
using namespace utils::temperature;
- temperatureUnit->setCurrentValue(unit == Temperature::Unit::Celsius ? celsiusDegreeSymbol
- : fahrenheitDegreeSymbol);
- body->setMinMaxArrowsVisibility(temperatureUnit->isAtMin(), temperatureUnit->isAtMax());
+ temperatureUnit->set_value(unit == Temperature::Unit::Celsius ? celsiusDegreeSymbol : fahrenheitDegreeSymbol);
+ body->setMinMaxArrowsVisibility(temperatureUnit->is_min(), temperatureUnit->is_max());
}
} // namespace gui
M products/BellHybrid/apps/application-bell-settings/widgets/TemperatureUnitListItem.hpp => products/BellHybrid/apps/application-bell-settings/widgets/TemperatureUnitListItem.hpp +1 -1
@@ 20,7 20,7 @@ namespace gui
auto setUnit(utils::temperature::Temperature::Unit unit) -> void;
private:
- UTF8Spinner *temperatureUnit{};
+ StringSpinner *temperatureUnit{};
};
} // namespace gui
M products/BellHybrid/apps/application-bell-settings/widgets/TimeFormatSetListItem.cpp => products/BellHybrid/apps/application-bell-settings/widgets/TimeFormatSetListItem.cpp +7 -7
@@ 26,13 26,13 @@ namespace gui
setEdges(RectangleEdge::None);
setFocusItem(body);
- timeFormat = new UTF8Spinner({fmtSpinner12H, fmtSpinner24H}, Boundaries::Fixed);
+ timeFormat = new StringSpinner({fmtSpinner12H, fmtSpinner24H}, Boundaries::Fixed);
timeFormat->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::center_layout_h);
timeFormat->setFont(bell_settings_style::time_fmt_set_list_item::font);
timeFormat->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
timeFormat->setFocusEdges(RectangleEdge::None);
timeFormat->onValueChanged = [this](const auto &) {
- body->setMinMaxArrowsVisibility(timeFormat->isAtMin(), timeFormat->isAtMax());
+ body->setMinMaxArrowsVisibility(timeFormat->is_min(), timeFormat->is_max());
};
body->getCenterBox()->addWidget(timeFormat);
@@ 64,19 64,19 @@ namespace gui
auto TimeFormatSetListItem::getTimeFmt() const noexcept -> utils::time::Locale::TimeFormat
{
- return timeFormat->getCurrentValue() == fmtSpinner12H ? utils::time::Locale::TimeFormat::FormatTime12H
- : utils::time::Locale::TimeFormat::FormatTime24H;
+ return timeFormat->value() == fmtSpinner12H ? utils::time::Locale::TimeFormat::FormatTime12H
+ : utils::time::Locale::TimeFormat::FormatTime24H;
}
auto TimeFormatSetListItem::setTimeFmt(utils::time::Locale::TimeFormat fmt) noexcept -> void
{
using namespace utils::time;
if (fmt == Locale::TimeFormat::FormatTime12H) {
- timeFormat->setCurrentValue(fmtSpinner12H);
+ timeFormat->set_value(fmtSpinner12H);
}
else if (fmt == Locale::TimeFormat::FormatTime24H) {
- timeFormat->setCurrentValue(fmtSpinner24H);
+ timeFormat->set_value(fmtSpinner24H);
}
- body->setMinMaxArrowsVisibility(timeFormat->isAtMin(), timeFormat->isAtMax());
+ body->setMinMaxArrowsVisibility(timeFormat->is_min(), timeFormat->is_max());
}
} // namespace gui
M products/BellHybrid/apps/application-bell-settings/widgets/TimeFormatSetListItem.hpp => products/BellHybrid/apps/application-bell-settings/widgets/TimeFormatSetListItem.hpp +1 -1
@@ 30,7 30,7 @@ namespace gui
private:
Label *bottomDescription{};
- UTF8Spinner *timeFormat;
+ StringSpinner *timeFormat;
};
} // namespace gui
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.cpp +1 -1
@@ 11,7 11,7 @@
namespace gui
{
BellSettingsBedtimeToneWindow::BellSettingsBedtimeToneWindow(
- app::ApplicationCommon *app, std::unique_ptr<app::bell_settings::BedtimeSettingsPresenter::Presenter> presenter)
+ app::ApplicationCommon *app, std::unique_ptr<app::bell_settings::SettingsPresenter::Presenter> presenter)
: AppWindow(app, name), presenter{std::move(presenter)}
{
this->presenter->attach(this);
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.hpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.hpp +2 -3
@@ 17,8 17,7 @@ namespace gui
public:
static constexpr auto name = "BellSettingsBedtimeToneWindow";
explicit BellSettingsBedtimeToneWindow(
- app::ApplicationCommon *app,
- std::unique_ptr<app::bell_settings::BedtimeSettingsPresenter::Presenter> presenter);
+ app::ApplicationCommon *app, std::unique_ptr<app::bell_settings::SettingsPresenter::Presenter> presenter);
void buildInterface() override;
void onBeforeShow(gui::ShowMode mode, gui::SwitchData *data) override;
@@ 29,6 28,6 @@ namespace gui
private:
SideListView *sidelistview{};
- std::unique_ptr<app::bell_settings::BedtimeSettingsPresenter::Presenter> presenter;
+ std::unique_ptr<app::bell_settings::SettingsPresenter::Presenter> presenter;
};
} /* namespace gui */
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsLanguageWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsLanguageWindow.cpp +5 -5
@@ 36,17 36,17 @@ namespace gui
topMessage->drawUnderline(false);
auto data = presenter->getLanguages();
- spinner = new UTF8Spinner({data.begin(), data.end()}, Boundaries::Fixed);
+ spinner = new StringSpinner({data.begin(), data.end()}, Boundaries::Fixed);
spinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::center_layout_h);
spinner->setFont(style::window::font::large);
spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
spinner->setFocusEdges(RectangleEdge::None);
- spinner->setCurrentValue(presenter->getSelectedLanguage());
+ spinner->set_value(presenter->getSelectedLanguage());
spinner->onValueChanged = [this](const auto &) {
- body->setMinMaxArrowsVisibility(spinner->isAtMin(), spinner->isAtMax());
+ body->setMinMaxArrowsVisibility(spinner->is_min(), spinner->is_max());
};
body->getCenterBox()->addWidget(spinner);
- body->setMinMaxArrowsVisibility(spinner->isAtMin(), spinner->isAtMax());
+ body->setMinMaxArrowsVisibility(spinner->is_min(), spinner->is_max());
body->resize();
}
@@ 62,7 62,7 @@ namespace gui
return true;
}
else if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
- presenter->setLanguage(spinner->getCurrentValue());
+ presenter->setLanguage(spinner->value());
return true;
}
return AppWindow::onInput(inputEvent);
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsLanguageWindow.hpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsLanguageWindow.hpp +1 -1
@@ 28,6 28,6 @@ namespace gui
std::unique_ptr<app::bell_settings::LanguageWindowPresenter::Presenter> presenter;
BellBaseLayout *body{};
- UTF8Spinner *spinner = nullptr;
+ StringSpinner *spinner = nullptr;
};
} // namespace gui
M products/BellHybrid/apps/common/include/common/BellListItemProvider.hpp => products/BellHybrid/apps/common/include/common/BellListItemProvider.hpp +11 -0
@@ 12,6 12,17 @@ namespace app
public gui::ListItemProvider
{
public:
+ using Items = std::vector<gui::BellSideListItemWithCallbacks *>;
+ explicit BellListItemProvider(Items &&items)
+ {
+ for (const auto &item : items) {
+ internalData.emplace_back(item);
+ item->deleteByList = false;
+ }
+ }
+
+ BellListItemProvider() = default;
+
std::vector<gui::BellSideListItemWithCallbacks *> getListItems();
auto requestRecords(uint32_t offset, uint32_t limit) -> void override;
M products/BellHybrid/apps/common/include/common/LanguageUtils.hpp => products/BellHybrid/apps/common/include/common/LanguageUtils.hpp +2 -1
@@ 7,5 7,6 @@
namespace utils::language
{
- auto getCorrectMinutesNumeralForm(int val) -> std::string;
+ auto getCorrectMinutesNumeralForm(std::uint32_t val) -> std::string;
+ auto getCorrectSecondsNumeralForm(std::uint32_t val) -> std::string;
} // namespace utils::language
M products/BellHybrid/apps/common/include/common/widgets/ListItems.hpp => products/BellHybrid/apps/common/include/common/widgets/ListItems.hpp +4 -62
@@ 6,7 6,6 @@
#include <common/models/AbstractSettingsModel.hpp>
#include <common/widgets/BellSideListItemWithCallbacks.hpp>
-#include <apps-common/widgets/spinners/SpinnerContents.hpp>
#include <apps-common/widgets/spinners/Spinners.hpp>
#include <apps-common/widgets/TimeSetFmtSpinner.hpp>
@@ 15,6 14,7 @@
namespace gui
{
+
class OnOffListItem : public BellSideListItemWithCallbacks
{
public:
@@ 25,67 25,9 @@ namespace gui
private:
void setArrowsVisibility();
- const UTF8 onStr;
- const UTF8 offStr;
- UTF8Spinner *spinner{};
- };
-
- class NumListItem : public BellSideListItemWithCallbacks
- {
- public:
- explicit NumListItem(AbstractSettingsModel<std::uint8_t> &model,
- UIntegerSpinner::Range range,
- const std::string &topDescription = "",
- const std::string &bottomDescription = "");
-
- void setOnValueChanged(std::function<void(const UIntegerSpinner::Type &)> &&cb);
- UIntegerSpinner::Type getCurrentValue();
-
- private:
- UIntegerSpinner *spinner{};
-
- void setArrowsVisibility(UIntegerSpinner::Range range);
- };
-
- class NumWithStringListItem : public BellSideListItemWithCallbacks
- {
- public:
- using Value = NumWithString<std::uint32_t, UTF8>;
- using NumWithStringSpinner = GenericSpinner<StringPolicy<Value>>;
-
- explicit NumWithStringListItem(AbstractSettingsModel<std::uint8_t> &model,
- NumWithStringSpinner::Range range,
- const std::string &topDescription = "",
- const std::string &bottomDescription = "");
-
- bool isOff() const;
- NumWithStringSpinner *getSpinner()
- {
- return spinner;
- }
- NumWithStringSpinner::Type getCurrentValue();
- void setArrowsVisibility();
-
- private:
- NumWithStringSpinner *spinner{};
- const UTF8 offStr;
- const UTF8 minStr;
- };
-
- class UTF8ListItem : public BellSideListItemWithCallbacks
- {
- public:
- explicit UTF8ListItem(AbstractSettingsModel<UTF8> &model,
- UTF8Spinner::Range range,
- const std::string &topDescription = "");
-
- void setOnValueChanged(std::function<void(const UTF8 &)> &&cb);
- UTF8Spinner::Type getCurrentValue();
-
- private:
- void setArrowsVisibility(const UTF8Spinner::Range &range);
-
- UTF8Spinner *spinner{};
+ const std::string onStr;
+ const std::string offStr;
+ StringSpinner *spinner;
};
class TimeListItem : public BellSideListItemWithCallbacks
A products/BellHybrid/apps/common/include/common/widgets/list_items/Fraction.hpp => products/BellHybrid/apps/common/include/common/widgets/list_items/Fraction.hpp +60 -0
@@ 0,0 1,60 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "details.hpp"
+#include <i18n/i18n.hpp>
+#include <utility>
+
+namespace app::list_items
+{
+ /// Representation of fraction number tailored for GUI/app use
+ struct FractionData
+ {
+ bool operator==(const FractionData &oth) const
+ {
+ return denominator == oth.denominator and nominator == oth.nominator;
+ }
+ double to_double() const
+ {
+ return nominator == denominator ? 0 : static_cast<double>(nominator) / denominator;
+ }
+ int nominator;
+ int denominator;
+ };
+
+ struct FractionFormatter
+ {
+ public:
+ FractionFormatter() : off(utils::translate("app_settings_toggle_off"))
+ {}
+ std::string operator()(FractionData value) const
+ {
+ return value.nominator == value.denominator
+ ? off
+ : (std::to_string(value.nominator) + "/" + std::to_string(value.denominator));
+ }
+
+ private:
+ std::string off;
+ };
+
+ using FractionSpinner = gui::StringOutputSpinner<Model<FractionData>, FractionFormatter>;
+ class Fraction : public details::ListItemBase<FractionSpinner>
+ {
+ public:
+ Fraction(spinner_type::range &&range,
+ gui::AbstractSettingsModel<FractionData> &model,
+ const std::string &topDescription = "",
+ const std::string &bottomDescription = "")
+ : details::ListItemBase<spinner_type>(std::move(range), model, topDescription, bottomDescription)
+ {}
+
+ private:
+ void control_bottom_description(const FractionData &value) final
+ {
+ bottomText->setVisible(value.nominator != value.denominator);
+ }
+ };
+} // namespace app::list_items
A products/BellHybrid/apps/common/include/common/widgets/list_items/NumberWithSuffix.hpp => products/BellHybrid/apps/common/include/common/widgets/list_items/NumberWithSuffix.hpp +45 -0
@@ 0,0 1,45 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "details.hpp"
+#include <i18n/i18n.hpp>
+#include <utility>
+
+namespace app::list_items
+{
+ struct NumberWithSuffixFormatter
+ {
+ public:
+ NumberWithSuffixFormatter()
+ : suffix(utils::translate("common_minute_short")), off(utils::translate("app_settings_toggle_off"))
+ {}
+ std::string operator()(const std::uint8_t &value) const
+ {
+ return value == 0 ? off : (std::to_string(value) + " " + suffix);
+ }
+
+ private:
+ std::string suffix;
+ std::string off;
+ };
+
+ using NumberWithSuffixSpinner = gui::StringOutputSpinner<Model<std::uint8_t, true>, NumberWithSuffixFormatter>;
+ class NumberWithSuffix : public details::ListItemBase<NumberWithSuffixSpinner>
+ {
+ public:
+ NumberWithSuffix(spinner_type::range &&range,
+ gui::AbstractSettingsModel<spinner_type::value_type> &model,
+ const std::string &topDescription = "",
+ const std::string &bottomDescription = "")
+ : details::ListItemBase<spinner_type>(std::move(range), model, topDescription, bottomDescription)
+ {}
+
+ private:
+ void control_bottom_description(const spinner_type::value_type &value) final
+ {
+ bottomText->setVisible(value != 0);
+ }
+ };
+} // namespace app::list_items
A products/BellHybrid/apps/common/include/common/widgets/list_items/Numeric.hpp => products/BellHybrid/apps/common/include/common/widgets/list_items/Numeric.hpp +22 -0
@@ 0,0 1,22 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "details.hpp"
+#include <i18n/i18n.hpp>
+#include <utility>
+
+namespace app::list_items
+{
+ class Numeric : public details::ListItemBase<gui::UIntegerSpinner>
+ {
+ public:
+ Numeric(gui::UIntegerSpinner::range &&range,
+ gui::AbstractSettingsModel<gui::UIntegerSpinner::value_type> &model,
+ const std::string &topDescription = "",
+ const std::string &bottomDescription = "")
+ : details::ListItemBase<gui::UIntegerSpinner>(std::move(range), model, topDescription, bottomDescription)
+ {}
+ };
+} // namespace app::list_items
A products/BellHybrid/apps/common/include/common/widgets/list_items/OnOff.hpp => products/BellHybrid/apps/common/include/common/widgets/list_items/OnOff.hpp +30 -0
@@ 0,0 1,30 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "details.hpp"
+#include <i18n/i18n.hpp>
+#include <utility>
+
+namespace app::list_items
+{
+ class OnOff : public details::ListItemBase<gui::StringSpinner>
+ {
+ public:
+ explicit OnOff(gui::AbstractSettingsModel<gui::StringSpinner::value_type> &model,
+ const std::string &topDescription = "",
+ const std::string &bottomDescription = "")
+ : details::ListItemBase<gui::StringSpinner>(
+ {utils::translate("app_settings_toggle_off"), utils::translate("app_settings_toggle_on")},
+ model,
+ topDescription,
+ bottomDescription)
+ {}
+
+ [[nodiscard]] bool is_active() const
+ {
+ return value() == utils::translate("app_settings_toggle_on");
+ }
+ };
+} // namespace app::list_items
A products/BellHybrid/apps/common/include/common/widgets/list_items/Text.hpp => products/BellHybrid/apps/common/include/common/widgets/list_items/Text.hpp +24 -0
@@ 0,0 1,24 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "details.hpp"
+#include <i18n/i18n.hpp>
+#include <utility>
+
+namespace app::list_items
+{
+ class Text : public details::ListItemBase<gui::StringSpinner>
+ {
+ public:
+ Text(gui::StringSpinner::range &&range,
+ gui::AbstractSettingsModel<gui::StringSpinner::value_type> &model,
+ const std::string &topDescription = "",
+ const std::string &bottomDescription = "")
+ : details::ListItemBase<gui::StringSpinner>(std::move(range), model, topDescription, bottomDescription)
+ {
+ raw_spinner()->setFont(gui::bell_style::font_center);
+ }
+ };
+} // namespace app::list_items
A products/BellHybrid/apps/common/include/common/widgets/list_items/details.hpp => products/BellHybrid/apps/common/include/common/widgets/list_items/details.hpp +106 -0
@@ 0,0 1,106 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <common/models/AbstractSettingsModel.hpp>
+#include <common/widgets/BellSideListItemWithCallbacks.hpp>
+#include <common/data/StyleCommon.hpp>
+
+#include <apps-common/widgets/spinners/Spinners.hpp>
+#include <apps-common/widgets/TimeSetFmtSpinner.hpp>
+
+namespace app::list_items
+{
+ namespace details
+ {
+ template <typename SpinnerType> class ListItemBase : public gui::BellSideListItemWithCallbacks
+ {
+ public:
+ using spinner_type = SpinnerType;
+ using value_type = typename SpinnerType::value_type;
+
+ value_type value() const
+ {
+ return spinner->value();
+ }
+
+ void set_value(const value_type &value)
+ {
+ spinner->set_value(value);
+ }
+
+ void set_range(const typename spinner_type::range &range)
+ {
+ spinner->set_range(range);
+ }
+
+ void set_on_value_change_cb(std::function<void(const value_type &)> &&cb)
+ {
+ onValueChangeCb = std::move(cb);
+ }
+
+ protected:
+ SpinnerType *raw_spinner()
+ {
+ return spinner;
+ }
+
+ /// Might be overridden if the specific handling of the bottom text is needed
+ virtual void control_bottom_description(const value_type &value){};
+
+ explicit ListItemBase(typename SpinnerType::range &&range,
+ gui::AbstractSettingsModel<value_type> &model,
+ const std::string &topDescription = "",
+ const std::string &bottomDescription = "")
+ : BellSideListItemWithCallbacks(topDescription), model{model}, bottomDescription{bottomDescription}
+ {
+ spinner = new SpinnerType(std::move(range), gui::Boundaries::Fixed);
+ spinner->setMaximumSize(::style::bell_base_layout::w, ::style::bell_base_layout::h);
+ spinner->setFont(gui::bell_style::font);
+ spinner->setAlignment(
+ gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
+ spinner->setFocusEdges(gui::RectangleEdge::None);
+ body->getCenterBox()->addWidget(spinner);
+
+ if (not this->bottomDescription.empty()) {
+ setupBottomDescription(this->bottomDescription);
+ }
+
+ spinner->onValueChanged = [this](const auto &val) {
+ control_visibility();
+ if (onValueChangeCb) {
+ onValueChangeCb(val);
+ }
+ };
+
+ getValue = [this]() { this->model.setValue(this->spinner->value()); };
+ setValue = [this]() { this->spinner->set_value(this->model.getValue()); };
+
+ inputCallback = [this, &bottomDescription](Item &, const gui::InputEvent &event) {
+ return OnInputCallback(event);
+ };
+
+ focusChangedCallback = [this, &bottomDescription](Item &) {
+ OnFocusChangedCallback();
+ control_visibility();
+ return true;
+ };
+ }
+
+ private:
+ void control_visibility()
+ {
+ body->setMinMaxArrowsVisibility(spinner->is_min(), spinner->is_max());
+ if (not this->bottomDescription.empty()) {
+ control_bottom_description(spinner->value());
+ }
+ }
+ SpinnerType *spinner{};
+ gui::AbstractSettingsModel<value_type> &model;
+ std::string bottomDescription;
+ std::function<void(const value_type &)> onValueChangeCb;
+ };
+ } // namespace details
+
+} // namespace app::list_items
M products/BellHybrid/apps/common/src/LanguageUtils.cpp => products/BellHybrid/apps/common/src/LanguageUtils.cpp +28 -6
@@ 3,21 3,43 @@
#include <i18n/i18n.hpp>
-namespace utils::language
+namespace
{
- auto getCorrectMinutesNumeralForm(int val) -> std::string
+ std::string transform(const std::uint32_t val,
+ const std::string &minuteLower,
+ const std::string &minutesLower,
+ const std::string &minutesLowerGenitive)
{
if (val == 1) {
- return utils::translate("common_minute_lower");
+ return minuteLower;
}
if (utils::getDisplayLanguage() == "Polski") {
if (val < 10 || val > 20) {
if ((val % 10) == 2 || (val % 10) == 3 || (val % 10) == 4) {
- return utils::translate("common_minutes_lower");
+ return minutesLower;
}
}
- return utils::translate("common_minutes_lower_genitive");
+ return minutesLowerGenitive;
}
- return utils::translate("common_minutes_lower");
+ return minutesLower;
+ }
+} // namespace
+
+namespace utils::language
+{
+ auto getCorrectMinutesNumeralForm(const std::uint32_t val) -> std::string
+ {
+ return transform(val,
+ utils::translate("common_minute_lower"),
+ utils::translate("common_minutes_lower"),
+ utils::translate("common_minutes_lower_genitive"));
+ }
+
+ auto getCorrectSecondsNumeralForm(const std::uint32_t val) -> std::string
+ {
+ return transform(val,
+ utils::translate("common_second_lower"),
+ utils::translate("common_seconds_lower"),
+ utils::translate("common_seconds_lower_genitive"));
}
} // namespace utils::language
M products/BellHybrid/apps/common/src/models/SettingsModel.cpp => products/BellHybrid/apps/common/src/models/SettingsModel.cpp +3 -0
@@ 3,6 3,7 @@
#include <models/SettingsModel.hpp>
#include <utf8/UTF8.hpp>
+#include <widgets/list_items/Fraction.hpp>
namespace gui
{
template <class ValueType> SettingsModel<ValueType>::SettingsModel(sys::Service *app)
@@ 12,7 13,9 @@ namespace gui
template class SettingsModel<bool>;
template class SettingsModel<std::uint8_t>;
+ template class SettingsModel<std::uint32_t>;
template class SettingsModel<std::string>;
template class SettingsModel<UTF8>;
template class SettingsModel<time_t>;
+ template class SettingsModel<app::list_items::FractionData>;
} // namespace gui
M products/BellHybrid/apps/common/src/widgets/ListItems.cpp => products/BellHybrid/apps/common/src/widgets/ListItems.cpp +5 -146
@@ 12,17 12,17 @@ namespace gui
: BellSideListItemWithCallbacks(topDescription), onStr{utils::translate("app_settings_toggle_on")},
offStr{utils::translate("app_settings_toggle_off")}
{
- spinner = new UTF8Spinner(UTF8Spinner::Range{offStr, onStr}, Boundaries::Fixed);
+ spinner = new StringSpinner(StringSpinner::range{offStr, onStr}, Boundaries::Fixed);
spinner->setMaximumSize(::style::bell_base_layout::w, ::style::bell_base_layout::h);
spinner->setFont(bell_style::font);
spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
spinner->setFocusEdges(RectangleEdge::None);
- spinner->setCurrentValue(onStr);
+ spinner->set_value(onStr);
body->getCenterBox()->addWidget(spinner);
getValue = [&model, this]() { model.setValue(isActive()); };
setValue = [&model, this]() {
- spinner->setCurrentValue(model.getValue() ? onStr : offStr);
+ spinner->set_value(model.getValue() ? onStr : offStr);
setArrowsVisibility();
};
inputCallback = [this](Item &, const InputEvent &event) {
@@ 34,152 34,11 @@ namespace gui
bool OnOffListItem::isActive() const
{
- return spinner->getCurrentValue() == onStr;
+ return spinner->value() == onStr;
}
void OnOffListItem::setArrowsVisibility()
{
- const auto selectedVal = spinner->getCurrentValue();
- body->setMinMaxArrowsVisibility(selectedVal == offStr, selectedVal == onStr);
- }
-
- NumListItem::NumListItem(AbstractSettingsModel<std::uint8_t> &model,
- UIntegerSpinner::Range range,
- const std::string &topDescription,
- const std::string &bottomDescription)
- : BellSideListItemWithCallbacks(topDescription)
- {
- spinner = new UIntegerSpinner(range, Boundaries::Fixed);
- spinner->setMaximumSize(::style::bell_base_layout::w, ::style::bell_base_layout::h);
- spinner->setFont(bell_style::font);
- spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
- spinner->setFocusEdges(RectangleEdge::None);
- body->getCenterBox()->addWidget(spinner);
-
- setupBottomDescription(bottomDescription);
-
- getValue = [&model, this]() { model.setValue(spinner->getCurrentValue()); };
- setValue = [&model, this, range]() {
- spinner->setCurrentValue(model.getValue());
- setArrowsVisibility(range);
- };
-
- inputCallback = [&, range](Item &item, const InputEvent &event) {
- const auto result = OnInputCallback(event);
- setArrowsVisibility(range);
- return result;
- };
- }
- void NumListItem::setOnValueChanged(std::function<void(const UIntegerSpinner::Type &)> &&cb)
- {
- spinner->onValueChanged = cb;
- }
- UIntegerSpinner::Type NumListItem::getCurrentValue()
- {
- return spinner->getCurrentValue();
- }
-
- void NumListItem::setArrowsVisibility(UIntegerSpinner::Range range)
- {
- const auto selectedVal = spinner->getCurrentValue();
- body->setMinMaxArrowsVisibility(selectedVal == range.min, selectedVal == range.max);
- }
-
- NumWithStringListItem::NumWithStringListItem(AbstractSettingsModel<std::uint8_t> &model,
- NumWithStringSpinner::Range range,
- const std::string &topDescription,
- const std::string &bottomDescription)
- : BellSideListItemWithCallbacks(topDescription), minStr{utils::translate("common_minute_short")}
- {
-
- spinner = new NumWithStringSpinner(range, Boundaries::Fixed);
- spinner->setMaximumSize(::style::bell_base_layout::w, ::style::bell_base_layout::h);
- spinner->setFont(bell_style::font);
- spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
- spinner->setFocusEdges(RectangleEdge::None);
- body->getCenterBox()->addWidget(spinner);
-
- setupBottomDescription(bottomDescription);
-
- inputCallback = [&, range](Item &item, const InputEvent &event) {
- const auto result = OnInputCallback(event);
- bottomText->setVisible(spinner->getCurrentValue().getValue().has_value());
- setArrowsVisibility();
- return result;
- };
-
- focusChangedCallback = [&](Item &) {
- bottomText->setVisible(spinner->getCurrentValue().getValue().has_value());
- OnFocusChangedCallback();
- return true;
- };
-
- getValue = [&model, this]() {
- const auto val = spinner->getCurrentValue().getValue();
- model.setValue(not val ? 0 : *val);
- };
- setValue = [&model, this]() {
- const auto modelValue = model.getValue();
- if (modelValue > 0) {
- spinner->setCurrentValue(Value{modelValue, minStr});
- }
- else {
- spinner->setCurrentValue(Value{minStr});
- }
- setArrowsVisibility();
- };
- }
-
- bool NumWithStringListItem::isOff() const
- {
- return not spinner->getCurrentValue().getValue().has_value();
- }
-
- void NumWithStringListItem::setArrowsVisibility()
- {
- body->setMinMaxArrowsVisibility(spinner->isAtMin(), spinner->isAtMax());
- }
- NumWithString<uint32_t, UTF8> NumWithStringListItem::getCurrentValue()
- {
- return spinner->getCurrentValue();
- }
-
- UTF8ListItem::UTF8ListItem(AbstractSettingsModel<UTF8> &model,
- UTF8Spinner::Range range,
- const std::string &topDescription)
- : BellSideListItemWithCallbacks(topDescription)
- {
- spinner = new UTF8Spinner(range, Boundaries::Fixed);
- spinner->setMaximumSize(::style::bell_base_layout::w, ::style::bell_base_layout::h);
- spinner->setFont(bell_style::font_center);
- spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
- spinner->setFocusEdges(RectangleEdge::None);
- body->getCenterBox()->addWidget(spinner);
-
- getValue = [&model, this]() { model.setValue(spinner->getCurrentValue()); };
- setValue = [&model, this, range]() {
- spinner->setCurrentValue(model.getValue());
- setArrowsVisibility(range);
- };
- inputCallback = [&, range](Item &item, const InputEvent &event) {
- const auto result = OnInputCallback(event);
- setArrowsVisibility(range);
- return result;
- };
- }
-
- void UTF8ListItem::setOnValueChanged(std::function<void(const UTF8 &)> &&cb)
- {
- spinner->onValueChanged = cb;
- }
-
- UTF8Spinner::Type UTF8ListItem::getCurrentValue()
- {
- return spinner->getCurrentValue();
- }
- void UTF8ListItem::setArrowsVisibility(const UTF8Spinner::Range &range)
- {
- const auto selectedVal = spinner->getCurrentValue();
- body->setMinMaxArrowsVisibility(selectedVal == range.front(), selectedVal == range.back());
+ body->setMinMaxArrowsVisibility(spinner->is_min(), spinner->is_max());
}
TimeListItem::TimeListItem(AbstractSettingsModel<time_t> &model,
M products/BellHybrid/apps/common/src/widgets/TimeSetSpinnerVertical.cpp => products/BellHybrid/apps/common/src/widgets/TimeSetSpinnerVertical.cpp +23 -21
@@ 29,25 29,25 @@ namespace gui
setEdges(RectangleEdge::None);
hour =
- new UIntegerSpinnerFixed(UIntegerSpinnerFixed::Range{hourMin, hourMax, hourStep}, Boundaries::Continuous);
+ new UIntegerSpinnerFixed(UIntegerSpinnerFixed::range{hourMin, hourMax, hourStep}, Boundaries::Continuous);
updateFont(hour, fontName);
hour->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
hour->setEdges(RectangleEdge::None);
hour->setPenFocusWidth(style::time_set_spinner_vertical::focus::size);
- hour->setCurrentValue(0);
+ hour->set_value(0);
hour->setMargins(getHourMargins(fontName));
addWidget(hour);
- minute = new UIntegerSpinnerFixed(UIntegerSpinnerFixed::Range{minuteMin, minuteMax, minuteStep},
+ minute = new UIntegerSpinnerFixed(UIntegerSpinnerFixed::range{minuteMin, minuteMax, minuteStep},
Boundaries::Continuous);
updateFont(minute, fontName);
minute->setPenFocusWidth(style::time_set_spinner_vertical::focus::size);
minute->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
minute->setEdges(RectangleEdge::None);
- minute->setCurrentValue(0);
+ minute->set_value(0);
addWidget(minute);
resizeItems();
@@ 61,22 61,22 @@ namespace gui
switch (newFormat) {
case utils::time::Locale::TimeFormat::FormatTime12H: {
- auto hours = std::chrono::hours(hour->getCurrentValue());
- hour->setRange(UIntegerSpinnerFixed::Range{
+ auto hours = std::chrono::hours(hour->value());
+ hour->set_range(UIntegerSpinnerFixed::range{
time::Locale::min_hour_12H_mode, time::Locale::max_hour_12H_mode, hourStep});
if (timeFormat != newFormat) {
- hour->setCurrentValue(date::make12(hours).count());
+ hour->set_value(date::make12(hours).count());
}
} break;
case utils::time::Locale::TimeFormat::FormatTime24H: {
- auto hours = std::chrono::hours(hour->getCurrentValue());
- hour->setRange(UIntegerSpinnerFixed::Range{
+ auto hours = std::chrono::hours(hour->value());
+ hour->set_range(UIntegerSpinnerFixed::range{
time::Locale::min_hour_24H_mode, time::Locale::max_hour_24H_mode, hourStep});
if (newFormat != timeFormat) {
- hour->setCurrentValue(date::make24(hours, isPM()).count());
+ hour->set_value(date::make24(hours, isPM()).count());
}
} break;
default:
@@ 88,22 88,22 @@ namespace gui
auto TimeSetSpinnerVertical::setMinute(int value) noexcept -> void
{
- minute->setCurrentValue(value);
+ minute->set_value(value);
}
auto TimeSetSpinnerVertical::getHour() const noexcept -> int
{
- return hour->getCurrentValue();
+ return hour->value();
}
auto TimeSetSpinnerVertical::getMinute() const noexcept -> int
{
- return minute->getCurrentValue();
+ return minute->value();
}
auto TimeSetSpinnerVertical::setHour(int value) noexcept -> void
{
- hour->setCurrentValue(value);
+ hour->set_value(value);
}
auto TimeSetSpinnerVertical::updateFont(TextFixedSize *elem, const std::string &fontName) noexcept -> void
@@ 148,15 148,17 @@ namespace gui
const auto t = std::localtime(&time);
if (timeFormat == Locale::TimeFormat::FormatTime24H) {
- hour->setCurrentValue(t->tm_hour);
- minute->setCurrentValue(t->tm_min);
+ hour->set_value(t->tm_hour);
+ minute->set_value(t->tm_min);
}
else {
const auto hours = std::chrono::hours{t->tm_hour};
const auto time12H = date::make12(hours);
- hour->setCurrentValue(time12H.count());
- minute->setCurrentValue(t->tm_min);
+ hour->set_value(time12H.count());
+ minute->set_value(t->tm_min);
}
+
+ handleContentChanged();
}
auto TimeSetSpinnerVertical::getTime() const noexcept -> std::time_t
@@ 165,12 167,12 @@ namespace gui
const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
const auto newTime = std::localtime(&now);
if (timeFormat == Locale::TimeFormat::FormatTime24H) {
- newTime->tm_hour = hour->getCurrentValue();
+ newTime->tm_hour = hour->value();
}
else {
- newTime->tm_hour = date::make24(std::chrono::hours{hour->getCurrentValue()}, isPM()).count();
+ newTime->tm_hour = date::make24(std::chrono::hours{hour->value()}, isPM()).count();
}
- newTime->tm_min = minute->getCurrentValue();
+ newTime->tm_min = minute->value();
return std::mktime(newTime);
}