summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c18
-rw-r--r--redr.h51
-rw-r--r--redr_raylib.c124
-rw-r--r--view.c253
-rw-r--r--view.h23
5 files changed, 390 insertions, 79 deletions
diff --git a/main.c b/main.c
index 0f1260c..8f48a88 100644
--- a/main.c
+++ b/main.c
@@ -3,6 +3,7 @@
#include "config.h"
#include "redr.h"
#include "input.h"
+#include "view.h"
#ifndef MAIN_WINDOW_TITLE
#define MAIN_WINDOW_TITLE "window"
@@ -15,24 +16,33 @@ int main(int argc, char *argv[]) {
if (argc != 2)
return 1;
- /* set log */
log_init(LOGLEVEL, stdout);
struct redr_ctx *window;
- redr_init(&window, INIT_WIDTH, INIT_HEIGHT,
- 20, 1, MAIN_WINDOW_TITLE);
+ redr_init(&window, INIT_WIDTH, INIT_HEIGHT, MAIN_WINDOW_TITLE);
struct ed_buf *eb;
eb_init(&eb);
eb_bind(eb, argv[1]);
eb_load_file(eb);
+ struct view *root;
+ view_init_root(&root, window);
+
+ view_eb_create_under(root, eb, 0, 0, (float)INIT_WIDTH/2, INIT_HEIGHT, 20, 1, 0);
+ view_eb_create_under(root, eb, (float)INIT_WIDTH / 2, 0, (float)INIT_WIDTH/2, INIT_HEIGHT, 20, 1, 0);
while (!redr_should_close(window)) {
+ redr_begin_draw(window);
+
+ /* TODO: input -> view -> eb */
input_handle_event(eb);
- redr_draw(window, eb);
+ view_draw_under(root);
+
+ redr_end_draw(window);
}
+ view_free_under(root);
redr_free(window);
eb_free(eb);
}
diff --git a/redr.h b/redr.h
index a5f8005..104a7f1 100644
--- a/redr.h
+++ b/redr.h
@@ -1,13 +1,58 @@
#pragma once
-#include "editor.h"
#include <stdbool.h>
+struct redr_color {
+ unsigned char r, g, b, a;
+};
+
+#define LIGHTGRAY (struct redr_color){ 200, 200, 200, 255 } // Light Gray
+#define GRAY (struct redr_color){ 130, 130, 130, 255 } // Gray
+#define DARKGRAY (struct redr_color){ 80, 80, 80, 255 } // Dark Gray
+#define YELLOW (struct redr_color){ 253, 249, 0, 255 } // Yellow
+#define GOLD (struct redr_color){ 255, 203, 0, 255 } // Gold
+#define ORANGE (struct redr_color){ 255, 161, 0, 255 } // Orange
+#define PINK (struct redr_color){ 255, 109, 194, 255 } // Pink
+#define RED (struct redr_color){ 230, 41, 55, 255 } // Red
+#define MAROON (struct redr_color){ 190, 33, 55, 255 } // Maroon
+#define GREEN (struct redr_color){ 0, 228, 48, 255 } // Green
+#define LIME (struct redr_color){ 0, 158, 47, 255 } // Lime
+#define DARKGREEN (struct redr_color){ 0, 117, 44, 255 } // Dark Green
+#define SKYBLUE (struct redr_color){ 102, 191, 255, 255 } // Sky Blue
+#define BLUE (struct redr_color){ 0, 121, 241, 255 } // Blue
+#define DARKBLUE (struct redr_color){ 0, 82, 172, 255 } // Dark Blue
+#define PURPLE (struct redr_color){ 200, 122, 255, 255 } // Purple
+#define VIOLET (struct redr_color){ 135, 60, 190, 255 } // Violet
+#define DARKPURPLE (struct redr_color){ 112, 31, 126, 255 } // Dark Purple
+#define BEIGE (struct redr_color){ 211, 176, 131, 255 } // Beige
+#define BROWN (struct redr_color){ 127, 106, 79, 255 } // Brown
+#define DARKBROWN (struct redr_color){ 76, 63, 47, 255 } // Dark Brown
+
+#define WHITE (struct redr_color){ 255, 255, 255, 255 } // White
+#define BLACK (struct redr_color){ 0, 0, 0, 255 } // Black
+#define BLANK (struct redr_color){ 0, 0, 0, 0 } // Blank (Transparent)
+#define MAGENTA (struct redr_color){ 255, 0, 255, 255 } // Magenta
+
+struct redr_vector2 {
+ float x, y;
+};
+
struct redr_ctx;
void redr_init(struct redr_ctx **ctxp, float width, float height,
- float font_size, float font_spacing, const char *title);
+ const char *title);
+void redr_draw_text(struct redr_ctx *ctx, const char *text,
+ int x, int y, int fontSize, struct redr_color color);
bool redr_should_close(struct redr_ctx *ctx);
+float redr_width(struct redr_ctx *ctx);
+float redr_height(struct redr_ctx *ctx);
+bool redr_is_resized(struct redr_ctx *ctx);
void redr_resize(struct redr_ctx *ctx, float width, float height);
-void redr_draw(struct redr_ctx *ctx, const struct ed_buf *eb);
+void redr_begin_draw(struct redr_ctx *ctx);
+void redr_draw_text(struct redr_ctx *ctx, const char *text,
+ int x, int y, int font_size, struct redr_color color);
+void redr_clear_background(struct redr_ctx *ctx, struct redr_color color);
+struct redr_vector2 redr_measure_text(struct redr_ctx *ctx, const char *text,
+ float font_size, float spacing);
+void redr_end_draw(struct redr_ctx *ctx);
void redr_free(struct redr_ctx *ctx);
diff --git a/redr_raylib.c b/redr_raylib.c
index 03823d2..19e66b0 100644
--- a/redr_raylib.c
+++ b/redr_raylib.c
@@ -1,22 +1,16 @@
#include <raylib.h>
+#include "redr.h"
#include "log.h"
-#include "editor.h"
#include "mem.h"
-#include <string.h>
-
-#define MIN(a, b) ((a) < (b))? (a) : (b)
-
struct redr_ctx {
/* window */
float width;
float height;
const char *title;
- /* font */
- float font_size;
- float font_spacing;
+ void *window_handle;
};
static void CustomLogCallback(int logLevel, const char *text, va_list args) {
@@ -49,27 +43,15 @@ static void CustomLogCallback(int logLevel, const char *text, va_list args) {
log_printf(red_level, "\n");
}
-static inline void draw_text_slice(int x, int y, int size, Color c,
- const struct slice sl) {
- char line[4096];
- size_t len;
- if ((len = sl.len) > sizeof (line) - 1)
- len = sizeof(line) - 1;
- memcpy(line, sl.ptr, len);
- line[len] = '\0';
- DrawText(line, x, y, size, c);
-}
-
void redr_init(struct redr_ctx **ctxp, float width, float height,
- float font_size, float font_spacing, const char *title) {
+ const char *title) {
SetTraceLogCallback(CustomLogCallback);
struct redr_ctx *ctx = mem_malloc(sizeof(struct redr_ctx));
ctx->height = height;
ctx->width = width;
ctx->title = title;
- ctx->font_size = font_size;
- ctx->font_spacing = font_spacing;
+ ctx->window_handle = GetWindowHandle();
*ctxp = ctx;
@@ -80,63 +62,61 @@ void redr_init(struct redr_ctx **ctxp, float width, float height,
bool redr_should_close(struct redr_ctx *ctx) {
return WindowShouldClose();
+ (void)ctx;
}
-void redr_resize(struct redr_ctx *ctx) {
- if (IsWindowResized()) {
- ctx->width = GetScreenWidth();
- ctx->height = GetScreenHeight();
- }
+bool redr_is_resized(struct redr_ctx *ctx) {
+ return IsWindowResized();
+ (void)ctx;
+}
+
+float redr_width(struct redr_ctx *ctx) {
+ return GetScreenWidth();
+ (void)ctx;
+}
+
+float redr_height(struct redr_ctx *ctx) {
+ return GetScreenHeight();
+ (void)ctx;
+}
+
+void redr_resize(struct redr_ctx *ctx, float width, float height) {
+ ctx->width = width;
+ ctx->height = height;
}
-void redr_draw(struct redr_ctx *ctx, const struct ed_buf *eb) {
- float font_size = ctx->font_size;
- float spacing = ctx->font_spacing;
- float font_height = MeasureTextEx(GetFontDefault(), "a", font_size, spacing).y;
+struct redr_vector2 redr_measure_text(struct redr_ctx *ctx, const char *text,
+ float font_size, float spacing) {
+ Vector2 raw = MeasureTextEx(GetFontDefault(), text, font_size, spacing);
+ struct redr_vector2 res = {.x = raw.x, .y = raw.y };
+ return res;
+ (void)ctx;
+}
+
+void redr_draw_text(struct redr_ctx *ctx, const char *text,
+ int x, int y, int font_size, struct redr_color color) {
+ DrawText(text, x, y, font_size, *(Color *)&color);
+
+ (void)ctx;
+}
+
+void redr_clear_background(struct redr_ctx *ctx, struct redr_color color) {
+ ClearBackground(*(Color *)&color);
+
+ (void)ctx;
+}
+
+void redr_begin_draw(struct redr_ctx *ctx) {
BeginDrawing();
- ClearBackground(RAYWHITE);
-
- const size_t linenum_to_draw = MIN(eb_get_line_num(eb), ctx->height / font_height);
-
-#ifdef CONFIG_DEBUG
- log_printf(RED_LOG_DEBUG,
- "[draw]: %lu lines ------\n", linenum_to_draw);
- log_printf(RED_LOG_DEBUG,
- "[draw]: cursor: (%lu, %lu) ------\n",
- eb_get_cur_col(eb), eb_get_cur_row(eb));
-#endif
-
-
- for (size_t i = 0; i <= linenum_to_draw; i++) {
- struct slice sl = {};
- eb_get_line_slice(eb, i, &sl);
-
-#ifdef CONFIG_DEBUG
- log_printf(RED_LOG_DEBUG,
- "[draw]: line %lu, ptr=%p, len=%lu\n",
- i, sl.ptr, sl.len);
-#endif
-
- if (i != eb_get_cur_row(eb)) {
- draw_text_slice(10, 10 + font_size * i,
- font_size, BLACK, sl);
- } else { /* draw cursor */
-
-#define BUFSIZE 4096
- char buf[BUFSIZE];
- size_t cur_col = eb_get_cur_col(eb);
- strncpy(buf, sl.ptr == NULL? "" : sl.ptr, MIN(sl.len, BUFSIZE));
- if (sl.len < 4096)
- buf[sl.len] = '\0';
- if (buf[cur_col] == '\0')
- buf[cur_col + 1] = '\0';
- buf[cur_col] = '_';
- DrawText(buf, 10, 10 + font_size * i,
- font_size, BLACK);
- }
- }
+
+ (void)ctx;
+}
+
+void redr_end_draw(struct redr_ctx *ctx) {
EndDrawing();
+
+ (void)ctx;
}
void redr_free(struct redr_ctx *ctx) {
diff --git a/view.c b/view.c
new file mode 100644
index 0000000..88e0815
--- /dev/null
+++ b/view.c
@@ -0,0 +1,253 @@
+#include <string.h>
+
+#include "editor.h"
+#include "redr.h"
+#include "mem.h"
+
+#include "vector.h" /* children */
+
+#define MIN(a, b) ((a) < (b))? (a) : (b)
+
+struct view; /* for defining vector first */
+
+DEFINE_VECTOR(Vec_sviewp, struct view *);
+
+struct view_ops {
+ void (*draw)(struct view *);
+ void (*destroy)(struct view *);
+};
+
+enum view_type {
+ VIEW_NONE,
+ VIEW_ROOT,
+ VIEW_EB
+};
+
+struct view {
+ enum view_type type;
+ struct redr_ctx *window; /* context of window */
+
+ /* tree */
+ struct view *parent;
+ Vec_sviewp *children;
+
+ /* geometry */
+ float posx;
+ float posy;
+ float w;
+ float h;
+
+ /* style */
+ float font_size;
+ float font_spacing;
+
+ /* action */
+ const struct view_ops *ops;
+ int dirty:1; /* re-draw only when dirty */
+};
+
+static inline void draw_text_slice(struct redr_ctx *window, int x, int y, int size,
+ struct redr_color c,
+ const struct slice sl) {
+ char line[4096];
+ size_t len;
+ if ((len = sl.len) > sizeof (line) - 1)
+ len = sizeof(line) - 1;
+ memcpy(line, sl.ptr, len);
+ line[len] = '\0';
+ redr_draw_text(window, line, x, y, size, c);
+}
+
+static void draw_root(struct view *v) {
+ redr_clear_background(v->window, WHITE);
+}
+
+const struct view_ops root_op = {
+ .draw = draw_root,
+ .destroy = NULL,
+};
+
+void view_init_root(struct view **root, struct redr_ctx *window) {
+ struct view *nroot = mem_malloc(sizeof(struct view));
+
+ nroot->type = VIEW_ROOT;
+ nroot->window = window;
+
+ nroot->parent = NULL;
+ Vec_sviewp_init(&nroot->children);
+
+ nroot->posx = 0;
+ nroot->posy = 0;
+ nroot->w = redr_width(window);
+ nroot->h = redr_height(window);
+
+ nroot->font_size = 0;
+ nroot->font_spacing = 0;
+
+ nroot->ops = &root_op;
+ nroot->dirty = 0;
+
+ *root = nroot;
+}
+
+size_t view_child_num(struct view *vw) {
+ return Vec_sviewp_len(vw->children);
+}
+
+void view_free_under(struct view *root) {
+ Vec_sviewp *s1, *s2;
+ Vec_sviewp_init(&s1);
+ Vec_sviewp_init(&s2);
+
+ /* DFS search */
+ Vec_sviewp_push(s1, root);
+ size_t len;
+ while ((len = Vec_sviewp_len(s1)) > 0) {
+ struct view *vw;
+
+ vw = Vec_sviewp_get(s1, len - 1);
+ Vec_sviewp_pop(s1);
+ Vec_sviewp_push(s2, vw);
+
+ size_t child_num = view_child_num(vw);
+ for (size_t i = 0; i < child_num; i++)
+ Vec_sviewp_push(s1, Vec_sviewp_get(vw->children, i));
+ }
+ Vec_sviewp_free(s1);
+
+ /* free with reverse order of DFS */
+ while ((len = Vec_sviewp_len(s2)) > 0) {
+ struct view *vw;
+
+ vw = Vec_sviewp_get(s2, len - 1);
+ Vec_sviewp_pop(s2);
+
+ if (vw->ops && vw->ops->destroy)
+ vw->ops->destroy(vw);
+
+ Vec_sviewp_free(vw->children);
+ mem_free(vw);
+ }
+ Vec_sviewp_free(s2);
+}
+
+void view_draw_under(struct view *root) {
+ Vec_sviewp *stack;
+ Vec_sviewp_init(&stack);
+ Vec_sviewp_push(stack, root);
+
+ size_t len;
+ while ((len = Vec_sviewp_len(stack)) > 0) {
+ struct view *vw;
+
+ vw = Vec_sviewp_get(stack, len - 1);
+ Vec_sviewp_pop(stack);
+
+ if (vw->ops && vw->ops->draw)
+ vw->ops->draw(vw);
+
+ size_t child_num = view_child_num(vw);
+ for (size_t i = 0; i < child_num; i++)
+ Vec_sviewp_push(stack, Vec_sviewp_get(vw->children, i));
+ }
+ Vec_sviewp_free(stack);
+}
+
+struct view_eb {
+ struct view base;
+ struct ed_buf *eb;
+ float scroll;
+};
+
+static void view_eb_draw(struct view *veb) {
+ struct ed_buf *eb = ((struct view_eb *)veb)->eb;
+ float scroll = ((struct view_eb *)veb)->scroll;
+
+ float font_size = veb->font_size;
+ float spacing = veb->font_spacing;
+ float font_height = redr_measure_text(veb->window, "a", font_size, spacing).y;
+
+ struct redr_ctx *window = veb->window;
+
+ const size_t linenum_to_draw = MIN(eb_get_line_num(eb), veb->h / font_height);
+
+#ifdef CONFIG_DEBUG
+ log_printf(RED_LOG_DEBUG,
+ "[draw]: %lu lines ------\n", linenum_to_draw);
+ log_printf(RED_LOG_DEBUG,
+ "[draw]: cursor: (%lu, %lu) ------\n",
+ eb_get_cur_col(eb), eb_get_cur_row(eb));
+#endif
+
+ for (size_t i = scroll; i <= linenum_to_draw + scroll; i++) {
+ struct slice sl = {};
+ eb_get_line_slice(eb, i, &sl);
+
+#ifdef CONFIG_DEBUG
+ log_printf(RED_LOG_DEBUG,
+ "[draw]: line %lu, ptr=%p, len=%lu\n",
+ i, sl.ptr, sl.len);
+#endif
+
+ if (i != eb_get_cur_row(eb)) {
+ draw_text_slice(veb->window,
+ veb->posx + 10, veb->posy + 10 + font_size * i,
+ font_size, BLACK, sl);
+ } else { /* draw cursor */
+
+#define BUFSIZE 4096
+ char buf[BUFSIZE];
+ size_t cur_col = eb_get_cur_col(eb);
+ strncpy(buf, sl.ptr == NULL? "" : sl.ptr, MIN(sl.len, BUFSIZE));
+ if (sl.len < 4096)
+ buf[sl.len] = '\0';
+ if (buf[cur_col] == '\0')
+ buf[cur_col + 1] = '\0';
+ buf[cur_col] = '_';
+ redr_draw_text(window, buf, veb->posx + 10, veb->posy + 10 + font_size * i,
+ font_size, BLACK);
+ }
+ }
+}
+
+const struct view_ops view_eb_ops = {
+ .draw = view_eb_draw,
+ .destroy = NULL
+};
+
+struct view_eb *view_eb_create_under(struct view *upper,
+ struct ed_buf *eb,
+ float posx,
+ float posy,
+ float w,
+ float h,
+ float font_size,
+ float font_spacing,
+ float scroll) {
+ struct view_eb *veb = mem_malloc(sizeof *veb);
+
+
+ ((struct view *)veb)->type = VIEW_EB;
+ ((struct view *)veb)->window = upper->window;
+
+ ((struct view *)veb)->parent = upper;
+ Vec_sviewp_init(&((struct view *)veb)->children);
+
+ ((struct view *)veb)->posx = posx;
+ ((struct view *)veb)->posy = posy;
+ ((struct view *)veb)->w = w;
+ ((struct view *)veb)->h = h;
+
+ ((struct view *)veb)->font_size = font_size;
+ ((struct view *)veb)->font_spacing = font_spacing;
+
+ ((struct view *)veb)->ops = &view_eb_ops;
+ ((struct view *)veb)->dirty = 0;
+
+ veb->eb = eb;
+ veb->scroll = scroll;
+
+ Vec_sviewp_push(upper->children, (struct view *)veb);
+
+ return veb;
+}
diff --git a/view.h b/view.h
new file mode 100644
index 0000000..d9b3ff0
--- /dev/null
+++ b/view.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <stddef.h>
+
+#include "redr.h"
+#include "editor.h"
+
+struct view;
+
+
+void view_init_root(struct view **root, struct redr_ctx *window);
+size_t view_child_num(struct view *vw);
+void view_free_under(struct view *root);
+void view_draw_under(struct view *root);
+struct view_eb *view_eb_create_under(struct view *upper,
+ struct ed_buf *eb,
+ float posx,
+ float posy,
+ float w,
+ float h,
+ float font_size,
+ float font_spacing,
+ float scroll);