diff options
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | graphics.c | 28 | ||||
| -rw-r--r-- | input_field.c | 14 | ||||
| -rw-r--r-- | keybind.c | 9 | ||||
| -rw-r--r-- | layout.c | 72 | ||||
| -rw-r--r-- | state.h | 1 |
6 files changed, 74 insertions, 52 deletions
@@ -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 @@ -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 @@ -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); @@ -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); @@ -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; |
