Rename data types and start implementing drawing quads in ui
This commit is contained in:
parent
6df11cfdeb
commit
64f0328966
@ -7,28 +7,28 @@
|
|||||||
|
|
||||||
#define MAX_NODES 1024
|
#define MAX_NODES 1024
|
||||||
|
|
||||||
typedef i32 (*node_func_t)(i32 a, i32 b);
|
typedef i32 (*node_func)(i32 a, i32 b);
|
||||||
typedef enum node_type node_type_t;
|
typedef enum node_type node_type;
|
||||||
typedef union node_data node_data_t;
|
typedef union node_data node_data;
|
||||||
typedef struct node node_t;
|
typedef struct node node;
|
||||||
|
|
||||||
enum node_type {
|
enum node_type {
|
||||||
NODE_TYPE_IO,
|
NODEYPE_IO,
|
||||||
NODE_TYPE_OP,
|
NODEYPE_OP,
|
||||||
|
|
||||||
COUNT_NODE_TYPES,
|
COUNT_NODEYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
union node_data {
|
union node_data {
|
||||||
const char *path;
|
const char *path;
|
||||||
node_func_t func;
|
node_func func;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
rect_t rect;
|
rect rec;
|
||||||
ui_elem_colours_t colours;
|
ui_elem_colours colours;
|
||||||
node_type_t type;
|
node_type type;
|
||||||
node_data_t data;
|
node_data data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !NODES_H
|
#endif // !NODES_H
|
||||||
|
@ -18,7 +18,7 @@ i32 comp_sub(i32 a, i32 b);
|
|||||||
i32 comp_mul(i32 a, i32 b);
|
i32 comp_mul(i32 a, i32 b);
|
||||||
i32 comp_div(i32 a, i32 b);
|
i32 comp_div(i32 a, i32 b);
|
||||||
|
|
||||||
INTERNAL node_func_t ops[COUNT_COMP_OPS] = {
|
INTERNAL node_func ops[COUNT_COMP_OPS] = {
|
||||||
[COMP_OP_ADD] = comp_add,
|
[COMP_OP_ADD] = comp_add,
|
||||||
[COMP_OP_SUB] = comp_sub,
|
[COMP_OP_SUB] = comp_sub,
|
||||||
[COMP_OP_MUL] = comp_mul,
|
[COMP_OP_MUL] = comp_mul,
|
||||||
|
39
include/ui.h
39
include/ui.h
@ -6,7 +6,7 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define MAX_UI_ELEMENTS 4096
|
#define MAX_UI_ELEMENTS 8192
|
||||||
|
|
||||||
#define BUTTON_WIDTH 100
|
#define BUTTON_WIDTH 100
|
||||||
#define BUTTON_HEIGHT 40
|
#define BUTTON_HEIGHT 40
|
||||||
@ -14,11 +14,11 @@
|
|||||||
#define NODE_WIDTH 70
|
#define NODE_WIDTH 70
|
||||||
#define NODE_HEIGHT 20
|
#define NODE_HEIGHT 20
|
||||||
|
|
||||||
typedef enum ui_elem_type ui_elem_type_t;
|
typedef enum ui_elemype ui_elemype;
|
||||||
typedef struct ui_elem ui_elem_t;
|
typedef struct ui_elem ui_elem;
|
||||||
typedef struct ui_ctx ui_ctx_t;
|
typedef struct ui_ctx ui_ctx;
|
||||||
|
|
||||||
enum ui_elem_type {
|
enum ui_elemype {
|
||||||
UI_ELEM_NODE,
|
UI_ELEM_NODE,
|
||||||
UI_ELEM_BUTTON,
|
UI_ELEM_BUTTON,
|
||||||
|
|
||||||
@ -27,14 +27,14 @@ enum ui_elem_type {
|
|||||||
|
|
||||||
struct ui_elem {
|
struct ui_elem {
|
||||||
u64 id;
|
u64 id;
|
||||||
rect_t rect;
|
rect rect;
|
||||||
ui_elem_type_t type;
|
ui_elemype type;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ui_elem_colours ui_elem_colours_t;
|
typedef struct ui_elem_colours ui_elem_colours;
|
||||||
struct ui_elem_colours {
|
struct ui_elem_colours {
|
||||||
colour_t fill;
|
colour fill;
|
||||||
colour_t border;
|
colour border;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ui_ctx {
|
struct ui_ctx {
|
||||||
@ -47,17 +47,16 @@ struct ui_ctx {
|
|||||||
i32 rel_y;
|
i32 rel_y;
|
||||||
bool mouse_down;
|
bool mouse_down;
|
||||||
bool mouse_up;
|
bool mouse_up;
|
||||||
const window_t *wnd;
|
const window *wnd;
|
||||||
ui_elem_t elements[MAX_UI_ELEMENTS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_ui_ctx(ui_ctx_t *ctx);
|
void init_ui_ctx(ui_ctx *ctx);
|
||||||
void reset_ui_ctx(ui_ctx_t *ctx);
|
void reset_ui_ctx(ui_ctx *ctx);
|
||||||
void handle_ui_events(const window_t *wnd, ui_ctx_t *ctx,
|
void handle_ui_events(const window *wnd, ui_ctx *ctx, const SDL_Event *event);
|
||||||
const SDL_Event *event);
|
bool ui_button(const window *wnd, ui_ctx *ctx, rect rect,
|
||||||
bool button(const window_t *wnd, ui_ctx_t *ctx, rect_t rect,
|
ui_elem_colours colours);
|
||||||
ui_elem_colours_t colours);
|
rect ui_node(const window *wnd, ui_ctx *ctx, rect rect,
|
||||||
rect_t node(const window_t *wnd, ui_ctx_t *ctx, rect_t rect,
|
ui_elem_colours colours);
|
||||||
ui_elem_colours_t colours);
|
quad ui_quad(const window *wnd, ui_ctx *ctx, quad qd, ui_elem_colours colours);
|
||||||
|
|
||||||
#endif // !UI_H
|
#endif // !UI_H
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct point point_t;
|
typedef struct point point;
|
||||||
typedef struct line line_t;
|
typedef struct line line;
|
||||||
typedef struct triangle triangle_t;
|
typedef struct triangle triangle;
|
||||||
typedef struct gquad gquad_t;
|
typedef struct quad quad;
|
||||||
typedef struct rect rect_t;
|
typedef struct rect rect;
|
||||||
typedef struct window window_t;
|
typedef struct window window;
|
||||||
|
|
||||||
struct point {
|
struct point {
|
||||||
i32 x;
|
i32 x;
|
||||||
@ -20,25 +20,25 @@ struct point {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct line {
|
struct line {
|
||||||
point_t p0;
|
point p0;
|
||||||
point_t p1;
|
point p1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct triangle {
|
struct triangle {
|
||||||
point_t p0;
|
point p0;
|
||||||
point_t p1;
|
point p1;
|
||||||
point_t p2;
|
point p2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gquad {
|
struct quad {
|
||||||
point_t p0;
|
point p0;
|
||||||
point_t p1;
|
point p1;
|
||||||
point_t p2;
|
point p2;
|
||||||
point_t p3;
|
point p3;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rect {
|
struct rect {
|
||||||
point_t topleft;
|
point topleft;
|
||||||
i32 w;
|
i32 w;
|
||||||
i32 h;
|
i32 h;
|
||||||
};
|
};
|
||||||
@ -54,7 +54,7 @@ struct window {
|
|||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct colour colour_t;
|
typedef struct colour colour;
|
||||||
struct colour {
|
struct colour {
|
||||||
union {
|
union {
|
||||||
u32 abgr;
|
u32 abgr;
|
||||||
@ -62,18 +62,18 @@ struct colour {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
bool init_window(window_t *wnd, const char *title, u32 width, u32 height, i32 x,
|
bool init_window(window *wnd, const char *title, u32 width, u32 height, i32 x,
|
||||||
i32 y);
|
i32 y);
|
||||||
void cleanup_window(window_t *wnd);
|
void cleanup_window(window *wnd);
|
||||||
void clear_window(const window_t *wnd, colour_t colour);
|
void clear_window(const window *wnd, colour colour);
|
||||||
void swap_buffers(const window_t *wnd);
|
void swap_buffers(const window *wnd);
|
||||||
void draw_point(const window_t *wnd, point_t p, colour_t colour);
|
void draw_point(const window *wnd, point p, colour colour);
|
||||||
void draw_line(const window_t *wnd, const line_t *ln, colour_t colour);
|
void draw_line(const window *wnd, const line *ln, colour colour);
|
||||||
void draw_triangle(const window_t *wnd, triangle_t triangle, colour_t colour);
|
void draw_triangle(const window *wnd, triangle triangle, colour colour);
|
||||||
void fill_triangle(const window_t *wnd, triangle_t triangle, colour_t colour);
|
void fill_triangle(const window *wnd, triangle triangle, colour colour);
|
||||||
void draw_gquad(const window_t *wnd, gquad_t gquad, colour_t colour);
|
void draw_quad(const window *wnd, quad qd, colour colour);
|
||||||
void fill_gquad(const window_t *wnd, gquad_t gquad, colour_t colour);
|
void fill_quad(const window *wnd, quad qd, colour colour);
|
||||||
void draw_rect(const window_t *wnd, rect_t rect, colour_t colour);
|
void draw_rect(const window *wnd, rect rec, colour colour);
|
||||||
void fill_rect(const window_t *wnd, rect_t rect, colour_t colour);
|
void fill_rect(const window *wnd, rect rec, colour colour);
|
||||||
|
|
||||||
#endif // !WINDOW_H
|
#endif // !WINDOW_H
|
||||||
|
@ -15,35 +15,35 @@
|
|||||||
#define WINDOW_WIDTH 1280
|
#define WINDOW_WIDTH 1280
|
||||||
#define WINDOW_HEIGHT 720
|
#define WINDOW_HEIGHT 720
|
||||||
|
|
||||||
typedef struct compositor compositor_t;
|
typedef struct compositor compositor;
|
||||||
struct compositor {
|
struct compositor {
|
||||||
window_t windows[MAX_WINDOWS];
|
window windows[MAX_WINDOWS];
|
||||||
u32 active_window;
|
u32 active_window;
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
bool running;
|
bool running;
|
||||||
i64 node_hovered;
|
i64 node_hovered;
|
||||||
u64 count;
|
u64 count;
|
||||||
node_t *nodes;
|
node *nodes;
|
||||||
bool move_node;
|
bool move_node;
|
||||||
ui_ctx_t ctx;
|
ui_ctx ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
void add_node(compositor_t *comp, node_type_t type, node_data_t data, i32 x,
|
void add_node(compositor *comp, node_type type, node_data data, i32 x, i32 y,
|
||||||
i32 y, ui_elem_colours_t colours);
|
ui_elem_colours colours);
|
||||||
|
|
||||||
i32 run_main_loop(void) {
|
i32 run_main_loop(void) {
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
compositor_t comp = {0};
|
compositor comp = {0};
|
||||||
|
|
||||||
init_ui_ctx(&(comp.ctx));
|
init_ui_ctx(&(comp.ctx));
|
||||||
|
|
||||||
comp.nodes = (node_t *)malloc(sizeof(node_t) * MAX_NODES);
|
comp.nodes = (node *)malloc(sizeof(node) * MAX_NODES);
|
||||||
|
|
||||||
window_t *main_window = &(comp.windows[0]);
|
window *main_window = &(comp.windows[0]);
|
||||||
window_t *toolbox = &(comp.windows[1]);
|
window *toolbox = &(comp.windows[1]);
|
||||||
|
|
||||||
if (!init_window(main_window, "Compositor", WINDOW_WIDTH, WINDOW_HEIGHT, -1,
|
if (!init_window(main_window, "Compositor", WINDOW_WIDTH, WINDOW_HEIGHT, -1,
|
||||||
-1)) {
|
-1)) {
|
||||||
@ -60,22 +60,29 @@ i32 run_main_loop(void) {
|
|||||||
|
|
||||||
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
||||||
|
|
||||||
colour_t bg_colour = {.abgr = 0xffffffff};
|
colour bg_colour = {.abgr = 0xffffffff};
|
||||||
ui_elem_colours_t button_colours = (ui_elem_colours_t){
|
ui_elem_colours button_colours = (ui_elem_colours){
|
||||||
.fill = (colour_t){.abgr = 0xff89a83c},
|
.fill = (colour){.abgr = 0xff89a83c},
|
||||||
.border = (colour_t){.abgr = 0xff768432},
|
.border = (colour){.abgr = 0xff768432},
|
||||||
};
|
};
|
||||||
ui_elem_colours_t io_node_colours = (ui_elem_colours_t){
|
ui_elem_colours io_node_colours = (ui_elem_colours){
|
||||||
.fill = (colour_t){.abgr = 0xff2c84b7},
|
.fill = (colour){.abgr = 0xff2c84b7},
|
||||||
.border = (colour_t){.abgr = 0xff315c89},
|
.border = (colour){.abgr = 0xff315c89},
|
||||||
};
|
};
|
||||||
ui_elem_colours_t op_node_colours = (ui_elem_colours_t){
|
ui_elem_colours op_node_colours = (ui_elem_colours){
|
||||||
.fill = (colour_t){.abgr = 0xffad6c3a},
|
.fill = (colour){.abgr = 0xffad6c3a},
|
||||||
.border = (colour_t){.abgr = 0xff8e4a33},
|
.border = (colour){.abgr = 0xff8e4a33},
|
||||||
};
|
};
|
||||||
|
|
||||||
i32 toolbox_button_x = (toolbox->width - BUTTON_WIDTH) / 2;
|
i32 toolbox_button_x = (toolbox->width - BUTTON_WIDTH) / 2;
|
||||||
|
|
||||||
|
quad qd = (quad){
|
||||||
|
.p0 = (point){140, 40},
|
||||||
|
.p1 = (point){190, 40},
|
||||||
|
.p2 = (point){170, 200},
|
||||||
|
.p3 = (point){210, 200},
|
||||||
|
};
|
||||||
|
|
||||||
while (comp.running) {
|
while (comp.running) {
|
||||||
while (SDL_PollEvent(&(comp.event))) {
|
while (SDL_PollEvent(&(comp.event))) {
|
||||||
handle_ui_events(&(comp.windows[comp.active_window - 1]), &(comp.ctx),
|
handle_ui_events(&(comp.windows[comp.active_window - 1]), &(comp.ctx),
|
||||||
@ -92,10 +99,10 @@ i32 run_main_loop(void) {
|
|||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_ENTER: {
|
case SDL_WINDOWEVENT_ENTER: {
|
||||||
u32 id = comp.event.window.windowID;
|
u32 id = comp.event.window.windowID;
|
||||||
window_t *wnd = NULL;
|
window *wnd = NULL;
|
||||||
|
|
||||||
for (u64 i = 0; i < MAX_WINDOWS; ++i) {
|
for (u64 i = 0; i < MAX_WINDOWS; ++i) {
|
||||||
window_t *window = &(comp.windows[i]);
|
window *window = &(comp.windows[i]);
|
||||||
|
|
||||||
if (id == window->id) {
|
if (id == window->id) {
|
||||||
comp.active_window = id;
|
comp.active_window = id;
|
||||||
@ -117,10 +124,10 @@ i32 run_main_loop(void) {
|
|||||||
break;
|
break;
|
||||||
case SDL_DROPFILE:
|
case SDL_DROPFILE:
|
||||||
if (comp.event.drop.windowID == main_window->id) {
|
if (comp.event.drop.windowID == main_window->id) {
|
||||||
node_data_t data = (node_data_t){.path = comp.event.drop.file};
|
node_data data = (node_data){.path = comp.event.drop.file};
|
||||||
|
|
||||||
add_node(&comp, NODE_TYPE_IO, data, comp.ctx.mouse_x,
|
add_node(&comp, NODEYPE_IO, data, comp.ctx.mouse_x, comp.ctx.mouse_y,
|
||||||
comp.ctx.mouse_y, io_node_colours);
|
io_node_colours);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -132,26 +139,28 @@ i32 run_main_loop(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (u64 i = 0; i < COUNT_COMP_OPS; ++i) {
|
for (u64 i = 0; i < COUNT_COMP_OPS; ++i) {
|
||||||
rect_t rect = {
|
rect rect = {
|
||||||
.topleft.x = toolbox_button_x,
|
.topleft.x = toolbox_button_x,
|
||||||
.topleft.y = i * (BUTTON_HEIGHT + 20) + 30,
|
.topleft.y = i * (BUTTON_HEIGHT + 20) + 30,
|
||||||
.w = BUTTON_WIDTH,
|
.w = BUTTON_WIDTH,
|
||||||
.h = BUTTON_HEIGHT,
|
.h = BUTTON_HEIGHT,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (button(toolbox, &(comp.ctx), rect, button_colours)) {
|
if (ui_button(toolbox, &(comp.ctx), rect, button_colours)) {
|
||||||
node_data_t data = (node_data_t){.func = ops[i]};
|
node_data data = (node_data){.func = ops[i]};
|
||||||
|
|
||||||
add_node(&comp, NODE_TYPE_OP, data, comp.ctx.mouse_x, comp.ctx.mouse_y,
|
add_node(&comp, NODEYPE_OP, data, comp.ctx.mouse_x, comp.ctx.mouse_y,
|
||||||
op_node_colours);
|
op_node_colours);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u64 i = 0; i < comp.count; ++i) {
|
for (u64 i = 0; i < comp.count; ++i) {
|
||||||
comp.nodes[i].rect = node(main_window, &(comp.ctx), comp.nodes[i].rect,
|
comp.nodes[i].rec = ui_node(main_window, &(comp.ctx), comp.nodes[i].rec,
|
||||||
comp.nodes[i].colours);
|
comp.nodes[i].colours);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qd = ui_quad(main_window, &(comp.ctx), qd, op_node_colours);
|
||||||
|
|
||||||
for (u64 i = 0; i < MAX_WINDOWS; ++i) {
|
for (u64 i = 0; i < MAX_WINDOWS; ++i) {
|
||||||
swap_buffers(&(comp.windows[i]));
|
swap_buffers(&(comp.windows[i]));
|
||||||
}
|
}
|
||||||
@ -168,15 +177,15 @@ i32 run_main_loop(void) {
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_node(compositor_t *comp, node_type_t type, node_data_t data, i32 x,
|
void add_node(compositor *comp, node_type type, node_data data, i32 x, i32 y,
|
||||||
i32 y, ui_elem_colours_t colours) {
|
ui_elem_colours colours) {
|
||||||
if (comp->count + 1 >= MAX_NODES) {
|
if (comp->count + 1 >= MAX_NODES) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
comp->nodes[(comp->count)++] = (node_t){
|
comp->nodes[(comp->count)++] = (node){
|
||||||
.rect =
|
.rec =
|
||||||
(rect_t){
|
(rect){
|
||||||
.topleft.x = x,
|
.topleft.x = x,
|
||||||
.topleft.y = y,
|
.topleft.y = y,
|
||||||
.w = NODE_WIDTH,
|
.w = NODE_WIDTH,
|
||||||
|
155
src/ui.c
155
src/ui.c
@ -3,25 +3,24 @@
|
|||||||
#include "aliases/aliases.h"
|
#include "aliases/aliases.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
bool aabb(const ui_elem_t *elem, i32 x, i32 y) {
|
bool aabb(rect rect, i32 x, i32 y) {
|
||||||
return x > elem->rect.topleft.x && x <= elem->rect.topleft.x + elem->rect.w &&
|
return x > rect.topleft.x && x <= rect.topleft.x + rect.w &&
|
||||||
y > elem->rect.topleft.y && y <= elem->rect.topleft.y + elem->rect.h;
|
y > rect.topleft.y && y <= rect.topleft.y + rect.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_ui_ctx(ui_ctx_t *ctx) {
|
void init_ui_ctx(ui_ctx *ctx) {
|
||||||
*ctx = (ui_ctx_t){0};
|
*ctx = (ui_ctx){0};
|
||||||
ctx->hovered = -1;
|
ctx->hovered = -1;
|
||||||
ctx->active = -1;
|
ctx->active = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_ui_ctx(ui_ctx_t *ctx) {
|
void reset_ui_ctx(ui_ctx *ctx) {
|
||||||
ctx->count = 0;
|
ctx->count = 0;
|
||||||
ctx->mouse_down = false;
|
ctx->mouse_down = false;
|
||||||
ctx->mouse_up = false;
|
ctx->mouse_up = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_ui_events(const window_t *wnd, ui_ctx_t *ctx,
|
void handle_ui_events(const window *wnd, ui_ctx *ctx, const SDL_Event *event) {
|
||||||
const SDL_Event *event) {
|
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
if (wnd->id == event->motion.windowID) {
|
if (wnd->id == event->motion.windowID) {
|
||||||
@ -52,36 +51,32 @@ void handle_ui_events(const window_t *wnd, ui_ctx_t *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool button(const window_t *wnd, ui_ctx_t *ctx, rect_t rect,
|
bool ui_button(const window *wnd, ui_ctx *ctx, rect rec,
|
||||||
ui_elem_colours_t colours) {
|
ui_elem_colours colours) {
|
||||||
if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
|
if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_elem_t elem = (ui_elem_t){
|
u64 id = (ctx->count)++;
|
||||||
.id = (ctx->count)++,
|
|
||||||
.rect = rect,
|
|
||||||
.type = UI_ELEM_BUTTON,
|
|
||||||
};
|
|
||||||
|
|
||||||
fill_rect(wnd, rect, colours.fill);
|
fill_rect(wnd, rec, colours.fill);
|
||||||
draw_rect(wnd, rect, colours.border);
|
draw_rect(wnd, rec, colours.border);
|
||||||
|
|
||||||
if (wnd != ctx->wnd || (ctx->active >= 0 && ctx->active != elem.id)) {
|
if (wnd != ctx->wnd || (ctx->active >= 0 && ctx->active != id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aabb(&elem, ctx->mouse_x, ctx->mouse_y)) {
|
if (!aabb(rec, ctx->mouse_x, ctx->mouse_y)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->hovered = elem.id;
|
ctx->hovered = id;
|
||||||
|
|
||||||
if (ctx->mouse_down) {
|
if (ctx->mouse_down) {
|
||||||
ctx->active = elem.id;
|
ctx->active = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->mouse_up && ctx->hovered == elem.id && ctx->active == elem.id) {
|
if (ctx->mouse_up && ctx->hovered == id && ctx->active == id) {
|
||||||
ctx->hovered = ctx->active = -1;
|
ctx->hovered = ctx->active = -1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -89,51 +84,119 @@ bool button(const window_t *wnd, ui_ctx_t *ctx, rect_t rect,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rect_t node(const window_t *wnd, ui_ctx_t *ctx, rect_t rect,
|
rect ui_node(const window *wnd, ui_ctx *ctx, rect rec,
|
||||||
ui_elem_colours_t colours) {
|
ui_elem_colours colours) {
|
||||||
if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
|
if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
|
||||||
return (rect_t){0};
|
return (rect){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_elem_t elem = (ui_elem_t){
|
u64 id = (ctx->count)++;
|
||||||
.id = (ctx->count)++,
|
|
||||||
.rect = rect,
|
|
||||||
.type = UI_ELEM_NODE,
|
|
||||||
};
|
|
||||||
|
|
||||||
fill_rect(wnd, rect, colours.fill);
|
fill_rect(wnd, rec, colours.fill);
|
||||||
draw_rect(wnd, rect, colours.border);
|
draw_rect(wnd, rec, colours.border);
|
||||||
|
|
||||||
if (wnd != ctx->wnd || (ctx->active >= 0 && ctx->active != elem.id)) {
|
if (wnd != ctx->wnd || (ctx->active >= 0 && ctx->active != id)) {
|
||||||
return rect;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->mouse_up) {
|
if (ctx->mouse_up) {
|
||||||
ctx->hovered = ctx->active = -1;
|
ctx->hovered = ctx->active = -1;
|
||||||
ctx->rel_x = ctx->rel_y = 0;
|
ctx->rel_x = ctx->rel_y = 0;
|
||||||
return rect;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->hovered == elem.id && ctx->active == elem.id) {
|
if (ctx->hovered == id && ctx->active == id) {
|
||||||
return (rect_t){
|
return (rect){
|
||||||
.topleft.x = ctx->mouse_x + ctx->rel_x,
|
.topleft.x = ctx->mouse_x + ctx->rel_x,
|
||||||
.topleft.y = ctx->mouse_y + ctx->rel_y,
|
.topleft.y = ctx->mouse_y + ctx->rel_y,
|
||||||
.w = rect.w,
|
.w = rec.w,
|
||||||
.h = rect.h,
|
.h = rec.h,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aabb(&elem, ctx->mouse_x, ctx->mouse_y)) {
|
if (!aabb(rec, ctx->mouse_x, ctx->mouse_y)) {
|
||||||
return rect;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->hovered = elem.id;
|
ctx->hovered = id;
|
||||||
|
|
||||||
if (ctx->mouse_down) {
|
if (ctx->mouse_down) {
|
||||||
ctx->active = elem.id;
|
ctx->active = id;
|
||||||
ctx->rel_x = rect.topleft.x - ctx->mouse_x;
|
ctx->rel_x = rec.topleft.x - ctx->mouse_x;
|
||||||
ctx->rel_y = rect.topleft.y - ctx->mouse_y;
|
ctx->rel_y = rec.topleft.y - ctx->mouse_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rect;
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
quad ui_quad(const window *wnd, ui_ctx *ctx, quad qd, ui_elem_colours colours) {
|
||||||
|
if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
|
||||||
|
return (quad){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 id = (ctx->count)++;
|
||||||
|
|
||||||
|
fill_quad(wnd, qd, colours.fill);
|
||||||
|
|
||||||
|
if (wnd != ctx->wnd || (ctx->active >= 0 && ctx->active != id)) {
|
||||||
|
return qd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->mouse_up) {
|
||||||
|
ctx->hovered = ctx->active = -1;
|
||||||
|
ctx->rel_x = ctx->rel_y = 0;
|
||||||
|
return qd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->hovered == id && ctx->active == id) {
|
||||||
|
return (quad){
|
||||||
|
.p0 = (point){ctx->mouse_x - qd.p0.x + ctx->rel_x,
|
||||||
|
ctx->mouse_y - qd.p0.y + ctx->rel_y},
|
||||||
|
.p1 = (point){ctx->mouse_x - qd.p1.x + ctx->rel_x,
|
||||||
|
ctx->mouse_y - qd.p1.y + ctx->rel_y},
|
||||||
|
.p2 = (point){ctx->mouse_x - qd.p2.x + ctx->rel_x,
|
||||||
|
ctx->mouse_y - qd.p2.y + ctx->rel_y},
|
||||||
|
.p3 = (point){ctx->mouse_x - qd.p3.x + ctx->rel_x,
|
||||||
|
ctx->mouse_y - qd.p3.y + ctx->rel_y},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 _min_x_1 = qd.p0.x < qd.p1.x ? qd.p0.x : qd.p1.x;
|
||||||
|
i32 _min_x_2 = qd.p2.x < qd.p3.x ? qd.p2.x : qd.p3.x;
|
||||||
|
i32 min_x = _min_x_1 < _min_x_2 ? _min_x_1 : _min_x_2;
|
||||||
|
|
||||||
|
i32 _max_x_1 = qd.p0.x > qd.p1.x ? qd.p0.x : qd.p1.x;
|
||||||
|
i32 _max_x_2 = qd.p2.x > qd.p3.x ? qd.p2.x : qd.p3.x;
|
||||||
|
i32 max_x = _max_x_1 > _max_x_2 ? _max_x_1 : _max_x_2;
|
||||||
|
|
||||||
|
i32 _min_y_1 = qd.p0.y < qd.p1.y ? qd.p0.y : qd.p1.y;
|
||||||
|
i32 _min_y_2 = qd.p2.y < qd.p3.y ? qd.p2.y : qd.p3.y;
|
||||||
|
i32 min_y = _min_y_1 < _min_y_2 ? _min_y_1 : _min_y_2;
|
||||||
|
|
||||||
|
i32 _max_y_1 = qd.p0.y > qd.p1.y ? qd.p0.y : qd.p1.y;
|
||||||
|
i32 _max_y_2 = qd.p2.y > qd.p3.y ? qd.p2.y : qd.p3.y;
|
||||||
|
i32 max_y = _max_y_1 > _max_y_2 ? _max_y_1 : _max_y_2;
|
||||||
|
|
||||||
|
rect rec = (rect){
|
||||||
|
.topleft.x = min_x,
|
||||||
|
.topleft.y = min_y,
|
||||||
|
.w = max_x - min_x,
|
||||||
|
.h = max_y - min_y,
|
||||||
|
};
|
||||||
|
|
||||||
|
draw_rect(wnd, rec, (colour){.abgr = 0xff000000});
|
||||||
|
|
||||||
|
if (!aabb(rec, ctx->mouse_x, ctx->mouse_y)) {
|
||||||
|
return qd;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->hovered = id;
|
||||||
|
|
||||||
|
if (ctx->mouse_down) {
|
||||||
|
ctx->active = id;
|
||||||
|
ctx->rel_x = qd.p0.x - ctx->mouse_x;
|
||||||
|
ctx->rel_y = qd.p0.y - ctx->mouse_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return qd;
|
||||||
}
|
}
|
||||||
|
70
src/window.c
70
src/window.c
@ -5,7 +5,7 @@
|
|||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
bool init_window(window_t *wnd, const char *title, u32 width, u32 height, i32 x,
|
bool init_window(window *wnd, const char *title, u32 width, u32 height, i32 x,
|
||||||
i32 y) {
|
i32 y) {
|
||||||
i32 pos_x = x >= 0 ? x : SDL_WINDOWPOS_CENTERED;
|
i32 pos_x = x >= 0 ? x : SDL_WINDOWPOS_CENTERED;
|
||||||
i32 pos_y = y >= 0 ? y : SDL_WINDOWPOS_CENTERED;
|
i32 pos_y = y >= 0 ? y : SDL_WINDOWPOS_CENTERED;
|
||||||
@ -26,24 +26,24 @@ bool init_window(window_t *wnd, const char *title, u32 width, u32 height, i32 x,
|
|||||||
wnd->id = SDL_GetWindowID(wnd->window);
|
wnd->id = SDL_GetWindowID(wnd->window);
|
||||||
wnd->title = title;
|
wnd->title = title;
|
||||||
|
|
||||||
i32 x_tmp = -1;
|
i32 xmp = -1;
|
||||||
i32 y_tmp = -1;
|
i32 ymp = -1;
|
||||||
SDL_GetWindowPosition(wnd->window, &x_tmp, &y_tmp);
|
SDL_GetWindowPosition(wnd->window, &xmp, &ymp);
|
||||||
|
|
||||||
wnd->x = x_tmp;
|
wnd->x = xmp;
|
||||||
wnd->y = y_tmp;
|
wnd->y = ymp;
|
||||||
|
|
||||||
i32 w_tmp = -1;
|
i32 wmp = -1;
|
||||||
i32 h_tmp = -1;
|
i32 hmp = -1;
|
||||||
SDL_GetWindowSize(wnd->window, &w_tmp, &h_tmp);
|
SDL_GetWindowSize(wnd->window, &wmp, &hmp);
|
||||||
|
|
||||||
wnd->width = w_tmp;
|
wnd->width = wmp;
|
||||||
wnd->height = h_tmp;
|
wnd->height = hmp;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_window(window_t *wnd) {
|
void cleanup_window(window *wnd) {
|
||||||
if (wnd->renderer) {
|
if (wnd->renderer) {
|
||||||
SDL_DestroyRenderer(wnd->renderer);
|
SDL_DestroyRenderer(wnd->renderer);
|
||||||
wnd->renderer = NULL;
|
wnd->renderer = NULL;
|
||||||
@ -57,32 +57,32 @@ void cleanup_window(window_t *wnd) {
|
|||||||
wnd->width = wnd->height = wnd->id = 0;
|
wnd->width = wnd->height = wnd->id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_colour(const window_t *wnd, colour_t colour) {
|
void set_colour(const window *wnd, colour colour) {
|
||||||
SDL_SetRenderDrawColor(wnd->renderer, colour.colour.r, colour.colour.g,
|
SDL_SetRenderDrawColor(wnd->renderer, colour.colour.r, colour.colour.g,
|
||||||
colour.colour.b, colour.colour.a);
|
colour.colour.b, colour.colour.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_window(const window_t *wnd, colour_t colour) {
|
void clear_window(const window *wnd, colour colour) {
|
||||||
set_colour(wnd, colour);
|
set_colour(wnd, colour);
|
||||||
SDL_RenderClear(wnd->renderer);
|
SDL_RenderClear(wnd->renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap_buffers(const window_t *wnd) { SDL_RenderPresent(wnd->renderer); }
|
void swap_buffers(const window *wnd) { SDL_RenderPresent(wnd->renderer); }
|
||||||
|
|
||||||
void draw_point(const window_t *wnd, point_t p, colour_t colour) {
|
void draw_point(const window *wnd, point p, colour colour) {
|
||||||
set_colour(wnd, colour);
|
set_colour(wnd, colour);
|
||||||
SDL_RenderDrawPoint(wnd->renderer, p.x, p.y);
|
SDL_RenderDrawPoint(wnd->renderer, p.x, p.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_line(const window_t *wnd, const line_t *ln, colour_t colour) {
|
void draw_line(const window *wnd, const line *ln, colour colour) {
|
||||||
set_colour(wnd, colour);
|
set_colour(wnd, colour);
|
||||||
SDL_RenderDrawLine(wnd->renderer, ln->p0.x, ln->p0.y, ln->p1.x, ln->p1.y);
|
SDL_RenderDrawLine(wnd->renderer, ln->p0.x, ln->p0.y, ln->p1.x, ln->p1.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_triangle(const window_t *wnd, triangle_t triangle, colour_t colour) {
|
void draw_triangle(const window *wnd, triangle triangle, colour colour) {
|
||||||
line_t ln0 = {triangle.p0, triangle.p1};
|
line ln0 = {triangle.p0, triangle.p1};
|
||||||
line_t ln1 = {triangle.p0, triangle.p2};
|
line ln1 = {triangle.p0, triangle.p2};
|
||||||
line_t ln2 = {triangle.p1, triangle.p2};
|
line ln2 = {triangle.p1, triangle.p2};
|
||||||
|
|
||||||
draw_line(wnd, &ln0, colour);
|
draw_line(wnd, &ln0, colour);
|
||||||
draw_line(wnd, &ln1, colour);
|
draw_line(wnd, &ln1, colour);
|
||||||
@ -103,7 +103,7 @@ INTERNAL inline i32 half_space(i32 x1, i32 x2, i32 y1, i32 y2, i32 x, i32 y) {
|
|||||||
return (x2 - x1) * (y - y1) - (y2 - y1) * (x - x1);
|
return (x2 - x1) * (y - y1) - (y2 - y1) * (x - x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_triangle(const window_t *wnd, triangle_t triangle, colour_t colour) {
|
void fill_triangle(const window *wnd, triangle triangle, colour colour) {
|
||||||
// Basic triangle filling algorithm from
|
// Basic triangle filling algorithm from
|
||||||
// https://web.archive.org/web/20050408192410/http://sw-shader.sourceforge.net/rasterizer.html
|
// https://web.archive.org/web/20050408192410/http://sw-shader.sourceforge.net/rasterizer.html
|
||||||
i32 x1 = triangle.p0.x;
|
i32 x1 = triangle.p0.x;
|
||||||
@ -125,17 +125,17 @@ void fill_triangle(const window_t *wnd, triangle_t triangle, colour_t colour) {
|
|||||||
if (half_space(x2, x1, y2, y1, x, y) >= 0 &&
|
if (half_space(x2, x1, y2, y1, x, y) >= 0 &&
|
||||||
half_space(x3, x2, y3, y2, x, y) >= 0 &&
|
half_space(x3, x2, y3, y2, x, y) >= 0 &&
|
||||||
half_space(x1, x3, y1, y3, x, y) >= 0) {
|
half_space(x1, x3, y1, y3, x, y) >= 0) {
|
||||||
draw_point(wnd, (point_t){x, y}, colour);
|
draw_point(wnd, (point){x, y}, colour);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_gquad(const window_t *wnd, gquad_t gquad, colour_t colour) {
|
void draw_quad(const window *wnd, quad qd, colour colour) {
|
||||||
line_t l0 = (line_t){gquad.p0, gquad.p1};
|
line l0 = (line){qd.p0, qd.p1};
|
||||||
line_t l1 = (line_t){gquad.p1, gquad.p3};
|
line l1 = (line){qd.p1, qd.p3};
|
||||||
line_t l2 = (line_t){gquad.p3, gquad.p2};
|
line l2 = (line){qd.p3, qd.p2};
|
||||||
line_t l3 = (line_t){gquad.p2, gquad.p0};
|
line l3 = (line){qd.p2, qd.p0};
|
||||||
|
|
||||||
draw_line(wnd, &l0, colour);
|
draw_line(wnd, &l0, colour);
|
||||||
draw_line(wnd, &l1, colour);
|
draw_line(wnd, &l1, colour);
|
||||||
@ -143,26 +143,26 @@ void draw_gquad(const window_t *wnd, gquad_t gquad, colour_t colour) {
|
|||||||
draw_line(wnd, &l3, colour);
|
draw_line(wnd, &l3, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_gquad(const window_t *wnd, gquad_t gquad, colour_t colour) {
|
void fill_quad(const window *wnd, quad qd, colour colour) {
|
||||||
triangle_t t0 = (triangle_t){gquad.p3, gquad.p1, gquad.p0};
|
triangle t0 = (triangle){qd.p3, qd.p1, qd.p0};
|
||||||
triangle_t t1 = (triangle_t){gquad.p0, gquad.p2, gquad.p3};
|
triangle t1 = (triangle){qd.p0, qd.p2, qd.p3};
|
||||||
|
|
||||||
fill_triangle(wnd, t0, colour);
|
fill_triangle(wnd, t0, colour);
|
||||||
fill_triangle(wnd, t1, colour);
|
fill_triangle(wnd, t1, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_rect(const window_t *wnd, rect_t rect, colour_t colour) {
|
void draw_rect(const window *wnd, rect rec, colour colour) {
|
||||||
set_colour(wnd, colour);
|
set_colour(wnd, colour);
|
||||||
|
|
||||||
SDL_Rect dst = {rect.topleft.x, rect.topleft.y, rect.w, rect.h};
|
SDL_Rect dst = {rec.topleft.x, rec.topleft.y, rec.w, rec.h};
|
||||||
|
|
||||||
SDL_RenderDrawRect(wnd->renderer, &dst);
|
SDL_RenderDrawRect(wnd->renderer, &dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_rect(const window_t *wnd, rect_t rect, colour_t colour) {
|
void fill_rect(const window *wnd, rect rec, colour colour) {
|
||||||
set_colour(wnd, colour);
|
set_colour(wnd, colour);
|
||||||
|
|
||||||
SDL_Rect dst = {rect.topleft.x, rect.topleft.y, rect.w, rect.h};
|
SDL_Rect dst = {rec.topleft.x, rec.topleft.y, rec.w, rec.h};
|
||||||
|
|
||||||
SDL_RenderFillRect(wnd->renderer, &dst);
|
SDL_RenderFillRect(wnd->renderer, &dst);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user