diff options
| author | Louis Burda <quent.burda@gmail.com> | 2024-08-11 21:25:32 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2024-08-11 21:25:32 +0200 |
| commit | 5b6b578d984f3c19c9e7701bba014a7fffe1aab7 (patch) | |
| tree | 5d958bc6df970a14215f3e5240401c8674f68f08 | |
| parent | 1696179a664286697fb010e58283cacf8d3b3866 (diff) | |
| download | xnote-5b6b578d984f3c19c9e7701bba014a7fffe1aab7.tar.gz xnote-5b6b578d984f3c19c9e7701bba014a7fffe1aab7.zip | |
Make canvas draggable
| -rw-r--r-- | xnote.c | 159 |
1 files changed, 98 insertions, 61 deletions
@@ -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 = ¬es[note_count - 1]; - if (note->len > 1) { - note->len -= 1; - shrink(¬e->text, note->len, ¬e->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 = ¬es[note_count - 1]; + if (note->len > 1) { + note->len -= 1; + shrink(¬e->text, note->len, ¬e->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(¬es, ¬e_count, ¬e_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 = ¬es[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(); } |
