summaryrefslogtreecommitdiff
path: root/src/displayapp/widgets
diff options
context:
space:
mode:
authorJean-François Milants <jf@codingfield.com>2022-09-11 14:59:49 +0200
committerJean-François Milants <jf@codingfield.com>2022-09-11 14:59:49 +0200
commitada2c09581d2d13acfa5ce9a97671c0ec17863f1 (patch)
tree2f776adc59d0c63e403d2043cb8460e65d6c46fe /src/displayapp/widgets
parent18cff286c75f432095db4b188e0f9a8a9e2bd8e8 (diff)
parentc9a5c3fa5c930a5939d3114a6c6b48570d61ca24 (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.cpp87
-rw-r--r--src/displayapp/widgets/Counter.h19
-rw-r--r--src/displayapp/widgets/PageIndicator.cpp32
-rw-r--r--src/displayapp/widgets/PageIndicator.h23
-rw-r--r--src/displayapp/widgets/StatusIcons.cpp49
-rw-r--r--src/displayapp/widgets/StatusIcons.h39
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;
+ };
+ }
+ }
+}