diff --git a/headers/private/kernel/boot/platform.h b/headers/private/kernel/boot/platform.h index 3071c50316..f4549990bb 100644 --- a/headers/private/kernel/boot/platform.h +++ b/headers/private/kernel/boot/platform.h @@ -68,7 +68,7 @@ class MenuItem; extern void platform_add_menus(Menu *menu); extern void platform_update_menu_item(Menu *menu, MenuItem *item); extern void platform_run_menu(Menu *menu); -extern size_t platform_get_user_input_text(Menu *menu, const char *prompt, +extern size_t platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize); #endif diff --git a/headers/private/kernel/boot/platform/generic/text_menu.h b/headers/private/kernel/boot/platform/generic/text_menu.h index 437a2a41fd..791aee8be3 100644 --- a/headers/private/kernel/boot/platform/generic/text_menu.h +++ b/headers/private/kernel/boot/platform/generic/text_menu.h @@ -12,7 +12,7 @@ class MenuItem; void platform_generic_update_text_menu_item(Menu* menu, MenuItem* item); void platform_generic_run_text_menu(Menu* menu); -size_t platform_generic_get_user_input_text(Menu* menu, const char* prompt, +size_t platform_generic_get_user_input_text(Menu* menu, MenuItem* item, char* buffer, size_t bufferSize); #endif /* GENERIC_TEXT_MENU_H */ diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index b150e890ab..5068adb403 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -523,18 +523,35 @@ debug_menu_display_syslog(Menu* menu, MenuItem* item) static bool debug_menu_add_advanced_option(Menu* menu, MenuItem* item) { - char buffer[128]; - const char* prompt = "Option: "; + char buffer[256]; - size_t size = platform_get_user_input_text(menu, prompt, buffer, + size_t size = platform_get_user_input_text(menu, item, buffer, sizeof(buffer) - 1); if (size > 0) { - buffer[size] = '\n'; + char* token = NULL; + char *bufferOffset = buffer; + char *separator = NULL; uint32 pos = strlen(sSafeModeOptionsBuffer); - if (pos + size < sizeof(sSafeModeOptionsBuffer)) - strlcat(sSafeModeOptionsBuffer, buffer, - sizeof(sSafeModeOptionsBuffer)); + do { + token = bufferOffset; + separator = strchr(bufferOffset, ','); + if (separator != NULL) { + *separator = '\0'; + bufferOffset = separator + 1; + } else { + token = bufferOffset; + bufferOffset = NULL; + } + uint32 length = strlen(token) + 1; + if (pos + length < sizeof(sSafeModeOptionsBuffer)) { + strlcat(sSafeModeOptionsBuffer, token, + sizeof(sSafeModeOptionsBuffer)); + sSafeModeOptionsBuffer[pos + length - 1] = '\n'; + pos += length; + } else + break; + } while (token != NULL); } return true; diff --git a/src/system/boot/platform/amiga_m68k/menu.cpp b/src/system/boot/platform/amiga_m68k/menu.cpp index 227d798f63..ec82229d26 100644 --- a/src/system/boot/platform/amiga_m68k/menu.cpp +++ b/src/system/boot/platform/amiga_m68k/menu.cpp @@ -51,7 +51,7 @@ platform_add_menus(Menu *menu) } -void +void platform_update_menu_item(Menu *menu, MenuItem *item) { platform_generic_update_text_menu_item(menu, item); @@ -65,9 +65,9 @@ platform_run_menu(Menu *menu) } size_t -platform_get_user_input_text(Menu* menu, const char* prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/atari_m68k/menu.cpp b/src/system/boot/platform/atari_m68k/menu.cpp index 429951dbb6..57a448b746 100644 --- a/src/system/boot/platform/atari_m68k/menu.cpp +++ b/src/system/boot/platform/atari_m68k/menu.cpp @@ -67,9 +67,9 @@ platform_run_menu(Menu *menu) size_t -platform_get_user_input_text(Menu* menu, const char* prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/bios_ia32/menu.cpp b/src/system/boot/platform/bios_ia32/menu.cpp index d26879f1aa..6d59614896 100644 --- a/src/system/boot/platform/bios_ia32/menu.cpp +++ b/src/system/boot/platform/bios_ia32/menu.cpp @@ -114,9 +114,9 @@ platform_run_menu(Menu* menu) size_t -platform_get_user_input_text(Menu* menu, const char* prompt, char* buffer, +platform_get_user_input_text(Menu* menu, MenuItem* item, char* buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/generic/text_menu.cpp b/src/system/boot/platform/generic/text_menu.cpp index 5181792ad0..c845502c43 100644 --- a/src/system/boot/platform/generic/text_menu.cpp +++ b/src/system/boot/platform/generic/text_menu.cpp @@ -513,15 +513,20 @@ platform_generic_run_text_menu(Menu *menu) size_t -platform_generic_get_user_input_text(Menu* menu, const char* prompt, - char* buffer, size_t bufferSize) +platform_generic_get_user_input_text(Menu* menu, MenuItem* item, char* buffer, + size_t bufferSize) { size_t pos = 0; memset(buffer, 0, bufferSize); - int32 promptLength = strlen(prompt); - int32 line = console_height() / 2; + int32 promptLength = strlen(item->Label()) + 2; + int32 line = menu->IndexOf(item) - sMenuOffset; + if (line < 0 || line >= menu_height()) + return 0; + + line += kFirstLine; + console_set_cursor(kOffsetX, line); int32 x = kOffsetX + 1; console_set_cursor(0, line); console_set_color(kSelectedItemColor, kSelectedItemBackgroundColor); @@ -529,12 +534,15 @@ platform_generic_get_user_input_text(Menu* menu, const char* prompt, console_set_color(kTextColor, kBackgroundColor); console_set_cursor(0, line); print_spacing(x); - printf(prompt); + printf(item->Label()); + printf(": "); x += promptLength; console_set_color(kSelectedItemColor, kSelectedItemBackgroundColor); console_show_cursor(); console_set_cursor(x, line); + int32 scrollOffset = 0; + bool doScroll = false; int key = 0; size_t dataLength = 0; while (true) { @@ -546,35 +554,62 @@ platform_generic_get_user_input_text(Menu* menu, const char* prompt, { switch (key) { case TEXT_CONSOLE_KEY_LEFT: - if (pos != 0) + if (pos > 0) pos--; + else if (scrollOffset > 0) { + scrollOffset--; + doScroll = true; + } break; case TEXT_CONSOLE_KEY_RIGHT: - if (pos < dataLength) - pos++; + if (pos < dataLength) { + if (x + (int32)pos == console_width() - 1) { + scrollOffset++; + doScroll = true; + } else + pos++; + } break; default: break; } } else if (key == TEXT_CONSOLE_KEY_BACKSPACE) { - if (pos != 0) { - pos--; + if (pos != 0 || scrollOffset > 0) { + if (pos > 0) + pos--; + else if (scrollOffset > 0) + scrollOffset--; dataLength--; - buffer[pos] = '\0'; + int32 offset = pos + scrollOffset; + memmove(buffer + offset, buffer + offset + 1, dataLength - offset); console_set_cursor(x + pos, line); - printf(" "); + putchar(' '); + // if this was a mid-line backspace, the line will need to be redrawn + if (pos + scrollOffset < dataLength) + doScroll = true; } // only accept printable ascii characters } else if (key > 32 || key == TEXT_CONSOLE_KEY_SPACE) { - // don't allow the input to exceed either the buffer size - // or screen width - // TODO: support scrolling the line to allow larger inputs - if (x < (console_width() - 1) && pos < (bufferSize - 1)) { - buffer[pos++] = key; - printf("%c", key); + if (pos < (bufferSize - 1)) { + buffer[pos + scrollOffset] = key; + if (x + (int32)pos < console_width() - 1) { + putchar(key); + pos++; + } else { + scrollOffset++; + doScroll = true; + } + dataLength++; } } + + if (doScroll) { + console_set_cursor(x, line); + for (int32 i = x; i < console_width() - 1; i++) + putchar(buffer[scrollOffset + i - x]); + doScroll = false; + } console_set_cursor(x + pos, line); } diff --git a/src/system/boot/platform/openfirmware/menu.cpp b/src/system/boot/platform/openfirmware/menu.cpp index 03e69d3f81..47f9c6ff48 100644 --- a/src/system/boot/platform/openfirmware/menu.cpp +++ b/src/system/boot/platform/openfirmware/menu.cpp @@ -40,9 +40,9 @@ platform_run_menu(Menu *menu) size_t -platform_get_user_input_text(Menu *menu, const char *prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/u-boot/menu.cpp b/src/system/boot/platform/u-boot/menu.cpp index 10c3c226a4..f366fb139d 100644 --- a/src/system/boot/platform/u-boot/menu.cpp +++ b/src/system/boot/platform/u-boot/menu.cpp @@ -75,8 +75,8 @@ platform_run_menu(Menu *menu) void -platform_get_user_input_text(Menu *menu, const char *prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - platform_generic_get_user_input_text(menu, prompt, buffer, bufferSize); + platform_generic_get_user_input_text(menu, item, buffer, bufferSize); }