Added ui callbacks, want to play around with and flesh out more

main
noah metz 2024-11-12 20:59:41 -07:00
parent 7f3ed168df
commit 4aeea98d45
2 changed files with 204 additions and 45 deletions

@ -34,8 +34,6 @@ typedef struct ClientContextStruct {
UIContext* ui;
HexContext* hex;
double cursor[2];
vec3 position;
vec3 velocity;
@ -97,6 +95,55 @@ uint32_t add_hex_region(ClientContext* context) {
return i;
}
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);
}
}
void hue_bar_button_callback(void* ptr, float x, float y, int button, int action, int mods) {
(void)mods;
(void)x;
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);
} else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) {
clear_active_element(context->ui);
}
}
VkResult color_ui(ClientContext* context) {
GPUString strings[] = {
{
@ -221,6 +268,14 @@ VkResult color_ui(ClientContext* context) {
.num_drawables = sizeof(drawables)/sizeof(GPUDrawable),
};
UICallbacks callbacks[] = {
{
.element = 0x02,
.button = hue_bar_button_callback,
.cursor = hue_bar_cursor_callback,
},
};
ContainerInput container = {
.layers = &layer,
.layer_count = 1,
@ -228,6 +283,8 @@ VkResult color_ui(ClientContext* context) {
.id = 0x03,
.offset = {0, 0},
.size = {190, 150},
.callbacks = callbacks,
.callback_count = sizeof(callbacks)/sizeof(UICallbacks),
};
return create_container(&container, context->render, context->ui);
@ -687,7 +744,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
(void)mods;
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(context->ui->active_captures & UI_EVENT_KEY) {
if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->key != NULL) {
// Pass key to active element
} else {
switch(key) {
@ -923,7 +980,6 @@ 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)mods;
double cursor[2];
uint32_t container;
uint32_t element;
@ -933,10 +989,35 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) {
glfwGetCursorPos(window, &cursor[0], &cursor[1]);
if(context->ui->active_captures & UI_EVENT_BUTTON) {
// Pass button to active element
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);
vec2 element_pos = {
drawable_ptr->pos[0] + container_ptr->data.offset[0],
drawable_ptr->pos[1] + container_ptr->data.offset[1],
};
anchor_offset(context->render, container_ptr, element_pos);
vec2 element_size = {
drawable_ptr->size[0],
drawable_ptr->size[1],
};
context->ui->active_callbacks->button(
context,
(cursor[0] - element_pos[0])/element_size[0],
(cursor[1] - element_pos[1])/element_size[1],
button,
action,
mods);
} else if(ui_intersect(cursor, context->render, context->ui, &container, &element, position)) {
// Pass button to active UI 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) {
if(container_ptr->callbacks[c].button != NULL) {
container_ptr->callbacks[c].button(context, position[0], position[1], button, action, mods);
}
break;
}
}
} else {
update_hex_click(cursor, context->hex, context->render);
if(button == GLFW_MOUSE_BUTTON_MIDDLE) {
@ -958,9 +1039,9 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
vec2 position;
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(context->ui->active_captures & UI_EVENT_SCROLL) {
if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->scroll != NULL) {
// Pass scroll to active element
} else if(ui_intersect(context->cursor, context->render, context->ui, &container, &element, position)) {
} else if(ui_intersect(context->ui->cursor, context->render, context->ui, &container, &element, position)) {
// Pass scroll to hovered element
} else {
context->zoom = -yoffset;
@ -973,23 +1054,45 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
uint32_t element;
vec2 position;
vec2 last_cursor = {
context->cursor[0],
context->cursor[1],
context->ui->cursor[0],
context->ui->cursor[1],
};
context->cursor[0] = xpos;
context->cursor[1] = ypos;
context->ui->cursor[0] = xpos;
context->ui->cursor[1] = ypos;
if(context->camera_mode == true) {
context->cur_spin[0] = (xpos - last_cursor[0])/context->render->swapchain_extent.width*-100;
context->cur_spin[1] = (ypos - last_cursor[1])/context->render->swapchain_extent.height*100;
} else {
if(context->ui->active_captures & UI_EVENT_CURSOR) {
// Pass cursor to active element
} else if(ui_intersect(context->cursor, context->render, context->ui, &container, &element, position)) {
// Pass cursor to hovered element
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);
vec2 element_pos = {
drawable_ptr->pos[0] + container_ptr->data.offset[0],
drawable_ptr->pos[1] + container_ptr->data.offset[1],
};
anchor_offset(context->render, container_ptr, element_pos);
vec2 element_size = {
drawable_ptr->size[0],
drawable_ptr->size[1],
};
context->ui->active_callbacks->cursor(
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)) {
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].button != NULL) {
container_ptr->callbacks[c].cursor(context, position[0], position[1]);
}
break;
}
}
} else {
update_hex_hover(context->cursor, context->hex, context->render);
update_hex_hover(context->ui->cursor, context->hex, context->render);
}
}
}

