Primitive UI layout
This commit is contained in:
		
							parent
							
								
									9dec588ec1
								
							
						
					
					
						commit
						ebb7862792
					
				| @ -10,7 +10,7 @@ | |||||||
| #include <std/ui_core.h> | #include <std/ui_core.h> | ||||||
| #include <std/ui_builder.h> | #include <std/ui_builder.h> | ||||||
| 
 | 
 | ||||||
| #define default_font_height (64) | #define default_font_height (24) | ||||||
| auto proportional_font_height = default_font_height; | auto proportional_font_height = default_font_height; | ||||||
| auto monospace_font_height = default_font_height; | auto monospace_font_height = default_font_height; | ||||||
| 
 | 
 | ||||||
| @ -80,9 +80,26 @@ fn void ui_top_bar() | |||||||
|             ui_button(strlit("Button 3")); |             ui_button(strlit("Button 3")); | ||||||
|         } |         } | ||||||
|         ui_pop(parent); |         ui_pop(parent); | ||||||
|  |         ui_pop(child_layout_axis); | ||||||
|     } |     } | ||||||
|     ui_pop(pref_height); |     ui_pop(pref_height); | ||||||
|     ui_button(strlit("Hello!")); | } | ||||||
|  | 
 | ||||||
|  | STRUCT(UI_Node) | ||||||
|  | { | ||||||
|  |     String name; | ||||||
|  |     String type; | ||||||
|  |     String value; | ||||||
|  |     String namespace; | ||||||
|  |     String function; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | fn void ui_node(UI_Node node) | ||||||
|  | { | ||||||
|  |     auto* node_widget = ui_widget_make_format((UI_WidgetFlags) { | ||||||
|  |         .draw_background = 1, | ||||||
|  |         .draw_text = 1, | ||||||
|  |     }, "{s} : {s} = {s}##{s}{s}", node.name, node.type, node.value, node.function, node.namespace); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn void app_update() | fn void app_update() | ||||||
| @ -110,6 +127,41 @@ fn void app_update() | |||||||
|             ui_push(font_size, default_font_height); |             ui_push(font_size, default_font_height); | ||||||
| 
 | 
 | ||||||
|             ui_top_bar(); |             ui_top_bar(); | ||||||
|  |             ui_push(child_layout_axis, AXIS2_X); | ||||||
|  |             auto* workspace_widget = ui_widget_make_format((UI_WidgetFlags) {}, "workspace{u64}", window->os); | ||||||
|  |             ui_push(parent, workspace_widget); | ||||||
|  |             { | ||||||
|  |                 // Node visualizer
 | ||||||
|  |                 ui_push(child_layout_axis, AXIS2_Y); | ||||||
|  |                 auto* node_visualizer_widget = ui_widget_make_format((UI_WidgetFlags) { | ||||||
|  |                     .draw_background = 1, | ||||||
|  |                 }, "node_visualizer{u64}", window->os); | ||||||
|  | 
 | ||||||
|  |                 ui_push(parent, node_visualizer_widget); | ||||||
|  |                 { | ||||||
|  |                     ui_node((UI_Node) { | ||||||
|  |                         .name = strlit("a"), | ||||||
|  |                         .type = strlit("s32"), | ||||||
|  |                         .value = strlit("1"), | ||||||
|  |                         .namespace = strlit("foo"), | ||||||
|  |                         .function = strlit("main"), | ||||||
|  |                     }); | ||||||
|  |                     ui_node((UI_Node) { | ||||||
|  |                         .name = strlit("b"), | ||||||
|  |                         .type = strlit("s32"), | ||||||
|  |                         .value = strlit("2"), | ||||||
|  |                         .namespace = strlit("foo"), | ||||||
|  |                         .function = strlit("main"), | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |                 ui_pop(parent); | ||||||
|  |                 ui_pop(child_layout_axis); | ||||||
|  | 
 | ||||||
|  |                 // Side-panel stub
 | ||||||
|  |                 ui_button(strlit("Options")); | ||||||
|  |             } | ||||||
|  |             ui_pop(parent); | ||||||
|  |             ui_pop(child_layout_axis); | ||||||
| 
 | 
 | ||||||
|             ui_build_end(); |             ui_build_end(); | ||||||
| 
 | 
 | ||||||
| @ -166,8 +218,8 @@ void run_app() | |||||||
|     state.first_window->os = os_window_create((OSWindowCreate) { |     state.first_window->os = os_window_create((OSWindowCreate) { | ||||||
|         .name = strlit("Bloat Buster"), |         .name = strlit("Bloat Buster"), | ||||||
|         .size = { |         .size = { | ||||||
|             .width = 1024, |             .width = 1600, | ||||||
|             .height= 768, |             .height= 900, | ||||||
|         }, |         }, | ||||||
|         .refresh_callback = &window_refresh_callback, |         .refresh_callback = &window_refresh_callback, | ||||||
|     }); |     }); | ||||||
|  | |||||||
| @ -98,7 +98,7 @@ STRUCT(UI_Widget) | |||||||
|     // Persistent data across frames
 |     // Persistent data across frames
 | ||||||
|     u64 last_build_touched; |     u64 last_build_touched; | ||||||
|     float2 view_offset; |     float2 view_offset; | ||||||
|     float4 background_color; |     float4 background_colors[4]; | ||||||
|     float4 text_color; |     float4 text_color; | ||||||
| }; | }; | ||||||
| decl_vbp(UI_Widget); | decl_vbp(UI_Widget); | ||||||
| @ -226,6 +226,7 @@ EXPORT UI_Signal ui_signal_from_widget(UI_Widget* widget); | |||||||
| EXPORT UI_State* ui_state_get(); | EXPORT UI_State* ui_state_get(); | ||||||
| 
 | 
 | ||||||
| EXPORT UI_Widget* ui_widget_make(UI_WidgetFlags flags, String string); | EXPORT UI_Widget* ui_widget_make(UI_WidgetFlags flags, String string); | ||||||
|  | EXPORT UI_Widget* ui_widget_make_format(UI_WidgetFlags flags, const char* format, ...); | ||||||
| EXPORT UI_Size ui_pixels(u32 width, f32 strictness); | EXPORT UI_Size ui_pixels(u32 width, f32 strictness); | ||||||
| EXPORT UI_Size ui_percentage(f32 percentage, f32 strictness); | EXPORT UI_Size ui_percentage(f32 percentage, f32 strictness); | ||||||
| EXPORT UI_Size ui_em(f32 value, f32 strictness); | EXPORT UI_Size ui_em(f32 value, f32 strictness); | ||||||
|  | |||||||
| @ -2213,7 +2213,7 @@ void window_render_rect(RenderWindow* window, RectDraw draw) | |||||||
|         assert(draw.texture.p1.y - draw.texture.p0.y == draw.vertex.p1.y - draw.vertex.p0.y); |         assert(draw.texture.p1.y - draw.texture.p0.y == draw.vertex.p1.y - draw.vertex.p0.y); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto corner_radius = 10.0f; |     auto corner_radius = 5.0f; | ||||||
| 
 | 
 | ||||||
|     auto extent = draw.vertex.p1 - p0; |     auto extent = draw.vertex.p1 - p0; | ||||||
|     RectVertex vertices[] = { |     RectVertex vertices[] = { | ||||||
|  | |||||||
| @ -246,10 +246,13 @@ UI_Widget* ui_widget_make_from_key(UI_WidgetFlags flags, UI_Key key) | |||||||
|         ui_state->root = widget; |         ui_state->root = widget; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto color = count % 3 == 0; |  | ||||||
|     widget->key = key; |     widget->key = key; | ||||||
|     widget->background_color = (float4) { color, color, color, 1 }; | 
 | ||||||
|     widget->text_color = (float4) { !color, !color, !color, 1 }; |     for (u64 i = 0; i < array_length(widget->background_colors); i += 1) | ||||||
|  |     { | ||||||
|  |         widget->background_colors[i] = ui_top(background_color); | ||||||
|  |     } | ||||||
|  |     widget->text_color = ui_top(text_color); | ||||||
|     widget->flags = flags; |     widget->flags = flags; | ||||||
|     widget->first = 0; |     widget->first = 0; | ||||||
|     widget->last = 0; |     widget->last = 0; | ||||||
| @ -358,6 +361,7 @@ u8 ui_build_begin(OSWindow os_window, f64 frame_time, OSEventQueue* event_queue) | |||||||
| 
 | 
 | ||||||
|     u8 open = 1; |     u8 open = 1; | ||||||
| 
 | 
 | ||||||
|  |     auto mouse_button_count = 0; | ||||||
|     for (u32 generic_event_index = 0; open & (generic_event_index < event_queue->descriptors.length); generic_event_index += 1) |     for (u32 generic_event_index = 0; open & (generic_event_index < event_queue->descriptors.length); generic_event_index += 1) | ||||||
|     { |     { | ||||||
|         auto event_descriptor = event_queue->descriptors.pointer[generic_event_index]; |         auto event_descriptor = event_queue->descriptors.pointer[generic_event_index]; | ||||||
| @ -379,7 +383,8 @@ u8 ui_build_begin(OSWindow os_window, f64 frame_time, OSEventQueue* event_queue) | |||||||
|                         } break; |                         } break; | ||||||
|                     case OS_EVENT_MOUSE_PRESS: |                     case OS_EVENT_MOUSE_PRESS: | ||||||
|                         { |                         { | ||||||
|                             assert(previous_button_event.action == OS_EVENT_MOUSE_RELAX); |                             // TODO: handle properly
 | ||||||
|  |                             assert(previous_button_event.action == OS_EVENT_MOUSE_RELAX || mouse_button_count); | ||||||
|                         } break; |                         } break; | ||||||
|                     case OS_EVENT_MOUSE_REPEAT: |                     case OS_EVENT_MOUSE_REPEAT: | ||||||
|                         { |                         { | ||||||
| @ -388,6 +393,7 @@ u8 ui_build_begin(OSWindow os_window, f64 frame_time, OSEventQueue* event_queue) | |||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 ui_state->mouse_button_events[button.button] = button.event; |                 ui_state->mouse_button_events[button.button] = button.event; | ||||||
|  |                 mouse_button_count += 1; | ||||||
|             } break; |             } break; | ||||||
|         case OS_EVENT_TYPE_WINDOW_FOCUS: |         case OS_EVENT_TYPE_WINDOW_FOCUS: | ||||||
|             { |             { | ||||||
| @ -418,38 +424,38 @@ u8 ui_build_begin(OSWindow os_window, f64 frame_time, OSEventQueue* event_queue) | |||||||
| 
 | 
 | ||||||
|     if (open) |     if (open) | ||||||
|     { |     { | ||||||
|         // for (u64 i = 0; i < ui_state->widget_table.length; i += 1)
 |         for (u64 i = 0; i < ui_state->widget_table.length; i += 1) | ||||||
|         // {
 |         { | ||||||
|         //     auto* widget_table_element = &ui_state->widget_table.pointer[i];
 |             auto* widget_table_element = &ui_state->widget_table.pointer[i]; | ||||||
|         //     for (UI_Widget* widget = widget_table_element->first, *next = 0; widget; widget = next)
 |             for (UI_Widget* widget = widget_table_element->first, *next = 0; widget; widget = next) | ||||||
|         //     {
 |             { | ||||||
|         //         next = widget->hash_next;
 |                 next = widget->hash_next; | ||||||
|         //
 | 
 | ||||||
|         //         if (ui_key_equal(widget->key, ui_key_null()) || widget->last_build_touched + 1 < ui_state->build_count)
 |                 if (ui_key_equal(widget->key, ui_key_null()) || widget->last_build_touched + 1 < ui_state->build_count) | ||||||
|         //         {
 |                 { | ||||||
|         //             // Remove from the list
 |                     // Remove from the list
 | ||||||
|         //             if (widget->hash_previous)
 |                     if (widget->hash_previous) | ||||||
|         //             {
 |                     { | ||||||
|         //                 widget->hash_previous->hash_next = widget->hash_next;
 |                         widget->hash_previous->hash_next = widget->hash_next; | ||||||
|         //             }
 |                     } | ||||||
|         //
 | 
 | ||||||
|         //             if (widget->hash_next)
 |                     if (widget->hash_next) | ||||||
|         //             {
 |                     { | ||||||
|         //                 widget->hash_next->hash_previous = widget->hash_previous;
 |                         widget->hash_next->hash_previous = widget->hash_previous; | ||||||
|         //             }
 |                     } | ||||||
|         //
 | 
 | ||||||
|         //             if (widget_table_element->first == widget)
 |                     if (widget_table_element->first == widget) | ||||||
|         //             {
 |                     { | ||||||
|         //                 widget_table_element->first = widget->hash_next;
 |                         widget_table_element->first = widget->hash_next; | ||||||
|         //             }
 |                     } | ||||||
|         //
 | 
 | ||||||
|         //             if (widget_table_element->last == widget)
 |                     if (widget_table_element->last == widget) | ||||||
|         //             {
 |                     { | ||||||
|         //                 widget_table_element->last = widget->hash_previous;
 |                         widget_table_element->last = widget->hash_previous; | ||||||
|         //             }
 |                     } | ||||||
|         //         }
 |                 } | ||||||
|         //     }
 |             } | ||||||
|         // }
 |         } | ||||||
| 
 | 
 | ||||||
|         auto framebuffer_size = os_window_framebuffer_size_get(os_window); |         auto framebuffer_size = os_window_framebuffer_size_get(os_window); | ||||||
|         ui_push_next_only(pref_width, ui_pixels(framebuffer_size.width, 1.0f)); |         ui_push_next_only(pref_width, ui_pixels(framebuffer_size.width, 1.0f)); | ||||||
| @ -462,8 +468,8 @@ u8 ui_build_begin(OSWindow os_window, f64 frame_time, OSEventQueue* event_queue) | |||||||
|         ui_push(parent, root); |         ui_push(parent, root); | ||||||
| 
 | 
 | ||||||
|         ui_push(font_size, 12); |         ui_push(font_size, 12); | ||||||
|         ui_push(text_color, ((float4) { 1, 1, 1, 1 })); |         ui_push(text_color, ((float4) { 0.9, 0.9, 0.02, 1 })); | ||||||
|         ui_push(background_color, ((float4) { 0, 0, 0, 1 })); |         ui_push(background_color, ((float4) { 0.1, 0.1, 0.1, 1 })); | ||||||
|         ui_push(pref_width, ui_percentage(1.0, 0.0)); |         ui_push(pref_width, ui_percentage(1.0, 0.0)); | ||||||
|         ui_push(pref_height, ui_percentage(1.0, 0.0)); |         ui_push(pref_height, ui_percentage(1.0, 0.0)); | ||||||
|         // ui_push(pref_height, ui_em(1.8, 0.0));
 |         // ui_push(pref_height, ui_em(1.8, 0.0));
 | ||||||
| @ -724,7 +730,7 @@ void ui_draw() | |||||||
|         if (widget->flags.draw_background) |         if (widget->flags.draw_background) | ||||||
|         { |         { | ||||||
|             window_render_rect(window, (RectDraw) { |             window_render_rect(window, (RectDraw) { | ||||||
|                 .colors = { (float4) {1, 1, 1, 1 }, (float4) {1, 1, 1, 1}, widget->background_color, widget->background_color }, |                 .colors = { widget->background_colors[0], widget->background_colors[1], widget->background_colors[2], widget->background_colors[3] }, | ||||||
|                 .vertex = widget->rect, |                 .vertex = widget->rect, | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -142,16 +142,45 @@ fn void glfw_window_mouse_button_callback(GLFWwindow* window, int button, int ac | |||||||
|         default: unreachable(); |         default: unreachable(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     OSEventMouseButtonKind mouse_button = 0; | ||||||
|  |     switch (button) | ||||||
|  |     { | ||||||
|  |         case GLFW_MOUSE_BUTTON_1: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_1; | ||||||
|  |             break; | ||||||
|  |         case GLFW_MOUSE_BUTTON_2: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_2; | ||||||
|  |             break; | ||||||
|  |         case GLFW_MOUSE_BUTTON_3: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_3; | ||||||
|  |             break; | ||||||
|  |         case GLFW_MOUSE_BUTTON_4: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_4; | ||||||
|  |             break; | ||||||
|  |         case GLFW_MOUSE_BUTTON_5: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_5; | ||||||
|  |             break; | ||||||
|  |         case GLFW_MOUSE_BUTTON_6: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_6; | ||||||
|  |             break; | ||||||
|  |         case GLFW_MOUSE_BUTTON_7: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_7; | ||||||
|  |             break; | ||||||
|  |         case GLFW_MOUSE_BUTTON_8: | ||||||
|  |             mouse_button = OS_EVENT_MOUSE_BUTTON_8; | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     *vb_add(&event_queue->mouse_buttons, 1) = (OSEventMouseButton) { |     *vb_add(&event_queue->mouse_buttons, 1) = (OSEventMouseButton) { | ||||||
|         .button = button, |         .button = mouse_button, | ||||||
|         .event = (OSEventMouseButtonEvent){ |         .event = (OSEventMouseButtonEvent){ | ||||||
|             .action = os_action, |             .action = os_action, | ||||||
|             .mod_shift = mods & GLFW_MOD_SHIFT, |             .mod_shift = !!(mods & GLFW_MOD_SHIFT), | ||||||
|             .mod_control = mods & GLFW_MOD_CONTROL, |             .mod_control = !!(mods & GLFW_MOD_CONTROL), | ||||||
|             .mod_alt = mods & GLFW_MOD_ALT, |             .mod_alt = !!(mods & GLFW_MOD_ALT), | ||||||
|             .mod_super = mods & GLFW_MOD_SUPER, |             .mod_super = !!(mods & GLFW_MOD_SUPER), | ||||||
|             .mod_caps_lock = mods & GLFW_MOD_CAPS_LOCK, |             .mod_caps_lock = !!(mods & GLFW_MOD_CAPS_LOCK), | ||||||
|             .mod_num_lock = mods & GLFW_MOD_NUM_LOCK, |             .mod_num_lock = !!(mods & GLFW_MOD_NUM_LOCK), | ||||||
|         }, |         }, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 David Gonzalez Martin
						David Gonzalez Martin