summaryrefslogtreecommitdiff
path: root/src/displayapp/screens
diff options
context:
space:
mode:
authorITCactus <n/a>2022-05-09 17:45:53 +0200
committerITCactus <n/a>2022-06-30 15:14:23 +0200
commit319dfd23e7dd1ecfedea113e49dfe30b5a814c67 (patch)
treec216ae7c9204cf3e1ce7a1d83171f788df42efa7 /src/displayapp/screens
parentc0770cde8a1416e8dad3064bf0de8168ec0915db (diff)
[new watchface] watchface inspired by G7710, with day of year and week number info
Diffstat (limited to 'src/displayapp/screens')
-rw-r--r--src/displayapp/screens/CheckboxList.cpp115
-rw-r--r--src/displayapp/screens/CheckboxList.h49
-rw-r--r--src/displayapp/screens/Clock.cpp15
-rw-r--r--src/displayapp/screens/Clock.h1
-rw-r--r--src/displayapp/screens/WatchFaceCasioStyleG7710.cpp297
-rw-r--r--src/displayapp/screens/WatchFaceCasioStyleG7710.h91
-rw-r--r--src/displayapp/screens/settings/SettingWatchFace.h13
7 files changed, 577 insertions, 4 deletions
diff --git a/src/displayapp/screens/CheckboxList.cpp b/src/displayapp/screens/CheckboxList.cpp
new file mode 100644
index 00000000..7667946a
--- /dev/null
+++ b/src/displayapp/screens/CheckboxList.cpp
@@ -0,0 +1,115 @@
+#include "displayapp/screens/CheckboxList.h"
+#include "displayapp/DisplayApp.h"
+#include "displayapp/screens/Styles.h"
+#include "displayapp/screens/Symbols.h"
+
+using namespace Pinetime::Applications::Screens;
+
+namespace {
+ static void event_handler(lv_obj_t* obj, lv_event_t event) {
+ CheckboxList* screen = static_cast<CheckboxList*>(obj->user_data);
+ screen->UpdateSelected(obj, event);
+ }
+
+}
+
+CheckboxList::CheckboxList(const uint8_t screenID,
+ const uint8_t numScreens,
+ DisplayApp* app,
+ Controllers::Settings& settingsController,
+ const char* optionsTitle,
+ const char* optionsSymbol,
+ void (Controllers::Settings::*SetOptionIndex)(uint8_t),
+ uint8_t (Controllers::Settings::*GetOptionIndex )() const,
+ std::array<const char*, MAXLISTITEMS> options)
+ : Screen(app), screenID {screenID}, settingsController {settingsController},
+ SetOptionIndex {SetOptionIndex}, GetOptionIndex {GetOptionIndex},
+ options {options} {
+
+ settingsController.SetWatchfacesMenu(screenID);
+
+ // Set the background to Black
+ lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+
+ if (numScreens > 1) {
+ 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(), NULL);
+ 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, lv_color_hex(0x111111));
+ lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2);
+
+ const uint16_t indicatorSize = LV_VER_RES / numScreens;
+ const uint16_t indicatorPos = indicatorSize * screenID;
+
+ 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(), NULL);
+ 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, LV_COLOR_GRAY);
+ lv_line_set_points(pageIndicator, pageIndicatorPoints, 2);
+ }
+
+ lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
+
+ lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
+ lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
+ lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
+ lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
+
+ lv_obj_set_pos(container1, 10, 60);
+ lv_obj_set_width(container1, LV_HOR_RES - 20);
+ lv_obj_set_height(container1, LV_VER_RES - 50);
+ lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
+
+ lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
+ lv_label_set_text_static(title, optionsTitle);
+ lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
+ lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15);
+
+ lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
+ lv_label_set_text_static(icon, optionsSymbol);
+ lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
+ lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);
+
+ for (unsigned int i = 0; i < options.size(); i++) {
+ if (strcmp(options[i], "")) {
+ cbOption[i] = lv_checkbox_create(container1, nullptr);
+ lv_checkbox_set_text(cbOption[i], options[i]);
+ cbOption[i]->user_data = this;
+ lv_obj_set_event_cb(cbOption[i], event_handler);
+ SetRadioButtonStyle(cbOption[i]);
+
+ if (static_cast<unsigned int>((settingsController.*GetOptionIndex)() - MAXLISTITEMS*screenID) == i) {
+ lv_checkbox_set_checked(cbOption[i], true);
+ }
+ }
+ }
+}
+
+CheckboxList::~CheckboxList() {
+ lv_obj_clean(lv_scr_act());
+ settingsController.SaveSettings();
+}
+
+void CheckboxList::UpdateSelected(lv_obj_t* object, lv_event_t event) {
+ if (event == LV_EVENT_VALUE_CHANGED) {
+ for (unsigned int i = 0; i < options.size(); i++) {
+ if (strcmp(options[i], "")) {
+ if (object == cbOption[i]) {
+ lv_checkbox_set_checked(cbOption[i], true);
+ (settingsController.*SetOptionIndex)(MAXLISTITEMS*screenID + i);
+ } else {
+ lv_checkbox_set_checked(cbOption[i], false);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/displayapp/screens/CheckboxList.h b/src/displayapp/screens/CheckboxList.h
new file mode 100644
index 00000000..e90dcd30
--- /dev/null
+++ b/src/displayapp/screens/CheckboxList.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <lvgl/lvgl.h>
+#include <cstdint>
+#include <memory>
+#include "displayapp/screens/Screen.h"
+#include "displayapp/Apps.h"
+#include "components/settings/Settings.h"
+
+#define MAXLISTITEMS 4
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+ class CheckboxList : public Screen {
+ public:
+ CheckboxList(const uint8_t screenID,
+ const uint8_t numScreens,
+ DisplayApp* app,
+ Controllers::Settings& settingsController,
+ const char* optionsTitle,
+ const char* optionsSymbol,
+ void (Controllers::Settings::*SetOptionIndex)(uint8_t),
+ uint8_t (Controllers::Settings::*GetOptionIndex)() const,
+ std::array<const char*, MAXLISTITEMS> options);
+
+ ~CheckboxList() override;
+
+ void UpdateSelected(lv_obj_t* object, lv_event_t event);
+
+ private:
+ const uint8_t screenID;
+ Controllers::Settings& settingsController;
+ const char* optionsTitle;
+ const char* optionsSymbol;
+ void (Controllers::Settings::*SetOptionIndex)(uint8_t);
+ uint8_t (Controllers::Settings::*GetOptionIndex)() const;
+ std::array<const char*, MAXLISTITEMS> options;
+
+ lv_obj_t* cbOption[MAXLISTITEMS];
+
+ lv_point_t pageIndicatorBasePoints[2];
+ lv_point_t pageIndicatorPoints[2];
+ lv_obj_t* pageIndicatorBase;
+ lv_obj_t* pageIndicator;
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp
index 1687dccf..4e76af18 100644
--- a/src/displayapp/screens/Clock.cpp
+++ b/src/displayapp/screens/Clock.cpp
@@ -12,6 +12,7 @@
#include "displayapp/screens/WatchFaceTerminal.h"
#include "displayapp/screens/WatchFaceAnalog.h"
#include "displayapp/screens/WatchFacePineTimeStyle.h"
+#include "displayapp/screens/WatchFaceCasioStyleG7710.h"
using namespace Pinetime::Applications::Screens;
@@ -45,6 +46,9 @@ Clock::Clock(DisplayApp* app,
case 3:
return WatchFaceTerminalScreen();
break;
+ case 4:
+ return WatchFaceCasioStyleG7710();
+ break;
}
return WatchFaceDigitalScreen();
}()} {
@@ -103,3 +107,14 @@ std::unique_ptr<Screen> Clock::WatchFaceTerminalScreen() {
heartRateController,
motionController);
}
+
+std::unique_ptr<Screen> Clock::WatchFaceCasioStyleG7710() {
+ return std::make_unique<Screens::WatchFaceCasioStyleG7710>(app,
+ dateTimeController,
+ batteryController,
+ bleController,
+ notificatioManager,
+ settingsController,
+ heartRateController,
+ motionController);
+}
diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h
index 1ba752c7..5446a11b 100644
--- a/src/displayapp/screens/Clock.h
+++ b/src/displayapp/screens/Clock.h
@@ -48,6 +48,7 @@ namespace Pinetime {
std::unique_ptr<Screen> WatchFaceAnalogScreen();
std::unique_ptr<Screen> WatchFacePineTimeStyleScreen();
std::unique_ptr<Screen> WatchFaceTerminalScreen();
+ std::unique_ptr<Screen> WatchFaceCasioStyleG7710();
};
}
}
diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp
new file mode 100644
index 00000000..8f730d52
--- /dev/null
+++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp
@@ -0,0 +1,297 @@
+#include "displayapp/screens/WatchFaceCasioStyleG7710.h"
+
+#include <date/date.h>
+#include <lvgl/lvgl.h>
+#include <cstdio>
+#include "displayapp/screens/BatteryIcon.h"
+#include "displayapp/screens/BleIcon.h"
+#include "displayapp/screens/NotificationIcon.h"
+#include "displayapp/screens/Symbols.h"
+#include "components/battery/BatteryController.h"
+#include "components/ble/BleController.h"
+#include "components/ble/NotificationManager.h"
+#include "components/heartrate/HeartRateController.h"
+#include "components/motion/MotionController.h"
+#include "components/settings/Settings.h"
+using namespace Pinetime::Applications::Screens;
+
+
+WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(DisplayApp* app,
+ Controllers::DateTime& dateTimeController,
+ Controllers::Battery& batteryController,
+ Controllers::Ble& bleController,
+ Controllers::NotificationManager& notificatioManager,
+ Controllers::Settings& settingsController,
+ Controllers::HeartRateController& heartRateController,
+ Controllers::MotionController& motionController)
+ : Screen(app),
+ currentDateTime {{}},
+ dateTimeController {dateTimeController},
+ batteryController {batteryController},
+ bleController {bleController},
+ notificatioManager {notificatioManager},
+ settingsController {settingsController},
+ heartRateController {heartRateController},
+ motionController {motionController} {
+
+ batteryIcon = lv_label_create(lv_scr_act(), nullptr);
+ lv_label_set_text_static(batteryIcon, Symbols::batteryFull);
+ lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 0);
+
+ batteryPlug = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_static(batteryPlug, Symbols::plug);
+ lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0);
+
+ bleIcon = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_static(bleIcon, Symbols::bluetooth);
+ lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0);
+
+ notificationIcon = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false));
+ lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 5, 0);
+
+
+ label_day_of_week = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_align(label_day_of_week, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 10, 64);
+ lv_obj_set_style_local_text_color(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_obj_set_style_local_text_font(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_dots_40);
+ lv_label_set_text_static(label_day_of_week, "SUN");
+
+ label_week_number = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_align(label_week_number, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 5, 34);
+ lv_obj_set_style_local_text_color(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_obj_set_style_local_text_font(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_dots_40);
+ lv_label_set_text_static(label_week_number, "WK26");
+
+ label_day_of_year = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_align(label_day_of_year, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 25);
+ lv_obj_set_style_local_text_color(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_obj_set_style_local_text_font(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_7segment_40);
+ lv_label_set_text_static(label_day_of_year, "181-184");
+
+ static lv_style_t style_line;
+ lv_style_init(&style_line);
+ lv_style_set_line_width(&style_line, LV_STATE_DEFAULT, 2);
+ lv_style_set_line_color(&style_line, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_style_set_line_rounded(&style_line, LV_STATE_DEFAULT, true);
+
+ static lv_style_t style_border;
+ lv_style_init(&style_border);
+ lv_style_set_line_width(&style_border, LV_STATE_DEFAULT, 6);
+ lv_style_set_line_color(&style_border, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_style_set_line_rounded(&style_border, LV_STATE_DEFAULT, true);
+
+ line_day_of_week_number = lv_line_create(lv_scr_act(), nullptr);
+ static lv_point_t line_day_of_week_number_points[] = {{0, 0}, {100, 0}, {94, 70}, {0, 70}};
+ lv_line_set_points(line_day_of_week_number, line_day_of_week_number_points, 4);
+ lv_obj_add_style(line_day_of_week_number, LV_LINE_PART_MAIN, &style_border);
+ lv_obj_align(line_day_of_week_number, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 28);
+
+ line_day_of_year = lv_line_create(lv_scr_act(), nullptr);
+ static lv_point_t line_day_of_year_points[] = {{0, 5}, {130, 5}, {135, 0}};
+ lv_line_set_points(line_day_of_year, line_day_of_year_points, 3);
+ lv_obj_add_style(line_day_of_year, LV_LINE_PART_MAIN, &style_line);
+ lv_obj_align(line_day_of_year, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 55);
+
+ label_date = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 65);
+ lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_7segment_40);
+ lv_label_set_text_static(label_date, "6-30");
+
+ line_date = lv_line_create(lv_scr_act(), nullptr);
+ static lv_point_t line_date_points[] = {{0, 5}, {135, 5}, {140, 0}};
+ lv_line_set_points(line_date, line_date_points, 3);
+ lv_obj_add_style(line_date, LV_LINE_PART_MAIN, &style_line);
+ lv_obj_align(line_date, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 95);
+
+ label_time = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_7segment_115);
+ lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 0);
+
+ line_time = lv_line_create(lv_scr_act(), nullptr);
+ static lv_point_t line_time_points[] = {{0, 0}, {230, 0}, {235, 5}};
+ lv_line_set_points(line_time, line_time_points, 3);
+ lv_obj_add_style(line_time, LV_LINE_PART_MAIN, &style_line);
+ lv_obj_align(line_time, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, -35);
+
+ label_time_ampm = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(label_time_ampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_static(label_time_ampm, "");
+ lv_obj_align(label_time_ampm, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 5, -5);
+
+ backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_click(backgroundLabel, true);
+ lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
+ lv_obj_set_size(backgroundLabel, 240, 240);
+ lv_obj_set_pos(backgroundLabel, 0, 0);
+ lv_label_set_text_static(backgroundLabel, "");
+
+ heartbeatIcon = lv_label_create(lv_scr_act(), nullptr);
+ lv_label_set_text_static(heartbeatIcon, Symbols::heartBeat);
+ lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2);
+
+ heartbeatValue = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_static(heartbeatValue, "");
+ lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0);
+
+ stepValue = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_static(stepValue, "0");
+ lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2);
+
+ stepIcon = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(stepIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_static(stepIcon, Symbols::shoe);
+ lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0);
+
+ taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
+ Refresh();
+}
+
+WatchFaceCasioStyleG7710::~WatchFaceCasioStyleG7710() {
+ lv_task_del(taskRefresh);
+ lv_obj_clean(lv_scr_act());
+}
+
+void WatchFaceCasioStyleG7710::Refresh() {
+ powerPresent = batteryController.IsPowerPresent();
+ if (powerPresent.IsUpdated()) {
+ lv_label_set_text_static(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get()));
+ }
+
+ batteryPercentRemaining = batteryController.PercentRemaining();
+ if (batteryPercentRemaining.IsUpdated()) {
+ auto batteryPercent = batteryPercentRemaining.Get();
+ lv_label_set_text_static(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
+ }
+
+ bleState = bleController.IsConnected();
+ bleRadioEnabled = bleController.IsRadioEnabled();
+ if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
+ lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get()));
+ }
+ lv_obj_realign(batteryPlug);
+ lv_obj_realign(bleIcon);
+
+ notificationState = notificatioManager.AreNewNotificationsAvailable();
+ if (notificationState.IsUpdated()) {
+ lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(notificationState.Get()));
+ }
+
+ currentDateTime = dateTimeController.CurrentDateTime();
+
+ if (currentDateTime.IsUpdated()) {
+ auto newDateTime = currentDateTime.Get();
+
+ auto dp = date::floor<date::days>(newDateTime);
+ auto time = date::make_time(newDateTime - dp);
+ auto yearMonthDay = date::year_month_day(dp);
+
+ auto year = static_cast<int>(yearMonthDay.year());
+ auto month = static_cast<Pinetime::Controllers::DateTime::Months>(static_cast<unsigned>(yearMonthDay.month()));
+ auto day = static_cast<unsigned>(yearMonthDay.day());
+ auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding());
+
+ uint8_t hour = time.hours().count();
+ uint8_t minute = time.minutes().count();
+ auto weekNumberFormat = "%V";
+
+ if (displayedHour != hour || displayedMinute != minute) {
+ displayedHour = hour;
+ displayedMinute = minute;
+
+ if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
+ char ampmChar[2] = "A";
+ if (hour == 0) {
+ hour = 12;
+ } else if (hour == 12) {
+ ampmChar[0] = 'P';
+ } else if (hour > 12) {
+ hour = hour - 12;
+ ampmChar[0] = 'P';
+ }
+ lv_label_set_text(label_time_ampm, ampmChar);
+ lv_label_set_text_fmt(label_time, "%2d:%02d", hour, minute);
+ lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 30);
+ } else {
+ lv_label_set_text_fmt(label_time, "%02d:%02d", hour, minute);
+ lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 30);
+ }
+ }
+
+ if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
+ if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) {
+ // 24h mode: ddmmyyyy, first DOW=Monday;
+ lv_label_set_text_fmt(
+ label_date, "%3d-%2d", day, month);
+ weekNumberFormat = "%V"; // Replaced by the week number of the year (Monday as the first day of the week) as a decimal number [01,53]. If the week containing 1 January has four or more days in the new year, then it is considered week 1. Otherwise, it is the last week of the previous year, and the next week is week 1. Both January 4th and the first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
+ } else {
+ // 12h mode: mmddyyyy, first DOW=Sunday;
+ lv_label_set_text_fmt(
+ label_date, "%3d-%2d", month, day);
+ weekNumberFormat = "%U"; // Replaced by the week number of the year as a decimal number [00,53]. The first Sunday of January is the first day of week 1; days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
+ }
+
+ uint8_t weekNumber;
+ uint16_t dayOfYearNumber, daysTillEndOfYearNumber;
+
+ std::tm date = {};
+ date.tm_year = year - 1900;
+ date.tm_mon = static_cast<unsigned>(yearMonthDay.month()) - 1;
+ date.tm_mday = day + 1;
+ std::mktime( &date );
+
+ dayOfYearNumber = date.tm_yday;
+ daysTillEndOfYearNumber = yearMonthDay.year().is_leap() ? 366 : 365 - dayOfYearNumber;
+
+ char buffer[8];
+ strftime(buffer, 8, weekNumberFormat, &date);
+ weekNumber = atoi(buffer);
+
+ lv_label_set_text_fmt(label_day_of_week, "%s", dateTimeController.DayOfWeekShortToString());
+ lv_label_set_text_fmt(label_day_of_year, "%3d-%3d", dayOfYearNumber, daysTillEndOfYearNumber);
+ lv_label_set_text_fmt(label_week_number, "WK%02d", weekNumber);
+
+ lv_obj_realign(label_day_of_week);
+ lv_obj_realign(label_day_of_year);
+ lv_obj_realign(label_week_number);
+ lv_obj_realign(label_date);
+
+ currentYear = year;
+ currentMonth = month;
+ currentDayOfWeek = dayOfWeek;
+ currentDay = day;
+ }
+ }
+
+ heartbeat = heartRateController.HeartRate();
+ heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
+ if (heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) {
+ if (heartbeatRunning.Get()) {
+ lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x98B69A));
+ lv_label_set_text_fmt(heartbeatValue, "%d", heartbeat.Get());
+ } else {
+ lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x1B1B1B));
+ lv_label_set_text_static(heartbeatValue, "");
+ }
+
+ lv_obj_realign(heartbeatIcon);
+ lv_obj_realign(heartbeatValue);
+ }
+
+ stepCount = motionController.NbSteps();
+ motionSensorOk = motionController.IsSensorOk();
+ if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) {
+ lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get());
+ lv_obj_realign(stepValue);
+ lv_obj_realign(stepIcon);
+ }
+}
diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.h b/src/displayapp/screens/WatchFaceCasioStyleG7710.h
new file mode 100644
index 00000000..0cf7bbbf
--- /dev/null
+++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.h
@@ -0,0 +1,91 @@
+#pragma once
+
+#include <displayapp/screens/BatteryIcon.h>
+#include <lvgl/src/lv_core/lv_obj.h>
+#include <chrono>
+#include <cstdint>
+#include <memory>
+#include "displayapp/screens/Screen.h"
+#include "components/datetime/DateTimeController.h"
+#include "components/ble/BleController.h"
+
+namespace Pinetime {
+ namespace Controllers {
+ class Settings;
+ class Battery;
+ class Ble;
+ class NotificationManager;
+ class HeartRateController;
+ class MotionController;
+ }
+
+ namespace Applications {
+ namespace Screens {
+
+ class WatchFaceCasioStyleG7710 : public Screen {
+ public:
+ WatchFaceCasioStyleG7710(DisplayApp* app,
+ Controllers::DateTime& dateTimeController,
+ Controllers::Battery& batteryController,
+ Controllers::Ble& bleController,
+ Controllers::NotificationManager& notificatioManager,
+ Controllers::Settings& settingsController,
+ Controllers::HeartRateController& heartRateController,
+ Controllers::MotionController& motionController);
+ ~WatchFaceCasioStyleG7710() override;
+
+ void Refresh() override;
+
+ private:
+ uint8_t displayedHour = -1;
+ uint8_t displayedMinute = -1;
+
+ uint16_t currentYear = 1970;
+ Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
+ Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown;
+ uint8_t currentDay = 0;
+
+ DirtyValue<uint8_t> batteryPercentRemaining {};
+ DirtyValue<bool> powerPresent {};
+ DirtyValue<bool> bleState {};
+ DirtyValue<bool> bleRadioEnabled {};
+ DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
+ DirtyValue<bool> motionSensorOk {};
+ DirtyValue<uint32_t> stepCount {};
+ DirtyValue<uint8_t> heartbeat {};
+ DirtyValue<bool> heartbeatRunning {};
+ DirtyValue<bool> notificationState {};
+
+ lv_obj_t* label_time;
+ lv_obj_t* line_time;
+ lv_obj_t* label_time_ampm;
+ lv_obj_t* label_date;
+ lv_obj_t* line_date;
+ lv_obj_t* label_day_of_week;
+ lv_obj_t* label_week_number;
+ lv_obj_t* line_day_of_week_number;
+ lv_obj_t* label_day_of_year;
+ lv_obj_t* line_day_of_year;
+ lv_obj_t* backgroundLabel;
+ lv_obj_t* bleIcon;
+ lv_obj_t* batteryPlug;
+ lv_obj_t* heartbeatIcon;
+ lv_obj_t* heartbeatValue;
+ lv_obj_t* stepIcon;
+ lv_obj_t* stepValue;
+ lv_obj_t* notificationIcon;
+ lv_obj_t* batteryIcon;
+
+ Controllers::DateTime& dateTimeController;
+ Controllers::Battery& batteryController;
+ Controllers::Ble& bleController;
+ Controllers::NotificationManager& notificatioManager;
+ Controllers::Settings& settingsController;
+ Controllers::HeartRateController& heartRateController;
+ Controllers::MotionController& motionController;
+
+ lv_task_t* taskRefresh;
+ };
+ }
+ }
+}
diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h
index 62427b4f..801dcd73 100644
--- a/src/displayapp/screens/settings/SettingWatchFace.h
+++ b/src/displayapp/screens/settings/SettingWatchFace.h
@@ -4,8 +4,10 @@
#include <cstdint>
#include <lvgl/lvgl.h>
+#include "displayapp/screens/ScreenList.h"
#include "components/settings/Settings.h"
#include "displayapp/screens/Screen.h"
+#include "displayapp/screens/Symbols.h"
namespace Pinetime {
@@ -17,14 +19,17 @@ namespace Pinetime {
SettingWatchFace(DisplayApp* app, Pinetime::Controllers::Settings& settingsController);
~SettingWatchFace() override;
- void UpdateSelected(lv_obj_t* object, lv_event_t event);
+ bool OnTouchEvent(TouchEvents event) override;
private:
- static constexpr std::array<const char*, 4> options = {" Digital face", " Analog face", " PineTimeStyle", " Terminal"};
Controllers::Settings& settingsController;
+ ScreenList<2> screens;
- lv_obj_t* cbOption[options.size()];
+ static constexpr const char* title = "Watch face";
+ static constexpr const char* symbol = Symbols::home;
+ std::unique_ptr<Screen> CreateScreen1();
+ std::unique_ptr<Screen> CreateScreen2();
};
}
}
-}
+} \ No newline at end of file