From 90bc1f65d79502749aa3068b8acde996feb6529e Mon Sep 17 00:00:00 2001 From: Julian Vos Date: Sat, 3 Aug 2024 17:40:04 +0200 Subject: [PATCH 1/6] feat: add version of casio watchface with weather --- .gitignore | 2 + src/CMakeLists.txt | 1 + src/displayapp/UserApps.h | 1 + src/displayapp/apps/Apps.h.in | 1 + src/displayapp/apps/CMakeLists.txt | 1 + .../WatchFaceCasioStyleG7710Weather.cpp | 369 ++++++++++++++++++ .../screens/WatchFaceCasioStyleG7710Weather.h | 133 +++++++ .../screens/settings/SettingWatchFace.h | 1 + 8 files changed, 509 insertions(+) create mode 100644 src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp create mode 100644 src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h diff --git a/.gitignore b/.gitignore index 81e49ae0..14872a71 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ src/arm-none-eabi # clangd .cache/ + +node_modules/ \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd8ece62..e65f166a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -426,6 +426,7 @@ list(APPEND SOURCE_FILES displayapp/screens/WatchFaceTerminal.cpp displayapp/screens/WatchFacePineTimeStyle.cpp displayapp/screens/WatchFaceCasioStyleG7710.cpp + displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp ## diff --git a/src/displayapp/UserApps.h b/src/displayapp/UserApps.h index 67bbfa7d..79520d4e 100644 --- a/src/displayapp/UserApps.h +++ b/src/displayapp/UserApps.h @@ -11,6 +11,7 @@ #include "displayapp/screens/WatchFaceDigital.h" #include "displayapp/screens/WatchFaceAnalog.h" #include "displayapp/screens/WatchFaceCasioStyleG7710.h" +#include "displayapp/screens/WatchFaceCasioStyleG7710Weather.h" #include "displayapp/screens/WatchFaceInfineat.h" #include "displayapp/screens/WatchFacePineTimeStyle.h" #include "displayapp/screens/WatchFaceTerminal.h" diff --git a/src/displayapp/apps/Apps.h.in b/src/displayapp/apps/Apps.h.in index 2104a267..b0ed80c2 100644 --- a/src/displayapp/apps/Apps.h.in +++ b/src/displayapp/apps/Apps.h.in @@ -52,6 +52,7 @@ namespace Pinetime { Terminal, Infineat, CasioStyleG7710, + CasioStyleG7710Weather }; template diff --git a/src/displayapp/apps/CMakeLists.txt b/src/displayapp/apps/CMakeLists.txt index d7858760..5ccb6c06 100644 --- a/src/displayapp/apps/CMakeLists.txt +++ b/src/displayapp/apps/CMakeLists.txt @@ -27,6 +27,7 @@ else() set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::Terminal") set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::Infineat") set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::CasioStyleG7710") + set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::CasioStyleG7710Weather") set(WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}" CACHE STRING "List of watch faces to build into the firmware") endif() diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp new file mode 100644 index 00000000..8560f378 --- /dev/null +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp @@ -0,0 +1,369 @@ +#include "displayapp/screens/WatchFaceCasioStyleG7710Weather.h" + +#include +#include +#include "displayapp/screens/BatteryIcon.h" +#include "displayapp/screens/BleIcon.h" +#include "displayapp/screens/NotificationIcon.h" +#include "displayapp/screens/Symbols.h" +#include "displayapp/screens/WeatherSymbols.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" +#include "components/ble/SimpleWeatherService.h" +using namespace Pinetime::Applications::Screens; + +WatchFaceCasioStyleG7710Weather::WatchFaceCasioStyleG7710Weather(Controllers::DateTime& dateTimeController, + const Controllers::Battery& batteryController, + const Controllers::Ble& bleController, + Controllers::NotificationManager& notificatioManager, + Controllers::Settings& settingsController, + Controllers::HeartRateController& heartRateController, + Controllers::MotionController& motionController, + Controllers::FS& filesystem, + Controllers::SimpleWeatherService& weatherService) + : currentDateTime {{}}, + batteryIcon(false), + dateTimeController {dateTimeController}, + batteryController {batteryController}, + bleController {bleController}, + notificatioManager {notificatioManager}, + settingsController {settingsController}, + heartRateController {heartRateController}, + motionController {motionController}, + weatherService {weatherService} { + + lfs_file f = {}; + if (filesystem.FileOpen(&f, "/fonts/lv_font_dots_40.bin", LFS_O_RDONLY) >= 0) { + filesystem.FileClose(&f); + font_dot40 = lv_font_load("F:/fonts/lv_font_dots_40.bin"); + } + + if (filesystem.FileOpen(&f, "/fonts/7segments_40.bin", LFS_O_RDONLY) >= 0) { + filesystem.FileClose(&f); + font_segment40 = lv_font_load("F:/fonts/7segments_40.bin"); + } + + if (filesystem.FileOpen(&f, "/fonts/7segments_115.bin", LFS_O_RDONLY) >= 0) { + filesystem.FileClose(&f); + font_segment115 = lv_font_load("F:/fonts/7segments_115.bin"); + } + + label_battery_value = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(label_battery_value, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); + lv_obj_set_style_local_text_color(label_battery_value, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); + lv_label_set_text_static(label_battery_value, "00%"); + + batteryIcon.Create(lv_scr_act()); + batteryIcon.SetColor(color_text); + lv_obj_align(batteryIcon.GetObject(), label_battery_value, LV_ALIGN_OUT_LEFT_MID, -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, color_text); + lv_label_set_text_static(batteryPlug, Symbols::plug); + lv_obj_align(batteryPlug, batteryIcon.GetObject(), 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, color_text); + 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, color_text); + lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false)); + lv_obj_align(notificationIcon, bleIcon, LV_ALIGN_OUT_LEFT_MID, -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, color_text); + lv_obj_set_style_local_text_font(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40); + 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, 22); + lv_obj_set_style_local_text_color(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); + lv_obj_set_style_local_text_font(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40); + lv_label_set_text_static(label_week_number, "WK26"); + + weatherIcon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); + lv_obj_set_style_local_text_font(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &fontawesome_weathericons); + lv_label_set_text_static(weatherIcon, ""); + lv_obj_align(weatherIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 120, 30); + lv_obj_set_auto_realign(weatherIcon, true); + + label_temperature = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); + lv_obj_set_style_local_text_font(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); + lv_label_set_text(label_temperature, ""); + lv_obj_align(label_temperature, nullptr, LV_ALIGN_IN_TOP_RIGHT, -7, 30); + + 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, color_text); + lv_style_set_line_rounded(&style_line, LV_STATE_DEFAULT, true); + + 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, color_text); + lv_style_set_line_rounded(&style_border, LV_STATE_DEFAULT, true); + + line_icons = lv_line_create(lv_scr_act(), nullptr); + lv_line_set_points(line_icons, line_icons_points, 3); + lv_obj_add_style(line_icons, LV_LINE_PART_MAIN, &style_line); + lv_obj_align(line_icons, nullptr, LV_ALIGN_IN_TOP_RIGHT, -10, 18); + + line_day_of_week_number = lv_line_create(lv_scr_act(), nullptr); + 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, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 8); + + line_day_of_year = lv_line_create(lv_scr_act(), nullptr); + 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, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 60); + + label_date = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 70); + lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); + lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); + lv_label_set_text_static(label_date, "6-30"); + + line_date = lv_line_create(lv_scr_act(), nullptr); + 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, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 100); + + 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, color_text); + lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment115); + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 40); + + line_time = lv_line_create(lv_scr_act(), nullptr); + 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, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, -25); + + 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, color_text); + 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, color_text); + 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, color_text); + 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, color_text); + 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, color_text); + 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(); +} + +WatchFaceCasioStyleG7710Weather::~WatchFaceCasioStyleG7710Weather() { + lv_task_del(taskRefresh); + + lv_style_reset(&style_line); + lv_style_reset(&style_border); + + if (font_dot40 != nullptr) { + lv_font_free(font_dot40); + } + + if (font_segment40 != nullptr) { + lv_font_free(font_segment40); + } + + if (font_segment115 != nullptr) { + lv_font_free(font_segment115); + } + + lv_obj_clean(lv_scr_act()); +} + +void WatchFaceCasioStyleG7710Weather::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(); + batteryIcon.SetBatteryPercentage(batteryPercent); + lv_label_set_text_fmt(label_battery_value, "%d%%", 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(label_battery_value); + lv_obj_realign(batteryIcon.GetObject()); + lv_obj_realign(batteryPlug); + lv_obj_realign(bleIcon); + lv_obj_realign(notificationIcon); + + notificationState = notificatioManager.AreNewNotificationsAvailable(); + if (notificationState.IsUpdated()) { + lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); + } + + currentDateTime = std::chrono::time_point_cast(dateTimeController.CurrentDateTime()); + if (currentDateTime.IsUpdated()) { + uint8_t hour = dateTimeController.Hours(); + uint8_t minute = dateTimeController.Minutes(); + + 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); + } else { + lv_label_set_text_fmt(label_time, "%02d:%02d", hour, minute); + } + lv_obj_realign(label_time); + + currentDate = std::chrono::time_point_cast(currentDateTime.Get()); + if (currentDate.IsUpdated()) { + const char* weekNumberFormat = "%V"; + + uint16_t year = dateTimeController.Year(); + Controllers::DateTime::Months month = dateTimeController.Month(); + uint8_t day = dateTimeController.Day(); + int dayOfYear = dateTimeController.DayOfYear(); + 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] + } + + time_t ttTime = + std::chrono::system_clock::to_time_t(std::chrono::time_point_cast(currentDateTime.Get())); + tm* tmTime = std::localtime(&ttTime); + + // TODO: When we start using C++20, use std::chrono::year::is_leap + int daysInCurrentYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? 366 : 365; + uint16_t daysTillEndOfYearNumber = daysInCurrentYear - dayOfYear; + + char buffer[8]; + strftime(buffer, 8, weekNumberFormat, tmTime); + uint8_t weekNumber = atoi(buffer); + + lv_label_set_text_fmt(label_day_of_week, "%s", dateTimeController.DayOfWeekShortToString()); + lv_label_set_text_fmt(label_week_number, "WK%02d", weekNumber); + + lv_obj_realign(label_day_of_week); + lv_obj_realign(label_week_number); + lv_obj_realign(label_date); + } + } + + 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, color_text); + 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(); + if (stepCount.IsUpdated()) { + lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get()); + lv_obj_realign(stepValue); + lv_obj_realign(stepIcon); + } + + currentWeather = weatherService.Current(); + + if (currentWeather.IsUpdated()) { + auto optCurrentWeather = currentWeather.Get(); + + if (optCurrentWeather) { + int16_t temp = optCurrentWeather->temperature; + char tempUnit = 'C'; + + if (settingsController.GetWeatherFormat() == Controllers::Settings::WeatherFormat::Imperial) { + temp = Controllers::SimpleWeatherService::CelsiusToFahrenheit(temp); + tempUnit = 'F'; + } + + temp = temp / 100 + (temp % 100 >= 50 ? 1 : 0); + lv_label_set_text_fmt(label_temperature, "%d %c", temp, tempUnit); + lv_label_set_text(weatherIcon, Symbols::GetSymbol(optCurrentWeather->iconId)); + } else { + lv_label_set_text_static(label_temperature, ""); + lv_label_set_text(weatherIcon, ""); + } + + lv_obj_realign(label_temperature); + lv_obj_realign(weatherIcon); + } +} + +bool WatchFaceCasioStyleG7710Weather::IsAvailable(Pinetime::Controllers::FS& filesystem) { + lfs_file file = {}; + + if (filesystem.FileOpen(&file, "/fonts/lv_font_dots_40.bin", LFS_O_RDONLY) < 0) { + return false; + } + + filesystem.FileClose(&file); + if (filesystem.FileOpen(&file, "/fonts/7segments_40.bin", LFS_O_RDONLY) < 0) { + return false; + } + + filesystem.FileClose(&file); + if (filesystem.FileOpen(&file, "/fonts/7segments_115.bin", LFS_O_RDONLY) < 0) { + return false; + } + + filesystem.FileClose(&file); + return true; +} \ No newline at end of file diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h new file mode 100644 index 00000000..d3072507 --- /dev/null +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h @@ -0,0 +1,133 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "displayapp/screens/Screen.h" +#include "components/datetime/DateTimeController.h" +#include "components/ble/BleController.h" +#include "components/ble/SimpleWeatherService.h" +#include "utility/DirtyValue.h" +#include "displayapp/apps/Apps.h" + +namespace Pinetime { + namespace Controllers { + class Settings; + class Battery; + class Ble; + class NotificationManager; + class HeartRateController; + class MotionController; + } + + namespace Applications { + namespace Screens { + + class WatchFaceCasioStyleG7710Weather : public Screen { + public: + WatchFaceCasioStyleG7710Weather(Controllers::DateTime& dateTimeController, + const Controllers::Battery& batteryController, + const Controllers::Ble& bleController, + Controllers::NotificationManager& notificatioManager, + Controllers::Settings& settingsController, + Controllers::HeartRateController& heartRateController, + Controllers::MotionController& motionController, + Controllers::FS& filesystem, + Controllers::SimpleWeatherService& weather); + ~WatchFaceCasioStyleG7710Weather() override; + + void Refresh() override; + + static bool IsAvailable(Pinetime::Controllers::FS& filesystem); + + private: + Utility::DirtyValue batteryPercentRemaining {}; + Utility::DirtyValue powerPresent {}; + Utility::DirtyValue bleState {}; + Utility::DirtyValue bleRadioEnabled {}; + Utility::DirtyValue> currentDateTime {}; + Utility::DirtyValue stepCount {}; + Utility::DirtyValue heartbeat {}; + Utility::DirtyValue heartbeatRunning {}; + Utility::DirtyValue notificationState {}; + Utility::DirtyValue> currentDate; + Utility::DirtyValue> currentWeather {}; + + lv_point_t line_icons_points[3] {{0, 5}, {117, 5}, {122, 0}}; + lv_point_t line_day_of_week_number_points[4] {{0, 0}, {100, 0}, {95, 95}, {0, 95}}; + lv_point_t line_day_of_year_points[3] {{0, 5}, {130, 5}, {135, 0}}; + lv_point_t line_date_points[3] {{0, 5}, {135, 5}, {140, 0}}; + lv_point_t line_time_points[3] {{0, 0}, {230, 0}, {235, 5}}; + + lv_color_t color_text = lv_color_hex(0x98B69A); + + lv_style_t style_line; + lv_style_t style_border; + + 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* label_battery_value; + lv_obj_t* heartbeatIcon; + lv_obj_t* heartbeatValue; + lv_obj_t* stepIcon; + lv_obj_t* stepValue; + lv_obj_t* notificationIcon; + lv_obj_t* line_icons; + lv_obj_t* weatherIcon; + lv_obj_t* label_temperature; + + BatteryIcon batteryIcon; + + Controllers::DateTime& dateTimeController; + const Controllers::Battery& batteryController; + const Controllers::Ble& bleController; + Controllers::NotificationManager& notificatioManager; + Controllers::Settings& settingsController; + Controllers::HeartRateController& heartRateController; + Controllers::MotionController& motionController; + Controllers::SimpleWeatherService& weatherService; + + lv_task_t* taskRefresh; + lv_font_t* font_dot40 = nullptr; + lv_font_t* font_segment40 = nullptr; + lv_font_t* font_segment115 = nullptr; + }; + } + + template <> + struct WatchFaceTraits { + static constexpr WatchFace watchFace = WatchFace::CasioStyleG7710Weather; + static constexpr const char* name = "Casio weather"; + + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::WatchFaceCasioStyleG7710Weather(controllers.dateTimeController, + controllers.batteryController, + controllers.bleController, + controllers.notificationManager, + controllers.settingsController, + controllers.heartRateController, + controllers.motionController, + controllers.filesystem, + *controllers.weatherController); + }; + + static bool IsAvailable(Pinetime::Controllers::FS& filesystem) { + return Screens::WatchFaceCasioStyleG7710Weather::IsAvailable(filesystem); + } + }; + } +} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 4c75b0ab..8542bf51 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -11,6 +11,7 @@ #include "displayapp/screens/CheckboxList.h" #include "displayapp/screens/WatchFaceInfineat.h" #include "displayapp/screens/WatchFaceCasioStyleG7710.h" +#include "displayapp/screens/WatchFaceCasioStyleG7710Weather.h" namespace Pinetime { From adef8e8dd2c729a05eb1f72b5449f9e7d6df23b9 Mon Sep 17 00:00:00 2001 From: Julian Vos Date: Sat, 3 Aug 2024 17:43:52 +0200 Subject: [PATCH 2/6] fix: align weather temperature with date --- .../screens/WatchFaceCasioStyleG7710Weather.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp index 8560f378..76b441dc 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp @@ -92,14 +92,14 @@ WatchFaceCasioStyleG7710Weather::WatchFaceCasioStyleG7710Weather(Controllers::Da lv_obj_set_style_local_text_color(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); lv_obj_set_style_local_text_font(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &fontawesome_weathericons); lv_label_set_text_static(weatherIcon, ""); - lv_obj_align(weatherIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 120, 30); + lv_obj_align(weatherIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 110, 30); lv_obj_set_auto_realign(weatherIcon, true); label_temperature = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); lv_obj_set_style_local_text_font(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); lv_label_set_text(label_temperature, ""); - lv_obj_align(label_temperature, nullptr, LV_ALIGN_IN_TOP_RIGHT, -7, 30); + lv_obj_align(label_temperature, nullptr, LV_ALIGN_IN_TOP_RIGHT, -5, 30); lv_style_init(&style_line); lv_style_set_line_width(&style_line, LV_STATE_DEFAULT, 2); @@ -127,7 +127,7 @@ WatchFaceCasioStyleG7710Weather::WatchFaceCasioStyleG7710Weather(Controllers::Da lv_obj_align(line_day_of_year, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 60); label_date = lv_label_create(lv_scr_act(), nullptr); - lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 70); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -45, 70); lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); lv_label_set_text_static(label_date, "6-30"); @@ -259,10 +259,8 @@ void WatchFaceCasioStyleG7710Weather::Refresh() { if (currentDate.IsUpdated()) { const char* weekNumberFormat = "%V"; - uint16_t year = dateTimeController.Year(); Controllers::DateTime::Months month = dateTimeController.Month(); uint8_t day = dateTimeController.Day(); - int dayOfYear = dateTimeController.DayOfYear(); if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { // 24h mode: ddmmyyyy, first DOW=Monday; lv_label_set_text_fmt(label_date, "%3d-%2d", day, month); @@ -281,10 +279,6 @@ void WatchFaceCasioStyleG7710Weather::Refresh() { std::chrono::system_clock::to_time_t(std::chrono::time_point_cast(currentDateTime.Get())); tm* tmTime = std::localtime(&ttTime); - // TODO: When we start using C++20, use std::chrono::year::is_leap - int daysInCurrentYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? 366 : 365; - uint16_t daysTillEndOfYearNumber = daysInCurrentYear - dayOfYear; - char buffer[8]; strftime(buffer, 8, weekNumberFormat, tmTime); uint8_t weekNumber = atoi(buffer); @@ -335,7 +329,7 @@ void WatchFaceCasioStyleG7710Weather::Refresh() { } temp = temp / 100 + (temp % 100 >= 50 ? 1 : 0); - lv_label_set_text_fmt(label_temperature, "%d %c", temp, tempUnit); + lv_label_set_text_fmt(label_temperature, "%d°%c", temp, tempUnit); lv_label_set_text(weatherIcon, Symbols::GetSymbol(optCurrentWeather->iconId)); } else { lv_label_set_text_static(label_temperature, ""); From 7e75680b726ff7eaf83af4cd00347e0736c2d2e0 Mon Sep 17 00:00:00 2001 From: Julian Vos Date: Sat, 3 Aug 2024 17:44:42 +0200 Subject: [PATCH 3/6] fix: add degrees symbol and C/F to 7 segment 40 point font --- src/resources/fonts.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources/fonts.json b/src/resources/fonts.json index c4a63349..6fc3d43f 100644 --- a/src/resources/fonts.json +++ b/src/resources/fonts.json @@ -39,7 +39,7 @@ "sources": [ { "file": "fonts/7segment.woff", - "symbols": "0123456789: -" + "symbols": "0123456789: -°CF" } ], "bpp": 1, From d57ae5c9135732143aaa76d043a24baeec9dea55 Mon Sep 17 00:00:00 2001 From: Julian Vos Date: Sun, 4 Aug 2024 22:48:34 +0200 Subject: [PATCH 4/6] feat: make weather a setting --- src/CMakeLists.txt | 1 - src/components/settings/Settings.h | 16 + src/displayapp/UserApps.h | 1 - src/displayapp/apps/Apps.h.in | 3 +- src/displayapp/apps/CMakeLists.txt | 1 - .../screens/WatchFaceCasioStyleG7710.cpp | 150 +++++++- .../screens/WatchFaceCasioStyleG7710.h | 22 +- .../WatchFaceCasioStyleG7710Weather.cpp | 363 ------------------ .../screens/WatchFaceCasioStyleG7710Weather.h | 133 ------- .../screens/settings/SettingWatchFace.h | 1 - 10 files changed, 184 insertions(+), 507 deletions(-) delete mode 100644 src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp delete mode 100644 src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e65f166a..fd8ece62 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -426,7 +426,6 @@ list(APPEND SOURCE_FILES displayapp/screens/WatchFaceTerminal.cpp displayapp/screens/WatchFacePineTimeStyle.cpp displayapp/screens/WatchFaceCasioStyleG7710.cpp - displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp ## diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 06312077..aee23365 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -45,6 +45,10 @@ namespace Pinetime { PTSWeather weatherEnable = PTSWeather::Off; }; + struct CasioStyleG7710 { + PTSWeather weatherEnable = PTSWeather::Off; + }; + struct WatchFaceInfineat { bool showSideCover = true; int colorIndex = 0; @@ -154,6 +158,16 @@ namespace Pinetime { return settings.PTS.weatherEnable; }; + void SetCasioWeather(PTSWeather weatherEnable) { + if (weatherEnable != settings.casio.weatherEnable) + settingsChanged = true; + settings.casio.weatherEnable = weatherEnable; + } + + PTSWeather GetCasioWeather() const { + return settings.casio.weatherEnable; + } + void SetAppMenu(uint8_t menu) { appMenu = menu; }; @@ -302,6 +316,8 @@ namespace Pinetime { PineTimeStyle PTS; + CasioStyleG7710 casio; + WatchFaceInfineat watchFaceInfineat; std::bitset<5> wakeUpMode {0}; diff --git a/src/displayapp/UserApps.h b/src/displayapp/UserApps.h index 79520d4e..67bbfa7d 100644 --- a/src/displayapp/UserApps.h +++ b/src/displayapp/UserApps.h @@ -11,7 +11,6 @@ #include "displayapp/screens/WatchFaceDigital.h" #include "displayapp/screens/WatchFaceAnalog.h" #include "displayapp/screens/WatchFaceCasioStyleG7710.h" -#include "displayapp/screens/WatchFaceCasioStyleG7710Weather.h" #include "displayapp/screens/WatchFaceInfineat.h" #include "displayapp/screens/WatchFacePineTimeStyle.h" #include "displayapp/screens/WatchFaceTerminal.h" diff --git a/src/displayapp/apps/Apps.h.in b/src/displayapp/apps/Apps.h.in index b0ed80c2..bf4c1e97 100644 --- a/src/displayapp/apps/Apps.h.in +++ b/src/displayapp/apps/Apps.h.in @@ -51,8 +51,7 @@ namespace Pinetime { PineTimeStyle, Terminal, Infineat, - CasioStyleG7710, - CasioStyleG7710Weather + CasioStyleG7710 }; template diff --git a/src/displayapp/apps/CMakeLists.txt b/src/displayapp/apps/CMakeLists.txt index 5ccb6c06..d7858760 100644 --- a/src/displayapp/apps/CMakeLists.txt +++ b/src/displayapp/apps/CMakeLists.txt @@ -27,7 +27,6 @@ else() set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::Terminal") set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::Infineat") set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::CasioStyleG7710") - set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::CasioStyleG7710Weather") set(WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}" CACHE STRING "List of watch faces to build into the firmware") endif() diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp index c695f852..6e48161c 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp @@ -6,14 +6,24 @@ #include "displayapp/screens/BleIcon.h" #include "displayapp/screens/NotificationIcon.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/screens/WeatherSymbols.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" +#include "components/ble/SimpleWeatherService.h" + using namespace Pinetime::Applications::Screens; +namespace { + void event_handler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTimeController, const Controllers::Battery& batteryController, const Controllers::Ble& bleController, @@ -21,7 +31,8 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, Controllers::MotionController& motionController, - Controllers::FS& filesystem) + Controllers::FS& filesystem, + Controllers::SimpleWeatherService& weatherService) : currentDateTime {{}}, batteryIcon(false), dateTimeController {dateTimeController}, @@ -30,7 +41,8 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi notificatioManager {notificatioManager}, settingsController {settingsController}, heartRateController {heartRateController}, - motionController {motionController} { + motionController {motionController}, + weatherService {weatherService} { lfs_file f = {}; if (filesystem.FileOpen(&f, "/fonts/lv_font_dots_40.bin", LFS_O_RDONLY) >= 0) { @@ -89,6 +101,34 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi lv_obj_set_style_local_text_color(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); lv_obj_set_style_local_text_font(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); lv_label_set_text_static(label_day_of_year, "181-184"); + if (settingsController.GetCasioWeather() == Pinetime::Controllers::Settings::PTSWeather::On) { + lv_obj_set_hidden(label_day_of_year, false); + } else { + lv_obj_set_hidden(label_day_of_year, true); + } + + weatherIcon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); + lv_obj_set_style_local_text_font(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &fontawesome_weathericons); + lv_label_set_text_static(weatherIcon, ""); + lv_obj_align(weatherIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 110, 30); + lv_obj_set_auto_realign(weatherIcon, true); + if (settingsController.GetCasioWeather() == Pinetime::Controllers::Settings::PTSWeather::On) { + lv_obj_set_hidden(weatherIcon, false); + } else { + lv_obj_set_hidden(weatherIcon, true); + } + + label_temperature = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); + lv_obj_set_style_local_text_font(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); + lv_label_set_text(label_temperature, ""); + lv_obj_align(label_temperature, nullptr, LV_ALIGN_IN_TOP_RIGHT, -5, 30); + if (settingsController.GetCasioWeather() == Pinetime::Controllers::Settings::PTSWeather::On) { + lv_obj_set_hidden(label_temperature, false); + } else { + lv_obj_set_hidden(label_temperature, true); + } lv_style_init(&style_line); lv_style_set_line_width(&style_line, LV_STATE_DEFAULT, 2); @@ -116,7 +156,7 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi lv_obj_align(line_day_of_year, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 60); label_date = lv_label_create(lv_scr_act(), nullptr); - lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 70); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -45, 70); lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); lv_label_set_text_static(label_date, "6-30"); @@ -168,6 +208,26 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi lv_label_set_text_static(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + btnWeather = lv_btn_create(lv_scr_act(), nullptr); + btnWeather->user_data = this; + lv_obj_set_size(btnWeather, 160, 60); + lv_obj_align(btnWeather, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_bg_opa(btnWeather, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); + lv_obj_t* lblWeather = lv_label_create(btnWeather, nullptr); + lv_label_set_text_static(lblWeather, "Weather"); + lv_obj_set_event_cb(btnWeather, event_handler); + lv_obj_set_hidden(btnWeather, true); + + btnClose = lv_btn_create(lv_scr_act(), nullptr); + btnClose->user_data = this; + lv_obj_set_size(btnClose, 60, 60); + lv_obj_align(btnClose, lv_scr_act(), LV_ALIGN_CENTER, 0, -80); + lv_obj_set_style_local_bg_opa(btnClose, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); + lv_obj_t* lblClose = lv_label_create(btnClose, nullptr); + lv_label_set_text_static(lblClose, "X"); + lv_obj_set_event_cb(btnClose, event_handler); + lv_obj_set_hidden(btnClose, true); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); Refresh(); } @@ -310,6 +370,41 @@ void WatchFaceCasioStyleG7710::Refresh() { lv_obj_realign(stepValue); lv_obj_realign(stepIcon); } + + if (settingsController.GetCasioWeather() == Pinetime::Controllers::Settings::PTSWeather::On) { + currentWeather = weatherService.Current(); + + if (currentWeather.IsUpdated()) { + auto optCurrentWeather = currentWeather.Get(); + + if (optCurrentWeather) { + int16_t temp = optCurrentWeather->temperature; + char tempUnit = 'C'; + + if (settingsController.GetWeatherFormat() == Controllers::Settings::WeatherFormat::Imperial) { + temp = Controllers::SimpleWeatherService::CelsiusToFahrenheit(temp); + tempUnit = 'F'; + } + + temp = temp / 100 + (temp % 100 >= 50 ? 1 : 0); + lv_label_set_text_fmt(label_temperature, "%d°%c", temp, tempUnit); + lv_label_set_text(weatherIcon, Symbols::GetSymbol(optCurrentWeather->iconId)); + } else { + lv_label_set_text_static(label_temperature, ""); + lv_label_set_text(weatherIcon, ""); + } + + lv_obj_realign(label_temperature); + lv_obj_realign(weatherIcon); + } + } + + if (!lv_obj_get_hidden(btnClose)) { + if ((savedTick > 0) && (lv_tick_get() - savedTick > 3000)) { + CloseMenu(); + savedTick = 0; + } + } } bool WatchFaceCasioStyleG7710::IsAvailable(Pinetime::Controllers::FS& filesystem) { @@ -332,3 +427,52 @@ bool WatchFaceCasioStyleG7710::IsAvailable(Pinetime::Controllers::FS& filesystem filesystem.FileClose(&file); return true; } + +bool WatchFaceCasioStyleG7710::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + if ((event == Pinetime::Applications::TouchEvents::LongTap) && lv_obj_get_hidden(btnClose)) { + lv_obj_set_hidden(btnWeather, false); + lv_obj_set_hidden(btnClose, false); + savedTick = lv_tick_get(); + return true; + } + if ((event == Pinetime::Applications::TouchEvents::DoubleTap) && (lv_obj_get_hidden(btnClose) == false)) { + return true; + } + return false; +} + +void WatchFaceCasioStyleG7710::CloseMenu() { + settingsController.SaveSettings(); + lv_obj_set_hidden(btnWeather, true); + lv_obj_set_hidden(btnClose, true); +} + +bool WatchFaceCasioStyleG7710::OnButtonPushed() { + if (!lv_obj_get_hidden(btnClose)) { + CloseMenu(); + return true; + } + + return false; +} + +void WatchFaceCasioStyleG7710::UpdateSelected(lv_obj_t* object, lv_event_t event) { + if (event == LV_EVENT_CLICKED) { + if (object == btnWeather) { + if (lv_obj_get_hidden(weatherIcon)) { + lv_obj_set_hidden(weatherIcon, false); + lv_obj_set_hidden(label_temperature, false); + lv_obj_set_hidden(label_day_of_year, true); + settingsController.SetCasioWeather(Controllers::Settings::PTSWeather::On); + } else { + lv_obj_set_hidden(weatherIcon, true); + lv_obj_set_hidden(label_temperature, true); + lv_obj_set_hidden(label_day_of_year, false); + settingsController.SetCasioWeather(Controllers::Settings::PTSWeather::Off); + } + } + if (object == btnClose) { + CloseMenu(); + } + } +} diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.h b/src/displayapp/screens/WatchFaceCasioStyleG7710.h index 0f46a692..1e2e9456 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710.h +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.h @@ -9,6 +9,7 @@ #include "displayapp/screens/Screen.h" #include "components/datetime/DateTimeController.h" #include "components/ble/BleController.h" +#include "components/ble/SimpleWeatherService.h" #include "utility/DirtyValue.h" #include "displayapp/apps/Apps.h" @@ -34,9 +35,15 @@ namespace Pinetime { Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, Controllers::MotionController& motionController, - Controllers::FS& filesystem); + Controllers::FS& filesystem, + Controllers::SimpleWeatherService& weather); ~WatchFaceCasioStyleG7710() override; + bool OnTouchEvent(TouchEvents event) override; + bool OnButtonPushed() override; + + void UpdateSelected(lv_obj_t* object, lv_event_t event); + void Refresh() override; static bool IsAvailable(Pinetime::Controllers::FS& filesystem); @@ -52,6 +59,9 @@ namespace Pinetime { Utility::DirtyValue heartbeatRunning {}; Utility::DirtyValue notificationState {}; Utility::DirtyValue> currentDate; + Utility::DirtyValue> currentWeather {}; + + uint32_t savedTick = 0; lv_point_t line_icons_points[3] {{0, 5}, {117, 5}, {122, 0}}; lv_point_t line_day_of_week_number_points[4] {{0, 0}, {100, 0}, {95, 95}, {0, 95}}; @@ -84,6 +94,10 @@ namespace Pinetime { lv_obj_t* stepValue; lv_obj_t* notificationIcon; lv_obj_t* line_icons; + lv_obj_t* btnWeather; + lv_obj_t* btnClose; + lv_obj_t* weatherIcon; + lv_obj_t* label_temperature; BatteryIcon batteryIcon; @@ -94,11 +108,14 @@ namespace Pinetime { Controllers::Settings& settingsController; Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; + Controllers::SimpleWeatherService& weatherService; lv_task_t* taskRefresh; lv_font_t* font_dot40 = nullptr; lv_font_t* font_segment40 = nullptr; lv_font_t* font_segment115 = nullptr; + + void CloseMenu(); }; } @@ -115,7 +132,8 @@ namespace Pinetime { controllers.settingsController, controllers.heartRateController, controllers.motionController, - controllers.filesystem); + controllers.filesystem, + *controllers.weatherController); }; static bool IsAvailable(Pinetime::Controllers::FS& filesystem) { diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp deleted file mode 100644 index 76b441dc..00000000 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.cpp +++ /dev/null @@ -1,363 +0,0 @@ -#include "displayapp/screens/WatchFaceCasioStyleG7710Weather.h" - -#include -#include -#include "displayapp/screens/BatteryIcon.h" -#include "displayapp/screens/BleIcon.h" -#include "displayapp/screens/NotificationIcon.h" -#include "displayapp/screens/Symbols.h" -#include "displayapp/screens/WeatherSymbols.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" -#include "components/ble/SimpleWeatherService.h" -using namespace Pinetime::Applications::Screens; - -WatchFaceCasioStyleG7710Weather::WatchFaceCasioStyleG7710Weather(Controllers::DateTime& dateTimeController, - const Controllers::Battery& batteryController, - const Controllers::Ble& bleController, - Controllers::NotificationManager& notificatioManager, - Controllers::Settings& settingsController, - Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController, - Controllers::FS& filesystem, - Controllers::SimpleWeatherService& weatherService) - : currentDateTime {{}}, - batteryIcon(false), - dateTimeController {dateTimeController}, - batteryController {batteryController}, - bleController {bleController}, - notificatioManager {notificatioManager}, - settingsController {settingsController}, - heartRateController {heartRateController}, - motionController {motionController}, - weatherService {weatherService} { - - lfs_file f = {}; - if (filesystem.FileOpen(&f, "/fonts/lv_font_dots_40.bin", LFS_O_RDONLY) >= 0) { - filesystem.FileClose(&f); - font_dot40 = lv_font_load("F:/fonts/lv_font_dots_40.bin"); - } - - if (filesystem.FileOpen(&f, "/fonts/7segments_40.bin", LFS_O_RDONLY) >= 0) { - filesystem.FileClose(&f); - font_segment40 = lv_font_load("F:/fonts/7segments_40.bin"); - } - - if (filesystem.FileOpen(&f, "/fonts/7segments_115.bin", LFS_O_RDONLY) >= 0) { - filesystem.FileClose(&f); - font_segment115 = lv_font_load("F:/fonts/7segments_115.bin"); - } - - label_battery_value = lv_label_create(lv_scr_act(), nullptr); - lv_obj_align(label_battery_value, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); - lv_obj_set_style_local_text_color(label_battery_value, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_label_set_text_static(label_battery_value, "00%"); - - batteryIcon.Create(lv_scr_act()); - batteryIcon.SetColor(color_text); - lv_obj_align(batteryIcon.GetObject(), label_battery_value, LV_ALIGN_OUT_LEFT_MID, -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, color_text); - lv_label_set_text_static(batteryPlug, Symbols::plug); - lv_obj_align(batteryPlug, batteryIcon.GetObject(), 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, color_text); - 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, color_text); - lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false)); - lv_obj_align(notificationIcon, bleIcon, LV_ALIGN_OUT_LEFT_MID, -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, color_text); - lv_obj_set_style_local_text_font(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40); - 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, 22); - lv_obj_set_style_local_text_color(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40); - lv_label_set_text_static(label_week_number, "WK26"); - - weatherIcon = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &fontawesome_weathericons); - lv_label_set_text_static(weatherIcon, ""); - lv_obj_align(weatherIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 110, 30); - lv_obj_set_auto_realign(weatherIcon, true); - - label_temperature = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); - lv_label_set_text(label_temperature, ""); - lv_obj_align(label_temperature, nullptr, LV_ALIGN_IN_TOP_RIGHT, -5, 30); - - 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, color_text); - lv_style_set_line_rounded(&style_line, LV_STATE_DEFAULT, true); - - 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, color_text); - lv_style_set_line_rounded(&style_border, LV_STATE_DEFAULT, true); - - line_icons = lv_line_create(lv_scr_act(), nullptr); - lv_line_set_points(line_icons, line_icons_points, 3); - lv_obj_add_style(line_icons, LV_LINE_PART_MAIN, &style_line); - lv_obj_align(line_icons, nullptr, LV_ALIGN_IN_TOP_RIGHT, -10, 18); - - line_day_of_week_number = lv_line_create(lv_scr_act(), nullptr); - 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, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 8); - - line_day_of_year = lv_line_create(lv_scr_act(), nullptr); - 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, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 60); - - label_date = lv_label_create(lv_scr_act(), nullptr); - lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -45, 70); - lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); - lv_label_set_text_static(label_date, "6-30"); - - line_date = lv_line_create(lv_scr_act(), nullptr); - 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, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 100); - - 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, color_text); - lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment115); - lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 40); - - line_time = lv_line_create(lv_scr_act(), nullptr); - 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, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, -25); - - 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, color_text); - 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, color_text); - 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, color_text); - 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, color_text); - 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, color_text); - 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(); -} - -WatchFaceCasioStyleG7710Weather::~WatchFaceCasioStyleG7710Weather() { - lv_task_del(taskRefresh); - - lv_style_reset(&style_line); - lv_style_reset(&style_border); - - if (font_dot40 != nullptr) { - lv_font_free(font_dot40); - } - - if (font_segment40 != nullptr) { - lv_font_free(font_segment40); - } - - if (font_segment115 != nullptr) { - lv_font_free(font_segment115); - } - - lv_obj_clean(lv_scr_act()); -} - -void WatchFaceCasioStyleG7710Weather::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(); - batteryIcon.SetBatteryPercentage(batteryPercent); - lv_label_set_text_fmt(label_battery_value, "%d%%", 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(label_battery_value); - lv_obj_realign(batteryIcon.GetObject()); - lv_obj_realign(batteryPlug); - lv_obj_realign(bleIcon); - lv_obj_realign(notificationIcon); - - notificationState = notificatioManager.AreNewNotificationsAvailable(); - if (notificationState.IsUpdated()) { - lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); - } - - currentDateTime = std::chrono::time_point_cast(dateTimeController.CurrentDateTime()); - if (currentDateTime.IsUpdated()) { - uint8_t hour = dateTimeController.Hours(); - uint8_t minute = dateTimeController.Minutes(); - - 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); - } else { - lv_label_set_text_fmt(label_time, "%02d:%02d", hour, minute); - } - lv_obj_realign(label_time); - - currentDate = std::chrono::time_point_cast(currentDateTime.Get()); - if (currentDate.IsUpdated()) { - const char* weekNumberFormat = "%V"; - - Controllers::DateTime::Months month = dateTimeController.Month(); - uint8_t day = dateTimeController.Day(); - 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] - } - - time_t ttTime = - std::chrono::system_clock::to_time_t(std::chrono::time_point_cast(currentDateTime.Get())); - tm* tmTime = std::localtime(&ttTime); - - char buffer[8]; - strftime(buffer, 8, weekNumberFormat, tmTime); - uint8_t weekNumber = atoi(buffer); - - lv_label_set_text_fmt(label_day_of_week, "%s", dateTimeController.DayOfWeekShortToString()); - lv_label_set_text_fmt(label_week_number, "WK%02d", weekNumber); - - lv_obj_realign(label_day_of_week); - lv_obj_realign(label_week_number); - lv_obj_realign(label_date); - } - } - - 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, color_text); - 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(); - if (stepCount.IsUpdated()) { - lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get()); - lv_obj_realign(stepValue); - lv_obj_realign(stepIcon); - } - - currentWeather = weatherService.Current(); - - if (currentWeather.IsUpdated()) { - auto optCurrentWeather = currentWeather.Get(); - - if (optCurrentWeather) { - int16_t temp = optCurrentWeather->temperature; - char tempUnit = 'C'; - - if (settingsController.GetWeatherFormat() == Controllers::Settings::WeatherFormat::Imperial) { - temp = Controllers::SimpleWeatherService::CelsiusToFahrenheit(temp); - tempUnit = 'F'; - } - - temp = temp / 100 + (temp % 100 >= 50 ? 1 : 0); - lv_label_set_text_fmt(label_temperature, "%d°%c", temp, tempUnit); - lv_label_set_text(weatherIcon, Symbols::GetSymbol(optCurrentWeather->iconId)); - } else { - lv_label_set_text_static(label_temperature, ""); - lv_label_set_text(weatherIcon, ""); - } - - lv_obj_realign(label_temperature); - lv_obj_realign(weatherIcon); - } -} - -bool WatchFaceCasioStyleG7710Weather::IsAvailable(Pinetime::Controllers::FS& filesystem) { - lfs_file file = {}; - - if (filesystem.FileOpen(&file, "/fonts/lv_font_dots_40.bin", LFS_O_RDONLY) < 0) { - return false; - } - - filesystem.FileClose(&file); - if (filesystem.FileOpen(&file, "/fonts/7segments_40.bin", LFS_O_RDONLY) < 0) { - return false; - } - - filesystem.FileClose(&file); - if (filesystem.FileOpen(&file, "/fonts/7segments_115.bin", LFS_O_RDONLY) < 0) { - return false; - } - - filesystem.FileClose(&file); - return true; -} \ No newline at end of file diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h b/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h deleted file mode 100644 index d3072507..00000000 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710Weather.h +++ /dev/null @@ -1,133 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "displayapp/screens/Screen.h" -#include "components/datetime/DateTimeController.h" -#include "components/ble/BleController.h" -#include "components/ble/SimpleWeatherService.h" -#include "utility/DirtyValue.h" -#include "displayapp/apps/Apps.h" - -namespace Pinetime { - namespace Controllers { - class Settings; - class Battery; - class Ble; - class NotificationManager; - class HeartRateController; - class MotionController; - } - - namespace Applications { - namespace Screens { - - class WatchFaceCasioStyleG7710Weather : public Screen { - public: - WatchFaceCasioStyleG7710Weather(Controllers::DateTime& dateTimeController, - const Controllers::Battery& batteryController, - const Controllers::Ble& bleController, - Controllers::NotificationManager& notificatioManager, - Controllers::Settings& settingsController, - Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController, - Controllers::FS& filesystem, - Controllers::SimpleWeatherService& weather); - ~WatchFaceCasioStyleG7710Weather() override; - - void Refresh() override; - - static bool IsAvailable(Pinetime::Controllers::FS& filesystem); - - private: - Utility::DirtyValue batteryPercentRemaining {}; - Utility::DirtyValue powerPresent {}; - Utility::DirtyValue bleState {}; - Utility::DirtyValue bleRadioEnabled {}; - Utility::DirtyValue> currentDateTime {}; - Utility::DirtyValue stepCount {}; - Utility::DirtyValue heartbeat {}; - Utility::DirtyValue heartbeatRunning {}; - Utility::DirtyValue notificationState {}; - Utility::DirtyValue> currentDate; - Utility::DirtyValue> currentWeather {}; - - lv_point_t line_icons_points[3] {{0, 5}, {117, 5}, {122, 0}}; - lv_point_t line_day_of_week_number_points[4] {{0, 0}, {100, 0}, {95, 95}, {0, 95}}; - lv_point_t line_day_of_year_points[3] {{0, 5}, {130, 5}, {135, 0}}; - lv_point_t line_date_points[3] {{0, 5}, {135, 5}, {140, 0}}; - lv_point_t line_time_points[3] {{0, 0}, {230, 0}, {235, 5}}; - - lv_color_t color_text = lv_color_hex(0x98B69A); - - lv_style_t style_line; - lv_style_t style_border; - - 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* label_battery_value; - lv_obj_t* heartbeatIcon; - lv_obj_t* heartbeatValue; - lv_obj_t* stepIcon; - lv_obj_t* stepValue; - lv_obj_t* notificationIcon; - lv_obj_t* line_icons; - lv_obj_t* weatherIcon; - lv_obj_t* label_temperature; - - BatteryIcon batteryIcon; - - Controllers::DateTime& dateTimeController; - const Controllers::Battery& batteryController; - const Controllers::Ble& bleController; - Controllers::NotificationManager& notificatioManager; - Controllers::Settings& settingsController; - Controllers::HeartRateController& heartRateController; - Controllers::MotionController& motionController; - Controllers::SimpleWeatherService& weatherService; - - lv_task_t* taskRefresh; - lv_font_t* font_dot40 = nullptr; - lv_font_t* font_segment40 = nullptr; - lv_font_t* font_segment115 = nullptr; - }; - } - - template <> - struct WatchFaceTraits { - static constexpr WatchFace watchFace = WatchFace::CasioStyleG7710Weather; - static constexpr const char* name = "Casio weather"; - - static Screens::Screen* Create(AppControllers& controllers) { - return new Screens::WatchFaceCasioStyleG7710Weather(controllers.dateTimeController, - controllers.batteryController, - controllers.bleController, - controllers.notificationManager, - controllers.settingsController, - controllers.heartRateController, - controllers.motionController, - controllers.filesystem, - *controllers.weatherController); - }; - - static bool IsAvailable(Pinetime::Controllers::FS& filesystem) { - return Screens::WatchFaceCasioStyleG7710Weather::IsAvailable(filesystem); - } - }; - } -} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 8542bf51..4c75b0ab 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -11,7 +11,6 @@ #include "displayapp/screens/CheckboxList.h" #include "displayapp/screens/WatchFaceInfineat.h" #include "displayapp/screens/WatchFaceCasioStyleG7710.h" -#include "displayapp/screens/WatchFaceCasioStyleG7710Weather.h" namespace Pinetime { From 756b4f9dcd666e5d32a544914c7c79571da16b85 Mon Sep 17 00:00:00 2001 From: Julian Vos Date: Sun, 4 Aug 2024 22:57:56 +0200 Subject: [PATCH 5/6] fix: flipped the hiding around --- src/displayapp/screens/WatchFaceCasioStyleG7710.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp index 6e48161c..6e6d7c5d 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp @@ -102,9 +102,9 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi lv_obj_set_style_local_text_font(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); lv_label_set_text_static(label_day_of_year, "181-184"); if (settingsController.GetCasioWeather() == Pinetime::Controllers::Settings::PTSWeather::On) { - lv_obj_set_hidden(label_day_of_year, false); - } else { lv_obj_set_hidden(label_day_of_year, true); + } else { + lv_obj_set_hidden(label_day_of_year, false); } weatherIcon = lv_label_create(lv_scr_act(), nullptr); From c22a9df2cca1b948b1664882bf1c08f9c5166efc Mon Sep 17 00:00:00 2001 From: Julian Vos Date: Sun, 4 Aug 2024 22:58:39 +0200 Subject: [PATCH 6/6] feat: reaset timeout tick on tap --- src/displayapp/screens/WatchFaceCasioStyleG7710.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp index 6e6d7c5d..0bb82fd8 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp @@ -429,6 +429,9 @@ bool WatchFaceCasioStyleG7710::IsAvailable(Pinetime::Controllers::FS& filesystem } bool WatchFaceCasioStyleG7710::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + if (lv_obj_get_hidden(btnClose) == false) { + savedTick = lv_tick_get(); + } if ((event == Pinetime::Applications::TouchEvents::LongTap) && lv_obj_get_hidden(btnClose)) { lv_obj_set_hidden(btnWeather, false); lv_obj_set_hidden(btnClose, false);