diff options
| -rw-r--r-- | main.c | 18 | ||||
| -rw-r--r-- | redr.h | 51 | ||||
| -rw-r--r-- | redr_raylib.c | 124 | ||||
| -rw-r--r-- | view.c | 253 | ||||
| -rw-r--r-- | view.h | 23 |
5 files changed, 390 insertions, 79 deletions
@@ -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); } @@ -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) { @@ -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; +} @@ -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); |
