Make select prompt scroll if too many options

Also a little cleanup to the file browse one for consistency
This commit is contained in:
Pk11 2022-10-14 21:59:06 -05:00 committed by d0k3
parent c9d792cb27
commit 9416ec5ac0
2 changed files with 62 additions and 27 deletions

View File

@ -839,10 +839,11 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
} }
#endif #endif
u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { u32 ShowSelectPrompt(int n, const char** options, const char *format, ...) {
u32 str_width, str_height; u32 str_width, str_height;
u32 x, y, yopt; u32 x, y, yopt;
u32 sel = 0; int sel = 0, scroll = 0;
int n_show = min(n, 10);
char str[STRBUF_SIZE]; char str[STRBUF_SIZE];
va_list va; va_list va;
@ -854,30 +855,64 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) {
// else if (n == 1) return ShowPrompt(true, "%s\n%s?", str, options[0]) ? 1 : 0; // else if (n == 1) return ShowPrompt(true, "%s\n%s?", str, options[0]) ? 1 : 0;
str_width = GetDrawStringWidth(str); str_width = GetDrawStringWidth(str);
str_height = GetDrawStringHeight(str) + (n * (line_height + 2)) + (3 * line_height); str_height = GetDrawStringHeight(str) + (n_show * (line_height + 2)) + (3 * line_height);
if (str_width < 24 * font_width) str_width = 24 * font_width; if (str_width < 24 * font_width) str_width = 24 * font_width;
for (u32 i = 0; i < n; i++) if (str_width < GetDrawStringWidth(options[i])) for (int i = 0; i < n; i++) if (str_width < GetDrawStringWidth(options[i]) + (3 * font_width))
str_width = GetDrawStringWidth(options[i]); str_width = GetDrawStringWidth(options[i]) + (3 * font_width);
x = (str_width >= SCREEN_WIDTH_MAIN) ? 0 : (SCREEN_WIDTH_MAIN - str_width) / 2; x = (str_width >= SCREEN_WIDTH_MAIN) ? 0 : (SCREEN_WIDTH_MAIN - str_width) / 2;
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2; y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2;
yopt = y + GetDrawStringHeight(str) + 8; yopt = y + GetDrawStringHeight(str) + 8;
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, false, COLOR_STD_BG);
DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str);
DrawStringF(MAIN_SCREEN, x, yopt + (n*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "(<A> select, <B> cancel)"); DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "(<A> select, <B> cancel)");
while (true) { while (true) {
for (u32 i = 0; i < n; i++) { for (int i = scroll; i < scroll+n_show; i++) {
DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*i), (sel == i) ? COLOR_STD_FONT : COLOR_LIGHTGREY, COLOR_STD_BG, "%2.2s %s", DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*(i-scroll)), (sel == i) ? COLOR_STD_FONT : COLOR_LIGHTGREY, COLOR_STD_BG, "%2.2s %s",
(sel == i) ? "->" : "", options[i]); (sel == i) ? "->" : "", options[i]);
} }
// show [n more]
if (n - n_show - scroll > 0) {
char more_str[UTF_BUFFER_BYTESIZE(str_width / font_width)], temp_str[64];
snprintf(temp_str, 64, " [%d more]", (n - (n_show-1) - scroll));
ResizeString(more_str, temp_str, str_width / font_width, 8, false);
DrawString(MAIN_SCREEN, more_str, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG);
}
// show scroll bar
u32 bar_x = x + str_width + 2;
const u32 flist_height = (n_show * (line_height + 2));
const u32 bar_width = 2;
if (n > n_show) { // draw position bar at the right
const u32 bar_height_min = 32;
u32 bar_height = (n_show * flist_height) / n;
if (bar_height < bar_height_min) bar_height = bar_height_min;
const u32 bar_y = ((u64) scroll * (flist_height - bar_height)) / (n - n_show) + yopt;
DrawRectangle(MAIN_SCREEN, bar_x, bar_y, bar_width, bar_height, COLOR_SIDE_BAR);
}
u32 pad_state = InputWait(0); u32 pad_state = InputWait(0);
if (pad_state & BUTTON_DOWN) sel = (sel+1) % n; if (pad_state & BUTTON_DOWN) sel = (sel+1) % n;
else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n; else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n;
else if (pad_state & BUTTON_RIGHT) sel += n_show;
else if (pad_state & BUTTON_LEFT) sel -= n_show;
else if (pad_state & BUTTON_A) break; else if (pad_state & BUTTON_A) break;
else if (pad_state & BUTTON_B) { else if (pad_state & BUTTON_B) {
sel = n; sel = n;
break; break;
} }
if (sel < 0) sel = 0;
else if (sel >= n) sel = n-1;
int prev_scroll = scroll;
if (sel < scroll) scroll = sel;
else if (sel == n-1 && sel >= (scroll + n_show - 1)) scroll = sel - n_show + 1;
else if (sel >= (scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1;
if (scroll != prev_scroll) {
DrawRectangle(MAIN_SCREEN, x + font_width * 3, yopt, str_width + 4, (n_show * (line_height + 2)), COLOR_STD_BG);
}
} }
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, false, COLOR_STD_BG);
@ -885,12 +920,12 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) {
return (sel >= n) ? 0 : sel + 1; return (sel >= n) ? 0 : sel + 1;
} }
u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const char *format, ...) { u32 ShowFileScrollPrompt(int n, const DirEntry** options, bool hide_ext, const char *format, ...) {
u32 str_height, fname_len; u32 str_height, fname_len;
u32 x, y, yopt; u32 x, y, yopt;
const u32 item_width = SCREEN_WIDTH(MAIN_SCREEN) - 40; const u32 item_width = SCREEN_WIDTH(MAIN_SCREEN) - 40;
int sel = 0, scroll = 0; int sel = 0, scroll = 0;
u32 n_show = min(n, 10); int n_show = min(n, 10);
char str[STRBUF_SIZE]; char str[STRBUF_SIZE];
va_list va; va_list va;
@ -911,7 +946,7 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c
DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str);
DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "(<A> select, <B> cancel)"); DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "(<A> select, <B> cancel)");
while (true) { while (true) {
for (u32 i = scroll; i < scroll+n_show; i++) { for (int i = scroll; i < scroll+n_show; i++) {
char bytestr[16]; char bytestr[16];
FormatBytes(bytestr, options[i]->size); FormatBytes(bytestr, options[i]->size);
@ -925,19 +960,19 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c
ResizeString(content_str, temp_str, fname_len, 8, false); ResizeString(content_str, temp_str, fname_len, 8, false);
DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*(i-scroll)), DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*(i-scroll)),
(sel == (int)i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%2.2s %s", (sel == i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%2.2s %s",
(sel == (int)i) ? "->" : "", content_str); (sel == i) ? "->" : "", content_str);
DrawStringF(MAIN_SCREEN, x + item_width - font_width * 11, yopt + ((line_height+2)*(i-scroll)), DrawStringF(MAIN_SCREEN, x + item_width - font_width * 11, yopt + ((line_height+2)*(i-scroll)),
(sel == (int)i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%10.10s", (sel == i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%10.10s",
(options[i]->type == T_DIR) ? "(dir)" : (options[i]->type == T_DOTDOT) ? "(..)" : bytestr); (options[i]->type == T_DIR) ? "(dir)" : (options[i]->type == T_DOTDOT) ? "(..)" : bytestr);
} }
// show [n more] // show [n more]
if (n - n_show - scroll) { if (n - n_show - scroll > 0) {
char more_str[64 + 1]; char more_str[UTF_BUFFER_BYTESIZE(item_width / font_width)], temp_str[64];
snprintf(more_str, 64, " [%d more]", (int)(n - (n_show-1) - scroll)); snprintf(temp_str, 64, " [%d more]", (n - (n_show-1) - scroll));
DrawStringF(MAIN_SCREEN, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG, ResizeString(more_str, temp_str, item_width / font_width, 8, false);
"%-*s", (int) (item_width / font_width), more_str); DrawString(MAIN_SCREEN, more_str, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG);
} }
// show scroll bar // show scroll bar
u32 bar_x = x + item_width + 2; u32 bar_x = x + item_width + 2;
@ -955,8 +990,8 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c
} else DrawRectangle(MAIN_SCREEN, bar_x, yopt, bar_width, flist_height, COLOR_STD_BG); } else DrawRectangle(MAIN_SCREEN, bar_x, yopt, bar_width, flist_height, COLOR_STD_BG);
u32 pad_state = InputWait(0); u32 pad_state = InputWait(0);
if (pad_state & BUTTON_DOWN) sel++; if (pad_state & BUTTON_DOWN) sel = (sel+1) % n;
else if (pad_state & BUTTON_UP) sel--; else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n;
else if (pad_state & BUTTON_RIGHT) sel += n_show; else if (pad_state & BUTTON_RIGHT) sel += n_show;
else if (pad_state & BUTTON_LEFT) sel -= n_show; else if (pad_state & BUTTON_LEFT) sel -= n_show;
else if (pad_state & BUTTON_A) break; else if (pad_state & BUTTON_A) break;
@ -965,15 +1000,15 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c
break; break;
} }
if (sel < 0) sel = 0; if (sel < 0) sel = 0;
else if (sel >= (int)n) sel = n-1; else if (sel >= n) sel = n-1;
if (sel < scroll) scroll = sel; if (sel < scroll) scroll = sel;
else if (sel == (int) n-1 && sel >= (int)(scroll + n_show - 1)) scroll = sel - n_show + 1; else if (sel == n-1 && sel >= (scroll + n_show - 1)) scroll = sel - n_show + 1;
else if (sel >= (int)(scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1; else if (sel >= (scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1;
} }
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, false, COLOR_STD_BG);
return (sel >= (int)n) ? 0 : sel + 1; return (sel >= n) ? 0 : sel + 1;
} }
u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...) { u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...) {

View File

@ -88,8 +88,8 @@ void PRINTF_ARGS(2) ShowStringF(u16* screen, const char *format, ...);
void PRINTF_ARGS(4) ShowIconString(u16* icon, int w, int h, const char *format, ...); void PRINTF_ARGS(4) ShowIconString(u16* icon, int w, int h, const char *format, ...);
void PRINTF_ARGS(5) ShowIconStringF(u16* screen, u16* icon, int w, int h, const char *format, ...); void PRINTF_ARGS(5) ShowIconStringF(u16* screen, u16* icon, int w, int h, const char *format, ...);
bool PRINTF_ARGS(2) ShowPrompt(bool ask, const char *format, ...); bool PRINTF_ARGS(2) ShowPrompt(bool ask, const char *format, ...);
u32 PRINTF_ARGS(3) ShowSelectPrompt(u32 n, const char** options, const char *format, ...); u32 PRINTF_ARGS(3) ShowSelectPrompt(int n, const char** options, const char *format, ...);
u32 PRINTF_ARGS(4) ShowFileScrollPrompt(u32 n, const DirEntry** entries, bool hide_ext, const char *format, ...); u32 PRINTF_ARGS(4) ShowFileScrollPrompt(int n, const DirEntry** entries, bool hide_ext, const char *format, ...);
u32 PRINTF_ARGS(4) ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...); u32 PRINTF_ARGS(4) ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...);
bool PRINTF_ARGS(3) ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...); bool PRINTF_ARGS(3) ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...);
u64 PRINTF_ARGS(3) ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...); u64 PRINTF_ARGS(3) ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...);