zephr/ui: introduce IDs to ui elements to track the active element

This commit is contained in:
2024-01-08 05:55:58 +02:00
parent 56a6ace875
commit 0b89bf2390
6 changed files with 212 additions and 130 deletions
+30
View File
@@ -31,3 +31,33 @@ _Noreturn uintptr_t _core_abort(const char* file, int line, const char* message,
/* fprintf(stderr, "stacktrace:\n%s\n\n", stacktrace); */ /* fprintf(stderr, "stacktrace:\n%s\n\n", stacktrace); */
abort(); abort();
} }
///////////////////////////
//
//
// Hash
//
//
///////////////////////////
u32 core_fnv_hash32(const void* bytes, uptr size, u32 hash) {
const u8* b = bytes;
for (uptr idx = 0; idx < size; idx++) {
hash ^= b[idx];
hash *= CORE_FNV_HASH32_PRIME;
}
return hash;
}
u64 core_fnv_hash64(const void* bytes, uptr size, u64 hash) {
const u8* b = bytes;
for(uptr idx = 0; idx < size; idx++) {
hash ^= b[idx];
hash *= CORE_FNV_HASH64_PRIME;
}
return hash;
}
+18
View File
@@ -124,3 +124,21 @@ _Noreturn uintptr_t _core_abort(const char* file, int line, const char* message,
/* return (bool)(bitset[bit_idx >> 6] & (1 << (bit_idx & 63))); */ /* return (bool)(bitset[bit_idx >> 6] & (1 << (bit_idx & 63))); */
/* } */ /* } */
///////////////////////////
//
//
// Hash
//
//
///////////////////////////
#define CORE_FNV_HASH32_INIT 0x811c9dc5
#define CORE_FNV_HASH32_PRIME 0x01000193
#define CORE_FNV_HASH64_INIT 0xcbf29ce484222325
#define CORE_FNV_HASH64_PRIME 0x00000100000001B3
u32 core_fnv_hash32(const void* bytes, uptr size, u32 hash);
u64 core_fnv_hash64(const void* bytes, uptr size, u64 hash);
-32
View File
@@ -28,38 +28,6 @@ const Vec2 neighbors[4] = {
// //
/////////////////////////////////// ///////////////////////////////////
void print_board() {
printf("Board:\n");
for (int i = 0; i < 4; i++) {
printf(" ");
for (int j = 0; j < 4; j++) {
printf("%d ", game.board[i][j].value);
}
printf("\n");
}
}
void print_merge_status() {
printf("Merge Board:\n");
for (int i = 0; i < 4; i++) {
printf(" ");
for (int j = 0; j < 4; j++) {
printf("%d ", game.board[i][j].merged);
}
printf("\n");
}
}
void print_new_board() {
printf("New Board:\n");
for (int i = 0; i < 4; i++) {
printf(" ");
for (int j = 0; j < 4; j++) {
printf("%d ", game.board[i][j].new_value);
}
printf("\n");
}
}
Color get_tile_color(u16 value) { Color get_tile_color(u16 value) {
switch (value) { switch (value) {
+153 -87
View File
@@ -1,10 +1,12 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <glad/glx.h> #include <glad/glx.h>
#include <stb_image.h> #include <stb_image.h>
#include "shader.h" #include "shader.h"
#include "ui.h"
#include "zephr.h" #include "zephr.h"
Shader ui_shader; Shader ui_shader;
@@ -388,7 +390,10 @@ void draw_texture(UIConstraints *constraints, const TextureId texture_id, const
set_bool(ui_shader, "hasTexture", false); set_bool(ui_shader, "hasTexture", false);
} }
bool draw_button(UIConstraints *constraints, const Color color, const char *text, f32 radius, Alignment align, ButtonState state) { bool draw_button_with_location(const char *file, int line, UIConstraints *constraints, const Color color, const char *text, f32 radius, Alignment align, ButtonState state) {
UiIdHash hash = core_fnv_hash32(file, strlen(file), CORE_FNV_HASH32_INIT);
hash = core_fnv_hash32(&line, sizeof(line), hash);
Color text_color = COLOR_BLACK; Color text_color = COLOR_BLACK;
text_color.a = color.a; text_color.a = color.a;
Rect rect = {0}; Rect rect = {0};
@@ -398,6 +403,22 @@ bool draw_button(UIConstraints *constraints, const Color color, const char *text
bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos); bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos);
bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT; bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
bool left_mouse_released = zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
bool clicked = false;
if (zephr_ctx->ui.active_element == 0) {
if (is_hovered && left_mouse_pressed) {
zephr_ctx->ui.active_element = hash;
}
} else if (zephr_ctx->ui.active_element == hash) {
if (left_mouse_released) {
zephr_ctx->ui.active_element = 0;
if (is_hovered) {
clicked = true;
}
}
}
if (is_hovered && state == BUTTON_STATE_ACTIVE) { if (is_hovered && state == BUTTON_STATE_ACTIVE) {
zephr_set_cursor(ZEPHR_CURSOR_HAND); zephr_set_cursor(ZEPHR_CURSOR_HAND);
@@ -437,16 +458,19 @@ bool draw_button(UIConstraints *constraints, const Color color, const char *text
draw_text(text, font_size, text_constraints, text_color, ALIGN_CENTER); draw_text(text, font_size, text_constraints, text_color, ALIGN_CENTER);
} }
if (is_hovered && state == BUTTON_STATE_ACTIVE && zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) { if (clicked && state == BUTTON_STATE_ACTIVE) {
return true; return true;
} }
return false; return false;
} }
bool draw_icon_button(UIConstraints *constraints, Color btn_color, const TextureId icon_tex_id, f32 radius, Alignment align, ButtonState state) { bool draw_icon_button_with_location(const char *file, int line, UIConstraints *constraints, Color btn_color, const TextureId icon_tex_id, f32 radius, Alignment align, ButtonState state) {
CORE_DEBUG_ASSERT(icon_tex_id, "draw_icon_button() requires that you provide an icon texture"); CORE_DEBUG_ASSERT(icon_tex_id, "draw_icon_button() requires that you provide an icon texture");
UiIdHash hash = core_fnv_hash32(file, strlen(file), CORE_FNV_HASH32_INIT);
hash = core_fnv_hash32(&line, sizeof(line), hash);
Rect rect = {0}; Rect rect = {0};
Color icon_color = COLOR_WHITE; Color icon_color = COLOR_WHITE;
@@ -455,6 +479,22 @@ bool draw_icon_button(UIConstraints *constraints, Color btn_color, const Texture
bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos); bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos);
bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT; bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
bool left_mouse_released = zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
bool clicked = false;
if (zephr_ctx->ui.active_element == 0) {
if (is_hovered && left_mouse_pressed) {
zephr_ctx->ui.active_element = hash;
}
} else if (zephr_ctx->ui.active_element == hash) {
if (left_mouse_released) {
zephr_ctx->ui.active_element = 0;
if (is_hovered) {
clicked = true;
}
}
}
if (is_hovered && state == BUTTON_STATE_ACTIVE) { if (is_hovered && state == BUTTON_STATE_ACTIVE) {
zephr_set_cursor(ZEPHR_CURSOR_HAND); zephr_set_cursor(ZEPHR_CURSOR_HAND);
@@ -486,47 +526,58 @@ bool draw_icon_button(UIConstraints *constraints, Color btn_color, const Texture
set_height_constraint(&icon_constraints, constraints->height * 0.8f, UI_CONSTRAINT_FIXED); set_height_constraint(&icon_constraints, constraints->height * 0.8f, UI_CONSTRAINT_FIXED);
draw_texture(&icon_constraints, icon_tex_id, icon_color, 0, ALIGN_CENTER); draw_texture(&icon_constraints, icon_tex_id, icon_color, 0, ALIGN_CENTER);
if (is_hovered && state == BUTTON_STATE_ACTIVE && zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) { if (clicked && state == BUTTON_STATE_ACTIVE) {
return true; return true;
} }
return false; return false;
} }
f32 draw_color_picker_slider(UIConstraints *constraints, Alignment align) { #define draw_color_picker_slider(constraints, align) draw_color_picker_slider_with_location(__FILE__, __LINE__, constraints, align)
f32 draw_color_picker_slider_with_location(const char *file, int line, UIConstraints *constraints, Alignment align) {
static f32 slider_selection = 0; static f32 slider_selection = 0;
static bool slider_dragging = false; static bool dragging = false;
UiIdHash hash = core_fnv_hash32(file, strlen(file), CORE_FNV_HASH32_INIT);
hash = core_fnv_hash32(&line, sizeof(line), hash);
use_shader(color_chooser_shader); use_shader(color_chooser_shader);
set_bool(color_chooser_shader, "isSlider", true); set_bool(color_chooser_shader, "isSlider", true);
set_mat4f(color_chooser_shader, "projection", (float *)zephr_ctx->projection.m); set_mat4f(color_chooser_shader, "projection", (float *)zephr_ctx->projection.m);
Vec2f pos = { 0.f, 0.f }; Rect rect = {0};
Sizef size = { 0.f, 0.f };
apply_constraints(constraints, &pos, &size); apply_constraints(constraints, &rect.pos, &rect.size);
apply_alignment(align, constraints, &pos, size); apply_alignment(align, constraints, &rect.pos, rect.size);
// set the positions after applying alignment so children can use them // set the positions after applying alignment so children can use them
constraints->x = pos.x; constraints->x = rect.pos.x;
constraints->y = pos.y; constraints->y = rect.pos.y;
if (inside_rect(&(Rect){{constraints->x, constraints->y}, {constraints->width, constraints->height}}, &zephr_ctx->mouse.pos) && bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos);
zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) { bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
slider_dragging = true; bool left_mouse_released = zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
if (zephr_ctx->ui.active_element == 0) {
if (is_hovered && left_mouse_pressed) {
zephr_ctx->ui.active_element = hash;
dragging = true;
}
} else if (zephr_ctx->ui.active_element == hash) {
if (left_mouse_released) {
zephr_ctx->ui.active_element = 0;
dragging = false;
}
} }
if (zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) { if (dragging) {
slider_dragging = false;
}
if (slider_dragging) {
slider_selection = CORE_CLAMP((zephr_ctx->mouse.pos.y - constraints->y) / constraints->height, 0, 1); slider_selection = CORE_CLAMP((zephr_ctx->mouse.pos.y - constraints->y) / constraints->height, 0, 1);
} }
Matrix4x4 model = identity(); Matrix4x4 model = identity();
apply_translation(&model, pos); apply_translation(&model, rect.pos);
set_mat4f(color_chooser_shader, "model", (float *)model.m); set_mat4f(color_chooser_shader, "model", (float *)model.m);
@@ -534,14 +585,14 @@ f32 draw_color_picker_slider(UIConstraints *constraints, Alignment align) {
float vertices[6][4] = { float vertices[6][4] = {
// bottom left tri // bottom left tri
{0, 0 + size.height, 0.0, 1.0}, {0, 0 + rect.size.height, 0.0, 1.0},
{0, 0, 0.0, 0.0}, {0, 0, 0.0, 0.0},
{0 + size.width, 0, 1.0, 0.0}, {0 + rect.size.width, 0, 1.0, 0.0},
// top right tri // top right tri
{0, 0 + size.height, 0.0, 1.0}, {0, 0 + rect.size.height, 0.0, 1.0},
{0 + size.width, 0, 1.0, 0.0}, {0 + rect.size.width, 0, 1.0, 0.0},
{0 + size.width, 0 + size.height, 1.0, 1.0}, {0 + rect.size.width, 0 + rect.size.height, 1.0, 1.0},
}; };
glBindBuffer(GL_ARRAY_BUFFER, ui_vbo); glBindBuffer(GL_ARRAY_BUFFER, ui_vbo);
@@ -553,39 +604,66 @@ f32 draw_color_picker_slider(UIConstraints *constraints, Alignment align) {
glBindVertexArray(0); glBindVertexArray(0);
set_bool(color_chooser_shader, "isSlider", false); set_bool(color_chooser_shader, "isSlider", false);
// draw the selection
UIConstraints triangle_con = default_constraints;
set_parent_constraint(&triangle_con, constraints);
set_x_constraint(&triangle_con, -11, UI_CONSTRAINT_RELATIVE_PIXELS);
set_y_constraint(&triangle_con, slider_selection, UI_CONSTRAINT_RELATIVE);
set_rotation_constraint(&triangle_con, -90);
set_width_constraint(&triangle_con, 14, UI_CONSTRAINT_RELATIVE_PIXELS);
set_height_constraint(&triangle_con, 0.5f, UI_CONSTRAINT_ASPECT_RATIO);
triangle_con.y += -(triangle_con.height / 2.f);
draw_triangle(&triangle_con, COLOR_BLACK, ALIGN_TOP_LEFT);
set_x_constraint(&triangle_con, 1, UI_CONSTRAINT_RELATIVE);
triangle_con.x -= triangle_con.height / 2;
set_rotation_constraint(&triangle_con, 90);
draw_triangle(&triangle_con, COLOR_BLACK, ALIGN_TOP_LEFT);
return slider_selection; return slider_selection;
} }
Vec2f draw_color_picker_canvas(UIConstraints *constraints, f32 slider_percentage, Alignment align) { #define draw_color_picker_canvas(constraints, slider_percentage, align) draw_color_picker_canvas_with_location(__FILE__, __LINE__, constraints, slider_percentage, align)
static bool canvas_dragging = false;
Vec2f draw_color_picker_canvas_with_location(const char* file, int line, UIConstraints *constraints, f32 slider_percentage, Alignment align) {
static bool dragging = false;
static Vec2f canvas_pos = {0}; static Vec2f canvas_pos = {0};
UiIdHash hash = core_fnv_hash32(file, strlen(file), CORE_FNV_HASH32_INIT);
hash = core_fnv_hash32(&line, sizeof(line), hash);
use_shader(color_chooser_shader); use_shader(color_chooser_shader);
set_bool(color_chooser_shader, "isSlider", false); set_bool(color_chooser_shader, "isSlider", false);
set_float(color_chooser_shader, "sliderPercentage", slider_percentage); set_float(color_chooser_shader, "sliderPercentage", slider_percentage);
set_mat4f(color_chooser_shader, "projection", (float *)zephr_ctx->projection.m); set_mat4f(color_chooser_shader, "projection", (float *)zephr_ctx->projection.m);
Vec2f pos = { 0.f, 0.f }; Rect rect = {0};
Sizef size = { 0.f, 0.f };
apply_constraints(constraints, &pos, &size); apply_constraints(constraints, &rect.pos, &rect.size);
apply_alignment(align, constraints, &pos, size); apply_alignment(align, constraints, &rect.pos, rect.size);
// set the positions after applying alignment so children can use them // set the positions after applying alignment so children can use them
constraints->x = pos.x; constraints->x = rect.pos.x;
constraints->y = pos.y; constraints->y = rect.pos.y;
if (inside_rect(&(Rect){{constraints->x, constraints->y}, {constraints->width, constraints->height}}, &zephr_ctx->mouse.pos) && bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos);
zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) { bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
canvas_dragging = true; bool left_mouse_released = zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
if (zephr_ctx->ui.active_element == 0) {
if (is_hovered && left_mouse_pressed) {
zephr_ctx->ui.active_element = hash;
dragging = true;
}
} else if (zephr_ctx->ui.active_element == hash) {
if (left_mouse_released) {
zephr_ctx->ui.active_element = 0;
dragging = false;
}
} }
if (zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) { if (dragging) {
canvas_dragging = false;
}
if (canvas_dragging) {
f32 x = (zephr_ctx->mouse.pos.x - constraints->x) / constraints->width; f32 x = (zephr_ctx->mouse.pos.x - constraints->x) / constraints->width;
f32 y = (zephr_ctx->mouse.pos.y - constraints->y) / constraints->height; f32 y = (zephr_ctx->mouse.pos.y - constraints->y) / constraints->height;
@@ -594,7 +672,7 @@ Vec2f draw_color_picker_canvas(UIConstraints *constraints, f32 slider_percentage
} }
Matrix4x4 model = identity(); Matrix4x4 model = identity();
apply_translation(&model, pos); apply_translation(&model, rect.pos);
set_mat4f(color_chooser_shader, "model", (float *)model.m); set_mat4f(color_chooser_shader, "model", (float *)model.m);
@@ -602,14 +680,14 @@ Vec2f draw_color_picker_canvas(UIConstraints *constraints, f32 slider_percentage
float vertices[6][4] = { float vertices[6][4] = {
// bottom left tri // bottom left tri
{0, 0 + size.height, 0.0, 1.0}, {0, 0 + rect.size.height, 0.0, 1.0},
{0, 0, 0.0, 0.0}, {0, 0, 0.0, 0.0},
{0 + size.width, 0, 1.0, 0.0}, {0 + rect.size.width, 0, 1.0, 0.0},
// top right tri // top right tri
{0, 0 + size.height, 0.0, 1.0}, {0, 0 + rect.size.height, 0.0, 1.0},
{0 + size.width, 0, 1.0, 0.0}, {0 + rect.size.width, 0, 1.0, 0.0},
{0 + size.width, 0 + size.height, 1.0, 1.0}, {0 + rect.size.width, 0 + rect.size.height, 1.0, 1.0},
}; };
glBindBuffer(GL_ARRAY_BUFFER, ui_vbo); glBindBuffer(GL_ARRAY_BUFFER, ui_vbo);
@@ -620,6 +698,33 @@ Vec2f draw_color_picker_canvas(UIConstraints *constraints, f32 slider_percentage
glBindVertexArray(0); glBindVertexArray(0);
// draw the selection
UIConstraints triangle_con = default_constraints;
set_parent_constraint(&triangle_con, constraints);
set_x_constraint(&triangle_con, canvas_pos.x, UI_CONSTRAINT_RELATIVE);
set_y_constraint(&triangle_con, canvas_pos.y, UI_CONSTRAINT_RELATIVE);
set_width_constraint(&triangle_con, 14, UI_CONSTRAINT_RELATIVE_PIXELS);
set_height_constraint(&triangle_con, 0.5f, UI_CONSTRAINT_ASPECT_RATIO);
triangle_con.x -= triangle_con.height;
triangle_con.y -= triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 0);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
triangle_con.x += triangle_con.height * 2;
triangle_con.y += triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 90);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
triangle_con.x -= triangle_con.height * 2;
triangle_con.y += triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 180);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
triangle_con.x -= triangle_con.height * 2;
triangle_con.y -= triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 270);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
return canvas_pos; return canvas_pos;
} }
@@ -641,50 +746,11 @@ void draw_color_picker_popup(UIConstraints *picker_button_con) {
set_width_constraint(&color_slider_con, 0.1f, UI_CONSTRAINT_ASPECT_RATIO); set_width_constraint(&color_slider_con, 0.1f, UI_CONSTRAINT_ASPECT_RATIO);
f32 slider_selection = draw_color_picker_slider(&color_slider_con, ALIGN_TOP_RIGHT); f32 slider_selection = draw_color_picker_slider(&color_slider_con, ALIGN_TOP_RIGHT);
UIConstraints triangle_con = default_constraints;
set_parent_constraint(&triangle_con, &color_slider_con);
set_x_constraint(&triangle_con, -11, UI_CONSTRAINT_RELATIVE_PIXELS);
set_y_constraint(&triangle_con, slider_selection, UI_CONSTRAINT_RELATIVE);
set_rotation_constraint(&triangle_con, -90);
set_width_constraint(&triangle_con, 14, UI_CONSTRAINT_RELATIVE_PIXELS);
set_height_constraint(&triangle_con, 0.5f, UI_CONSTRAINT_ASPECT_RATIO);
triangle_con.y += -(triangle_con.height / 2.f);
draw_triangle(&triangle_con, COLOR_BLACK, ALIGN_TOP_LEFT);
set_x_constraint(&triangle_con, 1, UI_CONSTRAINT_RELATIVE);
triangle_con.x -= triangle_con.height / 2;
set_rotation_constraint(&triangle_con, 90);
draw_triangle(&triangle_con, COLOR_BLACK, ALIGN_TOP_LEFT);
set_x_constraint(&color_slider_con, 0.04f, UI_CONSTRAINT_RELATIVE); set_x_constraint(&color_slider_con, 0.04f, UI_CONSTRAINT_RELATIVE);
set_y_constraint(&color_slider_con, 0.05f, UI_CONSTRAINT_RELATIVE); set_y_constraint(&color_slider_con, 0.05f, UI_CONSTRAINT_RELATIVE);
set_width_constraint(&color_slider_con, popup_con.width * 0.8f, UI_CONSTRAINT_FIXED); set_width_constraint(&color_slider_con, popup_con.width * 0.8f, UI_CONSTRAINT_FIXED);
Vec2f canvas_pos = draw_color_picker_canvas(&color_slider_con, slider_selection, ALIGN_TOP_LEFT); Vec2f canvas_pos = draw_color_picker_canvas(&color_slider_con, slider_selection, ALIGN_TOP_LEFT);
set_parent_constraint(&triangle_con, &color_slider_con);
set_x_constraint(&triangle_con, canvas_pos.x, UI_CONSTRAINT_RELATIVE);
set_y_constraint(&triangle_con, canvas_pos.y, UI_CONSTRAINT_RELATIVE);
triangle_con.x -= triangle_con.height;
triangle_con.y -= triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 0);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
triangle_con.x += triangle_con.height * 2;
triangle_con.y += triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 90);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
triangle_con.x -= triangle_con.height * 2;
triangle_con.y += triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 180);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
triangle_con.x -= triangle_con.height * 2;
triangle_con.y -= triangle_con.height * 2;
set_rotation_constraint(&triangle_con, 270);
draw_triangle(&triangle_con, COLOR_WHITE, ALIGN_TOP_LEFT);
UIConstraints button_con = default_constraints; UIConstraints button_con = default_constraints;
set_parent_constraint(&button_con, &popup_con); set_parent_constraint(&button_con, &popup_con);
set_x_constraint(&button_con, 0.04f, UI_CONSTRAINT_RELATIVE); set_x_constraint(&button_con, 0.04f, UI_CONSTRAINT_RELATIVE);
+8 -2
View File
@@ -3,6 +3,8 @@
#include "texture.h" #include "texture.h"
#include "zephr_math.h" #include "zephr_math.h"
typedef u32 UiIdHash;
typedef enum Alignment { typedef enum Alignment {
ALIGN_TOP_LEFT, ALIGN_TOP_LEFT,
ALIGN_TOP_CENTER, ALIGN_TOP_CENTER,
@@ -44,6 +46,7 @@ typedef struct UI {
Rect popup_rect; Rect popup_rect;
UIConstraints popup_parent_constraints; UIConstraints popup_parent_constraints;
Color *popup_revert_color; Color *popup_revert_color;
UiIdHash active_element;
} UI; } UI;
typedef enum ButtonState { typedef enum ButtonState {
@@ -65,7 +68,10 @@ bool inside_rect(Rect *rect, Vec2 *point);
void draw_quad(UIConstraints *constraints, const Color color, float border_radius, Alignment align); void draw_quad(UIConstraints *constraints, const Color color, float border_radius, Alignment align);
void draw_circle(UIConstraints *constraints, const Color color, Alignment align); void draw_circle(UIConstraints *constraints, const Color color, Alignment align);
void draw_triangle(UIConstraints *constraints, const Color color, Alignment align); void draw_triangle(UIConstraints *constraints, const Color color, Alignment align);
bool draw_button(UIConstraints *constraints, Color color, const char *text, f32 radius, Alignment align, ButtonState state); bool draw_button_with_location(const char* file, int line, UIConstraints *constraints, Color color, const char *text, f32 radius, Alignment align, ButtonState state);
bool draw_icon_button(UIConstraints *constraints, Color color, const TextureId icon_tex_id, f32 radius, Alignment align, ButtonState state); bool draw_icon_button_with_location(const char* fie, int line, UIConstraints *constraints, Color color, const TextureId icon_tex_id, f32 radius, Alignment align, ButtonState state);
void draw_color_picker_popup(UIConstraints *picker_button_con); void draw_color_picker_popup(UIConstraints *picker_button_con);
void draw_color_picker(UIConstraints *constraints, Color *color, Alignment align, ButtonState state); void draw_color_picker(UIConstraints *constraints, Color *color, Alignment align, ButtonState state);
#define draw_button(constraints, color, text, radius, align, state) draw_button_with_location(__FILE__, __LINE__, constraints, color, text, radius, align, state)
#define draw_icon_button(constraints, color, icon_tex_id, radius, align, state) draw_icon_button_with_location(__FILE__, __LINE__, constraints, color, icon_tex_id, radius, align, state)
-6
View File
@@ -1073,15 +1073,9 @@ bool zephr_iter_events(ZephrEvent *event_out) {
break; break;
case Button2: case Button2:
event_out->mouse.button = ZEPHR_MOUSE_BUTTON_MIDDLE; event_out->mouse.button = ZEPHR_MOUSE_BUTTON_MIDDLE;
if (!inside_rect(&zephr_ctx->ui.popup_rect, &event_out->mouse.position)) {
zephr_ctx->ui.popup_open = false;
}
break; break;
case Button3: case Button3:
event_out->mouse.button = ZEPHR_MOUSE_BUTTON_RIGHT; event_out->mouse.button = ZEPHR_MOUSE_BUTTON_RIGHT;
if (!inside_rect(&zephr_ctx->ui.popup_rect, &event_out->mouse.position)) {
zephr_ctx->ui.popup_open = false;
}
break; break;
} }