aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Jamison <jackqjamison@gmail.com>2025-11-08 18:17:52 -0500
committerJack Jamison <jackqjamison@gmail.com>2025-11-08 18:17:52 -0500
commitd0b1b2db2210d4fe31701d144d03a37ea55ece00 (patch)
treee23a61d925aca202b8835f8f8e3c34097e4ce783
parent6e038b0c45c1c2e351ce6ead8b80bc7b1031988f (diff)
allow selecting the prompt
-rw-r--r--README.md2
-rw-r--r--graphics.c28
-rw-r--r--input_field.c14
-rw-r--r--keybind.c9
-rw-r--r--layout.c72
-rw-r--r--state.h1
6 files changed, 74 insertions, 52 deletions
diff --git a/README.md b/README.md
index 27d6fa1..da5cf7f 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ cursor_color = (0.9, 0.9, 0.9, 0.5)
- [x] config file
- [x] starting text
- [x] if lines provided are less than specified, set lines to smallest possible amount
-- [ ] add ability to select the input field
+- [x] add ability to select the input field
- [ ] fix prompt clipping issue
- [ ] border, top padding and set exact height
- [ ] unicode + text shaping + display unrenderable characters as something
diff --git a/graphics.c b/graphics.c
index f6d6721..7377ed7 100644
--- a/graphics.c
+++ b/graphics.c
@@ -181,6 +181,7 @@ void render_frame(client_state *state) {
rect_t prompt, input, options;
calculate_layout(state, &prompt, &input, &options, false, false);
+ // draw prompt
if (state->prompt && *state->prompt) {
glScissor(prompt.x, prompt.y, prompt.dx, prompt.dy);
@@ -203,6 +204,22 @@ void render_frame(client_state *state) {
glDrawElements(GL_TRIANGLES, state->prompt_text_buffer.num_elements, GL_UNSIGNED_INT, 0);
}
+ // calculate cursor size
+ float cursor_size = state->atlas.metrics['M'].bitmap_width;
+ if (state->cursor_index != array_size(state->input_buffer)) {
+ cursor_size = state->atlas.metrics[(int)state->input_buffer[state->cursor_index]].advance_x;
+ }
+
+ // draw selected input background
+ if (state->selected_filtered_item == -1 && !state->exact_match) {
+ glUseProgram(state->box_shader);
+ glUniform4f(state->b_color_uniform, config.highlight_color.r,config.highlight_color.g,config.highlight_color.b,config.highlight_color.a);
+ glUniform2f(state->b_screen_size_uniform, state->width, state->height);
+ glUniform2f(state->b_start_uniform, input.x, input.y);
+ glUniform2f(state->b_size_uniform, input.dx, input.dy);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ }
+
// draw input buffer
glUseProgram(state->text_shader);
glActiveTexture(GL_TEXTURE0);
@@ -214,11 +231,6 @@ void render_frame(client_state *state) {
glUniform2f(state->t_offset_uniform, input.x + state->horizontal_spacing / 2.0f, input.y - state->atlas.vert_shift);
glDrawElements(GL_TRIANGLES, state->input_buffer_grafix.num_elements, GL_UNSIGNED_INT, 0);
- // calculate cursor size
- float cursor_size = state->atlas.metrics['M'].bitmap_width;
- if (state->cursor_index != array_size(state->input_buffer)) {
- cursor_size = state->atlas.metrics[(int)state->input_buffer[state->cursor_index]].advance_x;
- }
// draw cursor
glUseProgram(state->box_shader);
glUniform4f(state->b_color_uniform, config.cursor_color.r,config.cursor_color.g,config.cursor_color.b,config.cursor_color.a);
@@ -232,13 +244,13 @@ void render_frame(client_state *state) {
// draw highlighted option box
if (state->selected_filtered_item != -1) {
- item_display_t* display = &state->filtered_items[state->selected_filtered_item];
+ rect_t rect = state->filtered_items[state->selected_filtered_item].r;
glUseProgram(state->box_shader);
glUniform4f(state->b_color_uniform, config.highlight_color.r,config.highlight_color.g,config.highlight_color.b,config.highlight_color.a);
glUniform2f(state->b_screen_size_uniform, state->width, state->height);
- glUniform2f(state->b_start_uniform, display->r.x, display->r.y);
- glUniform2f(state->b_size_uniform, display->r.dx, display->r.dy);
+ glUniform2f(state->b_start_uniform, rect.x, rect.y);
+ glUniform2f(state->b_size_uniform, rect.dx, rect.dy);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
diff --git a/input_field.c b/input_field.c
index 6a4dd54..c221e6f 100644
--- a/input_field.c
+++ b/input_field.c
@@ -66,12 +66,14 @@ void refilter_items(client_state* state) {
}
}
- // select item
- if (array_size(state->filtered_items) > 0) {
- state->selected_filtered_item = 0;
- }
- else {
- state->selected_filtered_item = -1;
+ // automatically select item
+ if (state->selected_filtered_item != -1 || state->forced_selected_zero) {
+ if (array_size(state->filtered_items) == 0) {
+ state->selected_filtered_item = -1;
+ state->forced_selected_zero = true;
+ } else {
+ state->selected_filtered_item = 0;
+ }
}
// update layout
diff --git a/keybind.c b/keybind.c
index 0a23e5d..5e357fb 100644
--- a/keybind.c
+++ b/keybind.c
@@ -39,7 +39,7 @@ key_repeat_t insert_selected(client_state* state) {
}
key_repeat_t select_next(client_state* state) {
- if (state->selected_filtered_item != -1) {
+ if (state->selected_filtered_item + 1 < array_size(state->filtered_items)) {
state->selected_filtered_item = MIN(state->selected_filtered_item + 1, (int)array_size(state->filtered_items) - 1);
rect_t prompt, input, options;
calculate_layout(state, &prompt, &input, &options, true, false);
@@ -49,7 +49,8 @@ key_repeat_t select_next(client_state* state) {
key_repeat_t select_previous(client_state* state) {
if (state->selected_filtered_item != -1) {
- state->selected_filtered_item = MAX(state->selected_filtered_item - 1, 0);
+ state->selected_filtered_item = MAX(state->selected_filtered_item - 1, state->exact_match ? 0 : -1);
+ if (state->selected_filtered_item == -1) state->forced_selected_zero = false;
rect_t prompt, input, options;
calculate_layout(state, &prompt, &input, &options, true, false);
}
@@ -57,7 +58,7 @@ key_repeat_t select_previous(client_state* state) {
}
key_repeat_t select_first(client_state* state) {
- if (state->selected_filtered_item != -1) {
+ if (array_size(state->filtered_items) > 0) {
state->selected_filtered_item = 0;
rect_t prompt, input, options;
calculate_layout(state, &prompt, &input, &options, true, false);
@@ -66,7 +67,7 @@ key_repeat_t select_first(client_state* state) {
}
key_repeat_t select_last(client_state* state) {
- if (state->selected_filtered_item != -1) {
+ if (array_size(state->filtered_items) > 0) {
state->selected_filtered_item = array_size(state->filtered_items) - 1;
rect_t prompt, input, options;
calculate_layout(state, &prompt, &input, &options, true, false);
diff --git a/layout.c b/layout.c
index 86c4155..ed561a8 100644
--- a/layout.c
+++ b/layout.c
@@ -80,34 +80,38 @@ void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t
if (array_size(state->filtered_items) != 0) {
if (config.fancy_scroll) {
// calculate fancy scroll offset
- if (state->lines) {
- // calc vertical scroll
- float selected_bot = state->scroll_offset + state->filtered_items[state->selected_filtered_item].r.y;
- float selected_top = selected_bot + state->filtered_items[state->selected_filtered_item].r.dy;
- if (selected_bot < options->y) {
- state->scroll_offset -= selected_bot;
- }
- float diff = selected_top - (options->y + options->dy);
- if (diff > 0) {
- state->scroll_offset -= diff;
+ if (state->selected_filtered_item != -1) {
+ if (state->lines) {
+ // calc vertical scroll
+ float selected_bot = state->scroll_offset + state->filtered_items[state->selected_filtered_item].r.y;
+ float selected_top = selected_bot + state->filtered_items[state->selected_filtered_item].r.dy;
+ if (selected_bot < options->y) {
+ state->scroll_offset -= selected_bot;
+ }
+ float diff = selected_top - (options->y + options->dy);
+ if (diff > 0) {
+ state->scroll_offset -= diff;
+ }
+ } else {
+ // calc horizontal scroll
+ item_display_t* selected = &state->filtered_items[state->selected_filtered_item];
+ float selected_left = state->scroll_offset + selected->r.x;
+ float selected_right = selected_left + selected->r.dx;
+ float right_diff = selected_right - (options->x + options->dx);
+ float left_diff = selected_left - options->x;
+
+ if (selected->r.dx > options->dx) {
+ state->scroll_offset -= left_diff;
+ }
+ else if (right_diff > 0) {
+ state->scroll_offset -= right_diff;
+ }
+ else if (left_diff < 0) {
+ state->scroll_offset -= left_diff;
+ }
}
} else {
- // calc horizontal scroll
- item_display_t* selected = &state->filtered_items[state->selected_filtered_item];
- float selected_left = state->scroll_offset + selected->r.x;
- float selected_right = selected_left + selected->r.dx;
- float right_diff = selected_right - (options->x + options->dx);
- float left_diff = selected_left - options->x;
-
- if (selected->r.dx > options->dx) {
- state->scroll_offset -= left_diff;
- }
- else if (right_diff > 0) {
- state->scroll_offset -= right_diff;
- }
- else if (left_diff < 0) {
- state->scroll_offset -= left_diff;
- }
+ state->scroll_offset = 0;
}
// display all filtered items (could be optimized)
@@ -119,13 +123,15 @@ void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t
// determine what page the selected item is in
size_t selected_page = 0;
- size_t selected_page_index = 0;
- for(size_t i = 0; i < array_size(state->page_indices); ++i) {
- if (state->selected_filtered_item < state->page_indices[i]) {
- break;
+ size_t selected_page_index = state->page_indices[selected_page];
+ if (state->selected_filtered_item != -1) {
+ for(size_t i = 0; i < array_size(state->page_indices); ++i) {
+ if (state->selected_filtered_item < state->page_indices[i]) {
+ break;
+ }
+ selected_page = i;
+ selected_page_index = state->page_indices[i];
}
- selected_page = i;
- selected_page_index = state->page_indices[i];
}
// determine scroll to put that page at the start
@@ -136,7 +142,7 @@ void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t
rect_t r = state->filtered_items[selected_page_index].r;
state->scroll_offset = options->x - r.x;
}
-
+
// display filtered items on the page
state->displayed_item_start = state->page_indices[selected_page];
state->displayed_item_end = (selected_page + 1 < array_size(state->page_indices)) ? state->page_indices[selected_page + 1] : array_size(state->filtered_items);
diff --git a/state.h b/state.h
index ac31120..1eab360 100644
--- a/state.h
+++ b/state.h
@@ -132,6 +132,7 @@ typedef struct {
uint32_t width, height;
item_display_t* filtered_items;
int selected_filtered_item;
+ bool forced_selected_zero;
char* input_buffer;
size_t cursor_index;