From b27b546fdb466aab25523ad75eb07b46e492d22e Mon Sep 17 00:00:00 2001 From: Austin-Fulbright Date: Wed, 11 Sep 2024 06:01:11 -0400 Subject: [PATCH 1/2] added custom theme builder --- .vscode/settings.json | 7 +++ dependencies.lock.esp32s3 | 108 ++++++++++++++++++++++++++++++++------ main/button_events.h | 6 +++ main/gui.c | 6 ++- main/gui.h | 3 +- main/process/dashboard.c | 88 ++++++++++++++++++++++++++++++- main/ui/dashboard.c | 41 ++++++++++++++- 7 files changed, 239 insertions(+), 20 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..702395da --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "idf.adapterTargetName": "esp32s3", + "idf.port": "/dev/ttyACM0", + "idf.openOcdConfigs": [ + "board/esp32s3-builtin.cfg" + ] +} \ No newline at end of file diff --git a/dependencies.lock.esp32s3 b/dependencies.lock.esp32s3 index 43bb07c1..926f06af 100644 --- a/dependencies.lock.esp32s3 +++ b/dependencies.lock.esp32s3 @@ -1,81 +1,159 @@ dependencies: espressif/button: component_hash: 1f5297fe16f0ee988dbb14b6f4c91782fe2baf85025bb15cc1e0093edd3fb2ee + dependencies: + - name: espressif/cmake_utilities + registry_url: https://components.espressif.com/ + require: private + version: 0.* + - name: idf + require: private + version: '>=4.0' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 3.2.0 espressif/cbor: component_hash: 440f4ee4504841cc9b4f3a8ef755776a612ac9dace355514c68b999868f990ff + dependencies: + - name: idf + require: private + version: '>=4.3' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 0.6.0~1 espressif/cmake_utilities: component_hash: 351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f + dependencies: + - name: idf + require: private + version: '>=4.1' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 0.5.3 espressif/esp-dsp: component_hash: 3e7bbd487f1357a1d4944d0c85966d049501ea281b8a4c7f93f7cfedd5b7f23d + dependencies: + - name: idf + require: private + version: '>=4.2' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 1.4.12 espressif/esp32-camera: component_hash: a1933162caca04a3a3bb0dca00bb56fcb3c50cd3779ab2f2b03ad8536e9bd0d0 + dependencies: [] source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 2.0.9 espressif/esp_lcd_touch: component_hash: d4d8f2dc33205797169a97a02e0d89a8982f59fe0509129b54422052b8522f59 + dependencies: + - name: idf + require: private + version: '>=4.4.2' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 1.1.1 espressif/esp_lcd_touch_ft5x06: component_hash: 97759953d9436a365e9427078c5b04ecce4e6a50f50cf62c68cd6bfa229b812c + dependencies: + - name: espressif/esp_lcd_touch + registry_url: https://components.espressif.com/ + require: public + version: ^1.0.4 + - name: idf + require: private + version: '>=4.4.2' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 1.0.6 espressif/esp_tinyusb: component_hash: f151d680d6847bfcfd5d8eb6d1c3ff926c208e6b963b2e83643a141bc70baa15 + dependencies: + - name: idf + require: private + version: '>=5.0' + - name: espressif/tinyusb + registry_url: https://components.espressif.com/ + require: public + version: '>=0.14.2' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 1.4.4 espressif/libsodium: component_hash: f6e982479a2389cb6868e8fb761cf23aba6c355a8090b3e906299807775f58a3 + dependencies: + - name: idf + require: private + version: '>=4.2' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 1.0.20~1 espressif/nghttp: component_hash: 5e55c2fc982f7ddd257818be86f50d60705f3fd3a39d709c399434e81d458e1e + dependencies: + - name: idf + require: private + version: '>=5.0' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service version: 1.58.0 espressif/tinyusb: component_hash: 256fd8aee92ae9f1014538b8601508907a2da386b64f6d42f35a67f9288d1b20 + dependencies: + - name: idf + require: private + version: '>=5.0' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service + targets: + - esp32s2 + - esp32s3 + - esp32p4 version: 0.15.0~9 espressif/usb_host_msc: component_hash: fb036253308af19de381558560f3a57ead7d2139cf5212b684a408caeb7753cb + dependencies: + - name: idf + require: private + version: '>=4.4.1' source: - service_url: https://api.components.espressif.com/ + registry_url: https://components.espressif.com/ type: service + targets: + - esp32s2 + - esp32s3 + - esp32p4 version: 1.1.2 idf: - component_hash: null source: type: idf version: 5.2.2 -manifest_hash: a71d5a8d6dfacd88754066af10bbd322320a68f03e2842b3633eb0f7b4644801 +direct_dependencies: +- espressif/button +- espressif/cbor +- espressif/cmake_utilities +- espressif/esp-dsp +- espressif/esp32-camera +- espressif/esp_lcd_touch +- espressif/esp_lcd_touch_ft5x06 +- espressif/esp_tinyusb +- espressif/libsodium +- espressif/nghttp +- espressif/tinyusb +- espressif/usb_host_msc +- idf +manifest_hash: f87516193b33af3806bb180876292cbd0a4407775edbdef8169afdad9f537888 target: esp32s3 -version: 1.0.0 +version: 2.0.0 diff --git a/main/button_events.h b/main/button_events.h index 7a24058d..41e723a2 100644 --- a/main/button_events.h +++ b/main/button_events.h @@ -131,6 +131,12 @@ typedef enum { BTN_SETTINGS_DISPLAY_BRIGHTNESS, BTN_SETTINGS_DISPLAY_ORIENTATION, BTN_SETTINGS_DISPLAY_THEME, + BTN_SETTINGS_CREATE_CUSTOM_THEME, + BTN_THEME_SAVE, + BTN_COLOR_RED, + BTN_COLOR_GREEN, + BTN_COLOR_BLUE, + BTN_SETTINGS_CUSTOM_THEME_EXIT, BTN_SETTINGS_XPUB_EXPORT, BTN_SETTINGS_QR_PINSERVER, BTN_SETTINGS_TEMPORARY_WALLET_LOGIN, diff --git a/main/gui.c b/main/gui.c index 29515b18..cba7b65b 100644 --- a/main/gui.c +++ b/main/gui.c @@ -44,6 +44,7 @@ const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_ORANGE = 0xE0D3; const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_BLUE = 0xD318; const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_DARKGREY = 0xA210; const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_LIGHTGREY = 0xB294; +color_t CUSTOM_THEME_COLOR = 0xE010; typedef struct _activity_holder_t activity_holder_t; struct _activity_holder_t { @@ -220,8 +221,11 @@ void gui_set_highlight_color(const uint8_t theme) case 4: gui_highlight_color = GUI_BLOCKSTREAM_HIGHTLIGHT_LIGHTGREY; break; + case 5: + gui_highlight_color = CUSTOM_THEME_COLOR; //custom theme + break; default: - gui_highlight_color = GUI_BLOCKSTREAM_HIGHTLIGHT_DEFAULT; // jade green + gui_highlight_color = GUI_BLOCKSTREAM_HIGHTLIGHT_DEFAULT; //jade green break; } } diff --git a/main/gui.h b/main/gui.h index 871e48a1..964cf0a2 100644 --- a/main/gui.h +++ b/main/gui.h @@ -20,6 +20,7 @@ extern const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_ORANGE; extern const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_BLUE; extern const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_DARKGREY; extern const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_LIGHTGREY; +extern color_t CUSTOM_THEME_COLOR; // -------------- Configuration ----------------- @@ -49,7 +50,7 @@ extern uint8_t GUI_DEFAULT_FONT; #define GUI_SPLIT_FILL_REMAINING 0xFF // Number of GUI themes -#define GUI_NUM_DISPLAY_THEMES 5 +#define GUI_NUM_DISPLAY_THEMES 6 // Bits used to enable or disable a border #define GUI_BORDER_TOP_BIT 0 diff --git a/main/process/dashboard.c b/main/process/dashboard.c index 09892a44..353e86c0 100644 --- a/main/process/dashboard.c +++ b/main/process/dashboard.c @@ -179,6 +179,8 @@ gui_activity_t* make_uninitialised_settings_activity(void); gui_activity_t* make_locked_settings_activity(void); gui_activity_t* make_unlocked_settings_activity(void); +gui_activity_t* make_custom_theme_activity(gui_view_node_t** red_textbox, gui_view_node_t** green_textbox, gui_view_node_t** blue_textbox); + gui_activity_t* make_wallet_settings_activity(void); gui_activity_t* make_device_settings_activity(void); gui_activity_t* make_usbstorage_settings_activity(bool unlocked); @@ -1823,7 +1825,7 @@ static void update_home_screen_item_highlight_color(gui_view_node_t* item) static void handle_display_theme(void) { static const char* THEME_NAMES[GUI_NUM_DISPLAY_THEMES] - = { "Jade Green", "Bitcoin Orange", "Liquid Blue", "Cypherpunk Black", "Open-Source Opal" }; + = { "Jade Green", "Bitcoin Orange", "Liquid Blue", "Cypherpunk Black", "Open-Source Opal", "Custom Theme" }; JADE_ASSERT(GUI_NUM_DISPLAY_THEMES < GUI_FLAGS_THEMES_MASK); const uint8_t initial_gui_flags = storage_get_gui_flags(); @@ -1876,6 +1878,86 @@ static void handle_display_theme(void) } } + + +void generate_color_string(char* buffer, size_t size, const char* color_name, int color_value) { + snprintf(buffer, size, "%s{%d}", color_name, color_value); +} + +void handle_color_activity(const char* color_name, int* color, gui_view_node_t* color_text, gui_activity_t* parent_act) { + gui_view_node_t* color_c_text = NULL; + char color_str[20]; + generate_color_string(color_str, sizeof(color_str), color_name, *color); + + gui_activity_t* act = make_carousel_activity(color_name, NULL, &color_c_text); + gui_update_text(color_c_text, color_str); + gui_set_current_activity(act); + + int32_t ev_id; + while (gui_activity_wait_event(act, GUI_EVENT, ESP_EVENT_ANY_ID, NULL, &ev_id, NULL, 0)) { + if (ev_id == GUI_WHEEL_LEFT_EVENT) { + *color = (*color - 8 + 256) % 256; + } else if (ev_id == GUI_WHEEL_RIGHT_EVENT) { + *color = (*color + 8) % 256; + } else if (ev_id == gui_get_click_event()) { + break; + } + + // Update color string and repaint + generate_color_string(color_str, sizeof(color_str), color_name, *color); + gui_update_text(color_c_text, color_str); + gui_repaint(color_c_text->parent); + } + + // Update the original color text and return to the main activity + gui_update_text(color_text, color_str); + gui_set_current_activity(parent_act); +} + +// Main custom theme handler +static void handle_custom_theme(void) { + gui_view_node_t* red_text = NULL; + gui_view_node_t* green_text = NULL; + gui_view_node_t* blue_text = NULL; + + int red = 0, green = 0, blue = 0; + char red_text_str[20], green_text_str[20], blue_text_str[20]; + + generate_color_string(red_text_str, sizeof(red_text_str), "Red", red); + generate_color_string(green_text_str, sizeof(green_text_str), "Green", green); + generate_color_string(blue_text_str, sizeof(blue_text_str), "Blue", blue); + + gui_activity_t* act = make_custom_theme_activity(&red_text, &green_text, &blue_text); + int32_t ev_id; + + while (true) { + gui_set_current_activity(act); + bool ret = gui_activity_wait_event(act, GUI_BUTTON_EVENT, ESP_EVENT_ANY_ID, NULL, &ev_id, NULL, 0); + if (ret) { + if (ev_id == BTN_THEME_SAVE) { + // Save the current color combination as the custom theme color + CUSTOM_THEME_COLOR = (red << 16) | (green << 8) | blue; + break; + } else if (ev_id == BTN_SETTINGS_CUSTOM_THEME_EXIT) { + // Exit the custom theme screen + break; + } else if (ev_id == BTN_COLOR_RED) { + // Handle red color adjustment + handle_color_activity("Red", &red, red_text, act); + } else if (ev_id == BTN_COLOR_GREEN) { + // Handle green color adjustment + handle_color_activity("Green", &green, green_text, act); + } else if (ev_id == BTN_COLOR_BLUE) { + // Handle blue color adjustment + handle_color_activity("Blue", &blue, blue_text, act); + } + } + } +} + + + + static void handle_flip_orientation(void) { const uint8_t initial_gui_flags = storage_get_gui_flags(); @@ -2191,6 +2273,10 @@ static void handle_settings(const bool startup_menu) // Change to 'Device' menu act = make_display_settings_activity(); break; + case BTN_SETTINGS_CREATE_CUSTOM_THEME: + // Change to 'Create Custom Theme' menu + handle_custom_theme(); + break; case BTN_SETTINGS_AUTHENTICATION: case BTN_SETTINGS_OTP_EXIT: diff --git a/main/ui/dashboard.c b/main/ui/dashboard.c index eafc7559..1feb6031 100644 --- a/main/ui/dashboard.c +++ b/main/ui/dashboard.c @@ -398,6 +398,7 @@ gui_activity_t* make_prefs_settings_activity(const bool initialised_and_locked, return make_menu_activity("Settings", hdrbtns, 2, menubtns, 3); } + gui_activity_t* make_display_settings_activity(void) { btn_data_t hdrbtns[] = { { .txt = "=", .font = JADE_SYMBOLS_16x16_FONT, .ev_id = BTN_SETTINGS_DISPLAY_EXIT }, @@ -422,13 +423,49 @@ gui_activity_t* make_display_settings_activity(void) #else // DIY units btn_data_t menubtns[] = { { .txt = "Flip Orientation", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_ORIENTATION }, - { .txt = "Theme", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_THEME } }; - const size_t num_menubtns = 2; + { .txt = "Theme", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_THEME }, + { .txt = "Create Custom Theme", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_CREATE_CUSTOM_THEME } }; + const size_t num_menubtns = 3; #endif return make_menu_activity("Display", hdrbtns, 2, menubtns, num_menubtns); } +void create_color_button_and_textbox(gui_view_node_t** textbox, const char* color_name, color_t color, gui_view_node_t* parent, uint32_t ev_id) { + gui_make_text(textbox, color_name, TFT_WHITE); + gui_set_align(*textbox, GUI_ALIGN_CENTER, GUI_ALIGN_MIDDLE); + gui_set_margins(*textbox, GUI_MARGIN_ALL_DIFFERENT, 0, 0, 0, 0); + gui_set_borders(*textbox, color, 1, GUI_BORDER_ALL); + gui_set_colors(*textbox, color, TFT_LIGHTGREY); + + btn_data_t button_data = { .content = *textbox, .font = GUI_DEFAULT_FONT, .ev_id = ev_id }; + add_button(parent, &button_data); +} + +gui_activity_t* make_custom_theme_activity(gui_view_node_t** red_textbox, gui_view_node_t** green_textbox, gui_view_node_t** blue_textbox) { + JADE_INIT_OUT_PPTR(red_textbox); + JADE_INIT_OUT_PPTR(green_textbox); + JADE_INIT_OUT_PPTR(blue_textbox); + + btn_data_t hdrbtns[] = { + { .txt = "Save", .font = GUI_DEFAULT_FONT, .ev_id = BTN_THEME_SAVE }, + { .txt = "Exit", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_CUSTOM_THEME_EXIT } + }; + + gui_activity_t* act = gui_make_activity(); + gui_view_node_t* parent = add_title_bar(act, "Custom", hdrbtns, 2, NULL); + + gui_view_node_t* vsplit; + gui_make_vsplit(&vsplit, GUI_SPLIT_RELATIVE, 3, 33, 33, 33); + gui_set_parent(vsplit, parent); + + create_color_button_and_textbox(red_textbox, "Red {0}", TFT_RED, vsplit, BTN_COLOR_RED); + create_color_button_and_textbox(green_textbox, "Green {0}", TFT_GREEN, vsplit, BTN_COLOR_GREEN); + create_color_button_and_textbox(blue_textbox, "Blue {0}", TFT_BLUE, vsplit, BTN_COLOR_BLUE); + + return act; +} + gui_activity_t* make_authentication_activity(const bool initialised_and_pin_unlocked) { btn_data_t hdrbtns[] = { { .txt = "=", .font = JADE_SYMBOLS_16x16_FONT, .ev_id = BTN_SETTINGS_AUTHENTICATION_EXIT }, From c10f7fffb1767af73ce26664d9daf660b3a7c8c9 Mon Sep 17 00:00:00 2001 From: Austin-Fulbright Date: Wed, 11 Sep 2024 07:55:08 -0400 Subject: [PATCH 2/2] added functions for persistence --- .gitignore | 4 +++- .vscode/settings.json | 5 ++++- main/gui.c | 7 ++++++- main/gui.h | 2 ++ main/process/dashboard.c | 1 + main/storage.c | 15 +++++++++++++++ main/storage.h | 3 +++ 7 files changed, 34 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 641471f9..02ab0e77 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,6 @@ main/autogen_lang.* tools/bsdiff .idea/ managed_components/ -.DS_Store \ No newline at end of file +.DS_Store +.vscode/ +dependencies.lock.esp32s3 diff --git a/.vscode/settings.json b/.vscode/settings.json index 702395da..179307ab 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,8 @@ "idf.port": "/dev/ttyACM0", "idf.openOcdConfigs": [ "board/esp32s3-builtin.cfg" - ] + ], + "files.associations": { + "storage.h": "c" + } } \ No newline at end of file diff --git a/main/gui.c b/main/gui.c index cba7b65b..d5824387 100644 --- a/main/gui.c +++ b/main/gui.c @@ -44,7 +44,8 @@ const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_ORANGE = 0xE0D3; const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_BLUE = 0xD318; const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_DARKGREY = 0xA210; const color_t GUI_BLOCKSTREAM_HIGHTLIGHT_LIGHTGREY = 0xB294; -color_t CUSTOM_THEME_COLOR = 0xE010; +color_t CUSTOM_THEME_COLOR = 0x4c04; + typedef struct _activity_holder_t activity_holder_t; struct _activity_holder_t { @@ -111,6 +112,10 @@ extern const uint8_t statusbar_logo_start[] asm("_binary_statusbar_small_bin_gz_ extern const uint8_t statusbar_logo_end[] asm("_binary_statusbar_small_bin_gz_end"); #endif +void initialize_custom_theme_color(void) { + CUSTOM_THEME_COLOR = storage_get_custom_theme_color(); +} + static void make_status_bar(void) { gui_view_node_t* status_parent = NULL; diff --git a/main/gui.h b/main/gui.h index 964cf0a2..4f9da928 100644 --- a/main/gui.h +++ b/main/gui.h @@ -400,6 +400,8 @@ typedef struct { gui_view_node_t* last_activity_next_button; } linked_activities_info_t; +void initialize_custom_theme_color(void); + gui_event_t gui_get_click_event(void); void gui_set_click_event(bool use_wheel_click); diff --git a/main/process/dashboard.c b/main/process/dashboard.c index 353e86c0..f7a265e6 100644 --- a/main/process/dashboard.c +++ b/main/process/dashboard.c @@ -1937,6 +1937,7 @@ static void handle_custom_theme(void) { if (ev_id == BTN_THEME_SAVE) { // Save the current color combination as the custom theme color CUSTOM_THEME_COLOR = (red << 16) | (green << 8) | blue; + storage_set_custom_theme_color(CUSTOM_THEME_COLOR); break; } else if (ev_id == BTN_SETTINGS_CUSTOM_THEME_EXIT) { // Exit the custom theme screen diff --git a/main/storage.c b/main/storage.c index f3a2d50a..e3597704 100644 --- a/main/storage.c +++ b/main/storage.c @@ -38,6 +38,8 @@ static const char* GUI_FLAGS_FIELD = "guiflags"; static const char* BLE_FLAGS_FIELD = "bleflags"; static const char* QR_FLAGS_FIELD = "qrflags"; +static const char* CUSTOM_THEME_COLOR_FIELD = "customtheme"; + // Deprecated/removed keys static const char* CLICK_EVENT_FIELD = "clickevent"; @@ -629,6 +631,19 @@ uint8_t storage_get_gui_flags(void) return read_blob_fixed(DEFAULT_NAMESPACE, GUI_FLAGS_FIELD, &gui_flags, sizeof(gui_flags)) ? gui_flags : 0; } + + +bool storage_set_custom_theme_color(uint16_t color) { + + return store_blob(DEFAULT_NAMESPACE, CUSTOM_THEME_COLOR_FIELD, (const uint8_t*)&color, sizeof(color)); +} + +uint16_t storage_get_custom_theme_color(void) { + uint16_t color = 0; + + return read_blob_fixed(DEFAULT_NAMESPACE, CUSTOM_THEME_COLOR_FIELD, (uint8_t*)&color, sizeof(color)) ? color : 0; +} + bool storage_set_ble_flags(uint8_t flags) { return store_blob(DEFAULT_NAMESPACE, BLE_FLAGS_FIELD, &flags, sizeof(flags)); diff --git a/main/storage.h b/main/storage.h index a58facaf..c7b4c28e 100644 --- a/main/storage.h +++ b/main/storage.h @@ -79,6 +79,9 @@ uint8_t storage_get_brightness(void); bool storage_set_gui_flags(uint8_t color); uint8_t storage_get_gui_flags(void); +bool storage_set_custom_theme_color(uint16_t color); +uint16_t storage_get_custom_theme_color(void); + bool storage_set_ble_flags(uint8_t flags); uint8_t storage_get_ble_flags(void);