summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-02-09 09:37:41 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-02-09 09:37:41 -0500
commitf9afc00d15f934d8509f3eeb7c62b01ca84ca204 (patch)
tree779ee27d67666fd3d99794bb37a2f086e06bee6b
parent91c98a180acab2152f4c60070a4bac3a98d9d486 (diff)
improve buffer_unsaved_changes
so that making an edit then undoing it doesn't count as making a change
-rw-r--r--buffer.c23
-rw-r--r--ted.h5
-rw-r--r--ui.c27
3 files changed, 43 insertions, 12 deletions
diff --git a/buffer.c b/buffer.c
index 33ae6be..7cb1208 100644
--- a/buffer.c
+++ b/buffer.c
@@ -34,6 +34,9 @@ static void buffer_clear_redo_history(TextBuffer *buffer) {
buffer_edit_free(edit);
}
arr_clear(buffer->redo_history);
+ // if the write pos is in the redo history,
+ if (buffer->undo_history_write_pos > arr_len(buffer->undo_history))
+ buffer->undo_history_write_pos = U32_MAX; // get rid of it
}
static void buffer_clear_undo_history(TextBuffer *buffer) {
@@ -41,8 +44,13 @@ static void buffer_clear_undo_history(TextBuffer *buffer) {
buffer_edit_free(edit);
}
arr_clear(buffer->undo_history);
+ buffer->undo_history_write_pos = U32_MAX;
}
+static void buffer_clear_undo_redo(TextBuffer *buffer) {
+ buffer_clear_undo_history(buffer);
+ buffer_clear_redo_history(buffer);
+}
bool buffer_empty(TextBuffer *buffer) {
return buffer->nlines == 1 && buffer->lines[0].len == 0;
@@ -56,12 +64,6 @@ bool buffer_is_untitled(TextBuffer *buffer) {
return streq(buffer->filename, TED_UNTITLED);
}
-// clear all undo and redo events
-void buffer_clear_undo_redo(TextBuffer *buffer) {
- buffer_clear_undo_history(buffer);
- buffer_clear_redo_history(buffer);
-}
-
// add this edit to the undo history
static void buffer_append_edit(TextBuffer *buffer, BufferEdit const *edit) {
// whenever an edit is made, clear the redo history
@@ -138,7 +140,7 @@ static bool buffer_pos_valid(TextBuffer *buffer, BufferPos p) {
bool buffer_unsaved_changes(TextBuffer *buffer) {
if (buffer_is_untitled(buffer) && buffer_empty(buffer))
return false; // don't worry about empty untitled buffers
- return buffer->modified;
+ return arr_len(buffer->undo_history) != buffer->undo_history_write_pos;
}
// code point at position.
@@ -1885,11 +1887,10 @@ bool buffer_save(TextBuffer *buffer) {
if (!buffer_haserr(buffer))
buffer_seterr(buffer, "Couldn't close file %s.", buffer->filename);
}
- bool success = !buffer_haserr(buffer);
- if (success) {
- buffer->modified = false;
- }
buffer->last_write_time = time_last_modified(buffer->filename);
+ bool success = !buffer_haserr(buffer);
+ if (success)
+ buffer->undo_history_write_pos = arr_len(buffer->undo_history);
return success;
} else {
buffer_seterr(buffer, "Couldn't open file %s for writing: %s.", buffer->filename, strerror(errno));
diff --git a/ted.h b/ted.h
index 5b8d5c6..7d7f7c7 100644
--- a/ted.h
+++ b/ted.h
@@ -131,11 +131,14 @@ typedef struct {
bool is_line_buffer; // "line buffers" are buffers which can only have one line of text (used for inputs)
bool selection;
bool store_undo_events; // set to false to disable undo events
- bool modified; // has the buffer been modified since it was loaded/saved?
+ // This is set to true whenever a change is made to the buffer, and never set to false by buffer_ functions.
+ // (Distinct from buffer_unsaved_changes)
+ bool modified;
float x1, y1, x2, y2;
u32 nlines;
u32 lines_capacity;
+ u32 undo_history_write_pos; // where in the undo history was the last write? used by buffer_unsaved_changes
u32 longest_line_on_screen; // length of the longest line on screen. used to determine how far right we can scroll.
// to cache syntax highlighting properly, it is important to keep track of the
diff --git a/ui.c b/ui.c
index 49c0dc8..b743d82 100644
--- a/ui.c
+++ b/ui.c
@@ -582,6 +582,7 @@ static void popup_render(Ted *ted, u32 options, char const *title, char const *b
text_get_size(font_bold, title, &title_size.x, &title_size.y);
v2 title_pos = v2_sub(V2(window_width * 0.5f, y), V2(title_size.x * 0.5f, 0));
text_utf8(font_bold, title, title_pos.x, title_pos.y, colors[COLOR_TEXT]);
+ text_render(font_bold);
// body text
float text_x1 = rect_x1(r) + padding;
@@ -598,3 +599,29 @@ static void popup_render(Ted *ted, u32 options, char const *title, char const *b
text_render(font);
}
+
+static void checkbox_frame(Ted *ted, bool *value, char const *label, v2 pos) {
+ Font *font = ted->font;
+ float char_height = text_font_char_height(font);
+ float checkbox_size = char_height;
+ Settings const *settings = &ted->settings;
+ u32 const *colors = settings->colors;
+
+ Rect checkbox_rect = rect(pos, V2(checkbox_size, checkbox_size));
+
+ for (u32 i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) {
+ if (rect_contains_point(checkbox_rect, ted->mouse_clicks[SDL_BUTTON_LEFT][i])) {
+ *value = !*value;
+ }
+ }
+
+ if (*value)
+ gl_geometry_rect(checkbox_rect, colors[COLOR_TEXT]);
+ else
+ gl_geometry_rect_border(checkbox_rect, 1, colors[COLOR_TEXT]);
+ v2 text_pos = v2_add(pos, V2(checkbox_size, 0));
+ text_utf8(font, label, text_pos.x, text_pos.y, colors[COLOR_TEXT]);
+
+ gl_geometry_draw();
+ text_render(font);
+}