@ -263,7 +263,12 @@ VkResult create_container(
}
context->containers[index].layer_count = container->layer_count;
context->containers[index].callbacks = malloc(sizeof(UICallbacks)*container->callback_count);
context->containers[index].callback_count = container->callback_count;
memcpy(
context->containers[index].callbacks,
container->callbacks,
sizeof(UICallbacks)*container->callback_count);
return VK_SUCCESS;
}
@ -1148,6 +1153,35 @@ VkResult map_string(
return VK_SUCCESS;
}
Container* context_container(uint32_t container_id, UIContext* ui) {
uint32_t c;
Container* ret = NULL;
for(c = 0; c < ui->max_containers; c++) {
if(ui->containers[c].id == container_id) {
ret = &ui->containers[c];
break;
}
}
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,
@ -1157,18 +1191,12 @@ VkResult update_ui_string(
RenderContext* gpu) {
VkResult result;
uint32_t c;
for(c = 0; c < ui->max_containers; c++) {
if(ui->containers[c].id == container_id) {
break;
}
}
if(c == ui->max_containers) {
Container* container = context_container(container_id, ui);
if(container == NULL) {
return VK_ERROR_UNKNOWN;
}
Container* container = &ui->containers[c];
Layer* layer = &container->layers[layer_index];
layer->strings_buffer[string_index].length = strlen(string);
if(strlen(string) > 0) {
@ -1223,30 +1251,13 @@ bool ui_intersect(
uint32_t* container,
uint32_t* element,
vec2 position) {
vec2 screen = {
gpu->swapchain_extent.width/gpu->window_scale[0],
gpu->swapchain_extent.height/gpu->window_scale[1],
};
for(uint32_t c = 0; c < ui->max_containers; c++) {
if(ui->containers[c].id == 0x00000000) {
continue;
}
vec2 container_offset = {ui->containers[c].data.offset[0], ui->containers[c].data.offset[1]};
switch(ui->containers[c].data.anchor) {
case ANCHOR_TOP_LEFT:
break;
case ANCHOR_TOP_RIGHT:
container_offset[0] += screen[0] - ui->containers[c].data.size[0];
break;
case ANCHOR_BOTTOM_LEFT:
container_offset[1] += screen[1] - ui->containers[c].data.size[1];
break;
case ANCHOR_BOTTOM_RIGHT:
container_offset[0] += screen[0] - ui->containers[c].data.size[0];
container_offset[1] += screen[1] - ui->containers[c].data.size[1];
break;
}
anchor_offset(gpu, &ui->containers[c], container_offset);
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++) {
@ -1270,3 +1281,48 @@ bool ui_intersect(
return false;
}
void clear_active_element(UIContext* ui) {
ui->active_callbacks = NULL;
ui->active_element = 0;
ui->active_container = 0;
}
void set_active_element(uint32_t container, uint32_t element, UIContext* ui) {
ui->active_container = container;
ui->active_element = element;
ui->active_callbacks = NULL;
Container* container_ptr = context_container(container, ui);
if(container_ptr == NULL) {
fprintf(stderr, "set_active_element passed invalid container id");
return;
}
for(uint32_t c = 0; c < container_ptr->callback_count; container_ptr++) {
if(container_ptr->callbacks[c].element == element) {
ui->active_callbacks = &container_ptr->callbacks[c];
break;
}
}
}
void anchor_offset(RenderContext* gpu, Container* container, vec2 offset) {
vec2 screen = {
gpu->swapchain_extent.width/gpu->window_scale[0],
gpu->swapchain_extent.height/gpu->window_scale[1],
};
switch(container->data.anchor) {
case ANCHOR_TOP_LEFT:
break;
case ANCHOR_TOP_RIGHT:
offset[0] += screen[0] - container->data.size[0];
break;
case ANCHOR_BOTTOM_LEFT:
offset[1] += screen[1] - container->data.size[1];
break;
case ANCHOR_BOTTOM_RIGHT:
offset[0] += screen[0] - container->data.size[0];
offset[1] += screen[1] - container->data.size[1];
break;
}
}