Changed string update to use container ID instead of index, updated callbacks to prepare for UI element callbacks

main
noah metz 2024-11-12 17:39:29 -07:00
parent 22b6c6a5ae
commit 7f3ed168df
3 changed files with 416 additions and 320 deletions

@ -18,6 +18,12 @@
#define DRAWABLE_TYPE_RECT 0 #define DRAWABLE_TYPE_RECT 0
#define DRAWABLE_TYPE_GLYPH 1 #define DRAWABLE_TYPE_GLYPH 1
#define DRAWABLE_TYPE_IMAGE 2 #define DRAWABLE_TYPE_IMAGE 2
#define DRAWABLE_TYPE_RECT_HSV 3
#define UI_EVENT_CURSOR (1 << 0)
#define UI_EVENT_SCROLL (1 << 1)
#define UI_EVENT_BUTTON (1 << 2)
#define UI_EVENT_KEY (1 << 3)
typedef struct UIPushConstantStruct { typedef struct UIPushConstantStruct {
VkDeviceAddress layer; VkDeviceAddress layer;
@ -204,6 +210,10 @@ typedef struct UIContext {
GPUUIContext data; GPUUIContext data;
FT_Library freetype; FT_Library freetype;
uint32_t active_element;
uint32_t active_container;
uint32_t active_captures;
} UIContext; } UIContext;
VkResult create_ui_context( VkResult create_ui_context(
@ -251,10 +261,18 @@ VkResult update_ui_context_resolution(
VkResult update_ui_string( VkResult update_ui_string(
char* string, char* string,
uint32_t container_index, uint32_t container_id,
uint32_t layer_index, uint32_t layer_index,
uint32_t string_index, uint32_t string_index,
UIContext* ui, UIContext* ui,
RenderContext* gpu); RenderContext* gpu);
bool ui_intersect(
double cursor[2],
RenderContext* gpu,
UIContext* ui,
uint32_t* container,
uint32_t* element,
vec2 position);
#endif #endif

@ -26,7 +26,6 @@ typedef struct EditorContextStruct {
vec4 saved_colors[12]; vec4 saved_colors[12];
vec4 current_color; vec4 current_color;
vec4 color_string; vec4 color_string;
bool selecting_color;
} EditorContext; } EditorContext;
typedef struct ClientContextStruct { typedef struct ClientContextStruct {
@ -35,9 +34,6 @@ typedef struct ClientContextStruct {
UIContext* ui; UIContext* ui;
HexContext* hex; HexContext* hex;
uint32_t clicked_container;
uint32_t clicked_element;
double cursor[2]; double cursor[2];
vec3 position; vec3 position;
@ -120,14 +116,14 @@ VkResult color_ui(ClientContext* context) {
.color = {{0.4, 0.4, 0.4, 0.4}, {0.4, 0.4, 0.4, 0.4}, {0.4, 0.4, 0.4, 0.4}, {0.4, 0.4, 0.4, 0.4}}, .color = {{0.4, 0.4, 0.4, 0.4}, {0.4, 0.4, 0.4, 0.4}, {0.4, 0.4, 0.4, 0.4}, {0.4, 0.4, 0.4, 0.4}},
}, },
{ {
.type = 0x03, .type = DRAWABLE_TYPE_RECT_HSV,
.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, .id = 0x01,
}, },
{ {
.type = 0x03, .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}},
@ -409,44 +405,44 @@ VkResult update_region_info_ui(ClientContext* context) {
snprintf(temp, snprintf(temp,
sizeof(temp), sizeof(temp),
"Region %4d", context->editor.selected_region); "Region %4d", context->editor.selected_region);
VK_RESULT(update_ui_string(temp, 0, 0, 0, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x01, 0, 0, context->ui, context->render));
if(selected_region == NULL) { if(selected_region == NULL) {
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 0, 0, 1, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x01, 0, 1, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 0, 0, 2, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x01, 0, 2, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 0, 0, 3, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x01, 0, 3, context->ui, context->render));
} else { } else {
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"Q: %4d", selected_region->data.q); "Q: %4d", selected_region->data.q);
VK_RESULT(update_ui_string(temp, 0, 0, 1, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x01, 0, 1, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"R: %4d", selected_region->data.r); "R: %4d", selected_region->data.r);
VK_RESULT(update_ui_string(temp, 0, 0, 2, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x01, 0, 2, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"Y: %4d", selected_region->data.y); "Y: %4d", selected_region->data.y);
VK_RESULT(update_ui_string(temp, 0, 0, 3, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x01, 0, 3, context->ui, context->render));
} }
return VK_SUCCESS; return VK_SUCCESS;
@ -463,49 +459,49 @@ VkResult update_hex_info_ui(ClientContext* context) {
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 0, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 0, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 1, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 1, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 2, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 2, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 3, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 3, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 4, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 4, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 5, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 5, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 6, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 6, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
""); "");
VK_RESULT(update_ui_string(temp, 1, 0, 7, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 7, context->ui, context->render));
} else { } else {
GPUHex* hex = &region->data.hexes[context->hex->data.clicked_hex]; GPUHex* hex = &region->data.hexes[context->hex->data.clicked_hex];
snprintf(temp, snprintf(temp,
@ -513,7 +509,7 @@ VkResult update_hex_info_ui(ClientContext* context) {
"%d-%d", "%d-%d",
context->hex->data.clicked_region, context->hex->data.clicked_region,
context->hex->data.clicked_hex); context->hex->data.clicked_hex);
VK_RESULT(update_ui_string(temp, 1, 0, 0, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 0, context->ui, context->render));
int32_t hex_index = context->hex->data.clicked_hex; int32_t hex_index = context->hex->data.clicked_hex;
@ -526,6 +522,7 @@ VkResult update_hex_info_ui(ClientContext* context) {
side = floor(ring/radius); side = floor(ring/radius);
} }
// TODO: fix, these are wrong lmao
int32_t hex_q = hex_starts_qr[side][0]*radius + hex_directions_qr[side][0]*(ring-(radius*side)); int32_t hex_q = hex_starts_qr[side][0]*radius + hex_directions_qr[side][0]*(ring-(radius*side));
int32_t hex_r = hex_starts_qr[side][1]*radius + hex_directions_qr[side][1]*(ring-(radius*side)); int32_t hex_r = hex_starts_qr[side][1]*radius + hex_directions_qr[side][1]*(ring-(radius*side));
@ -540,49 +537,49 @@ VkResult update_hex_info_ui(ClientContext* context) {
world_r, world_r,
region->data.y, region->data.y,
context->hex->data.clicked_vertex); context->hex->data.clicked_vertex);
VK_RESULT(update_ui_string(temp, 1, 0, 1, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 1, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"%02.02f %02.02f %02.02f", "%02.02f %02.02f %02.02f",
hex->height[0], hex->height[1], hex->height[2]); hex->height[0], hex->height[1], hex->height[2]);
VK_RESULT(update_ui_string(temp, 1, 0, 2, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 2, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"%02.02f %02.02f %02.02f", "%02.02f %02.02f %02.02f",
hex->height[3], hex->height[4], hex->height[5]); hex->height[3], hex->height[4], hex->height[5]);
VK_RESULT(update_ui_string(temp, 1, 0, 3, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 3, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"%08X", "%08X",
hex->color[0]); hex->color[0]);
VK_RESULT(update_ui_string(temp, 1, 0, 4, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 4, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"%08X %08X", "%08X %08X",
hex->color[1], hex->color[2]); hex->color[1], hex->color[2]);
VK_RESULT(update_ui_string(temp, 1, 0, 5, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 5, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"%08X %08X", "%08X %08X",
hex->color[3], hex->color[4]); hex->color[3], hex->color[4]);
VK_RESULT(update_ui_string(temp, 1, 0, 6, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 6, context->ui, context->render));
snprintf( snprintf(
temp, temp,
sizeof(temp), sizeof(temp),
"%08X %08X", "%08X %08X",
hex->color[5], hex->color[6]); hex->color[5], hex->color[6]);
VK_RESULT(update_ui_string(temp, 1, 0, 7, context->ui, context->render)); VK_RESULT(update_ui_string(temp, 0x02, 0, 7, context->ui, context->render));
} }
return VK_SUCCESS; return VK_SUCCESS;
@ -602,8 +599,6 @@ VkResult main_thread(ClientContext* context) {
double delta_time = (frame_time - last_frame_time); double delta_time = (frame_time - last_frame_time);
// Reset callback variables // Reset callback variables
context->clicked_element = 0x00000000;
context->clicked_container = 0x00000000;
context->zoom = 0; context->zoom = 0;
context->cur_spin[0] = 0; context->cur_spin[0] = 0;
context->cur_spin[1] = 0; context->cur_spin[1] = 0;
@ -688,9 +683,13 @@ VkResult main_thread(ClientContext* context) {
} }
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
(void)scancode; (void)scancode;
(void)mods; (void)mods;
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(context->ui->active_captures & UI_EVENT_KEY) {
// Pass key to active element
} else {
switch(key) { switch(key) {
case GLFW_KEY_A: case GLFW_KEY_A:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
@ -920,29 +919,27 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
} }
break; break;
} }
}
} }
bool contains(double* point, GPUContainer* container, GPUDrawable* rect) { void button_callback(GLFWwindow* window, int button, int action, int mods) {
vec2 pos = { (void)mods;
container->offset[0] + rect->pos[0], double cursor[2];
container->offset[1] + rect->pos[1], uint32_t container;
}; uint32_t element;
return (point[0] >= pos[0] && point[0] <= pos[0] + rect->size[0]) && vec2 position;
(point[1] >= pos[1] && point[1] <= pos[1] + rect->size[1]) &&
(point[0] >= container->offset[0] && point[0] <= container->offset[0] + container->size[0]) &&
(point[1] >= container->offset[1] && point[1] <= container->offset[1] + container->size[1]);
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
(void)mods;
(void)context;
double cursor[2];
glfwGetCursorPos(window, &cursor[0], &cursor[1]); glfwGetCursorPos(window, &cursor[0], &cursor[1]);
switch(button) {
// Handle camera hover if(context->ui->active_captures & UI_EVENT_BUTTON) {
case GLFW_MOUSE_BUTTON_RIGHT: // Pass button to active element
} else if(ui_intersect(cursor, context->render, context->ui, &container, &element, position)) {
// Pass button to active UI element
} else {
update_hex_click(cursor, context->hex, context->render);
if(button == GLFW_MOUSE_BUTTON_MIDDLE) {
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
context->camera_mode = true; context->camera_mode = true;
@ -950,57 +947,51 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
context->camera_mode = false; context->camera_mode = false;
} }
break;
case GLFW_MOUSE_BUTTON_LEFT:
if(action == GLFW_PRESS) {
// Hex intersection
update_hex_click(cursor, context->hex, context->render);
// UI intersections
for(uint32_t c = 0; c < context->ui->max_containers; c++) {
if(context->ui->containers[c].id == 0x00000000) {
continue;
} }
for(uint32_t l = 0; l < context->ui->containers[c].layer_count; l++) {
for(uint32_t d = 0; d < context->ui->containers[c].layers[l].data.num_drawables; d++) {
if(context->ui->containers[c].layers[l].drawables_buffer[d].id == 0x00000000) {
continue;
}
if(contains(
cursor,
&context->ui->containers[c].data,
&context->ui->containers[c].layers[l].drawables_buffer[d])) {
context->clicked_container = context->ui->containers[c].id;
context->clicked_element = context->ui->containers[c].layers[l].drawables_buffer[d].id;
}
}
}
}
}
break;
} }
} }
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
(void)xoffset; (void)xoffset;
uint32_t container;
uint32_t element;
vec2 position;
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(context->ui->active_captures & UI_EVENT_SCROLL) {
// Pass scroll to active element
} else if(ui_intersect(context->cursor, context->render, context->ui, &container, &element, position)) {
// Pass scroll to hovered element
} else {
context->zoom = -yoffset; context->zoom = -yoffset;
}
} }
void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) { void cursor_callback(GLFWwindow* window, double xpos, double ypos) {
ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(context->camera_mode == true) { uint32_t container;
context->cur_spin[0] = (xpos - context->cursor[0])/context->render->swapchain_extent.width*-100; uint32_t element;
context->cur_spin[1] = (ypos - context->cursor[1])/context->render->swapchain_extent.height*100; vec2 position;
vec2 last_cursor = {
context->cursor[0],
context->cursor[1],
};
context->cursor[0] = xpos; context->cursor[0] = xpos;
context->cursor[1] = ypos; context->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
} else { } else {
context->cursor[0] = xpos;
context->cursor[1] = ypos;
update_hex_hover(context->cursor, context->hex, context->render); update_hex_hover(context->cursor, context->hex, context->render);
} }
}
} }
int main() { int main() {
@ -1035,9 +1026,9 @@ int main() {
glfwSetWindowUserPointer(context.window, &context); glfwSetWindowUserPointer(context.window, &context);
glfwSetKeyCallback(context.window, key_callback); glfwSetKeyCallback(context.window, key_callback);
glfwSetMouseButtonCallback(context.window, mouse_button_callback); glfwSetMouseButtonCallback(context.window, button_callback);
glfwSetScrollCallback(context.window, scroll_callback); glfwSetScrollCallback(context.window, scroll_callback);
glfwSetCursorPosCallback(context.window, cursor_pos_callback); glfwSetCursorPosCallback(context.window, cursor_callback);
int error; int error;
VkResult result; VkResult result;

@ -1150,15 +1150,26 @@ VkResult map_string(
VkResult update_ui_string( VkResult update_ui_string(
char* string, char* string,
uint32_t container_index, uint32_t container_id,
uint32_t layer_index, uint32_t layer_index,
uint32_t string_index, uint32_t string_index,
UIContext* ui, UIContext* ui,
RenderContext* gpu) { RenderContext* gpu) {
VkResult result; VkResult result;
Container* container = &ui->containers[container_index];
Layer* layer = &container->layers[layer_index];
uint32_t c;
for(c = 0; c < ui->max_containers; c++) {
if(ui->containers[c].id == container_id) {
break;
}
}
if(c == ui->max_containers) {
return VK_ERROR_UNKNOWN;
}
Container* container = &ui->containers[c];
Layer* layer = &container->layers[layer_index];
layer->strings_buffer[string_index].length = strlen(string); layer->strings_buffer[string_index].length = strlen(string);
if(strlen(string) > 0) { if(strlen(string) > 0) {
VK_RESULT(map_string( VK_RESULT(map_string(
@ -1183,3 +1194,79 @@ VkResult update_ui_string(
return VK_SUCCESS; return VK_SUCCESS;
} }
bool ui_contains(
double point[2],
vec2 container_offset,
vec2 container_size,
GPUDrawable* rect,
vec2 position) {
vec2 pos = {
container_offset[0] + rect->pos[0],
container_offset[1] + rect->pos[1],
};
if((point[0] >= pos[0] && point[0] <= pos[0] + rect->size[0]) &&
(point[1] >= pos[1] && point[1] <= pos[1] + rect->size[1]) &&
(point[0] >= container_offset[0] && point[0] <= container_offset[0] + container_size[0]) &&
(point[1] >= container_offset[1] && point[1] <= container_offset[1] + container_size[1])){
position[0] = (point[0] - pos[0])/rect->size[0];
position[1] = (point[1] - pos[1])/rect->size[1];
return true;
}
return false;
}
bool ui_intersect(
double cursor[2],
RenderContext* gpu,
UIContext* ui,
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;
}
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(
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;
return true;
}
}
}
}
return false;
}