This commit is contained in:
Your Name 2025-04-22 20:01:59 +12:00
parent 4117b3daaf
commit 6a381b539c

View File

@ -21,11 +21,12 @@ int fullscreen_window::ncurses_streambuf::overflow(int c) {
} }
fullscreen_window::fullscreen_window(std::string title) { fullscreen_window::fullscreen_window(std::string title) {
// Initialize ncurses
initscr(); initscr();
cbreak(); raw(); // Use raw mode for better control
noecho(); noecho();
keypad(stdscr, TRUE); keypad(stdscr, TRUE); // Enable keypad
curs_set(0); curs_set(0); // Hide cursor
refresh(); refresh();
// Create display window (takes up all but bottom 4 lines) // Create display window (takes up all but bottom 4 lines)
@ -33,11 +34,13 @@ fullscreen_window::fullscreen_window(std::string title) {
getmaxyx(stdscr, max_y, max_x); getmaxyx(stdscr, max_y, max_x);
display_win = newwin(max_y - 4, max_x, 0, 0); display_win = newwin(max_y - 4, max_x, 0, 0);
scrollok(display_win, TRUE); scrollok(display_win, TRUE);
keypad(display_win, TRUE); // Enable keypad for display window
wrefresh(display_win); wrefresh(display_win);
// Create input window (bottom 4 lines) // Create input window (bottom 4 lines)
input_win = newwin(4, max_x, max_y - 4, 0); input_win = newwin(4, max_x, max_y - 4, 0);
box(input_win, 0, 0); box(input_win, 0, 0);
keypad(input_win, TRUE); // Enable keypad for input window
wrefresh(input_win); wrefresh(input_win);
// Set up output redirection // Set up output redirection
@ -138,6 +141,9 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
std::string filter = ""; std::string filter = "";
auto last_key_time = std::chrono::steady_clock::now(); auto last_key_time = std::chrono::steady_clock::now();
int scroll_offset = 0; int scroll_offset = 0;
std::vector<std::string> last_filtered_choices;
int last_selected = -1;
int last_scroll_offset = -1;
while (true) { while (true) {
// Filter choices based on input // Filter choices based on input
@ -153,12 +159,6 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
filter = ""; filter = "";
} }
// Calculate total width needed
int total_width = 0;
for (const auto& choice : filtered_choices) {
total_width += choice.length() + 3; // +3 for " | " separator
}
// Get window dimensions // Get window dimensions
int max_y, max_x; int max_y, max_x;
getmaxyx(input_win, max_y, max_x); getmaxyx(input_win, max_y, max_x);
@ -179,6 +179,16 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
} }
} }
// Only redraw if something changed
if (filtered_choices != last_filtered_choices ||
selected != last_selected ||
scroll_offset != last_scroll_offset) {
// Clear the input window except for the prompt
werase(input_win);
box(input_win, 0, 0);
mvwprintw(input_win, 1, 2, "%s", prompt.c_str());
// Display filtered choices horizontally // Display filtered choices horizontally
int x = 2 - scroll_offset; int x = 2 - scroll_offset;
for (size_t i = 0; i < filtered_choices.size(); i++) { for (size_t i = 0; i < filtered_choices.size(); i++) {
@ -207,14 +217,23 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
wrefresh(input_win); wrefresh(input_win);
// Update last state
last_filtered_choices = filtered_choices;
last_selected = selected;
last_scroll_offset = scroll_offset;
}
int ch = wgetch(input_win); int ch = wgetch(input_win);
// Handle key input // Handle key input
if (ch == '\n') { switch (ch) {
case '\n':
if (!filtered_choices.empty()) { if (!filtered_choices.empty()) {
return filtered_choices[selected]; return filtered_choices[selected];
} }
} else if (ch == 27) { // ESC key break;
case 27: // ESC key
if (!filter.empty()) { if (!filter.empty()) {
// Clear the filter and reset selection // Clear the filter and reset selection
filter = ""; filter = "";
@ -224,21 +243,28 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
// Only return if filter is already empty // Only return if filter is already empty
return ""; return "";
} }
} else if (ch == KEY_LEFT || ch == KEY_UP) { break;
case KEY_LEFT:
case KEY_UP:
if (selected > 0) { if (selected > 0) {
selected--; selected--;
} else { } else {
selected = filtered_choices.size() - 1; // Wrap to end selected = filtered_choices.size() - 1; // Wrap to end
} }
continue; // Skip the rest of the loop break;
} else if (ch == KEY_RIGHT || ch == KEY_DOWN) {
case KEY_RIGHT:
case KEY_DOWN:
if (selected < filtered_choices.size() - 1) { if (selected < filtered_choices.size() - 1) {
selected++; selected++;
} else { } else {
selected = 0; // Wrap to beginning selected = 0; // Wrap to beginning
} }
continue; // Skip the rest of the loop break;
} else if (isprint(ch)) {
default:
if (isalnum(ch)) {
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_key_time).count(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_key_time).count();
@ -250,6 +276,8 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
selected = 0; selected = 0;
last_key_time = now; last_key_time = now;
} }
break;
}
} }
} }