From 7d3af600bd056e0f4be7d31122cc2dbb352cef70 Mon Sep 17 00:00:00 2001 From: JF Date: Thu, 20 Aug 2020 21:09:45 +0200 Subject: [PATCH] Add TouchModes : in Gestures mode, only 1 event is processed for each touchevent. This allows to recognize gesture and handle them in Screens or in DisplayApp. In Polling mode, X/Y positions are sent continuously to lvgl, allowing to scroll inside a dropdown menu for example. --- src/CMakeLists.txt | 4 ++ src/DisplayApp/DisplayApp.cpp | 13 ++++- src/DisplayApp/DisplayApp.h | 4 ++ src/DisplayApp/Screens/DropDownDemo.cpp | 64 +++++++++++++++++++++++++ src/DisplayApp/Screens/DropDownDemo.h | 29 +++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/DisplayApp/Screens/DropDownDemo.cpp create mode 100644 src/DisplayApp/Screens/DropDownDemo.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63bb0591..dbd919bc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -287,6 +287,8 @@ set(LVGL_SRC libs/lvgl/src/lv_objx/lv_bar.h libs/lvgl/src/lv_objx/lv_slider.h libs/lvgl/src/lv_objx/lv_slider.c + libs/lvgl/src/lv_objx/lv_ddlist.c + libs/lvgl/src/lv_objx/lv_ddlist.h ) list(APPEND IMAGE_FILES @@ -327,6 +329,7 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/Tile.cpp DisplayApp/Screens/Meter.cpp DisplayApp/Screens/Gauge.cpp + DisplayApp/Screens/DropDownDemo.cpp DisplayApp/Screens/Modal.cpp DisplayApp/Screens/BatteryIcon.cpp DisplayApp/Screens/BleIcon.cpp @@ -400,6 +403,7 @@ set(INCLUDE_FILES DisplayApp/Screens/Tile.h DisplayApp/Screens/Meter.h DisplayApp/Screens/Gauge.h + DisplayApp/Screens/DropDownDemo.h DisplayApp/Screens/Modal.h DisplayApp/Screens/BatteryIcon.h DisplayApp/Screens/BleIcon.cpp diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 175bdc80..6de746cc 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -171,6 +171,12 @@ void DisplayApp::Refresh() { break; } } + + if(touchMode == TouchModes::Polling) { + auto info = touchPanel.GetTouchInfo(); + if(info.action == 2) // 2 = contact + lvgl.SetNewTapEvent(info.x, info.y); + } } void DisplayApp::RunningState() { @@ -219,7 +225,8 @@ TouchEvents DisplayApp::OnTouchEvent() { if(info.isTouch) { switch(info.gesture) { case Pinetime::Drivers::Cst816S::Gestures::SingleTap: - lvgl.SetNewTapEvent(info.x, info.y); + if(touchMode == TouchModes::Gestures) + lvgl.SetNewTapEvent(info.x, info.y); return TouchEvents::Tap; case Pinetime::Drivers::Cst816S::Gestures::LongPress: return TouchEvents::LongTap; @@ -257,3 +264,7 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { } } + +void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) { + touchMode = mode; +} diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index 478953c8..345e06d4 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -34,6 +34,7 @@ namespace Pinetime { NewNotification, BleFirmwareUpdateStarted }; enum class FullRefreshDirections { None, Up, Down }; + enum class TouchModes { Gestures, Polling }; DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &, Controllers::Battery &batteryController, Controllers::Ble &bleController, @@ -46,6 +47,8 @@ namespace Pinetime { void StartApp(Apps app); void SetFullRefresh(FullRefreshDirections direction); + void SetTouchMode(TouchModes mode); + private: TaskHandle_t taskHandle; static void Process(void* instance); @@ -81,6 +84,7 @@ namespace Pinetime { std::unique_ptr modal; Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::FirmwareValidator validator; + TouchModes touchMode = TouchModes::Gestures; }; } } diff --git a/src/DisplayApp/Screens/DropDownDemo.cpp b/src/DisplayApp/Screens/DropDownDemo.cpp new file mode 100644 index 00000000..735a0cce --- /dev/null +++ b/src/DisplayApp/Screens/DropDownDemo.cpp @@ -0,0 +1,64 @@ +#include +#include +#include "DropDownDemo.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp *app) : Screen(app) { + // Create the dropdown object, with many item, and fix its height + ddlist = lv_ddlist_create(lv_scr_act(), NULL); + lv_ddlist_set_options(ddlist, "Apple\n" + "Banana\n" + "Orange\n" + "Melon\n" + "Grape\n" + "Raspberry\n" + "A\n" + "B\n" + "C\n" + "D\n" + "E"); + lv_ddlist_set_fix_width(ddlist, 150); + lv_ddlist_set_draw_arrow(ddlist, true); + lv_ddlist_set_fix_height(ddlist, 150); + lv_obj_align(ddlist, NULL, LV_ALIGN_IN_TOP_MID, 0, 20); +} + +DropDownDemo::~DropDownDemo() { + // Reset the touchmode + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_obj_clean(lv_scr_act()); +} + +bool DropDownDemo::Refresh() { + auto* list = static_cast(ddlist->ext_attr); + + // Switch touchmode to Polling if the dropdown is opened. This will allow to scroll inside the + // dropdown while it is opened. + // Disable the polling mode when the dropdown is closed to be able to handle the gestures. + if(list->opened) + app->SetTouchMode(DisplayApp::TouchModes::Polling); + else + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + return running; +} + +bool DropDownDemo::OnButtonPushed() { + running = false; + return true; +} + +bool DropDownDemo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + // If the dropdown is opened, notify Display app that it doesn't need to handle the event + // (this will prevent displayApp from going back to the menu or clock scree). + auto* list = static_cast(ddlist->ext_attr); + if(list->opened) { + return true; + } else { + return false; + } +} + diff --git a/src/DisplayApp/Screens/DropDownDemo.h b/src/DisplayApp/Screens/DropDownDemo.h new file mode 100644 index 00000000..7c75efc0 --- /dev/null +++ b/src/DisplayApp/Screens/DropDownDemo.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include "Screen.h" +#include +#include +#include + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class DropDownDemo : public Screen{ + public: + DropDownDemo(DisplayApp* app); + ~DropDownDemo() override; + + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + + private: + lv_obj_t * ddlist; + bool running = true; + bool isDropDownOpened = false; + }; + } + } +}