summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-01-24 15:46:08 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-01-24 15:46:08 -0500
commitaccf188e7c84ee627d5e4cfe12c141e929699830 (patch)
tree16ff19058ecae11b8cba9ba1d0d4f7bb1ae18184
parent8c5eb397121c7fb3fa7feb2391d7c9b674b4190b (diff)
scroll file selector when selected goes offscreen
-rw-r--r--buffer.c17
-rw-r--r--command.c4
-rw-r--r--config.c6
-rw-r--r--ted.cfg2
-rw-r--r--ted.h1
-rw-r--r--ui.c36
6 files changed, 47 insertions, 19 deletions
diff --git a/buffer.c b/buffer.c
index db47e2c..cc97e19 100644
--- a/buffer.c
+++ b/buffer.c
@@ -150,7 +150,7 @@ static inline Font *buffer_font(TextBuffer *buffer) {
}
// Get the settings used for this buffer.
-static inline Settings *buffer_settings(TextBuffer *buffer) {
+static inline Settings const *buffer_settings(TextBuffer *buffer) {
return &buffer->ted->settings;
}
@@ -845,24 +845,25 @@ static bool buffer_clip_rect(TextBuffer *buffer, Rect *r) {
// if the cursor is offscreen, this will scroll to make it onscreen.
static void buffer_scroll_to_cursor(TextBuffer *buffer) {
+ Settings const *settings = buffer_settings(buffer);
i64 cursor_line = buffer->cursor_pos.line;
i64 cursor_col = buffer_index_to_column(buffer, (u32)cursor_line, buffer->cursor_pos.index);
i64 display_lines = buffer_display_lines(buffer);
i64 display_cols = buffer_display_cols(buffer);
double scroll_x = buffer->scroll_x, scroll_y = buffer->scroll_y;
- i64 scroll_padding = 5;
+ i64 scrolloff = settings->scrolloff;
// scroll left if cursor is off screen in that direction
- double max_scroll_x = (double)(cursor_col - scroll_padding);
+ double max_scroll_x = (double)(cursor_col - scrolloff);
scroll_x = mind(scroll_x, max_scroll_x);
// scroll right
- double min_scroll_x = (double)(cursor_col - display_cols + scroll_padding);
+ double min_scroll_x = (double)(cursor_col - display_cols + scrolloff);
scroll_x = maxd(scroll_x, min_scroll_x);
// scroll up
- double max_scroll_y = (double)(cursor_line - scroll_padding);
+ double max_scroll_y = (double)(cursor_line - scrolloff);
scroll_y = mind(scroll_y, max_scroll_y);
// scroll down
- double min_scroll_y = (double)(cursor_line - display_lines + scroll_padding);
+ double min_scroll_y = (double)(cursor_line - display_lines + scrolloff);
scroll_y = maxd(scroll_y, min_scroll_y);
buffer->scroll_x = scroll_x;
@@ -1718,8 +1719,8 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
float header_height = char_height;
Ted *ted = buffer->ted;
- Settings *settings = buffer_settings(buffer);
- u32 *colors = settings->colors;
+ Settings const *settings = buffer_settings(buffer);
+ u32 const *colors = settings->colors;
float border_thickness = settings->border_thickness;
diff --git a/command.c b/command.c
index 40636b6..74a624a 100644
--- a/command.c
+++ b/command.c
@@ -38,11 +38,11 @@ void command_execute(Ted *ted, Command c, i64 argument) {
if (buffer) buffer_cursor_move_right(buffer, argument);
break;
case CMD_UP:
- if (file_selector->open) file_selector_up(file_selector, argument);
+ if (file_selector->open) file_selector_up(ted, file_selector, argument);
else if (buffer) buffer_cursor_move_up(buffer, argument);
break;
case CMD_DOWN:
- if (file_selector->open) file_selector_down(file_selector, argument);
+ if (file_selector->open) file_selector_down(ted, file_selector, argument);
else if (buffer) buffer_cursor_move_down(buffer, argument);
break;
case CMD_SELECT_LEFT:
diff --git a/config.c b/config.c
index 9a2bed8..39a5d80 100644
--- a/config.c
+++ b/config.c
@@ -312,6 +312,12 @@ void config_read(Ted *ted, char const *filename) {
} else {
config_err(cfg, "Invalid padding: %s.", value);
}
+ } else if (streq(key, "scrolloff")) {
+ if (is_integer && integer >= 1 && integer < 100) {
+ settings->scrolloff = (u8)integer;
+ } else {
+ config_err(cfg, "Invalid scrolloff: %s.", value);
+ }
} else {
config_err(cfg, "Unrecognized core setting: %s.", key);
}
diff --git a/ted.cfg b/ted.cfg
index a28424e..623e914 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -6,6 +6,8 @@ cursor-width = 1
# set -off to 0 to disable blinking
cursor-blink-time-on = 0.5
cursor-blink-time-off = 0.3
+# amount of scroll "padding" (minimum number of lines below the cursor will the bottom of the screen be)
+scrolloff = 5
# if you do a bunch of typing, then undo, it will generally
# undo the past this many seconds of editing.
undo-save-time = 6
diff --git a/ted.h b/ted.h
index f1374b3..16fb131 100644
--- a/ted.h
+++ b/ted.h
@@ -13,6 +13,7 @@ typedef struct {
u8 undo_save_time;
u8 border_thickness;
u8 padding;
+ u8 scrolloff;
} Settings;
#define SCANCODE_COUNT 0x120 // SDL scancodes should be less than this value.
diff --git a/ui.c b/ui.c
index 8184ecd..8f90bbb 100644
--- a/ui.c
+++ b/ui.c
@@ -12,6 +12,28 @@ static float file_selector_entries_start_y(Ted const *ted, FileSelector const *f
+ char_height * 1.5f; // make room for line buffer
}
+// number of file entries that can be displayed on the screen
+static u32 file_selector_n_display_entries(Ted const *ted, FileSelector const *fs) {
+ float char_height = text_font_char_height(ted->font);
+ float entries_h = rect_y2(fs->bounds) - file_selector_entries_start_y(ted, fs);
+ return (u32)(entries_h / char_height);
+}
+
+static void file_selector_clamp_scroll(Ted const *ted, FileSelector *fs) {
+ float max_scroll = (float)fs->n_entries - (float)file_selector_n_display_entries(ted, fs);
+ if (max_scroll < 0) max_scroll = 0;
+ fs->scroll = clampf(fs->scroll, 0, max_scroll);
+}
+
+static void file_selector_scroll_to_selected(Ted const *ted, FileSelector *fs) {
+ u32 n_display_entries = file_selector_n_display_entries(ted, fs);
+ float scrolloff = ted->settings.scrolloff;
+ float min_scroll = (float)fs->selected - ((float)n_display_entries - scrolloff);
+ float max_scroll = (float)fs->selected - scrolloff;
+ fs->scroll = clampf(fs->scroll, min_scroll, max_scroll);
+ file_selector_clamp_scroll(ted, fs);
+}
+
// 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,
@@ -41,16 +63,18 @@ static void file_selector_free(FileSelector *fs) {
memset(fs, 0, sizeof *fs);
}
-static void file_selector_up(FileSelector *fs, i64 n) {
+static void file_selector_up(Ted const *ted, FileSelector *fs, i64 n) {
i64 selected = fs->selected - n;
selected = mod_i64(selected, fs->n_entries);
fs->selected = (u32)selected;
+ file_selector_scroll_to_selected(ted, fs);
}
-static void file_selector_down(FileSelector *fs, i64 n) {
+static void file_selector_down(Ted const *ted, FileSelector *fs, i64 n) {
i64 selected = fs->selected + n;
selected = mod_i64(selected, fs->n_entries);
fs->selected = (u32)selected;
+ file_selector_scroll_to_selected(ted, fs);
}
static int qsort_file_entry_cmp(void const *av, void const *bv, void *search_termv) {
@@ -351,13 +375,7 @@ static char *file_selector_update(Ted *ted, FileSelector *fs) {
// 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);
+ file_selector_clamp_scroll(ted, fs);
free(search_term);
return NULL;