Skip to content

Commit 085c9ab

Browse files
committed
Merge branch 'develop' into timer_battery_reading
2 parents 044036e + fab49f8 commit 085c9ab

37 files changed

Lines changed: 423 additions & 351 deletions

doc/ui/example.png

10.4 KB
Loading

doc/ui_guidelines.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# UI design guidelines
2+
3+
- Align objects all the way to the edge or corner
4+
- Buttons should generally be at least 50px high
5+
- Buttons should generally be on the bottom edge
6+
- Make interactable objects **big**
7+
- Recommendations for inner padding, aka distance between buttons:
8+
- When aligning 4 objects: 4px, e.g. Settings
9+
- When aligning 3 objects: 6px, e.g. App list
10+
- When aligning 2 objects: 10px, e.g. Quick settings
11+
- When using a page indicator, leave 8px for it on the right side
12+
- It is acceptable to leave 8px on the left side as well to center the content
13+
- Top bar takes at least 20px + padding
14+
- Top bar right icons move 8px to the left when using a page indicator
15+
16+
![example layouts](./ui/example.png)

src/CMakeLists.txt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ list(APPEND SOURCE_FILES
495495
components/heartrate/Biquad.cpp
496496
components/heartrate/Ptagc.cpp
497497
components/heartrate/HeartRateController.cpp
498+
499+
touchhandler/TouchHandler.cpp
498500
)
499501

500502
list(APPEND RECOVERY_SOURCE_FILES
@@ -552,6 +554,7 @@ list(APPEND RECOVERY_SOURCE_FILES
552554
components/heartrate/Ptagc.cpp
553555
components/motor/MotorController.cpp
554556
components/fs/FS.cpp
557+
touchhandler/TouchHandler.cpp
555558
)
556559

557560
list(APPEND RECOVERYLOADER_SOURCE_FILES
@@ -660,6 +663,7 @@ set(INCLUDE_FILES
660663
components/heartrate/Ptagc.h
661664
components/heartrate/HeartRateController.h
662665
components/motor/MotorController.h
666+
touchhandler/TouchHandler.h
663667
)
664668

665669
include_directories(
@@ -839,7 +843,7 @@ target_compile_options(${EXECUTABLE_NAME} PUBLIC
839843

840844
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
841845
SUFFIX ".out"
842-
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"
846+
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"
843847
)
844848

845849
add_custom_command(TARGET ${EXECUTABLE_NAME}
@@ -869,7 +873,7 @@ target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC
869873

870874
set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES
871875
SUFFIX ".out"
872-
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"
876+
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"
873877
)
874878

875879
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
@@ -906,7 +910,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC
906910

907911
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES
908912
SUFFIX ".out"
909-
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"
913+
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"
910914
)
911915

912916
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME}
@@ -936,7 +940,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC
936940

937941
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES
938942
SUFFIX ".out"
939-
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"
943+
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"
940944
)
941945

942946
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}
@@ -977,7 +981,7 @@ add_dependencies(${EXECUTABLE_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY_MCUBOOT
977981

978982
set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES
979983
SUFFIX ".out"
980-
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"
984+
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"
981985
)
982986

983987
add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME}
@@ -1010,7 +1014,7 @@ add_dependencies(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY
10101014

10111015
set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PROPERTIES
10121016
SUFFIX ".out"
1013-
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"
1017+
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"
10141018
)
10151019

10161020
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}

src/displayapp/DisplayApp.cpp

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,26 @@ namespace {
5353
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0;
5454
}
5555

