UI fixes and new layout features

This commit is contained in:
2024-12-30 01:42:27 +01:00
parent 6ed67e8fcb
commit 6cf19a6f9b
5 changed files with 144 additions and 228 deletions

View File

@@ -5,7 +5,7 @@ MAX_WINDOWS :: 128;
SCROLL_SPEED :: 5;
WINDOW_TITLE_BAR_HEIGHT :: 20.0;
WINDOW_BORDER_WIDTH :: 3.0;
WINDOW_BORDER_WIDTH :: 3;
UI_Box_Flags :: enum_flags u32 {
NONE :: 0;
@@ -55,7 +55,8 @@ UI_Box :: struct {
hash: u32;
last_used_frame_index: u64;
root_for_window: *UI_Window;
window: *UI_Window;
root_in_window: bool;
parent: *UI_Box;
first_child: *UI_Box;
last_child: *UI_Box;
@@ -165,6 +166,7 @@ UI_State :: struct {
last_box: *UI_Box;
mouse_over_window: bool;
parent_stack: Stack(*UI_Box);
allocator: Allocator;
@@ -254,7 +256,6 @@ ui_box_make :: (flags: UI_Box_Flags, hash: u32) -> *UI_Box {
actual_hash += ui_state.current_window.hash + actual_hash;
}
box := get_ui_box_or_create_new(actual_hash);
box.last_used_frame_index = ui_state.frame_index;
box.first_child = null;
@@ -264,13 +265,16 @@ ui_box_make :: (flags: UI_Box_Flags, hash: u32) -> *UI_Box {
box.num_children = 0;
box.flags = flags;
box.parent = null;
box.root_for_window = null;
box.window = null;
box.root_in_window = false;
if ui_state.current_window && parent == null {
array_add(*ui_state.current_window.boxes, box);
box.root_for_window = ui_state.current_window;
box.root_in_window = true;
}
box.window = ui_state.current_window;
// Set the links
box.parent = parent;
if box.parent != null {
@@ -345,7 +349,7 @@ ui_init :: () {
ui_state.sampler = create_sampler(engine.renderer);
//ui_state.fonts.regular = create_font(engine.renderer, "../assets/fonts/roboto/Roboto-Regular.ttf", 32);
ui_state.fonts.regular = create_font(engine.renderer, "../assets/fonts/Inconsolata-Regular.ttf", 18);
ui_state.fonts.regular = create_font(engine.renderer, "../assets/fonts/Inconsolata-Regular.ttf", 14);
ui_state.fonts.button = create_font(engine.renderer, "../assets/fonts/roboto/Roboto-Regular.ttf", 14);
// ui_rect
@@ -504,8 +508,8 @@ ui_figure_out_sizes :: () {
if box.semantic_size[0].size_kind == .PCT {
if box.parent != null {
box.size.x = box.parent.size.x * box.semantic_size[0].value - (box.parent.padding_left + box.parent.padding_right);
} else if box.root_for_window != null {
box.size.x = cast(float)box.root_for_window.size.x * box.semantic_size[0].value - (WINDOW_BORDER_WIDTH);
} else if box.root_in_window {
box.size.x = cast(float)box.window.size.x * box.semantic_size[0].value - (cast(float)WINDOW_BORDER_WIDTH);
} else {
assert(false);
}
@@ -513,8 +517,8 @@ ui_figure_out_sizes :: () {
if box.semantic_size[1].size_kind == .PCT {
if box.parent != null {
box.size.y = box.parent.size.y * box.semantic_size[1].value - (box.parent.padding_top + box.parent.padding_bottom);
} else if box.root_for_window != null {
box.size.y = cast(float)box.root_for_window.size.y * box.semantic_size[0].value - (WINDOW_BORDER_WIDTH);
} else if box.root_in_window {
box.size.y = cast(float)box.window.size.y * box.semantic_size[0].value - (cast(float)WINDOW_BORDER_WIDTH);
} else {
assert(false);
}
@@ -566,10 +570,10 @@ ui_figure_out_sizes :: () {
// Find final positions
for *box : ui_state.boxes {
if box.parent == null {
if box.root_for_window {
window := box.root_for_window;
box.rect.x = xx (window.actual_position.x + window.scroll_offset.x) + WINDOW_BORDER_WIDTH;
box.rect.y = xx (window.actual_position.y + window.scroll_offset.y) + WINDOW_BORDER_WIDTH + WINDOW_TITLE_BAR_HEIGHT;
if box.root_in_window {
window := box.window;
box.rect.x = xx (window.actual_position.x + window.scroll_offset.x) + cast(float)WINDOW_BORDER_WIDTH;
box.rect.y = xx (window.actual_position.y + window.scroll_offset.y) + cast(float)WINDOW_BORDER_WIDTH + WINDOW_TITLE_BAR_HEIGHT;
} else {
box.rect.x = 0.0;
box.rect.y = 0.0;
@@ -762,6 +766,8 @@ get_rect_instance_buffer :: () -> *Instanced_Rects_Data {
ui_render :: () {
// Draw each window separately
for window: ui_state.windows {
if window.last_used_frame_index != ui_state.frame_index continue;
// Draw outer rect + border of window
title_bar_buffer_data := get_rect_instance_buffer();
inv_w := 1.0 / cast(float)engine.renderer.render_target_width;
@@ -814,7 +820,7 @@ ui_render :: () {
{
if window.title.count > 0 {
font_handle := ui_state.fonts.regular;
x : float = (xx window.actual_position.x + WINDOW_BORDER_WIDTH + 2);
x : float = cast(float)(xx window.actual_position.x + cast(u32)WINDOW_BORDER_WIDTH + 2);
y : float = (cast(float)engine.renderer.render_target_height - (window.actual_position.y + WINDOW_BORDER_WIDTH + 2.0));
text_size := get_text_size(engine.renderer, window.title, font_handle);
@@ -830,10 +836,10 @@ ui_render :: () {
}
push_cmd_set_scissor(engine.renderer,
xx window.size.x,
xx (window.size.y - WINDOW_TITLE_BAR_HEIGHT),
xx window.actual_position.x,
xx (window.actual_position.y + WINDOW_TITLE_BAR_HEIGHT));
xx window.size.x- cast(u32)(WINDOW_BORDER_WIDTH*2),
xx (window.size.y - WINDOW_TITLE_BAR_HEIGHT - cast(u32)(WINDOW_BORDER_WIDTH*2)),
xx window.actual_position.x + cast(u32)WINDOW_BORDER_WIDTH,
xx (window.actual_position.y + WINDOW_TITLE_BAR_HEIGHT + WINDOW_BORDER_WIDTH));
buffer_data := get_rect_instance_buffer();
@@ -900,6 +906,10 @@ ui_render :: () {
//}
}
ui_mouse_over_window :: () -> bool {
return ui_state.mouse_over_window;
}
#scope_file
set_properties_to_defaults :: () {
background_color = .{1,1,1,1};
@@ -1103,7 +1113,7 @@ ui_render_text_recursively :: (box: *UI_Box) {
inv_h := 1.0 / cast(float)engine.renderer.render_target_height;
if box.flags & .DRAW_TEXT {
font_handle := ui_state.fonts.regular;
font_handle := ui_state.fonts.button;
if box.text.count > 0 {
text_size := get_text_size(engine.renderer, box.text, font_handle);
@@ -1150,8 +1160,23 @@ ui_update_input :: () {
mouse_x := engine.input.mouse.x;
mouse_y := engine.input.mouse.y;
ui_state.mouse_over_window = false;
for *window: ui_state.windows {
if window.last_used_frame_index != ui_state.frame_index continue;
rect: Rect;
rect.x = xx window.actual_position.x;
rect.y = xx window.actual_position.y;
rect.w = xx window.size.x;
rect.h = xx window.size.y;
if is_mouse_inside(mouse_x, mouse_y, rect) {
ui_state.mouse_over_window = true;
}
}
// Scrolling
for *window: ui_state.windows {
if window.last_used_frame_index != ui_state.frame_index continue;
rect: Rect;
rect.x = xx window.actual_position.x;
rect.y = xx (window.actual_position.y+WINDOW_TITLE_BAR_HEIGHT);
@@ -1159,12 +1184,14 @@ ui_update_input :: () {
rect.h = xx (window.size.y - WINDOW_TITLE_BAR_HEIGHT);
if is_mouse_inside(mouse_x, mouse_y, rect) {
ui_state.mouse_over_window = true;
window.scroll_offset.y += cast(s32) engine.input.mouse.wheel * SCROLL_SPEED;
}
}
if ui_state.currently_moving_window == null {
for *window: ui_state.windows {
if window.last_used_frame_index != ui_state.frame_index continue;
rect: Rect;
rect.x = xx window.actual_position.x;
rect.y = xx window.actual_position.y;
@@ -1188,6 +1215,7 @@ ui_update_input :: () {
}
for *window: ui_state.windows {
if window.last_used_frame_index != ui_state.frame_index continue;
window.actual_position = window.position + window.offset;
}
@@ -1212,7 +1240,14 @@ ui_update_input :: () {
box.interaction.left_mouse_pressed = false;
}
} else {
if is_mouse_inside(mouse_x, mouse_y, box.rect) && key_pressed(.MOUSE_LEFT) {
window := box.window;
rect := box.rect;
rect.x = clamp(rect.x, cast(float)window.actual_position.x, cast(float)window.actual_position.x + window.size.x);
rect.w += rect.x - box.rect.x;
rect.y = clamp(rect.y, cast(float)window.actual_position.y, cast(float)window.actual_position.y + window.size.y);
rect.h += rect.y - box.rect.y;
if is_mouse_inside(mouse_x, mouse_y, rect) && key_pressed(.MOUSE_LEFT) {
box.interaction.left_mouse_pressed = true;
box.interaction.left_mouse_down = true;
}

View File

@@ -98,6 +98,16 @@ ui_label :: (text: string, text_color: Color = .{1,1,1,1}, identifier: s64 = 0,
box := ui_box_make(.DRAW_TEXT, get_hash(loc, identifier));
}
ui_label_for_fields :: (text: string, text_color: Color = .{1,1,1,1}, identifier: s64 = 0, loc := #caller_location) {
ui_set_next_text(text);
ui_set_next_background_color(.{0.0,1.0,1.0,0.0});
ui_set_next_text_color(text_color);
ui_set_next_size_x(.PCT, 0.5);
ui_set_next_size_y(.TEXT_DIM);
ui_set_next_padding(5);
box := ui_box_make(.DRAW_TEXT, get_hash(loc, identifier));
}
ui_label_fill_parent_x :: (text: string, identifier: s64 = 0, loc := #caller_location) {
ui_set_next_text(text);
ui_set_next_background_color(.{0.0,1.0,1.0,0.0});
@@ -288,7 +298,6 @@ ui_int_field :: (label: string, value: *int, identifier: s64 = 0, loc := #caller
ui_float_field :: (label: string, value: *float, identifier: s64 = 0, loc := #caller_location) -> bool {
changed := false;
ui_container_layout(identifier=identifier, loc=loc);
ui_set_next_size_x(.CHILDREN_SUM);
ui_push_parent(ui_state.last_box, .LEFT, .HORIZONTAL);
{
ui_label(label);
@@ -425,16 +434,27 @@ ui_float_field :: (value: *float, identifier: s64 = 0, loc := #caller_location)
ui_vector_field :: (label: string, value: *Vector3, identifier: s64 = 0, loc := #caller_location) -> bool {
changed := false;
ui_set_next_size_x(.TEXT_DIM);
ui_set_next_size_y(.TEXT_DIM);
ui_container_layout(identifier=identifier, loc=loc);
ui_push_parent(ui_state.last_box, .LEFT, .HORIZONTAL);
{
ui_label(label);
ui_label_for_fields(label);
//ui_set_next_size_x(.PCT, 0.5);
//ui_set_next_size_y(.CHILDREN_SUM);
//container := ui_box_make(0, get_hash(loc, 123));
//ui_push_parent(ui_state.last_box, .LEFT, .HORIZONTAL);
ui_label("X");
changed |= ui_float_field(*value.x);
ui_label("Y");
changed |= ui_float_field(*value.y);
ui_label("Z");
changed |= ui_float_field(*value.z);
//ui_pop_parent();
}
ui_pop_parent();