aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--font.c4
-rw-r--r--graphics.c71
-rw-r--r--input_field.c8
-rw-r--r--main.c2
-rw-r--r--state.h3
5 files changed, 64 insertions, 24 deletions
diff --git a/font.c b/font.c
index aff5a30..c67e427 100644
--- a/font.c
+++ b/font.c
@@ -66,6 +66,8 @@ bool freetype_init(client_state* state, const char* file) {
}
state->load_flags = FT_LOAD_RENDER;
state->line_height = state->ft_face->size->metrics.height >> 6;
+ state->horizontal_spacing = state->line_height / 2.0f;
+
return true;
}
@@ -154,7 +156,7 @@ void atlas_calc_item_widths(client_state* state) {
if (state->items) {
array_for_all(item_t, item, state->items) {
item->pixel_len = atlas_get_strwidth(state, item->text);
- state->required_width = MAX(state->required_width, item->pixel_len + state->line_height / 2.0f);
+ state->required_width = MAX(state->required_width, item->pixel_len + state->horizontal_spacing);
}
}
}
diff --git a/graphics.c b/graphics.c
index c6b0650..448b225 100644
--- a/graphics.c
+++ b/graphics.c
@@ -148,48 +148,75 @@ void render_frame(client_state *state) {
glBindTexture(GL_TEXTURE_2D, state->atlas.texture);
// calculate input buffer
- float horizontal_spacing = state->line_height / 2.0f;
float input_y = state->line_height * state->lines;
float input_width;
if (state->lines > 0) { input_width = state->width; }
else { input_width = state->width / 3.0f; }
// draw input buffer
- glScissor(0, input_y, input_width - horizontal_spacing / 2.0f, state->line_height);
+ glScissor(0, input_y, input_width - state->horizontal_spacing / 2.0f, state->line_height);
glBindVertexArray(state->input_buffer_grafix.vao);
- glUniform2f(state->offset_uniform, horizontal_spacing / 2.0f, input_y - state->atlas.vert_shift);
+ glUniform2f(state->offset_uniform, state->horizontal_spacing / 2.0f, input_y - state->atlas.vert_shift);
glDrawElements(GL_TRIANGLES, state->input_buffer_grafix.num_elements, GL_UNSIGNED_INT, 0);
- float pen_x = 0.0f;
- float pen_y = input_y;
-
+ float start;
// set up starting pen and scissor for options
if (state->lines > 0) {
- glScissor(0, 0, state->width, pen_y);
- pen_y -= state->line_height;
- }
- else {
- pen_x = input_width;
- glScissor(pen_x, 0, state->width, state->line_height);
+ glScissor(0, 0, state->width, input_y);
+ start = input_y - state->line_height + state->scroll;
+
+ // calc scroll
+ float selected_bot = start - state->filtered_items[state->selected_filtered_item].offset;
+ float selected_top = selected_bot + state->line_height;
+ if (selected_bot < 0) {
+ state->scroll -= selected_bot;
+ start -= selected_bot;
+ }
+ float diff = selected_top - input_y;
+ if (diff > 0) {
+ state->scroll -= diff;
+ start -= diff;
+ }
+ } else {
+ glScissor(input_width, 0, state->width, state->line_height);
+ start = input_width + state->scroll;
+
+ // calc scroll
+ item_display_t* selected = &state->filtered_items[state->selected_filtered_item];
+ float selected_left = start + selected->offset;
+ float selected_right = selected_left + selected->item->pixel_len + state->horizontal_spacing;
+ float diff = selected_right - state->width;
+ if (diff > 0) {
+ state->scroll -= diff;
+ start -= diff;
+ }
+ diff = selected_left - input_width;
+ if (diff < 0) {
+ state->scroll -= diff;
+ start -= diff;
+ }
}
// draw options
for (uint32_t i = 0; i < array_size(state->filtered_items); ++i) {
- item_t* item = state->filtered_items[i].item;
-
- glBindVertexArray(item->text_buffer.vao);
- glUniform2f(state->offset_uniform, pen_x + horizontal_spacing / 2.0f, pen_y - state->atlas.vert_shift);
- if (i == state->selected_filtered_item) glUniform3f(state->color_uniform, 0.0f, 0.4f, 0.8f);
- glDrawElements(GL_TRIANGLES, item->text_buffer.num_elements, GL_UNSIGNED_INT, 0);
- if (i == state->selected_filtered_item) glUniform3f(state->color_uniform, 1.0f, 1.0f, 1.0f);
+ item_display_t* display = &state->filtered_items[i];
+ item_t* item = display->item;
- // shift pen
+ float x,y;
if (state->lines > 0) {
- pen_y -= state->line_height;
+ x = 0;
+ y = start - display->offset;
}
else {
- pen_x += item->pixel_len + horizontal_spacing;
+ x = start + display->offset;
+ y = 0;
}
+
+ glBindVertexArray(item->text_buffer.vao);
+ glUniform2f(state->offset_uniform, x + state->horizontal_spacing / 2.0f, y - state->atlas.vert_shift);
+ if (i == state->selected_filtered_item) glUniform3f(state->color_uniform, 0.0f, 0.4f, 0.8f);
+ glDrawElements(GL_TRIANGLES, item->text_buffer.num_elements, GL_UNSIGNED_INT, 0);
+ if (i == state->selected_filtered_item) glUniform3f(state->color_uniform, 1.0f, 1.0f, 1.0f);
}
// present screen
diff --git a/input_field.c b/input_field.c
index 3e0a3e2..34f3fc2 100644
--- a/input_field.c
+++ b/input_field.c
@@ -24,6 +24,14 @@ void filter_items(client_state* state) {
// select item
if (array_size(state->filtered_items) > 0) state->selected_filtered_item = 0;
else state->selected_filtered_item = -1;
+
+ // lay out items
+ float offset = 0;
+ array_for_all(item_display_t, display, state->filtered_items) {
+ display->offset = offset;
+ if (state->lines > 0) offset += state->line_height;
+ else offset += display->item->pixel_len + state->horizontal_spacing;
+ }
}
void update_text_buffer(client_state* state) {
diff --git a/main.c b/main.c
index b2d847e..e334a8f 100644
--- a/main.c
+++ b/main.c
@@ -40,7 +40,6 @@ int main(int argc, char* argv[]) {
// read input
parse_args(&state, argc, argv);
read_stdin(&state);
- filter_items(&state);
// find font
char* font = get_font("Monospace");
@@ -83,6 +82,7 @@ int main(int argc, char* argv[]) {
array_for_all(item_t, item, state.items) {
init_text_buffer(&state, &item->text_buffer, item->text, strlen(item->text));
}
+ filter_items(&state);
// event loop
while (state.running) {
diff --git a/state.h b/state.h
index 1eb9e22..baec931 100644
--- a/state.h
+++ b/state.h
@@ -48,6 +48,7 @@ typedef struct {
typedef struct {
item_t* item;
+ float offset;
} item_display_t;
typedef struct {
@@ -95,6 +96,7 @@ typedef struct {
uint32_t line_height;
uint32_t required_width;
+ float horizontal_spacing;
// arguments
int lines;
@@ -104,6 +106,7 @@ typedef struct {
// state
char* input_buffer;
+ float scroll;
int selected_filtered_item;
uint32_t width, height;
item_t* items;