summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xnote.c159
1 files changed, 98 insertions, 61 deletions
diff --git a/xnote.c b/xnote.c
index 0d7f546..06afd69 100644
--- a/xnote.c
+++ b/xnote.c
@@ -26,11 +26,12 @@ struct note {
};
enum event {
- EVENT_IDLE,
+ EVENT_START,
EVENT_START_LINE,
EVENT_END_LINE,
EVENT_START_NOTE,
EVENT_MOUSE_MOVE,
+ EVENT_MOUSE_DRAG,
};
static struct line *lines = NULL;
@@ -45,9 +46,17 @@ static enum event *events = NULL;
static size_t event_count = 0;
static size_t event_cap = 0;
+static double canvas_x = 0;
+static double canvas_y = 0;
+
static double cursor_x = 0;
static double cursor_y = 0;
+static double drag_canvas_x = 0;
+static double drag_canvas_y = 0;
+static double drag_cursor_x = 0;
+static double drag_cursor_y = 0;
+
static int window_width = 0;
static int window_height = 0;
@@ -114,29 +123,42 @@ push_event(enum event event)
*slot = event;
}
-static void
+static enum event
pop_event(void)
{
- while (event_count > 0) {
- event_count -= 1;
- enum event event = events[event_count];
- switch (event) {
+ event_count -= 1;
+ enum event event = events[event_count];
+ switch (event) {
+ case EVENT_START_LINE:
+ line_count -= 1;
+ free(lines[line_count].points);
+ break;
+ case EVENT_START_NOTE:
+ note_count -= 1;
+ free(notes[note_count].text);
+ break;
+ case EVENT_START:
+ event_count += 1;
+ break;
+ default:
+ break;
+ }
+ return event;
+}
+
+static void
+undo(void)
+{
+ while (1) {
+ switch (pop_event()) {
case EVENT_START_LINE:
- line_count -= 1;
- free(lines[line_count].points);
- goto exit;
case EVENT_START_NOTE:
- note_count -= 1;
- free(notes[note_count].text);
- goto exit;
- case EVENT_IDLE:
- event_count += 1;
+ case EVENT_START:
goto exit;
default:
- break;
+ continue;
}
}
-
exit:
shrink(&events, event_count, &event_cap, sizeof(enum event));
}
@@ -172,8 +194,11 @@ mouse_move_cb(GLFWwindow *window, double x, double y)
}
struct point *point = append(&line->points,
&line->count, &line->cap, sizeof(struct point));
- point->x = cursor_x;
- point->y = cursor_y;
+ point->x = canvas_x + cursor_x;
+ point->y = canvas_y + cursor_y;
+ } else if (last_event() == EVENT_MOUSE_DRAG) {
+ canvas_x = drag_canvas_x - (cursor_x - drag_cursor_x);
+ canvas_y = drag_canvas_y - (cursor_y - drag_cursor_y);
} else if (last_event() != EVENT_MOUSE_MOVE) {
push_event(EVENT_MOUSE_MOVE);
}
@@ -182,24 +207,34 @@ mouse_move_cb(GLFWwindow *window, double x, double y)
static void
mouse_press_cb(GLFWwindow *window, int button, int action, int mods)
{
- if (button != GLFW_MOUSE_BUTTON_LEFT) return;
-
- if (action == GLFW_PRESS) {
- struct line *line = append(&lines,
- &line_count, &line_cap, sizeof(struct line));
- line->count = line->cap = 0;
- line->points = NULL;
- struct point *point = append(&line->points,
- &line->count, &line->cap, sizeof(struct point));
- point->x = cursor_x;
- point->y = cursor_y;
- push_event(EVENT_START_LINE);
- } else if (action == GLFW_RELEASE) {
- if (last_event() == EVENT_START_LINE) {
- struct line *line = &lines[line_count-1];
- shrink(&line->points, line->count,
- &line->cap, sizeof(struct point));
- push_event(EVENT_END_LINE);
+ if (button == GLFW_MOUSE_BUTTON_LEFT) {
+ if (action == GLFW_PRESS) {
+ struct line *line = append(&lines,
+ &line_count, &line_cap, sizeof(struct line));
+ line->count = line->cap = 0;
+ line->points = NULL;
+ struct point *point = append(&line->points,
+ &line->count, &line->cap, sizeof(struct point));
+ point->x = canvas_x + cursor_x;
+ point->y = canvas_y + cursor_y;
+ push_event(EVENT_START_LINE);
+ } else if (action == GLFW_RELEASE) {
+ if (last_event() == EVENT_START_LINE) {
+ struct line *line = &lines[line_count-1];
+ shrink(&line->points, line->count,
+ &line->cap, sizeof(struct point));
+ push_event(EVENT_END_LINE);
+ }
+ }
+ } else if (button == GLFW_MOUSE_BUTTON_RIGHT) {
+ if (action == GLFW_PRESS) {
+ drag_canvas_x = canvas_x;
+ drag_canvas_y = canvas_y;
+ drag_cursor_x = cursor_x;
+ drag_cursor_y = cursor_y;
+ push_event(EVENT_MOUSE_DRAG);
+ } else if (action == GLFW_RELEASE && last_event() == EVENT_MOUSE_DRAG) {
+ pop_event();
}
}
}
@@ -207,26 +242,26 @@ mouse_press_cb(GLFWwindow *window, int button, int action, int mods)
static void
key_press_cb(GLFWwindow *window, int key, int scancode, int action, int mods)
{
- if (action != GLFW_PRESS) return;
-
- if ((mods & GLFW_MOD_CONTROL) && !strcmp(glfwGetKeyName(key, scancode), "z")) {
- if (event_count) pop_event();
- } else if ((mods & GLFW_MOD_CONTROL) && !strcmp(glfwGetKeyName(key, scancode), "c")) {
- for (size_t i = 0; i < line_count; i++)
- free(lines[i].points);
- line_count = 0;
- for (size_t i = 0; i < note_count; i++)
- free(notes[i].text);
- note_count = 0;
- event_count = 0;
- } else if (key == GLFW_KEY_BACKSPACE && last_event() == EVENT_START_NOTE) {
- if (note_count) {
- struct note *note = &notes[note_count - 1];
- if (note->len > 1) {
- note->len -= 1;
- shrink(&note->text, note->len, &note->cap, 1);
- } else if (note->len == 1) {
- pop_event();
+ if (action == GLFW_PRESS) {
+ if ((mods & GLFW_MOD_CONTROL) && !strcmp(glfwGetKeyName(key, scancode), "z")) {
+ if (event_count) undo();
+ } else if ((mods & GLFW_MOD_CONTROL) && !strcmp(glfwGetKeyName(key, scancode), "c")) {
+ for (size_t i = 0; i < line_count; i++)
+ free(lines[i].points);
+ line_count = 0;
+ for (size_t i = 0; i < note_count; i++)
+ free(notes[i].text);
+ note_count = 0;
+ event_count = 0;
+ } else if (key == GLFW_KEY_BACKSPACE && last_event() == EVENT_START_NOTE) {
+ if (note_count) {
+ struct note *note = &notes[note_count - 1];
+ if (note->len > 1) {
+ note->len -= 1;
+ shrink(&note->text, note->len, &note->cap, 1);
+ } else if (note->len == 1) {
+ pop_event();
+ }
}
}
}
@@ -242,8 +277,8 @@ key_char_cb(GLFWwindow *window, unsigned int codepoint)
struct note *note = append(&notes, &note_count, &note_cap, sizeof(struct note));
note->text = NULL;
note->len = note->cap = 0;
- note->x = cursor_x;
- note->y = cursor_y;
+ note->x = canvas_x + cursor_x;
+ note->y = canvas_y + cursor_y;
push_event(EVENT_START_NOTE);
}
@@ -318,7 +353,7 @@ main(void)
window_resize_cb(window, window_width, window_height);
- push_event(EVENT_IDLE);
+ push_event(EVENT_START);
FT_Library freetype;
FT_Face face;
@@ -354,14 +389,16 @@ main(void)
for (size_t i = 0; i < note_count; i++) {
struct note *note = &notes[i];
- draw_text(note->text, note->len, note->x, note->y);
+ draw_text(note->text, note->len,
+ note->x - canvas_x, note->y - canvas_y);
}
for (size_t i = 0; i < line_count; i++) {
struct line *line = &lines[i];
glBegin(GL_LINE_STRIP);
for (size_t k = 0; k < line->count; k++)
- glVertex2f(line->points[k].x, line->points[k].y);
+ glVertex2f(line->points[k].x - canvas_x,
+ line->points[k].y - canvas_y);
glEnd();
}