summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c2
-rw-r--r--menu.c171
-rw-r--r--ted-internal.h3
-rw-r--r--ted.h2
-rw-r--r--ui.c13
5 files changed, 167 insertions, 24 deletions
diff --git a/main.c b/main.c
index 6e3f46b..5c38d1c 100644
--- a/main.c
+++ b/main.c
@@ -500,6 +500,7 @@ int main(int argc, char **argv) {
gl_geometry_init();
text_init();
+ menu_init(ted);
autocomplete_init(ted);
signature_help_init(ted);
usages_init(ted);
@@ -1197,6 +1198,7 @@ int main(int argc, char **argv) {
session_write(ted);
rename_symbol_quit(ted);
document_link_quit(ted);
+ menu_quit(ted);
for (int i = 0; i < TED_LSP_MAX; ++i) {
if (!ted->lsps[i]) break;
diff --git a/menu.c b/menu.c
index 3ec19a6..2d8ccba 100644
--- a/menu.c
+++ b/menu.c
@@ -373,6 +373,32 @@ void menu_update(Ted *ted) {
}*/
}
+static Rect selection_menu_render_bg(Ted *ted) {
+ const Settings *settings = ted_active_settings(ted);
+ const float menu_width = ted_get_menu_width(ted);
+ const float padding = settings->padding;
+ const u32 *colors = settings->colors;
+ const float window_width = ted->window_width, window_height = ted->window_height;
+ Rect bounds = rect(
+ Vec2(window_width * 0.5f - 0.5f * menu_width, padding),
+ Vec2(menu_width, window_height - 2 * padding)
+ );
+
+ float x1, y1, x2, y2;
+ rect_coords(bounds, &x1, &y1, &x2, &y2);
+
+ // menu rectangle & border
+ gl_geometry_rect(bounds, colors[COLOR_MENU_BG]);
+ gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]);
+ gl_geometry_draw();
+
+ x1 += padding;
+ y1 += padding;
+ x2 -= padding;
+ y2 -= padding;
+ return rect4(x1, y1, x2, y2);
+}
+
void menu_render(Ted *ted) {
const Settings *settings = ted_active_settings(ted);
const u32 *colors = settings->colors;
@@ -390,7 +416,6 @@ void menu_render(Ted *ted) {
const float char_height = text_font_char_height(font);
const float char_height_bold = text_font_char_height(font_bold);
const float line_buffer_height = ted_line_buffer_height(ted);
- const float padding = settings->padding;
if (*ted->warn_overwrite) {
const char *path = ted->warn_overwrite;
@@ -402,26 +427,6 @@ void menu_render(Ted *ted) {
return;
}
- const float menu_width = ted_get_menu_width(ted);
- Rect bounds = rect(
- Vec2(window_width * 0.5f - 0.5f * menu_width, padding),
- Vec2(menu_width, window_height - 2 * padding)
- );
-
- float x1, y1, x2, y2;
- rect_coords(bounds, &x1, &y1, &x2, &y2);
-
- if (menu == MENU_OPEN || menu == MENU_SAVE_AS || menu == MENU_GOTO_DEFINITION || menu == MENU_COMMAND_SELECTOR) {
- // menu rectangle & border
- gl_geometry_rect(bounds, colors[COLOR_MENU_BG]);
- gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]);
- gl_geometry_draw();
-
- x1 += padding;
- y1 += padding;
- x2 -= padding;
- y2 -= padding;
- }
switch (menu) {
@@ -586,3 +591,127 @@ void menu_shell_up(Ted *ted) {
void menu_shell_down(Ted *ted) {
menu_shell_move(ted, +1);
}
+
+static void open_menu_open(Ted *ted) {
+ ted_switch_to_buffer(ted, &ted->line_buffer);
+ ted->file_selector.create_menu = false;
+}
+
+static void open_menu_update(Ted *ted) {
+ char *selected_file = file_selector_update(ted, &ted->file_selector);
+ if (selected_file) {
+ // open that file!
+ menu_close(ted);
+ ted_open_file(ted, selected_file);
+ free(selected_file);
+ }
+}
+
+static void open_menu_render(Ted *ted) {
+ FileSelector *fs = &ted->file_selector;
+ strbuf_cpy(fs->title, "Open...");
+ fs->bounds = selection_menu_render_bg(ted);
+ file_selector_render(ted, fs);
+}
+
+static bool open_menu_close(Ted *ted) {
+ file_selector_free(&ted->file_selector);
+ buffer_clear(&ted->line_buffer);
+ return true;
+}
+
+static void save_as_menu_open(Ted *ted) {
+ ted_switch_to_buffer(ted, &ted->line_buffer);
+ ted->file_selector.create_menu = false;
+}
+
+static void save_as_menu_update(Ted *ted) {
+ if (*ted->warn_overwrite) {
+ switch (popup_update(ted, POPUP_YES_NO_CANCEL)) {
+ case POPUP_NONE:
+ // no option selected
+ break;
+ case POPUP_YES: {
+ // overwrite it!
+ TextBuffer *buffer = ted->prev_active_buffer;
+ if (buffer) {
+ buffer_save_as(buffer, ted->warn_overwrite);
+ }
+ menu_close(ted);
+ } break;
+ case POPUP_NO:
+ // back to the file selector
+ *ted->warn_overwrite = '\0';
+ ted_switch_to_buffer(ted, &ted->line_buffer);
+ break;
+ case POPUP_CANCEL:
+ // close "save as" menu
+ menu_close(ted);
+ break;
+ }
+ } else {
+ char *selected_file = file_selector_update(ted, &ted->file_selector);
+ if (selected_file) {
+ TextBuffer *buffer = ted->prev_active_buffer;
+ if (buffer) {
+ if (fs_path_type(selected_file) != FS_NON_EXISTENT) {
+ // file already exists! warn about overwriting it.
+ strbuf_cpy(ted->warn_overwrite, selected_file);
+ ted_switch_to_buffer(ted, NULL);
+ } else {
+ // create the new file.
+ buffer_save_as(buffer, selected_file);
+ menu_close(ted);
+ }
+ }
+ free(selected_file);
+ }
+ }
+}
+
+static void save_as_menu_render(Ted *ted) {
+ FileSelector *fs = &ted->file_selector;
+ strbuf_cpy(fs->title, "Save as...");
+ fs->bounds = selection_menu_render_bg(ted);
+ file_selector_render(ted, fs);
+}
+
+static bool save_as_menu_close(Ted *ted) {
+ file_selector_free(&ted->file_selector);
+ buffer_clear(&ted->line_buffer);
+ return true;
+}
+
+void menu_register(Ted *ted, const MenuInfo *infop) {
+ MenuInfo info = *infop;
+ if (!*info.name) {
+ ted_error(ted, "menu has no name");
+ return;
+ }
+ info.name[sizeof info.name - 1] = '\0';
+ arr_add(ted->all_menus, info);
+}
+
+void menu_init(Ted *ted) {
+ MenuInfo save_as_menu = {
+ .open = save_as_menu_open,
+ .update = save_as_menu_update,
+ .render = save_as_menu_render,
+ .close = save_as_menu_close,
+ };
+ strbuf_cpy(save_as_menu.name, MENU_SAVE_AS);
+ menu_register(ted, &save_as_menu);
+
+ MenuInfo open_menu = {
+ .open = open_menu_open,
+ .update = open_menu_update,
+ .render = open_menu_render,
+ .close = open_menu_close,
+ };
+ strbuf_cpy(open_menu.name, MENU_OPEN);
+ menu_register(ted, &open_menu);
+}
+
+void menu_quit(Ted *ted) {
+ arr_clear(ted->all_menus);
+}
diff --git a/ted-internal.h b/ted-internal.h
index bb76a3c..83a088d 100644
--- a/ted-internal.h
+++ b/ted-internal.h
@@ -283,6 +283,7 @@ typedef struct {
} FileEntry;
struct FileSelector {
+ char title[32];
Selector sel;
Rect bounds;
u32 n_entries;
@@ -797,6 +798,8 @@ void macro_add(Ted *ted, Command command, const CommandArgument *argument);
void macros_free(Ted *ted);
// === menu.c ===
+void menu_init(Ted *ted);
+void menu_quit(Ted *ted);
void menu_update(Ted *ted);
void menu_render(Ted *ted);
/// move to next/previous command
diff --git a/ted.h b/ted.h
index 1213724..7b9afa9 100644
--- a/ted.h
+++ b/ted.h
@@ -793,6 +793,8 @@ void macro_stop_recording(Ted *ted);
void macro_execute(Ted *ted, u32 index);
// === menu.c ===
+/// register a new menu
+void menu_register(Ted *ted, const MenuInfo *infop);
void menu_close(Ted *ted);
void menu_open(Ted *ted, const char *menu_name);
void menu_open_with_context(Ted *ted, const char *menu_name, void *context);
diff --git a/ui.c b/ui.c
index 8d98fac..e5f1666 100644
--- a/ui.c
+++ b/ui.c
@@ -119,6 +119,9 @@ void selector_render(Ted *ted, Selector *s) {
float padding = settings->padding;
Rect bounds = s->bounds;
+
+ float x1, y1, x2, y2;
+ rect_coords(bounds, &x1, &y1, &x2, &y2);
for (u32 i = 0; i < s->n_entries; ++i) {
// highlight entry user is hovering over/selecting
@@ -133,8 +136,6 @@ void selector_render(Ted *ted, Selector *s) {
}
gl_geometry_draw();
- float x1, y1, x2, y2;
- rect_coords(bounds, &x1, &y1, &x2, &y2);
// search buffer
float line_buffer_height = ted_line_buffer_height(ted);
buffer_render(&ted->line_buffer, rect4(x1, y1, x2, y1 + line_buffer_height));
@@ -491,11 +492,16 @@ void file_selector_render(Ted *ted, FileSelector *fs) {
const Settings *settings = ted_active_settings(ted);
const u32 *colors = settings->colors;
Rect bounds = fs->bounds;
- Font *font = ted->font;
+ Font *font = ted->font, *font_bold = ted->font_bold;
float padding = settings->padding;
float char_height = text_font_char_height(font);
float x1, y1, x2, y2;
rect_coords(bounds, &x1, &y1, &x2, &y2);
+
+ if (*fs->title) {
+ text_utf8(font_bold, fs->title, x1, y1, colors[COLOR_TEXT]);
+ y1 += text_font_char_height(font_bold) * 0.75f + padding;
+ }
// current working directory
text_utf8(font, fs->cwd, x1, y1, colors[COLOR_TEXT]);
@@ -525,6 +531,7 @@ void file_selector_render(Ted *ted, FileSelector *fs) {
sel->n_entries = fs->n_entries;
selector_render(ted, sel);
+ text_render(font_bold);
}
vec2 button_get_size(Ted *ted, const char *text) {