|  |  |  | @ -22,10 +22,6 @@ typedef struct EditorContextStruct { | 
		
	
		
			
				|  |  |  |  |   uint32_t last_clicked_region; | 
		
	
		
			
				|  |  |  |  |   uint32_t last_clicked_hex; | 
		
	
		
			
				|  |  |  |  |   uint32_t last_clicked_vertex; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   vec4 saved_colors[12]; | 
		
	
		
			
				|  |  |  |  |   vec4 current_color; | 
		
	
		
			
				|  |  |  |  |   vec4 color_string; | 
		
	
		
			
				|  |  |  |  | } EditorContext; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | typedef struct ClientContextStruct { | 
		
	
	
		
			
				
					|  |  |  | @ -128,7 +124,7 @@ void hsv_to_rgb(vec3 hsv, vec3 rgb) { | 
		
	
		
			
				|  |  |  |  |    rgb[2] = temp[2] + m; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void rgb_string_set(ClientContext* context, vec3 hsv) { | 
		
	
		
			
				|  |  |  |  | void rgb_string_set(UIContext* ui, RenderContext* gpu, vec3 hsv) { | 
		
	
		
			
				|  |  |  |  |   vec3 rgb; | 
		
	
		
			
				|  |  |  |  |   hsv_to_rgb(hsv, rgb); | 
		
	
		
			
				|  |  |  |  |   char temp[10]; | 
		
	
	
		
			
				
					|  |  |  | @ -136,17 +132,17 @@ void rgb_string_set(ClientContext* context, vec3 hsv) { | 
		
	
		
			
				|  |  |  |  |       (uint)(rgb[0]*255), | 
		
	
		
			
				|  |  |  |  |       (uint)(rgb[1]*255), | 
		
	
		
			
				|  |  |  |  |       (uint)(rgb[2]*255)); | 
		
	
		
			
				|  |  |  |  |   update_ui_string(temp, COLOR_PICK_CONTAINER_ID, 0, 0, context->ui, context->render); | 
		
	
		
			
				|  |  |  |  |   update_ui_string(temp, COLOR_PICK_CONTAINER_ID, 0, 0, ui, gpu); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void sv_square_pick(ClientContext* context, float s, float v) { | 
		
	
		
			
				|  |  |  |  | void sv_square_pick(UIContext* ui, RenderContext* gpu, float s, float v) { | 
		
	
		
			
				|  |  |  |  |   if(s < 0) s = 0; | 
		
	
		
			
				|  |  |  |  |   if(s > 1) s = 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(v < 0) v = 0; | 
		
	
		
			
				|  |  |  |  |   if(v > 1) v = 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   Container* container = context_container(COLOR_PICK_CONTAINER_ID, context->ui); | 
		
	
		
			
				|  |  |  |  |   Container* container = context_container(COLOR_PICK_CONTAINER_ID, ui); | 
		
	
		
			
				|  |  |  |  |   Layer* layer = &container->layers[0]; | 
		
	
		
			
				|  |  |  |  |   GPUDrawable* select_outline = &layer->drawables_buffer[3]; | 
		
	
		
			
				|  |  |  |  |   GPUDrawable* select = &layer->drawables_buffer[4]; | 
		
	
	
		
			
				
					|  |  |  | @ -174,53 +170,50 @@ void sv_square_pick(ClientContext* context, float s, float v) { | 
		
	
		
			
				|  |  |  |  |       layer->drawables, | 
		
	
		
			
				|  |  |  |  |       3*sizeof(GPUDrawable) + offsetof(GPUDrawable, pos), | 
		
	
		
			
				|  |  |  |  |       1*sizeof(vec2), | 
		
	
		
			
				|  |  |  |  |       context->render); | 
		
	
		
			
				|  |  |  |  |       gpu); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   add_transfers( | 
		
	
		
			
				|  |  |  |  |       &select->pos[0], | 
		
	
		
			
				|  |  |  |  |       layer->drawables, | 
		
	
		
			
				|  |  |  |  |       4*sizeof(GPUDrawable) + offsetof(GPUDrawable, pos), | 
		
	
		
			
				|  |  |  |  |       1*sizeof(vec2), | 
		
	
		
			
				|  |  |  |  |       context->render); | 
		
	
		
			
				|  |  |  |  |       gpu); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   add_transfers( | 
		
	
		
			
				|  |  |  |  |       &select->color[0], | 
		
	
		
			
				|  |  |  |  |       layer->drawables, | 
		
	
		
			
				|  |  |  |  |       4*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | 
		
	
		
			
				|  |  |  |  |       4*sizeof(vec4), | 
		
	
		
			
				|  |  |  |  |       context->render); | 
		
	
		
			
				|  |  |  |  |       gpu); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   rgb_string_set(context, select->color[0]); | 
		
	
		
			
				|  |  |  |  |   rgb_string_set(ui, gpu, select->color[0]); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void sv_square_button_callback(void* ptr, float x, float y, int button, int action, int mods) { | 
		
	
		
			
				|  |  |  |  | void sv_square_button_callback(UIContext* ui, RenderContext* gpu, 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(COLOR_PICK_CONTAINER_ID, 0, 1, context->ui); | 
		
	
		
			
				|  |  |  |  |     sv_square_pick(context, x, y); | 
		
	
		
			
				|  |  |  |  |     set_active_element(COLOR_PICK_CONTAINER_ID, 0, 1, ui); | 
		
	
		
			
				|  |  |  |  |     sv_square_pick(ui, gpu, x, y); | 
		
	
		
			
				|  |  |  |  |   } else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) { | 
		
	
		
			
				|  |  |  |  |     clear_active_element(context->ui); | 
		
	
		
			
				|  |  |  |  |     clear_active_element(ui, gpu); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void sv_square_cursor_callback(void* ptr, float x, float y) { | 
		
	
		
			
				|  |  |  |  |   ClientContext* context = (ClientContext*)ptr; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(context->ui->active_element == 1 | 
		
	
		
			
				|  |  |  |  |   && context->ui->active_layer == 0 | 
		
	
		
			
				|  |  |  |  |   && context->ui->active_container == COLOR_PICK_CONTAINER_ID) { | 
		
	
		
			
				|  |  |  |  |     sv_square_pick(context, x, y); | 
		
	
		
			
				|  |  |  |  | void sv_square_cursor_callback(UIContext* ui, RenderContext* gpu, float x, float y) { | 
		
	
		
			
				|  |  |  |  |   if(ui->active_element == 1 | 
		
	
		
			
				|  |  |  |  |   && ui->active_layer == 0 | 
		
	
		
			
				|  |  |  |  |   && ui->active_container == COLOR_PICK_CONTAINER_ID) { | 
		
	
		
			
				|  |  |  |  |     sv_square_pick(ui, gpu, x, y); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hue_bar_set(ClientContext* context, float y) { | 
		
	
		
			
				|  |  |  |  | void hue_bar_set(UIContext* ui, RenderContext* gpu, float y) { | 
		
	
		
			
				|  |  |  |  |   if(y < 0) y = 0; | 
		
	
		
			
				|  |  |  |  |   if(y > 1) y = 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   Container* container = context_container(COLOR_PICK_CONTAINER_ID, context->ui); | 
		
	
		
			
				|  |  |  |  |   Container* container = context_container(COLOR_PICK_CONTAINER_ID, ui); | 
		
	
		
			
				|  |  |  |  |   Layer* layer = &container->layers[0]; | 
		
	
		
			
				|  |  |  |  |   GPUDrawable* sv_square = &layer->drawables_buffer[1]; | 
		
	
		
			
				|  |  |  |  |   GPUDrawable* select = &layer->drawables_buffer[4]; | 
		
	
	
		
			
				
					|  |  |  | @ -240,52 +233,95 @@ void hue_bar_set(ClientContext* context, float y) { | 
		
	
		
			
				|  |  |  |  |       layer->drawables, | 
		
	
		
			
				|  |  |  |  |       1*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | 
		
	
		
			
				|  |  |  |  |       4*sizeof(vec4), | 
		
	
		
			
				|  |  |  |  |       context->render); | 
		
	
		
			
				|  |  |  |  |       gpu); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   add_transfers( | 
		
	
		
			
				|  |  |  |  |       &select->color[0], | 
		
	
		
			
				|  |  |  |  |       layer->drawables, | 
		
	
		
			
				|  |  |  |  |       4*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | 
		
	
		
			
				|  |  |  |  |       4*sizeof(vec4), | 
		
	
		
			
				|  |  |  |  |       context->render); | 
		
	
		
			
				|  |  |  |  |       gpu); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   rgb_string_set(context, select->color[0]); | 
		
	
		
			
				|  |  |  |  |   rgb_string_set(ui, gpu, select->color[0]); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hue_bar_scroll_callback(void* ptr, double x, double y) { | 
		
	
		
			
				|  |  |  |  | void hue_bar_scroll_callback(UIContext* ui, RenderContext* gpu, double x, double y) { | 
		
	
		
			
				|  |  |  |  |   (void)x; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   ClientContext* context = (ClientContext*)ptr; | 
		
	
		
			
				|  |  |  |  |   Container* container = context_container(COLOR_PICK_CONTAINER_ID, ui); | 
		
	
		
			
				|  |  |  |  |   hue_bar_set(ui, gpu, y*0.01 + container->layers[0].drawables_buffer[1].color[0][0]); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hue_bar_cursor_callback(UIContext* ui, RenderContext* gpu, float x, float y) { | 
		
	
		
			
				|  |  |  |  |   (void)x; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   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]); | 
		
	
		
			
				|  |  |  |  |   if(ui->active_element == 2 | 
		
	
		
			
				|  |  |  |  |   && ui->active_layer == 0 | 
		
	
		
			
				|  |  |  |  |   && ui->active_container == COLOR_PICK_CONTAINER_ID) { | 
		
	
		
			
				|  |  |  |  |     hue_bar_set(ui, gpu, y); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hue_bar_cursor_callback(void* ptr, float x, float y) { | 
		
	
		
			
				|  |  |  |  | void hue_bar_button_callback(UIContext* ui, RenderContext* gpu, 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(COLOR_PICK_CONTAINER_ID, 0, 2, ui); | 
		
	
		
			
				|  |  |  |  |     hue_bar_set(ui, gpu, y); | 
		
	
		
			
				|  |  |  |  |   } else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) { | 
		
	
		
			
				|  |  |  |  |     clear_active_element(ui, gpu); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hex_string_set_color(UIContext* ui, RenderContext* gpu, float color) { | 
		
	
		
			
				|  |  |  |  |   Container* container = context_container(COLOR_PICK_CONTAINER_ID, ui); | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[0][2] = color; | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[0][3] = color; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[1][2] = color; | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[1][3] = color; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[2][2] = color; | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[2][3] = color; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[3][2] = color; | 
		
	
		
			
				|  |  |  |  |   container->layers[0].drawables_buffer[5].color[3][3] = color; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   add_transfers( | 
		
	
		
			
				|  |  |  |  |       &container->layers[0].drawables_buffer[5].color[0], | 
		
	
		
			
				|  |  |  |  |       container->layers[0].drawables, | 
		
	
		
			
				|  |  |  |  |       5*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | 
		
	
		
			
				|  |  |  |  |       4*sizeof(vec4), | 
		
	
		
			
				|  |  |  |  |       gpu); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool hex_string_key_callback(UIContext* ui, RenderContext* gpu, int key, int action, int mods) { | 
		
	
		
			
				|  |  |  |  |   (void)mods; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(context->ui->active_element == 2 | 
		
	
		
			
				|  |  |  |  |   && context->ui->active_layer == 0 | 
		
	
		
			
				|  |  |  |  |   && context->ui->active_container == COLOR_PICK_CONTAINER_ID) { | 
		
	
		
			
				|  |  |  |  |     hue_bar_set(context, y); | 
		
	
		
			
				|  |  |  |  |   if(action == GLFW_PRESS && key == GLFW_KEY_ESCAPE) { | 
		
	
		
			
				|  |  |  |  |     clear_active_element(ui, gpu); | 
		
	
		
			
				|  |  |  |  |     return true; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return false; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hue_bar_button_callback(void* ptr, float x, float y, int button, int action, int mods) { | 
		
	
		
			
				|  |  |  |  | void hex_string_button_callback(UIContext* ui, RenderContext* gpu, float x, float y, int button, int action, int mods) { | 
		
	
		
			
				|  |  |  |  |   (void)mods; | 
		
	
		
			
				|  |  |  |  |   (void)x; | 
		
	
		
			
				|  |  |  |  |   (void)y; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   ClientContext* context = (ClientContext*)ptr; | 
		
	
		
			
				|  |  |  |  |   if(action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT) { | 
		
	
		
			
				|  |  |  |  |     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); | 
		
	
		
			
				|  |  |  |  |     set_active_element(COLOR_PICK_CONTAINER_ID, 0, 5, ui); | 
		
	
		
			
				|  |  |  |  |     hex_string_set_color(ui, gpu, 1); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void hex_string_deselect_callback(UIContext* ui, RenderContext* gpu) { | 
		
	
		
			
				|  |  |  |  |   hex_string_set_color(ui, gpu, 0); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult color_ui(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |   GPUString strings[] = { | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
	
		
			
				
					|  |  |  | @ -332,6 +368,7 @@ VkResult color_ui(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .pos = {20, 134}, | 
		
	
		
			
				|  |  |  |  |       .size = {95, 15}, | 
		
	
		
			
				|  |  |  |  |       .events = UI_EVENT_BUTTON | UI_EVENT_CURSOR, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .pos = {146, 2}, | 
		
	
	
		
			
				
					|  |  |  | @ -422,6 +459,13 @@ VkResult color_ui(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |       .cursor = hue_bar_cursor_callback, | 
		
	
		
			
				|  |  |  |  |       .scroll = hue_bar_scroll_callback, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .layer = 0, | 
		
	
		
			
				|  |  |  |  |       .element = 5, | 
		
	
		
			
				|  |  |  |  |       .button = hex_string_button_callback, | 
		
	
		
			
				|  |  |  |  |       .key = hex_string_key_callback, | 
		
	
		
			
				|  |  |  |  |       .deselect = hex_string_deselect_callback, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   ContainerInput container = { | 
		
	
	
		
			
				
					|  |  |  | @ -893,237 +937,239 @@ 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) { | 
		
	
		
			
				|  |  |  |  |     context->ui->active_callbacks->key(context, key, action, mods); | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     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; | 
		
	
		
			
				|  |  |  |  |     if(context->ui->active_callbacks->key(context->ui, context->render, key, action, mods)) { | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_W: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->key_spin[1] += 1; | 
		
	
		
			
				|  |  |  |  |         } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |           context->key_spin[1] -= 1; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_S: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->key_spin[1] -= 1; | 
		
	
		
			
				|  |  |  |  |         } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |           context->key_spin[1] += 1; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |   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_UP: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[2] += 1; | 
		
	
		
			
				|  |  |  |  |         } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[2] -= 1; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_DOWN: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[2] -= 1; | 
		
	
		
			
				|  |  |  |  |         } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[2] += 1; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_W: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->key_spin[1] += 1; | 
		
	
		
			
				|  |  |  |  |       } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |         context->key_spin[1] -= 1; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_S: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->key_spin[1] -= 1; | 
		
	
		
			
				|  |  |  |  |       } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |         context->key_spin[1] += 1; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_LEFT: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[0] -= 1; | 
		
	
		
			
				|  |  |  |  |         } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[0] += 1; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_RIGHT: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[0] += 1; | 
		
	
		
			
				|  |  |  |  |         } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[0] -= 1; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_UP: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[2] += 1; | 
		
	
		
			
				|  |  |  |  |       } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[2] -= 1; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_DOWN: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[2] -= 1; | 
		
	
		
			
				|  |  |  |  |       } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[2] += 1; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_LEFT_SHIFT: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->velocity[1] -= 1; | 
		
	
		
			
				|  |  |  |  |         } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |           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: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[0] -= 1; | 
		
	
		
			
				|  |  |  |  |       } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[0] += 1; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_RIGHT: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[0] += 1; | 
		
	
		
			
				|  |  |  |  |       } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[0] -= 1; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_EQUAL: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->editor.selected_region = add_hex_region(context); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_LEFT_SHIFT: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->velocity[1] -= 1; | 
		
	
		
			
				|  |  |  |  |       } else if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |         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: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->editor.selected_region -= 1; | 
		
	
		
			
				|  |  |  |  |           if(context->editor.selected_region > MAX_LOADED_REGIONS) { | 
		
	
		
			
				|  |  |  |  |             context->editor.selected_region = MAX_LOADED_REGIONS; | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_EQUAL: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->editor.selected_region = add_hex_region(context); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_LEFT_BRACKET: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->editor.selected_region -= 1; | 
		
	
		
			
				|  |  |  |  |         if(context->editor.selected_region > MAX_LOADED_REGIONS) { | 
		
	
		
			
				|  |  |  |  |           context->editor.selected_region = MAX_LOADED_REGIONS; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_RIGHT_BRACKET: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           context->editor.selected_region += 1; | 
		
	
		
			
				|  |  |  |  |           if(context->editor.selected_region > MAX_LOADED_REGIONS) { | 
		
	
		
			
				|  |  |  |  |             context->editor.selected_region = 0; | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_RIGHT_BRACKET: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         context->editor.selected_region += 1; | 
		
	
		
			
				|  |  |  |  |         if(context->editor.selected_region > MAX_LOADED_REGIONS) { | 
		
	
		
			
				|  |  |  |  |           context->editor.selected_region = 0; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_I: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |             context->hex->regions[context->editor.selected_region]->data.q += 1; | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 &context->hex->regions[context->editor.selected_region]->data.q, | 
		
	
		
			
				|  |  |  |  |                 context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, q), | 
		
	
		
			
				|  |  |  |  |                 sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |                 context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |                 context->render); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_I: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |           context->hex->regions[context->editor.selected_region]->data.q += 1; | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               &context->hex->regions[context->editor.selected_region]->data.q, | 
		
	
		
			
				|  |  |  |  |               context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, q), | 
		
	
		
			
				|  |  |  |  |               sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |               context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |               context->render); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_K: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |             context->hex->regions[context->editor.selected_region]->data.q -= 1; | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 &context->hex->regions[context->editor.selected_region]->data.q, | 
		
	
		
			
				|  |  |  |  |                 context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, q), | 
		
	
		
			
				|  |  |  |  |                 sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |                 context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |                 context->render); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |         update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_K: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |           context->hex->regions[context->editor.selected_region]->data.q -= 1; | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               &context->hex->regions[context->editor.selected_region]->data.q, | 
		
	
		
			
				|  |  |  |  |               context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, q), | 
		
	
		
			
				|  |  |  |  |               sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |               context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |               context->render); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_J: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |             context->hex->regions[context->editor.selected_region]->data.r += 1; | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 &context->hex->regions[context->editor.selected_region]->data.r, | 
		
	
		
			
				|  |  |  |  |                 context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, r), | 
		
	
		
			
				|  |  |  |  |                 sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |                 context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |                 context->render); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |         update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_J: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |           context->hex->regions[context->editor.selected_region]->data.r += 1; | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               &context->hex->regions[context->editor.selected_region]->data.r, | 
		
	
		
			
				|  |  |  |  |               context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, r), | 
		
	
		
			
				|  |  |  |  |               sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |               context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |               context->render); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_L: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |             context->hex->regions[context->editor.selected_region]->data.r -= 1; | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 &context->hex->regions[context->editor.selected_region]->data.r, | 
		
	
		
			
				|  |  |  |  |                 context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, r), | 
		
	
		
			
				|  |  |  |  |                 sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |                 context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |                 context->render); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |         update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_L: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |           context->hex->regions[context->editor.selected_region]->data.r -= 1; | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               &context->hex->regions[context->editor.selected_region]->data.r, | 
		
	
		
			
				|  |  |  |  |               context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, r), | 
		
	
		
			
				|  |  |  |  |               sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |               context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |               context->render); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_O: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |             context->hex->regions[context->editor.selected_region]->data.y += 1; | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 &context->hex->regions[context->editor.selected_region]->data.y, | 
		
	
		
			
				|  |  |  |  |                 context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, y), | 
		
	
		
			
				|  |  |  |  |                 sizeof(int32_t), | 
		
	
		
			
				|  |  |  |  |                 context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |                 context->render); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |         update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_O: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |           context->hex->regions[context->editor.selected_region]->data.y += 1; | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               &context->hex->regions[context->editor.selected_region]->data.y, | 
		
	
		
			
				|  |  |  |  |               context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, y), | 
		
	
		
			
				|  |  |  |  |               sizeof(int32_t), | 
		
	
		
			
				|  |  |  |  |               context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |               context->render); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_U: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |             context->hex->regions[context->editor.selected_region]->data.y -= 1; | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 &context->hex->regions[context->editor.selected_region]->data.y, | 
		
	
		
			
				|  |  |  |  |                 context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, y), | 
		
	
		
			
				|  |  |  |  |                 sizeof(int32_t), | 
		
	
		
			
				|  |  |  |  |                 context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |                 context->render); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |         update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_U: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         if(context->hex->regions[context->editor.selected_region] != NULL) { | 
		
	
		
			
				|  |  |  |  |           context->hex->regions[context->editor.selected_region]->data.y -= 1; | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               &context->hex->regions[context->editor.selected_region]->data.y, | 
		
	
		
			
				|  |  |  |  |               context->hex->regions[context->editor.selected_region]->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, y), | 
		
	
		
			
				|  |  |  |  |               sizeof(int32_t), | 
		
	
		
			
				|  |  |  |  |               context->render->current_frame, | 
		
	
		
			
				|  |  |  |  |               context->render); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |         update_region_info_ui(context); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_Y: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           HexRegion* region = context->hex->regions[context->hex->data.clicked_region]; | 
		
	
		
			
				|  |  |  |  |           if(region != NULL) { | 
		
	
		
			
				|  |  |  |  |             region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] += 0.1;  | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 ®ion->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1], | 
		
	
		
			
				|  |  |  |  |                 region->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, hexes) | 
		
	
		
			
				|  |  |  |  |                 + 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); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_Y: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         HexRegion* region = context->hex->regions[context->hex->data.clicked_region]; | 
		
	
		
			
				|  |  |  |  |         if(region != NULL) { | 
		
	
		
			
				|  |  |  |  |           region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] += 0.1;  | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               ®ion->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1], | 
		
	
		
			
				|  |  |  |  |               region->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, hexes) | 
		
	
		
			
				|  |  |  |  |               + 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; | 
		
	
		
			
				|  |  |  |  |       case GLFW_KEY_H: | 
		
	
		
			
				|  |  |  |  |         if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |           HexRegion* region = context->hex->regions[context->hex->data.clicked_region]; | 
		
	
		
			
				|  |  |  |  |           if(region != NULL) { | 
		
	
		
			
				|  |  |  |  |             region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] -= 0.1;  | 
		
	
		
			
				|  |  |  |  |             add_transfer( | 
		
	
		
			
				|  |  |  |  |                 ®ion->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1], | 
		
	
		
			
				|  |  |  |  |                 region->region, | 
		
	
		
			
				|  |  |  |  |                 offsetof(GPUHexRegion, hexes) | 
		
	
		
			
				|  |  |  |  |                 + 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; | 
		
	
		
			
				|  |  |  |  |     case GLFW_KEY_H: | 
		
	
		
			
				|  |  |  |  |       if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |         HexRegion* region = context->hex->regions[context->hex->data.clicked_region]; | 
		
	
		
			
				|  |  |  |  |         if(region != NULL) { | 
		
	
		
			
				|  |  |  |  |           region->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1] -= 0.1;  | 
		
	
		
			
				|  |  |  |  |           add_transfer( | 
		
	
		
			
				|  |  |  |  |               ®ion->data.hexes[context->hex->data.clicked_hex].height[context->hex->data.clicked_vertex-1], | 
		
	
		
			
				|  |  |  |  |               region->region, | 
		
	
		
			
				|  |  |  |  |               offsetof(GPUHexRegion, hexes) | 
		
	
		
			
				|  |  |  |  |               + 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; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -1150,33 +1196,48 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) { | 
		
	
		
			
				|  |  |  |  |       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, UI_EVENT_BUTTON, &container, &layer, &element, position)) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     vec2 point = { | 
		
	
		
			
				|  |  |  |  |       (cursor[0] - element_pos[0])/element_size[0], | 
		
	
		
			
				|  |  |  |  |       (cursor[1] - element_pos[1])/element_size[1], | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     if(point[0] <= 1 && point[0] >= 0 && point[1] <= 1 && point[1] >= 0) { | 
		
	
		
			
				|  |  |  |  |       context->ui->active_callbacks->button( | 
		
	
		
			
				|  |  |  |  |           context->ui, | 
		
	
		
			
				|  |  |  |  |           context->render, | 
		
	
		
			
				|  |  |  |  |           point[0], | 
		
	
		
			
				|  |  |  |  |           point[1], | 
		
	
		
			
				|  |  |  |  |           button, | 
		
	
		
			
				|  |  |  |  |           action, | 
		
	
		
			
				|  |  |  |  |           mods); | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       clear_active_element(context->ui, context->render); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   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) { | 
		
	
		
			
				|  |  |  |  |         if(container_ptr->callbacks[c].button != NULL) { | 
		
	
		
			
				|  |  |  |  |           container_ptr->callbacks[c].button(context, position[0], position[1], button, action, mods); | 
		
	
		
			
				|  |  |  |  |           container_ptr->callbacks[c].button(context->ui, context->render, position[0], position[1], button, action, mods); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     update_hex_click(cursor, context->hex, context->render); | 
		
	
		
			
				|  |  |  |  |     if(button == GLFW_MOUSE_BUTTON_MIDDLE) { | 
		
	
		
			
				|  |  |  |  |       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; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   update_hex_click(cursor, context->hex, context->render); | 
		
	
		
			
				|  |  |  |  |   if(button == GLFW_MOUSE_BUTTON_MIDDLE) { | 
		
	
		
			
				|  |  |  |  |     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; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | @ -1190,7 +1251,7 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   ClientContext* context = (ClientContext*)glfwGetWindowUserPointer(window); | 
		
	
		
			
				|  |  |  |  |   if(context->ui->active_callbacks != NULL && context->ui->active_callbacks->scroll != NULL) { | 
		
	
		
			
				|  |  |  |  |     context->ui->active_callbacks->scroll(context, xoffset, yoffset); | 
		
	
		
			
				|  |  |  |  |     context->ui->active_callbacks->scroll(context->ui, context->render, xoffset, yoffset); | 
		
	
		
			
				|  |  |  |  |   } else if(ui_intersect( | 
		
	
		
			
				|  |  |  |  |         context->ui->cursor, | 
		
	
		
			
				|  |  |  |  |         context->render, | 
		
	
	
		
			
				
					|  |  |  | @ -1204,7 +1265,7 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { | 
		
	
		
			
				|  |  |  |  |     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); | 
		
	
		
			
				|  |  |  |  |           container_ptr->callbacks[c].scroll(context->ui, context->render, xoffset, yoffset); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
	
		
			
				
					|  |  |  | @ -1245,16 +1306,16 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) { | 
		
	
		
			
				|  |  |  |  |         drawable_ptr->size[1], | 
		
	
		
			
				|  |  |  |  |       }; | 
		
	
		
			
				|  |  |  |  |       context->ui->active_callbacks->cursor( | 
		
	
		
			
				|  |  |  |  |           context, | 
		
	
		
			
				|  |  |  |  |           context->ui, | 
		
	
		
			
				|  |  |  |  |           context->render, | 
		
	
		
			
				|  |  |  |  |           (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, 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) { | 
		
	
		
			
				|  |  |  |  |           if(container_ptr->callbacks[c].button != NULL) { | 
		
	
		
			
				|  |  |  |  |             container_ptr->callbacks[c].cursor(context, position[0], position[1]); | 
		
	
		
			
				|  |  |  |  |           if(container_ptr->callbacks[c].cursor != NULL) { | 
		
	
		
			
				|  |  |  |  |             container_ptr->callbacks[c].cursor(context->ui, context->render, position[0], position[1]); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           break; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
	
		
			
				
					|  |  |  | 
 |