diff options
| author | JF <jf@codingfield.com> | 2021-09-02 18:35:56 (GMT) |
|---|---|---|
| committer | Gitea <gitea@fake.local> | 2021-09-02 18:35:56 (GMT) |
| commit | 6c3d6fb2575888e582e7ef3004a0bc3bf6c588b6 (patch) | |
| tree | ac396c060b423dd98fd915e742c14fc457a6f6d9 /src | |
| parent | db6a701644116932f11c54ee0f619464de9faeb7 (diff) | |
| parent | 6f9f0e8b0e42a5526d47ca664534fb6b0ccb6ace (diff) | |
Merge branch 'develop' of JF/PineTime into master
Diffstat (limited to 'src')
105 files changed, 1562 insertions, 1206 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40e1f2a..a724290 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -418,6 +418,7 @@ list(APPEND SOURCE_FILES displayapp/screens/BatteryInfo.cpp displayapp/screens/Steps.cpp displayapp/screens/Timer.cpp + displayapp/Colors.cpp ## Settings displayapp/screens/settings/QuickSettings.cpp @@ -427,6 +428,7 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingWakeUp.cpp displayapp/screens/settings/SettingDisplay.cpp displayapp/screens/settings/SettingSteps.cpp + displayapp/screens/settings/SettingPineTimeStyle.cpp ## Watch faces displayapp/icons/bg_clock.c @@ -495,6 +497,8 @@ list(APPEND SOURCE_FILES components/heartrate/Biquad.cpp components/heartrate/Ptagc.cpp components/heartrate/HeartRateController.cpp + + touchhandler/TouchHandler.cpp ) list(APPEND RECOVERY_SOURCE_FILES @@ -552,6 +556,7 @@ list(APPEND RECOVERY_SOURCE_FILES components/heartrate/Ptagc.cpp components/motor/MotorController.cpp components/fs/FS.cpp + touchhandler/TouchHandler.cpp ) list(APPEND RECOVERYLOADER_SOURCE_FILES @@ -607,6 +612,7 @@ set(INCLUDE_FILES displayapp/screens/Metronome.h displayapp/screens/Motion.h displayapp/screens/Timer.h + displayapp/Colors.h drivers/St7789.h drivers/SpiNorFlash.h drivers/SpiMaster.h @@ -660,6 +666,7 @@ set(INCLUDE_FILES components/heartrate/Ptagc.h components/heartrate/HeartRateController.h components/motor/MotorController.h + touchhandler/TouchHandler.h ) include_directories( @@ -839,7 +846,7 @@ target_compile_options(${EXECUTABLE_NAME} PUBLIC set_target_properties(${EXECUTABLE_NAME} PROPERTIES SUFFIX ".out" - 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" + 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 -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_NAME} @@ -869,7 +876,7 @@ target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES SUFFIX ".out" - 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" + 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 -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME} @@ -906,7 +913,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES SUFFIX ".out" - 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_RECOVERY_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 -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME} @@ -936,7 +943,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES SUFFIX ".out" - 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" + 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 -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME} @@ -977,7 +984,7 @@ add_dependencies(${EXECUTABLE_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY_MCUBOOT set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES SUFFIX ".out" - 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_RECOVERYLOADER_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 -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME} @@ -1010,7 +1017,7 @@ add_dependencies(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_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_RECOVERYLOADER_FILE_NAME}.map" + 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 -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index fa476ea..f8a64ec 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -23,7 +23,6 @@ void Battery::Update() { return; } // Non blocking read - samples = 0; isReading = true; SaadcInit(); @@ -40,9 +39,9 @@ void Battery::SaadcInit() { nrf_saadc_channel_config_t adcChannelConfig = {.resistor_p = NRF_SAADC_RESISTOR_DISABLED, .resistor_n = NRF_SAADC_RESISTOR_DISABLED, - .gain = NRF_SAADC_GAIN1_5, + .gain = NRF_SAADC_GAIN1_4, .reference = NRF_SAADC_REFERENCE_INTERNAL, - .acq_time = NRF_SAADC_ACQTIME_3US, + .acq_time = NRF_SAADC_ACQTIME_40US, .mode = NRF_SAADC_MODE_SINGLE_ENDED, .burst = NRF_SAADC_BURST_ENABLED, .pin_p = batteryVoltageAdcInput, @@ -60,22 +59,21 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); // A hardware voltage divider divides the battery voltage by 2 - // ADC gain is 1/5 - // thus adc_voltage = battery_voltage / 2 * gain = battery_voltage / 10 - // reference_voltage is 0.6V + // ADC gain is 1/4 + // thus adc_voltage = battery_voltage / 2 * gain = battery_voltage / 8 + // reference_voltage is 600mV // p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024 - voltage = p_event->data.done.p_buffer[0] * 6000 / 1024; - percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min); - percentRemaining = std::max(percentRemaining, 0); - percentRemaining = std::min(percentRemaining, 100); - percentRemainingBuffer.Insert(percentRemaining); - - samples++; - if (samples > percentRemainingSamples) { - nrfx_saadc_uninit(); - isReading = false; + voltage = p_event->data.done.p_buffer[0] * (8 * 600) / 1024; + + if (voltage > battery_max) { + percentRemaining = 100; + } else if (voltage < battery_min) { + percentRemaining = 0; } else { - nrfx_saadc_sample(); + percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min); } + + nrfx_saadc_uninit(); + isReading = false; } } diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 1333ad0..6f09b73 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -7,38 +7,6 @@ namespace Pinetime { namespace Controllers { - /** A simple circular buffer that can be used to average - out the sensor values. The total capacity of the CircBuffer - is given as the template parameter N. - */ - template <int N> class CircBuffer { - public: - CircBuffer() : arr {}, sz {}, cap {N}, head {} { - } - /** - insert member function overwrites the next data to the current - HEAD and moves the HEAD to the newly inserted value. - */ - void Insert(const uint8_t num) { - head %= cap; - arr[head++] = num; - if (sz != cap) { - sz++; - } - } - - uint8_t GetAverage() const { - int sum = std::accumulate(arr.begin(), arr.end(), 0); - return static_cast<uint8_t>(sum / sz); - } - - private: - std::array<uint8_t, N> arr; /**< internal array used to store the values*/ - uint8_t sz; /**< The current size of the array.*/ - uint8_t cap; /**< Total capacity of the CircBuffer.*/ - uint8_t head; /**< The current head of the CircBuffer*/ - }; - class Battery { public: Battery(); @@ -47,10 +15,7 @@ namespace Pinetime { void Update(); uint8_t PercentRemaining() const { - auto avg = percentRemainingBuffer.GetAverage(); - avg = std::min(avg, static_cast<uint8_t>(100)); - avg = std::max(avg, static_cast<uint8_t>(0)); - return avg; + return percentRemaining; } uint16_t Voltage() const { @@ -69,14 +34,11 @@ namespace Pinetime { static Battery* instance; nrf_saadc_value_t saadc_value; - static constexpr uint8_t percentRemainingSamples = 5; - CircBuffer<percentRemainingSamples> percentRemainingBuffer {}; - static constexpr uint32_t chargingPin = 12; static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; uint16_t voltage = 0; - int percentRemaining = -1; + uint8_t percentRemaining = 0; bool isCharging = false; bool isPowerPresent = false; @@ -87,7 +49,6 @@ namespace Pinetime { static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); bool isReading = false; - uint8_t samples = 0; }; } } diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 28a70ab..d6aa83c 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -55,9 +55,9 @@ void DateTime::UpdateTime(uint32_t systickCounter) { auto time = date::make_time(currentDateTime - dp); auto yearMonthDay = date::year_month_day(dp); - year = (int) yearMonthDay.year(); - month = static_cast<Months>((unsigned) yearMonthDay.month()); - day = (unsigned) yearMonthDay.day(); + year = static_cast<int>(yearMonthDay.year()); + month = static_cast<Months>(static_cast<unsigned>(yearMonthDay.month())); + day = static_cast<unsigned>(yearMonthDay.day()); dayOfWeek = static_cast<Days>(date::weekday(yearMonthDay).iso_encoding()); hour = time.hours().count(); @@ -75,31 +75,31 @@ void DateTime::UpdateTime(uint32_t systickCounter) { } const char* DateTime::MonthShortToString() { - return DateTime::MonthsString[(uint8_t) month]; + return DateTime::MonthsString[static_cast<uint8_t>(month)]; } const char* DateTime::MonthShortToStringLow() { - return DateTime::MonthsStringLow[(uint8_t) month]; + return DateTime::MonthsStringLow[static_cast<uint8_t>(month)]; } const char* DateTime::MonthsToStringLow() { - return DateTime::MonthsLow[(uint8_t) month]; + return DateTime::MonthsLow[static_cast<uint8_t>(month)]; } const char* DateTime::DayOfWeekToString() { - return DateTime::DaysString[(uint8_t) dayOfWeek]; + return DateTime::DaysString[static_cast<uint8_t>(dayOfWeek)]; } const char* DateTime::DayOfWeekShortToString() { - return DateTime::DaysStringShort[(uint8_t) dayOfWeek]; + return DateTime::DaysStringShort[static_cast<uint8_t>(dayOfWeek)]; } const char* DateTime::DayOfWeekToStringLow() { - return DateTime::DaysStringLow[(uint8_t) dayOfWeek]; + return DateTime::DaysStringLow[static_cast<uint8_t>(dayOfWeek)]; } const char* DateTime::DayOfWeekShortToStringLow() { - return DateTime::DaysStringShortLow[(uint8_t) dayOfWeek]; + return DateTime::DaysStringShortLow[static_cast<uint8_t>(dayOfWeek)]; } void DateTime::Register(Pinetime::System::SystemTask* systemTask) { diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 3afa0ce..b25e6bc 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -3,7 +3,8 @@ #include "systemtask/SystemTask.h" #include "app_timer.h" -APP_TIMER_DEF(vibTimer); +APP_TIMER_DEF(shortVibTimer); +APP_TIMER_DEF(longVibTimer); using namespace Pinetime::Controllers; @@ -13,19 +14,39 @@ MotorController::MotorController(Controllers::Settings& settingsController) : se void MotorController::Init() { nrf_gpio_cfg_output(pinMotor); nrf_gpio_pin_set(pinMotor); - app_timer_create(&vibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate); + app_timer_init(); + + app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, StopMotor); + app_timer_create(&longVibTimer, APP_TIMER_MODE_REPEATED, Ring); } -void MotorController::SetDuration(uint8_t motorDuration) { +void MotorController::Ring(void* p_context) { + auto* motorController = static_cast<MotorController*>(p_context); + motorController->RunForDuration(50); +} - if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) +void MotorController::RunForDuration(uint8_t motorDuration) { + if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) { return; + } nrf_gpio_pin_clear(pinMotor); - /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ - app_timer_start(vibTimer, APP_TIMER_TICKS(motorDuration), NULL); + app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); +} + +void MotorController::StartRinging() { + if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) { + return; + } + Ring(this); + app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); } -void MotorController::vibrate(void* p_context) { +void MotorController::StopRinging() { + app_timer_stop(longVibTimer); nrf_gpio_pin_set(pinMotor); -}
\ No newline at end of file +} + +void MotorController::StopMotor(void* p_context) { + nrf_gpio_pin_set(pinMotor); +} diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index df61af7..d2c9fe5 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -12,11 +12,14 @@ namespace Pinetime { public: MotorController(Controllers::Settings& settingsController); void Init(); - void SetDuration(uint8_t motorDuration); + void RunForDuration(uint8_t motorDuration); + void StartRinging(); + static void StopRinging(); private: + static void Ring(void* p_context); Controllers::Settings& settingsController; - static void vibrate(void* p_context); + static void StopMotor(void* p_context); }; } } diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 93d6d21..a294ab7 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -17,6 +17,14 @@ namespace Pinetime { DoubleTap = 1, RaiseWrist = 2, }; + enum class Colors : uint8_t { + White, Silver, Gray, Black, Red, Maroon, Yellow, Olive, Lime, Green, Cyan, Teal, Blue, Navy, Magenta, Purple, Orange + }; + struct PineTimeStyle { + Colors ColorTime = Colors::Teal; + Colors ColorBar = Colors::Teal; + Colors ColorBG = Colors::Black; + }; Settings(Pinetime::Controllers::FS& fs); @@ -33,10 +41,38 @@ namespace Pinetime { return settings.clockFace; }; + void SetPTSColorTime(Colors colorTime) { + if (colorTime != settings.PTS.ColorTime) + settingsChanged = true; + settings.PTS.ColorTime = colorTime; + }; + Colors GetPTSColorTime() const { + return settings.PTS.ColorTime; + }; + + void SetPTSColorBar(Colors colorBar) { + if (colorBar != settings.PTS.ColorBar) + settingsChanged = true; + settings.PTS.ColorBar = colorBar; + }; + Colors GetPTSColorBar() const { + return settings.PTS.ColorBar; + }; + + void SetPTSColorBG(Colors colorBG) { + if (colorBG != settings.PTS.ColorBG) + settingsChanged = true; + settings.PTS.ColorBG = colorBG; + }; + Colors GetPTSColorBG() const { + return settings.PTS.ColorBG; + }; + void SetAppMenu(uint8_t menu) { appMenu = menu; }; - uint8_t GetAppMenu() { + + uint8_t GetAppMenu() const { return appMenu; }; @@ -127,9 +163,8 @@ namespace Pinetime { private: Pinetime::Controllers::FS& fs; - static constexpr uint32_t settingsVersion = 0x0001; + static constexpr uint32_t settingsVersion = 0x0002; struct SettingsData { - uint32_t version = settingsVersion; uint32_t stepsGoal = 10000; uint32_t screenTimeOut = 15000; @@ -139,6 +174,8 @@ namespace Pinetime { uint8_t clockFace = 0; + PineTimeStyle PTS; + std::bitset<3> wakeUpMode {0}; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index 684e3a4..dd51fdb 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -30,7 +30,8 @@ namespace Pinetime { SettingTimeFormat, SettingDisplay, SettingWakeUp, - SettingSteps + SettingSteps, + SettingPineTimeStyle }; } } diff --git a/src/displayapp/Colors.cpp b/src/displayapp/Colors.cpp new file mode 100644 index 0000000..f45f072 --- /dev/null +++ b/src/displayapp/Colors.cpp @@ -0,0 +1,27 @@ +#include "Colors.h" + +using namespace Pinetime::Applications; +using namespace Pinetime::Controllers; + +lv_color_t Pinetime::Applications::Convert(Pinetime::Controllers::Settings::Colors color) { + switch (color) { + case Pinetime::Controllers::Settings::Colors::White: return LV_COLOR_WHITE; + case Pinetime::Controllers::Settings::Colors::Silver: return LV_COLOR_SILVER; + case Pinetime::Controllers::Settings::Colors::Gray: return LV_COLOR_GRAY; + case Pinetime::Controllers::Settings::Colors::Black: return LV_COLOR_BLACK; + case Pinetime::Controllers::Settings::Colors::Red: return LV_COLOR_RED; + case Pinetime::Controllers::Settings::Colors::Maroon: return LV_COLOR_MAROON; + case Pinetime::Controllers::Settings::Colors::Yellow: return LV_COLOR_YELLOW; + case Pinetime::Controllers::Settings::Colors::Olive: return LV_COLOR_OLIVE; + case Pinetime::Controllers::Settings::Colors::Lime: return LV_COLOR_LIME; + case Pinetime::Controllers::Settings::Colors::Green: return LV_COLOR_GREEN; + case Pinetime::Controllers::Settings::Colors::Cyan: return LV_COLOR_CYAN; + case Pinetime::Controllers::Settings::Colors::Teal: return LV_COLOR_TEAL; + case Pinetime::Controllers::Settings::Colors::Blue: return LV_COLOR_BLUE; + case Pinetime::Controllers::Settings::Colors::Navy: return LV_COLOR_NAVY; + case Pinetime::Controllers::Settings::Colors::Magenta: return LV_COLOR_MAGENTA; + case Pinetime::Controllers::Settings::Colors::Purple: return LV_COLOR_PURPLE; + case Pinetime::Controllers::Settings::Colors::Orange: return LV_COLOR_ORANGE; + default: return LV_COLOR_WHITE; + } +} diff --git a/src/displayapp/Colors.h b/src/displayapp/Colors.h new file mode 100644 index 0000000..9db7dd2 --- /dev/null +++ b/src/displayapp/Colors.h @@ -0,0 +1,10 @@ +#pragma once + +#include <lvgl/src/lv_misc/lv_color.h> +#include <components/settings/Settings.h> + +namespace Pinetime { + namespace Applications { + lv_color_t Convert(Controllers::Settings::Colors color); + } +}
\ No newline at end of file diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 4d32a7e..d6100ec 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -42,6 +42,7 @@ #include "displayapp/screens/settings/SettingWakeUp.h" #include "displayapp/screens/settings/SettingDisplay.h" #include "displayapp/screens/settings/SettingSteps.h" +#include "displayapp/screens/settings/SettingPineTimeStyle.h" #include "libs/lv_conf.h" @@ -52,6 +53,28 @@ namespace { static inline bool in_isr(void) { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; } + + TouchEvents ConvertGesture(Pinetime::Drivers::Cst816S::Gestures gesture) { + switch (gesture) { + case Pinetime::Drivers::Cst816S::Gestures::SingleTap: + return TouchEvents::Tap; + case Pinetime::Drivers::Cst816S::Gestures::LongPress: + return TouchEvents::LongTap; + case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: + return TouchEvents::DoubleTap; + case Pinetime::Drivers::Cst816S::Gestures::SlideRight: + return TouchEvents::SwipeRight; + case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: + return TouchEvents::SwipeLeft; + case Pinetime::Drivers::Cst816S::Gestures::SlideDown: + return TouchEvents::SwipeDown; + case Pinetime::Drivers::Cst816S::Gestures::SlideUp: + return TouchEvents::SwipeUp; + case Pinetime::Drivers::Cst816S::Gestures::None: + default: + return TouchEvents::None; + } + } } DisplayApp::DisplayApp(Drivers::St7789& lcd, @@ -66,7 +89,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController) + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler) : lcd {lcd}, lvgl {lvgl}, touchPanel {touchPanel}, @@ -79,7 +103,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, settingsController {settingsController}, motorController {motorController}, motionController {motionController}, - timerController {timerController} { + timerController {timerController}, + touchHandler {touchHandler} { } void DisplayApp::Start() { @@ -140,8 +165,15 @@ void DisplayApp::Refresh() { lastWakeTime = xTaskGetTickCount(); if (messageReceived) { switch (msg) { - case Messages::GoToSleep: + case Messages::DimScreen: + // Backup brightness is the brightness to return to after dimming or sleeping brightnessController.Backup(); + brightnessController.Set(Controllers::BrightnessController::Levels::Low); + break; + case Messages::RestoreBrightness: + brightnessController.Restore(); + break; + case Messages::GoToSleep: while (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { brightnessController.Lower(); vTaskDelay(100); @@ -170,7 +202,7 @@ void DisplayApp::Refresh() { break; case Messages::TimerDone: if (currentApp == Apps::Timer) { - auto *timer = static_cast<Screens::Timer*>(currentScreen.get()); + auto* timer = static_cast<Screens::Timer*>(currentScreen.get()); timer->setDone(); } else { LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down); @@ -180,7 +212,7 @@ void DisplayApp::Refresh() { if (state != States::Running) { break; } - auto gesture = OnTouchEvent(); + auto gesture = ConvertGesture(touchHandler.GestureGet()); if (gesture == TouchEvents::None) { break; } @@ -204,7 +236,11 @@ void DisplayApp::Refresh() { } } else if (returnTouchEvent == gesture) { LoadApp(returnToApp, returnDirection); + brightnessController.Set(settingsController.GetBrightness()); + brightnessController.Backup(); } + } else { + touchHandler.CancelTap(); } } break; case Messages::ButtonPushed: @@ -213,6 +249,8 @@ void DisplayApp::Refresh() { } else { if (!currentScreen->OnButtonPushed()) { LoadApp(returnToApp, returnDirection); + brightnessController.Set(settingsController.GetBrightness()); + brightnessController.Backup(); } } break; @@ -227,23 +265,18 @@ void DisplayApp::Refresh() { } } - if(nextApp != Apps::None) { + if (nextApp != Apps::None) { LoadApp(nextApp, nextDirection); nextApp = Apps::None; } - if (state != States::Idle && touchMode == TouchModes::Polling) { - auto info = touchPanel.GetTouchInfo(); - if (info.action == 2) { // 2 = contact - if (!currentScreen->OnTouchEvent(info.x, info.y)) { - lvgl.SetNewTapEvent(info.x, info.y); - } - } + if (touchHandler.IsTouching()) { + currentScreen->OnTouchEvent(touchHandler.GetX(), touchHandler.GetY()); } } void DisplayApp::RunningState() { - if (!currentScreen->Refresh()) { + if (!currentScreen->IsRunning()) { LoadApp(returnToApp, returnDirection); } lv_task_handler(); @@ -261,6 +294,7 @@ void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction } void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) { + touchHandler.CancelTap(); currentScreen.reset(nullptr); SetFullRefresh(direction); @@ -295,12 +329,12 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Notifications: currentScreen = std::make_unique<Screens::Notifications>( - this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Normal); + this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Normal); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::NotificationsPreview: currentScreen = std::make_unique<Screens::Notifications>( - this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Preview); + this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Preview); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::Timer: @@ -337,13 +371,17 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique<Screens::SettingSteps>(this, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; + case Apps::SettingPineTimeStyle: + currentScreen = std::make_unique<Screens::SettingPineTimeStyle>(this, settingsController); + ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); + break; case Apps::BatteryInfo: currentScreen = std::make_unique<Screens::BatteryInfo>(this, batteryController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SysInfo: - currentScreen = - std::make_unique<Screens::SystemInfo>(this, dateTimeController, batteryController, brightnessController, bleController, watchdog, motionController); + currentScreen = std::make_unique<Screens::SystemInfo>( + this, dateTimeController, batteryController, brightnessController, bleController, watchdog, motionController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::FlashLight: @@ -373,6 +411,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) break; case Apps::Metronome: currentScreen = std::make_unique<Screens::Metronome>(this, motorController, *systemTask); + ReturnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::Motion: currentScreen = std::make_unique<Screens::Motion>(this, motionController); @@ -388,7 +427,7 @@ void DisplayApp::IdleState() { } void DisplayApp::PushMessage(Messages msg) { - if(in_isr()) { + if (in_isr()) { BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(msgQueue, &msg, &xHigherPriorityTaskWoken); @@ -400,35 +439,6 @@ void DisplayApp::PushMessage(Messages msg) { } } -TouchEvents DisplayApp::OnTouchEvent() { - auto info = touchPanel.GetTouchInfo(); - if (info.isTouch) { - switch (info.gesture) { - case Pinetime::Drivers::Cst816S::Gestures::SingleTap: - if (touchMode == TouchModes::Gestures) { - lvgl.SetNewTapEvent(info.x, info.y); - } - return TouchEvents::Tap; - case Pinetime::Drivers::Cst816S::Gestures::LongPress: - return TouchEvents::LongTap; - case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: - return TouchEvents::DoubleTap; - case Pinetime::Drivers::Cst816S::Gestures::SlideRight: - return TouchEvents::SwipeRight; - case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: - return TouchEvents::SwipeLeft; - case Pinetime::Drivers::Cst816S::Gestures::SlideDown: - return TouchEvents::SwipeDown; - case Pinetime::Drivers::Cst816S::Gestures::SlideUp: - return TouchEvents::SwipeUp; - case Pinetime::Drivers::Cst816S::Gestures::None: - default: - return TouchEvents::None; - } - } - return TouchEvents::None; -} - void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { switch (direction) { case DisplayApp::FullRefreshDirections::Down: @@ -454,12 +464,8 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { } } -void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) { - touchMode = mode; -} - void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) { - if(systemTask != nullptr) + if (systemTask != nullptr) systemTask->PushMessage(message); } diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index f4573ab..96951d1 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -14,6 +14,7 @@ #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" #include "components/timer/TimerController.h" +#include "touchhandler/TouchHandler.h" #include "Messages.h" namespace Pinetime { @@ -31,6 +32,7 @@ namespace Pinetime { class NotificationManager; class HeartRateController; class MotionController; + class TouchHandler; } namespace System { @@ -41,7 +43,6 @@ namespace Pinetime { public: enum class States { Idle, Running }; enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim }; - enum class TouchModes { Gestures, Polling }; DisplayApp(Drivers::St7789& lcd, Components::LittleVgl& lvgl, @@ -55,14 +56,14 @@ namespace Pinetime { Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController); + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler); void Start(); void PushMessage(Display::Messages msg); void StartApp(Apps app, DisplayApp::FullRefreshDirections direction); void SetFullRefresh(FullRefreshDirections direction); - void SetTouchMode(TouchModes mode); void Register(Pinetime::System::SystemTask* systemTask); @@ -81,6 +82,7 @@ namespace Pinetime { Pinetime::Controllers::MotorController& motorController; Pinetime::Controllers::MotionController& motionController; Pinetime::Controllers::TimerController& timerController; + Pinetime::Controllers::TouchHandler& touchHandler; Pinetime::Controllers::FirmwareValidator validator; Controllers::BrightnessController brightnessController; @@ -100,9 +102,7 @@ namespace Pinetime { FullRefreshDirections returnDirection = FullRefreshDirections::None; TouchEvents returnTouchEvent = TouchEvents::None; - TouchModes touchMode = TouchModes::Gestures; - - TouchEvents OnTouchEvent(); + TouchEvents GetGesture(); void RunningState(); void IdleState(); static void Process(void* instance); diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index fd517b1..17612ef 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -3,6 +3,7 @@ #include <task.h> #include <libraries/log/nrf_log.h> #include <components/rle/RleDecoder.h> +#include <touchhandler/TouchHandler.h> #include "displayapp/icons/infinitime/infinitime-nb.c" using namespace Pinetime::Applications; @@ -19,7 +20,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController) + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler) : lcd {lcd}, bleController {bleController} { } diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 638c007..8b2bc7f 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -29,6 +29,9 @@ namespace Pinetime { namespace System { class SystemTask; }; + namespace Controllers { + class TouchHandler; + } namespace Applications { class DisplayApp { public: @@ -44,7 +47,8 @@ namespace Pinetime { Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController); + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler); void Start(); void PushMessage(Pinetime::Applications::Display::Messages msg); void Register(Pinetime::System::SystemTask* systemTask); diff --git a/src/displayapp/DummyLittleVgl.h b/src/displayapp/DummyLittleVgl.h index 016165b..1db5134 100644 --- a/src/displayapp/DummyLittleVgl.h +++ b/src/displayapp/DummyLittleVgl.h @@ -32,6 +32,9 @@ namespace Pinetime { } void SetNewTapEvent(uint16_t x, uint16_t y) { } + void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) { + + } }; } } diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index c069afa..2bd5e57 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -166,43 +166,21 @@ void LittleVgl::FlushDisplay(const lv_area_t* area, lv_color_t* color_p) { lv_disp_flush_ready(&disp_drv); } -void LittleVgl::SetNewTapEvent(uint16_t x, uint16_t y) { +void LittleVgl::SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) { tap_x = x; tap_y = y; - tapped = true; + tapped = contact; } bool LittleVgl::GetTouchPadInfo(lv_indev_data_t* ptr) { + ptr->point.x = tap_x; + ptr->point.y = tap_y; if (tapped) { - ptr->point.x = tap_x; - ptr->point.y = tap_y; ptr->state = LV_INDEV_STATE_PR; - tapped = false; } else { ptr->state = LV_INDEV_STATE_REL; } return false; - /* - auto info = touchPanel.GetTouchInfo(); - - if((previousClick.x != info.x || previousClick.y != info.y) && - (info.gesture == Drivers::Cst816S::Gestures::SingleTap)) { - // TODO For an unknown reason, the first touch is taken twice into account. - // 'firstTouch' is a quite'n'dirty workaound until I find a better solution - if(firstTouch) ptr->state = LV_INDEV_STATE_REL; - else ptr->state = LV_INDEV_STATE_PR; - firstTouch = false; - previousClick.x = info.x; - previousClick.y = info.y; - } - else { - ptr->state = LV_INDEV_STATE_REL; - } - - ptr->point.x = info.x; - ptr->point.y = info.y; - return false; - */ } void LittleVgl::InitTheme() { diff --git a/src/displayapp/LittleVgl.h b/src/displayapp/LittleVgl.h index 41f934a..1f8a3d7 100644 --- a/src/displayapp/LittleVgl.h +++ b/src/displayapp/LittleVgl.h @@ -24,7 +24,7 @@ namespace Pinetime { void FlushDisplay(const lv_area_t* area, lv_color_t* color_p); bool GetTouchPadInfo(lv_indev_data_t* ptr); void SetFullRefresh(FullRefreshDirections direction); - void SetNewTapEvent(uint16_t x, uint16_t y); + void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact); private: void InitDisplay(); diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index ce65f84..322505e 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -13,8 +13,10 @@ namespace Pinetime { NewNotification, TimerDone, BleFirmwareUpdateStarted, - UpdateTimeOut + UpdateTimeOut, + DimScreen, + RestoreBrightness }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/fonts/README.md b/src/displayapp/fonts/README.md index ec4beb8..8a26084 100644 --- a/src/displayapp/fonts/README.md +++ b/src/displayapp/fonts/README.md @@ -13,7 +13,7 @@ * Do not enable font compression and horizontal subpixel hinting * Load the file `JetBrainsMono-Bold.tff` (use the file in this repo to ensure the version matches) and specify the following range : `0x20-0x7f, 0x410-0x44f` * Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following - range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569` + range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015` * Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts` * Add the font .c file path to src/CMakeLists.txt * Add an LV_FONT_DECLARE line in src/libs/lv_conf.h diff --git a/src/displayapp/fonts/jetbrains_mono_bold_20.c b/src/displayapp/fonts/jetbrains_mono_bold_20.c index 98243bb..d870552 100644 --- a/src/displayapp/fonts/jetbrains_mono_bold_20.c +++ b/src/displayapp/fonts/jetbrains_mono_bold_20.c @@ -734,6 +734,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xff, 0x7, 0xef, 0xf0, 0x10, 0xff, 0x0, 0x3, 0xc0, 0x0, + /* U+F015 "" */ + 0x0, 0x38, 0xe0, 0x0, 0xf9, 0xc0, 0x3, 0xfb, + 0x80, 0x1e, 0x3f, 0x0, 0x79, 0x3e, 0x1, 0xe7, + 0x3c, 0xf, 0x9f, 0xbc, 0x3c, 0xff, 0x9e, 0xf3, + 0xff, 0x9e, 0xcf, 0xff, 0x98, 0x3f, 0xff, 0x80, + 0x7f, 0xff, 0x0, 0xfc, 0x7e, 0x1, 0xf8, 0xfc, + 0x3, 0xf1, 0xf8, 0x7, 0xe3, 0xf0, 0xf, 0xc7, + 0xe0, + /* U+F017 "" */ 0x3, 0xf8, 0x1, 0xff, 0xc0, 0x7f, 0xfc, 0x1f, 0xff, 0xc7, 0xf1, 0xfc, 0xfe, 0x3f, 0x9f, 0xc7, @@ -823,6 +832,14 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xdf, 0x9e, 0x38, 0xf3, 0x7, 0x6, 0x0, 0xe0, 0x0, 0x1c, 0x0, 0x3, 0x80, 0x0, 0x70, 0x0, + /* U+F06E "" */ + 0x0, 0xfe, 0x0, 0xf, 0xff, 0x80, 0x3e, 0xf, + 0x80, 0xf8, 0xf, 0x83, 0xe3, 0x8f, 0x8f, 0x87, + 0x8f, 0xbf, 0x1f, 0x9f, 0xfe, 0xff, 0x3f, 0xfd, + 0xfe, 0x7e, 0xf9, 0xf8, 0xf8, 0xf9, 0xe3, 0xe0, + 0xf8, 0xf, 0x80, 0xf8, 0x3e, 0x0, 0xff, 0xf0, + 0x0, 0x3f, 0x80, 0x0, + /* U+F095 "" */ 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, 0x7, 0xf0, 0x0, 0x7f, 0x0, 0x7, 0xf0, 0x0, 0xff, 0x0, @@ -861,6 +878,13 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x1, 0xf8, 0x0, 0x9f, 0xc0, 0xf, 0xfc, 0x0, 0x7f, 0xc0, 0x7, 0xf8, 0x0, 0x1f, 0x0, 0x0, + /* U+F201 "" */ + 0x40, 0x0, 0x7, 0x0, 0x0, 0x38, 0x1, 0xf9, + 0xc0, 0x7, 0xce, 0x18, 0x1e, 0x71, 0xe1, 0xf3, + 0x9f, 0x9d, 0x9d, 0xff, 0xc4, 0xe6, 0x7c, 0x7, + 0x1, 0xc0, 0x38, 0x0, 0x1, 0xc0, 0x0, 0xe, + 0x0, 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe0, + /* U+F21E "" */ 0x1e, 0x7, 0x83, 0xf9, 0xfe, 0x7f, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfc, @@ -1182,42 +1206,45 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 2484, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, {.bitmap_index = 2498, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, {.bitmap_index = 2511, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2561, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2609, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2659, .adv_w = 240, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2688, .adv_w = 360, .box_w = 23, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2743, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2782, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2825, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 2853, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2901, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2940, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2979, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 3007, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3055, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3108, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3127, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3177, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3213, .adv_w = 320, .box_w = 20, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3261, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3304, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 3342, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 3380, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 3418, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 3456, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 3494, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3530, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 3568, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3597, .adv_w = 280, .box_w = 16, .box_h = 19, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 3635, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3701, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3750, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3800, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3860, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3913, .adv_w = 360, .box_w = 23, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3974, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 4029, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 4082, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0} + {.bitmap_index = 2561, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2610, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2658, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2708, .adv_w = 240, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2737, .adv_w = 360, .box_w = 23, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2792, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2831, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2874, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 2902, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2950, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2989, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3028, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3056, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3104, .adv_w = 360, .box_w = 23, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3148, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3201, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3220, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3270, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3306, .adv_w = 320, .box_w = 20, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3354, .adv_w = 320, .box_w = 21, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3394, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3437, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 3475, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 3513, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 3551, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 3589, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 3627, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3663, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 3701, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3730, .adv_w = 280, .box_w = 16, .box_h = 19, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 3768, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3834, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3883, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3933, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3993, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 4046, .adv_w = 360, .box_w = 23, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 4107, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4162, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4215, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0} }; /*--------------------- @@ -1225,11 +1252,11 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { *--------------------*/ static const uint16_t unicode_list_2[] = { - 0x0, 0x16, 0x23, 0x26, 0x27, 0x28, 0x39, 0x47, - 0x4a, 0x4b, 0x4c, 0x50, 0x68, 0x94, 0x128, 0x184, - 0x1e5, 0x1fb, 0x21d, 0x23f, 0x240, 0x241, 0x242, 0x243, - 0x251, 0x292, 0x293, 0x2f1, 0x3dc, 0x3fc, 0x45c, 0x54a, - 0x55f, 0x568, 0x59e, 0x59f, 0x6a8 + 0x0, 0x14, 0x16, 0x23, 0x26, 0x27, 0x28, 0x39, + 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x68, 0x6d, 0x94, + 0x128, 0x184, 0x1e5, 0x1fb, 0x200, 0x21d, 0x23f, 0x240, + 0x241, 0x242, 0x243, 0x251, 0x292, 0x293, 0x2f1, 0x3dc, + 0x3fc, 0x45c, 0x54a, 0x55f, 0x568, 0x59e, 0x59f, 0x6a8 }; /*Collect the unicode lists and glyph_id offsets*/ @@ -1245,7 +1272,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 61441, .range_length = 1705, .glyph_id_start = 160, - .unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 37, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 40, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 78c7cd9..6e7bbb7 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -34,12 +34,6 @@ ApplicationList::~ApplicationList() { lv_obj_clean(lv_scr_act()); } -bool ApplicationList::Refresh() { - if (running) - running = screens.Refresh(); - return running; -} - bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } @@ -62,7 +56,7 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen2() { {Symbols::paintbrush, Apps::Paint}, {Symbols::paddle, Apps::Paddle}, {"2", Apps::Twos}, - {"M", Apps::Motion}, + {Symbols::chartLine, Apps::Motion}, {Symbols::drum, Apps::Metronome}, {"", Apps::None}, }}; diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 88534ec..103c38a 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -18,7 +18,6 @@ namespace Pinetime { Pinetime::Controllers::Battery& batteryController, Controllers::DateTime& dateTimeController); ~ApplicationList() override; - bool Refresh() override; bool OnTouchEvent(TouchEvents event) override; private: @@ -33,4 +32,4 @@ namespace Pinetime { }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp index bb6626a..c67bcb2 100644 --- a/src/displayapp/screens/BatteryIcon.cpp +++ b/src/displayapp/screens/BatteryIcon.cpp @@ -5,13 +5,13 @@ using namespace Pinetime::Applications::Screens; const char* BatteryIcon::GetBatteryIcon(uint8_t batteryPercent) { - if (batteryPercent > 90) + if (batteryPercent > 87) return Symbols::batteryFull; - if (batteryPercent > 75) + if (batteryPercent > 62) return Symbols::batteryThreeQuarter; - if (batteryPercent > 50) + if (batteryPercent > 37) return Symbols::batteryHalf; - if (batteryPercent > 25) + if (batteryPercent > 12) return Symbols::batteryOneQuarter; return Symbols::batteryEmpty; } diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 0ab47eb..91c2651 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -4,11 +4,6 @@ using namespace Pinetime::Applications::Screens; -static void lv_update_task(struct _lv_task_t* task) { - auto user_data = static_cast<BatteryInfo*>(task->user_data); - user_data->UpdateScreen(); -} - BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Battery& batteryController) : Screen(app), batteryController {batteryController} { @@ -49,16 +44,16 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text_static(backgroundLabel, ""); - taskUpdate = lv_task_create(lv_update_task, 5000, LV_TASK_PRIO_LOW, this); - UpdateScreen(); + taskRefresh = lv_task_create(RefreshTaskCallback, 5000, LV_TASK_PRIO_MID, this); + Refresh(); } BatteryInfo::~BatteryInfo() { - lv_task_del(taskUpdate); + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -void BatteryInfo::UpdateScreen() { +void BatteryInfo::Refresh() { batteryController.Update(); @@ -85,7 +80,3 @@ void BatteryInfo::UpdateScreen() { lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10); lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_ON); } - -bool BatteryInfo::Refresh() { - return running; -} diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h index 6979324..63454a2 100644 --- a/src/displayapp/screens/BatteryInfo.h +++ b/src/displayapp/screens/BatteryInfo.h @@ -19,9 +19,7 @@ namespace Pinetime { BatteryInfo(DisplayApp* app, Pinetime::Controllers::Battery& batteryController); ~BatteryInfo() override; - bool Refresh() override; - - void UpdateScreen(); + void Refresh() override; private: Pinetime::Controllers::Battery& batteryController; @@ -31,7 +29,7 @@ namespace Pinetime { lv_obj_t* charging_bar; lv_obj_t* status; - lv_task_t* taskUpdate; + lv_task_t* taskRefresh; uint8_t batteryPercent = 0; uint16_t batteryVoltage = 0; diff --git a/src/displayapp/screens/Brightness.cpp b/src/displayapp/screens/Brightness.cpp index 47c1056..1278cd6 100644 --- a/src/displayapp/screens/Brightness.cpp +++ b/src/displayapp/screens/Brightness.cpp @@ -30,10 +30,6 @@ Brightness::~Brightness() { lv_obj_clean(lv_scr_act()); } -bool Brightness::Refresh() { - return running; -} - const char* Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) { switch (level) { case Pinetime::Controllers::BrightnessController::Levels::Off: diff --git a/src/displayapp/screens/Brightness.h b/src/displayapp/screens/Brightness.h index 9ee3375..14e4859 100644 --- a/src/displayapp/screens/Brightness.h +++ b/src/displayapp/screens/Brightness.h @@ -12,7 +12,6 @@ namespace Pinetime { public: Brightness(DisplayApp* app, Controllers::BrightnessController& brightness); ~Brightness() override; - bool Refresh() override; bool OnTouchEvent(TouchEvents event) override; @@ -31,4 +30,4 @@ namespace Pinetime { }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index e068497..5a5cd18 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -2,11 +2,6 @@ #include <date/date.h> #include <lvgl/lvgl.h> -#include <cstdio> -#include "BatteryIcon.h" -#include "BleIcon.h" -#include "NotificationIcon.h" -#include "Symbols.h" #include "components/battery/BatteryController.h" #include "components/motion/MotionController.h" #include "components/ble/BleController.h" @@ -55,11 +50,6 @@ Clock::~Clock() { lv_obj_clean(lv_scr_act()); } -bool Clock::Refresh() { - screen->Refresh(); - return running; -} - bool Clock::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screen->OnTouchEvent(event); } @@ -89,16 +79,3 @@ std::unique_ptr<Screen> Clock::PineTimeStyleScreen() { settingsController, motionController); } - -/* -// Examples for more watch faces -std::unique_ptr<Screen> Clock::WatchFaceMinimalScreen() { - return std::make_unique<Screens::WatchFaceMinimal>(app, dateTimeController, batteryController, bleController, notificatioManager, -settingsController); -} - -std::unique_ptr<Screen> Clock::WatchFaceCustomScreen() { - return std::make_unique<Screens::WatchFaceCustom>(app, dateTimeController, batteryController, bleController, notificatioManager, -settingsController); -} -*/
\ No newline at end of file diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index a48feea..648f72d 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -9,9 +9,6 @@ #include "components/datetime/DateTimeController.h" namespace Pinetime { - namespace Drivers { - class BMA421; - } namespace Controllers { class Settings; class Battery; @@ -34,8 +31,6 @@ namespace Pinetime { Controllers::MotionController& motionController); ~Clock() override; - bool Refresh() override; - bool OnTouchEvent(TouchEvents event) override; private: @@ -51,10 +46,6 @@ namespace Pinetime { std::unique_ptr<Screen> WatchFaceDigitalScreen(); std::unique_ptr<Screen> WatchFaceAnalogScreen(); std::unique_ptr<Screen> PineTimeStyleScreen(); - - // Examples for more watch faces - // std::unique_ptr<Screen> WatchFaceMinimalScreen(); - // std::unique_ptr<Screen> WatchFaceCustomScreen(); }; } } diff --git a/src/displayapp/screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp index edb2e49..79bda0b 100644 --- a/src/displayapp/screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -30,14 +30,16 @@ FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp* app, Pinetime lv_label_set_text(percentLabel, "Waiting..."); lv_obj_set_auto_realign(percentLabel, true); lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); startTime = xTaskGetTickCount(); } FirmwareUpdate::~FirmwareUpdate() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool FirmwareUpdate::Refresh() { +void FirmwareUpdate::Refresh() { switch (bleController.State()) { default: case Pinetime::Controllers::Ble::FirmwareUpdateStates::Idle: @@ -73,7 +75,6 @@ bool FirmwareUpdate::Refresh() { } break; } - return running; } void FirmwareUpdate::DisplayProgression() const { diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index 90c99f4..8fc86d8 100644 --- a/src/displayapp/screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -16,7 +16,7 @@ namespace Pinetime { FirmwareUpdate(DisplayApp* app, Pinetime::Controllers::Ble& bleController); ~FirmwareUpdate() override; - bool Refresh() override; + void Refresh() override; private: enum class States { Idle, Running, Validated, Error }; @@ -36,6 +36,7 @@ namespace Pinetime { void UpdateError(); + lv_task_t* taskRefresh; TickType_t startTime; }; } diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index 1d05be8..eef8f91 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -38,8 +38,9 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, lv_label_set_text(labelIsValidated, "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version."); buttonValidate = lv_btn_create(lv_scr_act(), nullptr); - lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); buttonValidate->user_data = this; + lv_obj_set_size(buttonValidate, 115, 50); + lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x009900)); @@ -48,6 +49,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, buttonReset = lv_btn_create(lv_scr_act(), nullptr); buttonReset->user_data = this; + lv_obj_set_size(buttonReset, 115, 50); lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x990000)); lv_obj_set_event_cb(buttonReset, ButtonEventHandler); @@ -61,15 +63,11 @@ FirmwareValidation::~FirmwareValidation() { lv_obj_clean(lv_scr_act()); } -bool FirmwareValidation::Refresh() { - return running; -} - void FirmwareValidation::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (object == buttonValidate && event == LV_EVENT_PRESSED) { + if (object == buttonValidate && event == LV_EVENT_CLICKED) { validator.Validate(); running = false; - } else if (object == buttonReset && event == LV_EVENT_PRESSED) { + } else if (object == buttonReset && event == LV_EVENT_CLICKED) { validator.Reset(); } } diff --git a/src/displayapp/screens/FirmwareValidation.h b/src/displayapp/screens/FirmwareValidation.h index 1ef5ba0..bfdb096 100644 --- a/src/displayapp/screens/FirmwareValidation.h +++ b/src/displayapp/screens/FirmwareValidation.h @@ -16,8 +16,6 @@ namespace Pinetime { FirmwareValidation(DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator); ~FirmwareValidation() override; - bool Refresh() override; - void OnButtonEvent(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index 7db2c6c..4bc5b55 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -65,10 +65,6 @@ void FlashLight::OnClickEvent(lv_obj_t* obj, lv_event_t event) { } } -bool FlashLight::Refresh() { - return running; -} - bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - return true; + return false; } diff --git a/src/displayapp/screens/FlashLight.h b/src/displayapp/screens/FlashLight.h index a862ffd..7f5ca6c 100644 --- a/src/displayapp/screens/FlashLight.h +++ b/src/displayapp/screens/FlashLight.h @@ -16,8 +16,6 @@ namespace Pinetime { FlashLight(DisplayApp* app, System::SystemTask& systemTask, Controllers::BrightnessController& brightness); ~FlashLight() override; - bool Refresh() override; - bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; void OnClickEvent(lv_obj_t* obj, lv_event_t event); diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 5689b63..b6ece27 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -64,14 +64,17 @@ HeartRate::HeartRate(Pinetime::Applications::DisplayApp* app, UpdateStartStopButton(isHrRunning); if (isHrRunning) systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + + taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this); } HeartRate::~HeartRate() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } -bool HeartRate::Refresh() { +void HeartRate::Refresh() { auto state = heartRateController.State(); switch (state) { @@ -86,8 +89,6 @@ bool HeartRate::Refresh() { lv_label_set_text(label_status, ToString(state)); lv_obj_align(label_status, label_hr, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); - - return running; } void HeartRate::OnStartStopEvent(lv_event_t event) { diff --git a/src/displayapp/screens/HeartRate.h b/src/displayapp/screens/HeartRate.h index a23c5af..7f7d3ad 100644 --- a/src/displayapp/screens/HeartRate.h +++ b/src/displayapp/screens/HeartRate.h @@ -20,7 +20,7 @@ namespace Pinetime { HeartRate(DisplayApp* app, Controllers::HeartRateController& HeartRateController, System::SystemTask& systemTask); ~HeartRate() override; - bool Refresh() override; + void Refresh() override; void OnStartStopEvent(lv_event_t event); @@ -33,6 +33,8 @@ namespace Pinetime { lv_obj_t* label_status; lv_obj_t* btn_startStop; lv_obj_t* label_startStop; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index 3224008..85a5e82 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -5,20 +5,13 @@ using namespace Pinetime::Applications::Screens; InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl {lvgl} { - app->SetTouchMode(DisplayApp::TouchModes::Polling); std::fill(b, b + bufferSize, selectColor); } InfiniPaint::~InfiniPaint() { - // Reset the touchmode - app->SetTouchMode(DisplayApp::TouchModes::Gestures); lv_obj_clean(lv_scr_act()); } -bool InfiniPaint::Refresh() { - return running; -} - bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { switch (event) { case Pinetime::Applications::TouchEvents::LongTap: diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index 6251752..0a70e03 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -17,8 +17,6 @@ namespace Pinetime { ~InfiniPaint() override; - bool Refresh() override; - bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(uint16_t x, uint16_t y) override; diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp index 0132dbd..1761a7b 100644 --- a/src/displayapp/screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -6,10 +6,10 @@ Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::Displ : Screen(app), labelText {labelText} { if (numScreens > 1) { - pageIndicatorBasePoints[0].x = 240 - 1; - pageIndicatorBasePoints[0].y = 6; - pageIndicatorBasePoints[1].x = 240 - 1; - pageIndicatorBasePoints[1].y = 240 - 6; + 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); @@ -17,13 +17,13 @@ Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::Displ lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - uint16_t indicatorSize = 228 / numScreens; + uint16_t indicatorSize = LV_VER_RES / numScreens; uint16_t indicatorPos = indicatorSize * screenID; - pageIndicatorPoints[0].x = 240 - 1; - pageIndicatorPoints[0].y = (6 + indicatorPos); - pageIndicatorPoints[1].x = 240 - 1; - pageIndicatorPoints[1].y = (6 + indicatorPos) + indicatorSize; + 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); @@ -36,7 +36,3 @@ Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::Displ Label::~Label() { lv_obj_clean(lv_scr_act()); } - -bool Label::Refresh() { - return running; -} diff --git a/src/displayapp/screens/Label.h b/src/displayapp/screens/Label.h index 62b80be..f1e4907 100644 --- a/src/displayapp/screens/Label.h +++ b/src/displayapp/screens/Label.h @@ -12,11 +12,7 @@ namespace Pinetime { Label(uint8_t screenID, uint8_t numScreens, DisplayApp* app, lv_obj_t* labelText); ~Label() override; - bool Refresh() override; - private: - bool running = true; - lv_obj_t* labelText = nullptr; lv_point_t pageIndicatorBasePoints[2]; lv_point_t pageIndicatorPoints[2]; @@ -25,4 +21,4 @@ namespace Pinetime { }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp index b4f4d2c..064b47a 100644 --- a/src/displayapp/screens/List.cpp +++ b/src/displayapp/screens/List.cpp @@ -25,42 +25,38 @@ List::List(uint8_t screenID, settingsController.SetSettingsMenu(screenID); if (numScreens > 1) { - pageIndicatorBasePoints[0].x = 240 - 1; - pageIndicatorBasePoints[0].y = 6; - pageIndicatorBasePoints[1].x = 240 - 1; - pageIndicatorBasePoints[1].y = 240 - 6; + 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_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - uint16_t indicatorSize = 228 / numScreens; - uint16_t indicatorPos = indicatorSize * screenID; + const uint16_t indicatorSize = LV_VER_RES / numScreens; + const uint16_t indicatorPos = indicatorSize * screenID; - pageIndicatorPoints[0].x = 240 - 1; - pageIndicatorPoints[0].y = 6 + indicatorPos; - pageIndicatorPoints[1].x = 240 - 1; - pageIndicatorPoints[1].y = 6 + indicatorPos + indicatorSize; + 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_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); } lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - // lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); 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_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 4); lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); lv_obj_set_pos(container1, 0, 0); - lv_obj_set_width(container1, LV_HOR_RES - 15); + lv_obj_set_width(container1, LV_HOR_RES - 8); lv_obj_set_height(container1, LV_VER_RES); lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); @@ -73,11 +69,11 @@ List::List(uint8_t screenID, itemApps[i] = lv_btn_create(container1, nullptr); lv_obj_set_style_local_bg_opa(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); - lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 57); lv_obj_set_style_local_bg_color(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_width(itemApps[i], LV_HOR_RES - 25); - lv_obj_set_height(itemApps[i], 52); + lv_obj_set_width(itemApps[i], LV_HOR_RES - 8); + lv_obj_set_height(itemApps[i], 57); lv_obj_set_event_cb(itemApps[i], ButtonEventHandler); lv_btn_set_layout(itemApps[i], LV_LAYOUT_ROW_MID); itemApps[i]->user_data = this; @@ -102,13 +98,8 @@ List::~List() { lv_obj_clean(lv_scr_act()); } -bool List::Refresh() { - - return running; -} - void List::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_RELEASED) { + if (event == LV_EVENT_CLICKED) { for (int i = 0; i < MAXLISTITEMS; i++) { if (apps[i] != Apps::None && object == itemApps[i]) { app->StartApp(apps[i], DisplayApp::FullRefreshDirections::Up); diff --git a/src/displayapp/screens/List.h b/src/displayapp/screens/List.h index a45fd1d..d9f61f2 100644 --- a/src/displayapp/screens/List.h +++ b/src/displayapp/screens/List.h @@ -27,8 +27,6 @@ namespace Pinetime { std::array<Applications, MAXLISTITEMS>& applications); ~List() override; - bool Refresh() override; - void OnButtonEvent(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/Meter.cpp b/src/displayapp/screens/Meter.cpp index e0dbdfa..57cde9c 100644 --- a/src/displayapp/screens/Meter.cpp +++ b/src/displayapp/screens/Meter.cpp @@ -20,17 +20,17 @@ Meter::Meter(Pinetime::Applications::DisplayApp* app) : Screen(app) { lv_obj_set_size(lmeter, 200, 200); lv_obj_align(lmeter, nullptr, LV_ALIGN_CENTER, 0, 0); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Meter::~Meter() { - + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Meter::Refresh() { +void Meter::Refresh() { lv_linemeter_set_value(lmeter, value++); /*Set the current value*/ if (value >= 60) value = 0; - - return running; } diff --git a/src/displayapp/screens/Meter.h b/src/displayapp/screens/Meter.h index 24af15a..9b3d1d4 100644 --- a/src/displayapp/screens/Meter.h +++ b/src/displayapp/screens/Meter.h @@ -14,13 +14,15 @@ namespace Pinetime { Meter(DisplayApp* app); ~Meter() override; - bool Refresh() override; + void Refresh() override; private: lv_style_t style_lmeter; lv_obj_t* lmeter; uint32_t value = 0; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 7bfbccb..884a4a5 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -1,35 +1,15 @@ #include "Metronome.h" - -#include "Screen.h" #include "Symbols.h" -#include "lvgl/lvgl.h" -#include "FreeRTOSConfig.h" -#include "task.h" - -#include <string> -#include <tuple> using namespace Pinetime::Applications::Screens; namespace { - float calculateDelta(const TickType_t startTime, const TickType_t currentTime) { - TickType_t delta = 0; - // Take care of overflow - if (startTime > currentTime) { - delta = 0xffffffff - startTime; - delta += (currentTime + 1); - } else { - delta = currentTime - startTime; - } - return static_cast<float>(delta) / static_cast<float>(configTICK_RATE_HZ); - } - - static void eventHandler(lv_obj_t* obj, lv_event_t event) { - Metronome* screen = static_cast<Metronome*>(obj->user_data); + void eventHandler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast<Metronome*>(obj->user_data); screen->OnEvent(obj, event); } - lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x = 0, uint8_t y = 0) { + lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x, uint8_t y) { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font); lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); @@ -41,7 +21,7 @@ namespace { } Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask) - : Screen(app), running {true}, currentState {States::Stopped}, startTime {}, motorController {motorController}, systemTask {systemTask} { + : Screen(app), motorController {motorController}, systemTask {systemTask} { bpmArc = lv_arc_create(lv_scr_act(), nullptr); bpmArc->user_data = this; @@ -52,10 +32,10 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl lv_arc_set_value(bpmArc, bpm); lv_obj_set_size(bpmArc, 210, 210); lv_arc_set_adjustable(bpmArc, true); - lv_obj_align(bpmArc, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 7); + lv_obj_align(bpmArc, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0); - bpmValue = createLabel(std::to_string(lv_arc_get_value(bpmArc)).c_str(), bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55); - bpmLegend = createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0); + bpmValue = createLabel("120", bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55); + createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0); bpmTap = lv_btn_create(lv_scr_act(), nullptr); bpmTap->user_data = this; @@ -69,55 +49,46 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl lv_obj_set_event_cb(bpbDropdown, eventHandler); lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_MAIN, LV_STATE_DEFAULT, 20); lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_LIST, LV_STATE_DEFAULT, 20); - lv_obj_align(bpbDropdown, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 15, -4); + lv_obj_set_size(bpbDropdown, 115, 50); + lv_obj_align(bpbDropdown, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_dropdown_set_options(bpbDropdown, "1\n2\n3\n4\n5\n6\n7\n8\n9"); lv_dropdown_set_selected(bpbDropdown, bpb - 1); - bpbLegend = lv_label_create(bpbDropdown, nullptr); - lv_label_set_text(bpbLegend, "bpb"); - lv_obj_align(bpbLegend, bpbDropdown, LV_ALIGN_IN_RIGHT_MID, -15, 0); + lv_dropdown_set_show_selected(bpbDropdown, false); + lv_dropdown_set_text(bpbDropdown, ""); + + currentBpbText = lv_label_create(bpbDropdown, nullptr); + lv_label_set_text_fmt(currentBpbText, "%d bpb", bpb); + lv_obj_align(currentBpbText, bpbDropdown, LV_ALIGN_CENTER, 0, 0); playPause = lv_btn_create(lv_scr_act(), nullptr); playPause->user_data = this; lv_obj_set_event_cb(playPause, eventHandler); - lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10); - lv_obj_set_height(playPause, 39); - playPauseLabel = lv_label_create(playPause, nullptr); - lv_label_set_text(playPauseLabel, Symbols::play); + lv_obj_set_size(playPause, 115, 50); + lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play); - app->SetTouchMode(DisplayApp::TouchModes::Polling); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Metronome::~Metronome() { - app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_task_del(taskRefresh); systemTask.PushMessage(System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } -bool Metronome::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - return true; -} - -bool Metronome::Refresh() { - switch (currentState) { - case States::Stopped: { - break; - } - case States::Running: { - if (calculateDelta(startTime, xTaskGetTickCount()) >= (60.0 / bpm)) { - counter--; - startTime -= 60.0 / bpm; - startTime = xTaskGetTickCount(); - if (counter == 0) { - counter = bpb; - motorController.SetDuration(90); - } else { - motorController.SetDuration(30); - } +void Metronome::Refresh() { + if (metronomeStarted) { + if (xTaskGetTickCount() - startTime > 60 * configTICK_RATE_HZ / bpm) { + startTime += 60 * configTICK_RATE_HZ / bpm; + counter--; + if (counter == 0) { + counter = bpb; + motorController.RunForDuration(90); + } else { + motorController.RunForDuration(30); } - break; } } - return running; } void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { @@ -128,42 +99,39 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { lv_label_set_text_fmt(bpmValue, "%03d", bpm); } else if (obj == bpbDropdown) { bpb = lv_dropdown_get_selected(obj) + 1; + lv_label_set_text_fmt(currentBpbText, "%d bpb", bpb); + lv_obj_realign(currentBpbText); } break; } case LV_EVENT_PRESSED: { if (obj == bpmTap) { - float timeDelta = calculateDelta(tappedTime, xTaskGetTickCount()); - if (tappedTime == 0 || timeDelta > 3) { - tappedTime = xTaskGetTickCount(); - } else { - bpm = ceil(60.0 / timeDelta); + TickType_t delta = xTaskGetTickCount() - tappedTime; + if (tappedTime != 0 && delta < configTICK_RATE_HZ * 3) { + bpm = configTICK_RATE_HZ * 60 / delta; lv_arc_set_value(bpmArc, bpm); lv_label_set_text_fmt(bpmValue, "%03d", bpm); - tappedTime = xTaskGetTickCount(); } + tappedTime = xTaskGetTickCount(); } break; } case LV_EVENT_CLICKED: { if (obj == playPause) { - currentState = (currentState == States::Stopped ? States::Running : States::Stopped); - switch (currentState) { - case States::Stopped: { - lv_label_set_text(playPauseLabel, Symbols::play); - systemTask.PushMessage(System::Messages::EnableSleeping); - break; - } - case States::Running: { - lv_label_set_text(playPauseLabel, Symbols::pause); - systemTask.PushMessage(System::Messages::DisableSleeping); - startTime = xTaskGetTickCount(); - counter = 1; - break; - } + metronomeStarted = !metronomeStarted; + if (metronomeStarted) { + lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::pause); + systemTask.PushMessage(System::Messages::DisableSleeping); + startTime = xTaskGetTickCount(); + counter = 1; + } else { + lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play); + systemTask.PushMessage(System::Messages::EnableSleeping); } } break; } + default: + break; } } diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index 3a1f108..f3a84dc 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -3,32 +3,34 @@ #include "systemtask/SystemTask.h" #include "components/motor/MotorController.h" -#include <array> +namespace Pinetime { + namespace Applications { + namespace Screens { -namespace Pinetime::Applications::Screens { + class Metronome : public Screen { + public: + Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask); + ~Metronome() override; + void Refresh() override; + void OnEvent(lv_obj_t* obj, lv_event_t event); - class Metronome : public Screen { - public: - Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask); - ~Metronome() override; - bool Refresh() override; - bool OnTouchEvent(TouchEvents event) override; - void OnEvent(lv_obj_t* obj, lv_event_t event); - enum class States { Running, Stopped }; + private: + TickType_t startTime = 0; + TickType_t tappedTime = 0; + Controllers::MotorController& motorController; + System::SystemTask& systemTask; + int16_t bpm = 120; + uint8_t bpb = 4; + uint8_t counter = 1; - private: - bool running; - States currentState; - TickType_t startTime; - TickType_t tappedTime = 0; - Controllers::MotorController& motorController; - System::SystemTask& systemTask; - uint16_t bpm = 120; - uint8_t bpb = 4; - uint8_t counter = 1; + bool metronomeStarted = false; - lv_obj_t *bpmArc, *bpmTap, *bpmValue, *bpmLegend; - lv_obj_t *bpbDropdown, *bpbLegend; - lv_obj_t *playPause, *playPauseLabel; - }; + lv_obj_t *bpmArc, *bpmTap, *bpmValue; + lv_obj_t *bpbDropdown, *currentBpbText; + lv_obj_t *playPause; + + lv_task_t* taskRefresh; + }; + } + } } diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp index a8bb3c1..2f1f7c2 100644 --- a/src/displayapp/screens/Motion.cpp +++ b/src/displayapp/screens/Motion.cpp @@ -32,31 +32,30 @@ Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionContr lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10); lv_label_set_recolor(label, true); - + labelStep = lv_label_create(lv_scr_act(), NULL); lv_obj_align(labelStep, chart, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_label_set_text(labelStep, "Steps ---"); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Motion::~Motion() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Motion::Refresh() { +void Motion::Refresh() { lv_chart_set_next(chart, ser1, motionController.X()); lv_chart_set_next(chart, ser2, motionController.Y()); lv_chart_set_next(chart, ser3, motionController.Z()); lv_label_set_text_fmt(labelStep, "Steps %lu", motionController.NbSteps()); - lv_label_set_text_fmt(label, "X #FF0000 %d# Y #008000 %d# Z #FFFF00 %d#", motionController.X() / 0x10, motionController.Y() / 0x10, motionController.Z() / 0x10); + lv_label_set_text_fmt(label, + "X #FF0000 %d# Y #008000 %d# Z #FFFF00 %d#", + motionController.X() / 0x10, + motionController.Y() / 0x10, + motionController.Z() / 0x10); lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10); - - return running; -} - -bool Motion::OnButtonPushed() { - running = false; - return true; } diff --git a/src/displayapp/screens/Motion.h b/src/displayapp/screens/Motion.h index 132b20e..20a18d0 100644 --- a/src/displayapp/screens/Motion.h +++ b/src/displayapp/screens/Motion.h @@ -17,8 +17,7 @@ namespace Pinetime { Motion(DisplayApp* app, Controllers::MotionController& motionController); ~Motion() override; - bool Refresh() override; - bool OnButtonPushed() override; + void Refresh() override; private: Controllers::MotionController& motionController; @@ -29,10 +28,8 @@ namespace Pinetime { lv_obj_t* label; lv_obj_t* labelStep; - static constexpr uint8_t nbStepsBufferSize = 9; - char nbStepsBuffer[nbStepsBufferSize + 1]; - bool running = true; + lv_task_t* taskRefresh; }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp index 9f10f50..47ddb65 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -50,60 +50,55 @@ inline void lv_img_set_src_arr(lv_obj_t* img, const lv_img_dsc_t* src_img) { Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::MusicService& music) : Screen(app), musicService(music) { lv_obj_t* label; + lv_style_init(&btn_style); + lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, 20); + lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, LV_COLOR_AQUA); + lv_style_set_bg_opa(&btn_style, LV_STATE_DEFAULT, LV_OPA_20); + btnVolDown = lv_btn_create(lv_scr_act(), nullptr); btnVolDown->user_data = this; lv_obj_set_event_cb(btnVolDown, event_handler); - lv_obj_set_size(btnVolDown, 65, 75); - lv_obj_align(btnVolDown, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 15, -10); - lv_obj_set_style_local_radius(btnVolDown, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnVolDown, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnVolDown, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnVolDown, 76, 76); + lv_obj_align(btnVolDown, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_add_style(btnVolDown, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnVolDown, nullptr); lv_label_set_text(label, Symbols::volumDown); - lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + lv_obj_set_hidden(btnVolDown, true); btnVolUp = lv_btn_create(lv_scr_act(), nullptr); btnVolUp->user_data = this; lv_obj_set_event_cb(btnVolUp, event_handler); - lv_obj_set_size(btnVolUp, 65, 75); - lv_obj_align(btnVolUp, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10); - lv_obj_set_style_local_radius(btnVolUp, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnVolUp, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnVolUp, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnVolUp, 76, 76); + lv_obj_align(btnVolUp, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_add_style(btnVolUp, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnVolUp, nullptr); lv_label_set_text(label, Symbols::volumUp); - lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + lv_obj_set_hidden(btnVolUp, true); btnPrev = lv_btn_create(lv_scr_act(), nullptr); btnPrev->user_data = this; lv_obj_set_event_cb(btnPrev, event_handler); - lv_obj_set_size(btnPrev, 65, 75); - lv_obj_align(btnPrev, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 15, -10); - lv_obj_set_style_local_radius(btnPrev, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnPrev, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnPrev, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnPrev, 76, 76); + lv_obj_align(btnPrev, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_add_style(btnPrev, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnPrev, nullptr); lv_label_set_text(label, Symbols::stepBackward); btnNext = lv_btn_create(lv_scr_act(), nullptr); btnNext->user_data = this; lv_obj_set_event_cb(btnNext, event_handler); - lv_obj_set_size(btnNext, 65, 75); - lv_obj_align(btnNext, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10); - lv_obj_set_style_local_radius(btnNext, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnNext, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnNext, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnNext, 76, 76); + lv_obj_align(btnNext, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_add_style(btnNext, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnNext, nullptr); lv_label_set_text(label, Symbols::stepForward); btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); btnPlayPause->user_data = this; lv_obj_set_event_cb(btnPlayPause, event_handler); - lv_obj_set_size(btnPlayPause, 65, 75); - lv_obj_align(btnPlayPause, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, -10); - lv_obj_set_style_local_radius(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnPlayPause, 76, 76); + lv_obj_align(btnPlayPause, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_obj_add_style(btnPlayPause, LV_STATE_DEFAULT, &btn_style); txtPlayPause = lv_label_create(btnPlayPause, nullptr); lv_label_set_text(txtPlayPause, Symbols::play); @@ -119,7 +114,6 @@ Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Mus constexpr int8_t MIDDLE_OFFSET = -25; txtArtist = lv_label_create(lv_scr_act(), nullptr); lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL_CIRC); - lv_label_set_anim_speed(txtArtist, 1); lv_obj_align(txtArtist, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 1 * FONT_HEIGHT); lv_label_set_align(txtArtist, LV_ALIGN_IN_LEFT_MID); lv_obj_set_width(txtArtist, LV_HOR_RES - 12); @@ -127,7 +121,6 @@ Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Mus txtTrack = lv_label_create(lv_scr_act(), nullptr); lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_SROLL_CIRC); - lv_label_set_anim_speed(txtTrack, 1); lv_obj_align(txtTrack, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 2 * FONT_HEIGHT + LINE_PAD); lv_label_set_align(txtTrack, LV_ALIGN_IN_LEFT_MID); @@ -146,13 +139,17 @@ Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Mus frameB = false; musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Music::~Music() { + lv_task_del(taskRefresh); + lv_style_reset(&btn_style); lv_obj_clean(lv_scr_act()); } -bool Music::Refresh() { +void Music::Refresh() { if (artist != musicService.getArtist()) { artist = musicService.getArtist(); currentLength = 0; @@ -216,8 +213,6 @@ bool Music::Refresh() { } else { lv_label_set_text(txtPlayPause, Symbols::play); } - - return running; } void Music::UpdateLength() { @@ -274,21 +269,19 @@ void Music::OnObjectEvent(lv_obj_t* obj, lv_event_t event) { bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) { switch (event) { case TouchEvents::SwipeUp: { - displayVolumeButtons = true; - lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); - lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + lv_obj_set_hidden(btnVolDown, false); + lv_obj_set_hidden(btnVolUp, false); - lv_obj_set_hidden(btnNext, displayVolumeButtons); - lv_obj_set_hidden(btnPrev, displayVolumeButtons); + lv_obj_set_hidden(btnNext, true); + lv_obj_set_hidden(btnPrev, true); return true; } case TouchEvents::SwipeDown: { - displayVolumeButtons = false; - lv_obj_set_hidden(btnNext, displayVolumeButtons); - lv_obj_set_hidden(btnPrev, displayVolumeButtons); + lv_obj_set_hidden(btnNext, false); + lv_obj_set_hidden(btnPrev, false); - lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); - lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + lv_obj_set_hidden(btnVolDown, true); + lv_obj_set_hidden(btnVolUp, true); return true; } case TouchEvents::SwipeLeft: { @@ -300,7 +293,7 @@ bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return true; } default: { - return true; + return false; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index ef8f1fe..6f2d80a 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -35,7 +35,7 @@ namespace Pinetime { ~Music() override; - bool Refresh() override; + void Refresh() override; void OnObjectEvent(lv_obj_t* obj, lv_event_t event); @@ -57,10 +57,11 @@ namespace Pinetime { lv_obj_t* imgDiscAnim; lv_obj_t* txtTrackDuration; + lv_style_t btn_style; + /** For the spinning disc animation */ bool frameB; - bool displayVolumeButtons = false; Pinetime::Controllers::MusicService& musicService; std::string artist; @@ -78,6 +79,8 @@ namespace Pinetime { bool playing; + lv_task_t* taskRefresh; + /** Watchapp */ }; } diff --git a/src/displayapp/screens/Navigation.cpp b/src/displayapp/screens/Navigation.cpp index 79b04e2..d437cc6 100644 --- a/src/displayapp/screens/Navigation.cpp +++ b/src/displayapp/screens/Navigation.cpp @@ -161,13 +161,16 @@ Navigation::Navigation(Pinetime::Applications::DisplayApp* app, Pinetime::Contro lv_bar_set_anim_time(barProgress, 500); lv_bar_set_range(barProgress, 0, 100); lv_bar_set_value(barProgress, 0, LV_ANIM_OFF); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Navigation::~Navigation() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Navigation::Refresh() { +void Navigation::Refresh() { if (flag != navService.getFlag()) { flag = navService.getFlag(); lv_label_set_text(imgFlag, iconForName(flag)); @@ -192,8 +195,4 @@ bool Navigation::Refresh() { lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_ORANGE); } } - - return running; } - - diff --git a/src/displayapp/screens/Navigation.h b/src/displayapp/screens/Navigation.h index eb7e00c..48f00a7 100644 --- a/src/displayapp/screens/Navigation.h +++ b/src/displayapp/screens/Navigation.h @@ -35,7 +35,7 @@ namespace Pinetime { Navigation(DisplayApp* app, Pinetime::Controllers::NavigationService& nav); ~Navigation() override; - bool Refresh() override; + void Refresh() override; private: lv_obj_t* imgFlag; @@ -49,6 +49,8 @@ namespace Pinetime { std::string narrative; std::string manDist; int progress; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 38b1242..22eb290 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -11,6 +11,7 @@ extern lv_font_t jetbrains_mono_bold_20; Notifications::Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Pinetime::Controllers::MotorController& motorController, Modes mode) : Screen(app), notificationManager {notificationManager}, alertNotificationService {alertNotificationService}, mode {mode} { notificationManager.ClearNewNotificationFlag(); @@ -36,25 +37,34 @@ Notifications::Notifications(DisplayApp* app, } if (mode == Modes::Preview) { - - timeoutLine = lv_line_create(lv_scr_act(), nullptr); - - lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_obj_set_style_local_line_rounded(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); - - lv_line_set_points(timeoutLine, timeoutLinePoints, 2); - timeoutTickCountStart = xTaskGetTickCount(); - timeoutTickCountEnd = timeoutTickCountStart + (5 * 1024); + if (notification.category == Controllers::NotificationManager::Categories::IncomingCall) { + motorController.StartRinging(); + } else { + motorController.RunForDuration(35); + timeoutLine = lv_line_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + lv_obj_set_style_local_line_rounded(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + + lv_line_set_points(timeoutLine, timeoutLinePoints, 2); + timeoutTickCountStart = xTaskGetTickCount(); + timeoutTickCountEnd = timeoutTickCountStart + (5 * 1024); + } } + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Notifications::~Notifications() { + lv_task_del(taskRefresh); + // make sure we stop any vibrations before exiting + Controllers::MotorController::StopRinging(); lv_obj_clean(lv_scr_act()); } -bool Notifications::Refresh() { - if (mode == Modes::Preview) { +void Notifications::Refresh() { + if (mode == Modes::Preview && timeoutLine != nullptr) { auto tick = xTaskGetTickCount(); int32_t pos = 240 - ((tick - timeoutTickCountStart) / ((timeoutTickCountEnd - timeoutTickCountStart) / 240)); if (pos < 0) @@ -63,13 +73,12 @@ bool Notifications::Refresh() { timeoutLinePoints[1].x = pos; lv_line_set_points(timeoutLine, timeoutLinePoints, 2); } - - return running; } bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - if (mode != Modes::Normal) - return true; + if (mode != Modes::Normal) { + return false; + } switch (event) { case Pinetime::Applications::TouchEvents::SwipeDown: { @@ -130,19 +139,9 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } namespace { - static void AcceptIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) { - auto* item = static_cast<Notifications::NotificationItem*>(obj->user_data); - item->OnAcceptIncomingCall(event); - } - - static void MuteIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) { + void CallEventHandler(lv_obj_t* obj, lv_event_t event) { auto* item = static_cast<Notifications::NotificationItem*>(obj->user_data); - item->OnMuteIncomingCall(event); - } - - static void RejectIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) { - auto* item = static_cast<Notifications::NotificationItem*>(obj->user_data); - item->OnRejectIncomingCall(event); + item->OnCallButtonEvent(obj, event); } } @@ -154,7 +153,6 @@ Notifications::NotificationItem::NotificationItem(const char* title, Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService) : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); @@ -184,7 +182,6 @@ Notifications::NotificationItem::NotificationItem(const char* title, } lv_label_set_text(alert_type, title); lv_label_set_long_mode(alert_type, LV_LABEL_LONG_SROLL_CIRC); - lv_label_set_anim_speed(alert_type, 3); lv_obj_set_width(alert_type, 180); lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 16); @@ -213,7 +210,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_accept = lv_btn_create(lv_scr_act(), nullptr); bt_accept->user_data = this; - lv_obj_set_event_cb(bt_accept, AcceptIncomingCallEventHandler); + lv_obj_set_event_cb(bt_accept, CallEventHandler); lv_obj_set_size(bt_accept, 76, 76); lv_obj_align(bt_accept, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); label_accept = lv_label_create(bt_accept, nullptr); @@ -222,7 +219,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_reject = lv_btn_create(lv_scr_act(), nullptr); bt_reject->user_data = this; - lv_obj_set_event_cb(bt_reject, RejectIncomingCallEventHandler); + lv_obj_set_event_cb(bt_reject, CallEventHandler); lv_obj_set_size(bt_reject, 76, 76); lv_obj_align(bt_reject, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); label_reject = lv_label_create(bt_reject, nullptr); @@ -231,7 +228,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_mute = lv_btn_create(lv_scr_act(), nullptr); bt_mute->user_data = this; - lv_obj_set_event_cb(bt_mute, MuteIncomingCallEventHandler); + lv_obj_set_event_cb(bt_mute, CallEventHandler); lv_obj_set_size(bt_mute, 76, 76); lv_obj_align(bt_mute, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); label_mute = lv_label_create(bt_mute, nullptr); @@ -247,25 +244,22 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_label_set_text(backgroundLabel, ""); } -void Notifications::NotificationItem::OnAcceptIncomingCall(lv_event_t event) { - if (event != LV_EVENT_CLICKED) - return; - - alertNotificationService.AcceptIncomingCall(); -} - -void Notifications::NotificationItem::OnMuteIncomingCall(lv_event_t event) { - if (event != LV_EVENT_CLICKED) +void Notifications::NotificationItem::OnCallButtonEvent(lv_obj_t* obj, lv_event_t event) { + if (event != LV_EVENT_CLICKED) { return; + } - alertNotificationService.MuteIncomingCall(); -} + Controllers::MotorController::StopRinging(); -void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) { - if (event != LV_EVENT_CLICKED) - return; + if (obj == bt_accept) { + alertNotificationService.AcceptIncomingCall(); + } else if (obj == bt_reject) { + alertNotificationService.RejectIncomingCall(); + } else if (obj == bt_mute) { + alertNotificationService.MuteIncomingCall(); + } - alertNotificationService.RejectIncomingCall(); + running = false; } Notifications::NotificationItem::~NotificationItem() { diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 51ca81d..f6f8b4c 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -5,6 +5,7 @@ #include <memory> #include "Screen.h" #include "components/ble/NotificationManager.h" +#include "components/motor/MotorController.h" namespace Pinetime { namespace Controllers { @@ -19,10 +20,11 @@ namespace Pinetime { explicit Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Pinetime::Controllers::MotorController& motorController, Modes mode); ~Notifications() override; - bool Refresh() override; + void Refresh() override; bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; class NotificationItem { @@ -35,12 +37,10 @@ namespace Pinetime { Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService); ~NotificationItem(); - bool Refresh() { - return false; + bool IsRunning() const { + return running; } - void OnAcceptIncomingCall(lv_event_t event); - void OnMuteIncomingCall(lv_event_t event); - void OnRejectIncomingCall(lv_event_t event); + void OnCallButtonEvent(lv_obj_t*, lv_event_t event); private: uint8_t notifNr = 0; @@ -60,6 +60,7 @@ namespace Pinetime { lv_obj_t* bottomPlaceholder; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; + bool running = true; }; private: @@ -75,9 +76,11 @@ namespace Pinetime { bool validDisplay = false; lv_point_t timeoutLinePoints[2] {{0, 1}, {239, 1}}; - lv_obj_t* timeoutLine; + lv_obj_t* timeoutLine = nullptr; uint32_t timeoutTickCountStart; uint32_t timeoutTickCountEnd; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Paddle.cpp b/src/displayapp/screens/Paddle.cpp index 5a939ac..3b6d60e 100644 --- a/src/displayapp/screens/Paddle.cpp +++ b/src/displayapp/screens/Paddle.cpp @@ -5,8 +5,6 @@ using namespace Pinetime::Applications::Screens; Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl {lvgl} { - app->SetTouchMode(DisplayApp::TouchModes::Polling); - background = lv_obj_create(lv_scr_act(), nullptr); lv_obj_set_size(background, LV_HOR_RES + 1, LV_VER_RES); lv_obj_set_pos(background, -1, 0); @@ -29,15 +27,16 @@ Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::Li lv_obj_set_style_local_bg_color(ball, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_obj_set_style_local_radius(ball, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); lv_obj_set_size(ball, ballSize, ballSize); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Paddle::~Paddle() { - // Reset the touchmode - app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Paddle::Refresh() { +void Paddle::Refresh() { ballX += dx; ballY += dy; @@ -69,7 +68,6 @@ bool Paddle::Refresh() { } } lv_label_set_text_fmt(points, "%04d", score); - return running; } bool Paddle::OnTouchEvent(Pinetime::Applications::TouchEvents event) { diff --git a/src/displayapp/screens/Paddle.h b/src/displayapp/screens/Paddle.h index 30ab8f9..fc2131a 100644 --- a/src/displayapp/screens/Paddle.h +++ b/src/displayapp/screens/Paddle.h @@ -16,7 +16,7 @@ namespace Pinetime { Paddle(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl); ~Paddle() override; - bool Refresh() override; + void Refresh() override; bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(uint16_t x, uint16_t y) override; @@ -40,6 +40,8 @@ namespace Pinetime { lv_obj_t* paddle; lv_obj_t* ball; lv_obj_t* background; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/PineTimeStyle.cpp b/src/displayapp/screens/PineTimeStyle.cpp index 591f3a4..7a712f4 100644 --- a/src/displayapp/screens/PineTimeStyle.cpp +++ b/src/displayapp/screens/PineTimeStyle.cpp @@ -23,6 +23,7 @@ #include <date/date.h> #include <lvgl/lvgl.h> #include <cstdio> +#include <displayapp/Colors.h> #include "BatteryIcon.h" #include "BleIcon.h" #include "NotificationIcon.h" @@ -52,7 +53,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, settingsController {settingsController}, motionController {motionController} { - /* This sets the watchface number to return to after leaving the menu */ + // This sets the watchface number to return to after leaving the menu settingsController.SetClockFace(2); displayedChar[0] = 0; @@ -61,44 +62,40 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, displayedChar[3] = 0; displayedChar[4] = 0; - /* Create a 200px wide background rectangle */ - + //Create a 200px wide background rectangle timebar = lv_obj_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBG())); lv_obj_set_style_local_radius(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); lv_obj_set_size(timebar, 200, 240); lv_obj_align(timebar, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 5, 0); - /* Display the time */ - + // Display the time timeDD1 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); - lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); lv_label_set_text(timeDD1, "12"); lv_obj_align(timeDD1, timebar, LV_ALIGN_IN_TOP_MID, 5, 5); timeDD2 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); - lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); lv_label_set_text(timeDD2, "34"); lv_obj_align(timeDD2, timebar, LV_ALIGN_IN_BOTTOM_MID, 5, -5); timeAMPM = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); lv_obj_set_style_local_text_line_space(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, -3); lv_label_set_text(timeAMPM, ""); lv_obj_align(timeAMPM, timebar, LV_ALIGN_IN_BOTTOM_LEFT, 2, -20); - /* Create a 40px wide bar down the right side of the screen */ - + // Create a 40px wide bar down the right side of the screen sidebar = lv_obj_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBar())); lv_obj_set_style_local_radius(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); lv_obj_set_size(sidebar, 40, 240); lv_obj_align(sidebar, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); - /* Display icons */ - + // Display icons batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_label_set_text(batteryIcon, Symbols::batteryFull); @@ -116,8 +113,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_align(notificationIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 40); - /* Calendar icon */ - + // Calendar icon calendarOuter = lv_obj_create(lv_scr_act(), nullptr); lv_obj_set_style_local_bg_color(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_set_style_local_radius(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); @@ -154,8 +150,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_size(calendarCrossBar2, 8, 3); lv_obj_align(calendarCrossBar2, calendarBar2, LV_ALIGN_IN_BOTTOM_MID, 0, 0); - /* Display date */ - + // Display date dateDayOfWeek = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(dateDayOfWeek, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_label_set_text(dateDayOfWeek, "THU"); @@ -191,7 +186,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 4); lv_obj_set_style_local_line_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); lv_obj_set_style_local_line_opa(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_pad_inner(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 4); backgroundLabel = lv_label_create(lv_scr_act(), nullptr); @@ -200,13 +195,17 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_size(backgroundLabel, 240, 240); lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text(backgroundLabel, ""); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); + Refresh(); } PineTimeStyle::~PineTimeStyle() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool PineTimeStyle::Refresh() { +void PineTimeStyle::Refresh() { batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); @@ -223,26 +222,17 @@ bool PineTimeStyle::Refresh() { bleState = bleController.IsConnected(); if (bleState.IsUpdated()) { - if (bleState.Get() == true) { - lv_label_set_text(bleIcon, BleIcon::GetIcon(true)); - lv_obj_realign(bleIcon); - } else { - lv_label_set_text(bleIcon, BleIcon::GetIcon(false)); - } + lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); + lv_obj_realign(bleIcon); } notificationState = notificatioManager.AreNewNotificationsAvailable(); if (notificationState.IsUpdated()) { - if (notificationState.Get() == true) { - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true)); - lv_obj_realign(notificationIcon); - } else { - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); - } + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); + lv_obj_realign(notificationIcon); } currentDateTime = dateTimeController.CurrentDateTime(); - if (currentDateTime.IsUpdated()) { auto newDateTime = currentDateTime.Get(); @@ -250,9 +240,9 @@ bool PineTimeStyle::Refresh() { auto time = date::make_time(newDateTime - dp); auto yearMonthDay = date::year_month_day(dp); - auto year = (int) yearMonthDay.year(); - auto month = static_cast<Pinetime::Controllers::DateTime::Months>((unsigned) yearMonthDay.month()); - auto day = (unsigned) yearMonthDay.day(); + 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()); int hour = time.hours().count(); @@ -263,60 +253,44 @@ bool PineTimeStyle::Refresh() { char hoursChar[3]; char ampmChar[5]; - - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - sprintf(hoursChar, "%02d", hour); - } else { - if (hour == 0 && hour != 12) { - hour = 12; - sprintf(ampmChar, "A\nM"); - } else if (hour == 12 && hour != 0) { - hour = 12; - sprintf(ampmChar, "P\nM"); - } else if (hour < 12 && hour != 0) { - sprintf(ampmChar, "A\nM"); - } else if (hour > 12 && hour != 0) { - hour = hour - 12; - sprintf(ampmChar, "P\nM"); - } + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { sprintf(hoursChar, "%02d", hour); + } else { + if (hour == 0 && hour != 12) { + hour = 12; + sprintf(ampmChar, "A\nM"); + } else if (hour == 12 && hour != 0) { + hour = 12; + sprintf(ampmChar, "P\nM"); + } else if (hour < 12 && hour != 0) { + sprintf(ampmChar, "A\nM"); + } else if (hour > 12 && hour != 0) { + hour = hour - 12; + sprintf(ampmChar, "P\nM"); } + sprintf(hoursChar, "%02d", hour); + } - if (hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] || + if (hoursChar[0] != displayedChar[0] or hoursChar[1] != displayedChar[1] or minutesChar[0] != displayedChar[2] or minutesChar[1] != displayedChar[3]) { displayedChar[0] = hoursChar[0]; displayedChar[1] = hoursChar[1]; displayedChar[2] = minutesChar[0]; displayedChar[3] = minutesChar[1]; - char hourStr[3]; - char minStr[3]; - - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { lv_label_set_text(timeAMPM, ampmChar); - } - - /* Display the time as 2 pairs of digits */ - sprintf(hourStr, "%c%c", hoursChar[0], hoursChar[1]); - lv_label_set_text(timeDD1, hourStr); + } - sprintf(minStr, "%c%c", minutesChar[0], minutesChar[1]); - lv_label_set_text(timeDD2, minStr); + lv_label_set_text_fmt(timeDD1, "%s", hoursChar); + lv_label_set_text_fmt(timeDD2, "%s", minutesChar); } if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - char dayOfWeekStr[4]; - char dayStr[3]; - char monthStr[4]; - - sprintf(dayOfWeekStr, "%s", dateTimeController.DayOfWeekShortToString()); - sprintf(dayStr, "%d", day); - sprintf(monthStr, "%s", dateTimeController.MonthShortToString()); - - lv_label_set_text(dateDayOfWeek, dayOfWeekStr); - lv_label_set_text(dateDay, dayStr); + lv_label_set_text_fmt(dateDayOfWeek, "%s", dateTimeController.DayOfWeekShortToString()); + lv_label_set_text_fmt(dateDay, "%d", day); lv_obj_realign(dateDay); - lv_label_set_text(dateMonth, monthStr); + lv_label_set_text_fmt(dateMonth, "%s", dateTimeController.MonthShortToString()); currentYear = year; currentMonth = month; @@ -335,6 +309,4 @@ bool PineTimeStyle::Refresh() { lv_obj_set_style_local_scale_grad_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); } } - - return running; -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h index 3b4ded1..cb74ead 100644 --- a/src/displayapp/screens/PineTimeStyle.h +++ b/src/displayapp/screens/PineTimeStyle.h @@ -30,9 +30,7 @@ namespace Pinetime { Controllers::MotionController& motionController); ~PineTimeStyle() override; - bool Refresh() override; - - void OnObjectEvent(lv_obj_t* pObj, lv_event_t i); + void Refresh() override; private: char displayedChar[5]; @@ -67,9 +65,6 @@ namespace Pinetime { lv_obj_t* calendarBar2; lv_obj_t* calendarCrossBar1; lv_obj_t* calendarCrossBar2; - lv_obj_t* heartbeatIcon; - lv_obj_t* heartbeatValue; - lv_obj_t* heartbeatBpm; lv_obj_t* notificationIcon; lv_obj_t* stepGauge; lv_color_t needle_colors[1]; @@ -80,6 +75,8 @@ namespace Pinetime { Controllers::NotificationManager& notificatioManager; Controllers::Settings& settingsController; Controllers::MotionController& motionController; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Screen.cpp b/src/displayapp/screens/Screen.cpp index 1467df3..6ae5b7b 100644 --- a/src/displayapp/screens/Screen.cpp +++ b/src/displayapp/screens/Screen.cpp @@ -1,2 +1,6 @@ #include "Screen.h" -using namespace Pinetime::Applications::Screens;
\ No newline at end of file +using namespace Pinetime::Applications::Screens; + +void Screen::RefreshTaskCallback(lv_task_t* task) { + static_cast<Screen*>(task->user_data)->Refresh(); +} diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h index 8e49c9d..ce5741b 100644 --- a/src/displayapp/screens/Screen.h +++ b/src/displayapp/screens/Screen.h @@ -2,6 +2,7 @@ #include <cstdint> #include "../TouchEvents.h" +#include <lvgl/lvgl.h> namespace Pinetime { namespace Applications { @@ -13,8 +14,12 @@ namespace Pinetime { DirtyValue() = default; // Use NSDMI explicit DirtyValue(T const& v) : value {v} { } // Use MIL and const-lvalue-ref - bool IsUpdated() const { - return isUpdated; + bool IsUpdated() { + if (this->isUpdated) { + this->isUpdated = false; + return true; + } + return false; } T const& Get() { this->isUpdated = false; @@ -34,25 +39,20 @@ namespace Pinetime { }; class Screen { + private: + virtual void Refresh() { + } + public: explicit Screen(DisplayApp* app) : app {app} { } virtual ~Screen() = default; - /** - * Most of the time, apps only react to events (touch events, for example). - * In this case you don't need to do anything in this method. - * - * For example, InfiniPaint does nothing in Refresh(). - * But, if you want to update your display periodically, draw an animation... - * you cannot do it in a touch event handler because these handlers are not - * called if the user does not touch the screen. - * - * That's why Refresh() is there: update the display periodically. - * - * @return false if the app can be closed, true if it must continue to run - **/ - virtual bool Refresh() = 0; + static void RefreshTaskCallback(lv_task_t* task); + + bool IsRunning() const { + return running; + } /** @return false if the button hasn't been handled by the app, true if it has been handled */ virtual bool OnButtonPushed() { @@ -60,6 +60,7 @@ namespace Pinetime { } /** @return false if the event hasn't been handled by the app, true if it has been handled */ + // Returning true will cancel lvgl tap virtual bool OnTouchEvent(TouchEvents event) { return false; } diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index ea66bfb..a9d747a 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -30,11 +30,6 @@ namespace Pinetime { lv_obj_clean(lv_scr_act()); } - bool Refresh() override { - running = current->Refresh(); - return running; - } - bool OnTouchEvent(TouchEvents event) override { if (mode == ScreenListModes::UpDown) { @@ -110,4 +105,4 @@ namespace Pinetime { }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp index 6aabd30..c41163a 100644 --- a/src/displayapp/screens/Steps.cpp +++ b/src/displayapp/screens/Steps.cpp @@ -5,13 +5,10 @@ using namespace Pinetime::Applications::Screens; -Steps::Steps( - Pinetime::Applications::DisplayApp *app, - Controllers::MotionController& motionController, - Controllers::Settings &settingsController) - : Screen(app), - motionController{motionController}, - settingsController{settingsController} { +Steps::Steps(Pinetime::Applications::DisplayApp* app, + Controllers::MotionController& motionController, + Controllers::Settings& settingsController) + : Screen(app), motionController {motionController}, settingsController {settingsController} { stepsArc = lv_arc_create(lv_scr_act(), nullptr); @@ -34,12 +31,12 @@ Steps::Steps( lv_label_set_text_fmt(lSteps, "%li", stepsCount); lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -20); - lv_obj_t * lstepsL = lv_label_create(lv_scr_act(), nullptr); + lv_obj_t* lstepsL = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(lstepsL, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); lv_label_set_text_static(lstepsL, "Steps"); lv_obj_align(lstepsL, lSteps, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); - lv_obj_t * lstepsGoal = lv_label_create(lv_scr_act(), nullptr); + lv_obj_t* lstepsGoal = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(lstepsGoal, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN); lv_label_set_text_fmt(lstepsGoal, "Goal\n%lu", settingsController.GetStepsGoal()); lv_label_set_align(lstepsGoal, LV_LABEL_ALIGN_CENTER); @@ -50,20 +47,20 @@ Steps::Steps( lv_obj_set_size(backgroundLabel, 240, 240); lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text_static(backgroundLabel, ""); + + taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this); } Steps::~Steps() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Steps::Refresh() { - +void Steps::Refresh() { stepsCount = motionController.NbSteps(); - + lv_label_set_text_fmt(lSteps, "%li", stepsCount); lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -20); - - lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal())); - return running; + lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal())); } diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h index 9c135e2..d7cf31e 100644 --- a/src/displayapp/screens/Steps.h +++ b/src/displayapp/screens/Steps.h @@ -15,24 +15,23 @@ namespace Pinetime { namespace Screens { class Steps : public Screen { - public: - Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings &settingsController); - ~Steps() override; + public: + Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings& settingsController); + ~Steps() override; - bool Refresh() override; - + void Refresh() override; - private: + private: + Controllers::MotionController& motionController; + Controllers::Settings& settingsController; - Controllers::MotionController& motionController; - Controllers::Settings& settingsController; + lv_obj_t* lSteps; + lv_obj_t* lStepsIcon; + lv_obj_t* stepsArc; - lv_obj_t * lSteps; - lv_obj_t * lStepsIcon; - lv_obj_t * stepsArc; - - uint32_t stepsCount; + uint32_t stepsCount; + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index f4db5d6..9b27a89 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -48,7 +48,6 @@ static void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) { StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) : Screen(app), systemTask {systemTask}, - running {true}, currentState {States::Init}, startTime {}, oldTimeElapsed {}, @@ -101,9 +100,12 @@ StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) lv_obj_set_style_local_text_color(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); lv_obj_align(lapTwoText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 55); lv_label_set_text(lapTwoText, ""); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } StopWatch::~StopWatch() { + lv_task_del(taskRefresh); systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } @@ -149,7 +151,7 @@ void StopWatch::pause() { systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } -bool StopWatch::Refresh() { +void StopWatch::Refresh() { if (currentState == States::Running) { timeElapsed = calculateDelta(startTime, xTaskGetTickCount()); currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed)); @@ -157,11 +159,10 @@ bool StopWatch::Refresh() { lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs); lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths); } - return running; } void StopWatch::playPauseBtnEventHandler(lv_event_t event) { - if (event != LV_EVENT_PRESSED) { + if (event != LV_EVENT_CLICKED) { return; } if (currentState == States::Init) { @@ -174,7 +175,7 @@ void StopWatch::playPauseBtnEventHandler(lv_event_t event) { } void StopWatch::stopLapBtnEventHandler(lv_event_t event) { - if (event != LV_EVENT_PRESSED) { + if (event != LV_EVENT_CLICKED) { return; } // If running, then this button is used to save laps @@ -196,8 +197,7 @@ void StopWatch::stopLapBtnEventHandler(lv_event_t event) { bool StopWatch::OnButtonPushed() { if (currentState == States::Running) { pause(); - } else { - running = false; + return true; } - return true; + return false; } diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h index e132f15..25634e9 100644 --- a/src/displayapp/screens/StopWatch.h +++ b/src/displayapp/screens/StopWatch.h @@ -64,7 +64,7 @@ namespace Pinetime::Applications::Screens { public: StopWatch(DisplayApp* app, System::SystemTask& systemTask); ~StopWatch() override; - bool Refresh() override; + void Refresh() override; void playPauseBtnEventHandler(lv_event_t event); void stopLapBtnEventHandler(lv_event_t event); @@ -77,7 +77,6 @@ namespace Pinetime::Applications::Screens { private: Pinetime::System::SystemTask& systemTask; TickType_t timeElapsed; - bool running; States currentState; TickType_t startTime; TickType_t oldTimeElapsed; @@ -86,5 +85,7 @@ namespace Pinetime::Applications::Screens { int lapNr = 0; lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap; lv_obj_t *lapOneText, *lapTwoText; + + lv_task_t* taskRefresh; }; } diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h index c9d6154..e68a7af 100644 --- a/src/displayapp/screens/Symbols.h +++ b/src/displayapp/screens/Symbols.h @@ -41,6 +41,9 @@ namespace Pinetime { static constexpr const char* hourGlass = "\xEF\x89\x92"; static constexpr const char* lapsFlag = "\xEF\x80\xA4"; static constexpr const char* drum = "\xEF\x95\xA9"; + static constexpr const char* chartLine = "\xEF\x88\x81"; + static constexpr const char* eye = "\xEF\x81\xAE"; + static constexpr const char* home = "\xEF\x80\x95"; // lv_font_sys_48.c static constexpr const char* settings = "\xEE\xA4\x82"; // e902 diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index f5bf0cc..b7a4fc6 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -20,6 +20,8 @@ namespace { return "BMA421"; case Pinetime::Controllers::MotionController::DeviceTypes::BMA425: return "BMA425"; + case Pinetime::Controllers::MotionController::DeviceTypes::Unknown: + return "???"; } return "???"; } @@ -63,18 +65,6 @@ SystemInfo::~SystemInfo() { lv_obj_clean(lv_scr_act()); } -bool SystemInfo::Refresh() { - if (running) { - screens.Refresh(); - } - return running; -} - -bool SystemInfo::OnButtonPushed() { - running = false; - return true; -} - bool SystemInfo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } @@ -210,30 +200,52 @@ bool SystemInfo::sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { } std::unique_ptr<Screen> SystemInfo::CreateScreen4() { - TaskStatus_t tasksStatus[7]; + TaskStatus_t tasksStatus[10]; lv_obj_t* infoTask = lv_table_create(lv_scr_act(), NULL); - lv_table_set_col_cnt(infoTask, 3); + lv_table_set_col_cnt(infoTask, 4); lv_table_set_row_cnt(infoTask, 8); - lv_obj_set_pos(infoTask, 10, 10); + lv_obj_set_pos(infoTask, 0, 10); lv_table_set_cell_value(infoTask, 0, 0, "#"); - lv_table_set_col_width(infoTask, 0, 50); - lv_table_set_cell_value(infoTask, 0, 1, "Task"); - lv_table_set_col_width(infoTask, 1, 80); - lv_table_set_cell_value(infoTask, 0, 2, "Free"); - lv_table_set_col_width(infoTask, 2, 90); + lv_table_set_col_width(infoTask, 0, 30); + lv_table_set_cell_value(infoTask, 0, 1, "S"); // State + lv_table_set_col_width(infoTask, 1, 30); + lv_table_set_cell_value(infoTask, 0, 2, "Task"); + lv_table_set_col_width(infoTask, 2, 80); + lv_table_set_cell_value(infoTask, 0, 3, "Free"); + lv_table_set_col_width(infoTask, 3, 90); - auto nb = uxTaskGetSystemState(tasksStatus, 7, nullptr); + auto nb = uxTaskGetSystemState(tasksStatus, sizeof(tasksStatus) / sizeof(tasksStatus[0]), nullptr); std::sort(tasksStatus, tasksStatus + nb, sortById); - for (uint8_t i = 0; i < nb; i++) { + for (uint8_t i = 0; i < nb && i < 7; i++) { lv_table_set_cell_value(infoTask, i + 1, 0, std::to_string(tasksStatus[i].xTaskNumber).c_str()); - lv_table_set_cell_value(infoTask, i + 1, 1, tasksStatus[i].pcTaskName); + char state[2] = {0}; + switch (tasksStatus[i].eCurrentState) { + case eReady: + case eRunning: + state[0] = 'R'; + break; + case eBlocked: + state[0] = 'B'; + break; + case eSuspended: + state[0] = 'S'; + break; + case eDeleted: + state[0] = 'D'; + break; + default: + state[0] = 'I'; // Invalid + break; + } + lv_table_set_cell_value(infoTask, i + 1, 1, state); + lv_table_set_cell_value(infoTask, i + 1, 2, tasksStatus[i].pcTaskName); if (tasksStatus[i].usStackHighWaterMark < 20) { std::string str1 = std::to_string(tasksStatus[i].usStackHighWaterMark) + " low"; - lv_table_set_cell_value(infoTask, i + 1, 2, str1.c_str()); + lv_table_set_cell_value(infoTask, i + 1, 3, str1.c_str()); } else { - lv_table_set_cell_value(infoTask, i + 1, 2, std::to_string(tasksStatus[i].usStackHighWaterMark).c_str()); + lv_table_set_cell_value(infoTask, i + 1, 3, std::to_string(tasksStatus[i].usStackHighWaterMark).c_str()); } } return std::make_unique<Screens::Label>(3, 5, app, infoTask); diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h index 9d471f6..5eb7054 100644 --- a/src/displayapp/screens/SystemInfo.h +++ b/src/displayapp/screens/SystemInfo.h @@ -30,13 +30,9 @@ namespace Pinetime { Pinetime::Drivers::WatchdogView& watchdog, Pinetime::Controllers::MotionController& motionController); ~SystemInfo() override; - bool Refresh() override; - bool OnButtonPushed() override; bool OnTouchEvent(TouchEvents event) override; private: - bool running = true; - Pinetime::Controllers::DateTime& dateTimeController; Pinetime::Controllers::Battery& batteryController; Pinetime::Controllers::BrightnessController& brightnessController; @@ -56,4 +52,4 @@ namespace Pinetime { }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index 3eb127c..1d4f0d0 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -6,15 +6,17 @@ using namespace Pinetime::Applications::Screens; namespace { static void lv_update_task(struct _lv_task_t* task) { - auto user_data = static_cast<Tile*>(task->user_data); + auto* user_data = static_cast<Tile*>(task->user_data); user_data->UpdateScreen(); } static void event_handler(lv_obj_t* obj, lv_event_t event) { + if (event != LV_EVENT_VALUE_CHANGED) return; + Tile* screen = static_cast<Tile*>(obj->user_data); - uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data(); + auto* eventDataPtr = (uint32_t*) lv_event_get_data(); uint32_t eventData = *eventDataPtr; - screen->OnObjectEvent(obj, event, eventData); + screen->OnValueChangedEvent(obj, eventData); } } @@ -33,37 +35,35 @@ Tile::Tile(uint8_t screenID, label_time = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); - lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 15, 6); + lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); // Battery batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); - lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 6); + lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -8, 0); if (numScreens > 1) { - pageIndicatorBasePoints[0].x = 240 - 1; - pageIndicatorBasePoints[0].y = 6; - pageIndicatorBasePoints[1].x = 240 - 1; - pageIndicatorBasePoints[1].y = 240 - 6; + pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[0].y = 0; + pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[1].y = LV_VER_RES; pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - uint16_t indicatorSize = 228 / numScreens; - uint16_t indicatorPos = indicatorSize * screenID; + const uint16_t indicatorSize = LV_VER_RES / numScreens; + const uint16_t indicatorPos = indicatorSize * screenID; - pageIndicatorPoints[0].x = 240 - 1; - pageIndicatorPoints[0].y = 6 + indicatorPos; - pageIndicatorPoints[1].x = 240 - 1; - pageIndicatorPoints[1].y = 6 + indicatorPos + indicatorSize; + pageIndicatorPoints[0].x = LV_HOR_RES - 1; + pageIndicatorPoints[0].y = indicatorPos; + pageIndicatorPoints[1].x = LV_HOR_RES - 1; + pageIndicatorPoints[1].y = indicatorPos + indicatorSize; pageIndicator = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); } @@ -83,7 +83,7 @@ Tile::Tile(uint8_t screenID, btnm1 = lv_btnmatrix_create(lv_scr_act(), nullptr); lv_btnmatrix_set_map(btnm1, btnmMap); - lv_obj_set_size(btnm1, LV_HOR_RES - 10, LV_VER_RES - 60); + lv_obj_set_size(btnm1, LV_HOR_RES - 16, LV_VER_RES - 60); lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 10); lv_obj_set_style_local_radius(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, 20); @@ -91,8 +91,11 @@ Tile::Tile(uint8_t screenID, lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_COLOR_AQUA); lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, LV_OPA_20); lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, lv_color_hex(0x111111)); + lv_obj_set_style_local_pad_all(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 0); + lv_obj_set_style_local_pad_inner(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 10); for (uint8_t i = 0; i < 6; i++) { + lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_CLICK_TRIG); if (applications[i].application == Apps::None) { lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_DISABLED); } @@ -120,13 +123,9 @@ void Tile::UpdateScreen() { lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); } -bool Tile::Refresh() { - return running; -} +void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) { + if(obj != btnm1) return; -void Tile::OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId) { - if (event == LV_EVENT_VALUE_CHANGED) { - app->StartApp(apps[buttonId], DisplayApp::FullRefreshDirections::Up); - running = false; - } + app->StartApp(apps[buttonId], DisplayApp::FullRefreshDirections::Up); + running = false; } diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index 4ebd81c..83d3fdf 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -30,9 +30,8 @@ namespace Pinetime { ~Tile() override; - bool Refresh() override; void UpdateScreen(); - void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); + void OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId); private: Pinetime::Controllers::Battery& batteryController; diff --git a/src/displayapp/screens/Timer.cpp b/src/displayapp/screens/Timer.cpp index 99e979b..ff3099d 100644 --- a/src/displayapp/screens/Timer.cpp +++ b/src/displayapp/screens/Timer.cpp @@ -4,10 +4,8 @@ #include "Symbols.h" #include "lvgl/lvgl.h" - using namespace Pinetime::Applications::Screens; - static void btnEventHandler(lv_obj_t* obj, lv_event_t event) { Timer* screen = static_cast<Timer*>(obj->user_data); screen->OnButtonEvent(obj, event); @@ -22,7 +20,7 @@ void Timer::createButtons() { lv_obj_set_width(btnMinutesUp, 60); txtMUp = lv_label_create(btnMinutesUp, nullptr); lv_label_set_text(txtMUp, "+"); - + btnMinutesDown = lv_btn_create(lv_scr_act(), nullptr); btnMinutesDown->user_data = this; lv_obj_set_event_cb(btnMinutesDown, btnEventHandler); @@ -31,7 +29,7 @@ void Timer::createButtons() { lv_obj_set_width(btnMinutesDown, 60); txtMDown = lv_label_create(btnMinutesDown, nullptr); lv_label_set_text(txtMDown, "-"); - + btnSecondsUp = lv_btn_create(lv_scr_act(), nullptr); btnSecondsUp->user_data = this; lv_obj_set_event_cb(btnSecondsUp, btnEventHandler); @@ -40,7 +38,7 @@ void Timer::createButtons() { lv_obj_set_width(btnSecondsUp, 60); txtSUp = lv_label_create(btnSecondsUp, nullptr); lv_label_set_text(txtSUp, "+"); - + btnSecondsDown = lv_btn_create(lv_scr_act(), nullptr); btnSecondsDown->user_data = this; lv_obj_set_event_cb(btnSecondsDown, btnEventHandler); @@ -49,24 +47,20 @@ void Timer::createButtons() { lv_obj_set_width(btnSecondsDown, 60); txtSDown = lv_label_create(btnSecondsDown, nullptr); lv_label_set_text(txtSDown, "-"); - } - Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) - : Screen(app), - running{true}, - timerController{timerController} { - + : Screen(app), running {true}, timerController {timerController} { + time = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - + uint32_t seconds = timerController.GetTimeRemaining() / 1000; lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60); lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20); - + btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); btnPlayPause->user_data = this; lv_obj_set_event_cb(btnPlayPause, btnEventHandler); @@ -79,20 +73,20 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) lv_label_set_text(txtPlayPause, Symbols::play); createButtons(); } - + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Timer::~Timer() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); - } -bool Timer::Refresh() { +void Timer::Refresh() { if (timerController.IsRunning()) { uint32_t seconds = timerController.GetTimeRemaining() / 1000; lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60); } - return running; } void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { @@ -105,11 +99,11 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { secondsToSet = seconds % 60; timerController.StopTimer(); createButtons(); - + } else if (secondsToSet + minutesToSet > 0) { lv_label_set_text(txtPlayPause, Symbols::pause); timerController.StartTimer((secondsToSet + minutesToSet * 60) * 1000); - + lv_obj_del(btnSecondsDown); btnSecondsDown = nullptr; lv_obj_del(btnSecondsUp); @@ -118,7 +112,6 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { btnMinutesDown = nullptr; lv_obj_del(btnMinutesUp); btnMinutesUp = nullptr; - } } else { if (!timerController.IsRunning()) { @@ -129,7 +122,7 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { minutesToSet++; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - + } else if (obj == btnMinutesDown) { if (minutesToSet == 0) { minutesToSet = 59; @@ -137,7 +130,7 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { minutesToSet--; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - + } else if (obj == btnSecondsUp) { if (secondsToSet >= 59) { secondsToSet = 0; @@ -145,7 +138,7 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { secondsToSet++; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - + } else if (obj == btnSecondsDown) { if (secondsToSet == 0) { secondsToSet = 59; @@ -153,21 +146,16 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { secondsToSet--; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - } } - } - } - } - void Timer::setDone() { lv_label_set_text(time, "00:00"); lv_label_set_text(txtPlayPause, Symbols::play); secondsToSet = 0; minutesToSet = 0; createButtons(); -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index 0d66f2d..d0fc8ed 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -8,35 +8,32 @@ #include "components/timer/TimerController.h" namespace Pinetime::Applications::Screens { - - + class Timer : public Screen { public: - - enum class Modes { - Normal, Done - }; - + enum class Modes { Normal, Done }; + Timer(DisplayApp* app, Controllers::TimerController& timerController); - + ~Timer() override; - - bool Refresh() override; - + + void Refresh() override; + void setDone(); - + void OnButtonEvent(lv_obj_t* obj, lv_event_t event); - + private: - bool running; uint8_t secondsToSet = 0; uint8_t minutesToSet = 0; Controllers::TimerController& timerController; - + void createButtons(); - - lv_obj_t* time, * msecTime, * btnPlayPause, * txtPlayPause, * btnMinutesUp, * btnMinutesDown, * btnSecondsUp, * btnSecondsDown, * txtMUp, - * txtMDown, * txtSUp, * txtSDown; + + lv_obj_t *time, *msecTime, *btnPlayPause, *txtPlayPause, *btnMinutesUp, *btnMinutesDown, *btnSecondsUp, *btnSecondsDown, *txtMUp, + *txtMDown, *txtSUp, *txtSDown; + + lv_task_t* taskRefresh; }; -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Twos.cpp b/src/displayapp/screens/Twos.cpp index eb26807..4201d50 100644 --- a/src/displayapp/screens/Twos.cpp +++ b/src/displayapp/screens/Twos.cpp @@ -102,10 +102,6 @@ Twos::~Twos() { lv_obj_clean(lv_scr_act()); } -bool Twos::Refresh() { - return running; -} - bool Twos::placeNewTile() { std::vector<std::pair<int, int>> availableCells; for (int row = 0; row < 4; row++) { @@ -295,4 +291,4 @@ void Twos::updateGridDisplay(Tile grid[][4]) { } } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/Twos.h b/src/displayapp/screens/Twos.h index 3367618..6d85cff 100644 --- a/src/displayapp/screens/Twos.h +++ b/src/displayapp/screens/Twos.h @@ -14,7 +14,6 @@ namespace Pinetime { public: Twos(DisplayApp* app); ~Twos() override; - bool Refresh() override; bool OnTouchEvent(TouchEvents event) override; @@ -36,4 +35,4 @@ namespace Pinetime { }; } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index f188937..75e35c1 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -10,38 +10,37 @@ LV_IMG_DECLARE(bg_clock); using namespace Pinetime::Applications::Screens; namespace { - -constexpr auto HOUR_LENGTH = 70; -constexpr auto MINUTE_LENGTH = 90; -constexpr auto SECOND_LENGTH = 110; +constexpr int16_t HourLength = 70; +constexpr int16_t MinuteLength = 90; +constexpr int16_t SecondLength = 110; // sin(90) = 1 so the value of _lv_trigo_sin(90) is the scaling factor const auto LV_TRIG_SCALE = _lv_trigo_sin(90); -int16_t cosine(int16_t angle) { +int16_t Cosine(int16_t angle) { return _lv_trigo_sin(angle + 90); } -int16_t sine(int16_t angle) { +int16_t Sine(int16_t angle) { return _lv_trigo_sin(angle); } -int16_t coordinate_x_relocate(int16_t x) { +int16_t CoordinateXRelocate(int16_t x) { return (x + LV_HOR_RES / 2); } -int16_t coordinate_y_relocate(int16_t y) { +int16_t CoordinateYRelocate(int16_t y) { return std::abs(y - LV_HOR_RES / 2); } -lv_point_t coordinate_relocate(int16_t radius, int16_t angle) { +lv_point_t CoordinateRelocate(int16_t radius, int16_t angle) { return lv_point_t{ - .x = coordinate_x_relocate(radius * static_cast<int32_t>(sine(angle)) / LV_TRIG_SCALE), - .y = coordinate_y_relocate(radius * static_cast<int32_t>(cosine(angle)) / LV_TRIG_SCALE) + .x = CoordinateXRelocate(radius * static_cast<int32_t>(Sine(angle)) / LV_TRIG_SCALE), + .y = CoordinateYRelocate(radius * static_cast<int32_t>(Cosine(angle)) / LV_TRIG_SCALE) }; } -} // namespace +} WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, Controllers::DateTime& dateTimeController, @@ -68,12 +67,12 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, Symbols::batteryHalf); - lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -8, -4); + lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 0); notificationIcon = lv_label_create(lv_scr_act(), NULL); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); - lv_obj_align(notificationIcon, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 8, -4); + lv_obj_align(notificationIcon, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); // Date - Day / Week day @@ -119,10 +118,12 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, lv_style_set_line_rounded(&hour_line_style_trace, LV_STATE_DEFAULT, false); lv_obj_add_style(hour_body_trace, LV_LINE_PART_MAIN, &hour_line_style_trace); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); UpdateClock(); } WatchFaceAnalog::~WatchFaceAnalog() { + lv_task_del(taskRefresh); lv_style_reset(&hour_line_style); lv_style_reset(&hour_line_style_trace); @@ -134,18 +135,17 @@ WatchFaceAnalog::~WatchFaceAnalog() { } void WatchFaceAnalog::UpdateClock() { - hour = dateTimeController.Hours(); minute = dateTimeController.Minutes(); second = dateTimeController.Seconds(); if (sMinute != minute) { auto const angle = minute * 6; - minute_point[0] = coordinate_relocate(30, angle); - minute_point[1] = coordinate_relocate(MINUTE_LENGTH, angle); + minute_point[0] = CoordinateRelocate(30, angle); + minute_point[1] = CoordinateRelocate(MinuteLength, angle); - minute_point_trace[0] = coordinate_relocate(5, angle); - minute_point_trace[1] = coordinate_relocate(31, angle); + minute_point_trace[0] = CoordinateRelocate(5, angle); + minute_point_trace[1] = CoordinateRelocate(31, angle); lv_line_set_points(minute_body, minute_point, 2); lv_line_set_points(minute_body_trace, minute_point_trace, 2); @@ -156,11 +156,11 @@ void WatchFaceAnalog::UpdateClock() { sMinute = minute; auto const angle = (hour * 30 + minute / 2); - hour_point[0] = coordinate_relocate(30, angle); - hour_point[1] = coordinate_relocate(HOUR_LENGTH, angle); + hour_point[0] = CoordinateRelocate(30, angle); + hour_point[1] = CoordinateRelocate(HourLength, angle); - hour_point_trace[0] = coordinate_relocate(5, angle); - hour_point_trace[1] = coordinate_relocate(31, angle); + hour_point_trace[0] = CoordinateRelocate(5, angle); + hour_point_trace[1] = CoordinateRelocate(31, angle); lv_line_set_points(hour_body, hour_point, 2); lv_line_set_points(hour_body_trace, hour_point_trace, 2); @@ -170,13 +170,13 @@ void WatchFaceAnalog::UpdateClock() { sSecond = second; auto const angle = second * 6; - second_point[0] = coordinate_relocate(-20, angle); - second_point[1] = coordinate_relocate(SECOND_LENGTH, angle); + second_point[0] = CoordinateRelocate(-20, angle); + second_point[1] = CoordinateRelocate(SecondLength, angle); lv_line_set_points(second_body, second_point, 2); } } -bool WatchFaceAnalog::Refresh() { +void WatchFaceAnalog::Refresh() { batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); @@ -186,16 +186,12 @@ bool WatchFaceAnalog::Refresh() { notificationState = notificationManager.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)); + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); } currentDateTime = dateTimeController.CurrentDateTime(); if (currentDateTime.IsUpdated()) { - month = dateTimeController.Month(); day = dateTimeController.Day(); dayOfWeek = dateTimeController.DayOfWeek(); @@ -203,7 +199,6 @@ bool WatchFaceAnalog::Refresh() { UpdateClock(); if ((month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - lv_label_set_text_fmt(label_date_day, "%s\n%02i", dateTimeController.DayOfWeekShortToString(), day); currentMonth = month; @@ -211,6 +206,4 @@ bool WatchFaceAnalog::Refresh() { currentDay = day; } } - - return true; } diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index ac7f0ac..406f4d5 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -32,7 +32,7 @@ namespace Pinetime { ~WatchFaceAnalog() override; - bool Refresh() override; + void Refresh() override; private: uint8_t sHour, sMinute, sSecond; @@ -58,14 +58,12 @@ namespace Pinetime { lv_obj_t* minute_body_trace; lv_obj_t* second_body; - // ## lv_point_t hour_point[2]; lv_point_t hour_point_trace[2]; lv_point_t minute_point[2]; lv_point_t minute_point_trace[2]; lv_point_t second_point[2]; - // ## lv_style_t hour_line_style; lv_style_t hour_line_style_trace; lv_style_t minute_line_style; @@ -83,6 +81,8 @@ namespace Pinetime { Controllers::Settings& settingsController; void UpdateClock(); + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index f1285ea..58ab619 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -12,9 +12,6 @@ #include "components/ble/NotificationManager.h" #include "components/heartrate/HeartRateController.h" #include "components/motion/MotionController.h" -#include "components/settings/Settings.h" -#include "../DisplayApp.h" - using namespace Pinetime::Applications::Screens; WatchFaceDigital::WatchFaceDigital(DisplayApp* app, @@ -36,15 +33,9 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, motionController {motionController} { settingsController.SetClockFace(0); - 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); + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 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(0xFF0000)); @@ -56,10 +47,10 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, 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); + 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(0x00FF00)); lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); - lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0); + lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); label_date = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60); @@ -84,7 +75,7 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, heartbeatIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatIcon, Symbols::heartBeat); lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); 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(0xCE1B1B)); @@ -94,45 +85,42 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, 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(0x00FFE7)); lv_label_set_text(stepValue, "0"); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); 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(0x00FFE7)); lv_label_set_text(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(); } WatchFaceDigital::~WatchFaceDigital() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool WatchFaceDigital::Refresh() { +void WatchFaceDigital::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(); + auto isCharging = batteryController.IsCharging() or 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_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); } - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 5); + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); 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)); + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); } currentDateTime = dateTimeController.CurrentDateTime(); @@ -144,9 +132,9 @@ bool WatchFaceDigital::Refresh() { auto time = date::make_time(newDateTime - dp); auto yearMonthDay = date::year_month_day(dp); - auto year = (int) yearMonthDay.year(); - auto month = static_cast<Pinetime::Controllers::DateTime::Months>((unsigned) yearMonthDay.month()); - auto day = (unsigned) yearMonthDay.day(); + 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()); int hour = time.hours().count(); @@ -175,15 +163,13 @@ bool WatchFaceDigital::Refresh() { sprintf(hoursChar, "%02d", hour); } - if (hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] || - minutesChar[1] != displayedChar[3]) { + if ((hoursChar[0] != displayedChar[0]) or (hoursChar[1] != displayedChar[1]) or (minutesChar[0] != displayedChar[2]) or + (minutesChar[1] != displayedChar[3])) { displayedChar[0] = hoursChar[0]; displayedChar[1] = hoursChar[1]; displayedChar[2] = minutesChar[0]; displayedChar[3] = minutesChar[1]; - char timeStr[6]; - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { lv_label_set_text(label_time_ampm, ampmChar); if (hoursChar[0] == '0') { @@ -191,8 +177,7 @@ bool WatchFaceDigital::Refresh() { } } - sprintf(timeStr, "%c%c:%c%c", hoursChar[0], hoursChar[1], minutesChar[0], minutesChar[1]); - lv_label_set_text(label_time, timeStr); + lv_label_set_text_fmt(label_time, "%s:%s", hoursChar, minutesChar); if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 0, 0); @@ -202,13 +187,11 @@ bool WatchFaceDigital::Refresh() { } if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - char dateStr[22]; if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - sprintf(dateStr, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year); + lv_label_set_text_fmt(label_date, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year); } else { - sprintf(dateStr, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year); + lv_label_set_text_fmt(label_date, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year); } - lv_label_set_text(label_date, dateStr); lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60); currentYear = year; @@ -229,7 +212,7 @@ bool WatchFaceDigital::Refresh() { lv_label_set_text_static(heartbeatValue, ""); } - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); } @@ -237,9 +220,7 @@ bool WatchFaceDigital::Refresh() { motionSensorOk = motionController.IsSensorOk(); if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) { lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get()); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); } - - return running; } diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 76c8d3d..48dc137 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -33,12 +33,10 @@ namespace Pinetime { Controllers::MotionController& motionController); ~WatchFaceDigital() override; - bool Refresh() override; - - void OnObjectEvent(lv_obj_t* pObj, lv_event_t i); + void Refresh() override; private: - char displayedChar[5]; + char displayedChar[5] {}; uint16_t currentYear = 1970; Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown; @@ -63,7 +61,6 @@ namespace Pinetime { lv_obj_t* batteryPlug; lv_obj_t* heartbeatIcon; lv_obj_t* heartbeatValue; - lv_obj_t* heartbeatBpm; lv_obj_t* stepIcon; lv_obj_t* stepValue; lv_obj_t* notificationIcon; @@ -75,6 +72,8 @@ namespace Pinetime { Controllers::Settings& settingsController; Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index acc2a27..22b5636 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -27,30 +27,38 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, batteryController {batteryController}, dateTimeController {dateTimeController}, brightness {brightness}, - motorController{motorController}, + motorController {motorController}, settingsController {settingsController} { + // This is the distance (padding) between all objects on this screen. + static constexpr uint8_t innerDistance = 10; + // Time label_time = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); - lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 15, 4); + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0); batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); - lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 4); + lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); - lv_obj_t* lbl_btn; + static constexpr uint8_t barHeight = 20 + innerDistance; + static constexpr uint8_t buttonHeight = (LV_VER_RES_MAX - barHeight - innerDistance) / 2; + static constexpr uint8_t buttonWidth = (LV_HOR_RES_MAX - innerDistance) / 2; // wide buttons + //static constexpr uint8_t buttonWidth = buttonHeight; // square buttons + static constexpr uint8_t buttonXOffset = (LV_HOR_RES_MAX - buttonWidth * 2 - innerDistance) / 2; + + lv_style_init(&btn_style); + lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, buttonHeight / 4); + lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, lv_color_hex(0x111111)); btn1 = lv_btn_create(lv_scr_act(), nullptr); btn1->user_data = this; lv_obj_set_event_cb(btn1, ButtonEventHandler); - lv_obj_align(btn1, nullptr, LV_ALIGN_CENTER, -50, -30); - lv_obj_set_style_local_radius(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); - - lv_btn_set_fit2(btn1, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_add_style(btn1, LV_BTN_PART_MAIN, &btn_style); + lv_obj_set_size(btn1, buttonWidth, buttonHeight); + lv_obj_align(btn1, nullptr, LV_ALIGN_IN_TOP_LEFT, buttonXOffset, barHeight); btn1_lvl = lv_label_create(btn1, nullptr); lv_obj_set_style_local_text_font(btn1_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -59,12 +67,11 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn2 = lv_btn_create(lv_scr_act(), nullptr); btn2->user_data = this; lv_obj_set_event_cb(btn2, ButtonEventHandler); - lv_obj_align(btn2, nullptr, LV_ALIGN_CENTER, 50, -30); - lv_obj_set_style_local_radius(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); - lv_btn_set_fit2(btn2, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_add_style(btn2, LV_BTN_PART_MAIN, &btn_style); + lv_obj_set_size(btn2, buttonWidth, buttonHeight); + lv_obj_align(btn2, nullptr, LV_ALIGN_IN_TOP_RIGHT, - buttonXOffset, barHeight); + lv_obj_t* lbl_btn; lbl_btn = lv_label_create(btn2, nullptr); lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); lv_label_set_text_static(lbl_btn, Symbols::highlight); @@ -72,14 +79,11 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn3 = lv_btn_create(lv_scr_act(), nullptr); btn3->user_data = this; lv_obj_set_event_cb(btn3, ButtonEventHandler); - lv_obj_align(btn3, nullptr, LV_ALIGN_CENTER, -50, 60); lv_btn_set_checkable(btn3, true); - lv_obj_set_style_local_radius(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); + lv_obj_add_style(btn3, LV_BTN_PART_MAIN, &btn_style); lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN); - lv_obj_set_style_local_bg_grad_dir(btn1, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_GRAD_DIR_NONE); - lv_btn_set_fit2(btn3, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_set_size(btn3, buttonWidth, buttonHeight); + lv_obj_align(btn3, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, buttonXOffset, 0); btn3_lvl = lv_label_create(btn3, nullptr); lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -94,11 +98,9 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn4 = lv_btn_create(lv_scr_act(), nullptr); btn4->user_data = this; lv_obj_set_event_cb(btn4, ButtonEventHandler); - lv_obj_align(btn4, nullptr, LV_ALIGN_CENTER, 50, 60); - lv_obj_set_style_local_radius(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); - lv_btn_set_fit2(btn4, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_add_style(btn4, LV_BTN_PART_MAIN, &btn_style); + lv_obj_set_size(btn4, buttonWidth, buttonHeight); + lv_obj_align(btn4, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, - buttonXOffset, 0); lbl_btn = lv_label_create(btn4, nullptr); lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -114,6 +116,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, } QuickSettings::~QuickSettings() { + lv_style_reset(&btn_style); lv_task_del(taskUpdate); lv_obj_clean(lv_scr_act()); settingsController.SaveSettings(); @@ -125,12 +128,12 @@ void QuickSettings::UpdateScreen() { } void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (object == btn2 && event == LV_EVENT_PRESSED) { + if (object == btn2 && event == LV_EVENT_CLICKED) { running = false; app->StartApp(Apps::FlashLight, DisplayApp::FullRefreshDirections::None); - } else if (object == btn1 && event == LV_EVENT_PRESSED) { + } else if (object == btn1 && event == LV_EVENT_CLICKED) { brightness.Step(); lv_label_set_text_static(btn1_lvl, brightness.GetIcon()); @@ -140,31 +143,16 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON); - motorController.SetDuration(35); + motorController.RunForDuration(35); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); } else { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); } - } else if (object == btn4 && event == LV_EVENT_PRESSED) { + } else if (object == btn4 && event == LV_EVENT_CLICKED) { running = false; settingsController.SetSettingsMenu(0); app->StartApp(Apps::Settings, DisplayApp::FullRefreshDirections::Up); } } - -bool QuickSettings::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - switch (event) { - case Pinetime::Applications::TouchEvents::SwipeLeft: - running = false; - return false; - - default: - return true; - } -} - -bool QuickSettings::Refresh() { - return running; -} diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h index a14f46b..c036fa5 100644 --- a/src/displayapp/screens/settings/QuickSettings.h +++ b/src/displayapp/screens/settings/QuickSettings.h @@ -27,9 +27,6 @@ namespace Pinetime { ~QuickSettings() override; - bool Refresh() override; - - bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; void OnButtonEvent(lv_obj_t* object, lv_event_t event); void UpdateScreen(); @@ -45,6 +42,8 @@ namespace Pinetime { lv_obj_t* batteryIcon; lv_obj_t* label_time; + lv_style_t btn_style; + lv_obj_t* btn1; lv_obj_t* btn1_lvl; lv_obj_t* btn2; diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index 4954185..d8d6c76 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -80,12 +80,8 @@ SettingDisplay::~SettingDisplay() { settingsController.SaveSettings(); } -bool SettingDisplay::Refresh() { - return running; -} - void SettingDisplay::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { + if (event == LV_EVENT_CLICKED) { for (int i = 0; i < optionsTotal; i++) { if (object == cbOption[i]) { lv_checkbox_set_checked(cbOption[i], true); @@ -110,4 +106,4 @@ void SettingDisplay::UpdateSelected(lv_obj_t* object, lv_event_t event) { } } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingDisplay.h b/src/displayapp/screens/settings/SettingDisplay.h index b8ed87e..51b23ac 100644 --- a/src/displayapp/screens/settings/SettingDisplay.h +++ b/src/displayapp/screens/settings/SettingDisplay.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingDisplay() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/SettingPineTimeStyle.cpp b/src/displayapp/screens/settings/SettingPineTimeStyle.cpp new file mode 100644 index 0000000..c9af19b --- /dev/null +++ b/src/displayapp/screens/settings/SettingPineTimeStyle.cpp @@ -0,0 +1,318 @@ +#include "SettingPineTimeStyle.h" +#include <lvgl/lvgl.h> +#include <displayapp/Colors.h> +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t* obj, lv_event_t event) { + SettingPineTimeStyle* screen = static_cast<SettingPineTimeStyle*>(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingPineTimeStyle::SettingPineTimeStyle(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) + : Screen(app), settingsController {settingsController} { + timebar = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBG())); + lv_obj_set_style_local_radius(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(timebar, 200, 240); + lv_obj_align(timebar, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 5, 0); + + // Display the time + + timeDD1 = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); + lv_label_set_text(timeDD1, "12"); + lv_obj_align(timeDD1, timebar, LV_ALIGN_IN_TOP_MID, 5, 5); + + timeDD2 = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); + lv_label_set_text(timeDD2, "34"); + lv_obj_align(timeDD2, timebar, LV_ALIGN_IN_BOTTOM_MID, 5, -5); + + timeAMPM = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); + lv_obj_set_style_local_text_line_space(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, -3); + lv_label_set_text(timeAMPM, "A\nM"); + lv_obj_align(timeAMPM, timebar, LV_ALIGN_IN_BOTTOM_LEFT, 2, -20); + + // Create a 40px wide bar down the right side of the screen + + sidebar = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBar())); + lv_obj_set_style_local_radius(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(sidebar, 40, 240); + lv_obj_align(sidebar, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); + + // Display icons + + batteryIcon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(batteryIcon, Symbols::batteryFull); + lv_obj_align(batteryIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2); + + 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(0x000000)); + lv_label_set_text(bleIcon, Symbols::bluetooth); + lv_obj_align(bleIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 25); + + // Calendar icon + + calendarOuter = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarOuter, 34, 34); + lv_obj_align(calendarOuter, sidebar, LV_ALIGN_CENTER, 0, 0); + + calendarInner = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarInner, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xffffff)); + lv_obj_set_style_local_radius(calendarInner, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarInner, 27, 27); + lv_obj_align(calendarInner, calendarOuter, LV_ALIGN_CENTER, 0, 0); + + calendarBar1 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarBar1, 3, 12); + lv_obj_align(calendarBar1, calendarOuter, LV_ALIGN_IN_TOP_MID, -6, -3); + + calendarBar2 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarBar2, 3, 12); + lv_obj_align(calendarBar2, calendarOuter, LV_ALIGN_IN_TOP_MID, 6, -3); + + calendarCrossBar1 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarCrossBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarCrossBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarCrossBar1, 8, 3); + lv_obj_align(calendarCrossBar1, calendarBar1, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + calendarCrossBar2 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarCrossBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarCrossBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarCrossBar2, 8, 3); + lv_obj_align(calendarCrossBar2, calendarBar2, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + // Display date + + dateDayOfWeek = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(dateDayOfWeek, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(dateDayOfWeek, "THU"); + lv_obj_align(dateDayOfWeek, sidebar, LV_ALIGN_CENTER, 0, -34); + + dateDay = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(dateDay, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(dateDay, "25"); + lv_obj_align(dateDay, sidebar, LV_ALIGN_CENTER, 0, 3); + + dateMonth = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(dateMonth, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(dateMonth, "MAR"); + lv_obj_align(dateMonth, sidebar, LV_ALIGN_CENTER, 0, 32); + + // Step count gauge + needle_colors[0] = LV_COLOR_WHITE; + stepGauge = lv_gauge_create(lv_scr_act(), nullptr); + lv_gauge_set_needle_count(stepGauge, 1, needle_colors); + lv_obj_set_size(stepGauge, 40, 40); + lv_obj_align(stepGauge, sidebar, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_gauge_set_scale(stepGauge, 360, 11, 0); + lv_gauge_set_angle_offset(stepGauge, 180); + lv_gauge_set_critical_value(stepGauge, (100)); + lv_gauge_set_range(stepGauge, 0, (100)); + lv_gauge_set_value(stepGauge, 0, 0); + + lv_obj_set_style_local_pad_right(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_pad_left(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_pad_bottom(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_opa(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_obj_set_style_local_scale_width(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_line_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_obj_set_style_local_line_opa(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_pad_inner(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 4); + + 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(backgroundLabel, ""); + + btnNextTime = lv_btn_create(lv_scr_act(), nullptr); + btnNextTime->user_data = this; + lv_obj_set_size(btnNextTime, 60, 60); + lv_obj_align(btnNextTime, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, -80); + lv_obj_set_style_local_bg_opa(btnNextTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnNextTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_set_event_cb(btnNextTime, event_handler); + + btnPrevTime = lv_btn_create(lv_scr_act(), nullptr); + btnPrevTime->user_data = this; + lv_obj_set_size(btnPrevTime, 60, 60); + lv_obj_align(btnPrevTime, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, -80); + lv_obj_set_style_local_bg_opa(btnPrevTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnPrevTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_set_event_cb(btnPrevTime, event_handler); + + btnNextBar = lv_btn_create(lv_scr_act(), nullptr); + btnNextBar->user_data = this; + lv_obj_set_size(btnNextBar, 60, 60); + lv_obj_align(btnNextBar, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, 0); + lv_obj_set_style_local_bg_opa(btnNextBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnNextBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_set_event_cb(btnNextBar, event_handler); + + btnPrevBar = lv_btn_create(lv_scr_act(), nullptr); + btnPrevBar->user_data = this; + lv_obj_set_size(btnPrevBar, 60, 60); + lv_obj_align(btnPrevBar, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, 0); + lv_obj_set_style_local_bg_opa(btnPrevBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnPrevBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_set_event_cb(btnPrevBar, event_handler); + + btnNextBG = lv_btn_create(lv_scr_act(), nullptr); + btnNextBG->user_data = this; + lv_obj_set_size(btnNextBG, 60, 60); + lv_obj_align(btnNextBG, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, 80); + lv_obj_set_style_local_bg_opa(btnNextBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnNextBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_set_event_cb(btnNextBG, event_handler); + + btnPrevBG = lv_btn_create(lv_scr_act(), nullptr); + btnPrevBG->user_data = this; + lv_obj_set_size(btnPrevBG, 60, 60); + lv_obj_align(btnPrevBG, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, 80); + lv_obj_set_style_local_bg_opa(btnPrevBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnPrevBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_set_event_cb(btnPrevBG, event_handler); + + btnReset = lv_btn_create(lv_scr_act(), nullptr); + btnReset->user_data = this; + lv_obj_set_size(btnReset, 60, 60); + lv_obj_align(btnReset, lv_scr_act(), LV_ALIGN_CENTER, 0, 80); + lv_obj_set_style_local_bg_opa(btnReset, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnReset, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Rst"); + lv_obj_set_event_cb(btnReset, event_handler); + + btnRandom = lv_btn_create(lv_scr_act(), nullptr); + btnRandom->user_data = this; + lv_obj_set_size(btnRandom, 60, 60); + lv_obj_align(btnRandom, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_bg_opa(btnRandom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnRandom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Rnd"); + lv_obj_set_event_cb(btnRandom, event_handler); +} + +SettingPineTimeStyle::~SettingPineTimeStyle() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +void SettingPineTimeStyle::UpdateSelected(lv_obj_t* object, lv_event_t event) { + auto valueTime = settingsController.GetPTSColorTime(); + auto valueBar = settingsController.GetPTSColorBar(); + auto valueBG = settingsController.GetPTSColorBG(); + + if (event == LV_EVENT_CLICKED) { + if (object == btnNextTime) { + valueTime = GetNext(valueTime); + + settingsController.SetPTSColorTime(valueTime); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + } + if (object == btnPrevTime) { + valueTime = GetPrevious(valueTime); + settingsController.SetPTSColorTime(valueTime); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + } + if (object == btnNextBar) { + valueBar = GetNext(valueBar); + if(valueBar == Controllers::Settings::Colors::Black) + valueBar = GetNext(valueBar); + settingsController.SetPTSColorBar(valueBar); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBar)); + } + if (object == btnPrevBar) { + valueBar = GetPrevious(valueBar); + if(valueBar == Controllers::Settings::Colors::Black) + valueBar = GetPrevious(valueBar); + settingsController.SetPTSColorBar(valueBar); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBar)); + } + if (object == btnNextBG) { + valueBG = GetNext(valueBG); + settingsController.SetPTSColorBG(valueBG); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBG)); + } + if (object == btnPrevBG) { + valueBG = GetPrevious(valueBG); + settingsController.SetPTSColorBG(valueBG); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBG)); + } + if (object == btnReset) { + settingsController.SetPTSColorTime(Controllers::Settings::Colors::Teal); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + settingsController.SetPTSColorBar(Controllers::Settings::Colors::Teal); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + settingsController.SetPTSColorBG(Controllers::Settings::Colors::Black); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Black)); + } + if (object == btnRandom) { + uint8_t randTime = rand() % 17; + uint8_t randBar = rand() % 17; + uint8_t randBG = rand() % 17; + // Check if the time color is the same as its background, or if the sidebar is black. If so, change them to more useful values. + if (randTime == randBG) { + randBG += 1; + } + if (randBar == 3) { + randBar -= 1; + } + settingsController.SetPTSColorTime(static_cast<Controllers::Settings::Colors>(randTime)); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast<Controllers::Settings::Colors>(randTime))); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast<Controllers::Settings::Colors>(randTime))); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast<Controllers::Settings::Colors>(randTime))); + settingsController.SetPTSColorBar(static_cast<Controllers::Settings::Colors>(randBar)); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast<Controllers::Settings::Colors>(randBar))); + settingsController.SetPTSColorBG(static_cast<Controllers::Settings::Colors>(randBG)); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast<Controllers::Settings::Colors>(randBG))); + } + } +} + +Pinetime::Controllers::Settings::Colors SettingPineTimeStyle::GetNext(Pinetime::Controllers::Settings::Colors color) { + auto colorAsInt = static_cast<uint8_t>(color); + Pinetime::Controllers::Settings::Colors nextColor; + if (colorAsInt < 16) { + nextColor = static_cast<Controllers::Settings::Colors>(colorAsInt + 1); + } else { + nextColor = static_cast<Controllers::Settings::Colors>(0); + } + return nextColor; +} + +Pinetime::Controllers::Settings::Colors SettingPineTimeStyle::GetPrevious(Pinetime::Controllers::Settings::Colors color) { + auto colorAsInt = static_cast<uint8_t>(color); + Pinetime::Controllers::Settings::Colors prevColor; + + if (colorAsInt > 0) { + prevColor = static_cast<Controllers::Settings::Colors>(colorAsInt - 1); + } else { + prevColor = static_cast<Controllers::Settings::Colors>(16); + } + return prevColor; +} diff --git a/src/displayapp/screens/settings/SettingPineTimeStyle.h b/src/displayapp/screens/settings/SettingPineTimeStyle.h new file mode 100644 index 0000000..397bd86 --- /dev/null +++ b/src/displayapp/screens/settings/SettingPineTimeStyle.h @@ -0,0 +1,56 @@ +#pragma once + +#include <cstdint> +#include <lvgl/lvgl.h> +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingPineTimeStyle : public Screen{ + public: + SettingPineTimeStyle(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); + ~SettingPineTimeStyle() override; + + void UpdateSelected(lv_obj_t *object, lv_event_t event); + + private: + Controllers::Settings& settingsController; + + Pinetime::Controllers::Settings::Colors GetNext(Controllers::Settings::Colors color); + Pinetime::Controllers::Settings::Colors GetPrevious(Controllers::Settings::Colors color); + + lv_obj_t * btnNextTime; + lv_obj_t * btnPrevTime; + lv_obj_t * btnNextBar; + lv_obj_t * btnPrevBar; + lv_obj_t * btnNextBG; + lv_obj_t * btnPrevBG; + lv_obj_t * btnReset; + lv_obj_t * btnRandom; + lv_obj_t * timebar; + lv_obj_t * sidebar; + lv_obj_t * timeDD1; + lv_obj_t * timeDD2; + lv_obj_t * timeAMPM; + lv_obj_t * dateDayOfWeek; + lv_obj_t * dateDay; + lv_obj_t * dateMonth; + lv_obj_t * backgroundLabel; + lv_obj_t * batteryIcon; + lv_obj_t * bleIcon; + lv_obj_t * calendarOuter; + lv_obj_t * calendarInner; + lv_obj_t * calendarBar1; + lv_obj_t * calendarBar2; + lv_obj_t * calendarCrossBar1; + lv_obj_t * calendarCrossBar2; + lv_obj_t * stepGauge; + lv_color_t needle_colors[1]; + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingSteps.cpp b/src/displayapp/screens/settings/SettingSteps.cpp index faa843e..bec7972 100644 --- a/src/displayapp/screens/settings/SettingSteps.cpp +++ b/src/displayapp/screens/settings/SettingSteps.cpp @@ -70,11 +70,6 @@ SettingSteps::~SettingSteps() { settingsController.SaveSettings(); } -bool SettingSteps::Refresh() { - return running; -} - - void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) { uint32_t value = settingsController.GetStepsGoal(); if(object == btnPlus && (event == LV_EVENT_PRESSED)) { @@ -95,4 +90,4 @@ void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) { } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingSteps.h b/src/displayapp/screens/settings/SettingSteps.h index 0a4c205..5fc05de 100644 --- a/src/displayapp/screens/settings/SettingSteps.h +++ b/src/displayapp/screens/settings/SettingSteps.h @@ -10,22 +10,19 @@ namespace Pinetime { namespace Applications { namespace Screens { - class SettingSteps : public Screen{ - public: - SettingSteps(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); - ~SettingSteps() override; + class SettingSteps : public Screen { + public: + SettingSteps(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); + ~SettingSteps() override; - bool Refresh() override; - void UpdateSelected(lv_obj_t *object, lv_event_t event); - - private: + void UpdateSelected(lv_obj_t* object, lv_event_t event); - Controllers::Settings& settingsController; + private: + Controllers::Settings& settingsController; - lv_obj_t * stepValue; - lv_obj_t * btnPlus; - lv_obj_t * btnMinus; - + lv_obj_t* stepValue; + lv_obj_t* btnPlus; + lv_obj_t* btnMinus; }; } } diff --git a/src/displayapp/screens/settings/SettingTimeFormat.cpp b/src/displayapp/screens/settings/SettingTimeFormat.cpp index 031a2a7..c99e3a0 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.cpp +++ b/src/displayapp/screens/settings/SettingTimeFormat.cpp @@ -64,10 +64,6 @@ SettingTimeFormat::~SettingTimeFormat() { settingsController.SaveSettings(); } -bool SettingTimeFormat::Refresh() { - return running; -} - void SettingTimeFormat::UpdateSelected(lv_obj_t* object, lv_event_t event) { if (event == LV_EVENT_VALUE_CHANGED) { for (int i = 0; i < optionsTotal; i++) { @@ -86,4 +82,4 @@ void SettingTimeFormat::UpdateSelected(lv_obj_t* object, lv_event_t event) { } } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingTimeFormat.h b/src/displayapp/screens/settings/SettingTimeFormat.h index 9203b45..eac4bdc 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.h +++ b/src/displayapp/screens/settings/SettingTimeFormat.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingTimeFormat(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingTimeFormat() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index 0e08035..d999004 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -36,7 +36,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: 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, Symbols::clock); + lv_label_set_text_static(icon, Symbols::eye); lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); @@ -72,10 +72,6 @@ SettingWakeUp::~SettingWakeUp() { settingsController.SaveSettings(); } -bool SettingWakeUp::Refresh() { - return running; -} - void SettingWakeUp::UpdateSelected(lv_obj_t* object, lv_event_t event) { using WakeUpMode = Pinetime::Controllers::Settings::WakeUpMode; if (event == LV_EVENT_VALUE_CHANGED && !ignoringEvents) { diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index 248dd9a..b9a31dc 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingWakeUp(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingWakeUp() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index 3e73489..cdec704 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -36,7 +36,7 @@ SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app, Pine 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, Symbols::clock); + lv_label_set_text_static(icon, Symbols::home); lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); @@ -75,10 +75,6 @@ SettingWatchFace::~SettingWatchFace() { settingsController.SaveSettings(); } -bool SettingWatchFace::Refresh() { - return running; -} - void SettingWatchFace::UpdateSelected(lv_obj_t* object, lv_event_t event) { if (event == LV_EVENT_VALUE_CHANGED) { for (uint8_t i = 0; i < optionsTotal; i++) { @@ -90,4 +86,4 @@ void SettingWatchFace::UpdateSelected(lv_obj_t* object, lv_event_t event) { } } } -}
\ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 1930a22..d4a96c6 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingWatchFace(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingWatchFace() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index e63a358..f82b03c 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -18,6 +18,9 @@ Settings::Settings(Pinetime::Applications::DisplayApp* app, Pinetime::Controller }, [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); + }, + [this]() -> std::unique_ptr<Screen> { + return CreateScreen3(); }}, Screens::ScreenListModes::UpDown} { } @@ -26,13 +29,6 @@ Settings::~Settings() { lv_obj_clean(lv_scr_act()); } -bool Settings::Refresh() { - - if (running) - running = screens.Refresh(); - return running; -} - bool Settings::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } @@ -41,12 +37,12 @@ std::unique_ptr<Screen> Settings::CreateScreen1() { std::array<Screens::List::Applications, 4> applications {{ {Symbols::sun, "Display", Apps::SettingDisplay}, - {Symbols::clock, "Wake Up", Apps::SettingWakeUp}, + {Symbols::eye, "Wake Up", Apps::SettingWakeUp}, {Symbols::clock, "Time format", Apps::SettingTimeFormat}, - {Symbols::clock, "Watch face", Apps::SettingWatchFace}, + {Symbols::home, "Watch face", Apps::SettingWatchFace}, }}; - return std::make_unique<Screens::List>(0, 2, app, settingsController, applications); + return std::make_unique<Screens::List>(0, 3, app, settingsController, applications); } std::unique_ptr<Screen> Settings::CreateScreen2() { @@ -58,5 +54,17 @@ std::unique_ptr<Screen> Settings::CreateScreen2() { {Symbols::list, "About", Apps::SysInfo}, }}; - return std::make_unique<Screens::List>(1, 2, app, settingsController, applications); + return std::make_unique<Screens::List>(1, 3, app, settingsController, applications); +} + +std::unique_ptr<Screen> Settings::CreateScreen3() { + + std::array<Screens::List::Applications, 4> applications {{ + {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, + {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None}, + }}; + + return std::make_unique<Screens::List>(2, 3, app, settingsController, applications); } diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index 711a6be..6c54cde 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -14,17 +14,16 @@ namespace Pinetime { Settings(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~Settings() override; - bool Refresh() override; - bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; private: Controllers::Settings& settingsController; - ScreenList<2> screens; + ScreenList<3> screens; std::unique_ptr<Screen> CreateScreen1(); std::unique_ptr<Screen> CreateScreen2(); + std::unique_ptr<Screen> CreateScreen3(); }; } } diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index fd9792b..b8f8e45 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -40,38 +40,40 @@ void Cst816S::Init() { */ static constexpr uint8_t motionMask = 0b00000101; twiMaster.Write(twiAddress, 0xEC, &motionMask, 1); + + /* + [7] EnTest - Interrupt pin to test, enable automatic periodic issued after a low pulse. + [6] EnTouch - When a touch is detected, a periodic pulsed Low. + [5] EnChange - Upon detecting a touch state changes, pulsed Low. + [4] EnMotion - When the detected gesture is pulsed Low. + [0] OnceWLP - Press gesture only issue a pulse signal is low. + */ + static constexpr uint8_t irqCtl = 0b01110000; + twiMaster.Write(twiAddress, 0xFA, &irqCtl, 1); } Cst816S::TouchInfos Cst816S::GetTouchInfo() { Cst816S::TouchInfos info; auto ret = twiMaster.Read(twiAddress, 0, touchData, sizeof(touchData)); - if (ret != TwiMaster::ErrorCodes::NoError) - return {}; - - auto nbTouchPoints = touchData[2] & 0x0f; - - uint8_t i = 0; - - uint8_t pointId = (touchData[touchIdIndex + (touchStep * i)]) >> 4; - if (nbTouchPoints == 0 && pointId == lastTouchId) + if (ret != TwiMaster::ErrorCodes::NoError) { + info.isValid = false; return info; + } - info.isTouch = true; + auto nbTouchPoints = touchData[2] & 0x0f; - auto xHigh = touchData[touchXHighIndex + (touchStep * i)] & 0x0f; - auto xLow = touchData[touchXLowIndex + (touchStep * i)]; + auto xHigh = touchData[touchXHighIndex] & 0x0f; + auto xLow = touchData[touchXLowIndex]; uint16_t x = (xHigh << 8) | xLow; - auto yHigh = touchData[touchYHighIndex + (touchStep * i)] & 0x0f; - auto yLow = touchData[touchYLowIndex + (touchStep * i)]; + auto yHigh = touchData[touchYHighIndex] & 0x0f; + auto yLow = touchData[touchYLowIndex]; uint16_t y = (yHigh << 8) | yLow; - auto action = touchData[touchEventIndex + (touchStep * i)] >> 6; /* 0 = Down, 1 = Up, 2 = contact*/ - info.x = x; info.y = y; - info.action = action; + info.touching = (nbTouchPoints > 0); info.gesture = static_cast<Gestures>(touchData[gestureIndex]); return info; @@ -90,4 +92,4 @@ void Cst816S::Sleep() { void Cst816S::Wakeup() { Init(); NRF_LOG_INFO("[TOUCHPANEL] Wakeup"); -}
\ No newline at end of file +} diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index 14c296e..d4c17bb 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -19,12 +19,9 @@ namespace Pinetime { struct TouchInfos { uint16_t x = 0; uint16_t y = 0; - uint8_t action = 0; - uint8_t finger = 0; - uint8_t pressure = 0; - uint8_t area = 0; Gestures gesture = Gestures::None; - bool isTouch = false; + bool touching = false; + bool isValid = true; }; Cst816S(TwiMaster& twiMaster, uint8_t twiAddress); @@ -41,23 +38,24 @@ namespace Pinetime { private: static constexpr uint8_t pinIrq = 28; static constexpr uint8_t pinReset = 10; - static constexpr uint8_t lastTouchId = 0x0f; + + // Unused/Unavailable commented out + static constexpr uint8_t gestureIndex = 1; static constexpr uint8_t touchPointNumIndex = 2; - static constexpr uint8_t touchMiscIndex = 8; - static constexpr uint8_t touchXYIndex = 7; - static constexpr uint8_t touchEventIndex = 3; + //static constexpr uint8_t touchEventIndex = 3; static constexpr uint8_t touchXHighIndex = 3; static constexpr uint8_t touchXLowIndex = 4; + //static constexpr uint8_t touchIdIndex = 5; static constexpr uint8_t touchYHighIndex = 5; static constexpr uint8_t touchYLowIndex = 6; - static constexpr uint8_t touchIdIndex = 5; - static constexpr uint8_t touchStep = 6; - static constexpr uint8_t gestureIndex = 1; + //static constexpr uint8_t touchStep = 6; + //static constexpr uint8_t touchXYIndex = 7; + //static constexpr uint8_t touchMiscIndex = 8; - uint8_t touchData[10]; + uint8_t touchData[7]; TwiMaster& twiMaster; uint8_t twiAddress; }; } -}
\ No newline at end of file +} diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index fc9edf8..7600927 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -8,45 +8,39 @@ using namespace Pinetime::Drivers; // TODO use shortcut to automatically send STOP when receive LastTX, for example // TODO use DMA/IRQ -TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module {module}, params {params} { +TwiMaster::TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl) + : module {module}, frequency {frequency}, pinSda {pinSda}, pinScl {pinScl} { +} + +void TwiMaster::ConfigurePins() const { + NRF_GPIO->PIN_CNF[pinScl] = + (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + + NRF_GPIO->PIN_CNF[pinSda] = + (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); } void TwiMaster::Init() { - if(mutex == nullptr) + if (mutex == nullptr) { mutex = xSemaphoreCreateBinary(); - - NRF_GPIO->PIN_CNF[params.pinScl] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - - NRF_GPIO->PIN_CNF[params.pinSda] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - - switch (module) { - case Modules::TWIM1: - twiBaseAddress = NRF_TWIM1; - break; - default: - return; } - switch (static_cast<Frequencies>(params.frequency)) { - case Frequencies::Khz100: - twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K100; - break; - case Frequencies::Khz250: - twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K250; - break; - case Frequencies::Khz400: - twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400; - break; - } + ConfigurePins(); - twiBaseAddress->PSEL.SCL = params.pinScl; - twiBaseAddress->PSEL.SDA = params.pinSda; + twiBaseAddress = module; + + twiBaseAddress->FREQUENCY = frequency; + + twiBaseAddress->PSEL.SCL = pinScl; + twiBaseAddress->PSEL.SDA = pinSda; twiBaseAddress->EVENTS_LASTRX = 0; twiBaseAddress->EVENTS_STOPPED = 0; twiBaseAddress->EVENTS_LASTTX = 0; @@ -57,19 +51,15 @@ void TwiMaster::Init() { twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); - /* // IRQ - NVIC_ClearPendingIRQ(_IRQn); - NVIC_SetPriority(_IRQn, 2); - NVIC_EnableIRQ(_IRQn); - */ - xSemaphoreGive(mutex); } TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* data, size_t size) { xSemaphoreTake(mutex, portMAX_DELAY); + Wakeup(); auto ret = Write(deviceAddress, ®isterAddress, 1, false); ret = Read(deviceAddress, data, size, true); + Sleep(); xSemaphoreGive(mutex); return ret; } @@ -77,9 +67,11 @@ TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAdd TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size) { ASSERT(size <= maxDataSize); xSemaphoreTake(mutex, portMAX_DELAY); + Wakeup(); internalBuffer[0] = registerAddress; std::memcpy(internalBuffer + 1, data, size); auto ret = Write(deviceAddress, internalBuffer, size + 1, true); + Sleep(); xSemaphoreGive(mutex); return ret; } @@ -170,17 +162,11 @@ TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t* dat } void TwiMaster::Sleep() { - while (twiBaseAddress->ENABLE != 0) { - twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); - } - nrf_gpio_cfg_default(6); - nrf_gpio_cfg_default(7); - NRF_LOG_INFO("[TWIMASTER] Sleep"); + twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); } void TwiMaster::Wakeup() { - Init(); - NRF_LOG_INFO("[TWIMASTER] Wakeup"); + twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); } /* Sometimes, the TWIM device just freeze and never set the event EVENTS_LASTTX. @@ -190,20 +176,10 @@ void TwiMaster::Wakeup() { * */ void TwiMaster::FixHwFreezed() { NRF_LOG_INFO("I2C device frozen, reinitializing it!"); - // Disable I²C - uint32_t twi_state = NRF_TWI1->ENABLE; - twiBaseAddress->ENABLE = TWIM_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; - NRF_GPIO->PIN_CNF[params.pinScl] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + uint32_t twi_state = NRF_TWI1->ENABLE; - NRF_GPIO->PIN_CNF[params.pinSda] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + Sleep(); - // Re-enable I²C twiBaseAddress->ENABLE = twi_state; -}
\ No newline at end of file +} diff --git a/src/drivers/TwiMaster.h b/src/drivers/TwiMaster.h index 6175b99..30ac6c5 100644 --- a/src/drivers/TwiMaster.h +++ b/src/drivers/TwiMaster.h @@ -8,16 +8,9 @@ namespace Pinetime { namespace Drivers { class TwiMaster { public: - enum class Modules { TWIM1 }; - enum class Frequencies { Khz100, Khz250, Khz400 }; enum class ErrorCodes { NoError, TransactionFailed }; - struct Parameters { - uint32_t frequency; - uint8_t pinSda; - uint8_t pinScl; - }; - TwiMaster(const Modules module, const Parameters& params); + TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl); void Init(); ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); @@ -30,10 +23,14 @@ namespace Pinetime { ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop); ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); void FixHwFreezed(); + void ConfigurePins() const; + NRF_TWIM_Type* twiBaseAddress; SemaphoreHandle_t mutex = nullptr; - const Modules module; - const Parameters params; + NRF_TWIM_Type* module; + uint32_t frequency; + uint8_t pinSda; + uint8_t pinScl; static constexpr uint8_t maxDataSize {16}; static constexpr uint8_t registerSize {1}; uint8_t internalBuffer[maxDataSize + registerSize]; @@ -41,4 +38,4 @@ namespace Pinetime { static constexpr uint32_t HwFreezedDelay {161000}; }; } -}
\ No newline at end of file +} diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 18fc3fa..73109c5 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -295,6 +295,7 @@ typedef void* lv_img_decoder_user_data_t; #define LV_TICK_CUSTOM 1 #if LV_TICK_CUSTOM == 1 #define LV_TICK_CUSTOM_INCLUDE "FreeRTOS.h" /*Header for the system time function*/ +uint32_t xTaskGetTickCount(); /*Forward declare to avoid compiler warning*/ #define LV_TICK_CUSTOM_SYS_TIME_EXPR (xTaskGetTickCount()) /*Expression evaluating to current system time in ms*/ #endif /*LV_TICK_CUSTOM*/ diff --git a/src/main.cpp b/src/main.cpp index ffbba5e..79e2ad8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include <libraries/gpiote/app_gpiote.h> #include <libraries/timer/app_timer.h> #include <softdevice/common/nrf_sdh.h> +#include <nrf_delay.h> // nimble #define min // workaround: nimble's min/max macros conflict with libstdc++ @@ -43,6 +44,7 @@ #include "drivers/TwiMaster.h" #include "drivers/Cst816s.h" #include "systemtask/SystemTask.h" +#include "touchhandler/TouchHandler.h" #if NRF_LOG_ENABLED #include "logging/NrfLogger.h" @@ -82,8 +84,7 @@ Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; // respecting correct timings. According to erratas heet, this magic value makes it run // at ~390Khz with correct timings. static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000}; -Pinetime::Drivers::TwiMaster twiMaster {Pinetime::Drivers::TwiMaster::Modules::TWIM1, - Pinetime::Drivers::TwiMaster::Parameters {MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}}; +Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}; Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #ifdef PINETIME_IS_RECOVERY static constexpr bool isFactory = true; @@ -118,6 +119,7 @@ Pinetime::Drivers::WatchdogView watchdogView(watchdog); Pinetime::Controllers::NotificationManager notificationManager; Pinetime::Controllers::MotionController motionController; Pinetime::Controllers::TimerController timerController; +Pinetime::Controllers::TouchHandler touchHandler(touchPanel, lvgl); Pinetime::Controllers::FS fs {spiNorFlash}; Pinetime::Controllers::Settings settingsController {fs}; @@ -136,7 +138,8 @@ Pinetime::Applications::DisplayApp displayApp(lcd, settingsController, motorController, motionController, - timerController); + timerController, + touchHandler); Pinetime::System::SystemTask systemTask(spi, lcd, @@ -158,7 +161,8 @@ Pinetime::System::SystemTask systemTask(spi, heartRateController, displayApp, heartRateApp, - fs); + fs, + touchHandler); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if (pin == pinTouchIrq) { @@ -300,6 +304,20 @@ int main(void) { nrf_drv_clock_init(); + // Unblock i2c? + nrf_gpio_cfg(pinTwiScl, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0D1, + NRF_GPIO_PIN_NOSENSE); + nrf_gpio_pin_set(pinTwiScl); + for (uint8_t i = 0; i < 16; i++) { + nrf_gpio_pin_toggle(pinTwiScl); + nrf_delay_us(5); + } + nrf_gpio_cfg_default(pinTwiScl); + debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); @@ -309,6 +327,7 @@ int main(void) { lvgl.Init(); systemTask.Start(); + nimble_port_init(); vTaskStartScheduler(); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 7efd1d6..0617b0c 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -33,6 +33,13 @@ namespace { } } +void DimTimerCallback(TimerHandle_t xTimer) { + + NRF_LOG_INFO("DimTimerCallback"); + auto sysTask = static_cast<SystemTask*>(pvTimerGetTimerID(xTimer)); + sysTask->OnDim(); +} + void IdleTimerCallback(TimerHandle_t xTimer) { NRF_LOG_INFO("IdleTimerCallback"); @@ -60,7 +67,8 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, Pinetime::Applications::HeartRateTask& heartRateApp, - Pinetime::Controllers::FS& fs) + Pinetime::Controllers::FS& fs, + Pinetime::Controllers::TouchHandler& touchHandler) : spi {spi}, lcd {lcd}, spiNorFlash {spiNorFlash}, @@ -72,18 +80,18 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, dateTimeController {dateTimeController}, timerController {timerController}, watchdog {watchdog}, - notificationManager{notificationManager}, + notificationManager {notificationManager}, motorController {motorController}, heartRateSensor {heartRateSensor}, motionSensor {motionSensor}, settingsController {settingsController}, - heartRateController{heartRateController}, - motionController{motionController}, - displayApp{displayApp}, + heartRateController {heartRateController}, + motionController {motionController}, + displayApp {displayApp}, heartRateApp(heartRateApp), - fs{fs}, + fs {fs}, + touchHandler {touchHandler}, nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { - } void SystemTask::Start() { @@ -105,16 +113,15 @@ void SystemTask::Work() { APP_GPIOTE_INIT(2); app_timer_init(); - + spi.Init(); spiNorFlash.Init(); spiNorFlash.Wakeup(); - + fs.Init(); nimbleController.Init(); nimbleController.StartAdvertising(); - brightnessController.Init(); lcd.Init(); twiMaster.Init(); @@ -179,8 +186,9 @@ void SystemTask::Work() { nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); } - idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut()), pdFALSE, this, IdleTimerCallback); - xTimerStart(idleTimer, 0); + idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); + dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback); + xTimerStart(dimTimer, 0); // Suppress endless loop diagnostic #pragma clang diagnostic push @@ -208,11 +216,10 @@ void SystemTask::Work() { doNotGoToSleep = true; break; case Messages::UpdateTimeOut: - xTimerChangePeriod(idleTimer, pdMS_TO_TICKS(settingsController.GetScreenTimeOut()), 0); + xTimerChangePeriod(dimTimer, pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), 0); break; case Messages::GoToRunning: spi.Wakeup(); - twiMaster.Wakeup(); // Double Tap needs the touch screen to be in normal mode if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { @@ -220,7 +227,7 @@ void SystemTask::Work() { } nimbleController.StartAdvertising(); - xTimerStart(idleTimer, 0); + xTimerStart(dimTimer, 0); spiNorFlash.Wakeup(); lcd.Wakeup(); @@ -230,22 +237,24 @@ void SystemTask::Work() { isSleeping = false; isWakingUp = false; + isDimmed = false; break; case Messages::TouchWakeUp: { - twiMaster.Wakeup(); - auto touchInfo = touchPanel.GetTouchInfo(); - twiMaster.Sleep(); - if (touchInfo.isTouch and ((touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and - settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) or - (touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and - settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)))) { - GoToRunning(); + if(touchHandler.GetNewTouchInfo()) { + auto gesture = touchHandler.GestureGet(); + if (gesture != Pinetime::Drivers::Cst816S::Gestures::None and ((gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) or + (gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)))) { + GoToRunning(); + } } } break; case Messages::GoToSleep: isGoingToSleep = true; NRF_LOG_INFO("[systemtask] Going to sleep"); xTimerStop(idleTimer, 0); + xTimerStop(dimTimer, 0); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); break; @@ -257,14 +266,13 @@ void SystemTask::Work() { if (isSleeping && !isWakingUp) { GoToRunning(); } - motorController.SetDuration(35); displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification); break; case Messages::OnTimerDone: if (isSleeping && !isWakingUp) { GoToRunning(); } - motorController.SetDuration(35); + motorController.RunForDuration(35); displayApp.PushMessage(Pinetime::Applications::Display::Messages::TimerDone); break; case Messages::BleConnected: @@ -283,13 +291,18 @@ void SystemTask::Work() { NVIC_SystemReset(); } doNotGoToSleep = false; - xTimerStart(idleTimer, 0); + xTimerStart(dimTimer, 0); break; case Messages::OnTouchEvent: + if (touchHandler.GetNewTouchInfo()) { + touchHandler.UpdateLvglTouchPoint(); + } ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); break; case Messages::OnButtonEvent: ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed); break; case Messages::OnDisplayTaskSleeping: if (BootloaderVersion::IsValid()) { @@ -304,7 +317,6 @@ void SystemTask::Work() { if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { touchPanel.Sleep(); } - twiMaster.Sleep(); isSleeping = true; isGoingToSleep = false; @@ -315,8 +327,8 @@ void SystemTask::Work() { stepCounterMustBeReset = true; break; case Messages::OnChargingEvent: - motorController.SetDuration(15); - // Battery level is updated on every message - there's no need to do anything + motorController.RunForDuration(15); + // Battery level is updated on every message - there's no need to do anything break; default: @@ -356,17 +368,12 @@ void SystemTask::UpdateMotion() { if (isSleeping && !settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) return; - if (isSleeping) - twiMaster.Wakeup(); - if (stepCounterMustBeReset) { motionSensor.ResetStepCounter(); stepCounterMustBeReset = false; } auto motionValues = motionSensor.Process(); - if (isSleeping) - twiMaster.Sleep(); motionController.IsSensorOk(motionSensor.IsOk()); motionController.Update(motionValues.x, motionValues.y, motionValues.z, motionValues.steps); @@ -381,7 +388,6 @@ void SystemTask::OnButtonPushed() { if (!isSleeping) { NRF_LOG_INFO("[systemtask] Button pushed"); PushMessage(Messages::OnButtonEvent); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed); } else { if (!isWakingUp) { NRF_LOG_INFO("[systemtask] Button pushed, waking up"); @@ -402,7 +408,6 @@ void SystemTask::OnTouchEvent() { return; if (!isSleeping) { PushMessage(Messages::OnTouchEvent); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); } else if (!isWakingUp) { if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap) or settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { @@ -416,20 +421,28 @@ void SystemTask::PushMessage(System::Messages msg) { isGoingToSleep = true; } - if(in_isr()) { + if (in_isr()) { BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(systemTasksMsgQueue, &msg, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { /* Actual macro used here is port specific. */ portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } } else { xQueueSend(systemTasksMsgQueue, &msg, portMAX_DELAY); } } +void SystemTask::OnDim() { + if (doNotGoToSleep) + return; + NRF_LOG_INFO("Dim timeout -> Dim screen") + displayApp.PushMessage(Pinetime::Applications::Display::Messages::DimScreen); + xTimerStart(idleTimer, 0); + isDimmed = true; +} + void SystemTask::OnIdle() { if (doNotGoToSleep) return; @@ -437,8 +450,13 @@ void SystemTask::OnIdle() { PushMessage(Messages::GoToSleep); } -void SystemTask::ReloadIdleTimer() const { +void SystemTask::ReloadIdleTimer() { if (isSleeping || isGoingToSleep) return; - xTimerReset(idleTimer, 0); + if (isDimmed) { + displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); + isDimmed = false; + } + xTimerReset(dimTimer, 0); + xTimerStop(idleTimer, 0); } diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index f8cf637..0266ba8 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -17,6 +17,7 @@ #include "components/motor/MotorController.h" #include "components/timer/TimerController.h" #include "components/fs/FS.h" +#include "touchhandler/TouchHandler.h" #ifdef PINETIME_IS_RECOVERY #include "displayapp/DisplayAppRecovery.h" @@ -24,7 +25,7 @@ #else #include "components/settings/Settings.h" #include "displayapp/DisplayApp.h" - #include "displayapp/LittleVgl.h" + #include "displayapp/LittleVgl.h" #endif #include "drivers/Watchdog.h" @@ -39,6 +40,9 @@ namespace Pinetime { class TwiMaster; class Hrs3300; } + namespace Controllers { + class TouchHandler; + } namespace System { class SystemTask { public: @@ -62,7 +66,8 @@ namespace Pinetime { Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, Pinetime::Applications::HeartRateTask& heartRateApp, - Pinetime::Controllers::FS& fs); + Pinetime::Controllers::FS& fs, + Pinetime::Controllers::TouchHandler& touchHandler); void Start(); void PushMessage(Messages msg); @@ -71,6 +76,7 @@ namespace Pinetime { void OnTouchEvent(); void OnIdle(); + void OnDim(); Pinetime::Controllers::NimbleController& nimble() { return nimbleController; @@ -91,7 +97,6 @@ namespace Pinetime { Pinetime::Components::LittleVgl& lvgl; Pinetime::Controllers::Battery& batteryController; - Pinetime::Controllers::Ble& bleController; Pinetime::Controllers::DateTime& dateTimeController; Pinetime::Controllers::TimerController& timerController; @@ -99,6 +104,7 @@ namespace Pinetime { std::atomic<bool> isSleeping {false}; std::atomic<bool> isGoingToSleep {false}; std::atomic<bool> isWakingUp {false}; + std::atomic<bool> isDimmed {false}; Pinetime::Drivers::Watchdog& watchdog; Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::MotorController& motorController; @@ -106,13 +112,12 @@ namespace Pinetime { Pinetime::Drivers::Bma421& motionSensor; Pinetime::Controllers::Settings& settingsController; Pinetime::Controllers::HeartRateController& heartRateController; - - Controllers::BrightnessController brightnessController; Pinetime::Controllers::MotionController& motionController; Pinetime::Applications::DisplayApp& displayApp; Pinetime::Applications::HeartRateTask& heartRateApp; Pinetime::Controllers::FS& fs; + Pinetime::Controllers::TouchHandler& touchHandler; Pinetime::Controllers::NimbleController nimbleController; static constexpr uint8_t pinSpiSck = 2; @@ -126,9 +131,10 @@ namespace Pinetime { static void Process(void* instance); void Work(); - void ReloadIdleTimer() const; + void ReloadIdleTimer(); bool isBleDiscoveryTimerRunning = false; uint8_t bleDiscoveryTimer = 0; + TimerHandle_t dimTimer; TimerHandle_t idleTimer; bool doNotGoToSleep = false; diff --git a/src/touchhandler/TouchHandler.cpp b/src/touchhandler/TouchHandler.cpp new file mode 100644 index 0000000..735b311 --- /dev/null +++ b/src/touchhandler/TouchHandler.cpp @@ -0,0 +1,65 @@ +#include "TouchHandler.h" + +using namespace Pinetime::Controllers; + +TouchHandler::TouchHandler(Drivers::Cst816S& touchPanel, Components::LittleVgl& lvgl) : touchPanel {touchPanel}, lvgl {lvgl} { +} + +void TouchHandler::CancelTap() { + if (info.touching) { + isCancelled = true; + lvgl.SetNewTouchPoint(-1, -1, true); + } +} + +Pinetime::Drivers::Cst816S::Gestures TouchHandler::GestureGet() { + auto returnGesture = gesture; + gesture = Drivers::Cst816S::Gestures::None; + return returnGesture; +} + +bool TouchHandler::GetNewTouchInfo() { + info = touchPanel.GetTouchInfo(); + + if (!info.isValid) { + return false; + } + + if (info.gesture != Pinetime::Drivers::Cst816S::Gestures::None) { + if (gestureReleased) { + if (info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideDown || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideLeft || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideUp || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideRight || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::LongPress) { + if (info.touching) { + gesture = info.gesture; + gestureReleased = false; + } + } else { + gesture = info.gesture; + } + } + } + + if (!info.touching) { + gestureReleased = true; + } + + return true; +} + +void TouchHandler::UpdateLvglTouchPoint() { + if (info.touching) { + if (!isCancelled) { + lvgl.SetNewTouchPoint(info.x, info.y, true); + } + } else { + if (isCancelled) { + lvgl.SetNewTouchPoint(-1, -1, false); + isCancelled = false; + } else { + lvgl.SetNewTouchPoint(info.x, info.y, false); + } + } +} diff --git a/src/touchhandler/TouchHandler.h b/src/touchhandler/TouchHandler.h new file mode 100644 index 0000000..f544293 --- /dev/null +++ b/src/touchhandler/TouchHandler.h @@ -0,0 +1,45 @@ +#pragma once +#include "drivers/Cst816s.h" +#include "systemtask/SystemTask.h" +#include <FreeRTOS.h> +#include <task.h> + +namespace Pinetime { + namespace Components { + class LittleVgl; + } + namespace Drivers { + class Cst816S; + } + namespace System { + class SystemTask; + } + namespace Controllers { + class TouchHandler { + public: + explicit TouchHandler(Drivers::Cst816S&, Components::LittleVgl&); + void CancelTap(); + bool GetNewTouchInfo(); + void UpdateLvglTouchPoint(); + + bool IsTouching() const { + return info.touching; + } + uint8_t GetX() const { + return info.x; + } + uint8_t GetY() const { + return info.y; + } + Drivers::Cst816S::Gestures GestureGet(); + private: + + Pinetime::Drivers::Cst816S::TouchInfos info; + Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Components::LittleVgl& lvgl; + Pinetime::Drivers::Cst816S::Gestures gesture; + bool isCancelled = false; + bool gestureReleased = true; + }; + } +} |
