M image/assets/lang/Deutsch.json => image/assets/lang/Deutsch.json +1 -1
@@ 3,6 3,7 @@
"common_open": "ÖFFNEN",
"common_call": "ANRUFEN",
"common_save": "SPEICHERN",
+ "common_edit": "ÄNDERN",
"common_send": "SENDEN",
"common_confirm": "BESTÄTIGEN",
"common_select": "AUSWÄHLEN",
@@ 108,7 109,6 @@
"app_alarm_clock_snooze_15_min": "15 min",
"app_alarm_clock_snooze_30_min": "30 min",
"app_alarm_clock_play_pause": "PAUSE",
- "app_alarm_clock_edit": "ÄNDERN",
"app_calendar_title_main": "Kalender",
"app_calendar_options_edit": "Ändern",
"app_calendar_options_delete": "Löschen",
M image/assets/lang/English.json => image/assets/lang/English.json +3 -2
@@ 3,6 3,7 @@
"common_open": "OPEN",
"common_call": "CALL",
"common_save": "SAVE",
+ "common_edit": "EDIT",
"common_import": "IMPORT",
"common_send": "SEND",
"common_confirm": "CONFIRM",
@@ 101,7 102,7 @@
"app_alarm_clock_title_main": "Alarm clock",
"app_alarm_clock_repeat_never": "Never",
"app_alarm_clock_repeat_everyday": "Everyday",
- "app_alarm_clock_repeat_week_days": "Week Days",
+ "app_alarm_clock_repeat_week_days": "Weekdays",
"app_alarm_clock_repeat_custom": "Custom",
"app_alarm_clock_no_alarms_information": "<text align='center' color='9'>No alarms yet.<p>Press <b>left arrow</b> to add new.</p></text>",
"app_alarm_clock_options_title": "Options",
@@ 114,11 115,11 @@
"app_alarm_clock_sound": "Sound",
"app_alarm_clock_snooze": "Snooze",
"app_alarm_clock_repeat": "Repeat",
+ "app_alarm_clock_no_snooze": "None",
"app_alarm_clock_snooze_5_min": "5 min",
"app_alarm_clock_snooze_10_min": "10 min",
"app_alarm_clock_snooze_15_min": "15 min",
"app_alarm_clock_snooze_30_min": "30 min",
- "app_alarm_clock_edit": "EDIT",
"app_alarm_clock_custom_repeat_title": "Custom repeat",
"app_calendar_title_main": "Calendar",
"app_calendar_all_day": "All day",
M image/assets/lang/Espanol.json => image/assets/lang/Espanol.json +1 -1
@@ 3,6 3,7 @@
"common_open": "ABRIR",
"common_call": "LLAMAR",
"common_save": "GUARDAR",
+ "common_edit": "EDITAR",
"common_send": "ENVIAR",
"common_confirm": "CONFIRMAR",
"common_select": "SELECCIONAR",
@@ 108,7 109,6 @@
"app_alarm_clock_snooze_15_min": "15 min",
"app_alarm_clock_snooze_30_min": "30 min",
"app_alarm_clock_play_pause": "REPRODUCIR/PAUSA",
- "app_alarm_clock_edit": "EDITAR",
"app_calendar_title_main": "Calendario",
"app_calendar_options_edit": "Editar",
"app_calendar_options_delete": "Eliminar",
M image/assets/lang/Francais.json => image/assets/lang/Francais.json +1 -1
@@ 3,6 3,7 @@
"common_open": "OUVRIR",
"common_call": "APPELER",
"common_save": "SAUVEGARDER",
+ "common_edit": "MODIFIER",
"common_send": "ENVOYER",
"common_confirm": "CONFIRMER",
"common_select": "SÉLECTIONNER",
@@ 112,7 113,6 @@
"app_alarm_clock_snooze_15_min": "15 min",
"app_alarm_clock_snooze_30_min": "30 min",
"app_alarm_clock_play_pause": "JOUER/PAUSE",
- "app_alarm_clock_edit": "MODIFIER",
"app_alarm_clock_custom_repeat_title": "Custom repeat",
"app_calendar_title_main": "Calendrier",
"app_calendar_all_day": "Toute la journée",
M image/assets/lang/Polski.json => image/assets/lang/Polski.json +1 -1
@@ 3,6 3,7 @@
"common_open": "OTWÓRZ",
"common_call": "ZADZWOŃ",
"common_save": "ZAPISZ",
+ "common_edit": "EDYTUJ",
"common_send": "WYŚLIJ",
"common_confirm": "POTWIERDŹ",
"common_select": "WYBIERZ",
@@ 108,7 109,6 @@
"app_alarm_clock_snooze_15_min": "15 min",
"app_alarm_clock_snooze_30_min": "30 min",
"app_alarm_clock_play_pause": "ODTWARZAJ/ZATRZYMAJ",
- "app_alarm_clock_edit": "EDYTUJ",
"app_calendar_title_main": "Kalendarz",
"app_calendar_options_edit": "Edytuj",
"app_calendar_options_delete": "Usuń",
M image/assets/lang/Svenska.json => image/assets/lang/Svenska.json +1 -1
@@ 3,6 3,7 @@
"common_open": "ÖPPNA",
"common_call": "RING",
"common_save": "SPARA",
+ "common_edit": "REDIGERA",
"common_send": "SKICKA",
"common_confirm": "BEKRÄFTA",
"common_select": "VÄLJ",
@@ 101,7 102,6 @@
"app_alarm_clock_snooze_15_min": "15 min",
"app_alarm_clock_snooze_30_min": "30 min",
"app_alarm_clock_play_pause": "SPELA/PAUSA",
- "app_alarm_clock_edit": "REDIGERA",
"app_alarm_clock_custom_repeat_title": "Välj veckodagar",
"app_calendar_title_main": "Kalender",
"app_calendar_all_day": "Hela dagen",
M module-apps/application-alarm-clock/ApplicationAlarmClock.cpp => module-apps/application-alarm-clock/ApplicationAlarmClock.cpp +20 -14
@@ 69,20 69,26 @@ namespace app
auto presenter = std::make_unique<alarmClock::AlarmClockMainWindowPresenter>(alarmsProvider);
return std::make_unique<alarmClock::AlarmClockMainWindow>(app, std::move(presenter));
});
- windowsFactory.attach(
- style::alarmClock::window::name::newEditAlarm, [](ApplicationCommon *app, const std::string &name) {
- auto alarmsRepository = std::make_unique<alarmClock::AlarmsDBRepository>(app);
- auto alarmsProvider = std::make_shared<alarmClock::NewEditAlarmModel>(app, std::move(alarmsRepository));
- auto presenter = std::make_unique<alarmClock::AlarmClockEditWindowPresenter>(alarmsProvider);
- return std::make_unique<alarmClock::NewEditAlarmWindow>(app, std::move(presenter));
- });
- windowsFactory.attach(
- style::alarmClock::window::name::customRepeat, [](ApplicationCommon *app, const std::string &name) {
- auto alarmsRepository = std::make_unique<alarmClock::AlarmsDBRepository>(app);
- auto alarmsProvider = std::make_shared<alarmClock::CustomRepeatModel>(app, std::move(alarmsRepository));
- auto presenter = std::make_unique<alarmClock::CustomRepeatWindowPresenter>(alarmsProvider);
- return std::make_unique<alarmClock::CustomRepeatWindow>(app, std::move(presenter));
- });
+
+ auto rRulePresenter = std::make_shared<alarmClock::AlarmRRulePresenter>();
+
+ windowsFactory.attach(style::alarmClock::window::name::newEditAlarm,
+ [rRulePresenter](ApplicationCommon *app, const std::string &name) {
+ auto alarmsRepository = std::make_unique<alarmClock::AlarmsDBRepository>(app);
+ auto alarmsProvider = std::make_shared<alarmClock::NewEditAlarmModel>(
+ app, rRulePresenter, std::move(alarmsRepository), !stm::api::isTimeFormat12h());
+ auto presenter =
+ std::make_unique<alarmClock::AlarmClockEditWindowPresenter>(alarmsProvider);
+ return std::make_unique<alarmClock::NewEditAlarmWindow>(app, std::move(presenter));
+ });
+ windowsFactory.attach(style::alarmClock::window::name::customRepeat,
+ [rRulePresenter](ApplicationCommon *app, const std::string &name) {
+ auto alarmsProvider =
+ std::make_shared<alarmClock::CustomRepeatModel>(app, rRulePresenter);
+ auto presenter =
+ std::make_unique<alarmClock::CustomRepeatWindowPresenter>(alarmsProvider);
+ return std::make_unique<alarmClock::CustomRepeatWindow>(app, std::move(presenter));
+ });
windowsFactory.attach(utils::translate("app_alarm_clock_options_title"),
[](ApplicationCommon *app, const std::string &name) {
return std::make_unique<gui::OptionWindow>(app, name);
M module-apps/application-alarm-clock/ApplicationAlarmClock.hpp => module-apps/application-alarm-clock/ApplicationAlarmClock.hpp +1 -1
@@ 16,7 16,7 @@ namespace app
std::string parent,
sys::phone_modes::PhoneMode phoneMode = sys::phone_modes::PhoneMode::Connected,
sys::bluetooth::BluetoothMode bluetoothMode = sys::bluetooth::BluetoothMode::Disabled,
- uint32_t stackDepth = 4096,
+ uint32_t stackDepth = 4096 * 2,
sys::ServicePriority priority = sys::ServicePriority::Idle);
sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;
M module-apps/application-alarm-clock/CMakeLists.txt => module-apps/application-alarm-clock/CMakeLists.txt +4 -3
@@ 13,13 13,14 @@ target_sources( ${PROJECT_NAME}
"${CMAKE_CURRENT_LIST_DIR}/widgets/AlarmItem.cpp"
"${CMAKE_CURRENT_LIST_DIR}/widgets/AlarmTimeItem.cpp"
"${CMAKE_CURRENT_LIST_DIR}/widgets/AlarmOptionsItem.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/widgets/AlarmSnoozeOptionsItem.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/widgets/AlarmMusicOptionsItem.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/widgets/AlarmRRuleOptionsItem.cpp"
"${CMAKE_CURRENT_LIST_DIR}/widgets/CustomCheckBoxWithLabel.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/widgets/addedit/AlarmOptionRepeat.cpp"
"${CMAKE_CURRENT_LIST_DIR}/presenter/AlarmClockMainWindowPresenter.cpp"
"${CMAKE_CURRENT_LIST_DIR}/presenter/AlarmClockEditWindowPresenter.cpp"
"${CMAKE_CURRENT_LIST_DIR}/presenter/CustomRepeatWindowPresenter.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/presenter/AlarmPresenter.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/data/AlarmsData.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/presenter/AlarmRRulePresenter.cpp"
PUBLIC
"${CMAKE_CURRENT_LIST_DIR}/ApplicationAlarmClock.hpp"
"${CMAKE_CURRENT_LIST_DIR}/widgets/AlarmClockStyle.hpp"
D module-apps/application-alarm-clock/data/AlarmsData.cpp => module-apps/application-alarm-clock/data/AlarmsData.cpp +0 -48
@@ 1,48 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 "AlarmsData.hpp"
-#include <map>
-
-static const std::map<WeekDayIso, const char *> weekDaysAbbreviation = {{WeekDayIso::Monday, "common_mon"},
- {WeekDayIso::Tuesday, "common_tue"},
- {WeekDayIso::Wednesday, "common_wed"},
- {WeekDayIso::Thursday, "common_thu"},
- {WeekDayIso::Friday, "common_fri"},
- {WeekDayIso::Saturday, "common_sat"},
- {WeekDayIso::Sunday, "common_sun"}};
-
-CustomRepeatValueParser::CustomRepeatValueParser(uint32_t repeatValue)
-{
- OptionParser parser;
- weekDayData = parser.setWeekDayOptions(repeatValue, std::make_unique<WeekDaysRepeatData>());
-}
-
-std::string CustomRepeatValueParser::getWeekDaysText() const
-{
- std::string weekDaysText;
- for (auto const &[key, val] : weekDaysAbbreviation) {
- if (weekDayData->getData(static_cast<uint32_t>(key))) {
- weekDaysText += utils::translate(val) + ", ";
- }
- }
- if (!weekDaysText.empty()) {
- weekDaysText.erase(weekDaysText.end() - 2);
- }
- return weekDaysText;
-}
-
-bool CustomRepeatValueParser::isCustomValueWeekDays() const
-{
- return weekDayData->getData(static_cast<uint32_t>(WeekDayIso::Monday)) &&
- weekDayData->getData(static_cast<uint32_t>(WeekDayIso::Tuesday)) &&
- weekDayData->getData(static_cast<uint32_t>(WeekDayIso::Wednesday)) &&
- weekDayData->getData(static_cast<uint32_t>(WeekDayIso::Thursday)) &&
- weekDayData->getData(static_cast<uint32_t>(WeekDayIso::Friday));
-}
-
-bool CustomRepeatValueParser::isCustomValueEveryday() const
-{
- return isCustomValueWeekDays() && weekDayData->getData(static_cast<uint32_t>(WeekDayIso::Saturday)) &&
- weekDayData->getData(static_cast<uint32_t>(WeekDayIso::Sunday));
-}
M module-apps/application-alarm-clock/data/AlarmsData.hpp => module-apps/application-alarm-clock/data/AlarmsData.hpp +0 -38
@@ 3,42 3,15 @@
#pragma once
-#include "application-calendar/data/OptionParser.hpp"
#include <module-db/Interface/AlarmEventRecord.hpp>
#include <SwitchData.hpp>
-enum class AlarmSnooze
-{
- FiveMinutes = 5,
- TenMinutes = 10,
- FifteenMinutes = 15,
- ThirtyMinutes = 30
-};
-
-enum class AlarmOptionItemName
-{
- Sound,
- Snooze,
- Repeat
-};
-
enum class AlarmAction
{
Add,
Edit
};
-enum class WeekDayIso
-{
- Monday = date::Monday.iso_encoding() - 1,
- Tuesday,
- Wednesday,
- Thursday,
- Friday,
- Saturday,
- Sunday
-};
-
class AlarmRecordData : public gui::SwitchData
{
protected:
@@ 57,14 30,3 @@ class AlarmRecordData : public gui::SwitchData
}
};
-class CustomRepeatValueParser
-{
- std::unique_ptr<WeekDaysRepeatData> weekDayData;
-
- public:
- explicit CustomRepeatValueParser(uint32_t repeatValue);
-
- [[nodiscard]] std::string getWeekDaysText() const;
- [[nodiscard]] bool isCustomValueWeekDays() const;
- [[nodiscard]] bool isCustomValueEveryday() const;
-};
M module-apps/application-alarm-clock/models/AlarmsModel.cpp => module-apps/application-alarm-clock/models/AlarmsModel.cpp +1 -1
@@ 44,7 44,7 @@ namespace app::alarmClock
return nullptr;
}
- auto item = new gui::AlarmItem(AlarmPresenter(record));
+ auto item = new gui::AlarmItem(std::make_shared<AlarmRRulePresenter>(record));
item->activatedCallback = [this, record](gui::Item &) {
record->enabled = !record->enabled;
alarmsRepository->update(*record, nullptr);
M module-apps/application-alarm-clock/models/CustomRepeatModel.cpp => module-apps/application-alarm-clock/models/CustomRepeatModel.cpp +29 -21
@@ 2,16 2,16 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "CustomRepeatModel.hpp"
-#include "application-alarm-clock/widgets/CustomCheckBoxWithLabel.hpp"
-#include "application-alarm-clock/widgets/AlarmClockStyle.hpp"
+
+#include <application-alarm-clock/widgets/AlarmClockStyle.hpp>
#include <ListView.hpp>
+#include <time/time_locale.hpp>
namespace app::alarmClock
{
-
CustomRepeatModel::CustomRepeatModel(app::ApplicationCommon *app,
- std::shared_ptr<AbstractAlarmsRepository> alarmsRepository)
- : application(app), alarmsRepository{std::move(alarmsRepository)}
+ std::shared_ptr<alarmClock::AlarmRRulePresenter> rRulePresenter)
+ : application(app), rRulePresenter(rRulePresenter)
{}
unsigned int CustomRepeatModel::requestRecordsCount()
@@ 21,7 21,7 @@ namespace app::alarmClock
unsigned int CustomRepeatModel::getMinimalItemSpaceRequired() const
{
- return style::alarmClock::window::item::checkBox::height;
+ return style::window::label::big_h + style::margins::big;
}
void CustomRepeatModel::requestRecords(uint32_t offset, uint32_t limit)
@@ 35,10 35,15 @@ namespace app::alarmClock
return getRecord(order);
}
- void CustomRepeatModel::createData(const WeekDaysRepeatData &data)
+ void CustomRepeatModel::createData()
{
- for (auto const &[key, dayName] : gui::CustomCheckBoxWithLabel::weekDays) {
- internalData.push_back(new gui::CustomCheckBoxWithLabel(application, utils::translate(dayName), data));
+ auto app = application;
+ for (auto const &[day, selected] : rRulePresenter->getCustomDays()) {
+ internalData.push_back(new gui::CustomCheckBoxWithLabel(
+ utils::translate(day),
+ selected,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text, false); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); }));
}
for (auto &item : internalData) {
@@ 46,30 51,33 @@ namespace app::alarmClock
}
}
- void CustomRepeatModel::loadData(const WeekDaysRepeatData &data)
+ void CustomRepeatModel::loadData()
{
list->reset();
eraseInternalData();
- createData(data);
+ createData();
list->rebuildList();
}
- std::vector<bool> CustomRepeatModel::getIsCheckedData()
+ void CustomRepeatModel::saveCheckedData()
{
- std::vector<bool> isCheckedData;
- isCheckedData.reserve(internalData.size());
- for (const auto &item : internalData) {
- if (item->onContentChangedCallback) {
- isCheckedData.push_back(item->onContentChangedCallback());
- }
- else {
- isCheckedData.push_back(false);
+ std::list<utl::Day> days = {};
+
+ for (unsigned int i = 0; i < internalData.size(); i++) {
+ if (internalData[i]->isChecked()) {
+ days.emplace_back(magic_enum::enum_cast<utl::Day>(i).value());
}
}
- return isCheckedData;
+ rRulePresenter->setOption(AlarmRRulePresenter::RRuleOptions::Custom, days);
+ }
+
+ void CustomRepeatModel::eraseData()
+ {
+ list->reset();
+ eraseInternalData();
}
} // namespace app::alarmClock
M module-apps/application-alarm-clock/models/CustomRepeatModel.hpp => module-apps/application-alarm-clock/models/CustomRepeatModel.hpp +15 -12
@@ 3,41 3,44 @@
#pragma once
-#include "application-alarm-clock/widgets/AlarmInternalListItem.hpp"
#include "application-alarm-clock/models/AlarmsRepository.hpp"
#include "application-alarm-clock/data/AlarmsData.hpp"
-#include "application-calendar/data/CalendarData.hpp"
-#include "Application.hpp"
-#include "InternalModel.hpp"
+#include <application-alarm-clock/widgets/CustomCheckBoxWithLabel.hpp>
+#include <application-alarm-clock/presenter/AlarmRRulePresenter.hpp>
+
+#include <Application.hpp>
+#include <InternalModel.hpp>
#include <ListItemProvider.hpp>
namespace app::alarmClock
{
- class CustomRepeatListItemProvider : public InternalModel<gui::AlarmInternalListItem *>,
+ class CustomRepeatListItemProvider : public InternalModel<gui::CustomCheckBoxWithLabel *>,
public gui::ListItemProvider
{
public:
CustomRepeatListItemProvider() = default;
- virtual void loadData(const WeekDaysRepeatData &data) = 0;
- virtual std::vector<bool> getIsCheckedData() = 0;
+ virtual void loadData() = 0;
+ virtual void eraseData() = 0;
+ virtual void saveCheckedData() = 0;
};
class CustomRepeatModel : public CustomRepeatListItemProvider
{
app::ApplicationCommon *application = nullptr;
- std::shared_ptr<AbstractAlarmsRepository> alarmsRepository;
- void createData(const WeekDaysRepeatData &data);
+ std::shared_ptr<app::alarmClock::AlarmRRulePresenter> rRulePresenter;
+ void createData();
public:
- CustomRepeatModel(app::ApplicationCommon *app, std::shared_ptr<AbstractAlarmsRepository> alarmsRepository);
+ CustomRepeatModel(app::ApplicationCommon *app, std::shared_ptr<alarmClock::AlarmRRulePresenter> rRulePresenter);
[[nodiscard]] unsigned int getMinimalItemSpaceRequired() const override;
[[nodiscard]] unsigned int requestRecordsCount() override;
[[nodiscard]] gui::ListItem *getItem(gui::Order order) override;
void requestRecords(uint32_t offset, uint32_t limit) override;
- void loadData(const WeekDaysRepeatData &data) override;
- std::vector<bool> getIsCheckedData() override;
+ void loadData() override;
+ void saveCheckedData() override;
+ void eraseData() override;
};
} // namespace app::alarmClock
M module-apps/application-alarm-clock/models/NewEditAlarmModel.cpp => module-apps/application-alarm-clock/models/NewEditAlarmModel.cpp +22 -18
@@ 2,18 2,24 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "NewEditAlarmModel.hpp"
-#include "application-alarm-clock/widgets/AlarmTimeItem.hpp"
-#include "application-alarm-clock/widgets/AlarmOptionsItem.hpp"
-#include "application-alarm-clock/widgets/addedit/AlarmOptionRepeat.hpp"
-#include "application-alarm-clock/widgets/AlarmClockStyle.hpp"
+
+#include <application-alarm-clock/widgets/AlarmTimeItem.hpp>
+#include <application-alarm-clock/widgets/AlarmSnoozeOptionsItem.hpp>
+#include <application-alarm-clock/widgets/AlarmMusicOptionsItem.hpp>
+#include <application-alarm-clock/widgets/AlarmRRuleOptionsItem.hpp>
+#include <application-alarm-clock/presenter/AlarmRRulePresenter.hpp>
+#include <application-alarm-clock/widgets/AlarmClockStyle.hpp>
+
#include <ListView.hpp>
namespace app::alarmClock
{
NewEditAlarmModel::NewEditAlarmModel(app::ApplicationCommon *app,
+ std::shared_ptr<alarmClock::AlarmRRulePresenter> rRulePresenter,
std::shared_ptr<AbstractAlarmsRepository> alarmsRepository,
bool mode24H)
- : application(app), alarmsRepository{std::move(alarmsRepository)}, mode24H(mode24H)
+ : application(app), alarmsRepository{std::move(alarmsRepository)}, rRulePresenter(rRulePresenter),
+ mode24H(mode24H)
{}
unsigned int NewEditAlarmModel::requestRecordsCount()
@@ 23,7 29,7 @@ namespace app::alarmClock
unsigned int NewEditAlarmModel::getMinimalItemSpaceRequired() const
{
- return style::alarmClock::window::item::options::height;
+ return style::alarmClock::window::item::options::h;
}
void NewEditAlarmModel::requestRecords(uint32_t offset, uint32_t limit)
@@ 37,7 43,7 @@ namespace app::alarmClock
return getRecord(order);
}
- void NewEditAlarmModel::createData(std::shared_ptr<AlarmEventRecord> record)
+ void NewEditAlarmModel::createData()
{
auto app = application;
assert(app != nullptr);
@@ 46,22 52,19 @@ namespace app::alarmClock
mode24H,
[app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text, false); },
[app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); }));
- internalData.push_back(new gui::AlarmOptionsItem(
- application,
- AlarmOptionItemName::Sound,
- [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text, false); },
- [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); }));
- internalData.push_back(new gui::AlarmOptionsItem(
+ internalData.push_back(new gui::AlarmMusicOptionsItem(
application,
- AlarmOptionItemName::Snooze,
+ utils::translate("app_alarm_clock_sound"),
[app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text, false); },
[app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); }));
- internalData.push_back(new gui::AlarmOptionRepeat(
+ internalData.push_back(new gui::AlarmSnoozeOptionsItem(utils::translate("app_alarm_clock_snooze")));
+
+ internalData.push_back(new gui::AlarmRRuleOptionsItem(
application,
- AlarmOptionItemName::Repeat,
- AlarmPresenter(record),
+ utils::translate("app_alarm_clock_repeat"),
+ rRulePresenter,
[app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text, false); },
[app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); }));
@@ 75,7 78,8 @@ namespace app::alarmClock
list->reset();
eraseInternalData();
- createData(record);
+ rRulePresenter->loadRecord(record);
+ createData();
for (auto &item : internalData) {
if (item->onLoadCallback) {
M module-apps/application-alarm-clock/models/NewEditAlarmModel.hpp => module-apps/application-alarm-clock/models/NewEditAlarmModel.hpp +10 -6
@@ 3,11 3,13 @@
#pragma once
-#include "application-alarm-clock/widgets/AlarmInternalListItem.hpp"
-#include "application-alarm-clock/models/AlarmsRepository.hpp"
-#include "application-alarm-clock/data/AlarmsData.hpp"
-#include "Application.hpp"
-#include "InternalModel.hpp"
+#include <application-alarm-clock/widgets/AlarmInternalListItem.hpp>
+#include <application-alarm-clock/models/AlarmsRepository.hpp>
+#include <application-alarm-clock/data/AlarmsData.hpp>
+#include <application-alarm-clock/presenter/AlarmRRulePresenter.hpp>
+
+#include <Application.hpp>
+#include <InternalModel.hpp>
#include <ListItemProvider.hpp>
#include <module-db/Interface/AlarmEventRecord.hpp>
@@ 28,18 30,20 @@ namespace app::alarmClock
{
app::ApplicationCommon *application = nullptr;
std::shared_ptr<AbstractAlarmsRepository> alarmsRepository;
+ std::shared_ptr<alarmClock::AlarmRRulePresenter> rRulePresenter;
gui::AlarmInternalListItem *repeatOption = nullptr;
bool mode24H = false;
public:
NewEditAlarmModel(app::ApplicationCommon *app,
+ std::shared_ptr<alarmClock::AlarmRRulePresenter> rRulePresenter,
std::shared_ptr<AbstractAlarmsRepository> alarmsRepository,
bool mode24H = false);
void loadData(std::shared_ptr<AlarmEventRecord> record) override;
void saveData(std::shared_ptr<AlarmEventRecord> alarm, AlarmAction action) override;
void loadRepeat(std::shared_ptr<AlarmEventRecord> record) override;
- void createData(std::shared_ptr<AlarmEventRecord> record);
+ void createData();
[[nodiscard]] unsigned int getMinimalItemSpaceRequired() const override;
[[nodiscard]] unsigned int requestRecordsCount() override;
M module-apps/application-alarm-clock/presenter/AlarmClockEditWindowPresenter.cpp => module-apps/application-alarm-clock/presenter/AlarmClockEditWindowPresenter.cpp +0 -8
@@ 25,12 25,4 @@ namespace app::alarmClock
alarmFieldsProvider->saveData(std::move(record), action);
}
- void AlarmClockEditWindowPresenter::loadRepeat(std::shared_ptr<AlarmEventRecord> record)
- {
- alarmFieldsProvider->loadRepeat(std::move(record));
- }
-
- void AlarmClockEditWindowPresenter::updateRepeat(std::shared_ptr<AlarmEventRecord> record, WeekDaysRepeatData data)
- {
- }
} // namespace app::alarmClock
M module-apps/application-alarm-clock/presenter/AlarmClockEditWindowPresenter.hpp => module-apps/application-alarm-clock/presenter/AlarmClockEditWindowPresenter.hpp +0 -4
@@ 25,8 25,6 @@ namespace app::alarmClock
[[nodiscard]] virtual std::shared_ptr<gui::ListItemProvider> getAlarmsItemProvider() const = 0;
virtual void loadData(std::shared_ptr<AlarmEventRecord> record) = 0;
virtual void saveData(std::shared_ptr<AlarmEventRecord> record, AlarmAction action) = 0;
- virtual void loadRepeat(std::shared_ptr<AlarmEventRecord> record) = 0;
- virtual void updateRepeat(std::shared_ptr<AlarmEventRecord> record, WeekDaysRepeatData data) = 0;
};
};
@@ 38,8 36,6 @@ namespace app::alarmClock
[[nodiscard]] std::shared_ptr<gui::ListItemProvider> getAlarmsItemProvider() const override;
void loadData(std::shared_ptr<AlarmEventRecord> record) override;
void saveData(std::shared_ptr<AlarmEventRecord> record, AlarmAction action) override;
- void loadRepeat(std::shared_ptr<AlarmEventRecord> record) override;
- void updateRepeat(std::shared_ptr<AlarmEventRecord> record, WeekDaysRepeatData data) override;
private:
std::shared_ptr<AlarmsInternalListItemProvider> alarmFieldsProvider;
R module-apps/application-alarm-clock/presenter/AlarmPresenter.cpp => module-apps/application-alarm-clock/presenter/AlarmRRulePresenter.cpp +53 -31
@@ 1,13 1,20 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "AlarmPresenter.hpp"
+#include "AlarmRRulePresenter.hpp"
#include "log.hpp"
namespace app::alarmClock
{
+ AlarmRRulePresenter::AlarmRRulePresenter(std::shared_ptr<AlarmEventRecord> recordToLoad) : alarm(recordToLoad)
+ {}
- utl::Day AlarmPresenter::dayToDay(uint32_t day_no)
+ void AlarmRRulePresenter::loadRecord(std::shared_ptr<AlarmEventRecord> recordToLoad)
+ {
+ alarm = std::move(recordToLoad);
+ }
+
+ utl::Day AlarmRRulePresenter::dayToDay(uint32_t day_no)
{
if (day_no == uint8_t(rrule::RRule::RRuleWeekday::SUNDAY_WEEKDAY)) {
return utl::Sun;
@@ 15,7 22,7 @@ namespace app::alarmClock
return utl::Day(day_no - 1);
}
- uint8_t AlarmPresenter::dayToDay(utl::Day day)
+ uint8_t AlarmRRulePresenter::dayToDay(utl::Day day)
{
if (day == utl::Sun) {
return uint8_t(rrule::RRule::RRuleWeekday::SUNDAY_WEEKDAY);
@@ 23,7 30,7 @@ namespace app::alarmClock
return day + 1;
}
- uint8_t AlarmPresenter::set_bit_days()
+ uint8_t AlarmRRulePresenter::setBitDays()
{
const auto &rr = rrule::RRule(alarm->rruleText);
uint8_t days = 0;
@@ 38,15 45,19 @@ namespace app::alarmClock
return days;
}
- UTF8 AlarmPresenter::getDescription()
+ UTF8 AlarmRRulePresenter::getDescription()
{
- auto setDays = set_bit_days();
+ auto setDays = setBitDays();
+ if (setDays == 0) {
+ return utils::translate("app_alarm_clock_repeat_never");
+ }
if (setDays == weekdaysMask) {
return utils::translate("app_alarm_clock_repeat_week_days");
}
if (setDays == weekMask) {
return utils::translate("app_alarm_clock_repeat_everyday");
}
+
UTF8 retval = "";
if (setDays > 0) {
for (unsigned int i = 0; i < utl::num_days; ++i) {
@@ 62,17 73,22 @@ namespace app::alarmClock
return retval;
}
- AlarmPresenter::Spinner AlarmPresenter::getSpinner()
+ bool AlarmRRulePresenter::isDaySet(uint8_t &days, uint8_t day)
{
- auto setDays = set_bit_days();
+ return 0x1 & (days >> day);
+ }
+
+ AlarmRRulePresenter::RRuleOptions AlarmRRulePresenter::getOption()
+ {
+ auto setDays = setBitDays();
if (setDays == 0) {
- return Spinner::Never;
+ return RRuleOptions::Never;
}
if (setDays == weekdaysMask) {
- return Spinner::Weekdays;
+ return RRuleOptions::Weekdays;
}
if (setDays == weekMask) {
- return Spinner::Weekly;
+ return RRuleOptions::Everyday;
}
auto get_set_days_count = [&]() {
uint8_t singleday = 0;
@@ 82,38 98,45 @@ namespace app::alarmClock
return singleday;
};
if (get_set_days_count() == 1) {
- return Spinner::OnDay;
+ return RRuleOptions::OnDay;
}
- return Spinner::Custom;
+ return RRuleOptions::Custom;
}
- void AlarmPresenter::setSpinner(AlarmPresenter::Spinner spin,
- const std::function<void(AlarmPresenter::Spinner)> &cb)
+ std::vector<std::pair<std::string, bool>> AlarmRRulePresenter::getCustomDays()
{
- switch (spin) {
- case AlarmPresenter::Spinner::Never:
+ std::vector<std::pair<std::string, bool>> selectedDays;
+ auto setDays = setBitDays();
+
+ for (unsigned int i = 0; i < utl::num_days; ++i) {
+ selectedDays.push_back({utils::time::Locale::get_day(i), isDaySet(setDays, i)});
+ }
+
+ return selectedDays;
+ }
+
+ void AlarmRRulePresenter::setOption(AlarmRRulePresenter::RRuleOptions options, const std::list<utl::Day> &days)
+ {
+ switch (options) {
+ case AlarmRRulePresenter::RRuleOptions::Never:
setDays({});
break;
- case AlarmPresenter::Spinner::OnDay:
- if (cb != nullptr) {
- cb(spin);
- }
+ case AlarmRRulePresenter::RRuleOptions::OnDay:
+ setDays(days);
break;
- case AlarmPresenter::Spinner::Custom:
- if (cb != nullptr) {
- cb(spin);
- }
+ case AlarmRRulePresenter::RRuleOptions::Custom:
+ setDays(days);
break;
- case AlarmPresenter::Spinner::Weekly:
+ case AlarmRRulePresenter::RRuleOptions::Everyday:
setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri, utl::Sat, utl::Sun});
break;
- case AlarmPresenter::Spinner::Weekdays:
+ case AlarmRRulePresenter::RRuleOptions::Weekdays:
setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri});
break;
}
}
- void AlarmPresenter::setDays(const std::list<utl::Day> &days)
+ void AlarmRRulePresenter::setDays(const std::list<utl::Day> &days)
{
if (days.empty()) {
alarm->rruleText = "";
@@ 130,10 153,10 @@ namespace app::alarmClock
}
}
- std::list<utl::Day> AlarmPresenter::getDays()
+ std::list<utl::Day> AlarmRRulePresenter::getDays()
{
std::list<utl::Day> ret;
- auto setDays = set_bit_days();
+ auto setDays = setBitDays();
for (unsigned int i = 0; i < utl::num_days; ++i) {
if ((0x1 & (setDays >> i)) != 0) {
ret.push_back(utl::Day(i));
@@ 141,5 164,4 @@ namespace app::alarmClock
}
return ret;
}
-
} // namespace app::alarmClock
R module-apps/application-alarm-clock/presenter/AlarmPresenter.hpp => module-apps/application-alarm-clock/presenter/AlarmRRulePresenter.hpp +26 -17
@@ 18,51 18,59 @@ namespace app::alarmClock
{
typedef utils::time::Locale utl;
- class AlarmPresenter;
+ class AlarmRRulePresenter;
- class AlarmEventItem;
+ class AlarmRRuleItem;
- class AlarmPresenter
+ class AlarmRRulePresenter
{
private:
/// our model
std::shared_ptr<AlarmEventRecord> alarm;
/// view managed
+ /// check if day is set
+ [[nodiscard]] bool isDaySet(uint8_t &days, uint8_t day);
+
protected:
/// changes day from lib to our days from monday
utl::Day dayToDay(uint32_t day_no);
/// changes day from our days to lib format
uint8_t dayToDay(utl::Day);
- uint8_t set_bit_days();
+ uint8_t setBitDays();
static constexpr uint8_t weekdaysMask = 0b0111110;
static constexpr uint8_t weekMask = 0b1111111;
public:
- enum class Spinner
+ enum class RRuleOptions
{
Never, /// we do not have any events set
OnDay, /// we have event on some - single day
Custom, /// there is some custom setup i.e. weekly + sunday - monday
- Weekly, /// everyday occurrence
+ Everyday, /// everyday occurrence
Weekdays, /// every monday to friday occurrence
};
- virtual ~AlarmPresenter() = default;
- explicit AlarmPresenter(std::shared_ptr<AlarmEventRecord> alarm) : alarm(std::move(alarm)){};
+ virtual ~AlarmRRulePresenter() = default;
+ explicit AlarmRRulePresenter(){};
+ explicit AlarmRRulePresenter(std::shared_ptr<AlarmEventRecord> recordToLoad);
+
+ void loadRecord(std::shared_ptr<AlarmEventRecord> recordToLoad);
/// get description for days in week as a coma separated string days, or weekday etc
UTF8 getDescription();
/// get information what time of occurrences we have in rrule
- /// please see `enum::Spinner` for more details
- Spinner getSpinner();
- /// set proper rrule from spinner
- void setSpinner(Spinner, const std::function<void(Spinner)> &cb);
+ /// please see `enum::RRuleOptions` for more details
+ RRuleOptions getOption();
+ /// set proper rrule from Options spinner
+ void setOption(RRuleOptions, const std::list<utl::Day> &days = {});
/// set values in model based on list of Enums (Mon, Tue etc)
void setDays(const std::list<utl::Day> &days);
/// get values in model as a list
std::list<utl::Day> getDays();
+ /// get custom days vector with selected days
+ std::vector<std::pair<std::string, bool>> getCustomDays();
/// if rrule is empty we can safely assume that there is no recurrence in the event
bool hasRecurrence() const
@@ 76,18 84,19 @@ namespace app::alarmClock
}
};
- class AlarmEventItem
+ class AlarmRRuleItem
{
- AlarmPresenter p;
+ std::shared_ptr<app::alarmClock::AlarmRRulePresenter> presenter;
protected:
- auto &presenter()
+ auto &getPresenter()
{
- return p;
+ return presenter;
}
public:
- explicit AlarmEventItem(AlarmPresenter p) : p(p)
+ explicit AlarmRRuleItem(std::shared_ptr<app::alarmClock::AlarmRRulePresenter> presenter)
+ : presenter(std::move(presenter))
{}
};
M module-apps/application-alarm-clock/presenter/CustomRepeatWindowPresenter.cpp => module-apps/application-alarm-clock/presenter/CustomRepeatWindowPresenter.cpp +10 -12
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "CustomRepeatWindowPresenter.hpp"
@@ 15,20 15,18 @@ namespace app::alarmClock
return customRepeatProvider;
}
- void CustomRepeatWindowPresenter::loadData(const WeekDaysRepeatData &data)
+ void CustomRepeatWindowPresenter::loadData()
{
- customRepeatProvider->loadData(data);
+ customRepeatProvider->loadData();
}
- WeekDaysRepeatData CustomRepeatWindowPresenter::getWeekDaysRepeatData()
+ void CustomRepeatWindowPresenter::eraseProviderData()
{
- auto weekDaysOptData = WeekDaysRepeatData();
- auto isCheckedData = customRepeatProvider->getIsCheckedData();
- uint32_t i = 0;
- for (const auto &checked : isCheckedData) {
- weekDaysOptData.setData(i, checked);
- ++i;
- }
- return weekDaysOptData;
+ customRepeatProvider->eraseData();
+ }
+
+ void CustomRepeatWindowPresenter::saveData()
+ {
+ customRepeatProvider->saveCheckedData();
}
} // namespace app::alarmClock
M module-apps/application-alarm-clock/presenter/CustomRepeatWindowPresenter.hpp => module-apps/application-alarm-clock/presenter/CustomRepeatWindowPresenter.hpp +7 -5
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 23,8 23,9 @@ namespace app::alarmClock
virtual ~Presenter() noexcept = default;
[[nodiscard]] virtual std::shared_ptr<gui::ListItemProvider> getItemProvider() = 0;
- virtual void loadData(const WeekDaysRepeatData &data) = 0;
- virtual WeekDaysRepeatData getWeekDaysRepeatData() = 0;
+ virtual void loadData() = 0;
+ virtual void saveData() = 0;
+ virtual void eraseProviderData() = 0;
};
};
@@ 34,8 35,9 @@ namespace app::alarmClock
explicit CustomRepeatWindowPresenter(std::shared_ptr<CustomRepeatListItemProvider> itemProvider);
[[nodiscard]] std::shared_ptr<gui::ListItemProvider> getItemProvider() override;
- void loadData(const WeekDaysRepeatData &data) override;
- WeekDaysRepeatData getWeekDaysRepeatData() override;
+ void loadData() override;
+ void saveData() override;
+ void eraseProviderData() override;
private:
std::shared_ptr<CustomRepeatListItemProvider> customRepeatProvider;
M module-apps/application-alarm-clock/tests/test-AlarmPresenter.cpp => module-apps/application-alarm-clock/tests/test-AlarmPresenter.cpp +49 -20
@@ 2,24 2,24 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
-#include <application-alarm-clock/presenter/AlarmPresenter.hpp>
+#include <application-alarm-clock/presenter/AlarmRRulePresenter.hpp>
using namespace app::alarmClock;
-class PubPresenter : public AlarmPresenter
+class PubPresenter : public AlarmRRulePresenter
{
public:
- PubPresenter() : AlarmPresenter(std::make_shared<AlarmEventRecord>())
+ PubPresenter() : AlarmRRulePresenter(std::make_shared<AlarmEventRecord>())
{}
utl::Day dayToDay(uint32_t day_no)
{
- return AlarmPresenter::dayToDay(day_no);
+ return AlarmRRulePresenter::dayToDay(day_no);
}
uint8_t dayToDay(utl::Day day)
{
- return AlarmPresenter::dayToDay(day);
+ return AlarmRRulePresenter::dayToDay(day);
}
};
@@ 32,7 32,7 @@ TEST_CASE("transformations test")
TEST_CASE("empty rrule")
{
std::shared_ptr<AlarmEventRecord> alarm;
- AlarmPresenter presenter(alarm);
+ AlarmRRulePresenter presenter(alarm);
REQUIRE(!presenter.hasRecurrence());
}
@@ 40,7 40,7 @@ TEST_CASE("empty rrule")
TEST_CASE("recurrence rule get & set")
{
auto alarm = std::make_shared<AlarmEventRecord>();
- AlarmPresenter presenter(alarm);
+ AlarmRRulePresenter presenter(alarm);
SECTION("no recurrence")
{
@@ 51,7 51,7 @@ TEST_CASE("recurrence rule get & set")
{
alarm->rruleText = "FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA;INTERVAL=1";
REQUIRE(presenter.hasRecurrence());
- REQUIRE(presenter.getSpinner() == AlarmPresenter::Spinner::Weekly);
+ REQUIRE(presenter.getOption() == AlarmRRulePresenter::RRuleOptions::Everyday);
REQUIRE(presenter.getDays().size() == 7);
}
@@ 78,62 78,91 @@ TEST_CASE("recurrence rule get & set")
}
}
-TEST_CASE("getSpinner")
+TEST_CASE("getOptions")
{
auto alarm = std::make_shared<AlarmEventRecord>();
- AlarmPresenter presenter(alarm);
+ AlarmRRulePresenter presenter(alarm);
SECTION("nothing")
{
- REQUIRE(presenter.getSpinner() == AlarmPresenter::Spinner::Never);
+ REQUIRE(presenter.getOption() == AlarmRRulePresenter::RRuleOptions::Never);
}
SECTION("weekdays")
{
presenter.setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri});
- REQUIRE(presenter.getSpinner() == AlarmPresenter::Spinner::Weekdays);
+ REQUIRE(presenter.getOption() == AlarmRRulePresenter::RRuleOptions::Weekdays);
}
SECTION("week")
{
presenter.setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri, utl::Sat, utl::Sun});
- REQUIRE(presenter.getSpinner() == AlarmPresenter::Spinner::Weekly);
+ REQUIRE(presenter.getOption() == AlarmRRulePresenter::RRuleOptions::Everyday);
}
SECTION("custom")
{
presenter.setDays({utl::Tue, utl::Wed, utl::Thu, utl::Fri, utl::Sat, utl::Sun});
- REQUIRE(presenter.getSpinner() == AlarmPresenter::Spinner::Custom);
+ REQUIRE(presenter.getOption() == AlarmRRulePresenter::RRuleOptions::Custom);
}
SECTION("signle day")
{
presenter.setDays({utl::Tue});
- REQUIRE(presenter.getSpinner() == AlarmPresenter::Spinner::OnDay);
+ REQUIRE(presenter.getOption() == AlarmRRulePresenter::RRuleOptions::OnDay);
}
}
-TEST_CASE("setSpinner")
+TEST_CASE("getCustomDays")
{
auto alarm = std::make_shared<AlarmEventRecord>();
- AlarmPresenter presenter(alarm);
+ AlarmRRulePresenter presenter(alarm);
+
+ std::list<utl::Day> days = {utl::Sun, utl::Wed, utl::Fri};
+ presenter.setOption(AlarmRRulePresenter::RRuleOptions::Custom, days);
+
+ REQUIRE(presenter.getCustomDays()[0] == std::pair<std::string, bool>{utils::time::Locale::get_day(utl::Sun), true});
+ REQUIRE(presenter.getCustomDays()[1] ==
+ std::pair<std::string, bool>{utils::time::Locale::get_day(utl::Mon), false});
+ REQUIRE(presenter.getCustomDays()[2] ==
+ std::pair<std::string, bool>{utils::time::Locale::get_day(utl::Tue), false});
+ REQUIRE(presenter.getCustomDays()[3] == std::pair<std::string, bool>{utils::time::Locale::get_day(utl::Wed), true});
+ REQUIRE(presenter.getCustomDays()[4] ==
+ std::pair<std::string, bool>{utils::time::Locale::get_day(utl::Thu), false});
+ REQUIRE(presenter.getCustomDays()[5] == std::pair<std::string, bool>{utils::time::Locale::get_day(utl::Fri), true});
+ REQUIRE(presenter.getCustomDays()[6] ==
+ std::pair<std::string, bool>{utils::time::Locale::get_day(utl::Sat), false});
+}
+
+TEST_CASE("setOptions")
+{
+ auto alarm = std::make_shared<AlarmEventRecord>();
+ AlarmRRulePresenter presenter(alarm);
SECTION("nothing")
{
- presenter.setSpinner(AlarmPresenter::Spinner::Never, nullptr);
+ presenter.setOption(AlarmRRulePresenter::RRuleOptions::Never);
REQUIRE(presenter.getDays().empty());
}
SECTION("weekdays")
{
- presenter.setSpinner(AlarmPresenter::Spinner::Weekdays, nullptr);
+ presenter.setOption(AlarmRRulePresenter::RRuleOptions::Weekdays);
REQUIRE(presenter.getDays() == std::list<utl::Day>{utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri});
}
SECTION("week")
{
- presenter.setSpinner(AlarmPresenter::Spinner::Weekly, nullptr);
+ presenter.setOption(AlarmRRulePresenter::RRuleOptions::Everyday);
REQUIRE(presenter.getDays() ==
std::list<utl::Day>{utl::Sun, utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri, utl::Sat});
}
+
+ SECTION("custom")
+ {
+ std::list<utl::Day> days = {utl::Sun, utl::Wed, utl::Fri};
+
+ presenter.setOption(AlarmRRulePresenter::RRuleOptions::Custom, days);
+ REQUIRE(presenter.getDays() == days);
+ }
}
M module-apps/application-alarm-clock/widgets/AlarmClockStyle.hpp => module-apps/application-alarm-clock/widgets/AlarmClockStyle.hpp +9 -19
@@ 21,43 21,33 @@ namespace style::alarmClock
{
inline constexpr auto newEditAlarm = "NewEditWindow";
inline constexpr auto customRepeat = "CustomRepeat";
- inline constexpr auto dialogYesNo = "DialogYesNo";
- }
+ inline constexpr auto dialogYesNo = "DialogYesNo";
+ } // namespace name
namespace item
{
inline constexpr auto height = 100;
- inline constexpr auto vBoxWidth = 200;
inline constexpr auto botMargin = 4;
- inline constexpr auto vBoxLeftMargin = 10;
inline constexpr auto imageMargin = 150;
inline constexpr auto timeHeight = 60 - style::margins::small;
inline constexpr auto periodHeight = 40;
namespace time
{
- inline constexpr auto height = 106;
- inline constexpr auto margin = 21;
- inline constexpr auto marginBot = 15;
+ inline constexpr auto width = style::listview::item_width_with_without_scroll;
+ inline constexpr auto height = 80;
+ inline constexpr auto marginTop = 32;
+ inline constexpr auto marginBot = 20;
inline constexpr auto separator = 30;
- inline constexpr auto timeInput12h = 120;
- inline constexpr auto timeInput24h = 195;
} // namespace time
namespace options
{
- inline constexpr auto height = 63;
- inline constexpr auto label_h = 30;
- inline constexpr auto arrow_w_h = 20;
+ inline constexpr auto spinner_h = 40;
+ inline constexpr auto label_h = 27;
+ inline constexpr auto h = spinner_h + label_h;
} // namespace options
- namespace checkBox
- {
- inline constexpr auto height = 44;
- inline constexpr auto marginTop = 18;
- inline constexpr auto inputBox_w = style::window::label::big_h;
- inline constexpr auto description_w = 280;
- } // namespace checkBox
} // namespace item
} // namespace window
M module-apps/application-alarm-clock/widgets/AlarmItem.cpp => module-apps/application-alarm-clock/widgets/AlarmItem.cpp +12 -13
@@ 10,7 10,8 @@
namespace gui
{
- AlarmItem::AlarmItem(app::alarmClock::AlarmPresenter p) : AlarmEventItem(p)
+ AlarmItem::AlarmItem(std::shared_ptr<app::alarmClock::AlarmRRulePresenter> presenter)
+ : AlarmRRuleItem(std::move(presenter))
{
setMinimumSize(style::window::default_body_width, style::alarmClock::window::item::height);
setMargins(gui::Margins(0, style::margins::small, 0, style::alarmClock::window::item::botMargin));
@@ 20,26 21,24 @@ namespace gui
vBox = new gui::VBox(hBox, 0, 0, 0, 0);
vBox->setEdges(gui::RectangleEdge::None);
- vBox->setMinimumSize(style::alarmClock::window::item::vBoxWidth, style::alarmClock::window::item::height);
- vBox->setMargins(gui::Margins(style::alarmClock::window::item::vBoxLeftMargin, 0, 0, 0));
+ vBox->setMaximumSize(style::window::default_body_width, style::alarmClock::window::item::height);
+ vBox->setMargins(gui::Margins(style::widgets::leftMargin, 0, 0, 0));
timeLabel = new gui::Label(vBox, 0, 0, 0, 0);
timeLabel->setEdges(gui::RectangleEdge::None);
- timeLabel->setMinimumSize(style::alarmClock::window::item::vBoxWidth,
- style::alarmClock::window::item::timeHeight);
+ timeLabel->setMaximumSize(style::window::default_body_width, style::alarmClock::window::item::timeHeight);
timeLabel->setMargins(gui::Margins(0, style::margins::small, 0, 0));
timeLabel->setAlignment(gui::Alignment{gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center});
timeLabel->setFont(style::window::font::largelight);
periodLabel = new gui::Label(vBox, 0, 0, 0, 0);
periodLabel->setEdges(gui::RectangleEdge::None);
- periodLabel->setMinimumSize(style::alarmClock::window::item::vBoxWidth,
- style::alarmClock::window::item::periodHeight);
+ periodLabel->setMaximumSize(style::window::default_body_width, style::alarmClock::window::item::periodHeight);
periodLabel->setAlignment(gui::Alignment{gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top});
periodLabel->setFont(style::window::font::small);
onOffImage = new gui::ButtonOnOff(hBox, ButtonState::On);
- onOffImage->setMargins(gui::Margins(style::alarmClock::window::item::imageMargin, 0, 0, 0));
+ onOffImage->setMargins(gui::Margins(0, 0, style::widgets::rightMargin, 0));
setAlarm();
@@ 51,16 50,16 @@ namespace gui
void AlarmItem::setAlarm()
{
- timeLabel->setText(TimePointToLocalizedTimeString(presenter().getAlarm()->startDate));
- onOffImage->switchState(presenter().getAlarm()->enabled ? ButtonState::Off : ButtonState::On);
+ timeLabel->setText(TimePointToLocalizedTimeString(getPresenter()->getAlarm()->startDate));
+ onOffImage->switchState(getPresenter()->getAlarm()->enabled ? ButtonState::Off : ButtonState::On);
- if (presenter().hasRecurrence()) {
- periodLabel->setText(presenter().getDescription());
+ if (getPresenter()->hasRecurrence()) {
+ periodLabel->setText(getPresenter()->getDescription());
}
if (periodLabel->getText().empty()) {
periodLabel->setMaximumSize(0, 0);
- timeLabel->setMinimumSize(style::alarmClock::window::item::vBoxWidth,
+ timeLabel->setMaximumSize(style::window::default_body_width,
style::alarmClock::window::item::timeHeight +
style::alarmClock::window::item::periodHeight);
vBox->resizeItems();
M module-apps/application-alarm-clock/widgets/AlarmItem.hpp => module-apps/application-alarm-clock/widgets/AlarmItem.hpp +3 -3
@@ 9,11 9,11 @@
#include <ListItem.hpp>
#include <BoxLayout.hpp>
#include <Label.hpp>
-#include <application-alarm-clock/presenter/AlarmPresenter.hpp>
+#include <application-alarm-clock/presenter/AlarmRRulePresenter.hpp>
namespace gui
{
- class AlarmItem : public ListItem, public app::alarmClock::AlarmEventItem
+ class AlarmItem : public ListItem, public app::alarmClock::AlarmRRuleItem
{
gui::HBox *hBox = nullptr;
gui::VBox *vBox = nullptr;
@@ 23,6 23,6 @@ namespace gui
void setAlarm();
public:
- explicit AlarmItem(app::alarmClock::AlarmPresenter);
+ explicit AlarmItem(std::shared_ptr<app::alarmClock::AlarmRRulePresenter>);
};
} // namespace gui
A module-apps/application-alarm-clock/widgets/AlarmMusicOptionsItem.cpp => module-apps/application-alarm-clock/widgets/AlarmMusicOptionsItem.cpp +179 -0
@@ 0,0 1,179 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "AlarmMusicOptionsItem.hpp"
+
+#include <service-audio/AudioServiceAPI.hpp>
+#include <purefs/filesystem_paths.hpp>
+
+namespace gui
+{
+ AlarmMusicOptionsItem::AlarmMusicOptionsItem(app::ApplicationCommon *app,
+ const std::string &description,
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode,
+ std::function<void()> bottomBarRestoreFromTemporaryMode)
+ : AlarmOptionsItem(description), bottomBarTemporaryMode(std::move(bottomBarTemporaryMode)),
+ bottomBarRestoreFromTemporaryMode(std::move(bottomBarRestoreFromTemporaryMode))
+ {
+ assert(app != nullptr);
+
+ // create audioOperations to allow sounds preview
+ audioOperations = std::make_unique<app::AsyncAudioOperations>(app);
+
+ alarmSoundList = getMusicFilesList();
+ std::vector<UTF8> printOptions;
+ for (const auto &musicFile : getMusicFilesList()) {
+ printOptions.push_back(musicFile.title);
+ }
+ optionSpinner->setData({printOptions});
+
+ inputCallback = [&](gui::Item &item, const gui::InputEvent &event) {
+ if (event.isShortRelease(gui::KeyCode::KEY_LF)) {
+ if (getFilePath(optionSpinner->getCurrentValue()) != currentlyPreviewedPath) {
+ playAudioPreview(getFilePath(optionSpinner->getCurrentValue()));
+ }
+ else if (musicStatus == MusicStatus::Stop) {
+ resumeAudioPreview();
+ }
+ else {
+ pauseAudioPreview();
+ }
+ }
+
+ // stop preview playback when we go back
+ if (musicStatus == MusicStatus::Play && event.isShortRelease(gui::KeyCode::KEY_RF)) {
+ stopAudioPreview();
+ }
+
+ return optionSpinner->onInput(event);
+ };
+
+ focusChangedCallback = [&](Item &item) {
+ setFocusItem(focus ? optionSpinner : nullptr);
+
+ if (focus) {
+ this->bottomBarTemporaryMode(utils::translate(style::strings::common::play_pause));
+ }
+ else {
+ this->bottomBarRestoreFromTemporaryMode();
+ }
+
+ // stop preview playback when we loose focus
+ if (musicStatus == MusicStatus::Play) {
+ stopAudioPreview();
+ }
+
+ return true;
+ };
+
+ onSaveCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
+ // stop preview playback if it is played
+ if (musicStatus == MusicStatus::Play) {
+ stopAudioPreview();
+ }
+
+ alarm->musicTone = getFilePath(optionSpinner->getCurrentValue());
+ };
+
+ onLoadCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
+ optionSpinner->setCurrentValue(getTitle(alarm->musicTone));
+ };
+ }
+
+ std::vector<tags::fetcher::Tags> AlarmMusicOptionsItem::getMusicFilesList()
+ {
+ const auto musicFolder = (purefs::dir::getCurrentOSPath() / "assets/audio/alarm").string();
+ std::vector<tags::fetcher::Tags> musicFiles;
+ LOG_INFO("Scanning music folder: %s", musicFolder.c_str());
+ for (const auto &ent : std::filesystem::directory_iterator(musicFolder)) {
+ if (!ent.is_directory()) {
+ const auto filePath = std::string(musicFolder) + "/" + ent.path().filename().c_str();
+ auto fileTags = tags::fetcher::fetchTags(filePath);
+ musicFiles.push_back(fileTags);
+ LOG_DEBUG("file: %s found", ent.path().filename().c_str());
+ }
+ }
+ LOG_INFO("Total number of music files found: %u", static_cast<unsigned int>(musicFiles.size()));
+ return musicFiles;
+ }
+
+ bool AlarmMusicOptionsItem::playAudioPreview(const std::string &path)
+ {
+ return audioOperations->play(path, [this, path](audio::RetCode retCode, audio::Token token) {
+ if (retCode != audio::RetCode::Success || !token.IsValid()) {
+ LOG_ERROR("Audio preview callback failed with retcode = %s. Token validity: %d",
+ str(retCode).c_str(),
+ token.IsValid());
+ return;
+ }
+ musicStatus = MusicStatus::Play;
+ currentlyPreviewedToken = token;
+ currentlyPreviewedPath = path;
+ });
+ }
+
+ bool AlarmMusicOptionsItem::pauseAudioPreview()
+ {
+ return audioOperations->pause(currentlyPreviewedToken, [this](audio::RetCode retCode, audio::Token token) {
+ if (token != currentlyPreviewedToken) {
+ LOG_ERROR("Audio preview pause failed: wrong token");
+ return;
+ }
+ if (retCode != audio::RetCode::Success || !token.IsValid()) {
+ LOG_ERROR("Audio preview pause failed with retcode = %s. Token validity: %d",
+ str(retCode).c_str(),
+ token.IsValid());
+ return;
+ }
+ musicStatus = MusicStatus::Stop;
+ });
+ }
+
+ bool AlarmMusicOptionsItem::resumeAudioPreview()
+ {
+ return audioOperations->resume(currentlyPreviewedToken, [this](audio::RetCode retCode, audio::Token token) {
+ if (token != currentlyPreviewedToken) {
+ LOG_ERROR("Audio preview resume failed: wrong token");
+ return;
+ }
+
+ if (retCode != audio::RetCode::Success || !token.IsValid()) {
+ LOG_ERROR("Audio preview pause failed with retcode = %s. Token validity: %d",
+ str(retCode).c_str(),
+ token.IsValid());
+ return;
+ }
+ musicStatus = MusicStatus::Play;
+ });
+ }
+
+ bool AlarmMusicOptionsItem::stopAudioPreview()
+ {
+ if (currentlyPreviewedToken.IsValid()) {
+ musicStatus = MusicStatus::Stop;
+ currentlyPreviewedPath = "";
+ return audioOperations->stop(currentlyPreviewedToken, [](audio::RetCode, audio::Token) {});
+ }
+ return false;
+ }
+
+ std::string AlarmMusicOptionsItem::getTitle(const std::string &filePath)
+ {
+ for (const auto &musicFile : alarmSoundList) {
+ if (musicFile.filePath == filePath) {
+ return musicFile.title;
+ }
+ }
+ return std::string();
+ }
+
+ std::string AlarmMusicOptionsItem::getFilePath(const std::string &title)
+ {
+ for (const auto &musicFile : alarmSoundList) {
+ if (musicFile.title == title) {
+ return musicFile.filePath;
+ }
+ }
+ return std::string();
+ }
+} /* namespace gui */
A module-apps/application-alarm-clock/widgets/AlarmMusicOptionsItem.hpp => module-apps/application-alarm-clock/widgets/AlarmMusicOptionsItem.hpp +51 -0
@@ 0,0 1,51 @@
+// 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 "AlarmOptionsItem.hpp"
+
+#include <application-alarm-clock/data/AlarmsData.hpp>
+#include <apps-common/ApplicationCommon.hpp>
+#include <apps-common/AudioOperations.hpp>
+#include <tags_fetcher/TagsFetcher.hpp>
+
+namespace gui
+{
+ class AlarmMusicOptionsItem : public AlarmOptionsItem
+ {
+ private:
+ enum class MusicStatus
+ {
+ Stop,
+ Play
+ };
+
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr;
+ std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr;
+
+ /// pointer to audio operations which allows to make audio preview
+ std::unique_ptr<app::AbstractAudioOperations> audioOperations;
+ std::vector<tags::fetcher::Tags> alarmSoundList;
+ MusicStatus musicStatus = MusicStatus::Stop;
+ audio::Token currentlyPreviewedToken;
+ std::string currentlyPreviewedPath;
+
+ std::vector<tags::fetcher::Tags> getMusicFilesList();
+
+ public:
+ explicit AlarmMusicOptionsItem(app::ApplicationCommon *app,
+ const std::string &description,
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
+ std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr);
+
+ private:
+ [[nodiscard]] std::string getTitle(const std::string &filePath);
+ [[nodiscard]] std::string getFilePath(const std::string &title);
+ bool playAudioPreview(const std::string &path);
+ bool pauseAudioPreview();
+ bool resumeAudioPreview();
+ bool stopAudioPreview();
+ };
+
+} /* namespace gui */<
\ No newline at end of file
M module-apps/application-alarm-clock/widgets/AlarmOptionsItem.cpp => module-apps/application-alarm-clock/widgets/AlarmOptionsItem.cpp +13 -315
@@ 2,34 2,19 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "AlarmOptionsItem.hpp"
+
#include "AlarmClockStyle.hpp"
#include <InputEvent.hpp>
#include <Style.hpp>
-#include <Utils.hpp>
-#include <service-audio/AudioServiceAPI.hpp>
-#include <purefs/filesystem_paths.hpp>
namespace gui
{
-
- AlarmOptionsItem::AlarmOptionsItem(app::ApplicationCommon *app,
- AlarmOptionItemName itemName,
- std::function<void(const UTF8 &)> bottomBarTemporaryMode,
- std::function<void()> bottomBarRestoreFromTemporaryMode)
- : itemName(itemName), bottomBarTemporaryMode(std::move(bottomBarTemporaryMode)),
- bottomBarRestoreFromTemporaryMode(std::move(bottomBarRestoreFromTemporaryMode))
+ AlarmOptionsItem::AlarmOptionsItem(const std::string &description, const std::vector<UTF8> &options)
{
- application = app;
- assert(app != nullptr);
-
- // create audioOperations to allow shounds preview
- audioOperations = std::make_unique<app::AsyncAudioOperations>(app);
+ setMinimumSize(style::listview::item_width_with_without_scroll, style::alarmClock::window::item::options::h);
- setMinimumSize(style::window::default_body_width, style::alarmClock::window::item::options::height);
-
- setEdges(RectangleEdge::Bottom);
- setPenWidth(style::window::default_border_rect_no_focus);
- setMargins(gui::Margins(style::margins::small, style::margins::huge / 2, 0, style::margins::huge / 2));
+ setEdges(RectangleEdge::None);
+ setMargins(gui::Margins(style::widgets::leftMargin, style::margins::large, 0, 0));
vBox = new gui::VBox(this, 0, 0, 0, 0);
vBox->setEdges(gui::RectangleEdge::None);
@@ 39,312 24,25 @@ namespace gui
descriptionLabel->setMinimumSize(style::window::default_body_width,
style::alarmClock::window::item::options::label_h);
descriptionLabel->setEdges(gui::RectangleEdge::None);
- descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
+ descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
descriptionLabel->setFont(style::window::font::small);
descriptionLabel->activeItem = false;
+ descriptionLabel->setText(description);
- hBox = new gui::HBox(vBox, 0, 0, 0, 0);
- hBox->setMinimumSize(style::window::default_body_width,
- style::alarmClock::window::item::options::height -
- style::alarmClock::window::item::options::label_h);
- hBox->setEdges(gui::RectangleEdge::None);
- hBox->activeItem = false;
-
- leftArrow = new gui::Image(hBox, 0, 0, 0, 0);
- leftArrow->setMinimumSize(style::alarmClock::window::item::options::arrow_w_h,
- style::alarmClock::window::item::options::arrow_w_h);
- leftArrow->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
- leftArrow->activeItem = false;
- leftArrow->set("arrow_left");
- leftArrow->setVisible(false);
-
- optionLabel = new gui::Label(hBox, 0, 0, 0, 0);
- optionLabel->setMinimumSize(
- style::window::default_body_width - 2 * style::alarmClock::window::item::options::arrow_w_h,
- style::alarmClock::window::item::options::height - style::alarmClock::window::item::options::label_h);
- optionLabel->setMargins(gui::Margins(style::alarmClock::window::item::options::arrow_w_h / 2, 0, 0, 0));
- optionLabel->setEdges(gui::RectangleEdge::None);
- optionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
- optionLabel->setFont(style::window::font::medium);
- optionLabel->activeItem = false;
-
- rightArrow = new gui::Image(hBox, 0, 0, 0, 0);
- rightArrow->setMinimumSize(style::alarmClock::window::item::options::arrow_w_h,
- style::alarmClock::window::item::options::arrow_w_h);
- rightArrow->setAlignment(Alignment(gui::Alignment::Horizontal::Right, gui::Alignment::Vertical::Center));
- rightArrow->activeItem = false;
- rightArrow->set("arrow_right");
- rightArrow->setVisible(false);
-
- prepareOptionsNames();
- applyCallbacks();
- }
-
- void AlarmOptionsItem::prepareOptionsNames()
- {
- songsList = getMusicFilesList();
- optionsNames.clear();
- switch (itemName) {
- case AlarmOptionItemName::Sound:
- descriptionLabel->setText(utils::translate("app_alarm_clock_sound"));
- break;
- case AlarmOptionItemName::Snooze:
- descriptionLabel->setText(utils::translate("app_alarm_clock_snooze"));
- break;
- case AlarmOptionItemName::Repeat:
- descriptionLabel->setText(utils::translate("app_alarm_clock_repeat"));
- break;
- }
- if (itemName == AlarmOptionItemName::Sound) {
- for (const auto &musicFile : songsList) {
- optionsNames.push_back(musicFile.title);
- }
- }
- else if (itemName == AlarmOptionItemName::Snooze) {
- optionsNames.push_back(utils::translate("app_alarm_clock_snooze_5_min"));
- optionsNames.push_back(utils::translate("app_alarm_clock_snooze_10_min"));
- optionsNames.push_back(utils::translate("app_alarm_clock_snooze_15_min"));
- optionsNames.push_back(utils::translate("app_alarm_clock_snooze_30_min"));
- }
- else if (itemName == AlarmOptionItemName::Repeat) {
- optionsNames.push_back(utils::translate("app_alarm_clock_repeat_never"));
- optionsNames.push_back(utils::translate("app_alarm_clock_repeat_everyday"));
- optionsNames.push_back(utils::translate("app_alarm_clock_repeat_week_days"));
- optionsNames.push_back(utils::translate("app_alarm_clock_repeat_custom"));
- }
- }
+ optionSpinner = new gui::TextSpinnerBox(vBox, options, Boundaries::Continuous);
+ optionSpinner->setMinimumSize(style::window::default_body_width,
+ style::alarmClock::window::item::options::spinner_h);
- void AlarmOptionsItem::applyCallbacks()
- {
- focusChangedCallback = [&](Item &item) {
- if (item.focus) {
- optionLabel->setFont(style::window::font::mediumbold);
- optionLabel->setMargins(gui::Margins(0, 0, 0, 0));
- leftArrow->setVisible(true);
- rightArrow->setVisible(true);
- hBox->resizeItems();
- if (itemName == AlarmOptionItemName::Sound) {
- bottomBarTemporaryMode(utils::translate(style::strings::common::play_pause));
- }
- if (itemName == AlarmOptionItemName::Repeat && actualVectorIndex == optionsNames.size() - 1) {
- bottomBarTemporaryMode(utils::translate("app_alarm_clock_edit"));
- }
- }
- else {
- optionLabel->setFont(style::window::font::medium);
- optionLabel->setMargins(gui::Margins(style::alarmClock::window::item::options::arrow_w_h / 2, 0, 0, 0));
- leftArrow->setVisible(false);
- rightArrow->setVisible(false);
- hBox->resizeItems();
- bottomBarRestoreFromTemporaryMode();
- }
-
- // stop preview playback when we loose focus
- if (itemName == AlarmOptionItemName::Sound && musicStatus == MusicStatus::Play) {
- stopAudioPreview();
- }
+ focusChangedCallback = [&](gui::Item &item) {
+ setFocusItem(focus ? optionSpinner : nullptr);
return true;
};
- inputCallback = [&](gui::Item &item, const gui::InputEvent &event) {
- if (!event.isShortRelease()) {
- return false;
- }
- if (event.is(gui::KeyCode::KEY_RF)) {
- setFocusItem(nullptr);
- }
-
- if (event.is(gui::KeyCode::KEY_LEFT)) {
- actualVectorIndex--;
- if (actualVectorIndex >= optionsNames.size()) {
- actualVectorIndex = optionsNames.size() - 1;
- if (itemName == AlarmOptionItemName::Repeat) {
- bottomBarTemporaryMode(utils::translate("app_alarm_clock_edit"));
- }
- }
- else if (itemName == AlarmOptionItemName::Repeat) {
- bottomBarRestoreFromTemporaryMode();
- }
- optionLabel->setText(optionsNames[actualVectorIndex]);
- return true;
- }
-
- if (event.is(gui::KeyCode::KEY_RIGHT)) {
- actualVectorIndex++;
- if (actualVectorIndex >= optionsNames.size()) {
- actualVectorIndex = 0;
- }
- if (actualVectorIndex == optionsNames.size() - 1 && itemName == AlarmOptionItemName::Repeat) {
- bottomBarTemporaryMode(utils::translate("app_alarm_clock_edit"));
- }
- else if (itemName == AlarmOptionItemName::Repeat) {
- bottomBarRestoreFromTemporaryMode();
- }
- optionLabel->setText(optionsNames[actualVectorIndex]);
- return true;
- }
-
- if (event.is(gui::KeyCode::KEY_LF) && itemName == AlarmOptionItemName::Repeat &&
- actualVectorIndex == optionsNames.size() - 1) {
- OptionParser parser;
- auto weekDayRepeatData = std::make_unique<WeekDaysRepeatData>();
- auto weekDayData = parser.setWeekDayOptions(repeatOptionValue, std::move(weekDayRepeatData));
- application->switchWindow(style::alarmClock::window::name::customRepeat, std::move(weekDayData));
- }
-
- if (event.is(gui::KeyCode::KEY_LF) && itemName == AlarmOptionItemName::Sound) {
- if (songsList[actualVectorIndex].filePath != currentlyPreviewedPath) {
- playAudioPreview(songsList[actualVectorIndex].filePath);
- }
- else if (musicStatus == MusicStatus::Stop) {
- resumeAudioPreview();
- }
- else {
- pauseAudioPreview();
- }
- }
-
- // stop preview playback when we go back
- if (itemName == AlarmOptionItemName::Sound && musicStatus == MusicStatus::Play &&
- event.is(gui::KeyCode::KEY_RF)) {
- stopAudioPreview();
- }
- return false;
- };
-
- onSaveCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
- switch (itemName) {
- case AlarmOptionItemName::Sound: {
- // stop preview playback if it is played
- if (musicStatus == MusicStatus::Play) {
- stopAudioPreview();
- }
- alarm->musicTone = songsList[actualVectorIndex].filePath;
- break;
- }
- case AlarmOptionItemName::Snooze: {
- alarm->snoozeDuration = static_cast<uint32_t>(snoozeOptions[actualVectorIndex]);
- break;
- }
- case AlarmOptionItemName::Repeat:
- // repead handled in class
- break;
- }
- };
-
- onLoadCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
- switch (itemName) {
- case AlarmOptionItemName::Sound: {
- auto it = std::find_if(songsList.begin(), songsList.end(), [alarm](const tags::fetcher::Tags &tag) {
- return tag.filePath == alarm->musicTone.c_str();
- });
- if (it == songsList.end()) {
- LOG_DEBUG("No such song in the list");
- actualVectorIndex = 0;
- }
- else {
- actualVectorIndex = std::distance(songsList.begin(), it);
- }
- break;
- }
- case AlarmOptionItemName::Snooze: {
- auto it = std::find(
- snoozeOptions.begin(), snoozeOptions.end(), static_cast<AlarmSnooze>(alarm->snoozeDuration));
- if (it == snoozeOptions.end()) {
- actualVectorIndex = 0;
- }
- else {
- actualVectorIndex = std::distance(snoozeOptions.begin(), it);
- }
- break;
- }
- case AlarmOptionItemName::Repeat:
- // repead handled in class
- break;
- }
- optionLabel->setText(optionsNames[actualVectorIndex]);
- };
+ inputCallback = [&](Item &item, const InputEvent &event) { return optionSpinner->onInput(event); };
dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
vBox->setArea({0, 0, newDim.w, newDim.h});
return true;
};
}
-
- std::vector<tags::fetcher::Tags> AlarmOptionsItem::getMusicFilesList()
- {
- const auto musicFolder = (purefs::dir::getUserDiskPath() / "music").string();
- std::vector<tags::fetcher::Tags> musicFiles;
- LOG_INFO("Scanning music folder: %s", musicFolder.c_str());
- for (const auto &ent : std::filesystem::directory_iterator(musicFolder)) {
- if (!ent.is_directory()) {
- const auto filePath = std::string(musicFolder) + "/" + ent.path().filename().c_str();
- auto fileTags = tags::fetcher::fetchTags(filePath);
- musicFiles.push_back(fileTags);
- LOG_DEBUG("file: %s found", ent.path().filename().c_str());
- }
- }
- LOG_INFO("Total number of music files found: %u", static_cast<unsigned int>(musicFiles.size()));
- return musicFiles;
- }
-
- bool AlarmOptionsItem::playAudioPreview(const std::string &path)
- {
- return audioOperations->play(path, [this, path](audio::RetCode retCode, audio::Token token) {
- if (retCode != audio::RetCode::Success || !token.IsValid()) {
- LOG_ERROR("Audio preview callback failed with retcode = %s. Token validity: %d",
- str(retCode).c_str(),
- token.IsValid());
- return;
- }
- musicStatus = MusicStatus::Play;
- currentlyPreviewedToken = token;
- currentlyPreviewedPath = path;
- });
- }
-
- bool AlarmOptionsItem::pauseAudioPreview()
- {
- return audioOperations->pause(currentlyPreviewedToken, [this](audio::RetCode retCode, audio::Token token) {
- if (token != currentlyPreviewedToken) {
- LOG_ERROR("Audio preview pause failed: wrong token");
- return;
- }
- if (retCode != audio::RetCode::Success || !token.IsValid()) {
- LOG_ERROR("Audio preview pause failed with retcode = %s. Token validity: %d",
- str(retCode).c_str(),
- token.IsValid());
- return;
- }
- musicStatus = MusicStatus::Stop;
- });
- }
-
- bool AlarmOptionsItem::resumeAudioPreview()
- {
- return audioOperations->resume(currentlyPreviewedToken, [this](audio::RetCode retCode, audio::Token token) {
- if (token != currentlyPreviewedToken) {
- LOG_ERROR("Audio preview resume failed: wrong token");
- return;
- }
-
- if (retCode != audio::RetCode::Success || !token.IsValid()) {
- LOG_ERROR("Audio preview pause failed with retcode = %s. Token validity: %d",
- str(retCode).c_str(),
- token.IsValid());
- return;
- }
- musicStatus = MusicStatus::Play;
- });
- }
-
- bool AlarmOptionsItem::stopAudioPreview()
- {
- if (currentlyPreviewedToken.IsValid()) {
- musicStatus = MusicStatus::Stop;
- currentlyPreviewedPath = "";
- return audioOperations->stop(currentlyPreviewedToken, [](audio::RetCode, audio::Token) {});
- }
- return false;
- }
} /* namespace gui */
M module-apps/application-alarm-clock/widgets/AlarmOptionsItem.hpp => module-apps/application-alarm-clock/widgets/AlarmOptionsItem.hpp +8 -48
@@ 3,65 3,25 @@
#pragma once
-#include <apps-common/ApplicationCommon.hpp>
#include "AlarmInternalListItem.hpp"
-#include "application-alarm-clock/data/AlarmsData.hpp"
-#include <apps-common/AudioOperations.hpp>
+
#include <Label.hpp>
-#include <Image.hpp>
#include <BoxLayout.hpp>
-#include <tags_fetcher/TagsFetcher.hpp>
+#include <widgets/TextSpinnerBox.hpp>
namespace gui
{
- const std::array<AlarmSnooze, 4> snoozeOptions = {
- AlarmSnooze::FiveMinutes, AlarmSnooze::TenMinutes, AlarmSnooze::FifteenMinutes, AlarmSnooze::ThirtyMinutes};
-
class AlarmOptionsItem : public AlarmInternalListItem
{
- protected:
- enum class MusicStatus
- {
- Stop,
- Play
- };
- app::ApplicationCommon *application = nullptr;
- gui::VBox *vBox = nullptr;
- gui::HBox *hBox = nullptr;
- gui::Label *optionLabel = nullptr;
- gui::Label *descriptionLabel = nullptr;
- gui::Image *leftArrow = nullptr;
- gui::Image *rightArrow = nullptr;
- AlarmOptionItemName itemName;
- std::vector<std::string> optionsNames;
- /// pointer to audio operations which allows to make audio preview
- std::unique_ptr<app::AbstractAudioOperations> audioOperations;
-
- std::vector<tags::fetcher::Tags> songsList;
- MusicStatus musicStatus = MusicStatus::Stop;
- audio::Token currentlyPreviewedToken;
- std::string currentlyPreviewedPath;
-
- unsigned int actualVectorIndex = 0;
- uint32_t repeatOptionValue = 0;
-
- std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr;
- std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr;
- void prepareOptionsNames();
- void applyCallbacks();
- std::vector<tags::fetcher::Tags> getMusicFilesList();
-
public:
- AlarmOptionsItem(app::ApplicationCommon *app,
- AlarmOptionItemName itemName,
- std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
- std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr);
+ explicit AlarmOptionsItem(const std::string &description, const std::vector<UTF8> &options = {});
protected:
- bool playAudioPreview(const std::string &path);
- bool pauseAudioPreview();
- bool resumeAudioPreview();
- bool stopAudioPreview();
+ gui::TextSpinnerBox *optionSpinner = nullptr;
+
+ private:
+ gui::VBox *vBox = nullptr;
+ gui::Label *descriptionLabel = nullptr;
};
} /* namespace gui */
A module-apps/application-alarm-clock/widgets/AlarmRRuleOptionsItem.cpp => module-apps/application-alarm-clock/widgets/AlarmRRuleOptionsItem.cpp +94 -0
@@ 0,0 1,94 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "AlarmRRuleOptionsItem.hpp"
+
+#include <application-alarm-clock/widgets/AlarmClockStyle.hpp>
+
+namespace gui
+{
+ AlarmRRuleOptionsItem::AlarmRRuleOptionsItem(app::ApplicationCommon *app,
+ const std::string &description,
+ std::shared_ptr<app::alarmClock::AlarmRRulePresenter> presenter,
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode,
+ std::function<void()> bottomBarRestoreFromTemporaryMode)
+ : AlarmOptionsItem(description), AlarmRRuleItem(std::move(presenter)), app(app),
+ bottomBarTemporaryMode(std::move(bottomBarTemporaryMode)),
+ bottomBarRestoreFromTemporaryMode(std::move(bottomBarRestoreFromTemporaryMode))
+ {
+ printOptions();
+
+ inputCallback = [&](gui::Item &item, const gui::InputEvent &event) {
+ auto ret = optionSpinner->onInput(event);
+
+ if (getRRuleOption(optionSpinner->getCurrentValue()) == RRule::Custom) {
+ this->bottomBarTemporaryMode(utils::translate(style::strings::common::edit));
+ if (event.isShortRelease(gui::KeyCode::KEY_LF)) {
+ this->app->switchWindow(style::alarmClock::window::name::customRepeat);
+ }
+ }
+ else {
+ this->bottomBarRestoreFromTemporaryMode();
+ }
+
+ return ret;
+ };
+
+ focusChangedCallback = [&](Item &item) {
+ setFocusItem(focus ? optionSpinner : nullptr);
+
+ if (getRRuleOption(optionSpinner->getCurrentValue()) == RRule::Custom) {
+ this->bottomBarTemporaryMode(utils::translate(style::strings::common::edit));
+ }
+ else {
+ this->bottomBarRestoreFromTemporaryMode();
+ }
+
+ return true;
+ };
+
+ onSaveCallback = [&]([[maybe_unused]] std::shared_ptr<AlarmEventRecord> alarm) {
+ if (getRRuleOption(optionSpinner->getCurrentValue()) != RRule::Custom) {
+ getPresenter()->setOption(getRRuleOption(optionSpinner->getCurrentValue()));
+ }
+ };
+
+ onLoadCallback = [&]([[maybe_unused]] std::shared_ptr<AlarmEventRecord> alarm) {
+ checkCustomOption(getPresenter()->getDescription());
+ optionSpinner->setCurrentValue(getPresenter()->getDescription());
+ };
+ }
+
+ AlarmRRuleOptionsItem::RRule AlarmRRuleOptionsItem::getRRuleOption(const std::string &selectedOption)
+ {
+ for (auto const &option : rRuleOptions) {
+ if (option.second == selectedOption) {
+ return option.first;
+ }
+ }
+
+ return AlarmRRuleOptionsItem::RRule::Never;
+ }
+
+ void AlarmRRuleOptionsItem::checkCustomOption(const std::string &selectedOption)
+ {
+ for (auto const &option : rRuleOptions) {
+ if (selectedOption.empty() || option.second == selectedOption) {
+ return;
+ }
+ }
+
+ // replace Custom with days options
+ rRuleOptions.back().second = selectedOption;
+ printOptions();
+ }
+
+ void AlarmRRuleOptionsItem::printOptions()
+ {
+ std::vector<UTF8> printOptions;
+ for (auto const &option : rRuleOptions) {
+ printOptions.push_back(option.second);
+ }
+ optionSpinner->setData({printOptions});
+ }
+} /* namespace gui */
A module-apps/application-alarm-clock/widgets/AlarmRRuleOptionsItem.hpp => module-apps/application-alarm-clock/widgets/AlarmRRuleOptionsItem.hpp +39 -0
@@ 0,0 1,39 @@
+// 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 "AlarmOptionsItem.hpp"
+
+#include <application-alarm-clock/data/AlarmsData.hpp>
+#include <application-alarm-clock/presenter/AlarmRRulePresenter.hpp>
+#include <ApplicationCommon.hpp>
+
+namespace gui
+{
+ class AlarmRRuleOptionsItem : public AlarmOptionsItem, public app::alarmClock::AlarmRRuleItem
+ {
+ private:
+ app::ApplicationCommon *app = nullptr;
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr;
+ std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr;
+
+ using RRule = app::alarmClock::AlarmRRulePresenter::RRuleOptions;
+ std::vector<std::pair<RRule, std::string>> rRuleOptions = {
+ {RRule::Never, utils::translate("app_alarm_clock_repeat_never")},
+ {RRule::Everyday, utils::translate("app_alarm_clock_repeat_everyday")},
+ {RRule::Weekdays, utils::translate("app_alarm_clock_repeat_week_days")},
+ {RRule::Custom, utils::translate("app_alarm_clock_repeat_custom")}};
+
+ [[nodiscard]] RRule getRRuleOption(const std::string &selectedOption);
+ void checkCustomOption(const std::string &selectedOption);
+ void printOptions();
+
+ public:
+ explicit AlarmRRuleOptionsItem(app::ApplicationCommon *app,
+ const std::string &description,
+ std::shared_ptr<app::alarmClock::AlarmRRulePresenter> presenter,
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
+ std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr);
+ };
+} /* namespace gui */
A module-apps/application-alarm-clock/widgets/AlarmSnoozeOptionsItem.cpp => module-apps/application-alarm-clock/widgets/AlarmSnoozeOptionsItem.cpp +36 -0
@@ 0,0 1,36 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "AlarmSnoozeOptionsItem.hpp"
+#include <i18n/i18n.hpp>
+
+namespace gui
+{
+ AlarmSnoozeOptionsItem::AlarmSnoozeOptionsItem(const std::string &description) : AlarmOptionsItem(description)
+ {
+ std::vector<UTF8> printOptions;
+
+ for (auto const &option : snoozeOptions) {
+ printOptions.push_back(option.second);
+ }
+
+ optionSpinner->setData({printOptions});
+
+ onSaveCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
+ for (auto const &option : snoozeOptions) {
+ if (option.second == optionSpinner->getCurrentValue().c_str()) {
+ alarm->snoozeDuration = option.first.count();
+ }
+ }
+ };
+
+ onLoadCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
+ auto valueToLoad = alarm->snoozeDuration;
+ for (auto const &option : snoozeOptions) {
+ if (option.first.count() == valueToLoad) {
+ optionSpinner->setCurrentValue(option.second);
+ }
+ }
+ };
+ }
+} /* namespace gui */
A module-apps/application-alarm-clock/widgets/AlarmSnoozeOptionsItem.hpp => module-apps/application-alarm-clock/widgets/AlarmSnoozeOptionsItem.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 "AlarmOptionsItem.hpp"
+
+namespace gui
+{
+ class AlarmSnoozeOptionsItem : public AlarmOptionsItem
+ {
+ public:
+ explicit AlarmSnoozeOptionsItem(const std::string &description);
+
+ private:
+ std::vector<std::pair<std::chrono::minutes, const std::string>> snoozeOptions = {
+ {std::chrono::minutes{0}, utils::translate("app_alarm_clock_no_snooze")},
+ {std::chrono::minutes{5}, utils::translate("app_alarm_clock_snooze_5_min")},
+ {std::chrono::minutes{10}, utils::translate("app_alarm_clock_snooze_10_min")},
+ {std::chrono::minutes{15}, utils::translate("app_alarm_clock_snooze_15_min")},
+ {std::chrono::minutes{30}, utils::translate("app_alarm_clock_snooze_30_min")}};
+ };
+} /* namespace gui */
M module-apps/application-alarm-clock/widgets/AlarmTimeItem.cpp => module-apps/application-alarm-clock/widgets/AlarmTimeItem.cpp +11 -8
@@ 18,10 18,11 @@ namespace gui
: mode24H{mode24H}, bottomBarTemporaryMode(std::move(bottomBarTemporaryMode)),
bottomBarRestoreFromTemporaryMode(std::move(bottomBarRestoreFromTemporaryMode))
{
- setMinimumSize(style::window::default_body_width, timeItem::height);
+ setMinimumSize(timeItem::width, timeItem::height);
setEdges(RectangleEdge::None);
- setMargins(gui::Margins(style::margins::small, timeItem::margin, 0, timeItem::marginBot));
+ setMargins(gui::Margins(
+ style::widgets::leftMargin, timeItem::marginTop, style::widgets::rightMargin, timeItem::marginBot));
hBox = new gui::HBox(this, 0, 0, 0, 0);
hBox->setEdges(gui::RectangleEdge::None);
@@ 31,7 32,7 @@ namespace gui
applyItemSpecificProperties(hourInput);
colonLabel = new gui::Label(hBox, 0, 0, 0, 0);
- colonLabel->setMinimumSize(timeItem::separator, timeItem::height - timeItem::separator);
+ colonLabel->setMinimumSize(timeItem::separator, timeItem::height);
colonLabel->setEdges(gui::RectangleEdge::None);
colonLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
colonLabel->setFont(style::window::font::medium);
@@ 181,10 182,11 @@ namespace gui
return true;
};
- mode12hInput->setMinimumSize(timeItem::timeInput12h, timeItem::height - timeItem::separator);
+ auto elemWidth = (timeItem::width - (2 * timeItem::separator)) / 3;
+ mode12hInput->setMinimumSize(elemWidth, timeItem::height);
mode12hInput->setMargins(gui::Margins(timeItem::separator, 0, 0, 0));
- hourInput->setMinimumSize(timeItem::timeInput12h, timeItem::height - timeItem::separator);
- minuteInput->setMinimumSize(timeItem::timeInput12h, timeItem::height - timeItem::separator);
+ hourInput->setMinimumSize(elemWidth, timeItem::height);
+ minuteInput->setMinimumSize(elemWidth, timeItem::height);
onLoadCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
hourInput->setText(TimePointToHourString12H(alarm->startDate));
@@ 198,8 200,9 @@ namespace gui
};
}
else {
- hourInput->setMinimumSize(timeItem::timeInput24h, timeItem::height - timeItem::separator);
- minuteInput->setMinimumSize(timeItem::timeInput24h, timeItem::height - timeItem::separator);
+ auto elemWidth = (timeItem::width - timeItem::separator) / 2;
+ hourInput->setMinimumSize(elemWidth, timeItem::height);
+ minuteInput->setMinimumSize(elemWidth, timeItem::height);
onLoadCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) {
hourInput->setText(TimePointToHourString24H(alarm->startDate));
M module-apps/application-alarm-clock/widgets/CustomCheckBoxWithLabel.cpp => module-apps/application-alarm-clock/widgets/CustomCheckBoxWithLabel.cpp +30 -74
@@ 3,97 3,53 @@
#include "CustomCheckBoxWithLabel.hpp"
#include "AlarmClockStyle.hpp"
+
+#include <application-alarm-clock/data/AlarmsData.hpp>
+
#include <InputEvent.hpp>
namespace gui
{
- const std::map<WeekDayIso, std::string> CustomCheckBoxWithLabel::weekDays = {
- {WeekDayIso::Monday, style::strings::common::Monday},
- {WeekDayIso::Tuesday, style::strings::common::Tuesday},
- {WeekDayIso::Wednesday, style::strings::common::Wednesday},
- {WeekDayIso::Thursday, style::strings::common::Thursday},
- {WeekDayIso::Friday, style::strings::common::Friday},
- {WeekDayIso::Saturday, style::strings::common::Saturday},
- {WeekDayIso::Sunday, style::strings::common::Sunday}};
-
- CustomCheckBoxWithLabel::CustomCheckBoxWithLabel(app::ApplicationCommon *app,
- const std::string &description,
- const WeekDaysRepeatData &data)
- : application(app), checkBoxData(data)
+ CustomCheckBoxWithLabel::CustomCheckBoxWithLabel(
+ const std::string &description,
+ bool initialState,
+ const std::function<void(const UTF8 &text)> &bottomBarTemporaryMode,
+ const std::function<void()> &bottomBarRestoreFromTemporaryMode)
+ : initialState(initialState)
{
- assert(application != nullptr);
-
- setMinimumSize(style::window::default_body_width, style::alarmClock::window::item::checkBox::height);
- setMargins(gui::Margins(style::margins::small, style::alarmClock::window::item::checkBox::marginTop, 0, 0));
setEdges(RectangleEdge::None);
+ setMinimumSize(style::window::default_body_width, style::window::label::big_h);
+ setMargins(gui::Margins(style::widgets::leftMargin, style::margins::big, 0, 0));
+
+ checkBoxWithLabel = new gui::CheckBoxWithLabel(this,
+ 0,
+ 0,
+ 0,
+ 0,
+ description,
+ bottomBarTemporaryMode,
+ bottomBarRestoreFromTemporaryMode,
+ BottomBar::Side::LEFT);
+
+ inputCallback = [&]([[maybe_unused]] Item &item, const InputEvent &event) {
+ return checkBoxWithLabel->onInput(event);
+ };
- hBox = new gui::HBox(this, 0, 0, 0, 0);
- hBox->setEdges(gui::RectangleEdge::None);
-
- checkBox = new gui::CheckBox(
- hBox,
- 0,
- 0,
- 0,
- 0,
- [=](const UTF8 &text) { application->getCurrentWindow()->bottomBarTemporaryMode(text, false); },
- [=]() { application->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
- checkBox->setMinimumSize(style::alarmClock::window::item::checkBox::inputBox_w,
- style::alarmClock::window::item::checkBox::height);
-
- descriptionLabel = new gui::Label(hBox, 0, 0, 0, 0);
- descriptionLabel->setMinimumSize(style::alarmClock::window::item::checkBox::description_w,
- style::alarmClock::window::item::checkBox::height);
- descriptionLabel->setMargins(gui::Margins(style::margins::very_big, 0, 0, 0));
- descriptionLabel->setEdges(gui::RectangleEdge::None);
- descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
- descriptionLabel->setFont(style::window::font::medium);
- descriptionLabel->setText(description);
-
- applyCallbacks();
- setCheckBoxes();
- }
-
- void CustomCheckBoxWithLabel::applyCallbacks()
- {
focusChangedCallback = [&](Item &item) {
- if (focus) {
- descriptionLabel->setFont(style::window::font::mediumbold);
- setFocusItem(checkBox);
- }
- else {
- descriptionLabel->setFont(style::window::font::medium);
- setFocusItem(nullptr);
- }
+ setFocusItem(focus ? checkBoxWithLabel : nullptr);
return true;
};
- inputCallback = [&](gui::Item &item, const gui::InputEvent &event) {
- if (event.is(gui::KeyCode::KEY_RF) || event.is(gui::KeyCode::KEY_ENTER)) {
- setFocusItem(nullptr);
- return false;
- }
- if (checkBox->onInput(event)) {
- checkBox->resizeItems();
- return true;
- }
- return false;
- };
- onContentChangedCallback = [&]() { return checkBox->isChecked(); };
-
dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
- hBox->setArea({0, 0, newDim.w, newDim.h});
+ checkBoxWithLabel->setArea({0, 0, newDim.w, newDim.h});
+ checkBoxWithLabel->setChecked(this->initialState);
return true;
};
}
- void CustomCheckBoxWithLabel::setCheckBoxes()
+ bool CustomCheckBoxWithLabel::isChecked()
{
- for (auto const &[key, dayName] : weekDays) {
- if (descriptionLabel->getText() == utils::translate(dayName)) {
- checkBox->setCheck(checkBoxData.getData(static_cast<uint32_t>(key)));
- }
- }
+ return checkBoxWithLabel->isChecked();
}
} // namespace gui
M module-apps/application-alarm-clock/widgets/CustomCheckBoxWithLabel.hpp => module-apps/application-alarm-clock/widgets/CustomCheckBoxWithLabel.hpp +14 -21
@@ 1,33 1,26 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// 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 "AlarmInternalListItem.hpp"
-#include "application-alarm-clock/data/AlarmsData.hpp"
-#include "ApplicationCommon.hpp"
-#include "application-calendar/data/CalendarData.hpp"
-#include <BoxLayout.hpp>
-#include <CheckBox.hpp>
+#include <ListItem.hpp>
+#include <CheckBoxWithLabel.hpp>
+
+#include <application-calendar/data/CalendarData.hpp>
namespace gui
{
- class CustomCheckBoxWithLabel : public AlarmInternalListItem
+ class CustomCheckBoxWithLabel : public ListItem
{
- gui::HBox *hBox = nullptr;
- app::ApplicationCommon *application = nullptr;
- gui::Label *descriptionLabel = nullptr;
- gui::CheckBox *checkBox = nullptr;
- WeekDaysRepeatData checkBoxData;
-
- void setCheckBoxes();
- void applyCallbacks();
+ private:
+ gui::CheckBoxWithLabel *checkBoxWithLabel = nullptr;
+ bool initialState = false;
public:
- CustomCheckBoxWithLabel(app::ApplicationCommon *app,
- const std::string &description,
- const WeekDaysRepeatData &data);
-
- static const std::map<WeekDayIso, std::string> weekDays;
+ CustomCheckBoxWithLabel(const std::string &description,
+ bool initialState,
+ const std::function<void(const UTF8 &text)> &bottomBarTemporaryMode = nullptr,
+ const std::function<void()> &bottomBarRestoreFromTemporaryMode = nullptr);
+ bool isChecked();
};
} // namespace gui
D module-apps/application-alarm-clock/widgets/addedit/AlarmOptionRepeat.cpp => module-apps/application-alarm-clock/widgets/addedit/AlarmOptionRepeat.cpp +0 -48
@@ 1,48 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 "AlarmOptionRepeat.hpp"
-#include <time/time/time_locale.hpp>
-
-namespace gui
-{
- AlarmOptionRepeat::AlarmOptionRepeat(app::ApplicationCommon *app,
- AlarmOptionItemName name,
- app::alarmClock::AlarmPresenter p,
- std::function<void(const UTF8 &text)> mode,
- std::function<void()> restore)
- : AlarmOptionsItem(app, name, std::move(mode), std::move(restore)), app::alarmClock::AlarmEventItem(p)
- {
- onSaveCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) { onSave(alarm); };
- onLoadCallback = [&](std::shared_ptr<AlarmEventRecord> alarm) { onLoad(alarm); };
- }
-
- void AlarmOptionRepeat::onSave(std::shared_ptr<AlarmEventRecord> alarm)
- {
- typedef utils::time::Locale::Day utl;
- static int i = 0;
- if (i == 0) {
- presenter().setDays({utl::Mon, utl::Tue});
- i++;
- }
- else if (i == 1) {
- presenter().setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri});
- i++;
- }
- else if (i == 2) {
- presenter().setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri, utl::Sat, utl::Sun});
- i++;
- }
- else if (i == 3) {
- presenter().setDays({});
- i = 0;
- }
- LOG_DEBUG("TEXT: %s .... %s", presenter().getDescription().c_str(), alarm->rruleText.c_str());
- }
-
- void AlarmOptionRepeat::onLoad(std::shared_ptr<AlarmEventRecord> alarm)
- {
- LOG_INFO("loading option repeat");
- descriptionLabel->setText(presenter().getDescription());
- }
-}; // namespace gui
D module-apps/application-alarm-clock/widgets/addedit/AlarmOptionRepeat.hpp => module-apps/application-alarm-clock/widgets/addedit/AlarmOptionRepeat.hpp +0 -29
@@ 1,29 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 "log.hpp"
-#pragma once
-
-#include <application-alarm-clock/widgets/AlarmOptionsItem.hpp>
-#include <application-alarm-clock/presenter/AlarmPresenter.hpp>
-
-namespace gui
-{
- class AlarmOptionRepeat : public AlarmOptionsItem, public app::alarmClock::AlarmEventItem
- {
- public:
- AlarmOptionRepeat(app::ApplicationCommon *app,
- AlarmOptionItemName name,
- app::alarmClock::AlarmPresenter p,
- std::function<void(const UTF8 &text)> mode = nullptr,
- std::function<void()> restore = nullptr);
-
- /// Will be changed - just example on how to save data
- /// sets value by presenter to model - to be set in db
- void onSave(std::shared_ptr<AlarmEventRecord> alarm);
- /// Will be changed - just example on usage how to load data
- /// loads value to UI
- void onLoad(std::shared_ptr<AlarmEventRecord> alarm);
- };
-
-} /* namespace gui */
M module-apps/application-alarm-clock/windows/AlarmClockMainWindow.cpp => module-apps/application-alarm-clock/windows/AlarmClockMainWindow.cpp +1 -0
@@ 85,6 85,7 @@ namespace app::alarmClock
if (inputEvent.isShortRelease(gui::KeyCode::KEY_LEFT)) {
auto rec = new AlarmEventRecord();
rec->startDate = TimePointNow();
+ rec->snoozeDuration = 10;
auto event = std::make_shared<AlarmEventRecord>(*rec);
std::unique_ptr<AlarmRecordData> data = std::make_unique<AlarmRecordData>(event);
data->setDescription(style::alarmClock::newAlarm);
M module-apps/application-alarm-clock/windows/CustomRepeatWindow.cpp => module-apps/application-alarm-clock/windows/CustomRepeatWindow.cpp +15 -11
@@ 3,6 3,11 @@
#include "CustomRepeatWindow.hpp"
+#include <application-alarm-clock/data/AlarmsData.hpp>
+#include <application-alarm-clock/widgets/AlarmClockStyle.hpp>
+
+#include <InputEvent.hpp>
+
namespace app::alarmClock
{
@@ 34,15 39,16 @@ namespace app::alarmClock
setFocusItem(list);
}
- void CustomRepeatWindow::onBeforeShow(gui::ShowMode mode, gui::SwitchData *data)
+ void CustomRepeatWindow::onClose(gui::Window::CloseReason reason)
{
- if (auto receivedData = dynamic_cast<WeekDaysRepeatData *>(data); receivedData != nullptr) {
- weekDaysOptData = *receivedData;
- }
- else {
- weekDaysOptData = WeekDaysRepeatData();
+ if (reason != CloseReason::PhoneLock) {
+ presenter->eraseProviderData();
}
- presenter->loadData(weekDaysOptData);
+ }
+
+ void CustomRepeatWindow::onBeforeShow(gui::ShowMode mode, gui::SwitchData *data)
+ {
+ presenter->loadData();
}
bool CustomRepeatWindow::onInput(const gui::InputEvent &inputEvent)
@@ 52,10 58,8 @@ namespace app::alarmClock
}
if (inputEvent.isShortRelease(gui::KeyCode::KEY_ENTER)) {
- weekDaysOptData = presenter->getWeekDaysRepeatData();
- application->switchWindow(style::alarmClock::window::name::newEditAlarm,
- gui::ShowMode::GUI_SHOW_RETURN,
- std::make_unique<WeekDaysRepeatData>(weekDaysOptData));
+ presenter->saveData();
+ application->switchWindow(style::alarmClock::window::name::newEditAlarm);
return true;
}
return false;
M module-apps/application-alarm-clock/windows/CustomRepeatWindow.hpp => module-apps/application-alarm-clock/windows/CustomRepeatWindow.hpp +5 -7
@@ 1,13 1,11 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// 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 "application-alarm-clock/widgets/AlarmClockStyle.hpp"
-#include "application-alarm-clock/presenter/CustomRepeatWindowPresenter.hpp"
-#include "application-alarm-clock/data/AlarmsData.hpp"
-#include "Application.hpp"
-#include <InputEvent.hpp>
+#include <application-alarm-clock/presenter/CustomRepeatWindowPresenter.hpp>
+
+#include <Application.hpp>
#include <ListView.hpp>
namespace app::alarmClock
@@ 16,13 14,13 @@ namespace app::alarmClock
{
gui::ListView *list = nullptr;
std::unique_ptr<CustomRepeatWindowContract::Presenter> presenter;
- WeekDaysRepeatData weekDaysOptData;
public:
CustomRepeatWindow(app::ApplicationCommon *app,
std::unique_ptr<CustomRepeatWindowContract::Presenter> &&windowPresenter);
void onBeforeShow(gui::ShowMode mode, gui::SwitchData *data) override;
+ void onClose(CloseReason reason) override;
bool onInput(const gui::InputEvent &inputEvent) override;
void buildInterface() override;
};
M module-apps/application-alarm-clock/windows/NewEditAlarmWindow.cpp => module-apps/application-alarm-clock/windows/NewEditAlarmWindow.cpp +0 -10
@@ 2,9 2,6 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "NewEditAlarmWindow.hpp"
-#include "application-alarm-clock/data/AlarmsData.hpp"
-#include "application-calendar/data/OptionParser.hpp"
-#include <module-db/Interface/AlarmEventRecord.hpp>
namespace app::alarmClock
{
@@ 54,13 51,6 @@ namespace app::alarmClock
}
presenter->loadData(alarmRecord);
}
-
- if (mode == gui::ShowMode::GUI_SHOW_RETURN) {
- if (auto receivedData = dynamic_cast<WeekDaysRepeatData *>(data); receivedData != nullptr) {
- presenter->updateRepeat(alarmRecord, *receivedData);
- presenter->loadRepeat(alarmRecord);
- }
- }
}
bool NewEditAlarmWindow::onInput(const gui::InputEvent &inputEvent)
M module-apps/application-calendar/models/MonthModel.cpp => module-apps/application-calendar/models/MonthModel.cpp +1 -1
@@ 38,7 38,7 @@ uint32_t MonthModel::getFirstWeekOffset()
return 6;
}
else {
- return this->firstWeekDayNumb - 1;
+ return this->firstWeekDayNumb;
}
}
M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +1 -0
@@ 40,6 40,7 @@ target_sources(apps-common
widgets/InputBox.cpp
widgets/ModesBox.cpp
widgets/SpinBox.cpp
+ widgets/TextSpinnerBox.cpp
widgets/TextWithIconsWidget.cpp
widgets/TimeSetSpinner.cpp
widgets/AlarmSetSpinner.cpp
M module-apps/apps-common/widgets/DateWidget.cpp => module-apps/apps-common/widgets/DateWidget.cpp +0 -5
@@ 125,11 125,6 @@ namespace gui
setOnInputCallback(*dayInput);
setOnInputCallback(*monthInput);
setOnInputCallback(*yearInput);
-
- dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
- vBox->setArea({0, 0, newDim.w, newDim.h});
- return true;
- };
}
date::year_month_day DateWidget::validateDate()
A module-apps/apps-common/widgets/TextSpinnerBox.cpp => module-apps/apps-common/widgets/TextSpinnerBox.cpp +67 -0
@@ 0,0 1,67 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "TextSpinnerBox.hpp"
+
+namespace gui
+{
+ TextSpinnerBox::TextSpinnerBox(Item *parent, const std::vector<UTF8> &data, Boundaries boundaries) : HBox(parent)
+ {
+ setEdges(RectangleEdge::Bottom);
+
+ leftArrow = new gui::ImageBox(this, new Image("arrow_left_24px_W_G"));
+ leftArrow->setMinimumSizeToFitImage();
+ leftArrow->setVisible(false);
+
+ spinner = new UTF8Spinner(data, Boundaries::Continuous, Orientation::Horizontal);
+ spinner->setFont(style::window::font::medium);
+ spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ spinner->setEdges(RectangleEdge::All);
+ spinner->setVisible(true);
+ addWidget(spinner);
+
+ rightArrow = new gui::ImageBox(this, new Image("arrow_right_24px_W_G"));
+ rightArrow->setMinimumSizeToFitImage();
+ rightArrow->setVisible(false);
+
+ inputCallback = [&](Item &item, const InputEvent &event) { return spinner->onInput(event); };
+
+ focusChangedCallback = [&](gui::Item &item) {
+ if (focus) {
+ leftArrow->setVisible(true);
+ rightArrow->setVisible(true);
+ spinner->setFont(style::window::font::mediumbold);
+ setPenWidth(style::window::default_border_focus_w);
+ }
+ else {
+ leftArrow->setVisible(false);
+ rightArrow->setVisible(false);
+ spinner->setFont(style::window::font::medium);
+ setPenWidth(style::window::default_border_rect_no_focus);
+ }
+ resizeItems();
+ return true;
+ };
+
+ dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
+ spinner->setMaximumSize(widgetArea.w, widgetArea.h);
+ resizeItems();
+ return true;
+ };
+ }
+
+ void TextSpinnerBox::setData(const std::vector<UTF8> &data)
+ {
+ spinner->setRange(data);
+ }
+
+ UTF8 TextSpinnerBox::getCurrentValue() const noexcept
+ {
+ return spinner->getCurrentValue();
+ }
+
+ void TextSpinnerBox::setCurrentValue(UTF8 val)
+ {
+ spinner->setCurrentValue(val);
+ }
+} // namespace gui
A module-apps/apps-common/widgets/TextSpinnerBox.hpp => module-apps/apps-common/widgets/TextSpinnerBox.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 <widgets/spinners/Spinners.hpp>
+#include <BoxLayout.hpp>
+#include <ImageBox.hpp>
+
+#include <vector>
+
+namespace gui
+{
+ class TextSpinnerBox : public HBox
+ {
+ public:
+ TextSpinnerBox(Item *parent, const 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;
+ };
+} // namespace gui
M module-apps/apps-common/widgets/spinners/GenericSpinner.hpp => module-apps/apps-common/widgets/spinners/GenericSpinner.hpp +42 -24
@@ 14,32 14,35 @@ namespace gui
using Range = typename Policy::Range;
using Type = typename Policy::Type;
- explicit GenericSpinner(Range range, Boundaries boundaries = Boundaries::Continuous);
-
- void setFocusEdges(RectangleEdge edges);
+ 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);
- private:
+ void setFocusEdges(RectangleEdge edges);
bool onInput(const InputEvent &inputEvent) override;
-
bool onFocus(bool state) override;
+ private:
void stepNext();
-
void stepPrevious();
-
+ bool isPreviousEvent(const InputEvent &inputEvent);
+ bool isNextEvent(const InputEvent &inputEvent);
void update();
Policy policy;
RectangleEdge focusEdges = RectangleEdge::Bottom;
+ Orientation orientation = Orientation::Vertical;
};
template <typename ValuePolicy>
- GenericSpinner<ValuePolicy>::GenericSpinner(GenericSpinner::Range range, Boundaries boundaries)
- : policy{range, boundaries}
+ GenericSpinner<ValuePolicy>::GenericSpinner(GenericSpinner::Range range,
+ Boundaries boundaries,
+ Orientation orientation)
+ : policy{range, boundaries}, orientation(orientation)
{
setEditMode(EditMode::Browse);
drawUnderline(false);
@@ 51,24 54,46 @@ namespace gui
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_UP)) ||
+ (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_DOWN)) ||
+ (orientation == Orientation::Horizontal && inputEvent.is(KeyCode::KEY_RIGHT));
+ }
+
template <typename ValuePolicy> bool GenericSpinner<ValuePolicy>::onInput(const InputEvent &inputEvent)
{
if (inputEvent.isShortRelease()) {
- switch (inputEvent.getKeyCode()) {
- case KeyCode::KEY_UP:
- stepNext();
- return true;
- case KeyCode::KEY_DOWN:
+ if (isPreviousEvent(inputEvent)) {
stepPrevious();
return true;
- default:
- break;
+ }
+ else if (isNextEvent(inputEvent)) {
+ stepNext();
+ return true;
}
}
return false;
@@ 102,11 127,4 @@ namespace gui
{
setText(policy.str());
}
-
- template <typename Policy>
- typename GenericSpinner<Policy>::Type GenericSpinner<Policy>::getCurrentValue() const noexcept
- {
- return policy.get();
- }
-
} // namespace gui
M module-apps/apps-common/widgets/spinners/SpinnerContents.hpp => module-apps/apps-common/widgets/spinners/SpinnerContents.hpp +2 -0
@@ 10,6 10,8 @@ namespace gui
template <typename ValueT, typename StringT> class NumWithString
{
public:
+ NumWithString() = default;
+
NumWithString(ValueT value, StringT string) : value{value}, string{string}
{}
M module-apps/apps-common/widgets/spinners/SpinnerPolicies.hpp => module-apps/apps-common/widgets/spinners/SpinnerPolicies.hpp +22 -7
@@ 5,10 5,9 @@
#include <gui/Common.hpp>
-#include <utf8/UTF8.hpp>
-
-#include <cstdint>
#include <vector>
+#include <cstdint>
+#include <utf8/UTF8.hpp>
namespace gui
{
@@ 23,12 22,12 @@ namespace gui
ValType get() const
{
- return range[pos];
+ return pos < range.size() ? range[pos] : ValType{};
}
UTF8 str() const
{
- return range[pos];
+ return pos < range.size() ? range[pos] : UTF8{};
}
void set(ValType val)
@@ 71,13 70,21 @@ namespace gui
}
}
+ void updateRange(Range newRange)
+ {
+ if (range != newRange) {
+ range = newRange;
+ pos = 0;
+ }
+ }
+
private:
std::uint32_t upRange() const
{
return range.size() - 1;
}
- const Range range;
+ Range range;
std::uint32_t pos{};
const Boundaries boundaries{};
};
@@ 141,8 148,16 @@ namespace gui
}
}
+ void updateRange(Range newRange)
+ {
+ if (range != newRange) {
+ range = newRange;
+ currentValue = 0;
+ }
+ }
+
private:
- const Range range;
+ Range range;
ValType currentValue{};
const Boundaries boundaries{};
};
M module-gui/gui/Common.hpp => module-gui/gui/Common.hpp +4 -13
@@ 72,20 72,10 @@ namespace gui
GUI_SHOW_RETURN
};
- enum class AlignementFlags
- {
- GUI_ALIGN_VERTICAL_CENTER = 0x01,
- GUI_ALIGN_VERTICAL_TOP = 0x02,
- GUI_ALIGN_VERTICAL_BOTTOM = 0x04,
- GUI_ALIGN_HORIZONTAL_CENTER = 0x08,
- GUI_ALIGN_HORIZONTAL_LEFT = 0x10,
- GUI_ALIGN_HORIZONTAL_RIGHT = 0x20
- };
-
- enum class OrientationFlags
+ enum class Orientation
{
- GUI_ORIENTATION_HORIZONTAL = 0x00,
- GUI_ORIENTATION_VERTICAL = 0x01
+ Vertical,
+ Horizontal
};
template <class T> bool operator&(const T &lhs, const T &rhs)
@@ 139,6 129,7 @@ namespace gui
BottomLeft = 0x40,
BottomRight = 0x80,
};
+
enum class Boundaries
{
Fixed, ///< Fixed - will stop scrolling on first or last elements on appropriate top or bottom
M module-gui/gui/widgets/BoxLayout.cpp => module-gui/gui/widgets/BoxLayout.cpp +1 -1
@@ 569,7 569,7 @@ namespace gui
resizeItems();
setNavigation();
- return true;
+ return Item::onDimensionChanged(oldDim, newDim);
}
HBox::HBox() : BoxLayout()
M module-gui/gui/widgets/ImageBox.cpp => module-gui/gui/widgets/ImageBox.cpp +4 -2
@@ 5,8 5,7 @@
using namespace gui;
-ImageBox::ImageBox(
- Item *parent, const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h, Image *image)
+ImageBox::ImageBox(Item *parent, const Position &x, const Position &y, const Length &w, const Length &h, Image *image)
: HBox(parent, x, y, w, h), image(image)
{
setEdges(RectangleEdge::None);
@@ 14,6 13,9 @@ ImageBox::ImageBox(
addWidget(image);
}
+ImageBox::ImageBox(Item *parent, Image *image) : ImageBox(parent, 0, 0, 0, 0, image)
+{}
+
void ImageBox::showImage(bool show)
{
image->setVisible(show);
M module-gui/gui/widgets/ImageBox.hpp => module-gui/gui/widgets/ImageBox.hpp +2 -2
@@ 11,8 11,8 @@ namespace gui
class ImageBox : public HBox
{
public:
- ImageBox(
- Item *parent, const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h, Image *image);
+ ImageBox(Item *parent, const Position &x, const Position &y, const Length &w, const Length &h, Image *image);
+ ImageBox(Item *parent, Image *image);
~ImageBox() override = default;
M module-gui/gui/widgets/Style.hpp => module-gui/gui/widgets/Style.hpp +3 -0
@@ 165,6 165,7 @@ namespace style
inline constexpr auto call = "common_call";
inline constexpr auto send = "common_send";
inline constexpr auto save = "common_save";
+ inline constexpr auto edit = "common_edit";
inline constexpr auto import = "common_import";
inline constexpr auto confirm = "common_confirm";
inline constexpr auto select = "common_select";
@@ 237,6 238,8 @@ namespace style
inline constexpr auto item_width_with_scroll =
style::window::default_body_width - style::listview::scroll::item_margin;
+ inline constexpr auto item_width_with_without_scroll =
+ style::window::default_body_width - 2 * style::listview::scroll::item_margin;
inline constexpr auto body_width_with_scroll =
style::window::default_body_width + style::listview::scroll::margin;
M module-services/service-time/ServiceTime.hpp => module-services/service-time/ServiceTime.hpp +1 -1
@@ 30,7 30,7 @@ namespace stm
class ServiceTime : public sys::Service
{
private:
- static constexpr auto StackDepth = 2048;
+ static constexpr auto StackDepth = 2048 * 4;
std::unique_ptr<TimeManager> timeManager;
M module-utils/time/time/time_locale.hpp => module-utils/time/time/time_locale.hpp +11 -9
@@ 28,7 28,7 @@ namespace utils
// imo it would be nicer to have datetime locales in different json with thiny bit nicer and more effective
// getters
const std::array<std::string, num_days> daysShort = {
- "common_mo", "common_tu", "common_we", "common_th", "common_fr", "common_sa", "common_su"};
+ "common_sun", "common_mon", "common_tue", "common_wed", "common_thu", "common_fri", "common_sat"};
const std::array<std::string, num_days> days = {"common_sunday",
"common_monday",
@@ 158,9 158,15 @@ namespace utils
LOG_ERROR("Bad value: %d", day);
return "";
}
- else {
- return translate(tlocale.days[day]);
+ return translate(tlocale.days[day]);
+ }
+
+ static const UTF8 get_day(const uint32_t &day)
+ {
+ if (day >= num_days) {
+ return "";
}
+ return translate(tlocale.days[day]);
}
static const UTF8 get_short_day(const uint32_t &day)
@@ 169,9 175,7 @@ namespace utils
LOG_ERROR("Bad value");
return "";
}
- else {
- return translate(tlocale.daysShort[day]);
- }
+ return translate(tlocale.daysShort[day]);
}
static const UTF8 get_month(enum Month mon)
@@ 180,9 184,7 @@ namespace utils
LOG_ERROR("Bad value %d", mon);
return "";
}
- else {
- return translate(tlocale.months[mon]);
- }
+ return translate(tlocale.months[mon]);
}
static const UTF8 yesterday()