Skip to content

Commit 13afd95

Browse files
committed
message_dialog: now multiple options; app_inspect menu and app deletion
1 parent ce03dec commit 13afd95

11 files changed

Lines changed: 226 additions & 44 deletions

File tree

main/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ idf_component_register(
1717
"menu/wifi_edit.c"
1818
"menu/wifi_scan.c"
1919
"menu/apps.c"
20+
"menu/app_inspect.c"
2021
"menu/firmware_update.c"
2122
"menu/message_dialog.c"
2223
"menu/device_information.c"

main/menu/app_inspect.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
2+
#include "app_inspect.h"
3+
#include <string.h>
4+
#include "appfs.h"
5+
#include "bsp/input.h"
6+
#include "common/display.h"
7+
#include "gui_footer.h"
8+
#include "gui_style.h"
9+
#include "icons.h"
10+
#include "menu/apps.h"
11+
#include "menu/message_dialog.h"
12+
#include "pax_gfx.h"
13+
#include "pax_matrix.h"
14+
#include "pax_text.h"
15+
#include "pax_types.h"
16+
17+
#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
18+
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)
19+
#define FOOTER_LEFT \
20+
((gui_header_field_t[]){{get_icon(ICON_ESC), "/"}, \
21+
{get_icon(ICON_F1), "Back"}, \
22+
{get_icon(ICON_F2), "Start"}, \
23+
{get_icon(ICON_F5), "Delete App"}}), \
24+
4
25+
#define FOOTER_RIGHT NULL, 0
26+
#define TEXT_FONT pax_font_sky_mono
27+
#define TEXT_SIZE 18
28+
#elif defined(CONFIG_BSP_TARGET_MCH2022)
29+
#define FOOTER_LEFT ((gui_header_field_t[]){{NULL, "🅱 Back"}}), 1
30+
#define FOOTER_RIGHT NULL, 0
31+
#define TEXT_FONT pax_font_sky_mono
32+
#define TEXT_SIZE 9
33+
#else
34+
#define FOOTER_LEFT NULL, 0
35+
#define FOOTER_RIGHT NULL, 0
36+
#define TEXT_FONT pax_font_sky_mono
37+
#define TEXT_SIZE 9
38+
#endif
39+
40+
// static void delete_app(app_t*app){
41+
// appfsDeleteFile(app->slug);
42+
//
43+
// }
44+
45+
static void render(pax_buf_t* buffer, gui_theme_t* theme, pax_vec2_t position, bool partial, bool icons, app_t* app) {
46+
47+
char text_buffer[256];
48+
int line = 0;
49+
50+
if (!partial || icons) {
51+
snprintf(text_buffer, sizeof(text_buffer), "App Info: %s", app->name);
52+
render_base_screen_statusbar(buffer, theme, !partial, !partial || icons, !partial,
53+
((gui_header_field_t[]){{get_icon(ICON_DEVICE_INFO), text_buffer}}), 1,
54+
FOOTER_LEFT, FOOTER_RIGHT);
55+
}
56+
57+
if (!partial) {
58+
59+
if (app->name) {
60+
snprintf(text_buffer, sizeof(text_buffer), "Name: %s", app->name);
61+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
62+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
63+
}
64+
65+
if (app->description) {
66+
snprintf(text_buffer, sizeof(text_buffer), "Description: %s", app->description);
67+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
68+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
69+
}
70+
71+
if (app->author) {
72+
snprintf(text_buffer, sizeof(text_buffer), "Author: %s", app->author);
73+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
74+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
75+
}
76+
77+
if (app->version) {
78+
snprintf(text_buffer, sizeof(text_buffer), "Version: %ld", app->version);
79+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
80+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
81+
}
82+
83+
if (app->slug) {
84+
snprintf(text_buffer, sizeof(text_buffer), "Slug: %s", app->slug);
85+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
86+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
87+
}
88+
}
89+
90+
display_blit_buffer(buffer);
91+
}
92+
93+
bool menu_app_inspect(pax_buf_t* buffer, gui_theme_t* theme, app_t* app) {
94+
QueueHandle_t input_event_queue = NULL;
95+
ESP_ERROR_CHECK(bsp_input_get_queue(&input_event_queue));
96+
97+
int header_height = theme->header.height + (theme->header.vertical_margin * 2);
98+
int footer_height = theme->footer.height + (theme->footer.vertical_margin * 2);
99+
100+
pax_vec2_t position = {
101+
.x0 = theme->menu.horizontal_margin + theme->menu.horizontal_padding,
102+
.y0 = header_height + theme->menu.vertical_margin + theme->menu.vertical_padding,
103+
.x1 = pax_buf_get_width(buffer) - theme->menu.horizontal_margin - theme->menu.horizontal_padding,
104+
.y1 = pax_buf_get_height(buffer) - footer_height - theme->menu.vertical_margin - theme->menu.vertical_padding,
105+
};
106+
107+
render(buffer, theme, position, false, false, app);
108+
109+
while (1) {
110+
bsp_input_event_t event;
111+
if (xQueueReceive(input_event_queue, &event, pdMS_TO_TICKS(1000)) == pdTRUE) {
112+
switch (event.type) {
113+
case INPUT_EVENT_TYPE_NAVIGATION: {
114+
if (event.args_navigation.state) {
115+
switch (event.args_navigation.key) {
116+
case BSP_INPUT_NAVIGATION_KEY_ESC:
117+
case BSP_INPUT_NAVIGATION_KEY_F1:
118+
case BSP_INPUT_NAVIGATION_KEY_GAMEPAD_B:
119+
return false;
120+
case BSP_INPUT_NAVIGATION_KEY_F2:
121+
execute_app(buffer, theme, position, app);
122+
render(buffer, theme, position, false, false, app);
123+
break;
124+
case BSP_INPUT_NAVIGATION_KEY_F5:
125+
bsp_input_navigation_key_t dia_result =
126+
message_dialog(buffer, theme, "Delete App", "Do you really want to delete the app?",
127+
MESSAGE_DIALOG_FOOTER_YES_NO);
128+
if (dia_result == BSP_INPUT_NAVIGATION_KEY_F4) {
129+
appfsDeleteFile(app->slug);
130+
char text_buffer[256];
131+
snprintf(text_buffer, sizeof(text_buffer), "/sd/apps/%s", app->slug);
132+
remove(text_buffer);
133+
snprintf(text_buffer, sizeof(text_buffer), "/int/apps/%s", app->slug);
134+
remove(text_buffer);
135+
return true;
136+
}
137+
render(buffer, theme, position, false, false, app);
138+
break;
139+
default:
140+
break;
141+
}
142+
}
143+
break;
144+
}
145+
default:
146+
break;
147+
}
148+
} else {
149+
render(buffer, theme, position, false, false, app);
150+
}
151+
}
152+
}

