M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 7,6 7,7 @@
### Added
* Added custom alarms functionality
+* Added update instruction screen at end of onboarding
### Changed / Improved
* Changed the refresh rate of the progress bar screen
M image/system_a/data/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +5 -0
@@ 130,6 130,11 @@
"app_bell_settings_time_units_time_message": "Zeit",
"app_bell_settings_turn_off": "Ausschalten",
"app_bell_turn_off_question": "Schalten Sie das Ger\u00e4t aus?",
+ "app_bell_update_instruction_title": "Update-Leitfaden",
+ "app_bell_update_instruction_1st_point": "<text>Lade Mudita Center über<br/><text weight='regular'>mudita.com/center</text></text>",
+ "app_bell_update_instruction_2nd_point": "Verbinde Harmony per USB-C mit dem PC",
+ "app_bell_update_instruction_3rd_point": "Öffne Mudita Center",
+ "app_bell_update_instruction_4th_point": "<text>Klicke in Overview auf <text weight='regular'>Update</text></text>",
"app_bell_welcome_charge_message": "<text>Charge Harmony<br/>und leicht dr\u00fccken</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>ist ausgeschaltet</text>",
"app_bellmain_alarm": "Alarm",
M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +5 -0
@@ 164,6 164,11 @@
"app_bell_settings_time_units_time_message": "Time",
"app_bell_settings_turn_off": "Turn off",
"app_bell_turn_off_question": "Turn off Mudita Harmony?",
+ "app_bell_update_instruction_title": "Update Guide",
+ "app_bell_update_instruction_1st_point": "<text>Download Mudita Center from<br/><text weight='regular'>mudita.com/center</text></text>",
+ "app_bell_update_instruction_2nd_point": "Connect Harmony to computer via USB-C",
+ "app_bell_update_instruction_3rd_point": "Open Mudita Center",
+ "app_bell_update_instruction_4th_point": "<text>On Overview click<br/><text weight='regular'>Update</text></text>",
"app_bell_welcome_charge_message": "<text>Charge Harmony<br/>and press light click</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>is switched OFF</text>",
"app_bellmain_alarm": "Alarm",
M image/system_a/data/lang/Espanol.json => image/system_a/data/lang/Espanol.json +5 -0
@@ 129,6 129,11 @@
"app_bell_settings_time_units_time_message": "Hora",
"app_bell_settings_turn_off": "Apagar",
"app_bell_turn_off_question": "\u00bfApagar Mudita Harmony?",
+ "app_bell_update_instruction_title": "Cómo actualizar",
+ "app_bell_update_instruction_1st_point": "<text>Descarga Mudita Center en<br/><text weight='regular'>mudita.com/center</text></text>",
+ "app_bell_update_instruction_2nd_point": "Conecta Harmony a un PC con un USB-C",
+ "app_bell_update_instruction_3rd_point": "Abre Mudita Center",
+ "app_bell_update_instruction_4th_point": "<text>Haz clic en <text weight='regular'>Update</text> en<br/>Overview</text>",
"app_bell_welcome_charge_message": "<text>Carga tu Harmony<br/>y pulsa levemente</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>est\u00e1 apagado</text>",
"app_bellmain_alarm": "Alarma",
M image/system_a/data/lang/Francais.json => image/system_a/data/lang/Francais.json +5 -0
@@ 131,6 131,11 @@
"app_bell_settings_time_units_time_message": "Heure",
"app_bell_settings_turn_off": "\u00c9teindre",
"app_bell_turn_off_question": "\u00c9teindre l'appareil ?",
+ "app_bell_update_instruction_title": "Guide des MaJ",
+ "app_bell_update_instruction_1st_point": "<text>Téléchargez Mudita Center sur<br/><text weight='regular'>mudita.com/center</text></text>",
+ "app_bell_update_instruction_2nd_point": "Branchez Harmony à votre PC via USB-C",
+ "app_bell_update_instruction_3rd_point": "Ouvrez Mudita Center",
+ "app_bell_update_instruction_4th_point": "<text>Dans Overview ><br/><text weight='regular'>Update</text></text>",
"app_bell_welcome_charge_message": "<text>Rechargez Harmony<br/>et appuyez l\u00e9g\u00e8rement</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>est d\u00e9sactiv\u00e9</text>",
"app_bellmain_alarm": "Alarme",
M image/system_a/data/lang/Polski.json => image/system_a/data/lang/Polski.json +5 -0
@@ 130,6 130,11 @@
"app_bell_settings_time_units_time_message": "Czas",
"app_bell_settings_turn_off": "Wy\u0142\u0105cz",
"app_bell_turn_off_question": "Wy\u0142\u0105czy\u0107 Mudita Harmony?",
+ "app_bell_update_instruction_title": "Jak aktualizować",
+ "app_bell_update_instruction_1st_point": "<text>Pobierz Mudita Center<br/>z <text weight='regular'>mudita.com/center</text></text>",
+ "app_bell_update_instruction_2nd_point": "Podłącz Harmony do PC za pomocą USB-C",
+ "app_bell_update_instruction_3rd_point": "Otwórz Mudita Center",
+ "app_bell_update_instruction_4th_point": "<text>Kliknij <text weight='regular'>Update</text><br/>w Overview</text>",
"app_bell_welcome_charge_message": "<text>Na\u0142aduj Harmony<br/>i kliknij lekko</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>jest wy\u0142\u0105czony</text>",
"app_bellmain_alarm": "Alarm",
M module-gui/gui/widgets/ThreeBox.cpp => module-gui/gui/widgets/ThreeBox.cpp +2 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ThreeBox.hpp"
@@ 21,6 21,7 @@ namespace gui
{}
template class HThreeBox<HBox, HBox, HBox>;
+ template class HThreeBox<HBox, VBox, HBox>;
template class VThreeBox<VBox, VBox, VBox>;
} // namespace gui
M products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp => products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp +20 -1
@@ 5,6 5,7 @@
#include <presenter/OnBoardingLanguageWindowPresenter.hpp>
#include <presenter/OnBoardingShortcutsWindowPresenter.hpp>
+#include <presenter/OnBoardingUpdateInstructionWindowPresenter.hpp>
#include <windows/OnBoardingLanguageWindow.hpp>
#include <windows/OnBoardingFinalizeWindow.hpp>
#include <windows/OnBoardingOnOffWindow.hpp>
@@ 21,6 22,7 @@
#include <common/windows/BellFinishedWindow.hpp>
#include <common/windows/BellWelcomeWindow.hpp>
#include <common/windows/ShortcutsWindow.hpp>
+#include <common/windows/UpdateInstructionWindow.hpp>
#include <common/models/LayoutModel.hpp>
#include <application-bell-settings/models/TemperatureUnitModel.hpp>
@@ 119,6 121,13 @@ namespace app
});
windowsFactory.attach(
+ gui::window::name::onBoardingUpdateInstructionWindow,
+ [this](ApplicationCommon *app, const std::string &name) {
+ auto presenter = std::make_unique<OnBoarding::OnBoardingUpdateInstructionWindowPresenter>(this);
+ return std::make_unique<gui::UpdateInstructionWindow>(app, std::move(presenter), name);
+ });
+
+ windowsFactory.attach(
gui::window::name::onBoardingSettingsWindow, [this](ApplicationCommon *app, const std::string &name) {
auto layoutModel = std::make_unique<bell_settings::LayoutModel>(this);
auto temperatureUnitModel = std::make_unique<bell_settings::TemperatureUnitModel>(app);
@@ 290,11 299,21 @@ namespace app
else
informationState = OnBoarding::InformationStates::RotateInfo;
}
+ else if (window->getName() == gui::window::name::onBoardingUpdateInstructionWindow) {
+ const auto updateInstructionWindow = dynamic_cast<gui::UpdateInstructionWindow *>(window);
+ if (updateInstructionWindow != nullptr && updateInstructionWindow->isLastLayout()) {
+ informationState = OnBoarding::InformationStates::RotateInfo;
+ }
+ else {
+ informationState = OnBoarding::InformationStates::LightClickInfo;
+ }
+ }
else {
informationState = OnBoarding::InformationStates::LightClickInfo;
}
}
- else if (getCurrentWindow()->getName() != gui::window::name::onBoardingShortcutsWindow) {
+ else if (getCurrentWindow()->getName() != gui::window::name::onBoardingShortcutsWindow &&
+ getCurrentWindow()->getName() != gui::window::name::onBoardingUpdateInstructionWindow) {
if (inputEvent.isKeyRelease(gui::KeyCode::KEY_RIGHT) ||
inputEvent.isKeyRelease(gui::KeyCode::KEY_LEFT)) {
informationState = OnBoarding::InformationStates::DeepClickWarningInfo;
M products/BellHybrid/apps/application-bell-onboarding/CMakeLists.txt => products/BellHybrid/apps/application-bell-onboarding/CMakeLists.txt +2 -0
@@ 23,10 23,12 @@ target_sources(application-bell-onboarding
presenter/OnBoardingLanguageWindowPresenter.cpp
presenter/OnBoardingFinalizeWindowPresenter.cpp
presenter/OnBoardingShortcutsWindowPresenter.cpp
+ presenter/OnBoardingUpdateInstructionWindowPresenter.cpp
presenter/OnBoardingLanguageWindowPresenter.hpp
presenter/OnBoardingFinalizeWindowPresenter.hpp
presenter/OnBoardingShortcutsWindowPresenter.hpp
+ presenter/OnBoardingUpdateInstructionWindowPresenter.hpp
windows/OnBoardingLanguageWindow.hpp
windows/OnBoardingOnOffWindow.hpp
windows/OnBoardingSettingsWindow.hpp
M products/BellHybrid/apps/application-bell-onboarding/include/application-bell-onboarding/BellOnBoardingNames.hpp => products/BellHybrid/apps/application-bell-onboarding/include/application-bell-onboarding/BellOnBoardingNames.hpp +9 -8
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 12,12 12,13 @@ namespace app
namespace gui::window::name
{
- inline constexpr auto onBoardingOnOffWindow = "BellOnBoardingOnOff";
- inline constexpr auto onBoardingLanguageWindow = "BellOnBoardingLanguage";
- inline constexpr auto onBoardingShortcutsOptionWindow = "BellOnBoardingShortcutsOption";
- inline constexpr auto onBoardingShortcutsWindow = gui::window::name::shortcutsWindow;
- inline constexpr auto onBoardingSettingsWindow = "BellOnBoardingSettings";
- inline constexpr auto finalizeOnBoardingWindow = "BellOnBoardingFinalize";
- inline constexpr auto informationOnBoardingWindow = "BellOnBoardingInformation";
+ inline constexpr auto onBoardingOnOffWindow = "BellOnBoardingOnOff";
+ inline constexpr auto onBoardingLanguageWindow = "BellOnBoardingLanguage";
+ inline constexpr auto onBoardingShortcutsOptionWindow = "BellOnBoardingShortcutsOption";
+ inline constexpr auto onBoardingShortcutsWindow = gui::window::name::shortcutsWindow;
+ inline constexpr auto onBoardingUpdateInstructionWindow = gui::window::name::updateInstructionWindow;
+ inline constexpr auto onBoardingSettingsWindow = "BellOnBoardingSettings";
+ inline constexpr auto finalizeOnBoardingWindow = "BellOnBoardingFinalize";
+ inline constexpr auto informationOnBoardingWindow = "BellOnBoardingInformation";
} // namespace gui::window::name
A products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingUpdateInstructionWindowPresenter.cpp => products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingUpdateInstructionWindowPresenter.cpp +57 -0
@@ 0,0 1,57 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "OnBoardingUpdateInstructionWindowPresenter.hpp"
+#include <BellOnBoardingNames.hpp>
+#include <common/layouts/UpdateInstructionLayoutProvider.hpp>
+#include <common/layouts/UpdateInstructionLayouts.hpp>
+#include <InputEvent.hpp>
+#include <keymap/KeyMap.hpp>
+
+namespace app::OnBoarding
+{
+ OnBoardingUpdateInstructionWindowPresenter::OnBoardingUpdateInstructionWindowPresenter(app::ApplicationCommon *app)
+ : app(app)
+ {
+ initLayoutOptions();
+ }
+
+ std::vector<gui::Item *> OnBoardingUpdateInstructionWindowPresenter::getLayouts() const
+ {
+ return layoutOptions;
+ }
+
+ gui::Item *OnBoardingUpdateInstructionWindowPresenter::getFirstLayout() const
+ {
+ return layoutOptions.empty() ? nullptr : layoutOptions.front();
+ }
+
+ bool OnBoardingUpdateInstructionWindowPresenter::isLastLayout(const gui::Item *layout) const
+ {
+ return !layoutOptions.empty() && layoutOptions.back() == layout;
+ }
+
+ void OnBoardingUpdateInstructionWindowPresenter::initLayoutOptions()
+ {
+ const auto layoutsList = gui::factory::getUpdateInstructionLayouts();
+
+ for (auto &layoutEntry : layoutsList) {
+ layoutOptions.push_back(layoutEntry()->getLayout());
+ }
+ }
+
+ bool OnBoardingUpdateInstructionWindowPresenter::onInput(const gui::InputEvent &inputEvent,
+ const gui::Item *currentLayout)
+ {
+ if (inputEvent.isShortRelease()) {
+ const auto key = mapKey(inputEvent.getKeyCode());
+ if (key == KeyMap::LightPress) {
+ if (isLastLayout(currentLayout)) {
+ app->switchWindow(gui::window::name::finalizeOnBoardingWindow);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+} // namespace app::OnBoarding
A products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingUpdateInstructionWindowPresenter.hpp => products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingUpdateInstructionWindowPresenter.hpp +29 -0
@@ 0,0 1,29 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <common/windows/UpdateInstructionWindowContract.hpp>
+#include <apps-common/ApplicationCommon.hpp>
+
+#include <vector>
+#include <Item.hpp>
+
+namespace app::OnBoarding
+{
+ class OnBoardingUpdateInstructionWindowPresenter : public gui::UpdateInstructionWindowContract::Presenter
+ {
+ private:
+ app::ApplicationCommon *app;
+ std::vector<gui::Item *> layoutOptions;
+ void initLayoutOptions();
+
+ public:
+ explicit OnBoardingUpdateInstructionWindowPresenter(app::ApplicationCommon *app);
+
+ std::vector<gui::Item *> getLayouts() const override;
+ bool isLastLayout(const gui::Item *layout) const override;
+ gui::Item *getFirstLayout() const override;
+ bool onInput(const gui::InputEvent &inputEvent, const gui::Item *currentLayout) override;
+ };
+} // namespace app::OnBoarding
M products/BellHybrid/apps/application-bell-onboarding/windows/OnBoardingSettingsWindow.cpp => products/BellHybrid/apps/application-bell-onboarding/windows/OnBoardingSettingsWindow.cpp +2 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "OnBoardingSettingsWindow.hpp"
@@ 12,7 12,7 @@ namespace gui
std::string name)
: BellSettingsTimeUnitsWindow(app, std::move(windowPresenter), name)
{
- finishedCallback = [this]() { application->switchWindow(window::name::finalizeOnBoardingWindow); };
+ finishedCallback = [this]() { application->switchWindow(window::name::onBoardingUpdateInstructionWindow); };
returnCallback = [this]() { application->switchWindow(window::name::onBoardingShortcutsOptionWindow); };
}
} // namespace gui
M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +8 -0
@@ 37,6 37,7 @@ target_sources(application-bell-common
src/windows/BellBatteryStatusWindow.cpp
src/windows/AppsBatteryStatusWindow.cpp
src/windows/AudioErrorWindow.cpp
+ src/windows/UpdateInstructionWindow.cpp
src/models/SettingsModel.cpp
src/models/BedtimeModel.cpp
@@ 87,6 88,8 @@ target_sources(application-bell-common
src/layouts/HomeScreenLayoutVerticalWithDate.cpp
src/layouts/ShortcutsLayouts.cpp
src/layouts/ShortcutsLayoutClassic.cpp
+ src/layouts/UpdateInstructionLayouts.cpp
+ src/layouts/UpdateInstructionLayoutClassic.cpp
PUBLIC
include/common/BellListItemProvider.hpp
@@ 104,6 107,8 @@ target_sources(application-bell-common
include/common/windows/BellBatteryStatusWindow.hpp
include/common/windows/AppsBatteryStatusWindow.hpp
include/common/windows/AudioErrorWindow.hpp
+ include/common/windows/UpdateInstructionWindowContract.hpp
+ include/common/windows/UpdateInstructionWindow.hpp
include/common/TimeUtils.hpp
include/common/data/BatteryUtils.hpp
@@ 173,6 178,9 @@ target_sources(application-bell-common
include/common/layouts/ShortcutsLayouts.hpp
include/common/layouts/ShortcutsLayoutProvider.hpp
include/common/layouts/ShortcutsLayoutClassic.hpp
+ include/common/layouts/UpdateInstructionLayouts.hpp
+ include/common/layouts/UpdateInstructionLayoutProvider.hpp
+ include/common/layouts/UpdateInstructionLayoutClassic.hpp
)
target_link_libraries(application-bell-common
M products/BellHybrid/apps/common/include/common/BellCommonNames.hpp => products/BellHybrid/apps/common/include/common/BellCommonNames.hpp +3 -2
@@ 5,6 5,7 @@
namespace gui::window::name
{
- inline constexpr auto shortcutsWindow = "BellShortcuts";
- inline constexpr auto audioErrorWindow = "AudioError";
+ inline constexpr auto shortcutsWindow = "BellShortcuts";
+ inline constexpr auto updateInstructionWindow = "BellUpdateInstruction";
+ inline constexpr auto audioErrorWindow = "AudioError";
} // namespace gui::window::name
A products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayoutClassic.hpp => products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayoutClassic.hpp +45 -0
@@ 0,0 1,45 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "UpdateInstructionLayoutProvider.hpp"
+
+#include <BoxLayout.hpp>
+#include <ImageBox.hpp>
+
+namespace gui
+{
+ class BellBaseLayout;
+
+ using Instruction = std::vector<std::pair<std::string, UTF8>>;
+
+ class UpdateInstructionLayoutClassic : public UpdateInstructionLayoutProvider, VBox
+ {
+ public:
+ UpdateInstructionLayoutClassic(const UTF8 &image,
+ const UTF8 &title,
+ const Instruction &instruction,
+ bool leftArrowVisible = true,
+ bool rightArrowVisible = true);
+
+ auto getLayout() -> Item * override;
+
+ private:
+ struct InstructionPoint
+ {
+ HBox *container;
+ Text *textBox;
+ Text *numberBox;
+ };
+ std::vector<InstructionPoint> instructionPoints;
+
+ ImageBox *leftArrowBox;
+ ImageBox *rightArrowBox;
+
+ Text *titleBox;
+ ImageBox *imageBox;
+
+ void buildInterface(const Instruction &instruction);
+ };
+}; // namespace gui
A products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayoutProvider.hpp => products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayoutProvider.hpp +30 -0
@@ 0,0 1,30 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <utf8/UTF8.hpp>
+
+namespace gui
+{
+ class Item;
+
+ class UpdateInstructionLayoutProvider
+ {
+ protected:
+ const UTF8 image;
+ const UTF8 title;
+ const bool leftArrowVisible;
+ const bool rightArrowVisible;
+
+ public:
+ UpdateInstructionLayoutProvider(const UTF8 &image,
+ const UTF8 &title,
+ bool leftArrow = true,
+ bool rightArrow = true)
+ : image{image}, title{title}, leftArrowVisible{leftArrow}, rightArrowVisible{rightArrow} {};
+ virtual ~UpdateInstructionLayoutProvider() noexcept = default;
+
+ virtual Item *getLayout() = 0;
+ };
+}; // namespace gui
A products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayouts.hpp => products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayouts.hpp +19 -0
@@ 0,0 1,19 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <functional>
+#include <map>
+#include <string>
+
+namespace gui
+{
+ class UpdateInstructionLayoutProvider;
+ using LayoutGenerator = std::function<UpdateInstructionLayoutProvider *()>;
+
+ namespace factory
+ {
+ std::vector<LayoutGenerator> getUpdateInstructionLayouts();
+ } // namespace factory
+}; // namespace gui
A products/BellHybrid/apps/common/include/common/windows/UpdateInstructionWindow.hpp => products/BellHybrid/apps/common/include/common/windows/UpdateInstructionWindow.hpp +32 -0
@@ 0,0 1,32 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "UpdateInstructionWindowContract.hpp"
+#include <ApplicationCommon.hpp>
+#include <AppWindow.hpp>
+#include <apps-common/widgets/spinners/Spinners.hpp>
+
+namespace gui
+{
+ class SideListView;
+ class UpdateInstructionWindow : public AppWindow, public UpdateInstructionWindowContract::View
+ {
+ std::unique_ptr<UpdateInstructionWindowContract::Presenter> presenter;
+ SideListView *sideListView = nullptr;
+ WidgetSpinner *spinner = nullptr;
+
+ bool onInput(const gui::InputEvent &inputEvent) override;
+ void buildInterface() override;
+
+ void onValueChanged(const std::uint32_t currentValue);
+
+ public:
+ UpdateInstructionWindow(app::ApplicationCommon *app,
+ std::unique_ptr<UpdateInstructionWindowContract::Presenter> &&presenter,
+ const std::string &name);
+
+ bool isLastLayout() const;
+ };
+} // namespace gui
A products/BellHybrid/apps/common/include/common/windows/UpdateInstructionWindowContract.hpp => products/BellHybrid/apps/common/include/common/windows/UpdateInstructionWindowContract.hpp +30 -0
@@ 0,0 1,30 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <apps-common/BasePresenter.hpp>
+#include <vector>
+#include <Item.hpp>
+
+namespace gui
+{
+ class UpdateInstructionWindowContract
+ {
+ public:
+ class View
+ {
+ public:
+ virtual ~View() = default;
+ };
+
+ class Presenter : public app::BasePresenter<UpdateInstructionWindowContract::View>
+ {
+ public:
+ virtual std::vector<gui::Item *> getLayouts() const = 0;
+ virtual bool isLastLayout(const gui::Item *layout) const = 0;
+ virtual gui::Item *getFirstLayout() const = 0;
+ virtual bool onInput(const gui::InputEvent &inputEvent, const gui::Item *currentLayout) = 0;
+ };
+ };
+} // namespace gui
A products/BellHybrid/apps/common/src/layouts/UpdateInstructionLayoutClassic.cpp => products/BellHybrid/apps/common/src/layouts/UpdateInstructionLayoutClassic.cpp +187 -0
@@ 0,0 1,187 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "layouts/UpdateInstructionLayoutClassic.hpp"
+#include <apps-common/widgets/BellBaseLayout.hpp>
+#include <i18n/i18n.hpp>
+#include <Style.hpp>
+#include <TextFixedSize.hpp>
+
+namespace
+{
+ namespace container
+ {
+ constexpr auto width = 544U;
+ constexpr auto height = 436U;
+ constexpr auto top_margin = 20U;
+
+ namespace centerBox
+ {
+ constexpr auto width = 448U;
+ constexpr auto height = container::height;
+ } // namespace centerBox
+
+ namespace imageBox
+ {
+ constexpr auto width = centerBox::width;
+ constexpr auto height = 120U;
+ } // namespace imageBox
+
+ namespace title
+ {
+ constexpr auto height = 56U;
+ constexpr auto width = centerBox::width;
+ constexpr auto font = style::window::font::large;
+ constexpr auto bottom_margin = 32U;
+ } // namespace title
+
+ namespace instruction
+ {
+ constexpr auto maxNumberOfLines = 3;
+ constexpr auto width = centerBox::width - 40U;
+ constexpr auto minHeight = 43U;
+ constexpr auto maxHeight = minHeight * maxNumberOfLines;
+ constexpr auto bottom_margin = 14U;
+
+ namespace number
+ {
+ constexpr auto width = 36U;
+ constexpr auto font = style::window::font::verybiglight;
+ } // namespace number
+
+ namespace text
+ {
+ constexpr auto width = instruction::width - number::width;
+ constexpr auto font = style::window::font::verybiglight;
+ } // namespace text
+ } // namespace instruction
+
+ } // namespace container
+} // namespace
+
+namespace gui
+{
+ UpdateInstructionLayoutClassic::UpdateInstructionLayoutClassic(const UTF8 &image,
+ const UTF8 &title,
+ const Instruction &instruction,
+ bool leftArrowVisible,
+ bool rightArrowVisible)
+ : UpdateInstructionLayoutProvider(image, title, leftArrowVisible, rightArrowVisible),
+ VBox(nullptr, 0, 0, style::bell_base_layout::w, style::bell_base_layout::h)
+ {
+ buildInterface(instruction);
+ }
+
+ void UpdateInstructionLayoutClassic::buildInterface(const Instruction &instruction)
+ {
+ setAlignment(Alignment::Horizontal::Center);
+
+ auto containerThreeBox = new HThreeBox<HBox, VBox, HBox>(this);
+ containerThreeBox->setMinimumSize(container::width, container::height);
+ containerThreeBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ containerThreeBox->setMargins(Margins(0, container::top_margin, 0, 0));
+ containerThreeBox->setEdges(RectangleEdge::None);
+
+ // -------------------------- left box -------------------------------------------
+ containerThreeBox->firstBox = new HBox(containerThreeBox);
+ containerThreeBox->firstBox->setAlignment(Alignment(Alignment::Vertical::Center));
+ containerThreeBox->firstBox->setEdges(RectangleEdge::None);
+ containerThreeBox->firstBox->activeItem = false;
+
+ leftArrowBox = new ImageBox(nullptr, new Image("bell_arrow_left_W_M"));
+ leftArrowBox->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
+ leftArrowBox->setMinimumSizeToFitImage();
+ leftArrowBox->setVisible(leftArrowVisible);
+ leftArrowBox->setEdges(RectangleEdge::None);
+ containerThreeBox->firstBox->setMinimumSize(leftArrowBox->widgetMinimumArea.w,
+ leftArrowBox->widgetMinimumArea.h);
+
+ containerThreeBox->firstBox->addWidget(leftArrowBox);
+
+ // -------------------------- center box -------------------------------------------
+ containerThreeBox->centerBox = new VBox(containerThreeBox);
+ containerThreeBox->centerBox->setEdges(RectangleEdge::None);
+ containerThreeBox->centerBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
+ containerThreeBox->centerBox->setMinimumSize(container::centerBox::width, container::centerBox::height);
+ containerThreeBox->centerBox->setMaximumSize(container::centerBox::width, container::centerBox::height);
+
+ imageBox = new ImageBox(nullptr, new Image(image, ImageTypeSpecifier::W_G));
+ imageBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
+ imageBox->setMinimumSizeToFitImage();
+ imageBox->setMaximumSize(container::imageBox::width, container::imageBox::height);
+ imageBox->setVisible(true);
+
+ titleBox = new Text(nullptr, 0, 0, 0, 0);
+ titleBox->setMinimumSize(container::title::width, container::title::height);
+ titleBox->setMaximumSize(container::title::width, container::title::height);
+ titleBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
+ titleBox->setMargins(Margins(0, 0, 0, container::title::bottom_margin));
+ titleBox->setTextType(TextType::SingleLine);
+ titleBox->setEditMode(EditMode::Browse);
+ titleBox->setFont(container::title::font);
+ titleBox->setRichText(utils::translate(title));
+
+ containerThreeBox->centerBox->addWidget(imageBox);
+ containerThreeBox->centerBox->addWidget(titleBox);
+
+ for (const auto &point : instruction) {
+ auto instructionContainer = new HBox(nullptr);
+ instructionContainer->setEdges(RectangleEdge::None);
+ instructionContainer->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Top));
+ instructionContainer->setMargins(Margins(0, 0, 0, container::instruction::bottom_margin));
+ instructionContainer->setMinimumSize(container::instruction::width, container::instruction::minHeight);
+ instructionContainer->setMaximumSize(container::instruction::width, container::instruction::maxHeight);
+
+ auto numberBox = new Text(nullptr, 0, 0, 0, 0);
+ numberBox->setMinimumSize(container::instruction::number::width, container::instruction::minHeight);
+ numberBox->setAlignment(Alignment::Horizontal::Left);
+ numberBox->setTextType(TextType::MultiLine);
+ numberBox->setEditMode(EditMode::Browse);
+ numberBox->setFont(container::instruction::number::font);
+ numberBox->setRichText(point.first);
+
+ auto textBox = new Text(nullptr, 0, 0, 0, 0);
+ textBox->setMinimumSize(container::instruction::text::width, container::instruction::minHeight);
+ textBox->setMaximumSize(container::instruction::text::width, container::instruction::maxHeight);
+ textBox->setAlignment(Alignment::Horizontal::Left);
+ textBox->setTextType(TextType::MultiLine);
+ textBox->setEditMode(EditMode::Browse);
+ textBox->setFont(container::instruction::text::font);
+ textBox->setRichText(utils::translate(point.second));
+
+ InstructionPoint instructionPoint{.container = std::move(instructionContainer),
+ .textBox = std::move(textBox),
+ .numberBox = std::move(numberBox)};
+ instructionPoints.push_back(std::move(instructionPoint));
+ }
+
+ for (const auto &point : instructionPoints) {
+ point.container->addWidget(point.numberBox);
+ point.container->addWidget(point.textBox);
+ containerThreeBox->centerBox->addWidget(point.container);
+ }
+
+ // -------------------------- right box -------------------------------------------
+ containerThreeBox->lastBox = new HBox(containerThreeBox);
+ containerThreeBox->lastBox->setAlignment(Alignment(Alignment::Vertical::Center));
+ containerThreeBox->lastBox->setEdges(RectangleEdge::None);
+ containerThreeBox->lastBox->activeItem = false;
+
+ rightArrowBox = new ImageBox(nullptr, new Image("bell_arrow_right_W_M"));
+ rightArrowBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
+ rightArrowBox->setMinimumSizeToFitImage();
+ rightArrowBox->setVisible(rightArrowVisible);
+ rightArrowBox->setEdges(RectangleEdge::None);
+ containerThreeBox->lastBox->setMinimumSize(rightArrowBox->widgetMinimumArea.w,
+ rightArrowBox->widgetMinimumArea.h);
+
+ containerThreeBox->lastBox->addWidget(rightArrowBox);
+
+ this->resizeItems();
+ }
+
+ auto UpdateInstructionLayoutClassic::getLayout() -> Item *
+ {
+ return this;
+ }
+}; // namespace gui
A products/BellHybrid/apps/common/src/layouts/UpdateInstructionLayouts.cpp => products/BellHybrid/apps/common/src/layouts/UpdateInstructionLayouts.cpp +24 -0
@@ 0,0 1,24 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "layouts/UpdateInstructionLayouts.hpp"
+#include "layouts/UpdateInstructionLayoutClassic.hpp"
+
+namespace gui::factory
+{
+ std::vector<LayoutGenerator> getUpdateInstructionLayouts()
+ {
+ return {{[]() {
+ const Instruction instructions{{"1.", "app_bell_update_instruction_1st_point"},
+ {"2.", "app_bell_update_instruction_2nd_point"}};
+ return new UpdateInstructionLayoutClassic(
+ "bell_mudita_logo", "app_bell_update_instruction_title", instructions, false, true);
+ }},
+ {[]() {
+ const Instruction instructions{{"3.", "app_bell_update_instruction_3rd_point"},
+ {"4.", "app_bell_update_instruction_4th_point"}};
+ return new UpdateInstructionLayoutClassic(
+ "bell_mudita_logo", "app_bell_update_instruction_title", instructions, true, false);
+ }}};
+ }
+} // namespace gui::factory
A products/BellHybrid/apps/common/src/windows/UpdateInstructionWindow.cpp => products/BellHybrid/apps/common/src/windows/UpdateInstructionWindow.cpp +64 -0
@@ 0,0 1,64 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "windows/UpdateInstructionWindow.hpp"
+
+#include <Style.hpp>
+#include <SideListView.hpp>
+#include <gui/input/InputEvent.hpp>
+
+namespace gui
+{
+ UpdateInstructionWindow::UpdateInstructionWindow(
+ app::ApplicationCommon *app,
+ std::unique_ptr<UpdateInstructionWindowContract::Presenter> &&presenter,
+ const std::string &name)
+ : AppWindow(app, name), presenter{std::move(presenter)}
+ {
+ this->presenter->attach(this);
+ buildInterface();
+ }
+
+ void UpdateInstructionWindow::buildInterface()
+ {
+ AppWindow::buildInterface();
+
+ statusBar->setVisible(false);
+ header->setTitleVisibility(false);
+ navBar->setVisible(false);
+
+ auto layouts = presenter->getLayouts();
+ spinner = new WidgetSpinner(this, {layouts.begin(), layouts.end()}, Boundaries::Fixed);
+ spinner->setSize(style::window_width, style::window_height);
+ spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ spinner->setFocusEdges(RectangleEdge::None);
+ auto selectedLayout = presenter->getFirstLayout();
+ spinner->setCurrentValue(selectedLayout);
+
+ spinner->onValueChanged = [this](const auto &) {
+ getApplication()->render(gui::RefreshModes::GUI_REFRESH_DEEP);
+ };
+
+ setFocusItem(spinner);
+ }
+
+ bool UpdateInstructionWindow::isLastLayout() const
+ {
+ auto currentLayout = spinner->getCurrentValue();
+ return presenter->isLastLayout(currentLayout);
+ }
+
+ bool UpdateInstructionWindow::onInput(const gui::InputEvent &inputEvent)
+ {
+ if (spinner->onInput(inputEvent)) {
+ return true;
+ }
+
+ if (presenter->onInput(inputEvent, spinner->getCurrentValue())) {
+ return true;
+ }
+
+ return AppWindow::onInput(inputEvent);
+ }
+
+} // namespace gui