From 49bf8e824c1ffc903b62859a6ef58b56e23bcdc5 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sun, 15 Dec 2024 21:15:54 +0100 Subject: [PATCH] Various improvements and fixes (#128) - Fix for display orientation assumption in Display app - Update logo (added colours) - Fix for double stopping the Files app - Deny registration of apps and services that are already registered - Updated `ideas.md` for these changes - Other cleanup --- .../YellowBoard/Source/hal/YellowDisplay.cpp | 1 + Buildscripts/logo.cmake | 44 +++++++ CMakeLists.txt | 2 + Data/assets/boot_logo.png | Bin 1639 -> 2367 bytes Data/assets_sources/Tactility.svg | 112 +++++++++--------- Documentation/ideas.md | 38 +++--- Tactility/Source/app/ManifestRegistry.cpp | 11 +- Tactility/Source/app/desktop/Desktop.cpp | 6 +- Tactility/Source/app/display/Display.cpp | 37 +++--- Tactility/Source/app/files/Files.cpp | 5 - .../Source/service/ServiceRegistry.cpp | 6 +- 11 files changed, 162 insertions(+), 100 deletions(-) create mode 100644 Buildscripts/logo.cmake diff --git a/Boards/YellowBoard/Source/hal/YellowDisplay.cpp b/Boards/YellowBoard/Source/hal/YellowDisplay.cpp index da346750..571b701e 100644 --- a/Boards/YellowBoard/Source/hal/YellowDisplay.cpp +++ b/Boards/YellowBoard/Source/hal/YellowDisplay.cpp @@ -111,6 +111,7 @@ bool YellowDisplay::start() { .panel_handle = panelHandle, .buffer_size = TWODOTFOUR_LCD_DRAW_BUFFER_SIZE, .double_buffer = false, + .trans_size = 0, .hres = TWODOTFOUR_LCD_HORIZONTAL_RESOLUTION, .vres = TWODOTFOUR_LCD_VERTICAL_RESOLUTION, .monochrome = false, diff --git a/Buildscripts/logo.cmake b/Buildscripts/logo.cmake new file mode 100644 index 00000000..27d34292 --- /dev/null +++ b/Buildscripts/logo.cmake @@ -0,0 +1,44 @@ +get_filename_component(VERSION_TEXT_FILE version.txt ABSOLUTE) + +file(READ ${VERSION_TEXT_FILE} TACTILITY_VERSION) + +if (DEFINED ENV{ESP_IDF_VERSION}) + set(TACTILITY_TARGET " @ ESP-IDF") +else() + set(TACTILITY_TARGET " @ Simulator") +endif() + +if(NOT WIN32) + string(ASCII 27 Esc) + set(ColourReset "${Esc}[m") + set(Cyan "${Esc}[36m") + set(Grey "${Esc}[37m") + set(LightPurple "${Esc}[1;35m") + set(White "${Esc}[1;37m") +else() + set(ColourReset "") + set(Cyan "") + set(Grey "") + set(LightPurple "") + set(White "") +endif() + +# Some terminals (e.g. GitHub Actions) reset colour for every in a multiline message(), +# so we add the colour to each line instead of assuming it would automatically be re-used. +message("\n\n\ + ${LightPurple}@@\n\ + ${LightPurple}@@@\n\ + ${LightPurple}@@@\n\ + ${LightPurple}@@@\n\ + ${LightPurple}@@@\n\ + ${Cyan}@@@@@@@@@@@@@@@@${LightPurple}@@@\n\ + ${Cyan}@@@@@@@@@@@@@@@@@${LightPurple}@@@\n\ + ${Cyan}@@@ ${LightPurple}@@@ ${White}Tactility ${TACTILITY_VERSION}\n\ + ${Cyan}@@@ ${LightPurple}@@@ ${Grey}${TACTILITY_TARGET}\n\ + ${Cyan}@@@${LightPurple}@@@@@@@@@@@@@@@@@\n\ + ${Cyan}@@@${LightPurple}@@@@@@@@@@@@@@@@\n\ + ${Cyan}@@@\n\ + ${Cyan}@@@\n\ + ${Cyan}@@@\n\ + ${Cyan}@@@\n\ + ${Cyan}@@\n\n${ColourReset}") diff --git a/CMakeLists.txt b/CMakeLists.txt index 0485f478..c194baca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_CXX_COMPILER_TARGET}") +include("Buildscripts/logo.cmake") + if (DEFINED ENV{ESP_IDF_VERSION}) message("Building with ESP-IDF v$ENV{ESP_IDF_VERSION}") include($ENV{IDF_PATH}/tools/cmake/project.cmake) diff --git a/Data/assets/boot_logo.png b/Data/assets/boot_logo.png index aee938228ad24f85165d2dbce8c4f7d3e64dc59f..0a3c5fc8b0d255f5abe14f758f8c98a3f4fdac29 100644 GIT binary patch literal 2367 zcmc&$dpy$%8y{Xmsbns5eN~eZQZCc5atS55Rc^5`5_UoT+_ssw&Rd*_3MZH8B3(p7 zMjMvg$x_ZH8+Hk&gU#COQX5|VfBrguyzd{+^L#(g<@0<#&*!<_^z-%9P}f%nfj}DG zUhV;#lKPWWRW`XFnn~UiYFMw36c9)$>L)1-I%$J9m5@}A;M71&Y$|Xu83h6Wz$zY{ zkP>|ni?YHb$CZhk^g$riA#eBNL22a+6U4+(z^GR;TeDzep8wKEkpsGk(#IYt%Yh-a znoPBD5_YlWFyhHb%j%wy82{0ezvSeZJw%)B(aOhA8*FiWbtk?9)83Patoh4MOl|^c306g@qWyjcSCp>nE)gNNr zqu6~R+KFxrJlR;0u@WIAOQC;O2i-JJHOz9 z{m0Y3JN$VcjDc$04e>#shhDMv#@QH9Iej(p0tH@9EqnLpLl7#*YfEJ$@;@DChHtg% z-bHT}_DTP#PUHWUSGFPXFbr&r_$7uJ!Nmr$w%#5`9zat`u}Cy)ZWGVZo9?N>Dqs8{ zIK5=ljymS!8FTT0p>(3dZ3{cXaTj7k(X{tw#D?Y@lH>1_1u~`c!m-MBJ;Drp)qni1 zDDKA{VhI0qY=skr)}XDf2e;Jp{;Pf(9K9lvqWVYn+<7zpapS{SQoTv=cv~_Pin6ye zP5R)Lxiat`*a6_*&2Xhj6q1a%B}hRp2h>uP4}!+MP7t4n)jxI;#(JzmW? z-*4YD6;g0>P3{ay6zkMem2S)Qsd-|_((dQSaSlhttkd%4rTW;mUoZP{Z!O%$P-G4> z+JNwAehRrMV^pPkqKdm+%zeF?%O2HMbopa7qi1BRC?1I~i+oinE@EaJ|9ysTy&*cB z+5hU;rBaW9m)e zcvXu9<;FY4dToj6S1_RLl*W_PvVX$r;YBxI5Nq)EM=)?*t}(CNUb1xbv2C~WE~8o% zlK)JwJVaFt}7{Z%7hGESWHtrYs^Wed5l~=2@#?)=O2E5VTZNi{?Fs$TxZj8I9 z=z#y&=fJ<*6J&%Vl53tg+vz`c!p)C6+Y9Dt^Hdk#c1atv%XU#wsAj1upGHR1b?U#T zEXTQplI->inMw$gY5b&0xSAXUI~O&)&6Ni_uSCo(Ky0r)ImFo!UfEEeE?Hmm=(#U! zURF#PtZg+7mMv!*@c#%N&|=(rL}$ije`nYtBM0bV+1`vbM*k}JVCTLbxEjJG%u1Ay zZIG?Os5FiKL@FVjW-Pt?VSQ*|ypXn~RLg{EYWQ~hq19=Z^q7hhH>!+as!lqyW_FrU zZ*q5jiRF=TiKf{7SPyv`1PgN^6fFkkux--1jBjwr3?!E(NOGwr+RGOhnOY`d1*?-; zPR6T#;d>ZiYBjK(E+Y<#Y{fv*!Zt#Htr8hD3@Rud1Mt$xur|x(w}T!%?SeM(N*sKq zt>b`A%|vDgzOS6VvOWV_FSkyLEtdurQlK8JBZ&OAb20N$k7kO!&3fJ4D~Wk2=mHZ& z(JEjhX`RyfTyrz*QG3+OAgO2 z6TV#3MxGV4o+Lg{{D8fnBT7-To)_6i+yst~vnV#%y9uC1md)T{%moQK| zt5j89gdI)_c+|62owlLCyUKfJD%>!;_F-F=sYK3Q4Sx%%g1b~Y<}88h7Q=ngNWnK9 z1Zx~~!UNt;e$c#rXMJ}%kEFhGR#)Fn|*dj1%}IfkwqY-BQ}LElFcNDP?4&qFjJQAUmmGr=R@;Vm&N_A^6R=6S0ppKS0bTV>0;BYJJbK*Cv*Ma!i?NC0*c6G zPpQ_pzhpo?W)=!KY1MsW{+-i(r?1U@Z4^rT>uqV-mJ-T@Zc*WDjKC}YjvAY0vYVb? zs@6R9;nTPS?s3bxPUt&BzQ;Esy&VQ%;8Dx%#UplYjCWwf*(07c(5T{R-Mb%o|F?tv d^KaPL66?LxxZT){wE6siyghu~>s*mJ{{`glxyk?l literal 1639 zcma)7eK^wz0RC;W$>(fQVI?CRHg4C4bvmVGLc4Cl&3C>P+t@B$k7}eEYG>ThGNfI0 zJI*DQk4kHi5o0ZkZ9=J3z8BX}=broT?w_9L{dk`DulITXd2FNFaBkcfW>N|5CpTn#Om`@Uxe(h`^%htuPMjEoFyGW94U z_AosjOG{5Io$|B-0H}69Vb7uC{K>LZwnfl}_S1K2hnf@mtCG#B9}2f{eSOU=cu-1G zeDV>!V4p$ZZf~>{EV%LK<%9-_EygB`e^1)*zePdgEBIfT0hczpYrup&!JS);on3^F5l$YBtwyP!O8^ZrJJ zxL&*>R$lKAZ5oqc^dg1XvXpB`3##Sy-@*+<+uwu>OWU&=9`lRI-{sADXmZ)c&;_8| z76seProR_w9wFY0ekzElx_}nx*Sch&f9JwROeE?(cP}GbAd_i>*7K~l{zd$G0X90M ze=E@jR8LOn2f?o?^{P?E@c&nL7Hu4W^8Ml)eQ*XyUp$mX@i21LrxGeG!4tH(y>r&rx3wjpCZ>r` z#-x(_VjJ=Hk*`L4)mI90RDQZMU3m|%L7zL`zeT+b7r)&db&}*eYO1I0dzE88mCtI? z@e3sPjF|e`0b!0g)p|lRTYawg)*Em1v_mzoS5l@|1(br9F!=GL_Ko}QAUz?=k+4r& zY~zHb_HX31(4yXk@wbn8mtve6=t23K^dDm+{{^{2(hUuUtd-eu(!|b8c0nQ85xrI} z@-Os&EFX%gSYNqv91am0DZ^RA0}GIEws^I+$1(jxPJyhG&@qaU=Y>^QA;52*VY1=NlHtIz-3dtqfEji@+mWDM)c*dT{jV)%Q%(?H;gyA<{Q0QY zejRl(%vtH>;&Q?vlto7}B*yTkb=;t-ce!k4uGA5oPU)JWmRQU3qnIyU_c4ETm~6TUzCt>Obt9iy{y>#1uCRu1c*dR;GoiKh9F_ zyoK*2E)N-Ja*ACPa@01}U>9_FZ~KZe`(?lAg)nm`_#F)E!*~%n_Y96=+}F>V*68$@ z&c8fD&wD4@bNqW9-DYp3dR>lX1m0R^ol*h1J<ZpXL6bqL1CcKxNyQb zwloewF~%1B#=y--C4# zR6*V1ZFMu)5n4m}c4^T0CCmcyLQ(1XlZ@;Nj#PIgXNIJ;uB{X+lH{|tLjj$xYNth& ziJC(SS-($u|3Rp!E3BOG_#rXocGIy@G!sxj#kVXKi1?DFla{F?B+T4jMM)I>o$dq1 z%!7Tew`RJ?s}n@3$d%K+k8o5@(g9wqfc=i~_9Az#CTMQbC9VA~GXH463nj`Q*?H+E zZfX-^g56s8#e=E_oT+?hndypYXiW)jTu}*@1V7323v6O)%E~blbz%aOq_EK}nBDZr zYe}M}9V^4SiZC7!>W@s-qCi)nn02P$^T;t^W7uB~+8e2YSC1=<Xy$xC~m ztJ@OoLKQT-sE6RY5Koxr+2Iz@f~<1KI>_SH0|lDb+RU;hv0qDv+m6M`kP%q46+#Yt aggiVyGk@*G?8xd#0Q>im2({kP*?$9;MD`2- diff --git a/Data/assets_sources/Tactility.svg b/Data/assets_sources/Tactility.svg index 7acc57b2..699ed9cf 100644 --- a/Data/assets_sources/Tactility.svg +++ b/Data/assets_sources/Tactility.svg @@ -9,9 +9,9 @@ id="svg1" inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="Tactility.svg" - inkscape:export-filename="Tactility.png" - inkscape:export-xdpi="96" - inkscape:export-ydpi="96" + inkscape:export-filename="../assets/boot_logo.png" + inkscape:export-xdpi="22.013334" + inkscape:export-ydpi="22.013334" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" @@ -27,14 +27,14 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="1" - inkscape:cx="410.5" - inkscape:cy="336.5" - inkscape:window-width="2115" - inkscape:window-height="1295" - inkscape:window-x="26" - inkscape:window-y="23" - inkscape:window-maximized="0" - inkscape:current-layer="svg1" + inkscape:cx="411" + inkscape:cy="336" + inkscape:window-width="1503" + inkscape:window-height="930" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="g29" showgrid="false" /> @@ -221,53 +221,55 @@ inkscape:label="Glyph"> - - - + inkscape:label="Upright T" + style="fill:#7376ff;fill-opacity:1" /> - - - + inkscape:label="Upside-down T" + style="fill:#f876e9;fill-opacity:1" /> + + + + id.c_str()); hash_mutex.acquire(TtWaitForever); - app_manifest_map[manifest->id] = manifest; + + if (app_manifest_map[manifest->id] == nullptr) { + app_manifest_map[manifest->id] = manifest; + } else { + TT_LOG_E(TAG, "App id in use: %s", manifest->id.c_str()); + } + hash_mutex.release(); } _Nullable const AppManifest * findAppById(const std::string& id) { hash_mutex.acquire(TtWaitForever); - auto iterator = app_manifest_map.find(id); - _Nullable const AppManifest* result = iterator != app_manifest_map.end() ? iterator->second : nullptr; + _Nullable const AppManifest* result = app_manifest_map[id.c_str()]; hash_mutex.release(); return result; } diff --git a/Tactility/Source/app/desktop/Desktop.cpp b/Tactility/Source/app/desktop/Desktop.cpp index bd901167..7c86fefb 100644 --- a/Tactility/Source/app/desktop/Desktop.cpp +++ b/Tactility/Source/app/desktop/Desktop.cpp @@ -49,8 +49,10 @@ static void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) { lv_obj_set_flex_grow(wrapper, 1); auto* display = lv_obj_get_display(parent); - auto orientation = lv_display_get_rotation(display); - if (orientation == LV_DISPLAY_ROTATION_0 || orientation == LV_DISPLAY_ROTATION_180) { + auto horizontal_px = lv_display_get_horizontal_resolution(display); + auto vertical_px = lv_display_get_vertical_resolution(display); + bool is_landscape_display = horizontal_px > vertical_px; + if (is_landscape_display) { lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_ROW); } else { lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); diff --git a/Tactility/Source/app/display/Display.cpp b/Tactility/Source/app/display/Display.cpp index 77575f70..cc85d73d 100644 --- a/Tactility/Source/app/display/Display.cpp +++ b/Tactility/Source/app/display/Display.cpp @@ -30,17 +30,17 @@ static void onSliderEvent(lv_event_t* event) { } } -#define ORIENTATION_LANDSCAPE 0 -#define ORIENTATION_LANDSCAPE_FLIPPED 1 -#define ORIENTATION_PORTRAIT_LEFT 2 -#define ORIENTATION_PORTRAIT_RIGHT 3 +#define ROTATION_DEFAULT 0 +#define ROTATION_180 1 +#define ROTATION_270 2 +#define ROTATION_90 3 -static lv_display_rotation_t orientationSettingToDisplayOrientation(uint32_t setting) { - if (setting == ORIENTATION_LANDSCAPE_FLIPPED) { +static lv_display_rotation_t orientationSettingToDisplayRotation(uint32_t setting) { + if (setting == ROTATION_180) { return LV_DISPLAY_ROTATION_180; - } else if (setting == ORIENTATION_PORTRAIT_LEFT) { + } else if (setting == ROTATION_270) { return LV_DISPLAY_ROTATION_270; - } else if (setting == ORIENTATION_PORTRAIT_RIGHT) { + } else if (setting == ROTATION_90) { return LV_DISPLAY_ROTATION_90; } else { return LV_DISPLAY_ROTATION_0; @@ -49,13 +49,13 @@ static lv_display_rotation_t orientationSettingToDisplayOrientation(uint32_t set static uint32_t dipslayOrientationToOrientationSetting(lv_display_rotation_t orientation) { if (orientation == LV_DISPLAY_ROTATION_90) { - return ORIENTATION_PORTRAIT_RIGHT; + return ROTATION_90; } else if (orientation == LV_DISPLAY_ROTATION_180) { - return ORIENTATION_LANDSCAPE_FLIPPED; + return ROTATION_180; } else if (orientation == LV_DISPLAY_ROTATION_270) { - return ORIENTATION_PORTRAIT_LEFT; + return ROTATION_270; } else { - return ORIENTATION_LANDSCAPE; + return ROTATION_DEFAULT; } } @@ -63,7 +63,7 @@ static void onOrientationSet(lv_event_t* event) { auto* dropdown = static_cast(lv_event_get_target(event)); uint32_t selected = lv_dropdown_get_selected(dropdown); TT_LOG_I(TAG, "Selected %ld", selected); - lv_display_rotation_t rotation = orientationSettingToDisplayOrientation(selected); + lv_display_rotation_t rotation = orientationSettingToDisplayRotation(selected); if (lv_display_get_rotation(lv_display_get_default()) != rotation) { lv_display_set_rotation(lv_display_get_default(), rotation); setRotation(rotation); @@ -111,8 +111,17 @@ static void onShow(AppContext& app, lv_obj_t* parent) { lv_label_set_text(orientation_label, "Orientation"); lv_obj_align(orientation_label, LV_ALIGN_TOP_LEFT, 0, 40); + auto horizontal_px = lv_display_get_horizontal_resolution(lvgl_display); + auto vertical_px = lv_display_get_vertical_resolution(lvgl_display); + bool is_landscape_display = horizontal_px > vertical_px; + lv_obj_t* orientation_dropdown = lv_dropdown_create(wrapper); - lv_dropdown_set_options(orientation_dropdown, "Landscape\nLandscape (flipped)\nPortrait Left\nPortrait Right"); + if (is_landscape_display) { + lv_dropdown_set_options(orientation_dropdown, "Landscape\nLandscape (flipped)\nPortrait Left\nPortrait Right"); + } else { + lv_dropdown_set_options(orientation_dropdown, "Portrait\nPortrait (flipped)\nLandscape Left\nLandscape Right"); + } + lv_obj_align(orientation_dropdown, LV_ALIGN_TOP_RIGHT, 0, 32); lv_obj_add_event_cb(orientation_dropdown, onOrientationSet, LV_EVENT_VALUE_CHANGED, nullptr); uint32_t orientation_selected = dipslayOrientationToOrientationSetting( diff --git a/Tactility/Source/app/files/Files.cpp b/Tactility/Source/app/files/Files.cpp index d168d894..5e234423 100644 --- a/Tactility/Source/app/files/Files.cpp +++ b/Tactility/Source/app/files/Files.cpp @@ -100,10 +100,6 @@ static void onNavigateUpPressed(TT_UNUSED lv_event_t* event) { updateViews(files_data); } -static void onExitAppPressed(TT_UNUSED lv_event_t* event) { - service::loader::stopApp(); -} - static void viewFile(const char* path, const char* filename) { size_t path_len = strlen(path); size_t filename_len = strlen(filename); @@ -222,7 +218,6 @@ static void onShow(AppContext& app, lv_obj_t* parent) { lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_t* toolbar = lvgl::toolbar_create(parent, "Files"); - lvgl::toolbar_set_nav_action(toolbar, LV_SYMBOL_CLOSE, &onExitAppPressed, nullptr); lvgl::toolbar_add_action(toolbar, LV_SYMBOL_UP, &onNavigateUpPressed, nullptr); data->list = lv_list_create(parent); diff --git a/TactilityHeadless/Source/service/ServiceRegistry.cpp b/TactilityHeadless/Source/service/ServiceRegistry.cpp index 022f1771..c3dd71dd 100644 --- a/TactilityHeadless/Source/service/ServiceRegistry.cpp +++ b/TactilityHeadless/Source/service/ServiceRegistry.cpp @@ -24,7 +24,11 @@ void addService(const ServiceManifest* manifest) { TT_LOG_I(TAG, "Adding %s", manifest->id.c_str()); manifest_mutex.acquire(TtWaitForever); - service_manifest_map[manifest->id] = manifest; + if (service_manifest_map[manifest->id] == nullptr) { + service_manifest_map[manifest->id] = manifest; + } else { + TT_LOG_E(TAG, "Service id in use: %s", manifest->id.c_str()); + } manifest_mutex.release(); }