summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-01-24 13:25:42 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-01-24 13:25:42 -0500
commitb9079377328e9abeb20950ac144a7ebd98fde88e (patch)
tree785b79f91037990ec74195bdc0dad2cbd9248c60
parent33b951f3b5d89c0ba7e7c7d821a9eafb37088872 (diff)
file selector scrolling
-rw-r--r--main.c3
-rw-r--r--ted.h3
-rw-r--r--ui.c35
3 files changed, 32 insertions, 9 deletions
diff --git a/main.c b/main.c
index ca8c991..b7ee115 100644
--- a/main.c
+++ b/main.c
@@ -256,6 +256,7 @@ int main(int argc, char **argv) {
bool alt_down = keyboard_state[SDL_SCANCODE_LALT] || keyboard_state[SDL_SCANCODE_RALT];
memset(ted->nmouse_clicks, 0, sizeof ted->nmouse_clicks);
+ ted->scroll_total_x = ted->scroll_total_y = 0;
//printf("%p\n",(void *)ted->drag_buffer);
@@ -271,6 +272,8 @@ int main(int argc, char **argv) {
case SDL_MOUSEWHEEL: {
// scroll with mouse wheel
Sint32 dx = event.wheel.x, dy = -event.wheel.y;
+ ted->scroll_total_x += dx;
+ ted->scroll_total_y += dy;
double scroll_speed = 2.5;
if (ted->active_buffer)
buffer_scroll(ted->active_buffer, dx * scroll_speed, dy * scroll_speed);
diff --git a/ted.h b/ted.h
index 077d32d..9746c6f 100644
--- a/ted.h
+++ b/ted.h
@@ -86,6 +86,7 @@ typedef struct {
typedef struct {
Rect bounds;
u32 n_entries;
+ float scroll;
FileEntry *entries;
char cwd[TED_PATH_MAX];
bool submitted; // set to true if the line buffer was just submitted this frame.
@@ -94,7 +95,6 @@ typedef struct {
typedef struct Ted {
Font *font_bold;
Font *font;
-
TextBuffer *active_buffer;
// buffer we are currently drag-to-selecting in, if any
TextBuffer *drag_buffer;
@@ -106,6 +106,7 @@ typedef struct Ted {
v2 mouse_pos;
u8 nmouse_clicks[4]; // nmouse_clicks[i] = length of mouse_clicks[i]
v2 mouse_clicks[4][32]; // mouse_clicks[SDL_BUTTON_RIGHT], for example, is all the right mouse-clicks that have happened this frame
+ int scroll_total_x, scroll_total_y; // total amount scrolled in the x and y direction this frame
Menu menu;
FileSelector file_selector;
TextBuffer line_buffer; // general-purpose line buffer for inputs -- used for menus
diff --git a/ui.c b/ui.c
index 87f2175..7ffada0 100644
--- a/ui.c
+++ b/ui.c
@@ -2,17 +2,24 @@
#include <fcntl.h>
#endif
+static float file_selector_entries_start_y(Ted const *ted, FileSelector const *fs) {
+ Rect bounds = fs->bounds;
+ float padding = ted->settings.padding;
+ float char_height = text_font_char_height(ted->font);
+ float char_height_bold = text_font_char_height(ted->font_bold);
+ return bounds.pos.y
+ + char_height_bold + padding // make room for cwd
+ + char_height * 1.5f; // make room for line buffer
+}
+
// where is the ith entry in the file selector on the screen?
// returns false if it's completely offscreen
static bool file_selector_entry_pos(Ted const *ted, FileSelector const *fs,
u32 i, Rect *r) {
Rect bounds = fs->bounds;
- float padding = ted->settings.padding;
float char_height = text_font_char_height(ted->font);
- float char_height_bold = text_font_char_height(ted->font_bold);
- *r = rect(V2(bounds.pos.x, bounds.pos.y
- + char_height_bold + padding // make room for cwd
- + char_height * 1.5f // make room for line buffer
+ *r = rect(V2(bounds.pos.x, file_selector_entries_start_y(ted, fs)
+ - char_height * fs->scroll
+ char_height * (float)i),
V2(bounds.size.x, char_height));
return rect_clip_to_rect(r, bounds);
@@ -31,16 +38,16 @@ static void file_selector_clear_entries(FileSelector *fs) {
static void file_selector_free(FileSelector *fs) {
file_selector_clear_entries(fs);
- fs->cwd[0] = '\0';
+ memset(fs, 0, sizeof *fs);
}
static int qsort_file_entry_cmp(void const *av, void const *bv) {
FileEntry const *a = av, *b = bv;
// put directories first
- if (a->type > b->type) {
+ if (a->type == FS_DIRECTORY && b->type != FS_DIRECTORY) {
return -1;
}
- if (a->type < b->type) {
+ if (a->type != FS_DIRECTORY && b->type == FS_DIRECTORY) {
return +1;
}
return strcmp_case_insensitive(a->name, b->name);
@@ -311,10 +318,22 @@ static char *file_selector_update(Ted *ted, FileSelector *fs) {
}
free(files);
+
} else {
ted_seterr(ted, "Couldn't list directory '%s'.", cwd);
}
+ // apply scroll
+ float scroll_speed = 2.5f;
+ fs->scroll += scroll_speed * (float)ted->scroll_total_y;
+ // clamp scroll
+ float char_height = text_font_char_height(ted->font);
+ float entries_h = rect_y2(fs->bounds) - file_selector_entries_start_y(ted, fs);
+ u32 n_display_entries = (u32)(entries_h / char_height);
+ float max_scroll = (float)fs->n_entries - (float)n_display_entries;
+ if (max_scroll < 0) max_scroll = 0;
+ fs->scroll = clampf(fs->scroll, 0, max_scroll);
+
free(search_term);
return NULL;
}