diff options
author | Jean-François Milants <jf@codingfield.com> | 2022-09-11 14:59:49 +0200 |
---|---|---|
committer | Jean-François Milants <jf@codingfield.com> | 2022-09-11 14:59:49 +0200 |
commit | ada2c09581d2d13acfa5ce9a97671c0ec17863f1 (patch) | |
tree | 2f776adc59d0c63e403d2043cb8460e65d6c46fe /src/displayapp/widgets | |
parent | 18cff286c75f432095db4b188e0f9a8a9e2bd8e8 (diff) | |
parent | c9a5c3fa5c930a5939d3114a6c6b48570d61ca24 (diff) |
Merge branch 'develop' into infineat-external-resources
# Conflicts:
# src/displayapp/screens/Symbols.h
# src/displayapp/screens/settings/SettingWatchFace.cpp
# src/displayapp/screens/settings/SettingWatchFace.h
Diffstat (limited to 'src/displayapp/widgets')
-rw-r--r-- | src/displayapp/widgets/Counter.cpp | 87 | ||||
-rw-r--r-- | src/displayapp/widgets/Counter.h | 19 | ||||
-rw-r--r-- | src/displayapp/widgets/PageIndicator.cpp | 32 | ||||
-rw-r--r-- | src/displayapp/widgets/PageIndicator.h | 23 | ||||
-rw-r--r-- | src/displayapp/widgets/StatusIcons.cpp | 49 | ||||
-rw-r--r-- | src/displayapp/widgets/StatusIcons.h | 39 |
6 files changed, 231 insertions, 18 deletions
diff --git a/src/displayapp/widgets/Counter.cpp b/src/displayapp/widgets/Counter.cpp index ecf39613..e95178ec 100644 --- a/src/displayapp/widgets/Counter.cpp +++ b/src/displayapp/widgets/Counter.cpp @@ -1,4 +1,6 @@ #include "displayapp/widgets/Counter.h" +#include "components/datetime/DateTimeController.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Widgets; @@ -6,35 +8,51 @@ namespace { void upBtnEventHandler(lv_obj_t* obj, lv_event_t event) { auto* widget = static_cast<Counter*>(obj->user_data); if (event == LV_EVENT_SHORT_CLICKED || event == LV_EVENT_LONG_PRESSED_REPEAT) { - widget->Increment(); + widget->UpBtnPressed(); } } void downBtnEventHandler(lv_obj_t* obj, lv_event_t event) { auto* widget = static_cast<Counter*>(obj->user_data); if (event == LV_EVENT_SHORT_CLICKED || event == LV_EVENT_LONG_PRESSED_REPEAT) { - widget->Decrement(); + widget->DownBtnPressed(); } } + constexpr int digitCount(int number) { + int digitCount = 0; + while (number > 0) { + digitCount++; + number /= 10; + } + return digitCount; + } } -Counter::Counter(int min, int max) : min {min}, max {max} { +Counter::Counter(int min, int max, lv_font_t& font) : min {min}, max {max}, value {min}, font {font}, leadingZeroCount {digitCount(max)} { } -void Counter::Increment() { +void Counter::UpBtnPressed() { value++; if (value > max) { value = min; } UpdateLabel(); + + if (ValueChangedHandler != nullptr) { + ValueChangedHandler(userData); + } }; -void Counter::Decrement() { +void Counter::DownBtnPressed() { value--; if (value < min) { value = max; } UpdateLabel(); + + if (ValueChangedHandler != nullptr) { + ValueChangedHandler(userData); + } }; void Counter::SetValue(int newValue) { @@ -58,23 +76,64 @@ void Counter::ShowControls() { } void Counter::UpdateLabel() { - lv_label_set_text_fmt(number, "%.2i", value); + if (twelveHourMode) { + if (value == 0) { + lv_label_set_text_static(number, "12"); + } else if (value <= 12) { + lv_label_set_text_fmt(number, "%.*i", leadingZeroCount, value); + } else { + lv_label_set_text_fmt(number, "%.*i", leadingZeroCount, value - 12); + } + } else if (monthMode) { + lv_label_set_text(number, Controllers::DateTime::MonthShortToStringLow(static_cast<Controllers::DateTime::Months>(value))); + } else { + lv_label_set_text_fmt(number, "%.*i", leadingZeroCount, value); + } } -void Counter::Create() { - constexpr lv_color_t bgColor = LV_COLOR_MAKE(0x38, 0x38, 0x38); +// Value is kept between 0 and 23, but the displayed value is converted to 12-hour. +// Make sure to set the max and min values to 0 and 23. Otherwise behaviour is undefined +void Counter::EnableTwelveHourMode() { + twelveHourMode = true; +} +// Value is kept between 1 and 12, but the displayed value is the corresponding month +// Make sure to set the max and min values to 1 and 12. Otherwise behaviour is undefined +void Counter::EnableMonthMode() { + monthMode = true; +} + +// Counter cannot be resized after creation, +// so the newMax value must have the same number of digits as the old one +void Counter::SetMax(int newMax) { + max = newMax; + if (value > max) { + value = max; + UpdateLabel(); + } +} + +void Counter::SetValueChangedEventCallback(void* userData, void (*handler)(void* userData)) { + this->userData = userData; + this->ValueChangedHandler = handler; +} + +void Counter::Create() { counterContainer = lv_obj_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_bg_color(counterContainer, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor); + lv_obj_set_style_local_bg_color(counterContainer, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); number = lv_label_create(counterContainer, nullptr); - lv_obj_set_style_local_text_font(number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); + lv_obj_set_style_local_text_font(number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &font); lv_obj_align(number, nullptr, LV_ALIGN_CENTER, 0, 0); lv_obj_set_auto_realign(number, true); - lv_label_set_text_static(number, "00"); + if (monthMode) { + lv_label_set_text_static(number, "Jan"); + } else { + lv_label_set_text_fmt(number, "%d", max); + } static constexpr uint8_t padding = 5; - const uint8_t width = lv_obj_get_width(number) + padding * 2; + const uint8_t width = std::max(lv_obj_get_width(number) + padding * 2, 58); static constexpr uint8_t btnHeight = 50; const uint8_t containerHeight = btnHeight * 2 + lv_obj_get_height(number) + padding * 2; @@ -83,7 +142,7 @@ void Counter::Create() { UpdateLabel(); upBtn = lv_btn_create(counterContainer, nullptr); - lv_obj_set_style_local_bg_color(upBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor); + lv_obj_set_style_local_bg_color(upBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); lv_obj_set_size(upBtn, width, btnHeight); lv_obj_align(upBtn, nullptr, LV_ALIGN_IN_TOP_MID, 0, 0); upBtn->user_data = this; @@ -95,7 +154,7 @@ void Counter::Create() { lv_obj_align(upLabel, nullptr, LV_ALIGN_CENTER, 0, 0); downBtn = lv_btn_create(counterContainer, nullptr); - lv_obj_set_style_local_bg_color(downBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor); + lv_obj_set_style_local_bg_color(downBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); lv_obj_set_size(downBtn, width, btnHeight); lv_obj_align(downBtn, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0); downBtn->user_data = this; diff --git a/src/displayapp/widgets/Counter.h b/src/displayapp/widgets/Counter.h index 3df8b839..825860b8 100644 --- a/src/displayapp/widgets/Counter.h +++ b/src/displayapp/widgets/Counter.h @@ -6,14 +6,18 @@ namespace Pinetime { namespace Widgets { class Counter { public: - Counter(int min, int max); + Counter(int min, int max, lv_font_t& font); void Create(); - void Increment(); - void Decrement(); + void UpBtnPressed(); + void DownBtnPressed(); void SetValue(int newValue); void HideControls(); void ShowControls(); + void EnableTwelveHourMode(); + void EnableMonthMode(); + void SetMax(int newMax); + void SetValueChangedEventCallback(void* userData, void (*handler)(void* userData)); int GetValue() const { return value; @@ -25,6 +29,7 @@ namespace Pinetime { private: void UpdateLabel(); + void (*ValueChangedHandler)(void* userData) = nullptr; lv_obj_t* counterContainer; lv_obj_t* upBtn; @@ -33,9 +38,15 @@ namespace Pinetime { lv_obj_t* upperLine; lv_obj_t* lowerLine; lv_point_t linePoints[2]; - int value = 0; int min; int max; + int value; + const int leadingZeroCount; + bool twelveHourMode = false; + bool monthMode = false; + lv_font_t& font; + + void* userData = nullptr; }; } } diff --git a/src/displayapp/widgets/PageIndicator.cpp b/src/displayapp/widgets/PageIndicator.cpp new file mode 100644 index 00000000..84d03e7e --- /dev/null +++ b/src/displayapp/widgets/PageIndicator.cpp @@ -0,0 +1,32 @@ +#include "displayapp/widgets/PageIndicator.h" +#include "displayapp/InfiniTimeTheme.h" + +using namespace Pinetime::Applications::Widgets; + +PageIndicator::PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens) : nCurrentScreen {nCurrentScreen}, nScreens {nScreens} { +} + +void PageIndicator::Create() { + pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[0].y = 0; + pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[1].y = LV_VER_RES; + + pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, Colors::bgDark); + lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); + + const int16_t indicatorSize = LV_VER_RES / nScreens; + const int16_t indicatorPos = indicatorSize * nCurrentScreen; + + pageIndicatorPoints[0].x = LV_HOR_RES - 1; + pageIndicatorPoints[0].y = indicatorPos; + pageIndicatorPoints[1].x = LV_HOR_RES - 1; + pageIndicatorPoints[1].y = indicatorPos + indicatorSize; + + pageIndicator = lv_line_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray); + lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); +} diff --git a/src/displayapp/widgets/PageIndicator.h b/src/displayapp/widgets/PageIndicator.h new file mode 100644 index 00000000..8484735e --- /dev/null +++ b/src/displayapp/widgets/PageIndicator.h @@ -0,0 +1,23 @@ +#pragma once +#include <lvgl/lvgl.h> + +namespace Pinetime { + namespace Applications { + namespace Widgets { + class PageIndicator { + public: + PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens); + void Create(); + + private: + uint8_t nCurrentScreen; + uint8_t nScreens; + + lv_point_t pageIndicatorBasePoints[2]; + lv_point_t pageIndicatorPoints[2]; + lv_obj_t* pageIndicatorBase; + lv_obj_t* pageIndicator; + }; + } + } +} diff --git a/src/displayapp/widgets/StatusIcons.cpp b/src/displayapp/widgets/StatusIcons.cpp new file mode 100644 index 00000000..607f3745 --- /dev/null +++ b/src/displayapp/widgets/StatusIcons.cpp @@ -0,0 +1,49 @@ +#include "displayapp/widgets/StatusIcons.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Widgets; + +StatusIcons::StatusIcons(Controllers::Battery& batteryController, Controllers::Ble& bleController) + : batteryController {batteryController}, bleController {bleController} { +} + +void StatusIcons::Create() { + container = lv_cont_create(lv_scr_act(), nullptr); + lv_cont_set_layout(container, LV_LAYOUT_ROW_TOP); + lv_cont_set_fit(container, LV_FIT_TIGHT); + lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + + bleIcon = lv_label_create(container, nullptr); + lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x0082FC)); + lv_label_set_text_static(bleIcon, Screens::Symbols::bluetooth); + + batteryPlug = lv_label_create(container, nullptr); + lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); + lv_label_set_text_static(batteryPlug, Screens::Symbols::plug); + + batteryIcon.Create(container); + + lv_obj_align(container, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); +} + +void StatusIcons::Update() { + powerPresent = batteryController.IsPowerPresent(); + if (powerPresent.IsUpdated()) { + lv_obj_set_hidden(batteryPlug, !powerPresent.Get()); + } + + batteryPercentRemaining = batteryController.PercentRemaining(); + if (batteryPercentRemaining.IsUpdated()) { + auto batteryPercent = batteryPercentRemaining.Get(); + batteryIcon.SetBatteryPercentage(batteryPercent); + } + + bleState = bleController.IsConnected(); + bleRadioEnabled = bleController.IsRadioEnabled(); + if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) { + lv_obj_set_hidden(bleIcon, !bleState.Get()); + } + + lv_obj_realign(container); +} diff --git a/src/displayapp/widgets/StatusIcons.h b/src/displayapp/widgets/StatusIcons.h new file mode 100644 index 00000000..f4a30a80 --- /dev/null +++ b/src/displayapp/widgets/StatusIcons.h @@ -0,0 +1,39 @@ +#pragma once + +#include <lvgl/lvgl.h> + +#include "displayapp/screens/Screen.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" +#include "displayapp/screens/BatteryIcon.h" + +namespace Pinetime { + namespace Applications { + namespace Widgets { + class StatusIcons { + public: + StatusIcons(Controllers::Battery& batteryController, Controllers::Ble& bleController); + void Align(); + void Create(); + lv_obj_t* GetObject() { + return container; + } + void Update(); + + private: + Screens::BatteryIcon batteryIcon; + Pinetime::Controllers::Battery& batteryController; + Controllers::Ble& bleController; + + Screens::DirtyValue<uint8_t> batteryPercentRemaining {}; + Screens::DirtyValue<bool> powerPresent {}; + Screens::DirtyValue<bool> bleState {}; + Screens::DirtyValue<bool> bleRadioEnabled {}; + + lv_obj_t* bleIcon; + lv_obj_t* batteryPlug; + lv_obj_t* container; + }; + } + } +} |