diff --git a/client/include/ui.h b/client/include/ui.h index e8a4388..bc753c9 100644 --- a/client/include/ui.h +++ b/client/include/ui.h @@ -76,7 +76,6 @@ typedef struct GPUStringStruct { uint32_t offset; uint32_t length; uint32_t font; - uint32_t id; } GPUString; typedef struct GPUDrawableStruct { @@ -85,7 +84,7 @@ typedef struct GPUDrawableStruct { vec4 color[4]; uint32_t type; uint32_t var; - uint32_t id; + uint32_t events; } GPUDrawable; 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 struct UICallbacksStruct { + uint32_t layer; uint32_t element; ui_key_callback key; ui_button_callback button; @@ -232,6 +232,7 @@ typedef struct UIContextStruct { UICallbacks* active_callbacks; uint32_t active_container; + uint32_t active_layer; uint32_t active_element; double cursor[2]; @@ -289,17 +290,18 @@ VkResult update_ui_string( RenderContext* gpu); Container* context_container(uint32_t container_id, UIContext* ui); -GPUDrawable* container_drawable(uint32_t element_id, Container* container); bool ui_intersect( double cursor[2], RenderContext* gpu, UIContext* ui, + uint32_t events, uint32_t* container, + uint32_t* layer, uint32_t* element, 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); diff --git a/client/shader/ui_common.glsl b/client/shader/ui_common.glsl index ac734f4..bb97b10 100644 --- a/client/shader/ui_common.glsl +++ b/client/shader/ui_common.glsl @@ -45,7 +45,6 @@ struct String { uint offset; uint len; uint font; - uint id; }; layout(std430, buffer_reference) readonly buffer StringList { @@ -62,7 +61,7 @@ struct Drawable { vec4 color[4]; uint type; uint var; - uint id; + uint events; }; layout(std430, buffer_reference) readonly buffer DrawableList { diff --git a/client/src/main.c b/client/src/main.c index 60709ce..e606a35 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -95,26 +95,45 @@ uint32_t add_hex_region(ClientContext* context) { return i; } +#define COLOR_PICK_CONTAINER_ID 0x03 +void hue_bar_set(ClientContext* context, float y) { + if(y < 0) y = 0; + if(y > 1) y = 1; + + Container* container = context_container(COLOR_PICK_CONTAINER_ID, context->ui); + Layer* layer = &container->layers[0]; + GPUDrawable* sv_square = &layer->drawables_buffer[1]; + + 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( + &sv_square->color[0], + layer->drawables, + 1*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), + 4*sizeof(vec4), + 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 == 0x02 && context->ui->active_container == 0x03) { - if(y < 0) y = 0; - 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); + if(context->ui->active_element == 2 + && context->ui->active_layer == 0 + && context->ui->active_container == COLOR_PICK_CONTAINER_ID) { + hue_bar_set(context, y); } } @@ -124,21 +143,8 @@ void hue_bar_button_callback(void* ptr, float x, float y, int button, int action ClientContext* context = (ClientContext*)ptr; if(action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT) { - set_active_element(0x03, 0x02, context->ui); - if(y < 0) y = 0; - 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); + set_active_element(COLOR_PICK_CONTAINER_ID, 0, 2, context->ui); + hue_bar_set(context, y); } else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) { clear_active_element(context->ui); } @@ -167,91 +173,78 @@ VkResult color_ui(ClientContext* context) { .pos = {2, 2}, .size = {130, 130}, .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, .pos = {134, 2}, .size = {10, 130}, .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}, .size = {95, 15}, - .id = 0x03, }, { .pos = {146, 2}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x04, }, { .pos = {168, 2}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x05, }, { .pos = {146, 24}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x06, }, { .pos = {168, 24}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x07, }, { .pos = {146, 46}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x08, }, { .pos = {168, 46}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x09, }, { .pos = {146, 68}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x0A, }, { .pos = {168, 68}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x0B, }, { .pos = {146, 90}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x0C, }, { .pos = {168, 90}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x0D, }, { .pos = {146, 112}, .size = {20, 20}, .color = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - .id = 0x0E, }, { .pos = {168, 112}, .size = {20, 20}, .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[] = { { - .element = 0x02, + .layer = 0, + .element = 2, .button = hue_bar_button_callback, .cursor = hue_bar_cursor_callback, + .scroll = hue_bar_scroll_callback, }, }; @@ -280,7 +275,7 @@ VkResult color_ui(ClientContext* context) { .layers = &layer, .layer_count = 1, .anchor = ANCHOR_BOTTOM_LEFT, - .id = 0x03, + .id = COLOR_PICK_CONTAINER_ID, .offset = {0, 0}, .size = {190, 150}, .callbacks = callbacks, @@ -745,7 +740,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); 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 { switch(key) { 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) { double cursor[2]; uint32_t container; + uint32_t layer; uint32_t element; 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) { 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 = { drawable_ptr->pos[0] + container_ptr->data.offset[0], 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, action, 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); for(uint32_t c = 0; c < container_ptr->callback_count; c++) { 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)xoffset; uint32_t container; + uint32_t layer; uint32_t element; vec2 position; ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->scroll != NULL) { - // Pass scroll to active element - } else if(ui_intersect(context->ui->cursor, context->render, context->ui, &container, &element, position)) { - // Pass scroll to hovered element + context->ui->active_callbacks->scroll(context, xoffset, yoffset); + } else if(ui_intersect( + 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 { context->zoom = -yoffset; } @@ -1052,6 +1065,7 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) { ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); uint32_t container; uint32_t element; + uint32_t layer; vec2 position; vec2 last_cursor = { context->ui->cursor[0], @@ -1067,7 +1081,7 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) { } else { if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->cursor != NULL) { 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 = { drawable_ptr->pos[0] + container_ptr->data.offset[0], drawable_ptr->pos[1] + container_ptr->data.offset[1], @@ -1081,7 +1095,8 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) { context, (context->ui->cursor[0] - element_pos[0])/element_size[0], (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); for(uint32_t c = 0; c < container_ptr->callback_count; c++) { if(container_ptr->callbacks[c].element == element) { diff --git a/client/src/ui.c b/client/src/ui.c index e8cd953..c2a219a 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -1166,22 +1166,6 @@ Container* context_container(uint32_t container_id, UIContext* ui) { 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( char* string, uint32_t container_id, @@ -1248,7 +1232,9 @@ bool ui_intersect( double cursor[2], RenderContext* gpu, UIContext* ui, + uint32_t events, uint32_t* container, + uint32_t* layer, uint32_t* element, vec2 position) { 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 d = 0; d < ui->containers[c].layers[l].data.num_drawables; d++) { - if(ui->containers[c].layers[l].drawables_buffer[d].id == 0x00000000) { - continue; - } - if(ui_contains( + if(ui->containers[c].layers[l].drawables_buffer[d].events & events + && ui_contains( cursor, container_offset, ui->containers[c].data.size, &ui->containers[c].layers[l].drawables_buffer[d], position)) { *container = ui->containers[c].id; - *element = ui->containers[c].layers[l].drawables_buffer[d].id; + *layer = l; + *element = d; return true; } } @@ -1287,9 +1272,10 @@ void clear_active_element(UIContext* ui) { 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_element = element; + ui->active_layer = layer; ui->active_callbacks = NULL; Container* container_ptr = context_container(container, ui); 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++) { - 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]; break; }