aboutsummaryrefslogtreecommitdiff
path: root/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'layout.c')
-rw-r--r--layout.c123
1 files changed, 87 insertions, 36 deletions
diff --git a/layout.c b/layout.c
index 11706d6..d9051cd 100644
--- a/layout.c
+++ b/layout.c
@@ -2,13 +2,9 @@
#include "array.h"
#include "config.h"
-void init_layout(client_state* state) {
-
-}
-
-void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t* options, bool recalc_options) {
-
+void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t* options, bool recalc_options, bool recalc_pages) {
if (state->prompt && *state->prompt) {
+
*prompt = (rect_t){ .x = 0, .y = state->line_height * state->lines, .dx = state->prompt_text_buffer.pixel_len + state->horizontal_spacing, .dy = state->line_height };
}
else {
@@ -31,7 +27,7 @@ void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t
options->dy = state->line_height;
}
- if (recalc_options) {
+ if (recalc_options || recalc_pages) {
// calculate starting conditions
rect_t cur;
@@ -56,49 +52,104 @@ void calculate_layout(client_state* state, rect_t* prompt, rect_t* input, rect_t
}
}
- // calculate fancy scroll
- if (fancy_scroll && array_size(state->filtered_items) != 0) {
+ // calculate page indices
+ if (recalc_pages && !fancy_scroll) {
+ state->current_page = 0;
+ array_clear(state->page_indices);
- // calculate if we should adjust scrolling
if (state->lines) {
- // calc vertical scroll
- float selected_bot = state->fancy_scroll + 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->fancy_scroll -= selected_bot;
- }
- float diff = selected_top - (options->y + options->dy);
- if (diff > 0) {
- state->fancy_scroll -= diff;
+ // this won't work if we add sized images and bullshit to the option list
+ for (size_t i = 0; i < array_size(state->filtered_items); i += state->lines) {
+ array_add(state->page_indices, i);
}
} else {
- // calc horizontal scroll
- item_display_t* selected = &state->filtered_items[state->selected_filtered_item];
- float selected_left = state->fancy_scroll + 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->fancy_scroll -= left_diff;
+ array_add(state->page_indices, 0);
+ float page_x = options->x;
+ size_t i = 0;
+ array_for_all(item_display_t, display, state->filtered_items) {
+ // check if past the end of the page
+ if (((display->r.x + display->r.dx) - page_x) / options->dx >= 1.f) {
+ page_x = display->r.x;
+ array_add(state->page_indices, i);
+ }
+ ++i;
+ }
+ }
+ }
+
+ if (array_size(state->filtered_items) != 0) {
+ if (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;
+ }
+ } 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 if (right_diff > 0) {
- state->fancy_scroll -= right_diff;
+
+ // display all filtered items (could be optimized)
+ state->displayed_item_start = 0;
+ state->displayed_item_end = array_size(state->filtered_items);
+
+ } else {
+ // calculate page scroll offset
+
+ // 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;
+ }
+ selected_page = i;
+ selected_page_index = state->page_indices[i];
}
- else if (left_diff < 0) {
- state->fancy_scroll -= left_diff;
+
+ // determine scroll to put that page at the start
+ if (state->lines) {
+ rect_t r = state->filtered_items[selected_page_index].r;
+ state->scroll_offset = (options->y + options->dy) - (r.y + r.dy);
+ } else {
+ 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);
}
// apply scroll offset
array_for_all(item_display_t, display, state->filtered_items) {
if (state->lines) {
- display->r.y += state->fancy_scroll;
+ display->r.y += state->scroll_offset;
} else {
- display->r.x += state->fancy_scroll;
+ display->r.x += state->scroll_offset;
}
}
-
- }
+ }
}
}