summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-01-19 10:22:52 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-01-19 10:22:52 -0500
commit7ba80aaa38c95fdb84cd8fb51d51b5d897c5de95 (patch)
tree3bc8daa12db1b25301e775967f2b423386f11e9b
parent8a4984e0e15fcfb0be6db242ab3f60325b80abd8 (diff)
opening files by clicking on them
-rw-r--r--buffer.c7
-rw-r--r--colors.h4
-rw-r--r--command.c13
-rw-r--r--main.c32
-rw-r--r--menu.c43
-rw-r--r--ted-base.c20
-rw-r--r--ted.cfg1
-rw-r--r--ted.h3
-rw-r--r--util.c4
9 files changed, 100 insertions, 27 deletions
diff --git a/buffer.c b/buffer.c
index 477a1c9..9481236 100644
--- a/buffer.c
+++ b/buffer.c
@@ -74,7 +74,7 @@ static char *buffer_strdup(TextBuffer *buffer, char const *src) {
}
void buffer_create(TextBuffer *buffer, Ted *ted) {
- util_zero_memory(buffer, sizeof *buffer);
+ memset(buffer, 0, sizeof *buffer);
buffer->store_undo_events = true;
buffer->ted = ted;
}
@@ -459,7 +459,7 @@ void buffer_free(TextBuffer *buffer) {
arr_free(buffer->undo_history);
arr_free(buffer->redo_history);
- util_zero_memory(buffer, sizeof *buffer);
+ memset(buffer, 0, sizeof *buffer);
}
// clear contents, undo history, etc. of a buffer
@@ -474,6 +474,7 @@ void buffer_clear(TextBuffer *buffer) {
} else {
buffer_create(buffer, ted);
}
+ memcpy(buffer->error, error, sizeof error);
}
void buffer_load_file(TextBuffer *buffer, char const *filename) {
@@ -1128,7 +1129,7 @@ static Status buffer_insert_lines(TextBuffer *buffer, u32 where, u32 number) {
buffer->lines + where,
(old_nlines - where) * sizeof *buffer->lines);
// zero new lines
- util_zero_memory(buffer->lines + where, number * sizeof *buffer->lines);
+ memset(buffer->lines + where, 0, number * sizeof *buffer->lines);
buffer->nlines = new_nlines;
return true;
}
diff --git a/colors.h b/colors.h
index d51d7e7..b09fcc1 100644
--- a/colors.h
+++ b/colors.h
@@ -9,6 +9,7 @@ ENUM_U16 {
COLOR_SELECTION_BG,
COLOR_MENU_BACKDROP,
COLOR_MENU_BG,
+ COLOR_MENU_HL,
COLOR_COUNT
} ENUM_U16_END(ColorSetting);
@@ -27,7 +28,8 @@ static ColorName const color_names[COLOR_COUNT] = {
{COLOR_TEXT, "text"},
{COLOR_SELECTION_BG, "selection-bg"},
{COLOR_MENU_BACKDROP, "menu-backdrop"},
- {COLOR_MENU_BG, "menu-bg"}
+ {COLOR_MENU_BG, "menu-bg"},
+ {COLOR_MENU_HL, "menu-hl"}
};
static ColorSetting color_setting_from_str(char const *str) {
diff --git a/command.c b/command.c
index 9bd58bc..206274a 100644
--- a/command.c
+++ b/command.c
@@ -156,16 +156,13 @@ void command_execute(Ted *ted, Command c, i64 argument) {
assert(0);
break;
case MENU_OPEN: {
- TextBuffer *open_to = &ted->main_buffer;
char *filename_cstr = str32_to_utf8_cstr(buffer_get_line(&ted->line_buffer, 0));
if (filename_cstr) {
- buffer_load_file(open_to, filename_cstr);
- buffer = open_to;
- if (buffer_haserr(open_to)) {
- // @TODO: something
- }
+ buffer = ted_open_file(ted, filename_cstr);
free(filename_cstr);
- menu_close(ted, true);
+ menu_close(ted, false);
+ } else {
+ ted_seterr(ted, "Out of memory.");
}
} break;
}
@@ -174,7 +171,7 @@ void command_execute(Ted *ted, Command c, i64 argument) {
}
if (buffer && buffer_haserr(buffer)) {
- strncpy(ted->error, buffer_geterr(buffer), sizeof ted->error - 1);
+ ted_seterr_to_buferr(ted, buffer);
buffer_clearerr(buffer);
}
}
diff --git a/main.c b/main.c
index 3c05744..bfbeac2 100644
--- a/main.c
+++ b/main.c
@@ -235,10 +235,17 @@ int main(int argc, char **argv) {
SDL_Event event;
Uint8 const *keyboard_state = SDL_GetKeyboardState(NULL);
-
+
+ { // get mouse position
+ int mouse_x = 0, mouse_y = 0;
+ SDL_GetMouseState(&mouse_x, &mouse_y);
+ ted->mouse_pos = V2((float)mouse_x, (float)mouse_y);
+ }
bool ctrl_down = keyboard_state[SDL_SCANCODE_LCTRL] || keyboard_state[SDL_SCANCODE_RCTRL];
bool shift_down = keyboard_state[SDL_SCANCODE_LSHIFT] || keyboard_state[SDL_SCANCODE_RSHIFT];
bool alt_down = keyboard_state[SDL_SCANCODE_LALT] || keyboard_state[SDL_SCANCODE_RALT];
+
+ memset(ted->nmouse_clicks, 0, sizeof ted->nmouse_clicks);
while (SDL_PollEvent(&event)) {
TextBuffer *buffer = ted->active_buffer;
@@ -256,12 +263,20 @@ int main(int argc, char **argv) {
if (ted->active_buffer)
buffer_scroll(ted->active_buffer, dx * scroll_speed, dy * scroll_speed);
} break;
- case SDL_MOUSEBUTTONDOWN:
- switch (event.button.button) {
+ case SDL_MOUSEBUTTONDOWN: {
+ Uint32 button = event.button.button;
+ float x = (float)event.button.x, y = (float)event.button.y;
+ if (button < arr_count(ted->nmouse_clicks)
+ && ted->nmouse_clicks[button] < arr_count(ted->mouse_clicks[button])) {
+ v2 *v = &ted->mouse_clicks[button][ted->nmouse_clicks[button]++];
+ v->x = x;
+ v->y = y;
+ }
+ switch (button) {
case SDL_BUTTON_LEFT: {
if (buffer) {
BufferPos pos = {0};
- if (buffer_pixels_to_pos(buffer, V2((float)event.button.x, (float)event.button.y), &pos)) {
+ if (buffer_pixels_to_pos(buffer, V2(x, y), &pos)) {
if (key_modifier == KEY_MODIFIER_SHIFT) {
buffer_select_to_pos(buffer, pos);
} else if (key_modifier == 0) {
@@ -280,7 +295,7 @@ int main(int argc, char **argv) {
}
} break;
}
- break;
+ } break;
case SDL_MOUSEMOTION:
if (event.motion.state == SDL_BUTTON_LMASK) {
if (buffer) {
@@ -327,6 +342,7 @@ int main(int argc, char **argv) {
}
if (ted_haserr(ted)) {
+ // @TODO: better error handling
die("%s", ted_geterr(ted));
}
}
@@ -389,6 +405,12 @@ int main(int argc, char **argv) {
menu_render(ted, menu);
}
+ if (ted_haserr(ted)) {
+ // @TODO: better error handling
+ die("%s", ted_geterr(ted));
+ }
+
+
#if DEBUG
buffer_check_valid(&ted->main_buffer);
buffer_check_valid(&ted->line_buffer);
diff --git a/menu.c b/menu.c
index 7c09d53..d82eb4a 100644
--- a/menu.c
+++ b/menu.c
@@ -54,10 +54,15 @@ static void menu_render(Ted *ted, Menu menu) {
rect_render_border(menu_rect, settings->border_thickness);
glEnd();
+ menu_x1 += inner_padding;
+ menu_y1 += inner_padding;
+ menu_x2 -= inner_padding;
+ menu_y2 -= inner_padding;
+
float line_buffer_height = char_height * 1.5f;
- float line_buffer_x1 = menu_x1 + inner_padding,
- line_buffer_y1 = menu_y1 + inner_padding,
- line_buffer_x2 = menu_x2 - inner_padding,
+ float line_buffer_x1 = menu_x1,
+ line_buffer_y1 = menu_y1,
+ line_buffer_x2 = menu_x2,
line_buffer_y2 = line_buffer_y1 + line_buffer_height;
buffer_render(&ted->line_buffer, line_buffer_x1, line_buffer_y1, line_buffer_x2, line_buffer_y2);
@@ -80,21 +85,47 @@ static void menu_render(Ted *ted, Menu menu) {
}
qsort(files, nfiles, sizeof *files, str_qsort_case_insensitive_cmp);
-
+ char const *file_to_open = NULL;
{ // render file names
- float x = menu_x1 + inner_padding, y = menu_y1 + line_buffer_height + inner_padding;
+ float start_x = menu_x1, start_y = line_buffer_y2 + inner_padding;
+ float x = start_x, y = start_y;
+
+ for (u32 i = 0; i < nfiles; ++i) {
+ // highlight entry user is mousing over
+ if (y >= menu_y2) break;
+ Rect r = rect4(x, y, menu_x2, minf(y + char_height, menu_y2));
+ y += char_height;
+ if (rect_contains_point(r, ted->mouse_pos)) {
+ glBegin(GL_QUADS);
+ gl_color_rgba(colors[COLOR_MENU_HL]);
+ rect_render(r);
+ glEnd();
+ }
+ for (u32 c = 0; c < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++c) {
+ if (rect_contains_point(r, ted->mouse_clicks[SDL_BUTTON_LEFT][c])) {
+ // this file got clicked on!
+ file_to_open = files[i];
+ }
+ }
+ }
+ x = start_x, y = start_y;
TextRenderState text_render_state = {.min_x = menu_x1, .max_x = menu_x2, .min_y = menu_y1, .max_y = menu_y2, .render = true};
gl_color_rgba(colors[COLOR_TEXT]);
for (u32 i = 0; i < nfiles; ++i) {
+ if (y >= menu_y2) break;
text_render_with_state(font, &text_render_state, files[i], x, y);
y += char_height;
}
}
+ if (file_to_open) {
+ ted_open_file(ted, file_to_open);
+ menu_close(ted, false);
+ }
+
for (u32 i = 0; i < nfiles; ++i) free(files[i]);
free(files);
}
free(search_term);
}
-
}
diff --git a/ted-base.c b/ted-base.c
index e00a70a..2eac197 100644
--- a/ted-base.c
+++ b/ted-base.c
@@ -2,6 +2,12 @@
#define ted_seterr(buffer, ...) \
snprintf(ted->error, sizeof ted->error - 1, __VA_ARGS__)
+void ted_seterr_to_buferr(Ted *ted, TextBuffer *buffer) {
+ size_t size = sizeof ted->error;
+ if (sizeof buffer->error < size) size = sizeof buffer->error;
+ memcpy(ted->error, buffer->error, size);
+}
+
bool ted_haserr(Ted *ted) {
return ted->error[0] != '\0';
}
@@ -80,5 +86,19 @@ static void ted_load_font(Ted *ted) {
}
}
+// returns buffer of new file
+static TextBuffer *ted_open_file(Ted *ted, char const *filename) {
+ TextBuffer *open_to = &ted->main_buffer;
+ buffer_load_file(open_to, filename);
+ if (buffer_haserr(open_to)) {
+ // @TODO: something
+ ted_seterr_to_buferr(ted, open_to);
+ return NULL;
+ } else {
+ ted->active_buffer = open_to;
+ return open_to;
+ }
+}
+
static void menu_open(Ted *ted, Menu menu);
static void menu_close(Ted *ted, bool restore_prev_active_buffer);
diff --git a/ted.cfg b/ted.cfg
index 11bfabc..2591f43 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -74,3 +74,4 @@ bg = #001
# By making it transparent, we can dim everything else while the menu is open.
menu-backdrop = #0004
menu-bg = #222
+menu-hl = #888 \ No newline at end of file
diff --git a/ted.h b/ted.h
index 36602cf..af1a2ae 100644
--- a/ted.h
+++ b/ted.h
@@ -82,6 +82,9 @@ typedef struct Ted {
TextBuffer *prev_active_buffer;
Settings settings;
float window_width, window_height;
+ 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
Menu menu;
TextBuffer line_buffer; // general-purpose line buffer for inputs -- used for menus
TextBuffer main_buffer;
diff --git a/util.c b/util.c
index 1d6bb79..8c1239c 100644
--- a/util.c
+++ b/util.c
@@ -15,10 +15,6 @@ static bool util_is_power_of_2(u64 x) {
return util_popcount(x) == 1;
}
-static void util_zero_memory(void *mem, size_t size) {
- memset(mem, 0, size);
-}
-
// for finding a character in a char32 string
static char32_t *util_mem32chr(char32_t *s, char32_t c, size_t n) {
for (size_t i = 0; i < n; ++i) {