Compare commits
	
		
			No commits in common. "46dd8625120376fd538e4a23dd3de3b65c23ca32" and "b436268ffa908898e7ba77dc86df8541d94b11dc" have entirely different histories. 
		
	
	
		
			46dd862512
			...
			b436268ffa
		
	
		
							
								
								
									
										4
									
								
								justfile
								
								
								
								
							
							
						
						
									
										4
									
								
								justfile
								
								
								
								
							|  | @ -3,8 +3,8 @@ alias r := run | ||||||
| 
 | 
 | ||||||
| build: transpile_shaders_metal | build: transpile_shaders_metal | ||||||
|     mkdir -p bin |     mkdir -p bin | ||||||
|     cc -Ivendor/ -g -Wall -Wextra -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC src/*.c -o bin/an_editor |     # cc -Ivendor/ -g -Wall -Wextra -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC src/*.c -o bin/an_editor | ||||||
|     # cc -Ivendor/ -g -Wall -Wextra src/*.c -o bin/an_editor -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor |     cc -Ivendor/ -g -Wall -Wextra src/*.c -o bin/an_editor -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor | ||||||
|     # cc bin/*.o -o bin/an_editor -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor |     # cc bin/*.o -o bin/an_editor -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor | ||||||
| 
 | 
 | ||||||
| run: build | run: build | ||||||
|  |  | ||||||
|  | @ -15,23 +15,23 @@ struct VertexOutput { | ||||||
|     @location(0) tex_coord: vec2<f32>, |     @location(0) tex_coord: vec2<f32>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct Params { | // struct Params { | ||||||
|     screen_size: vec4<f32>, | //     screen_size: vec4<f32>, | ||||||
| } | // } | ||||||
| 
 | 
 | ||||||
| fn to_device_position(position: vec2<f32>, size: vec2<f32>) -> vec4<f32> { | fn to_device_position(position: vec2<f32>, size: vec2<f32>) -> vec4<f32> { | ||||||
|     return vec4<f32>((((position / size) * 2.) - 1.), 1., 1.); |     return vec4<f32>((((position / size) * 2.) - 1.), 1., 1.); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @group(0) @binding(0) | @group(0) @binding(0) | ||||||
| var<uniform> params: Params; | var<uniform> screen_size: vec4<f32>; | ||||||
| 
 | 
 | ||||||
| @vertex | @vertex | ||||||
| fn vs_main(input: VertexInput) -> VertexOutput { | fn vs_main(input: VertexInput) -> VertexOutput { | ||||||
|     var out: VertexOutput; |     var out: VertexOutput; | ||||||
| 
 | 
 | ||||||
|     var vertex_pos = to_device_position(((input.position.xy + 1.) / 2.) * (input.size/2.0) + input.target_position + vec2<f32>(0., (input.y_offset/2.0)+32), params.screen_size.xy); |     var vertex_pos = to_device_position(((input.position.xy + 1.) / 2.) * (input.size/2.0) + input.target_position + vec2<f32>(0., (input.y_offset/2.0)+32), screen_size.xy); | ||||||
|     vertex_pos.y = -vertex_pos.y; |     // vertex_pos.y = -vertex_pos.y; | ||||||
|     var atlas_position = (((input.position.xy + 1.) / 2.) * input.size + input.atlas_position) / vec2<f32>(1024); |     var atlas_position = (((input.position.xy + 1.) / 2.) * input.size + input.atlas_position) / vec2<f32>(1024); | ||||||
| 
 | 
 | ||||||
|     out.position = vertex_pos; |     out.position = vertex_pos; | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										39
									
								
								src/main.c
								
								
								
								
							|  | @ -14,13 +14,8 @@ | ||||||
| #define SOKOL_LOG_IMPL | #define SOKOL_LOG_IMPL | ||||||
| 
 | 
 | ||||||
| // TODO: condition compilation
 | // TODO: condition compilation
 | ||||||
| #if defined (__APPLE__) | // #define SOKOL_METAL
 | ||||||
|     #define SOKOL_METAL |  | ||||||
| #elif defined (__linux__) || defined (__unix__) |  | ||||||
| #define SOKOL_GLCORE33 | #define SOKOL_GLCORE33 | ||||||
| #else |  | ||||||
|     #error "Unsupported platform for shaders" |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| #include <sokol/sokol_log.h> | #include <sokol/sokol_log.h> | ||||||
| #include <sokol/sokol_gfx.h> | #include <sokol/sokol_gfx.h> | ||||||
|  | @ -145,7 +140,6 @@ void ed_init() { | ||||||
|     // TODO: grab default font from the system
 |     // TODO: grab default font from the system
 | ||||||
|     FILE *ttf_file = fopen("./bin/JetBrainsMono-Medium.ttf", "rb"); |     FILE *ttf_file = fopen("./bin/JetBrainsMono-Medium.ttf", "rb"); | ||||||
|     if (!ttf_file) { |     if (!ttf_file) { | ||||||
|         fprintf(stderr, "failed to load font\n"); |  | ||||||
|         exit(1); |         exit(1); | ||||||
|     } |     } | ||||||
|     assert(fread(ttf_buffer, 1, 1<<20, ttf_file)); |     assert(fread(ttf_buffer, 1, 1<<20, ttf_file)); | ||||||
|  | @ -307,36 +301,33 @@ void ed_init() { | ||||||
|         }, |         }, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     // queue_text(_String("But what even is text! []!@#$%^&*()_=+"), (float[]){ 0, 0 });
 |     queue_text(_String("But what even is text! []!@#$%^&*()_=+"), (float[]){ 0, 0 }); | ||||||
|     // queue_text(_String("v0.1.0"), (float[]){ 32, 128 });
 |     queue_text(_String("v0.1.0"), (float[]){ 32, 128 }); | ||||||
|     // queue_text(_String("an_editor - what even"), (float[]){ 32, 256 });
 |     queue_text(_String("an_editor - what even"), (float[]){ 32, 256 }); | ||||||
| 
 | 
 | ||||||
|     state.ui_cx = ui_init_context(); |     state.ui_cx = init_ui_context(); | ||||||
| 
 | 
 | ||||||
| } |  | ||||||
| void ed_frame() { |  | ||||||
|     string label = _String("Number 1"); |     string label = _String("Number 1"); | ||||||
|     ui_element(&state.ui_cx, label); |     ht_set(&state.ui_cx.cached_elements, label, &(ui_element_cache_data) { | ||||||
|     ui_element(&state.ui_cx, _String("ui element 2")); |         .label = label, | ||||||
|     ui_element(&state.ui_cx, _String("ui element 3")); |         .size = { | ||||||
|  |             .axis = UI_AXIS_HORIZONTAL, | ||||||
|  |             .computed_size = { 200, 256 }, | ||||||
|  |         } | ||||||
|  |     }); | ||||||
| 
 | 
 | ||||||
|     ui_compute_layout(&state.ui_cx, 0); |  | ||||||
|     state.ui_cx.frame_elements.data[0].size.computed_size[0] = sapp_width(); |  | ||||||
|     state.ui_cx.frame_elements.data[0].size.computed_size[1] = sapp_height(); |  | ||||||
|     ui_update_cache(&state.ui_cx, 0); |  | ||||||
| 
 |  | ||||||
|     state.gpu_glyphs.size = 0; |  | ||||||
|     for (size_t i = 0; i < state.ui_cx.cached_elements.capacity; ++i) { |     for (size_t i = 0; i < state.ui_cx.cached_elements.capacity; ++i) { | ||||||
|         if (state.ui_cx.cached_elements.key_slots[i].key.data != NULL) { |         if (state.ui_cx.cached_elements.key_slots[i].key.data != NULL) { | ||||||
|             string text = state.ui_cx.cached_elements.key_slots[i].key; |             string text = state.ui_cx.cached_elements.key_slots[i].key; | ||||||
| 
 | 
 | ||||||
|             ui_element_cache_data *value = ht_get(&state.ui_cx.cached_elements, text); |             ui_element_cache_data *value = ht_get(&state.ui_cx.cached_elements, text); | ||||||
|             if (value) { |             if (value) { | ||||||
|                 queue_text(text, (float[]){ (float)value->size.computed_pos[0], (float)value->size.computed_pos[1] }); |                 queue_text(text, (float[]){ (float)value->size.computed_size[0], (float)value->size.computed_size[1] }); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | } | ||||||
|  | void ed_frame() { | ||||||
|     if (state.gpu_glyphs.size > 0) { |     if (state.gpu_glyphs.size > 0) { | ||||||
|         sg_update_buffer(state.bind.vertex_buffers[1], &(sg_range) { |         sg_update_buffer(state.bind.vertex_buffers[1], &(sg_range) { | ||||||
|             .ptr = state.gpu_glyphs.data, |             .ptr = state.gpu_glyphs.data, | ||||||
|  |  | ||||||
							
								
								
									
										245
									
								
								src/ui.h
								
								
								
								
							
							
						
						
									
										245
									
								
								src/ui.h
								
								
								
								
							|  | @ -5,12 +5,7 @@ | ||||||
| 
 | 
 | ||||||
| #define MAX_UI_ELEMENTS 2048 | #define MAX_UI_ELEMENTS 2048 | ||||||
| 
 | 
 | ||||||
| // TODO: replace this with functions
 | #define _elm(index) (&cx->frame_elements.data[index]) | ||||||
| #define _FONT_WIDTH 16 |  | ||||||
| #define _FONT_HEIGHT 32 |  | ||||||
| 
 |  | ||||||
| #define _elm(index) (cx->frame_elements.data+index) |  | ||||||
| #define _flags(index, flgs) ((_elm(index)->flags & (flgs)) == (flgs)) |  | ||||||
| 
 | 
 | ||||||
| #define _first(index) (_elm(index)->first) | #define _first(index) (_elm(index)->first) | ||||||
| #define _last(index) (_elm(index)->last) | #define _last(index) (_elm(index)->last) | ||||||
|  | @ -98,45 +93,22 @@ arrayTemplate(ui_element_frame_data); | ||||||
| typedef struct { | typedef struct { | ||||||
|     ed_ht cached_elements; |     ed_ht cached_elements; | ||||||
|     array(ui_element_frame_data) frame_elements; |     array(ui_element_frame_data) frame_elements; | ||||||
|     array(ui_element_frame_data) frame_floating_elements; |  | ||||||
| 
 | 
 | ||||||
|     size_t frame_index; |     size_t frame_index; | ||||||
|     uint32_t canvas_size[2]; |  | ||||||
| 
 | 
 | ||||||
|     size_t current_parent; |     size_t current_parent; | ||||||
| } ui_context; | } ui_context; | ||||||
| 
 | 
 | ||||||
| void ui_compute_layout(ui_context *cx, size_t element_index); |  | ||||||
| 
 | 
 | ||||||
| #ifdef ED_UI_IMPLEMENTATION | #ifdef ED_UI_IMPLEMENTATION | ||||||
| 
 | 
 | ||||||
| ui_context ui_init_context() { | ui_context init_ui_context() { | ||||||
|     ed_ht cached_elements = ht_create(MAX_UI_ELEMENTS, sizeof(ui_element_cache_data)); |     ed_ht cached_elements = ht_create(MAX_UI_ELEMENTS, sizeof(ui_element_cache_data)); | ||||||
|     array(ui_element_frame_data) frame_elements = newArray(ui_element_frame_data, MAX_UI_ELEMENTS); |     array(ui_element_frame_data) frame_elements = newArray(ui_element_frame_data, MAX_UI_ELEMENTS); | ||||||
|     array(ui_element_frame_data) frame_floating_elements = newArray(ui_element_frame_data, MAX_UI_ELEMENTS); |  | ||||||
| 
 |  | ||||||
|     ui_element_frame_data frame_data = (ui_element_frame_data) { |  | ||||||
|         .index = 0, |  | ||||||
|         // TODO: don't just set this to label, because then elements
 |  | ||||||
|         // with the same label can't be created together
 |  | ||||||
|         .key = _String("root"), |  | ||||||
|         .label = _String("root"), |  | ||||||
|         .first = -1, |  | ||||||
|         .last = -1, |  | ||||||
|         .next = -1, |  | ||||||
|         .prev = -1, |  | ||||||
|         .parent = -1, |  | ||||||
|         .size = { |  | ||||||
|             .axis = UI_AXIS_HORIZONTAL, |  | ||||||
|             .computed_size = { 640, 480 }, |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
|     pushArray(ui_element_frame_data, &frame_elements, frame_data); |  | ||||||
| 
 | 
 | ||||||
|     return (ui_context) { |     return (ui_context) { | ||||||
|         .cached_elements = cached_elements, |         .cached_elements = cached_elements, | ||||||
|         .frame_elements = frame_elements, |         .frame_elements = frame_elements, | ||||||
|         .frame_floating_elements = frame_floating_elements, |  | ||||||
|         .frame_index = 0, |         .frame_index = 0, | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  | @ -148,13 +120,11 @@ size_t ui_element(ui_context *cx, string label) { | ||||||
|         // with the same label can't be created together
 |         // with the same label can't be created together
 | ||||||
|         .key = label, |         .key = label, | ||||||
|         .label = label, |         .label = label, | ||||||
|         .first = -1, |         .first = 0, | ||||||
|         .last = -1, |         .last = 0, | ||||||
|         .next = -1, |         .next = 0, | ||||||
|         .prev = cx->frame_elements.data[cx->current_parent].last, |         .prev = cx->frame_elements.data[cx->current_parent].last, | ||||||
|         .parent = cx->current_parent, |         .parent = cx->current_parent, | ||||||
|         .size.semantic_size[0].type = UI_SEMANTIC_SIZE_FILL, |  | ||||||
|         .size.semantic_size[1].type = UI_SEMANTIC_SIZE_FILL, |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // Get cached element data
 |     // Get cached element data
 | ||||||
|  | @ -173,215 +143,20 @@ size_t ui_element(ui_context *cx, string label) { | ||||||
| 
 | 
 | ||||||
|     pushArray(ui_element_frame_data, &cx->frame_elements, frame_data); |     pushArray(ui_element_frame_data, &cx->frame_elements, frame_data); | ||||||
| 
 | 
 | ||||||
|     if (frame_data.prev < SIZE_MAX) { |     if (frame_data.prev) { | ||||||
|         _prev_ref(frame_data.index)->next = frame_data.index; |         _prev_ref(frame_data.index)->next = frame_data.index; | ||||||
|     } |     } | ||||||
|     if (_elm(cx->current_parent)->first == SIZE_MAX) { |     if (_elm(cx->current_parent)->first == 0) { | ||||||
|         _elm(cx->current_parent)->first = frame_data.index; |         _elm(cx->current_parent)->first = frame_data.index; | ||||||
|     } |     } | ||||||
|     _elm(cx->current_parent)->last = frame_data.index; |     _elm(cx->current_parent)->last = frame_data.index; | ||||||
| 
 |  | ||||||
|     return frame_data.index; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t _ui_ancestor_size(ui_context *cx, size_t element_index, ui_axis axis) { | void ui_compute_layout(ui_context *cx, uint32_t canvas_size[2], size_t element_index) { | ||||||
|     if (element_index == SIZE_MAX || _parent(element_index) == SIZE_MAX) { |  | ||||||
|         return cx->frame_elements.data[0].size.computed_size[axis]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     switch (_parent_ref(element_index)->size.semantic_size[axis].type) { |  | ||||||
|         case UI_SEMANTIC_SIZE_FIT_TEXT: |  | ||||||
|         case UI_SEMANTIC_SIZE_FILL: |  | ||||||
|         case UI_SEMANTIC_SIZE_EXACT: |  | ||||||
|         case UI_SEMANTIC_SIZE_PERCENT_OF_PARENT: |  | ||||||
|             return _parent_ref(element_index)->size.computed_size[axis]; |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case UI_SEMANTIC_SIZE_CHILDREN_SUM: |  | ||||||
|             return _ui_ancestor_size(cx, _parent(element_index), axis); |  | ||||||
|             break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void _ui_compute_simple_layout(ui_context *cx, ui_element_frame_data *elm, ui_axis axis, bool *post_compute) { |  | ||||||
|     switch (elm->size.semantic_size[axis].type) { |  | ||||||
|         case UI_SEMANTIC_SIZE_FIT_TEXT: |  | ||||||
|             if (axis == UI_AXIS_HORIZONTAL) { |  | ||||||
|                 elm->size.computed_size[axis] = elm->label.len * _FONT_WIDTH; |  | ||||||
|             } else if (axis == UI_AXIS_VERTICAL) { |  | ||||||
|                 elm->size.computed_size[axis] = _FONT_WIDTH; |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case UI_SEMANTIC_SIZE_CHILDREN_SUM: |  | ||||||
|             post_compute[axis] = true; |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case UI_SEMANTIC_SIZE_FILL: |  | ||||||
|             // TODO: set to ancestor size for floating
 |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case UI_SEMANTIC_SIZE_EXACT: |  | ||||||
|             elm->size.computed_size[axis] = elm->size.semantic_size[axis].integer; |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case UI_SEMANTIC_SIZE_PERCENT_OF_PARENT: |  | ||||||
|             { |  | ||||||
|                 float semantic_value = (float)elm->size.semantic_size[axis].integer; |  | ||||||
|                 elm->size.computed_size[axis] = (uint32_t)((float)(_ui_ancestor_size(cx, elm->index, axis)) * (semantic_value/100.0)); |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void _ui_compute_children_layout(ui_context *cx, ui_element_frame_data *elm) { |  | ||||||
|     uint32_t child_size[2] = { 0 }; |  | ||||||
| 
 |  | ||||||
|     // NOTE: the number of fills for the opposite axis of this box needs to be 1
 |  | ||||||
|     // because it will never get incremented in the loop below and cause a divide by zero
 |  | ||||||
|     // and the number of fills for the axis of the box needs to start at zero or else it will
 |  | ||||||
|     // be n+1 causing incorrect sizes
 |  | ||||||
|     uint32_t num_fills[2] = { 1 }; |  | ||||||
|     num_fills[elm->size.axis] = 0; |  | ||||||
| 
 |  | ||||||
|     // TODO: maybe just use the actual data instead of copying?
 |  | ||||||
|     uint32_t elm_size[2] = { elm->size.computed_size[0], elm->size.computed_size[1] }; |  | ||||||
| 
 |  | ||||||
|     size_t child_index = elm->first; |  | ||||||
|     if (child_index < SIZE_MAX) { |  | ||||||
|         do { |  | ||||||
|             ui_compute_layout(cx, child_index); |  | ||||||
| 
 |  | ||||||
|             if (_elm(child_index)->size.semantic_size[elm->size.axis].type == UI_SEMANTIC_SIZE_FILL) { |  | ||||||
|                 num_fills[elm->size.axis] += 1; |  | ||||||
|             } else { |  | ||||||
|                 child_size[elm->size.axis] += _elm(child_index)->size.computed_size[elm->size.axis]; |  | ||||||
|             } |  | ||||||
|         } while ((child_index = _next(child_index)) < SIZE_MAX); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     child_index = elm->first; |  | ||||||
|     if (child_index < SIZE_MAX) { |  | ||||||
|         do { |  | ||||||
|             for (size_t axis = 0; axis < 2; ++axis) { |  | ||||||
|                 if (_elm(child_index)->size.semantic_size[axis].type == UI_SEMANTIC_SIZE_FILL) { |  | ||||||
|                     _elm(child_index)->size.computed_size[axis] = (elm_size[axis] - child_size[axis]) / num_fills[axis]; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             ui_compute_layout(cx, child_index); |  | ||||||
|         } while ((child_index = _next(child_index)) < SIZE_MAX); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ui_compute_layout(ui_context *cx, size_t element_index) { |  | ||||||
|     if (element_index == SIZE_MAX) return; |  | ||||||
| 
 |  | ||||||
|     ui_axis axis = UI_AXIS_HORIZONTAL; |     ui_axis axis = UI_AXIS_HORIZONTAL; | ||||||
|     __auto_type elm = _elm(element_index); |  | ||||||
| 
 | 
 | ||||||
|     if (_parent(element_index) < SIZE_MAX && !_flags(element_index, UI_FLAG_FLOATING)) { |     // FIXME: change me to use -1 for no reference to element
 | ||||||
|         __auto_type parent = _parent_ref(element_index); |     // TODO: actually compute layout
 | ||||||
|         axis = parent->size.axis; |  | ||||||
|         elm->size.computed_pos[0] = parent->size.computed_pos[0]; |  | ||||||
|         elm->size.computed_pos[1] = parent->size.computed_pos[1]; |  | ||||||
| 
 |  | ||||||
|         // TODO: implement scrolling
 |  | ||||||
|         // elm->size.computed_pos[axis] += parent.scroll_offset;
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (!_flags(element_index, UI_FLAG_FLOATING) && _prev(element_index) < SIZE_MAX) { |  | ||||||
|         __auto_type prev = _prev_ref(element_index); |  | ||||||
| 
 |  | ||||||
|         if (prev >= 0) { |  | ||||||
|             elm->size.computed_pos[axis] = prev->size.computed_pos[axis] + prev->size.computed_size[axis]; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     bool post_compute[2] = { false, false }; |  | ||||||
|     // only compute layout for children of root
 |  | ||||||
|     if (elm->index > 0) { |  | ||||||
|         _ui_compute_simple_layout(cx, elm, axis, post_compute); |  | ||||||
|     } |  | ||||||
|     _ui_compute_children_layout(cx, elm); |  | ||||||
| 
 |  | ||||||
|     // NOTE(pcleavelin): the only difference between these two blocks is the ordering of the switch block
 |  | ||||||
|     // they can probably be merged
 |  | ||||||
|     if (post_compute[UI_AXIS_HORIZONTAL]) { |  | ||||||
|         elm->size.computed_size[UI_AXIS_HORIZONTAL] = 0; |  | ||||||
| 
 |  | ||||||
|         size_t child_index = elm->first; |  | ||||||
|         if (child_index < SIZE_MAX) { |  | ||||||
|             do { |  | ||||||
|                 __auto_type child = _elm(child_index); |  | ||||||
| 
 |  | ||||||
|                 switch (elm->size.axis) { |  | ||||||
|                     case UI_AXIS_HORIZONTAL: |  | ||||||
|                         elm->size.computed_size[UI_AXIS_HORIZONTAL] += child->size.computed_size[UI_AXIS_HORIZONTAL]; |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     case UI_AXIS_VERTICAL: |  | ||||||
|                         if (child->size.computed_size[UI_AXIS_HORIZONTAL] > elm->size.computed_size[UI_AXIS_HORIZONTAL]) { |  | ||||||
|                             elm->size.computed_size[UI_AXIS_HORIZONTAL] = child->size.computed_size[UI_AXIS_HORIZONTAL]; |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
|                 } |  | ||||||
|             } while ((child_index = _next(child_index)) < SIZE_MAX); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     if (post_compute[UI_AXIS_VERTICAL]) { |  | ||||||
|         elm->size.computed_size[UI_AXIS_VERTICAL] = 0; |  | ||||||
| 
 |  | ||||||
|         size_t child_index = elm->first; |  | ||||||
|         if (child_index < SIZE_MAX) { |  | ||||||
|             do { |  | ||||||
|                 __auto_type child = _elm(child_index); |  | ||||||
| 
 |  | ||||||
|                 switch (elm->size.axis) { |  | ||||||
|                     case UI_AXIS_HORIZONTAL: |  | ||||||
|                         if (child->size.computed_size[UI_AXIS_VERTICAL] > elm->size.computed_size[UI_AXIS_VERTICAL]) { |  | ||||||
|                             elm->size.computed_size[UI_AXIS_VERTICAL] = child->size.computed_size[UI_AXIS_VERTICAL]; |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
|                     case UI_AXIS_VERTICAL: |  | ||||||
|                         elm->size.computed_size[UI_AXIS_VERTICAL] += child->size.computed_size[UI_AXIS_VERTICAL]; |  | ||||||
|                         break; |  | ||||||
|                 } |  | ||||||
|             } while ((child_index = _next(child_index)) < SIZE_MAX); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ui_update_cache(ui_context *cx, size_t element_index) { |  | ||||||
|     if (element_index == SIZE_MAX) return; |  | ||||||
| 
 |  | ||||||
|     size_t child_index = _elm(element_index)->first; |  | ||||||
|     if (child_index < SIZE_MAX) { |  | ||||||
|         do { |  | ||||||
|             __auto_type child = _elm(child_index); |  | ||||||
| 
 |  | ||||||
|             ht_set(&cx->cached_elements, child->key, &(ui_element_cache_data) { |  | ||||||
|                 .label = child->label, |  | ||||||
|                 .size = { |  | ||||||
|                     .axis = child->size.axis, |  | ||||||
|                     .semantic_size = { child->size.semantic_size[0], child->size.semantic_size[1] }, |  | ||||||
|                     .computed_size = { child->size.computed_size[0], child->size.computed_size[1] }, |  | ||||||
|                     .computed_pos = { child->size.computed_pos[0], child->size.computed_pos[1] }, |  | ||||||
|                 } |  | ||||||
|                 // FIXME: don't mangle last_instantiated_index
 |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             ui_update_cache(cx, child_index); |  | ||||||
|         } while ((child_index = _next(child_index)) < SIZE_MAX); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     cx->frame_elements.size = 1; |  | ||||||
|     cx->frame_elements.data[0].first = SIZE_MAX; |  | ||||||
|     cx->frame_elements.data[0].prev = SIZE_MAX; |  | ||||||
|     cx->frame_elements.data[0].next = SIZE_MAX; |  | ||||||
|     cx->frame_elements.data[0].last = SIZE_MAX; |  | ||||||
|     cx->frame_elements.data[0].parent = SIZE_MAX; |  | ||||||
|     cx->current_parent = 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue