diff --git a/Documentation/ideas.md b/Documentation/ideas.md index ebfdeee2..658a9e23 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -1,5 +1,4 @@ # TODOs -- Update `view_port` to use `ViewPort` as handle externally and `ViewPortData` internally - Create more unit tests for `tactility-core` and `tactility` (PC-only for now) - Have a way to deinit LVGL drivers that are created from `HardwareConfig` - Show a warning screen if firmware encryption or secure boot are off when saving WiFi credentials. @@ -28,9 +27,6 @@ - tt::setAppResult() for apps that need to return data to other apps (e.g. file selection) - Wi-Fi using dispatcher to dispatch its main functionality to the dedicated Wi-Fi CPU core (to avoid main loop hack) -# App Improvement Ideas -- Light/dark mode selection in Display settings app. - # App Ideas - BlueTooth keyboard app - Chip 8 emulator diff --git a/README.md b/README.md index 304dfbee..a11b0cb6 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ ## Overview -Tactility is a front-end application platform for ESP32. It is mainly intended for touchscreen devices. -It provides an application framework that is based on code from the [Flipper Zero](https://github.com/flipperdevices/flipperzero-firmware/) project. +Tactility is a front-end application platform for ESP32. +It is currently intended for touchscreen devices, but the goal is to also support different types of input in the future. +Tactility provides an application framework that borrows concepts from [Flipper Zero](https://github.com/flipperdevices/flipperzero-firmware/) and mobile phone operating systems. ![photo of devices running Tactility](Documentation/pics/tactility-devices.webp) **Status: Alpha** -A modern desktop with built-in apps: +A desktop with built-in apps: ![screenshot of desktop app](Documentation/pics/screenshot-Desktop.png) ![screenshot of settings app](Documentation/pics/screenshot-Settings.png) @@ -19,7 +20,6 @@ And much more! ![screenshot of GPIO app](Documentation/pics/screenshot-Gpio.png) ![screenshot of files app](Documentation/pics/screenshot-Files.png) - Play with the built-in apps or build your own! Use one of the supported devices or set up the drivers for your own hardware platform. Noteworthy features: @@ -30,7 +30,7 @@ Noteworthy features: Requirements: - ESP32 (any?) with a touchscreen -- [esp-idf 5.3](https://docs.espressif.com/projects/esp-idf/en/release-v5.3/esp32/get-started/index.html) or a newer v5.2.x +- [esp-idf 5.3](https://docs.espressif.com/projects/esp-idf/en/release-v5.3/esp32/get-started/index.html) or a newer v5.3.x ## Making apps is easy! @@ -57,12 +57,8 @@ static void app_show(App app, lv_obj_t* parent) { extern const AppManifest manifest = { .id = "HelloWorld", // Used to identify and start an app .name = "Hello World", // Shown on the desktop and app's toolbar - .icon = NULL, .type = AppTypeUser, - .on_start = nullptr, - .on_stop = nullptr, - .on_show = &app_show, // A minimal setup sets the on_show() function - .on_hide = nullptr + .on_show = &app_show // A minimal setup sets the on_show() function }; ``` @@ -108,7 +104,7 @@ git clone --recurse-submodules -j8 https://github.com/ByteWelder/Tactility.git ### Build environment setup -nsure you have [esp-idf 5.3](https://docs.espressif.com/projects/esp-idf/en/release-v5.3/esp32/get-started/index.html) installed, then select the correct device: +Ensure you have [esp-idf 5.3](https://docs.espressif.com/projects/esp-idf/en/release-v5.3/esp32/get-started/index.html) installed, then select the correct device: Copy the `sdkconfig.board.YOUR_BOARD` into `sdkconfig`. Use `sdkconfig.defaults` if you are setting up a custom board. diff --git a/Tactility/Source/Apps/Display/Display.cpp b/Tactility/Source/Apps/Display/Display.cpp index 09823d94..53743306 100644 --- a/Tactility/Source/Apps/Display/Display.cpp +++ b/Tactility/Source/Apps/Display/Display.cpp @@ -2,8 +2,9 @@ #include "Assets.h" #include "DisplayPreferences.h" #include "Tactility.h" -#include "lvgl.h" +#include "Ui/Style.h" #include "Ui/Toolbar.h" +#include "lvgl.h" namespace tt::app::settings::display { @@ -72,22 +73,24 @@ static void app_show(App app, lv_obj_t* parent) { lvgl::toolbar_create(parent, app); - lv_obj_t* wrapper = lv_obj_create(parent); - lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); - lv_obj_set_width(wrapper, LV_PCT(100)); - lv_obj_set_style_border_width(wrapper, 0, 0); - lv_obj_set_flex_grow(wrapper, 1); + lv_obj_t* main_wrapper = lv_obj_create(parent); + lv_obj_set_flex_flow(main_wrapper, LV_FLEX_FLOW_COLUMN); + lv_obj_set_width(main_wrapper, LV_PCT(100)); + lv_obj_set_flex_grow(main_wrapper, 1); - lv_obj_t* brightness_wrapper = lv_obj_create(wrapper); - lv_obj_set_size(brightness_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_t* brightness_label = lv_label_create(brightness_wrapper); + lv_obj_t* wrapper = lv_obj_create(main_wrapper); + lv_obj_set_width(wrapper, LV_PCT(100)); + lv_obj_set_style_pad_all(wrapper, 8, 0); + lv_obj_set_style_border_width(wrapper, 0, 0); + + lv_obj_t* brightness_label = lv_label_create(wrapper); lv_label_set_text(brightness_label, "Brightness"); - lv_obj_t* brightness_slider = lv_slider_create(brightness_wrapper); - lv_obj_set_width(brightness_slider, LV_PCT(100)); + lv_obj_t* brightness_slider = lv_slider_create(wrapper); + lv_obj_set_width(brightness_slider, LV_PCT(50)); + lv_obj_align(brightness_slider, LV_ALIGN_TOP_RIGHT, -8, 0); lv_slider_set_range(brightness_slider, 0, 255); lv_obj_add_event_cb(brightness_slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); - lv_obj_set_pos(brightness_slider, 0, 30); const Configuration* config = getConfiguration(); hal::SetBacklightDuty set_backlight_duty = config->hardware->display.setBacklightDuty; @@ -99,14 +102,13 @@ static void app_show(App app, lv_obj_t* parent) { lv_slider_set_value(brightness_slider, value, LV_ANIM_OFF); } - lv_obj_t* orientation_wrapper = lv_obj_create(wrapper); - lv_obj_set_size(orientation_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_t* orientation_label = lv_label_create(orientation_wrapper); + lv_obj_t* orientation_label = lv_label_create(wrapper); lv_label_set_text(orientation_label, "Orientation"); - lv_obj_align(orientation_label, LV_ALIGN_LEFT_MID, 0, 0); - lv_obj_t* orientation_dropdown = lv_dropdown_create(orientation_wrapper); + lv_obj_align(orientation_label, LV_ALIGN_TOP_LEFT, 0, 40); + + lv_obj_t* orientation_dropdown = lv_dropdown_create(wrapper); lv_dropdown_set_options(orientation_dropdown, "Landscape\nLandscape (flipped)\nPortrait Left\nPortrait Right"); - lv_obj_align(orientation_dropdown, LV_ALIGN_RIGHT_MID, 0, 0); + lv_obj_align(orientation_dropdown, LV_ALIGN_TOP_RIGHT, 0, 32); lv_obj_add_event_cb(orientation_dropdown, on_orientation_set, LV_EVENT_VALUE_CHANGED, nullptr); uint32_t orientation_selected = display_rotation_to_orientation_setting( lv_display_get_rotation(lv_display_get_default()) diff --git a/TactilityCore/Source/Check.h b/TactilityCore/Source/Check.h index f6ebd4a0..86ecc14c 100644 --- a/TactilityCore/Source/Check.h +++ b/TactilityCore/Source/Check.h @@ -53,7 +53,7 @@ TT_NORETURN void tt_crash_implementation(); * @param optional message (const char*) */ -#define tt_check(x, ...) if (!(x)) { TT_LOG_E("check", "Failed: %s", #x); }; +#define tt_check(x, ...) if (!(x)) { TT_LOG_E("check", "Failed: %s", #x); tt_crash_implementation(); }; /** Only in debug build: Assert condition and crash if assert failed */ #ifdef TT_DEBUG diff --git a/TactilityHeadless/Source/Hal/Configuration.h b/TactilityHeadless/Source/Hal/Configuration.h index 7d89746d..390935c1 100644 --- a/TactilityHeadless/Source/Hal/Configuration.h +++ b/TactilityHeadless/Source/Hal/Configuration.h @@ -33,7 +33,7 @@ typedef struct { /** * Create and initialize all LVGL devices. (e.g. display, touch, keyboard) */ - const InitLvgl initLvgl; + const InitLvgl _Nullable initLvgl; /** * Display HAL functionality. diff --git a/TactilityHeadless/Source/Hal/Hal.cpp b/TactilityHeadless/Source/Hal/Hal.cpp index 5b424306..5616e1f5 100644 --- a/TactilityHeadless/Source/Hal/Hal.cpp +++ b/TactilityHeadless/Source/Hal/Hal.cpp @@ -1,7 +1,7 @@ #include "Hal/Hal_i.h" #include "Hal/I2c/I2c.h" -#define TAG "hardware" +#define TAG "hal" namespace tt::hal { @@ -24,8 +24,10 @@ void init(const Configuration& configuration) { } } - tt_check(configuration.initLvgl, "Graphics init not set"); - tt_check(configuration.initLvgl(), "Graphics init failed"); + if (configuration.initLvgl != nullptr) { + TT_LOG_I(TAG, "Init LVGL"); + tt_check(configuration.initLvgl(), "LVGL init failed"); + } } } // namespace