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,318 +683,314 @@ 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;
switch(key) {
case GLFW_KEY_A:
if(action == GLFW_PRESS) {
context->key_spin[0] -= 1;
} else if(action == GLFW_RELEASE) {
context->key_spin[0] += 1;
}
break;
case GLFW_KEY_D:
if(action == GLFW_PRESS) {
context->key_spin[0] += 1;
} else if(action == GLFW_RELEASE) {
context->key_spin[0] -= 1;
}
break;
case GLFW_KEY_W: ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window);
if(action == GLFW_PRESS) { if(context->ui->active_captures & UI_EVENT_KEY) {
context->key_spin[1] += 1; // Pass key to active element
} else if(action == GLFW_RELEASE) { } else {
context->key_spin[1] -= 1; switch(key) {
} case GLFW_KEY_A:
break; if(action == GLFW_PRESS) {
case GLFW_KEY_S: context->key_spin[0] -= 1;
if(action == GLFW_PRESS) { } else if(action == GLFW_RELEASE) {
context->key_spin[1] -= 1; context->key_spin[0] += 1;
} else if(action == GLFW_RELEASE) { }
context->key_spin[1] += 1; break;
} case GLFW_KEY_D:
break; if(action == GLFW_PRESS) {
context->key_spin[0] += 1;
} else if(action == GLFW_RELEASE) {
context->key_spin[0] -= 1;
}
break;
case GLFW_KEY_UP: case GLFW_KEY_W:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->velocity[2] += 1; context->key_spin[1] += 1;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
context->velocity[2] -= 1; context->key_spin[1] -= 1;
} }
break; break;
case GLFW_KEY_DOWN: case GLFW_KEY_S:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->velocity[2] -= 1; context->key_spin[1] -= 1;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
context->velocity[2] += 1; context->key_spin[1] += 1;
} }
break; break;
case GLFW_KEY_LEFT: case GLFW_KEY_UP:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->velocity[0] -= 1; context->velocity[2] += 1;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
context->velocity[0] += 1; context->velocity[2] -= 1;
} }
break; break;
case GLFW_KEY_RIGHT: case GLFW_KEY_DOWN:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->velocity[0] += 1; context->velocity[2] -= 1;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
context->velocity[0] -= 1; context->velocity[2] += 1;
} }
break; break;
case GLFW_KEY_LEFT_SHIFT: case GLFW_KEY_LEFT:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->velocity[1] -= 1; context->velocity[0] -= 1;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
context->velocity[1] += 1; context->velocity[0] += 1;
} }
break; break;
case GLFW_KEY_SPACE: case GLFW_KEY_RIGHT:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->velocity[1] += 1; context->velocity[0] += 1;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
context->velocity[1] -= 1; context->velocity[0] -= 1;
} }
break; break;
case GLFW_KEY_EQUAL: case GLFW_KEY_LEFT_SHIFT:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->editor.selected_region = add_hex_region(context); context->velocity[1] -= 1;
} } else if(action == GLFW_RELEASE) {
break; context->velocity[1] += 1;
}
break;
case GLFW_KEY_SPACE:
if(action == GLFW_PRESS) {
context->velocity[1] += 1;
} else if(action == GLFW_RELEASE) {
context->velocity[1] -= 1;
}
break;
case GLFW_KEY_LEFT_BRACKET: case GLFW_KEY_EQUAL:
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
context->editor.selected_region -= 1; context->editor.selected_region = add_hex_region(context);
if(context->editor.selected_region > MAX_LOADED_REGIONS) { }
context->editor.selected_region = MAX_LOADED_REGIONS; break;
}
} case GLFW_KEY_LEFT_BRACKET:
break; if(action == GLFW_PRESS) {
case GLFW_KEY_RIGHT_BRACKET: context->editor.selected_region -= 1;
if(action == GLFW_PRESS) { if(context->editor.selected_region > MAX_LOADED_REGIONS) {
context->editor.selected_region += 1; context->editor.selected_region = MAX_LOADED_REGIONS;
if(context->editor.selected_region > MAX_LOADED_REGIONS) { }
context->editor.selected_region = 0; }
} break;
} case GLFW_KEY_RIGHT_BRACKET:
break; if(action == GLFW_PRESS) {
context->editor.selected_region += 1;
case GLFW_KEY_I: if(context->editor.selected_region > MAX_LOADED_REGIONS) {
if(action == GLFW_PRESS) { context->editor.selected_region = 0;
if(context->hex->regions[context->editor.selected_region] != NULL) { }
context->hex->regions[context->editor.selected_region]->data.q += 1; }
add_transfer( break;
&context->hex->regions[context->editor.selected_region]->data.q,
context->hex->regions[context->editor.selected_region]->region, case GLFW_KEY_I:
offsetof(GPUHexRegion, q), if(action == GLFW_PRESS) {
sizeof(uint32_t), if(context->hex->regions[context->editor.selected_region] != NULL) {
context->render->current_frame, context->hex->regions[context->editor.selected_region]->data.q += 1;
context->render); add_transfer(
} &context->hex->regions[context->editor.selected_region]->data.q,
update_region_info_ui(context); context->hex->regions[context->editor.selected_region]->region,
} offsetof(GPUHexRegion, q),
break; sizeof(uint32_t),
case GLFW_KEY_K: context->render->current_frame,
if(action == GLFW_PRESS) { context->render);
if(context->hex->regions[context->editor.selected_region] != NULL) { }
context->hex->regions[context->editor.selected_region]->data.q -= 1; update_region_info_ui(context);
add_transfer( }
&context->hex->regions[context->editor.selected_region]->data.q, break;
context->hex->regions[context->editor.selected_region]->region, case GLFW_KEY_K:
offsetof(GPUHexRegion, q), if(action == GLFW_PRESS) {
sizeof(uint32_t), if(context->hex->regions[context->editor.selected_region] != NULL) {
context->render->current_frame, context->hex->regions[context->editor.selected_region]->data.q -= 1;
context->render); add_transfer(
} &context->hex->regions[context->editor.selected_region]->data.q,
update_region_info_ui(context); context->hex->regions[context->editor.selected_region]->region,
} offsetof(GPUHexRegion, q),
break; sizeof(uint32_t),
case GLFW_KEY_J: context->render->current_frame,
if(action == GLFW_PRESS) { context->render);
if(context->hex->regions[context->editor.selected_region] != NULL) { }
context->hex->regions[context->editor.selected_region]->data.r += 1; update_region_info_ui(context);
add_transfer( }
&context->hex->regions[context->editor.selected_region]->data.r, break;
context->hex->regions[context->editor.selected_region]->region, case GLFW_KEY_J:
offsetof(GPUHexRegion, r), if(action == GLFW_PRESS) {
sizeof(uint32_t), if(context->hex->regions[context->editor.selected_region] != NULL) {
context->render->current_frame, context->hex->regions[context->editor.selected_region]->data.r += 1;
context->render); add_transfer(
} &context->hex->regions[context->editor.selected_region]->data.r,
update_region_info_ui(context); context->hex->regions[context->editor.selected_region]->region,
} offsetof(GPUHexRegion, r),
break; sizeof(uint32_t),
case GLFW_KEY_L: context->render->current_frame,
if(action == GLFW_PRESS) { context->render);
if(context->hex->regions[context->editor.selected_region] != NULL) { }
context->hex->regions[context->editor.selected_region]->data.r -= 1; update_region_info_ui(context);
add_transfer( }
&context->hex->regions[context->editor.selected_region]->data.r, break;
context->hex->regions[context->editor.selected_region]->region, case GLFW_KEY_L:
offsetof(GPUHexRegion, r), if(action == GLFW_PRESS) {
sizeof(uint32_t), if(context->hex->regions[context->editor.selected_region] != NULL) {
context->render->current_frame, context->hex->regions[context->editor.selected_region]->data.r -= 1;
context->render); add_transfer(
} &context->hex->regions[context->editor.selected_region]->data.r,
update_region_info_ui(context); context->hex->regions[context->editor.selected_region]->region,
} offsetof(GPUHexRegion, r),
break; sizeof(uint32_t),
case GLFW_KEY_O: context->render->current_frame,
if(action == GLFW_PRESS) { context->render);
if(context->hex->regions[context->editor.selected_region] != NULL) { }
context->hex->regions[context->editor.selected_region]->data.y += 1; update_region_info_ui(context);
add_transfer( }
&context->hex->regions[context->editor.selected_region]->data.y, break;
context->hex->regions[context->editor.selected_region]->region, case GLFW_KEY_O:
offsetof(GPUHexRegion, y), if(action == GLFW_PRESS) {
sizeof(int32_t), if(context->hex->regions[context->editor.selected_region] != NULL) {
context->render->current_frame, context->hex->regions[context->editor.selected_region]->data.y += 1;
context->render); add_transfer(
} &context->hex->regions[context->editor.selected_region]->data.y,
update_region_info_ui(context); context->hex->regions[context->editor.selected_region]->region,
} offsetof(GPUHexRegion, y),
break; sizeof(int32_t),
case GLFW_KEY_U: context->render->current_frame,
if(action == GLFW_PRESS) { context->render);
if(context->hex->regions[context->editor.selected_region] != NULL) { }
context->hex->regions[context->editor.selected_region]->data.y -= 1; update_region_info_ui(context);
add_transfer( }
&context->hex->regions[context->editor.selected_region]->data.y, break;
context->hex->regions[context->editor.selected_region]->region, case GLFW_KEY_U:
offsetof(GPUHexRegion, y), if(action == GLFW_PRESS) {
sizeof(int32_t), if(context->hex->regions[context->editor.selected_region] != NULL) {
context->render->current_frame, context->hex->regions[context->editor.selected_region]->data.y -= 1;
context->render); add_transfer(
} &context->hex->regions[context->editor.selected_region]->data.y,
update_region_info_ui(context); context->hex->regions[context->editor.selected_region]->region,
} offsetof(GPUHexRegion, y),
break; sizeof(int32_t),
context->render->current_frame,
case GLFW_KEY_Y: context->render);
if(action == GLFW_PRESS) { }
HexRegion* region = context->hex->regions[context->hex->data.clicked_region]; update_region_info_ui(context);
if(region != NULL) { }
region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] += 0.1; break;
add_transfer(
&region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1], case GLFW_KEY_Y:
region->region, if(action == GLFW_PRESS) {
offsetof(GPUHexRegion, hexes) HexRegion* region = context->hex->regions[context->hex->data.clicked_region];
+ sizeof(GPUHex)*context->hex->data.clicked_hex if(region != NULL) {
+ offsetof(GPUHex, height) region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] += 0.1;
+ sizeof(float)*(context->hex->data.clicked_vertex-1), add_transfer(
sizeof(float), &region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1],
context->render->current_frame, region->region,
context->render); offsetof(GPUHexRegion, hexes)
update_hex_info_ui(context); + sizeof(GPUHex)*context->hex->data.clicked_hex
} + offsetof(GPUHex, height)
} + sizeof(float)*(context->hex->data.clicked_vertex-1),
break; sizeof(float),
case GLFW_KEY_H: context->render->current_frame,
if(action == GLFW_PRESS) { context->render);
HexRegion* region = context->hex->regions[context->hex->data.clicked_region]; update_hex_info_ui(context);
if(region != NULL) { }
region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] -= 0.1; }
add_transfer( break;
&region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1], case GLFW_KEY_H:
region->region, if(action == GLFW_PRESS) {
offsetof(GPUHexRegion, hexes) HexRegion* region = context->hex->regions[context->hex->data.clicked_region];
+ sizeof(GPUHex)*context->hex->data.clicked_hex if(region != NULL) {
+ offsetof(GPUHex, height) region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] -= 0.1;
+ sizeof(float)*(context->hex->data.clicked_vertex-1), add_transfer(
sizeof(float), &region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1],
context->render->current_frame, region->region,
context->render); offsetof(GPUHexRegion, hexes)
update_hex_info_ui(context); + sizeof(GPUHex)*context->hex->data.clicked_hex
} + offsetof(GPUHex, height)
+ sizeof(float)*(context->hex->data.clicked_vertex-1),
sizeof(float),
context->render->current_frame,
context->render);
update_hex_info_ui(context);
}
}
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
case GLFW_MOUSE_BUTTON_RIGHT:
if(action == GLFW_PRESS) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
context->camera_mode = true;
} else {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
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++) { if(context->ui->active_captures & UI_EVENT_BUTTON) {
for(uint32_t d = 0; d < context->ui->containers[c].layers[l].data.num_drawables; d++) { // Pass button to active element
if(context->ui->containers[c].layers[l].drawables_buffer[d].id == 0x00000000) { } else if(ui_intersect(cursor, context->render, context->ui, &container, &element, position)) {
continue; // Pass button to active UI element
} } else {
if(contains( update_hex_click(cursor, context->hex, context->render);
cursor, if(button == GLFW_MOUSE_BUTTON_MIDDLE) {
&context->ui->containers[c].data, if(action == GLFW_PRESS) {
&context->ui->containers[c].layers[l].drawables_buffer[d])) { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
context->clicked_container = context->ui->containers[c].id; context->camera_mode = true;
context->clicked_element = context->ui->containers[c].layers[l].drawables_buffer[d].id; } else {
} glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
} context->camera_mode = false;
}
} }
} }
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;
context->zoom = -yoffset; 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;
}
} }
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[1] = ypos;
context->cursor[0] = xpos; if(context->camera_mode == true) {
context->cursor[1] = ypos; 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 { } else {
context->cursor[0] = xpos; if(context->ui->active_captures & UI_EVENT_CURSOR) {
context->cursor[1] = ypos; // Pass cursor to active element
update_hex_hover(context->cursor, context->hex, context->render); } else if(ui_intersect(context->cursor, context->render, context->ui, &container, &element, position)) {
// Pass cursor to hovered element
} else {
update_hex_hover(context->cursor, context->hex, context->render);
}
} }
} }
@ -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;
}