summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buffer.c12
-rw-r--r--colors.h4
-rw-r--r--command.c67
-rw-r--r--command.h2
-rw-r--r--main.c138
-rw-r--r--ted-base.c12
-rw-r--r--ted.cfg4
-rw-r--r--ted.h9
8 files changed, 161 insertions, 87 deletions
diff --git a/buffer.c b/buffer.c
index fcd803e..3445595 100644
--- a/buffer.c
+++ b/buffer.c
@@ -1258,6 +1258,14 @@ void buffer_select_all(TextBuffer *buffer) {
buffer_select_to_pos(buffer, buffer_end_of_file(buffer));
}
+// stop selecting
+void buffer_disable_selection(TextBuffer *buffer) {
+ if (buffer->selection) {
+ buffer->cursor_pos = buffer->selection_pos;
+ buffer->selection = false;
+ }
+}
+
static void buffer_shorten_line(Line *line, u32 new_len) {
assert(line->len >= new_len);
line->len = new_len; // @OPTIMIZE(memory): decrease line capacity
@@ -1595,6 +1603,7 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
float char_width = text_font_char_width(font),
char_height = text_font_char_height(font);
float header_height = char_height;
+ Ted *ted = buffer->ted;
Settings *settings = buffer_settings(buffer);
u32 *colors = settings->colors;
@@ -1758,7 +1767,8 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
text_chars_end(font);
- { // render cursor
+ if (buffer == ted->active_buffer) {
+ // render cursor
float time_on = settings->cursor_blink_time_on;
float time_off = settings->cursor_blink_time_off;
bool is_on = true;
diff --git a/colors.h b/colors.h
index 297e6d2..c3b978d 100644
--- a/colors.h
+++ b/colors.h
@@ -7,6 +7,7 @@ ENUM_U16 {
COLOR_BORDER,
COLOR_TEXT,
COLOR_SELECTION_BG,
+ COLOR_MENU_BG,
COLOR_COUNT
} ENUM_U16_END(ColorSetting);
@@ -23,7 +24,8 @@ static ColorName const color_names[COLOR_COUNT] = {
{COLOR_CURSOR_LINE_BG, "cursor-line-bg"},
{COLOR_BORDER, "border"},
{COLOR_TEXT, "text"},
- {COLOR_SELECTION_BG, "selection-bg"}
+ {COLOR_SELECTION_BG, "selection-bg"},
+ {COLOR_MENU_BG, "menu-bg"}
};
static ColorSetting color_setting_from_str(char const *str) {
diff --git a/command.c b/command.c
index 6b99a92..00e9f94 100644
--- a/command.c
+++ b/command.c
@@ -21,6 +21,7 @@ void command_execute(Ted *ted, Command c, i64 argument) {
TextBuffer *buffer = ted->active_buffer;
Settings *settings = &ted->settings;
+
switch (c) {
case CMD_UNKNOWN:
case CMD_COUNT:
@@ -30,97 +31,100 @@ void command_execute(Ted *ted, Command c, i64 argument) {
break;
case CMD_LEFT:
- buffer_cursor_move_left(buffer, argument);
+ if (buffer) buffer_cursor_move_left(buffer, argument);
break;
case CMD_RIGHT:
- buffer_cursor_move_right(buffer, argument);
+ if (buffer) buffer_cursor_move_right(buffer, argument);
break;
case CMD_UP:
- buffer_cursor_move_up(buffer, argument);
+ if (buffer) buffer_cursor_move_up(buffer, argument);
break;
case CMD_DOWN:
- buffer_cursor_move_down(buffer, argument);
+ if (buffer) buffer_cursor_move_down(buffer, argument);
break;
case CMD_SELECT_LEFT:
- buffer_select_left(buffer, argument);
+ if (buffer) buffer_select_left(buffer, argument);
break;
case CMD_SELECT_RIGHT:
- buffer_select_right(buffer, argument);
+ if (buffer) buffer_select_right(buffer, argument);
break;
case CMD_SELECT_UP:
- buffer_select_up(buffer, argument);
+ if (buffer) buffer_select_up(buffer, argument);
break;
case CMD_SELECT_DOWN:
- buffer_select_down(buffer, argument);
+ if (buffer) buffer_select_down(buffer, argument);
break;
case CMD_LEFT_WORD:
- buffer_cursor_move_left_words(buffer, argument);
+ if (buffer) buffer_cursor_move_left_words(buffer, argument);
break;
case CMD_RIGHT_WORD:
- buffer_cursor_move_right_words(buffer, argument);
+ if (buffer) buffer_cursor_move_right_words(buffer, argument);
break;
case CMD_SELECT_LEFT_WORD:
- buffer_select_left_words(buffer, argument);
+ if (buffer) buffer_select_left_words(buffer, argument);
break;
case CMD_SELECT_RIGHT_WORD:
- buffer_select_right_words(buffer, argument);
+ if (buffer) buffer_select_right_words(buffer, argument);
break;
case CMD_START_OF_LINE:
- buffer_cursor_move_to_start_of_line(buffer);
+ if (buffer) buffer_cursor_move_to_start_of_line(buffer);
break;
case CMD_END_OF_LINE:
- buffer_cursor_move_to_end_of_line(buffer);
+ if (buffer) buffer_cursor_move_to_end_of_line(buffer);
break;
case CMD_SELECT_START_OF_LINE:
- buffer_select_to_start_of_line(buffer);
+ if (buffer) buffer_select_to_start_of_line(buffer);
break;
case CMD_SELECT_END_OF_LINE:
- buffer_select_to_end_of_line(buffer);
+ if (buffer) buffer_select_to_end_of_line(buffer);
break;
case CMD_START_OF_FILE:
- buffer_cursor_move_to_start_of_file(buffer);
+ if (buffer) buffer_cursor_move_to_start_of_file(buffer);
break;
case CMD_END_OF_FILE:
- buffer_cursor_move_to_end_of_file(buffer);
+ if (buffer) buffer_cursor_move_to_end_of_file(buffer);
break;
case CMD_SELECT_START_OF_FILE:
- buffer_select_to_start_of_file(buffer);
+ if (buffer) buffer_select_to_start_of_file(buffer);
break;
case CMD_SELECT_END_OF_FILE:
- buffer_select_to_end_of_file(buffer);
+ if (buffer) buffer_select_to_end_of_file(buffer);
break;
case CMD_SELECT_ALL:
- buffer_select_all(buffer);
+ if (buffer) buffer_select_all(buffer);
break;
case CMD_BACKSPACE:
- buffer_backspace_at_cursor(buffer, argument);
+ if (buffer) buffer_backspace_at_cursor(buffer, argument);
break;
case CMD_DELETE:
- buffer_delete_chars_at_cursor(buffer, argument);
+ if (buffer) buffer_delete_chars_at_cursor(buffer, argument);
break;
case CMD_BACKSPACE_WORD:
- buffer_backspace_words_at_cursor(buffer, argument);
+ if (buffer) buffer_backspace_words_at_cursor(buffer, argument);
break;
case CMD_DELETE_WORD:
- buffer_delete_words_at_cursor(buffer, argument);
+ if (buffer) buffer_delete_words_at_cursor(buffer, argument);
break;
case CMD_PAGE_DOWN:
- buffer_page_down(buffer, argument);
+ if (buffer) buffer_page_down(buffer, argument);
break;
case CMD_PAGE_UP:
- buffer_page_up(buffer, argument);
+ if (buffer) buffer_page_up(buffer, argument);
break;
+ case CMD_OPEN:
+ ted_menu_open(ted, MENU_OPEN);
+ break;
case CMD_SAVE:
- buffer_save(buffer);
+ if (buffer) buffer_save(buffer);
break;
case CMD_UNDO:
- buffer_undo(buffer, argument);
+ if (buffer) buffer_undo(buffer, argument);
break;
case CMD_REDO:
- buffer_redo(buffer, argument);
+ if (buffer) buffer_redo(buffer, argument);
break;
case CMD_TEXT_SIZE_INCREASE: {
@@ -137,9 +141,10 @@ void command_execute(Ted *ted, Command c, i64 argument) {
ted_load_font(ted);
}
} break;
+
}
- if (buffer_haserr(buffer)) {
+ if (buffer && buffer_haserr(buffer)) {
strncpy(ted->error, buffer_geterr(buffer), sizeof ted->error - 1);
buffer_clearerr(buffer);
}
diff --git a/command.h b/command.h
index 7744fdb..db0080e 100644
--- a/command.h
+++ b/command.h
@@ -34,6 +34,7 @@ ENUM_U16 {
CMD_BACKSPACE_WORD,
CMD_DELETE_WORD,
+ CMD_OPEN,
CMD_SAVE,
CMD_UNDO,
CMD_REDO,
@@ -78,6 +79,7 @@ static CommandName const command_names[CMD_COUNT] = {
{"delete", CMD_DELETE},
{"backspace-word", CMD_BACKSPACE_WORD},
{"delete-word", CMD_DELETE_WORD},
+ {"open", CMD_OPEN},
{"save", CMD_SAVE},
{"undo", CMD_UNDO},
{"redo", CMD_REDO},
diff --git a/main.c b/main.c
index 8175ea0..06269ab 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,5 @@
// @TODO:
-// - text size (text-size, :increase-text-size, :decrease-text-size)
-// - put stuff in UserData on windows
+// - Windows installation
#include "base.h"
no_warn_start
#if _WIN32
@@ -143,34 +142,39 @@ int main(int argc, char **argv) {
if (ted_haserr(ted))
die("Error loadng font: %s", ted_geterr(ted));
+
TextBuffer text_buffer;
- TextBuffer *buffer = &text_buffer;
- buffer_create(buffer, ted);
- ted->active_buffer = buffer;
+ {
+ TextBuffer *buffer = &text_buffer;
+ buffer_create(buffer, ted);
+ ted->active_buffer = buffer;
- char const *starting_filename = "Untitled";
-
- switch (argc) {
- case 0: case 1: break;
- case 2:
- starting_filename = argv[1];
- break;
- default:
- die("Usage: %s [filename]", argv[0]);
- break;
- }
+ char const *starting_filename = "Untitled";
+
+ switch (argc) {
+ case 0: case 1: break;
+ case 2:
+ starting_filename = argv[1];
+ break;
+ default:
+ die("Usage: %s [filename]", argv[0]);
+ break;
+ }
- if (fs_file_exists(starting_filename)) {
- buffer_load_file(buffer, starting_filename);
- if (buffer_haserr(buffer))
- die("Error loading file: %s", buffer_geterr(buffer));
- } else {
- buffer_new_file(buffer, starting_filename);
- if (buffer_haserr(buffer))
- die("Error creating file: %s", buffer_geterr(buffer));
+ if (fs_file_exists(starting_filename)) {
+ buffer_load_file(buffer, starting_filename);
+ if (buffer_haserr(buffer))
+ die("Error loading file: %s", buffer_geterr(buffer));
+ } else {
+ buffer_new_file(buffer, starting_filename);
+ if (buffer_haserr(buffer))
+ die("Error creating file: %s", buffer_geterr(buffer));
+ }
}
+ u32 *colors = settings->colors;
+
Uint32 time_at_last_frame = SDL_GetTicks();
bool quit = false;
@@ -186,6 +190,7 @@ int main(int argc, char **argv) {
Uint8 const *keyboard_state = SDL_GetKeyboardState(NULL);
while (SDL_PollEvent(&event)) {
+ TextBuffer *buffer = ted->active_buffer;
u32 key_modifier = (u32)ctrl_down << KEY_MODIFIER_CTRL_BIT
| (u32)shift_down << KEY_MODIFIER_SHIFT_BIT
| (u32)alt_down << KEY_MODIFIER_ALT_BIT;
@@ -198,25 +203,28 @@ int main(int argc, char **argv) {
// scroll with mouse wheel
Sint32 dx = event.wheel.x, dy = -event.wheel.y;
double scroll_speed = 2.5;
- buffer_scroll(buffer, dx * scroll_speed, dy * scroll_speed);
+ 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_BUTTON_LEFT: {
- BufferPos pos = {0};
- if (buffer_pixels_to_pos(buffer, V2((float)event.button.x, (float)event.button.y), &pos)) {
- if (key_modifier == KEY_MODIFIER_SHIFT) {
- buffer_select_to_pos(buffer, pos);
- } else if (key_modifier == 0) {
- buffer_cursor_move_to_pos(buffer, pos);
- switch ((event.button.clicks - 1) % 3) {
- case 0: break; // single-click
- case 1: // double-click: select word
- buffer_select_word(buffer);
- break;
- case 2: // triple-click: select line
- buffer_select_line(buffer);
- break;
+ if (buffer) {
+ BufferPos pos = {0};
+ if (buffer_pixels_to_pos(buffer, V2((float)event.button.x, (float)event.button.y), &pos)) {
+ if (key_modifier == KEY_MODIFIER_SHIFT) {
+ buffer_select_to_pos(buffer, pos);
+ } else if (key_modifier == 0) {
+ buffer_cursor_move_to_pos(buffer, pos);
+ switch ((event.button.clicks - 1) % 3) {
+ case 0: break; // single-click
+ case 1: // double-click: select word
+ buffer_select_word(buffer);
+ break;
+ case 2: // triple-click: select line
+ buffer_select_line(buffer);
+ break;
+ }
}
}
}
@@ -225,9 +233,11 @@ int main(int argc, char **argv) {
break;
case SDL_MOUSEMOTION:
if (event.motion.state == SDL_BUTTON_LMASK) {
- BufferPos pos = {0};
- if (buffer_pixels_to_pos(buffer, V2((float)event.button.x, (float)event.button.y), &pos)) {
- buffer_select_to_pos(buffer, pos);
+ if (buffer) {
+ BufferPos pos = {0};
+ if (buffer_pixels_to_pos(buffer, V2((float)event.button.x, (float)event.button.y), &pos)) {
+ buffer_select_to_pos(buffer, pos);
+ }
}
}
break;
@@ -250,11 +260,19 @@ int main(int argc, char **argv) {
(u32)((modifier & (KMOD_LCTRL|KMOD_RCTRL)) != 0) << KEY_MODIFIER_CTRL_BIT |
(u32)((modifier & (KMOD_LSHIFT|KMOD_RSHIFT)) != 0) << KEY_MODIFIER_SHIFT_BIT |
(u32)((modifier & (KMOD_LALT|KMOD_RALT)) != 0) << KEY_MODIFIER_ALT_BIT;
+ if (key_combo == SDL_SCANCODE_ESCAPE << 3) {
+ // escape key
+ if (ted->menu) {
+ ted_menu_close(ted, true);
+ } else if (buffer) {
+ buffer_disable_selection(buffer);
+ }
+ }
if (key_combo < KEY_COMBO_COUNT) {
KeyAction *action = &ted->key_actions[key_combo];
if (action->command) {
command_execute(ted, action->command, action->argument);
- } else switch (event.key.keysym.sym) {
+ } else if (buffer) switch (event.key.keysym.sym) {
case SDLK_RETURN:
buffer_insert_char_at_cursor(buffer, U'\n');
break;
@@ -281,7 +299,8 @@ int main(int argc, char **argv) {
} break;
case SDL_TEXTINPUT: {
char *text = event.text.text;
- if (key_modifier == 0) // unfortunately, some key combinations like ctrl+minus still register as a "-" text input event
+ if (buffer
+ && key_modifier == 0) // unfortunately, some key combinations like ctrl+minus still register as a "-" text input event
buffer_insert_utf8_at_cursor(buffer, text);
} break;
}
@@ -302,19 +321,20 @@ int main(int argc, char **argv) {
time_at_last_frame = time_this_frame;
}
- if (key_modifier == KEY_MODIFIER_ALT) {
+ TextBuffer *active_buffer = ted->active_buffer;
+ if (active_buffer && key_modifier == KEY_MODIFIER_ALT) {
// alt + arrow keys to scroll
double scroll_speed = 20.0;
double scroll_amount_x = scroll_speed * frame_dt * 1.5; // characters are taller than they are wide
double scroll_amount_y = scroll_speed * frame_dt;
if (keyboard_state[SDL_SCANCODE_UP])
- buffer_scroll(buffer, 0, -scroll_amount_y);
+ buffer_scroll(active_buffer, 0, -scroll_amount_y);
if (keyboard_state[SDL_SCANCODE_DOWN])
- buffer_scroll(buffer, 0, +scroll_amount_y);
+ buffer_scroll(active_buffer, 0, +scroll_amount_y);
if (keyboard_state[SDL_SCANCODE_LEFT])
- buffer_scroll(buffer, -scroll_amount_x, 0);
+ buffer_scroll(active_buffer, -scroll_amount_x, 0);
if (keyboard_state[SDL_SCANCODE_RIGHT])
- buffer_scroll(buffer, +scroll_amount_x, 0);
+ buffer_scroll(active_buffer, +scroll_amount_x, 0);
}
@@ -339,17 +359,27 @@ int main(int argc, char **argv) {
{
float x1 = 50, y1 = 50, x2 = window_widthf-50, y2 = window_heightf-50;
- buffer_render(buffer, x1, y1, x2, y2);
+ buffer_render(&text_buffer, x1, y1, x2, y2);
if (text_has_err()) {
die("Text error: %s\n", text_get_err());
break;
}
}
+ if (ted->menu) {
+ glBegin(GL_QUADS);
+ gl_color_rgba(colors[COLOR_MENU_BG]);
+ rect_render(rect(V2(0, 0), V2(window_widthf, window_heightf)));
+ glEnd();
+ switch (ted->menu) {
+ case MENU_NONE: assert(0); break;
+ case MENU_OPEN:
+ break;
+ }
+ }
+
#if DEBUG
- //buffer_print_debug(buffer);
- buffer_check_valid(buffer);
- //buffer_print_undo_history(buffer);
+ buffer_check_valid(&text_buffer);
#endif
SDL_GL_SwapWindow(window);
@@ -358,7 +388,7 @@ int main(int argc, char **argv) {
SDL_GL_DeleteContext(glctx);
SDL_DestroyWindow(window);
SDL_Quit();
- buffer_free(buffer);
+ buffer_free(&text_buffer);
text_font_free(ted->font);
free(ted);
#if _WIN32
diff --git a/ted-base.c b/ted-base.c
index 6ac9c5f..ca0fbbb 100644
--- a/ted-base.c
+++ b/ted-base.c
@@ -82,3 +82,15 @@ static void ted_load_font(Ted *ted) {
ted_seterr(ted, "Couldn't find font file. There is probably a problem with your ted installation.");
}
}
+
+static void ted_menu_open(Ted *ted, Menu menu) {
+ ted->menu = menu;
+ ted->prev_active_buffer = ted->active_buffer;
+ ted->active_buffer = NULL;
+}
+
+static void ted_menu_close(Ted *ted, bool restore_prev_active_buffer) {
+ ted->menu = MENU_NONE;
+ if (restore_prev_active_buffer) ted->active_buffer = ted->prev_active_buffer;
+ ted->prev_active_buffer = NULL;
+}
diff --git a/ted.cfg b/ted.cfg
index 6573872..f18dc12 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -51,6 +51,7 @@ PageDown = :page-down
Ctrl+PageUp = 10 :page-up
Ctrl+PageDown = 10 :page-down
+Ctrl+o = :open
Ctrl+s = :save
Ctrl+z = :undo
Ctrl+Shift+z = :redo
@@ -65,3 +66,6 @@ cursor = #3ff
selection-bg = #36aa
text = #fff
bg = #001
+# The entire screen gets filled with this color when a menu (e.g. the "open" menu) is shown.
+# By making it transparent, we can dim everything else while the menu is open.
+menu-bg = #0004
diff --git a/ted.h b/ted.h
index 0f5b72c..8c475a9 100644
--- a/ted.h
+++ b/ted.h
@@ -65,10 +65,19 @@ typedef struct {
BufferEdit *redo_history; // dynamic array of redo history
} TextBuffer;
+ENUM_U16 {
+ MENU_NONE,
+ MENU_OPEN
+} ENUM_U16_END(Menu);
+
typedef struct Ted {
Font *font;
TextBuffer *active_buffer;
+ // while a menu or something is open, there is no active buffer. when the menu is closed,
+ // the old active buffer needs to be restored. that's what this stores.
+ TextBuffer *prev_active_buffer;
Settings settings;
+ Menu menu;
KeyAction key_actions[KEY_COMBO_COUNT];
char error[256];
} Ted;