56-
TouchEvents Convert(Pinetime::Drivers::Cst816S::TouchInfos info) {
57-
if (info.isTouch) {
58-
switch (info.gesture) {
59-
case Pinetime::Drivers::Cst816S::Gestures::SingleTap:
60-
return TouchEvents::Tap;
61-
case Pinetime::Drivers::Cst816S::Gestures::LongPress:
62-
return TouchEvents::LongTap;
63-
case Pinetime::Drivers::Cst816S::Gestures::DoubleTap:
64-
return TouchEvents::DoubleTap;
65-
case Pinetime::Drivers::Cst816S::Gestures::SlideRight:
66-
return TouchEvents::SwipeRight;
67-
case Pinetime::Drivers::Cst816S::Gestures::SlideLeft:
68-
return TouchEvents::SwipeLeft;
69-
case Pinetime::Drivers::Cst816S::Gestures::SlideDown:
70-
return TouchEvents::SwipeDown;
71-
case Pinetime::Drivers::Cst816S::Gestures::SlideUp:
72-
return TouchEvents::SwipeUp;
73-
case Pinetime::Drivers::Cst816S::Gestures::None:
74-
default:
75-
return TouchEvents::None;
76-
}
56+
TouchEvents ConvertGesture(Pinetime::Drivers::Cst816S::Gestures gesture) {
57+
switch (gesture) {
58+
case Pinetime::Drivers::Cst816S::Gestures::SingleTap:
59+
return TouchEvents::Tap;
60+
case Pinetime::Drivers::Cst816S::Gestures::LongPress:
61+
return TouchEvents::LongTap;
62+
case Pinetime::Drivers::Cst816S::Gestures::DoubleTap:
63+
return TouchEvents::DoubleTap;
64+
case Pinetime::Drivers::Cst816S::Gestures::SlideRight:
65+
return TouchEvents::SwipeRight;
66+
case Pinetime::Drivers::Cst816S::Gestures::SlideLeft:
67+
return TouchEvents::SwipeLeft;
68+
case Pinetime::Drivers::Cst816S::Gestures::SlideDown:
69+
return TouchEvents::SwipeDown;
70+
case Pinetime::Drivers::Cst816S::Gestures::SlideUp:
71+
return TouchEvents::SwipeUp;
72+
case Pinetime::Drivers::Cst816S::Gestures::None:
73+
default:
74+
return TouchEvents::None;
7775
}
78-
return TouchEvents::None;
7976
}
8077
}
8178

@@ -91,7 +88,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
9188
Controllers::Settings& settingsController,
9289
Pinetime::Controllers::MotorController& motorController,
9390
Pinetime::Controllers::MotionController& motionController,
94-
Pinetime::Controllers::TimerController& timerController)
91+
Pinetime::Controllers::TimerController& timerController,
92+
Pinetime::Controllers::TouchHandler& touchHandler)
9593
: lcd {lcd},
9694
lvgl {lvgl},
9795
touchPanel {touchPanel},
@@ -104,7 +102,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
104102
settingsController {settingsController},
105103
motorController {motorController},
106104
motionController {motionController},
107-
timerController {timerController} {
105+
timerController {timerController},
106+
touchHandler {touchHandler} {
108107
}
109108

110109
void DisplayApp::Start() {
@@ -209,8 +208,7 @@ void DisplayApp::Refresh() {
209208
if (state != States::Running) {
210209
break;
211210
}
212-
auto info = touchPanel.GetTouchInfo();
213-
auto gesture = Convert(info);
211+
auto gesture = ConvertGesture(touchHandler.GestureGet());
214212
if (gesture == TouchEvents::None) {
215213
break;
216214
}
@@ -236,11 +234,9 @@ void DisplayApp::Refresh() {
236234
LoadApp(returnToApp, returnDirection);
237235
brightnessController.Set(settingsController.GetBrightness());
238236
brightnessController.Backup();
239-
} else if (touchMode == TouchModes::Gestures) {
240-
if (gesture == TouchEvents::Tap) {
241-
lvgl.SetNewTapEvent(info.x, info.y);
242-
}
243237
}
238+
} else {
239+
touchHandler.CancelTap();
244240
}
245241
} break;
246242
case Messages::ButtonPushed:
@@ -270,13 +266,8 @@ void DisplayApp::Refresh() {
270266
nextApp = Apps::None;
271267
}
272268

273-
if (state != States::Idle && touchMode == TouchModes::Polling) {
274-
auto info = touchPanel.GetTouchInfo();
275-
if (info.action == 2) { // 2 = contact
276-
if (!currentScreen->OnTouchEvent(info.x, info.y)) {
277-
lvgl.SetNewTapEvent(info.x, info.y);
278-
}
279-
}
269+
if (touchHandler.IsTouching()) {
270+
currentScreen->OnTouchEvent(touchHandler.GetX(), touchHandler.GetY());
280271
}
281272
}
282273

@@ -299,6 +290,7 @@ void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction
299290
}
300291