main/menu/app_inspect.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include "app_metadata_parser.h"
4+
#include "gui_style.h"
5+
#include "pax_types.h"
6+
7+
bool menu_app_inspect(pax_buf_t* buffer, gui_theme_t* theme, app_t* app);

main/menu/apps.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <stddef.h>
33
#include <stdio.h>
44
#include <string.h>
5+
#include "app_inspect.h"
56
#include "app_metadata_parser.h"
67
#include "appfs.h"
78
#include "bsp/input.h"
@@ -11,6 +12,7 @@
1112
#include "gui_menu.h"
1213
#include "gui_style.h"
1314
#include "icons.h"
15+
#include "menu/app_inspect.h"
1416
#include "menu/message_dialog.h"
1517
#include "pax_gfx.h"
1618
#include "pax_matrix.h"
@@ -30,10 +32,10 @@ static void populate_menu(menu_t* menu, app_t** apps, size_t app_count) {
3032

3133
extern bool wifi_stack_get_task_done(void);
3234

33-
static void execute_app(pax_buf_t* buffer, gui_theme_t* theme, pax_vec2_t position, app_t* app) {
35+
void execute_app(pax_buf_t* buffer, gui_theme_t* theme, pax_vec2_t position, app_t* app) {
3436

3537
if (app == NULL) {
36-
message_dialog(buffer, theme, "Error", "No app selected", "OK");
38+
message_dialog(buffer, theme, "Error", "No app selected", MESSAGE_DIALOG_FOOTER_OK);
3739
return;
3840
}
3941

@@ -54,13 +56,14 @@ static void execute_app(pax_buf_t* buffer, gui_theme_t* theme, pax_vec2_t positi
5456
usb_mode_set(USB_DEBUG);
5557
esp_restart();
5658
} else {
57-
message_dialog(buffer, theme, "Error", "App not found", "OK");
59+
message_dialog(buffer, theme, "Error", "App not found", MESSAGE_DIALOG_FOOTER_OK);
5860
}
5961
}
6062

6163
#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
6264
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)
63-
#define FOOTER_LEFT ((gui_header_field_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), "Back"}}), 2
65+
#define FOOTER_LEFT \
66+
((gui_header_field_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), "Back"}, {get_icon(ICON_F2), "Info"}}), 3
6467
#define FOOTER_RIGHT ((gui_header_field_t[]){{NULL, "↑ / ↓ Navigate ⏎ Start app"}}), 1
6568
#elif defined(CONFIG_BSP_TARGET_MCH2022)
6669
#define FOOTER_LEFT NULL, 0
@@ -115,6 +118,19 @@ void menu_apps(pax_buf_t* buffer, gui_theme_t* theme) {
115118
menu_free(&menu);
116119
free_list_of_apps(apps, MAX_NUM_APPS);
117120
return;
121+
case BSP_INPUT_NAVIGATION_KEY_F2:
122+
void* arg = menu_get_callback_args(&menu, menu_get_position(&menu));
123+
app_t* app = (app_t*)arg;
124+
if (menu_app_inspect(buffer, theme, app)) {
125+
app = NULL;
126+
menu_free(&menu);
127+
free_list_of_apps(apps, MAX_NUM_APPS);
128+
number_of_apps = create_list_of_apps(apps, MAX_NUM_APPS);
129+
menu_initialize(&menu);
130+
populate_menu(&menu, apps, number_of_apps);
131+
}
132+
render(buffer, theme, &menu, position, false, true);
133+
break;
118134
case BSP_INPUT_NAVIGATION_KEY_UP:
119135
menu_navigate_previous(&menu);
120136
render(buffer, theme, &menu, position, true, false);

main/menu/apps.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#pragma once
22

3+
#include "app_metadata_parser.h"
34
#include "gui_style.h"
45
#include "pax_types.h"
56

7+
void execute_app(pax_buf_t* buffer, gui_theme_t* theme, pax_vec2_t position, app_t* app);
8+
69
void menu_apps(pax_buf_t* buffer, gui_theme_t* theme);

main/menu/message_dialog.c

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -183,23 +183,13 @@ void render_base_screen_statusbar(pax_buf_t* buffer, gui_theme_t* theme, bool ba
183183
header_right_count, footer_left, footer_left_count, footer_right, footer_right_count);
184184
}
185185

