From 8c53d0b70baa03c2b07360444a7cd0ad99bb8381 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Wed, 24 Feb 2021 19:40:24 +0000 Subject: Multi face support, analog clock, 12/24 config --- src/displayapp/screens/Clock.cpp | 256 +++++++-------------------------------- 1 file changed, 43 insertions(+), 213 deletions(-) (limited to 'src/displayapp/screens/Clock.cpp') diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 4b280adb..ea9ddd56 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -10,243 +10,73 @@ #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" -#include "components/heartrate/HeartRateController.h" #include "../DisplayApp.h" +#include "WatchFaceDigital.h" +#include "WatchFaceAnalog.h" -using namespace Pinetime::Applications::Screens; -static void event_handler(lv_obj_t * obj, lv_event_t event) { - Clock* screen = static_cast(obj->user_data); - screen->OnObjectEvent(obj, event); -} +using namespace Pinetime::Applications::Screens; Clock::Clock(DisplayApp* app, Controllers::DateTime& dateTimeController, Controllers::Battery& batteryController, Controllers::Ble& bleController, Controllers::NotificationManager& notificatioManager, - Controllers::HeartRateController& heartRateController): Screen(app), currentDateTime{{}}, - dateTimeController{dateTimeController}, batteryController{batteryController}, - bleController{bleController}, notificatioManager{notificatioManager}, - heartRateController{heartRateController} { - displayedChar[0] = 0; - displayedChar[1] = 0; - displayedChar[2] = 0; - displayedChar[3] = 0; - displayedChar[4] = 0; - - batteryIcon = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(batteryIcon, Symbols::batteryFull); - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2); - - batteryPlug = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(batteryPlug, Symbols::plug); - lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); - - bleIcon = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(bleIcon, Symbols::bluetooth); - lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); - - notificationIcon = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); - lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0); - - label_date = lv_label_create(lv_scr_act(), nullptr); - - lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); - - label_time = lv_label_create(lv_scr_act(), nullptr); - - lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed); - - lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0); - - backgroundLabel = lv_label_create(lv_scr_act(), nullptr); - backgroundLabel->user_data = this; - lv_obj_set_click(backgroundLabel, true); - lv_obj_set_event_cb(backgroundLabel, event_handler); - 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(backgroundLabel, ""); - - - heartbeatIcon = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(heartbeatIcon, Symbols::heartBeat); - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); - - heartbeatValue = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(heartbeatValue, "0"); - lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - - heartbeatBpm = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(heartbeatBpm, "BPM"); - lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - - stepValue = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(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_label_set_text(stepIcon, Symbols::shoe); - lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); -} + Controllers::Settings &settingsController, + Controllers::HeartRateController& heartRateController) : Screen(app), + dateTimeController{dateTimeController}, batteryController{batteryController}, + bleController{bleController}, notificatioManager{notificatioManager}, + settingsController{settingsController}, + heartRateController{heartRateController}, + screens{app, + settingsController.GetClockFace(), + { + [this]() -> std::unique_ptr { return WatchFaceDigitalScreen(); }, + [this]() -> std::unique_ptr { return WatchFaceAnalogScreen(); }, + //[this]() -> std::unique_ptr { return WatchFaceMinimalScreen(); }, + //[this]() -> std::unique_ptr { return WatchFaceCustomScreen(); } + }, + Screens::ScreenListModes::LongPress + } { + + settingsController.SetAppMenu(0); + + } Clock::~Clock() { lv_obj_clean(lv_scr_act()); } -bool Clock::Refresh() { - batteryPercentRemaining = batteryController.PercentRemaining(); - if (batteryPercentRemaining.IsUpdated()) { - auto batteryPercent = batteryPercentRemaining.Get(); - lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); - auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent(); - lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging)); - } - - bleState = bleController.IsConnected(); - if (bleState.IsUpdated()) { - if(bleState.Get() == true) { - lv_label_set_text(bleIcon, BleIcon::GetIcon(true)); - } else { - lv_label_set_text(bleIcon, BleIcon::GetIcon(false)); - } - } - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 5); - lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); - lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); - - notificationState = notificatioManager.AreNewNotificationsAvailable(); - if(notificationState.IsUpdated()) { - if(notificationState.Get() == true) - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true)); - else - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); - } - - currentDateTime = dateTimeController.CurrentDateTime(); - - if(currentDateTime.IsUpdated()) { - auto newDateTime = currentDateTime.Get(); - - auto dp = date::floor(newDateTime); - auto time = date::make_time(newDateTime-dp); - auto yearMonthDay = date::year_month_day(dp); - - auto year = (int)yearMonthDay.year(); - auto month = static_cast((unsigned)yearMonthDay.month()); - auto day = (unsigned)yearMonthDay.day(); - auto dayOfWeek = static_cast(date::weekday(yearMonthDay).iso_encoding()); - - auto hour = time.hours().count(); - auto minute = time.minutes().count(); - - char minutesChar[3]; - sprintf(minutesChar, "%02d", static_cast(minute)); - - char hoursChar[3]; - sprintf(hoursChar, "%02d", static_cast(hour)); - - char timeStr[6]; - sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); - - if(hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] || minutesChar[1] != displayedChar[3]) { - displayedChar[0] = hoursChar[0]; - displayedChar[1] = hoursChar[1]; - displayedChar[2] = minutesChar[0]; - displayedChar[3] = minutesChar[1]; - - lv_label_set_text(label_time, timeStr); - } - - if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - char dateStr[22]; - sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(dayOfWeek), day, MonthToString(month), year); - lv_label_set_text(label_date, dateStr); - - - currentYear = year; - currentMonth = month; - currentDayOfWeek = dayOfWeek; - currentDay = day; - } - } - - heartbeat = heartRateController.HeartRate(); - heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped; - if(heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) { - char heartbeatBuffer[4]; - if(heartbeatRunning.Get()) - sprintf(heartbeatBuffer, "%d", heartbeat.Get()); - else - sprintf(heartbeatBuffer, "---"); - - lv_label_set_text(heartbeatValue, heartbeatBuffer); - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); - lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - } - - // TODO stepCount = stepController.GetValue(); - if(stepCount.IsUpdated()) { - char stepBuffer[5]; - sprintf(stepBuffer, "%lu", stepCount.Get()); - lv_label_set_text(stepValue, stepBuffer); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); - lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); - } +bool Clock::Refresh() { + screens.Refresh(); return running; } -const char *Clock::MonthToString(Pinetime::Controllers::DateTime::Months month) { - return Clock::MonthsString[static_cast(month)]; +bool Clock::OnButtonPushed() { + running = false; + return false; } -const char *Clock::DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek) { - return Clock::DaysString[static_cast(dayOfWeek)]; +bool Clock::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); } -char const *Clock::DaysString[] = { - "", - "MONDAY", - "TUESDAY", - "WEDNESDAY", - "THURSDAY", - "FRIDAY", - "SATURDAY", - "SUNDAY" -}; - -char const *Clock::MonthsString[] = { - "", - "JAN", - "FEB", - "MAR", - "APR", - "MAY", - "JUN", - "JUL", - "AUG", - "SEP", - "OCT", - "NOV", - "DEC" -}; - -void Clock::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { - if(obj == backgroundLabel) { - if (event == LV_EVENT_CLICKED) { - - running = false; - } - } +std::unique_ptr Clock::WatchFaceDigitalScreen() { + return std::unique_ptr(new Screens::WatchFaceDigital(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController, heartRateController)); } -bool Clock::OnButtonPushed() { - running = false; - return false; +std::unique_ptr Clock::WatchFaceAnalogScreen() { + return std::unique_ptr(new Screens::WatchFaceAnalog(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController)); } +/* +// examples +std::unique_ptr Clock::WatchFaceMinimalScreen() { + return std::unique_ptr(new Screens::WatchFaceMinimal(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController)); +} +std::unique_ptr Clock::WatchFaceCustomScreen() { + return std::unique_ptr(new Screens::WatchFaceCustom(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController)); +} +*/ \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 3d6e8c3bebbdaafa764b06ebc2769f2eaac05298 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sat, 6 Mar 2021 19:55:36 +0000 Subject: Merge from upstream --- README.md | 4 +++- images/0.14.0/collage1.png | Bin 0 -> 621336 bytes images/0.14.0/collage2.png | Bin 0 -> 639600 bytes images/infinitime-logo-github.jpg | Bin 0 -> 37430 bytes src/CMakeLists.txt | 29 ++++++++++++++++++++--------- src/displayapp/screens/Clock.cpp | 3 ++- 6 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 images/0.14.0/collage1.png create mode 100644 images/0.14.0/collage2.png create mode 100644 images/infinitime-logo-github.jpg (limited to 'src/displayapp/screens/Clock.cpp') diff --git a/README.md b/README.md index 929d3404..3f89ec7d 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ The goal of this project is to design an open-source firmware for the Pinetime s ## Overview -![Pinetime screens](images/0.7.0/montage.jpg "PinetimeScreens") +![Pinetime screens](images/0.14.0/collage1.png "PinetimeScreens") +![Pinetime screens](images/0.14.0/collage2.png "PinetimeScreens") As of now, here is the list of achievements of this project: @@ -46,6 +47,7 @@ As of now, here is the list of achievements of this project: - Supported by 2 companion apps (development is in progress): * [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/) (on Android) * [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux) + * **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY) - **[Experimental]** OTA (Over-the-air) update via BLE - **[Experimental]** Bootloader based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/) diff --git a/images/0.14.0/collage1.png b/images/0.14.0/collage1.png new file mode 100644 index 00000000..fd5f27ba Binary files /dev/null and b/images/0.14.0/collage1.png differ diff --git a/images/0.14.0/collage2.png b/images/0.14.0/collage2.png new file mode 100644 index 00000000..293147dd Binary files /dev/null and b/images/0.14.0/collage2.png differ diff --git a/images/infinitime-logo-github.jpg b/images/infinitime-logo-github.jpg new file mode 100644 index 00000000..cf19e35c Binary files /dev/null and b/images/infinitime-logo-github.jpg differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6029f142..e26b52f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,17 @@ cmake_minimum_required(VERSION 3.10) project(pinetime-app C CXX ASM) + +set(CMAKE_C_STANDARD 99) +set(CMAKE_CXX_STANDARD 14) + +# set(CMAKE_GENERATOR "Unix Makefiles") +set(CMAKE_C_EXTENSIONS OFF) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + # define some variables just for this example to determine file locations set(NRF_PROJECT_NAME pinetime-app) set(NRF_BOARD pca10040) @@ -760,7 +771,7 @@ target_compile_options(nrf-sdk PRIVATE $<$,$>: ${COMMON_FLAGS} -O3> $<$,$>: ${COMMON_FLAGS} -O0> $<$,$>: ${COMMON_FLAGS} -O3> - $<$: -MP -MD -std=c99 -x assembler-with-cpp> + $<$: -MP -MD -x assembler-with-cpp> ) # NimBLE @@ -772,7 +783,7 @@ target_compile_options(nimble PRIVATE $<$,$>: ${COMMON_FLAGS} -O3 -Wno-unused-but-set-variable -Wno-maybe-uninitialized> $<$,$>: ${COMMON_FLAGS} -O0 -g3 -Wno-unused-but-set-variable -Wno-maybe-uninitialized> $<$,$>: ${COMMON_FLAGS} -O3 -Wno-unused-but-set-variable -Wno-maybe-uninitialized> - $<$: -MP -MD -std=c99 -x assembler-with-cpp> + $<$: -MP -MD -x assembler-with-cpp> ) # lvgl @@ -784,7 +795,7 @@ target_compile_options(lvgl PRIVATE $<$,$>: ${COMMON_FLAGS} -O3> $<$,$>: ${COMMON_FLAGS} -O0 -g3> $<$,$>: ${COMMON_FLAGS} -O3> - $<$: -MP -MD -std=c99 -x assembler-with-cpp> + $<$: -MP -MD -x assembler-with-cpp> ) # Build autonomous binary (without support for bootloader) @@ -799,12 +810,12 @@ target_compile_options(${EXECUTABLE_NAME} PUBLIC $<$,$>: ${COMMON_FLAGS} -O3> $<$,$>: ${COMMON_FLAGS} -O0 -g3> $<$,$>: ${COMMON_FLAGS} -O3> - $<$: -MP -MD -std=c99 -x assembler-with-cpp> + $<$: -MP -MD -x assembler-with-cpp> ) set_target_properties(${EXECUTABLE_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map" CXX_STANDARD 11 C_STANDARD 99 ) @@ -831,12 +842,12 @@ target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC $<$,$>: ${COMMON_FLAGS} -O3> $<$,$>: ${COMMON_FLAGS} -O0 -g3> $<$,$>: ${COMMON_FLAGS} -O3> - $<$: -MP -MD -std=c99 -x assembler-with-cpp> + $<$: -MP -MD -x assembler-with-cpp> ) set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map" CXX_STANDARD 11 C_STANDARD 99 ) @@ -860,12 +871,12 @@ target_compile_options(${EXECUTABLE_GRAPHICS_NAME} PUBLIC $<$,$>: ${COMMON_FLAGS} -O3> $<$,$>: ${COMMON_FLAGS} -O0 -g3> $<$,$>: ${COMMON_FLAGS} -O3> - $<$: -MP -MD -std=c99 -x assembler-with-cpp> + $<$: -MP -MD -x assembler-with-cpp> ) set_target_properties(${EXECUTABLE_GRAPHICS_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map" CXX_STANDARD 11 C_STANDARD 99 ) diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index ea9ddd56..342dd222 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -33,6 +33,7 @@ Clock::Clock(DisplayApp* app, { [this]() -> std::unique_ptr { return WatchFaceDigitalScreen(); }, [this]() -> std::unique_ptr { return WatchFaceAnalogScreen(); }, + // Examples for more watch faces //[this]() -> std::unique_ptr { return WatchFaceMinimalScreen(); }, //[this]() -> std::unique_ptr { return WatchFaceCustomScreen(); } }, @@ -71,7 +72,7 @@ std::unique_ptr Clock::WatchFaceAnalogScreen() { } /* -// examples +// Examples for more watch faces std::unique_ptr Clock::WatchFaceMinimalScreen() { return std::unique_ptr(new Screens::WatchFaceMinimal(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController)); } -- cgit v1.2.3-70-g09d2