Fleshed out UI callbacks some more by adding event bitmask to drawables

main
noah metz 2024-11-12 23:07:01 -07:00
parent 8a5de3e16e
commit 97b776e6f0
4 changed files with 86 additions and 84 deletions

@ -76,7 +76,6 @@ typedef struct GPUStringStruct {
uint32_t offset; uint32_t offset;
uint32_t length; uint32_t length;
uint32_t font; uint32_t font;
uint32_t id;
} GPUString; } GPUString;
typedef struct GPUDrawableStruct { typedef struct GPUDrawableStruct {
@ -85,7 +84,7 @@ typedef struct GPUDrawableStruct {
vec4 color[4]; vec4 color[4];
uint32_t type; uint32_t type;
uint32_t var; uint32_t var;
uint32_t id; uint32_t events;
} GPUDrawable; } GPUDrawable;
typedef struct GPULayerStruct { typedef struct GPULayerStruct {
@ -151,6 +150,7 @@ typedef void (*ui_scroll_callback)(void* ptr, double x, double y);
typedef void (*ui_cursor_callback)(void* ptr, float x, float y); typedef void (*ui_cursor_callback)(void* ptr, float x, float y);
typedef struct UICallbacksStruct { typedef struct UICallbacksStruct {
uint32_t layer;
uint32_t element; uint32_t element;
ui_key_callback key; ui_key_callback key;
ui_button_callback button; ui_button_callback button;
@ -232,6 +232,7 @@ typedef struct UIContextStruct {
UICallbacks* active_callbacks; UICallbacks* active_callbacks;
uint32_t active_container; uint32_t active_container;
uint32_t active_layer;
uint32_t active_element; uint32_t active_element;
double cursor[2]; double cursor[2];
@ -289,17 +290,18 @@ VkResult update_ui_string(
RenderContext* gpu); RenderContext* gpu);
Container* context_container(uint32_t container_id, UIContext* ui); Container* context_container(uint32_t container_id, UIContext* ui);
GPUDrawable* container_drawable(uint32_t element_id, Container* container);
bool ui_intersect( bool ui_intersect(
double cursor[2], double cursor[2],
RenderContext* gpu, RenderContext* gpu,
UIContext* ui, UIContext* ui,
uint32_t events,
uint32_t* container, uint32_t* container,
uint32_t* layer,
uint32_t* element, uint32_t* element,
vec2 position); vec2 position);
void set_active_element(uint32_t container, uint32_t element, UIContext* ui); void set_active_element(uint32_t container, uint32_t layer, uint32_t element, UIContext* ui);
void clear_active_element(UIContext* ui); void clear_active_element(UIContext* ui);

@ -45,7 +45,6 @@ struct String {
uint offset; uint offset;
uint len; uint len;
uint font; uint font;
uint id;
}; };
layout(std430, buffer_reference) readonly buffer StringList { layout(std430, buffer_reference) readonly buffer StringList {
@ -62,7 +61,7 @@ struct Drawable {
vec4 color[4]; vec4 color[4];
uint type; uint type;
uint var; uint var;
uint id; uint events;
}; };
layout(std430, buffer_reference) readonly buffer DrawableList { layout(std430, buffer_reference) readonly buffer DrawableList {

@ -95,27 +95,46 @@ uint32_t add_hex_region(ClientContext* context) {
return i; return i;
} }
void hue_bar_cursor_callback(void* ptr, float x, float y) { #define COLOR_PICK_CONTAINER_ID 0x03
(void)x; void hue_bar_set(ClientContext* context, float y) {
ClientContext* context = (ClientContext*)ptr;
if(context->ui->active_element == 0x02 && context->ui->active_container == 0x03) {
if(y < 0) y = 0; if(y < 0) y = 0;
if(y > 1) y = 1; if(y > 1) y = 1;
Container* container = context_container(0x03, context->ui); Container* container = context_container(COLOR_PICK_CONTAINER_ID, context->ui);
container->layers[0].drawables_buffer[1].color[0][0] = y; Layer* layer = &container->layers[0];
container->layers[0].drawables_buffer[1].color[1][0] = y; GPUDrawable* sv_square = &layer->drawables_buffer[1];
container->layers[0].drawables_buffer[1].color[2][0] = y;
container->layers[0].drawables_buffer[1].color[3][0] = y; sv_square->color[0][0] = y;
sv_square->color[1][0] = y;
sv_square->color[2][0] = y;
sv_square->color[3][0] = y;
add_transfers( add_transfers(
&container->layers[0].drawables_buffer[1].color[0], &sv_square->color[0],
container->layers[0].drawables, layer->drawables,
1*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), 1*sizeof(GPUDrawable) + offsetof(GPUDrawable, color),
4*sizeof(vec4), 4*sizeof(vec4),
context->render); context->render);
} }
void hue_bar_scroll_callback(void* ptr, double x, double y) {
(void)x;
ClientContext* context = (ClientContext*)ptr;
Container* container = context_container(COLOR_PICK_CONTAINER_ID, context->ui);
hue_bar_set(context, y*0.01 + container->layers[0].drawables_buffer[1].color[0][0]);
}
void hue_bar_cursor_callback(void* ptr, float x, float y) {
(void)x;
ClientContext* context = (ClientContext*)ptr;
if(context->ui->active_element == 2
&& context->ui->active_layer == 0
&& context->ui->active_container == COLOR_PICK_CONTAINER_ID) {
hue_bar_set(context, y);
}
} }
void hue_bar_button_callback(void* ptr, float x, float y, int button, int action, int mods) { void hue_bar_button_callback(void* ptr, float x, float y, int button, int action, int mods) {
@ -124,21 +143,8 @@ void hue_bar_button_callback(void* ptr, float x, float y, int button, int action
ClientContext* context = (ClientContext*)ptr; ClientContext* context = (ClientContext*)ptr;
if(action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT) { if(action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT) {
set_active_element(0x03, 0x02, context->ui); set_active_element(COLOR_PICK_CONTAINER_ID, 0, 2, context->ui);
if(y < 0) y = 0; hue_bar_set(context, y);
if(y > 1) y = 1;
Container* container = context_container(0x03, context->ui);
container->layers[0].drawables_buffer[1].color[0][0] = y;
container->layers[0].drawables_buffer[1].color[1][0] = y;
container->layers[0].drawables_buffer[1].color[2][0] = y;
container->layers[0].drawables_buffer[1].color[3][0] = y;
add_transfers(
&container->layers[0].drawables_buffer[1].color[0],
container->layers[0].drawables,
1*sizeof(GPUDrawable) + offsetof(GPUDrawable, color),
4*sizeof(vec4),
context->render);
} else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) { } else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) {
clear_active_element(context->ui); clear_active_element(context->ui);
} }
@ -167,91 +173,78 @@ VkResult color_ui(ClientContext* context) {
.pos = {2, 2}, .pos = {2, 2},
.size = {130, 130}, .size = {130, 130},
.color = {{0, 0, 1, 1}, {0, 1, 1, 1}, {0, 0, 0, 1}, {0, 1, 0, 1}}, .color = {{0, 0, 1, 1}, {0, 1, 1, 1}, {0, 0, 0, 1}, {0, 1, 0, 1}},
.id = 0x01, .events = UI_EVENT_BUTTON,
}, },
{ {
.type = DRAWABLE_TYPE_RECT_HSV, .type = DRAWABLE_TYPE_RECT_HSV,
.pos = {134, 2}, .pos = {134, 2},
.size = {10, 130}, .size = {10, 130},
.color = {{0, 1, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{0, 1, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x02, .events = UI_EVENT_BUTTON | UI_EVENT_SCROLL,
}, },
{ {
.pos = {20, 134}, .pos = {20, 134},
.size = {95, 15}, .size = {95, 15},
.id = 0x03,
}, },
{ {
.pos = {146, 2}, .pos = {146, 2},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x04,
}, },
{ {
.pos = {168, 2}, .pos = {168, 2},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x05,
}, },
{ {
.pos = {146, 24}, .pos = {146, 24},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x06,
}, },
{ {
.pos = {168, 24}, .pos = {168, 24},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x07,
}, },
{ {
.pos = {146, 46}, .pos = {146, 46},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x08,
}, },
{ {
.pos = {168, 46}, .pos = {168, 46},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x09,
}, },
{ {
.pos = {146, 68}, .pos = {146, 68},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x0A,
}, },
{ {
.pos = {168, 68}, .pos = {168, 68},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x0B,
}, },
{ {
.pos = {146, 90}, .pos = {146, 90},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x0C,
}, },
{ {
.pos = {168, 90}, .pos = {168, 90},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x0D,
}, },
{ {
.pos = {146, 112}, .pos = {146, 112},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x0E,
}, },
{ {
.pos = {168, 112}, .pos = {168, 112},
.size = {20, 20}, .size = {20, 20},
.color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}},
.id = 0x0F,
}, },
}; };
@ -270,9 +263,11 @@ VkResult color_ui(ClientContext* context) {
UICallbacks callbacks[] = { UICallbacks callbacks[] = {
{ {
.element = 0x02, .layer = 0,
.element = 2,
.button = hue_bar_button_callback, .button = hue_bar_button_callback,
.cursor = hue_bar_cursor_callback, .cursor = hue_bar_cursor_callback,
.scroll = hue_bar_scroll_callback,
}, },
}; };
@ -280,7 +275,7 @@ VkResult color_ui(ClientContext* context) {
.layers = &layer, .layers = &layer,
.layer_count = 1, .layer_count = 1,
.anchor = ANCHOR_BOTTOM_LEFT, .anchor = ANCHOR_BOTTOM_LEFT,
.id = 0x03, .id = COLOR_PICK_CONTAINER_ID,
.offset = {0, 0}, .offset = {0, 0},
.size = {190, 150}, .size = {190, 150},
.callbacks = callbacks, .callbacks = callbacks,
@ -745,7 +740,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->key != NULL) { if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->key != NULL) {
// Pass key to active element context->ui->active_callbacks->key(context, key, action, mods);
} else { } else {
switch(key) { switch(key) {
case GLFW_KEY_A: case GLFW_KEY_A:
@ -982,6 +977,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
void button_callback(GLFWwindow* window, int button, int action, int mods) { void button_callback(GLFWwindow* window, int button, int action, int mods) {
double cursor[2]; double cursor[2];
uint32_t container; uint32_t container;
uint32_t layer;
uint32_t element; uint32_t element;
vec2 position; vec2 position;
@ -991,7 +987,7 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) {
if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->button != NULL) { if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->button != NULL) {
Container* container_ptr = context_container(context->ui->active_container, context->ui); Container* container_ptr = context_container(context->ui->active_container, context->ui);
GPUDrawable* drawable_ptr = container_drawable(context->ui->active_element, container_ptr); GPUDrawable* drawable_ptr = &container_ptr->layers[context->ui->active_layer].drawables_buffer[context->ui->active_element];
vec2 element_pos = { vec2 element_pos = {
drawable_ptr->pos[0] + container_ptr->data.offset[0], drawable_ptr->pos[0] + container_ptr->data.offset[0],
drawable_ptr->pos[1] + container_ptr->data.offset[1], drawable_ptr->pos[1] + container_ptr->data.offset[1],
@ -1008,7 +1004,7 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) {
button, button,
action, action,
mods); mods);
} else if(ui_intersect(cursor, context->render, context->ui, &container, &element, position)) { } else if(ui_intersect(cursor, context->render, context->ui, UI_EVENT_BUTTON, &container, &layer, &element, position)) {
Container* container_ptr = context_container(container, context->ui); Container* container_ptr = context_container(container, context->ui);
for(uint32_t c = 0; c < container_ptr->callback_count; c++) { for(uint32_t c = 0; c < container_ptr->callback_count; c++) {
if(container_ptr->callbacks[c].element == element) { if(container_ptr->callbacks[c].element == element) {
@ -1035,14 +1031,31 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) {
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
(void)xoffset; (void)xoffset;
uint32_t container; uint32_t container;
uint32_t layer;
uint32_t element; uint32_t element;
vec2 position; vec2 position;
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->scroll != NULL) { if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->scroll != NULL) {
// Pass scroll to active element context->ui->active_callbacks->scroll(context, xoffset, yoffset);
} else if(ui_intersect(context->ui->cursor, context->render, context->ui, &container, &element, position)) { } else if(ui_intersect(
// Pass scroll to hovered element context->ui->cursor,
context->render,
context->ui,
UI_EVENT_SCROLL,
&container,
&layer,
&element,
position)) {
Container* container_ptr = context_container(container, context->ui);
for(uint32_t c = 0; c < container_ptr->callback_count; c++) {
if(container_ptr->callbacks[c].element == element) {
if(container_ptr->callbacks[c].scroll != NULL) {
container_ptr->callbacks[c].scroll(context, xoffset, yoffset);
}
break;
}
}
} else { } else {
context->zoom = -yoffset; context->zoom = -yoffset;
} }
@ -1052,6 +1065,7 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
uint32_t container; uint32_t container;
uint32_t element; uint32_t element;
uint32_t layer;
vec2 position; vec2 position;
vec2 last_cursor = { vec2 last_cursor = {
context->ui->cursor[0], context->ui->cursor[0],
@ -1067,7 +1081,7 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
} else { } else {
if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->cursor != NULL) { if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->cursor != NULL) {
Container* container_ptr = context_container(context->ui->active_container, context->ui); Container* container_ptr = context_container(context->ui->active_container, context->ui);
GPUDrawable* drawable_ptr = container_drawable(context->ui->active_element, container_ptr); GPUDrawable* drawable_ptr = &container_ptr->layers[context->ui->active_layer].drawables_buffer[context->ui->active_element];
vec2 element_pos = { vec2 element_pos = {
drawable_ptr->pos[0] + container_ptr->data.offset[0], drawable_ptr->pos[0] + container_ptr->data.offset[0],
drawable_ptr->pos[1] + container_ptr->data.offset[1], drawable_ptr->pos[1] + container_ptr->data.offset[1],
@ -1081,7 +1095,8 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
context, context,
(context->ui->cursor[0] - element_pos[0])/element_size[0], (context->ui->cursor[0] - element_pos[0])/element_size[0],
(context->ui->cursor[1] - element_pos[1])/element_size[1]); (context->ui->cursor[1] - element_pos[1])/element_size[1]);
} else if(ui_intersect(context->ui->cursor, context->render, context->ui, &container, &element, position)) { } else if(ui_intersect(context->ui->cursor, context->render, context->ui, UI_EVENT_CURSOR, &container, &layer, &element, position)) {
fprintf(stderr, "Intersect %d %d %d\n", container, layer, element);
Container* container_ptr = context_container(container, context->ui); Container* container_ptr = context_container(container, context->ui);
for(uint32_t c = 0; c < container_ptr->callback_count; c++) { for(uint32_t c = 0; c < container_ptr->callback_count; c++) {
if(container_ptr->callbacks[c].element == element) { if(container_ptr->callbacks[c].element == element) {

@ -1166,22 +1166,6 @@ Container* context_container(uint32_t container_id, UIContext* ui) {
return ret; return ret;
} }
GPUDrawable* container_drawable(uint32_t element_id, Container* container) {
if(container == NULL || element_id == 0) {
return NULL;
}
for(uint32_t l = 0; l < container->layer_count; l++) {
for(uint32_t d = 0; d < container->layers[l].data.num_drawables; d++) {
if(container->layers[l].drawables_buffer[d].id == element_id) {
return &container->layers[l].drawables_buffer[d];
}
}
}
return NULL;
}
VkResult update_ui_string( VkResult update_ui_string(
char* string, char* string,
uint32_t container_id, uint32_t container_id,
@ -1248,7 +1232,9 @@ bool ui_intersect(
double cursor[2], double cursor[2],
RenderContext* gpu, RenderContext* gpu,
UIContext* ui, UIContext* ui,
uint32_t events,
uint32_t* container, uint32_t* container,
uint32_t* layer,
uint32_t* element, uint32_t* element,
vec2 position) { vec2 position) {
for(uint32_t c = 0; c < ui->max_containers; c++) { for(uint32_t c = 0; c < ui->max_containers; c++) {
@ -1261,17 +1247,16 @@ bool ui_intersect(
for(uint32_t l = 0; l < ui->containers[c].layer_count; l++) { for(uint32_t l = 0; l < ui->containers[c].layer_count; l++) {
for(uint32_t d = 0; d < ui->containers[c].layers[l].data.num_drawables; d++) { for(uint32_t d = 0; d < ui->containers[c].layers[l].data.num_drawables; d++) {
if(ui->containers[c].layers[l].drawables_buffer[d].id == 0x00000000) { if(ui->containers[c].layers[l].drawables_buffer[d].events & events
continue; && ui_contains(
}
if(ui_contains(
cursor, cursor,
container_offset, container_offset,
ui->containers[c].data.size, ui->containers[c].data.size,
&ui->containers[c].layers[l].drawables_buffer[d], &ui->containers[c].layers[l].drawables_buffer[d],
position)) { position)) {
*container = ui->containers[c].id; *container = ui->containers[c].id;
*element = ui->containers[c].layers[l].drawables_buffer[d].id; *layer = l;
*element = d;
return true; return true;
} }
} }
@ -1287,9 +1272,10 @@ void clear_active_element(UIContext* ui) {
ui->active_container = 0; ui->active_container = 0;
} }
void set_active_element(uint32_t container, uint32_t element, UIContext* ui) { void set_active_element(uint32_t container, uint32_t layer, uint32_t element, UIContext* ui) {
ui->active_container = container; ui->active_container = container;
ui->active_element = element; ui->active_element = element;
ui->active_layer = layer;
ui->active_callbacks = NULL; ui->active_callbacks = NULL;
Container* container_ptr = context_container(container, ui); Container* container_ptr = context_container(container, ui);
if(container_ptr == NULL) { if(container_ptr == NULL) {
@ -1298,7 +1284,7 @@ void set_active_element(uint32_t container, uint32_t element, UIContext* ui) {
} }
for(uint32_t c = 0; c < container_ptr->callback_count; container_ptr++) { for(uint32_t c = 0; c < container_ptr->callback_count; container_ptr++) {
if(container_ptr->callbacks[c].element == element) { if(container_ptr->callbacks[c].element == element && container_ptr->callbacks[c].layer == layer) {
ui->active_callbacks = &container_ptr->callbacks[c]; ui->active_callbacks = &container_ptr->callbacks[c];
break; break;
} }