186-
#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
187-
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)
188-
#define FOOTER_LEFT ((gui_header_field_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), (char*)action_text}}), 2
189-
#define FOOTER_RIGHT NULL, 0
190-
#elif defined(CONFIG_BSP_TARGET_MCH2022)
191-
#define FOOTER_LEFT ((gui_header_field_t[]){{NULL, "🅱"}, {NULL, (char*)action_text}}), 2
192186
#define FOOTER_RIGHT NULL, 0
193-
#else
194-
#define FOOTER_LEFT NULL, 0
195-
#define FOOTER_RIGHT NULL, 0
196-
#endif
197187

198188
static void render(pax_buf_t* buffer, gui_theme_t* theme, pax_vec2_t position, const char* title, const char* message,
199-
const char* action_text, bool partial, bool icons) {
189+
gui_header_field_t* headers, int header_count, bool partial, bool icons) {
200190
if (!partial || icons) {
201191
render_base_screen_statusbar(buffer, theme, !partial, !partial || icons, !partial,
202-
((gui_header_field_t[]){{get_icon(ICON_ERROR), title}}), 1, FOOTER_LEFT,
192+
((gui_header_field_t[]){{get_icon(ICON_ERROR), title}}), 1, headers, header_count,
203193
FOOTER_RIGHT);
204194
}
205195
if (!partial) {
@@ -209,8 +199,8 @@ static void render(pax_buf_t* buffer, gui_theme_t* theme, pax_vec2_t position, c
209199
display_blit_buffer(buffer);
210200
}
211201

212-
void message_dialog(pax_buf_t* buffer, gui_theme_t* theme, const char* title, const char* message,
213-
const char* action_text) {
202+
bsp_input_navigation_key_t message_dialog(pax_buf_t* buffer, gui_theme_t* theme, const char* title, const char* message,
203+
gui_header_field_t* headers, int header_count) {
214204
QueueHandle_t input_event_queue = NULL;
215205
ESP_ERROR_CHECK(bsp_input_get_queue(&input_event_queue));
216206

@@ -224,29 +214,20 @@ void message_dialog(pax_buf_t* buffer, gui_theme_t* theme, const char* title, co
224214
.y1 = pax_buf_get_height(buffer) - footer_height - theme->menu.vertical_margin - theme->menu.vertical_padding,
225215
};
226216

227-
render(buffer, theme, position, title, message, action_text, false, true);
217+
render(buffer, theme, position, title, message, headers, header_count, false, true);
228218
while (1) {
229219
bsp_input_event_t event;
230220
if (xQueueReceive(input_event_queue, &event, pdMS_TO_TICKS(1000)) == pdTRUE) {
231221
switch (event.type) {
232222
case INPUT_EVENT_TYPE_NAVIGATION: {
233-
if (event.args_navigation.state) {
234-
switch (event.args_navigation.key) {
235-
case BSP_INPUT_NAVIGATION_KEY_ESC:
236-
case BSP_INPUT_NAVIGATION_KEY_F1:
237-
case BSP_INPUT_NAVIGATION_KEY_GAMEPAD_B:
238-
return;
239-
default:
240-
break;
241-
}
242-
}
223+
if (event.args_navigation.state) return event.args_navigation.key;
243224
break;
244225
}
245226
default:
246227
break;
247228
}
248229
} else {
249-
render(buffer, theme, position, title, message, action_text, true, true);
230+
render(buffer, theme, position, title, message, headers, header_count, true, true);
250231
}
251232
}
252233
}

main/menu/message_dialog.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#pragma once
22

3+
#include "bsp/input.h"
34
#include "gui_footer.h"
45
#include "gui_style.h"
56
#include "pax_types.h"
6-
77
void render_base_screen(pax_buf_t* buffer, gui_theme_t* theme, bool background, bool header, bool footer,
88
gui_header_field_t* header_left, size_t header_left_count, gui_header_field_t* header_right,
99
size_t header_right_count, gui_header_field_t* footer_left, size_t footer_left_count,
@@ -13,5 +13,23 @@ void render_base_screen_statusbar(pax_buf_t* buffer, gui_theme_t* theme, bool ba
1313
gui_header_field_t* footer_left, size_t footer_left_count,
1414
gui_header_field_t* footer_right, size_t footer_right_count);
1515

16-
void message_dialog(pax_buf_t* buffer, gui_theme_t* theme, const char* title, const char* message,
17-
const char* action_text);
16+
bsp_input_navigation_key_t message_dialog(pax_buf_t* buffer, gui_theme_t* theme, const char* title, const char* message,
17+
gui_header_field_t* headers, int header_count);
18+
19+
#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
20+
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)
21+
#define MESSAGE_DIALOG_FOOTER_OK ((gui_header_field_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), "OK"}}), 2
22+
#define MESSAGE_DIALOG_FOOTER_GOBACK \
23+
((gui_header_field_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), "Go back"}}), 2
24+
#define MESSAGE_DIALOG_FOOTER_YES_NO \
25+
((gui_header_field_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), "No"}, {get_icon(ICON_F4), "Yes"}}), 3
26+
27+
#elif defined(CONFIG_BSP_TARGET_MCH2022)
28+
#define MESSAGE_DIALOG_FOOTER_OK ((gui_header_field_t[]){{NULL, "🅱"}, {NULL, "Ok"}}), 2
29+
#define MESSAGE_DIALOG_FOOTER_YES_NO ((gui_header_field_t[]){{NULL, "🅱"}, {NULL, "Ok"}}), 2
30+
#define MESSAGE_DIALOG_FOOTER_YES_GOBACK ((gui_header_field_t[]){{NULL, "🅱"}, {NULL, "Ok"}}), 2
31+
#else
32+
#define MESSAGE_DIALOG_FOOTER_OK NULL, 0
33+
#define MESSAGE_DIALOG_FOOTER_GOBACK NULL, 0
34+
#define MESSAGE_DIALOG_FOOTER_YES_NO NULL, 0
35+
#endif