301292
void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) {
293+
touchHandler.CancelTap();
302294
currentScreen.reset(nullptr);
303295
SetFullRefresh(direction);
304296

@@ -464,10 +456,6 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) {
464456
}
465457
}
466458

467-
void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) {
468-
touchMode = mode;
469-
}
470-
471459
void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) {
472460
if (systemTask != nullptr)
473461
systemTask->PushMessage(message);

src/displayapp/DisplayApp.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "components/settings/Settings.h"
1515
#include "displayapp/screens/Screen.h"
1616
#include "components/timer/TimerController.h"
17+
#include "touchhandler/TouchHandler.h"
1718
#include "Messages.h"
1819

1920
namespace Pinetime {
@@ -31,6 +32,7 @@ namespace Pinetime {
3132
class NotificationManager;
3233
class HeartRateController;
3334
class MotionController;
35+
class TouchHandler;
3436
}
3537

3638
namespace System {
@@ -41,7 +43,6 @@ namespace Pinetime {
4143
public:
4244
enum class States { Idle, Running };
4345
enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim };
44-
enum class TouchModes { Gestures, Polling };
4546

4647
DisplayApp(Drivers::St7789& lcd,
4748
Components::LittleVgl& lvgl,
@@ -55,14 +56,14 @@ namespace Pinetime {
5556
Controllers::Settings& settingsController,
5657
Pinetime::Controllers::MotorController& motorController,
5758
Pinetime::Controllers::MotionController& motionController,
58-
Pinetime::Controllers::TimerController& timerController);
59+
Pinetime::Controllers::TimerController& timerController,
60+
Pinetime::Controllers::TouchHandler& touchHandler);
5961
void Start();
6062
void PushMessage(Display::Messages msg);
6163

6264
void StartApp(Apps app, DisplayApp::FullRefreshDirections direction);
6365

6466
void SetFullRefresh(FullRefreshDirections direction);
65-
void SetTouchMode(TouchModes mode);
6667

6768
void Register(Pinetime::System::SystemTask* systemTask);
6869

@@ -81,6 +82,7 @@ namespace Pinetime {
8182
Pinetime::Controllers::MotorController& motorController;
8283
Pinetime::Controllers::MotionController& motionController;
8384
Pinetime::Controllers::TimerController& timerController;
85+
Pinetime::Controllers::TouchHandler& touchHandler;
8486

8587
Pinetime::Controllers::FirmwareValidator validator;
8688
Controllers::BrightnessController brightnessController;
@@ -100,8 +102,7 @@ namespace Pinetime {
100102
FullRefreshDirections returnDirection = FullRefreshDirections::None;
101103
TouchEvents returnTouchEvent = TouchEvents::None;
102104

103-
TouchModes touchMode = TouchModes::Gestures;
104-
105+
TouchEvents GetGesture();
105106
void RunningState();
106107
void IdleState();
107108
static void Process(void* instance);

src/displayapp/DisplayAppRecovery.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <task.h>
44
#include <libraries/log/nrf_log.h>
55
#include <components/rle/RleDecoder.h>
6+
#include <touchhandler/TouchHandler.h>
67
#include "displayapp/icons/infinitime/infinitime-nb.c"
78

89
using namespace Pinetime::Applications;
@@ -19,7 +20,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
1920
Controllers::Settings& settingsController,
2021
Pinetime::Controllers::MotorController& motorController,
2122
Pinetime::Controllers::MotionController& motionController,
22-
Pinetime::Controllers::TimerController& timerController)
23+
Pinetime::Controllers::TimerController& timerController,
24+
Pinetime::Controllers::TouchHandler& touchHandler)
2325
: lcd {lcd}, bleController {bleController} {
2426

2527
}

src/displayapp/DisplayAppRecovery.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ namespace Pinetime {
2929
namespace System {
3030
class SystemTask;
3131
};
32+
namespace Controllers {
33+
class TouchHandler;
34+
}
3235
namespace Applications {
3336
class DisplayApp {
3437
public:
@@ -44,7 +47,8 @@ namespace Pinetime {
4447
Controllers::Settings& settingsController,
4548
Pinetime::Controllers::MotorController& motorController,
4649
Pinetime::Controllers::MotionController& motionController,
47-
Pinetime::Controllers::TimerController& timerController);
50+
Pinetime::Controllers::TimerController& timerController,
51+
Pinetime::Controllers::TouchHandler& touchHandler);
4852
void Start();
4953
void PushMessage(Pinetime::Applications::Display::Messages msg);
5054
void Register(Pinetime::System::SystemTask* systemTask);

src/displayapp/DummyLittleVgl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ namespace Pinetime {
3232
}
3333
void SetNewTapEvent(uint16_t x, uint16_t y) {
3434
}
35+
void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) {
36+
37+
}
3538
};
3639
}
3740
}

src/displayapp/LittleVgl.cpp

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -166,43 +166,21 @@ void LittleVgl::FlushDisplay(const lv_area_t* area, lv_color_t* color_p) {
166166
lv_disp_flush_ready(&disp_drv);
167167
}
168168

169-
void LittleVgl::SetNewTapEvent(uint16_t x, uint16_t y) {
169+
void LittleVgl::SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) {
170170
tap_x = x;
171171
tap_y = y;
172-
tapped = true;
172+
tapped = contact;
173173
}
174174

175175
bool LittleVgl::GetTouchPadInfo(lv_indev_data_t* ptr) {
176+
ptr->point.x = tap_x;
177+
ptr->point.y = tap_y;
176178
if (tapped) {
177-
ptr->point.x = tap_x;
178-
ptr->point.y = tap_y;
179179
ptr->state = LV_INDEV_STATE_PR;
180-
tapped = false;
181180
} else {
182181
ptr->state = LV_INDEV_STATE_REL;
183182
}
184183
return false;
185-
/*
186-
auto info = touchPanel.GetTouchInfo();
187-
188-
if((previousClick.x != info.x || previousClick.y != info.y) &&
189-
(info.gesture == Drivers::Cst816S::Gestures::SingleTap)) {
190-
// TODO For an unknown reason, the first touch is taken twice into account.
191-
// 'firstTouch' is a quite'n'dirty workaound until I find a better solution
192-
if(firstTouch) ptr->state = LV_INDEV_STATE_REL;
193-
else ptr->state = LV_INDEV_STATE_PR;
194-
firstTouch = false;
195-
previousClick.x = info.x;
196-
previousClick.y = info.y;
197-
}
198-
else {
199-
ptr->state = LV_INDEV_STATE_REL;
200-
}
201-
202-
ptr->point.x = info.x;
203-
ptr->point.y = info.y;
204-
return false;
205-
*/
206184
}
207185

208186
void LittleVgl::InitTheme() {

src/displayapp/LittleVgl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Pinetime {
2424
void FlushDisplay(const lv_area_t* area, lv_color_t* color_p);
2525
bool GetTouchPadInfo(lv_indev_data_t* ptr);
2626
void SetFullRefresh(FullRefreshDirections direction);
27-
void SetNewTapEvent(uint16_t x, uint16_t y);
27+
void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact);
2828

2929
private:
3030
void InitDisplay();

0 commit comments

Comments
 (0)