summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt16
-rw-r--r--src/components/battery/BatteryController.cpp32
-rw-r--r--src/components/battery/BatteryController.h43
-rw-r--r--src/components/datetime/DateTimeController.cpp20
-rw-r--r--src/components/motor/MotorController.cpp37
-rw-r--r--src/components/motor/MotorController.h7
-rw-r--r--src/displayapp/DisplayApp.cpp75
-rw-r--r--src/displayapp/DisplayApp.h11
-rw-r--r--src/displayapp/LittleVgl.cpp30
-rw-r--r--src/displayapp/LittleVgl.h2
-rw-r--r--src/displayapp/screens/BatteryIcon.cpp8
-rw-r--r--src/displayapp/screens/Clock.cpp20
-rw-r--r--src/displayapp/screens/Clock.h7
-rw-r--r--src/displayapp/screens/FirmwareValidation.cpp8
-rw-r--r--src/displayapp/screens/InfiniPaint.cpp3
-rw-r--r--src/displayapp/screens/Label.cpp18
-rw-r--r--src/displayapp/screens/List.cpp36
-rw-r--r--src/displayapp/screens/Metronome.cpp122
-rw-r--r--src/displayapp/screens/Metronome.h48
-rw-r--r--src/displayapp/screens/Music.cpp70
-rw-r--r--src/displayapp/screens/Music.h3
-rw-r--r--src/displayapp/screens/Notifications.cpp85
-rw-r--r--src/displayapp/screens/Notifications.h13
-rw-r--r--src/displayapp/screens/Paddle.cpp4
-rw-r--r--src/displayapp/screens/PineTimeStyle.cpp60
-rw-r--r--src/displayapp/screens/PineTimeStyle.h5
-rw-r--r--src/displayapp/screens/Screen.h1
-rw-r--r--src/displayapp/screens/ScreenList.h2
-rw-r--r--src/displayapp/screens/StopWatch.cpp4
-rw-r--r--src/displayapp/screens/SystemInfo.cpp6
-rw-r--r--src/displayapp/screens/Tile.cpp31
-rw-r--r--src/displayapp/screens/WatchFaceAnalog.cpp56
-rw-r--r--src/displayapp/screens/WatchFaceAnalog.h2
-rw-r--r--src/displayapp/screens/WatchFaceDigital.cpp59
-rw-r--r--src/displayapp/screens/WatchFaceDigital.h5
-rw-r--r--src/displayapp/screens/settings/QuickSettings.cpp61
-rw-r--r--src/displayapp/screens/settings/QuickSettings.h2
-rw-r--r--src/displayapp/screens/settings/SettingDisplay.cpp4
-rw-r--r--src/drivers/Cst816s.cpp38
-rw-r--r--src/drivers/Cst816s.h26
-rw-r--r--src/main.cpp24
-rw-r--r--src/systemtask/SystemTask.cpp30
-rw-r--r--src/systemtask/SystemTask.h11
-rw-r--r--src/touchhandler/TouchHandler.cpp65
-rw-r--r--src/touchhandler/TouchHandler.h45
45 files changed, 602 insertions, 653 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 40e1f2a5..ae3cc3b1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -495,6 +495,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 +554,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
@@ -660,6 +663,7 @@ set(INCLUDE_FILES
components/heartrate/Ptagc.h
components/heartrate/HeartRateController.h
components/motor/MotorController.h
+ touchhandler/TouchHandler.h
)
include_directories(
@@ -839,7 +843,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 +873,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 +910,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 +940,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 +981,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 +1014,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 fa476ea3..f8a64ecd 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 1333ad0e..6f09b737 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 28a70abc..d6aa83c8 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 3afa0ced..b25e6bc8 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 df61af78..d2c9fe5f 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/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index d4a73f5e..8cb8ed15 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -53,29 +53,26 @@ namespace {
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0;
}
- TouchEvents Convert(Pinetime::Drivers::Cst816S::TouchInfos info) {
- if (info.isTouch) {
- switch (info.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;
- }
+ 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;
}
- return TouchEvents::None;
}
}
@@ -91,7 +88,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},
@@ -104,7 +102,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
settingsController {settingsController},
motorController {motorController},
motionController {motionController},
- timerController {timerController} {
+ timerController {timerController},
+ touchHandler {touchHandler} {
}
void DisplayApp::Start() {
@@ -212,8 +211,7 @@ void DisplayApp::Refresh() {
if (state != States::Running) {
break;
}
- auto info = touchPanel.GetTouchInfo();
- auto gesture = Convert(info);
+ auto gesture = ConvertGesture(touchHandler.GestureGet());
if (gesture == TouchEvents::None) {
break;
}
@@ -239,11 +237,9 @@ void DisplayApp::Refresh() {
LoadApp(returnToApp, returnDirection);
brightnessController.Set(settingsController.GetBrightness());
brightnessController.Backup();
- } else if (touchMode == TouchModes::Gestures) {
- if (gesture == TouchEvents::Tap) {
- lvgl.SetNewTapEvent(info.x, info.y);
- }
}
+ } else {
+ touchHandler.CancelTap();
}
} break;
case Messages::ButtonPushed:
@@ -273,13 +269,8 @@ void DisplayApp::Refresh() {
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());
}
}
@@ -302,6 +293,7 @@ void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction
}
void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) {
+ touchHandler.CancelTap();
currentScreen.reset(nullptr);
SetFullRefresh(direction);
@@ -336,12 +328,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:
@@ -414,6 +406,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);
@@ -466,10 +459,6 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) {
}
}
-void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) {
- touchMode = mode;
-}
-
void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) {
if (systemTask != nullptr)
systemTask->PushMessage(message);
diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h
index 574be63f..96951d1c 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,8 +102,7 @@ namespace Pinetime {
FullRefreshDirections returnDirection = FullRefreshDirections::None;
TouchEvents returnTouchEvent = TouchEvents::None;
- TouchModes touchMode = TouchModes::Gestures;
-
+ TouchEvents GetGesture();
void RunningState();
void IdleState();
static void Process(void* instance);
diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp
index c069afa2..2bd5e57b 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 41f934a7..1f8a3d79 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/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp
index bb6626a5..c67bcb23 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/Clock.cpp b/src/displayapp/screens/Clock.cpp
index e0684976..86afee0c 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"
@@ -88,17 +83,4 @@ std::unique_ptr<Screen> Clock::PineTimeStyleScreen() {
notificatioManager,
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
+} \ No newline at end of file
diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h
index a48feea1..7968cced 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;
@@ -51,10 +48,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/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp
index 1d05be8d..34a43a9f 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);
@@ -66,10 +68,10 @@ bool FirmwareValidation::Refresh() {
}
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/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp
index 32240084..58bfa558 100644
--- a/src/displayapp/screens/InfiniPaint.cpp
+++ b/src/displayapp/screens/InfiniPaint.cpp
@@ -5,13 +5,10 @@
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());
}
diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp
index 0132dbd2..f724fd48 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);
diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp
index b4f4d2cf..91cab9f0 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;
@@ -108,7 +104,7 @@ bool List::Refresh() {
}
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/Metronome.cpp b/src/displayapp/screens/Metronome.cpp
index 7bfbccb7..5fbe5f36 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,52 +49,41 @@ 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);
-
- app->SetTouchMode(DisplayApp::TouchModes::Polling);
+ 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);
}
Metronome::~Metronome() {
- app->SetTouchMode(DisplayApp::TouchModes::Gestures);
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);
- }
+ 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;
@@ -128,42 +97,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 3a1f1084..a4baa096 100644
--- a/src/displayapp/screens/Metronome.h
+++ b/src/displayapp/screens/Metronome.h
@@ -3,32 +3,32 @@
#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;
+ bool 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;
+ };
+ }
+ }
}
diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp
index c8d5e4b0..257e9aea 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);
@@ -147,6 +142,7 @@ Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Mus
}
Music::~Music() {
+ lv_style_reset(&btn_style);
lv_obj_clean(lv_scr_act());
}
@@ -272,21 +268,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: {
@@ -298,7 +292,7 @@ bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
return true;
}
default: {
- return true;
+ return false;
}
}
}
diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h
index ef8f1fec..00d3ad92 100644
--- a/src/displayapp/screens/Music.h
+++ b/src/displayapp/screens/Music.h
@@ -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;
diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp
index 5c23ed1f..c061c146 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,31 @@ 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);
+ }
}
}
Notifications::~Notifications() {
+ // make sure we stop any vibrations before exiting
+ Controllers::MotorController::StopRinging();
lv_obj_clean(lv_scr_act());
}
bool Notifications::Refresh() {
- if (mode == Modes::Preview) {
+ if (mode == Modes::Preview && timeoutLine != nullptr) {
auto tick = xTaskGetTickCount();
int32_t pos = 240 - ((tick - timeoutTickCountStart) / ((timeoutTickCountEnd - timeoutTickCountStart) / 240));
if (pos < 0)
@@ -63,13 +70,13 @@ bool Notifications::Refresh() {
timeoutLinePoints[1].x = pos;
lv_line_set_points(timeoutLine, timeoutLinePoints, 2);
}
-
- return running;
+ return running && currentItem->IsRunning();
}
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 +137,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 +151,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));
@@ -212,7 +208,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);
@@ -221,7 +217,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);
@@ -230,7 +226,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);
@@ -246,25 +242,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 51ca81da..a02d9b46 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,6 +20,7 @@ namespace Pinetime {
explicit Notifications(DisplayApp* app,
Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::AlertNotificationService& alertNotificationService,
+ Pinetime::Controllers::MotorController& motorController,
Modes mode);
~Notifications() override;
@@ -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,7 +76,7 @@ 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;
};
diff --git a/src/displayapp/screens/Paddle.cpp b/src/displayapp/screens/Paddle.cpp
index 5a939ac7..79e0c3d3 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);
@@ -32,8 +30,6 @@ Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::Li
}
Paddle::~Paddle() {
- // Reset the touchmode
- app->SetTouchMode(DisplayApp::TouchModes::Gestures);
lv_obj_clean(lv_scr_act());
}
diff --git a/src/displayapp/screens/PineTimeStyle.cpp b/src/displayapp/screens/PineTimeStyle.cpp
index 0efb4dc3..98fd976c 100644
--- a/src/displayapp/screens/PineTimeStyle.cpp
+++ b/src/displayapp/screens/PineTimeStyle.cpp
@@ -51,7 +51,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
notificatioManager {notificatioManager},
settingsController {settingsController},
motionController {motionController} {
-
/* This sets the watchface number to return to after leaving the menu */
settingsController.SetClockFace(2);
@@ -62,7 +61,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
displayedChar[4] = 0;
/* 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_radius(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
@@ -70,7 +68,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
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, lv_color_hex(0x008080));
@@ -90,7 +87,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
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, lv_color_hex(0x008080));
lv_obj_set_style_local_radius(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
@@ -98,7 +94,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
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);
@@ -117,7 +112,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
lv_obj_align(notificationIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 40);
/* 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);
@@ -155,7 +149,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
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");
@@ -223,26 +216,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 +234,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,9 +247,8 @@ bool PineTimeStyle::Refresh() {
char hoursChar[3];
char ampmChar[5];
-
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) {
- sprintf(hoursChar, "%02d", hour);
+ sprintf(hoursChar, "%02d", hour);
} else {
if (hour == 0 && hour != 12) {
hour = 12;
@@ -282,41 +265,26 @@ bool PineTimeStyle::Refresh() {
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) {
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;
diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h
index 3b4ded1e..f4cd28e4 100644
--- a/src/displayapp/screens/PineTimeStyle.h
+++ b/src/displayapp/screens/PineTimeStyle.h
@@ -32,8 +32,6 @@ namespace Pinetime {
bool Refresh() override;
- void OnObjectEvent(lv_obj_t* pObj, lv_event_t i);
-
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];
diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h
index 6c9110c6..420f2015 100644
--- a/src/displayapp/screens/Screen.h
+++ b/src/displayapp/screens/Screen.h
@@ -64,6 +64,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 ea66bfb2..50d66328 100644
--- a/src/displayapp/screens/ScreenList.h
+++ b/src/displayapp/screens/ScreenList.h
@@ -110,4 +110,4 @@ namespace Pinetime {
};
}
}
-} \ No newline at end of file
+}
diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp
index f4db5d6e..e3db6299 100644
--- a/src/displayapp/screens/StopWatch.cpp
+++ b/src/displayapp/screens/StopWatch.cpp
@@ -161,7 +161,7 @@ bool StopWatch::Refresh() {
}
void StopWatch::playPauseBtnEventHandler(lv_event_t event) {
- if (event != LV_EVENT_PRESSED) {
+ if (event != LV_EVENT_CLICKED) {
return;
}
if (currentState == States::Init) {
@@ -174,7 +174,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
diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp
index e7c5b65a..35337511 100644
--- a/src/displayapp/screens/SystemInfo.cpp
+++ b/src/displayapp/screens/SystemInfo.cpp
@@ -207,7 +207,7 @@ 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, 4);
lv_table_set_row_cnt(infoTask, 8);
@@ -222,9 +222,9 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen4() {
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());
char state[2] = {0};
diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp
index d5d6cb80..2ffbfbc2 100644
--- a/src/displayapp/screens/Tile.cpp
+++ b/src/displayapp/screens/Tile.cpp
@@ -35,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);
}
@@ -85,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);
@@ -93,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);
}
diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp
index f1889379..1410fc28 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
@@ -123,7 +122,6 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
}
WatchFaceAnalog::~WatchFaceAnalog() {
-
lv_style_reset(&hour_line_style);
lv_style_reset(&hour_line_style_trace);
lv_style_reset(&minute_line_style);
@@ -134,18 +132,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 +153,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,8 +167,8 @@ 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);
}
}
@@ -186,16 +183,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 +196,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;
diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h
index ac7f0ac5..5d8c6a24 100644
--- a/src/displayapp/screens/WatchFaceAnalog.h
+++ b/src/displayapp/screens/WatchFaceAnalog.h
@@ -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;
diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp
index f1285eaf..2b902b3b 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,7 +85,7 @@ 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));
@@ -111,28 +102,21 @@ bool WatchFaceDigital::Refresh() {
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 +128,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 +159,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 +173,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 +183,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 +208,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,7 +216,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);
}
diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h
index 76c8d3dc..6a6e1ac6 100644
--- a/src/displayapp/screens/WatchFaceDigital.h
+++ b/src/displayapp/screens/WatchFaceDigital.h
@@ -35,10 +35,8 @@ namespace Pinetime {
bool Refresh() override;
- void OnObjectEvent(lv_obj_t* pObj, lv_event_t i);
-
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;
diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp
index 2cd24876..8190f9d7 100644
--- a/src/displayapp/screens/settings/QuickSettings.cpp
+++ b/src/displayapp/screens/settings/QuickSettings.cpp
@@ -30,27 +30,35 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app,
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,14 +143,14 @@ 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);
diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h
index e0fc0a87..2eefe1a7 100644
--- a/src/displayapp/screens/settings/QuickSettings.h
+++ b/src/displayapp/screens/settings/QuickSettings.h
@@ -44,6 +44,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 4954185d..aaf6a9f0 100644
--- a/src/displayapp/screens/settings/SettingDisplay.cpp
+++ b/src/displayapp/screens/settings/SettingDisplay.cpp
@@ -85,7 +85,7 @@ bool SettingDisplay::Refresh() {
}
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 +110,4 @@ void SettingDisplay::UpdateSelected(lv_obj_t* object, lv_event_t event) {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp
index fd9792b3..b8f8e45d 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 14c296ea..d4c17bb8 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/main.cpp b/src/main.cpp
index 524035fc..79e2ad86 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"
@@ -117,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};
@@ -135,7 +138,8 @@ Pinetime::Applications::DisplayApp displayApp(lcd,
settingsController,
motorController,
motionController,
- timerController);
+ timerController,
+ touchHandler);
Pinetime::System::SystemTask systemTask(spi,
lcd,
@@ -157,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) {
@@ -299,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);
@@ -308,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 4316330f..08e21999 100644
--- a/src/systemtask/SystemTask.cpp
+++ b/src/systemtask/SystemTask.cpp
@@ -67,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},
@@ -79,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() {
@@ -116,7 +117,7 @@ void SystemTask::Work() {
spi.Init();
spiNorFlash.Init();
spiNorFlash.Wakeup();
-
+
fs.Init();
nimbleController.Init();
@@ -263,14 +264,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:
@@ -292,6 +292,9 @@ void SystemTask::Work() {
xTimerStart(dimTimer, 0);
break;
case Messages::OnTouchEvent:
+ if (touchHandler.GetNewTouchInfo()) {
+ touchHandler.UpdateLvglTouchPoint();
+ }
ReloadIdleTimer();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent);
break;
@@ -322,8 +325,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:
@@ -416,14 +419,13 @@ 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);
diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h
index ba434298..0266ba8a 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);
@@ -92,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;
@@ -113,6 +117,7 @@ namespace Pinetime {
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;
diff --git a/src/touchhandler/TouchHandler.cpp b/src/touchhandler/TouchHandler.cpp
new file mode 100644
index 00000000..735b311a
--- /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 00000000..f5442939
--- /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;
+ };
+ }
+}