main/menu/nametag.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "nametag.h"
22
#include "bsp/input.h"
3+
#include "bsp/led.h"
34
#include "common/display.h"
45
#include "esp_err.h"
56
#include "esp_log.h"
@@ -13,7 +14,6 @@
1314
#include "pax_matrix.h"
1415
#include "pax_text.h"
1516
#include "pax_types.h"
16-
#include "bsp/led.h"
1717

1818
static const char* TAG = "nametag";
1919

@@ -66,9 +66,9 @@ static void render_nametag(pax_buf_t* buffer) {
6666
uint8_t led_buffer[6 * 3] = {0};
6767

6868
static void set_led_color(uint8_t led, uint32_t color) {
69-
led_buffer[led * 3 + 0] = (color >> 8) & 0xFF; // G
70-
led_buffer[led * 3 + 1] = (color >> 16) & 0xFF; // R
71-
led_buffer[led * 3 + 2] = (color >> 0) & 0xFF; // B
69+
led_buffer[led * 3 + 0] = (color >> 8) & 0xFF; // G
70+
led_buffer[led * 3 + 1] = (color >> 16) & 0xFF; // R
71+
led_buffer[led * 3 + 2] = (color >> 0) & 0xFF; // B
7272
}
7373

7474
void menu_nametag(pax_buf_t* buffer, gui_theme_t* theme) {

main/menu/wifi.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ static void render(pax_buf_t* buffer, gui_theme_t* theme, menu_t* menu, pax_vec2
5959
static void add_manually(pax_buf_t* buffer, gui_theme_t* theme) {
6060
int index = wifi_settings_find_empty_slot();
6161
if (index == -1) {
62-
message_dialog(buffer, theme, "Error", "No empty slot, can not add another network", "Go back");
62+
message_dialog(buffer, theme, "Error", "No empty slot, can not add another network",
63+
MESSAGE_DIALOG_FOOTER_GOBACK);
6364
}
6465
menu_wifi_edit(buffer, theme, index, true, "", 0);
6566
}
@@ -143,4 +144,4 @@ static bool _menu_wifi(pax_buf_t* buffer, gui_theme_t* theme) {
143144

144145
void menu_wifi(pax_buf_t* buffer, gui_theme_t* theme) {
145146
while (_menu_wifi(buffer, theme));
146-
}
147+
}

0 commit comments

Comments
 (0)