Skip to content

Commit 0041341

Browse files
committed
Add filebrowser, rename settings menu files, start of radio install function
1 parent 9bbced3 commit 0041341

13 files changed

Lines changed: 326 additions & 61 deletions

File tree

components/gui/gui_menu.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,12 @@ const char* menu_get_value(menu_t* menu, size_t position) {
234234
return item->value;
235235
}
236236

237+
const char* menu_get_label(menu_t* menu, size_t position) {
238+
menu_item_t* item = menu_find_item(menu, position);
239+
if (item == NULL) return NULL;
240+
return item->label;
241+
}
242+
237243
void menu_set_value(menu_t* menu, size_t position, const char* value) {
238244
menu_item_t* item = menu_find_item(menu, position);
239245
if (item == NULL) {

components/gui/include/gui_menu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void* menu_get_callback_args(menu_t* menu, size_t position);
5555
pax_buf_t* menu_get_icon(menu_t* menu, size_t position);
5656
const char* menu_get_value(menu_t* menu, size_t position);
5757
void menu_set_value(menu_t* menu, size_t position, const char* value);
58+
const char* menu_get_label(menu_t* menu, size_t position);
5859

5960
void menu_render(pax_buf_t* pax_buffer, menu_t* menu, pax_vec2_t position, gui_theme_t* theme, bool partial);
6061
void menu_render_grid(pax_buf_t* pax_buffer, menu_t* menu, pax_vec2_t position, gui_theme_t* theme, bool partial);

main/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ idf_component_register(
1515

1616
# Menus
1717
"menu/home.c"
18-
"menu/settings.c"
18+
"menu/menu_settings.c"
1919
"menu/about.c"
2020
"menu/wifi.c"
2121
"menu/wifi_edit.c"
@@ -37,6 +37,7 @@ idf_component_register(
3737
"menu/menu_repository_client_project.c"
3838
"menu/menu_wifi_info.c"
3939
"menu/menu_power_information.c"
40+
"menu/menu_filebrowser.c"
4041

4142
# Fonts
4243
"chakrapetchmedium.c"

main/menu/home.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
#include "menu/nametag.h"
2121
#include "menu/rftest.h"
2222
#include "menu_repository_client.h"
23+
#include "menu_settings.h"
2324
#include "pax_gfx.h"
2425
#include "pax_matrix.h"
2526
#include "pax_types.h"
26-
#include "settings.h"
2727
#include "usb_device.h"
2828

2929
typedef enum {
@@ -45,7 +45,7 @@ static void execute_action(pax_buf_t* fb, menu_home_action_t action, gui_theme_t
4545
menu_nametag(fb, theme);
4646
break;
4747
case ACTION_SETTINGS:
48-
menu_settings(fb, theme);
48+
menu_settings();
4949
break;
5050
case ACTION_RFTEST:
5151
menu_rftest(fb, theme);
@@ -173,14 +173,11 @@ void menu_home(void) {
173173
}
174174
break;
175175
case BSP_INPUT_NAVIGATION_KEY_MENU:
176-
menu_settings(buffer, theme);
177-
render(buffer, theme, &menu, position, false, true);
178-
break;
179176
case BSP_INPUT_NAVIGATION_KEY_F5:
180177
if (event.args_navigation.modifiers & BSP_INPUT_MODIFIER_FUNCTION) {
181178
display_backlight();
182179
} else {
183-
menu_settings(buffer, theme);
180+
menu_settings();
184181
render(buffer, theme, &menu, position, false, true);
185182
}
186183
break;

main/menu/menu_filebrowser.c

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
#include <dirent.h>
2+
#include <string.h>
3+
#include "bsp/display.h"
4+
#include "bsp/input.h"
5+
#include "common/display.h"
6+
#include "common/theme.h"
7+
#include "gui_menu.h"
8+
#include "gui_style.h"
9+
#include "icons.h"
10+
#include "menu/message_dialog.h"
11+
#include "menu_settings.h"
12+
#include "pax_gfx.h"
13+
#include "pax_matrix.h"
14+
#include "pax_types.h"
15+
16+
static void render(menu_t* menu, pax_vec2_t position, bool partial, bool icons, const char* title) {
17+
pax_buf_t* buffer = display_get_buffer();
18+
gui_theme_t* theme = get_theme();
19+
20+
if (!partial || icons) {
21+
render_base_screen_statusbar(
22+
buffer, theme, !partial, !partial || icons, !partial,
23+
((gui_element_icontext_t[]){{get_icon(ICON_SD), (char*)title}}), 1,
24+
((gui_element_icontext_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), "Back"}}), 2,
25+
((gui_element_icontext_t[]){{NULL, "↑ / ↓ | ⏎ Select"}}), 1);
26+
}
27+
menu_render(buffer, menu, position, theme, partial);
28+
display_blit_buffer(buffer);
29+
}
30+
31+
static size_t populate_menu(const char* path, menu_t* menu, const char* filter[], size_t filter_length) {
32+
DIR* dir = opendir(path);
33+
if (dir == NULL) {
34+
return 0;
35+
}
36+
struct dirent* entry;
37+
size_t count = 0;
38+
while ((entry = readdir(dir)) != NULL) {
39+
if (entry->d_type == DT_DIR) {
40+
menu_insert_item_icon(menu, entry->d_name, NULL, (void*)1, -1, get_icon(ICON_SD));
41+
} else {
42+
bool matches_filter = false;
43+
for (size_t i = 0; i < filter_length; i++) {
44+
if (strlen(entry->d_name) > strlen(filter[i]) &&
45+
strcmp(entry->d_name + strlen(entry->d_name) - strlen(filter[i]), filter[i]) == 0) {
46+
matches_filter = true;
47+
break;
48+
}
49+
}
50+
if (matches_filter || filter_length == 0) {
51+
menu_insert_item_icon(menu, entry->d_name, NULL, (void*)0, -1, get_icon(ICON_INFO));
52+
}
53+
}
54+
}
55+
closedir(dir);
56+
return count;
57+
}
58+
59+
bool menu_filebrowser(const char* in_path, const char* filter[], size_t filter_length, char* out_filename,
60+
size_t filename_size, const char* title) {
61+
QueueHandle_t input_event_queue = NULL;
62+
ESP_ERROR_CHECK(bsp_input_get_queue(&input_event_queue));
63+
64+
char path[260] = {0};
65+
strncpy(path, in_path, sizeof(path) - 1);
66+
67+
while (1) {
68+
menu_t menu = {0};
69+
menu_initialize(&menu);
70+
71+
if (strcmp(path, "/sd") != 0 && strcmp(path, "/int") != 0) {
72+
menu_insert_item_icon(&menu, "..", NULL, (void*)0, -1, get_icon(ICON_SD));
73+
}
74+
populate_menu(path, &menu, filter, filter_length);
75+
76+
pax_buf_t* buffer = display_get_buffer();
77+
gui_theme_t* theme = get_theme();
78+
79+
int header_height = theme->header.height + (theme->header.vertical_margin * 2);
80+
int footer_height = theme->footer.height + (theme->footer.vertical_margin * 2);
81+
82+
pax_vec2_t position = {
83+
.x0 = theme->menu.horizontal_margin + theme->menu.horizontal_padding,
84+
.y0 = header_height + theme->menu.vertical_margin + theme->menu.vertical_padding,
85+
.x1 = pax_buf_get_width(buffer) - theme->menu.horizontal_margin - theme->menu.horizontal_padding,
86+
.y1 =
87+
pax_buf_get_height(buffer) - footer_height - theme->menu.vertical_margin - theme->menu.vertical_padding,
88+
};
89+
90+
render(&menu, position, false, true, title);
91+
bool reload = false;
92+
while (!reload) {
93+
bsp_input_event_t event;
94+
if (xQueueReceive(input_event_queue, &event, pdMS_TO_TICKS(1000)) == pdTRUE) {
95+
switch (event.type) {
96+
case INPUT_EVENT_TYPE_NAVIGATION: {
97+
if (event.args_navigation.state) {
98+
switch (event.args_navigation.key) {
99+
case BSP_INPUT_NAVIGATION_KEY_ESC:
100+
case BSP_INPUT_NAVIGATION_KEY_F1:
101+
case BSP_INPUT_NAVIGATION_KEY_GAMEPAD_B:
102+
menu_free(&menu);
103+
return false;
104+
case BSP_INPUT_NAVIGATION_KEY_UP:
105+
menu_navigate_previous(&menu);
106+
render(&menu, position, true, false, title);
107+
break;
108+
case BSP_INPUT_NAVIGATION_KEY_DOWN:
109+
menu_navigate_next(&menu);
110+
render(&menu, position, true, false, title);
111+
break;
112+
case BSP_INPUT_NAVIGATION_KEY_RETURN:
113+
case BSP_INPUT_NAVIGATION_KEY_GAMEPAD_A:
114+
case BSP_INPUT_NAVIGATION_KEY_JOYSTICK_PRESS: {
115+
void* arg = menu_get_callback_args(&menu, menu_get_position(&menu));
116+
const char* label = menu_get_label(&menu, menu_get_position(&menu));
117+
if (strncmp(label, "..", 2) == 0) {
118+
// Go up one directory
119+
char* last_slash = strrchr(path, '/');
120+
if (last_slash != NULL) {
121+
*last_slash = '\0';
122+
}
123+
reload = true;
124+
} else {
125+
bool is_dir = (bool)arg;
126+
if (is_dir) {
127+
// Navigate into directory
128+
if (strlen(path) + strlen(label) + 2 < sizeof(path)) {
129+
strcat(path, "/");
130+
strcat(path, label);
131+
reload = true;
132+
} else {
133+
message_dialog(get_icon(ICON_ERROR), "Error",
134+
"Path too long, can not navigate into directory",
135+
"Go back");
136+
render(&menu, position, false, true, title);
137+
}
138+
} else {
139+
snprintf(out_filename, filename_size, "%s/%s", path, label);
140+
menu_free(&menu);
141+
return true; // File selected
142+
}
143+
}
144+
break;
145+
}
146+
default:
147+
break;
148+
}
149+
}
150+
break;
151+
}
152+
default:
153+
break;
154+
}
155+
} else {
156+
render(&menu, position, true, true, title);
157+
}
158+
}
159+
160+
menu_free(&menu);
161+
}
162+
163+
return false;
164+
}

main/menu/menu_filebrowser.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 <stdbool.h>
4+
#include <stddef.h>
5+
6+
bool menu_filebrowser(const char* path, const char* filter[], size_t filter_length, char* out_filename,
7+
size_t filename_size, const char* title);
Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
#include "settings.h"
1+
#include "menu_settings.h"
22
#include "bsp/display.h"
33
#include "bsp/input.h"
4-
#include "chakrapetchmedium.h"
54
#include "common/display.h"
5+
#include "common/theme.h"
6+
#include "firmware_update.h"
67
#include "freertos/idf_additions.h"
7-
#include "gui_element_footer.h"
88
#include "gui_menu.h"
99
#include "gui_style.h"
1010
#include "icons.h"
1111
#include "menu/about.h"
1212
#include "menu/menu_power_information.h"
1313
#include "menu/message_dialog.h"
1414
#include "menu/wifi.h"
15+
#include "menu_device_information.h"
16+
#include "menu_filebrowser.h"
1517
#include "pax_gfx.h"
1618
#include "pax_matrix.h"
1719
#include "pax_types.h"
18-
// #include "shapes/pax_misc.h"
19-
#include "firmware_update.h"
20-
#include "menu_device_information.h"
2120
#include "radio_update.h"
2221
#include "settings_clock.h"
2322

@@ -33,6 +32,15 @@ typedef enum {
3332
ACTION_POWER_INFORMATION,
3433
} menu_home_action_t;
3534

35+
static void radio_update_v2(void) {
36+
char filename[260] = "";
37+
bool result =
38+
menu_filebrowser("/sd", (const char*[]){"trf"}, 1, filename, sizeof(filename), "Select radio firmware");
39+
if (result) {
40+
radio_install(filename);
41+
}
42+
}
43+
3644
static void execute_action(pax_buf_t* fb, menu_home_action_t action, gui_theme_t* theme) {
3745
switch (action) {
3846
case ACTION_WIFI:
@@ -47,11 +55,12 @@ static void execute_action(pax_buf_t* fb, menu_home_action_t action, gui_theme_t
4755
case ACTION_DEVICE_INFO:
4856
menu_device_information(fb, theme);
4957
break;
50-
case ACTION_ABOUT:
58+
case ACTION_ABOUT: {
5159
menu_about(fb, theme);
5260
break;
61+
}
5362
case ACTION_RADIO_UPDATE:
54-
radio_update(fb, theme, "/sd/firmware/radio/esp-hosted.zz", true, 1093760);
63+
radio_update_v2();
5564
break;
5665
case ACTION_POWER_INFORMATION:
5766
menu_power_information();
@@ -61,7 +70,10 @@ static void execute_action(pax_buf_t* fb, menu_home_action_t action, gui_theme_t
6170
}
6271
}
6372

64-
static void render(pax_buf_t* buffer, gui_theme_t* theme, menu_t* menu, pax_vec2_t position, bool partial, bool icons) {
73+
static void render(menu_t* menu, pax_vec2_t position, bool partial, bool icons) {
74+
pax_buf_t* buffer = display_get_buffer();
75+
gui_theme_t* theme = get_theme();
76+
6577
if (!partial || icons) {
6678
render_base_screen_statusbar(
6779
buffer, theme, !partial, !partial || icons, !partial,
@@ -73,7 +85,7 @@ static void render(pax_buf_t* buffer, gui_theme_t* theme, menu_t* menu, pax_vec2
7385
display_blit_buffer(buffer);
7486
}
7587

76-
void menu_settings(pax_buf_t* buffer, gui_theme_t* theme) {
88+
void menu_settings(void) {
7789
QueueHandle_t input_event_queue = NULL;
7890
ESP_ERROR_CHECK(bsp_input_get_queue(&input_event_queue));
7991

@@ -87,11 +99,14 @@ void menu_settings(pax_buf_t* buffer, gui_theme_t* theme) {
8799
menu_insert_item_icon(&menu, "Power information", NULL, (void*)ACTION_POWER_INFORMATION, -1,
88100
get_icon(ICON_BATTERY_UNKNOWN));
89101
menu_insert_item_icon(&menu, "About", NULL, (void*)ACTION_ABOUT, -1, get_icon(ICON_INFO));
90-
/*#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
91-
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)
92-
menu_insert_item_icon(&menu, "Update radio from SD card", NULL, (void*)ACTION_RADIO_UPDATE, -1,
93-
get_icon(ICON_RELEASE_ALERT));
94-
#endif*/
102+
#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
103+
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)
104+
menu_insert_item_icon(&menu, "Install radio firmware from SD card", NULL, (void*)ACTION_RADIO_UPDATE, -1,
105+
get_icon(ICON_RELEASE_ALERT));
106+
#endif
107+
108+
pax_buf_t* buffer = display_get_buffer();
109+
gui_theme_t* theme = get_theme();
95110

96111
int header_height = theme->header.height + (theme->header.vertical_margin * 2);
97112
int footer_height = theme->footer.height + (theme->footer.vertical_margin * 2);
@@ -103,7 +118,7 @@ void menu_settings(pax_buf_t* buffer, gui_theme_t* theme) {
103118
.y1 = pax_buf_get_height(buffer) - footer_height - theme->menu.vertical_margin - theme->menu.vertical_padding,
104119
};
105120

106-
render(buffer, theme, &menu, position, false, true);
121+
render(&menu, position, false, true);
107122
while (1) {
108123
bsp_input_event_t event;
109124
if (xQueueReceive(input_event_queue, &event, pdMS_TO_TICKS(1000)) == pdTRUE) {
@@ -118,18 +133,18 @@ void menu_settings(pax_buf_t* buffer, gui_theme_t* theme) {
118133
return;
119134
case BSP_INPUT_NAVIGATION_KEY_UP:
120135
menu_navigate_previous(&menu);
121-
render(buffer, theme, &menu, position, true, false);
136+
render(&menu, position, true, false);
122137
break;
123138
case BSP_INPUT_NAVIGATION_KEY_DOWN:
124139
menu_navigate_next(&menu);
125-
render(buffer, theme, &menu, position, true, false);
140+
render(&menu, position, true, false);
126141
break;
127142
case BSP_INPUT_NAVIGATION_KEY_RETURN:
128143
case BSP_INPUT_NAVIGATION_KEY_GAMEPAD_A:
129144
case BSP_INPUT_NAVIGATION_KEY_JOYSTICK_PRESS: {
130145
void* arg = menu_get_callback_args(&menu, menu_get_position(&menu));
131146
execute_action(buffer, (menu_home_action_t)arg, theme);
132-
render(buffer, theme, &menu, position, false, true);
147+
render(&menu, position, false, true);
133148
break;
134149
}
135150
default:
@@ -142,7 +157,7 @@ void menu_settings(pax_buf_t* buffer, gui_theme_t* theme) {
142157
break;
143158
}
144159
} else {
145-
render(buffer, theme, &menu, position, true, true);
160+
render(&menu, position, true, true);
146161
}
147162
}
148163
}

main/menu/menu_settings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
void menu_settings(void);

0 commit comments

Comments
 (0)