.
This commit is contained in:
parent
4117b3daaf
commit
6a381b539c
@ -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,76 +179,104 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display filtered choices horizontally
|
// Only redraw if something changed
|
||||||
int x = 2 - scroll_offset;
|
if (filtered_choices != last_filtered_choices ||
|
||||||
for (size_t i = 0; i < filtered_choices.size(); i++) {
|
selected != last_selected ||
|
||||||
if (i == selected) {
|
scroll_offset != last_scroll_offset) {
|
||||||
wattron(input_win, A_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only draw if visible
|
// Clear the input window except for the prompt
|
||||||
if (x + filtered_choices[i].length() > 0 && x < max_x - 2) {
|
werase(input_win);
|
||||||
mvwprintw(input_win, 2, x, "%s", filtered_choices[i].c_str());
|
box(input_win, 0, 0);
|
||||||
}
|
mvwprintw(input_win, 1, 2, "%s", prompt.c_str());
|
||||||
|
|
||||||
if (i == selected) {
|
// Display filtered choices horizontally
|
||||||
wattroff(input_win, A_REVERSE);
|
int x = 2 - scroll_offset;
|
||||||
}
|
for (size_t i = 0; i < filtered_choices.size(); i++) {
|
||||||
|
if (i == selected) {
|
||||||
x += filtered_choices[i].length() + 3; // +3 for " | " separator
|
wattron(input_win, A_REVERSE);
|
||||||
|
}
|
||||||
// Draw separator if not last item
|
|
||||||
if (i < filtered_choices.size() - 1) {
|
// Only draw if visible
|
||||||
if (x - 3 + 3 > 0 && x - 3 < max_x - 2) {
|
if (x + filtered_choices[i].length() > 0 && x < max_x - 2) {
|
||||||
mvwprintw(input_win, 2, x - 3, " | ");
|
mvwprintw(input_win, 2, x, "%s", filtered_choices[i].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == selected) {
|
||||||
|
wattroff(input_win, A_REVERSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
x += filtered_choices[i].length() + 3; // +3 for " | " separator
|
||||||
|
|
||||||
|
// Draw separator if not last item
|
||||||
|
if (i < filtered_choices.size() - 1) {
|
||||||
|
if (x - 3 + 3 > 0 && x - 3 < max_x - 2) {
|
||||||
|
mvwprintw(input_win, 2, x - 3, " | ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wrefresh(input_win);
|
||||||
|
|
||||||
|
// Update last state
|
||||||
|
last_filtered_choices = filtered_choices;
|
||||||
|
last_selected = selected;
|
||||||
|
last_scroll_offset = scroll_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrefresh(input_win);
|
|
||||||
|
|
||||||
int ch = wgetch(input_win);
|
int ch = wgetch(input_win);
|
||||||
|
|
||||||
// Handle key input
|
// Handle key input
|
||||||
if (ch == '\n') {
|
switch (ch) {
|
||||||
if (!filtered_choices.empty()) {
|
case '\n':
|
||||||
return filtered_choices[selected];
|
if (!filtered_choices.empty()) {
|
||||||
}
|
return filtered_choices[selected];
|
||||||
} else if (ch == 27) { // ESC key
|
}
|
||||||
if (!filter.empty()) {
|
break;
|
||||||
// Clear the filter and reset selection
|
|
||||||
filter = "";
|
case 27: // ESC key
|
||||||
selected = 0;
|
if (!filter.empty()) {
|
||||||
scroll_offset = 0;
|
// Clear the filter and reset selection
|
||||||
} else {
|
filter = "";
|
||||||
// Only return if filter is already empty
|
selected = 0;
|
||||||
return "";
|
scroll_offset = 0;
|
||||||
}
|
} else {
|
||||||
} else if (ch == KEY_LEFT || ch == KEY_UP) {
|
// Only return if filter is already empty
|
||||||
if (selected > 0) {
|
return "";
|
||||||
selected--;
|
}
|
||||||
} else {
|
break;
|
||||||
selected = filtered_choices.size() - 1; // Wrap to end
|
|
||||||
}
|
case KEY_LEFT:
|
||||||
continue; // Skip the rest of the loop
|
case KEY_UP:
|
||||||
} else if (ch == KEY_RIGHT || ch == KEY_DOWN) {
|
if (selected > 0) {
|
||||||
if (selected < filtered_choices.size() - 1) {
|
selected--;
|
||||||
selected++;
|
} else {
|
||||||
} else {
|
selected = filtered_choices.size() - 1; // Wrap to end
|
||||||
selected = 0; // Wrap to beginning
|
}
|
||||||
}
|
break;
|
||||||
continue; // Skip the rest of the loop
|
|
||||||
} else if (isprint(ch)) {
|
case KEY_RIGHT:
|
||||||
auto now = std::chrono::steady_clock::now();
|
case KEY_DOWN:
|
||||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_key_time).count();
|
if (selected < filtered_choices.size() - 1) {
|
||||||
|
selected++;
|
||||||
if (elapsed > 500) { // Reset filter if too much time has passed
|
} else {
|
||||||
filter = "";
|
selected = 0; // Wrap to beginning
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
filter += ch;
|
|
||||||
selected = 0;
|
default:
|
||||||
last_key_time = now;
|
if (isalnum(ch)) {
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_key_time).count();
|
||||||
|
|
||||||
|
if (elapsed > 500) { // Reset filter if too much time has passed
|
||||||
|
filter = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
filter += ch;
|
||||||
|
selected = 0;
|
||||||
|
last_key_time = now;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user