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 aee93822..0a3c5fc8 100644 Binary files a/Data/assets/boot_logo.png and b/Data/assets/boot_logo.png differ 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(); }