Aspect ratios in widgets

This commit is contained in:
2025-06-14 11:33:13 +02:00
parent d8aeca2d42
commit d899465ffd
3 changed files with 94 additions and 39 deletions
+7 -2
View File
@@ -26,7 +26,7 @@ uiman_init ()
Widget *debug_menu = Widget_container_new (FALSE, 8, 4);
Widget_set_background_image (debug_menu, RESTEX ("terrain4"));
VEC2_SETI (debug_menu->position, 32, 32);
VEC2_SETI (debug_menu->size, 350, 150);
VEC2_SETI (debug_menu->size, 350, 170);
debug_menu->border_width = 2;
VEC4_SETI (debug_menu->border_color, 0, 0, 0, 1);
Widget_add_child (ui_root, debug_menu);
@@ -36,7 +36,7 @@ uiman_init ()
Widget_add_child_weighed (debug_menu, Widget_label_make_int ("Chunks rendered: %d", &n_frame_chunks, TEXT_ALIGN_LEFT), 1);
Widget_add_child_weighed (debug_menu, Widget_label_make_int ("Entities rendered: %d", &n_frame_ents, TEXT_ALIGN_LEFT), 1);
Widget *poscont = Widget_container_new (TRUE, 0, 0);
Widget *poscont = Widget_container_new (TRUE, 0, 4);
Widget_add_child_weighed (poscont, Widget_label_make_float ("X: %.1f", &camera_position[0], TEXT_ALIGN_LEFT), 1);
Widget_add_child_weighed (poscont, Widget_label_make_float ("Y: %.1f", &camera_position[1], TEXT_ALIGN_CENTER), 1);
Widget_add_child_weighed (poscont, Widget_label_make_float ("Z: %.1f", &camera_position[2], TEXT_ALIGN_RIGHT), 1);
@@ -46,6 +46,11 @@ uiman_init ()
Widget_add_child_weighed (buttons, Widget_label_make_flag_switch_button ("Toggle wireframe", "wireframe_enabled"), 1);
Widget_add_child_weighed (buttons, Widget_label_make_flag_switch_button ("Toggle flying", "flight_enabled"), 1);
Widget *square_button = Widget_label_make_flag_switch_button ("T", "");
square_button->aspect_ratio = 1.0;
Widget_add_child_weighed (buttons, square_button, 1);
Widget_add_child_weighed (debug_menu, buttons, 1);
}
+64 -15
View File
@@ -216,9 +216,23 @@ Widget_container_layout (Widget *parent, gboolean horizontal)
float total_fixed = 0.0;
Widget *child;
WIDGET_FOREACH_CHILD (parent, i, child) {
if (child->layout_weight == 0.0)
WIDGET_FOREACH_CHILD (parent, i, child)
{
if (child->layout_weight == 0.0 || child->aspect_ratio > 0.0)
{
if (horizontal)
{
float h = parent->size[1] - 2 * parent->container.padding;
child->size[1] = h;
child->size[0] = h * child->aspect_ratio;
}
else
{
float w = parent->size[0] - 2 * parent->container.padding;
child->size[0] = w;
child->size[1] = w / child->aspect_ratio;
}
total_fixed += horizontal ? child->size[0] : child->size[1];
}
else
@@ -233,22 +247,55 @@ Widget_container_layout (Widget *parent, gboolean horizontal)
float weights_size = total_weights > 0.0 ? (total_size - total_fixed) / total_weights : 0;
float offset = parent->container.padding;
WIDGET_FOREACH_CHILD (parent, i, child) {
float size = (child->layout_weight == 0.0)
? (horizontal ? child->size[0] : child->size[1])
: child->layout_weight * weights_size;
WIDGET_FOREACH_CHILD (parent, i, child)
{
float size;
if (child->layout_weight == 0.0 || child->aspect_ratio > 0.0)
{
size = horizontal ? child->size[0] : child->size[1];
}
else
{
size = child->layout_weight * weights_size;
if (child->aspect_ratio > 0.0f)
{
if (horizontal)
{
child->size[0] = size;
child->size[1] = size / child->aspect_ratio;
}
else
{
child->size[1] = size;
child->size[0] = size * child->aspect_ratio;
}
}
else
{
if (horizontal)
{
child->size[0] = size;
child->size[1] = parent->size[1] - 2 * parent->container.padding;
}
else
{
child->size[1] = size;
child->size[0] = parent->size[0] - 2 * parent->container.padding;
}
}
}
if (horizontal)
{
VEC2_SETI (child->position, parent->position[0] + offset,
parent->position[1] + parent->container.padding);
VEC2_SETI (child->size, size, parent->size[1] - 2 * parent->container.padding);
}
else
{
VEC2_SETI (child->position, parent->position[0] + parent->container.padding,
parent->position[1] + offset);
VEC2_SETI (child->size, parent->size[0] - 2 * parent->container.padding, size);
}
offset += size + parent->container.child_spacing;
@@ -301,8 +348,10 @@ Widget_render (Widget *widget, mat4 projection, int window_height)
program_set_mat4 (RESPRG ("uiwidget"), "projection", projection);
/* X, Y is the lower left corner of the box. */
glScissor (widget->position[0], window_height - widget->position[1]
- widget->size[1], widget->size[0], widget->size[1]);
glScissor (floor (widget->position[0]),
floor (window_height - widget->position[1] - widget->size[1]),
ceil (widget->size[0]),
ceil (widget->size[1]));
SimpleMesh_render (&quad, FALSE);
@@ -384,11 +433,11 @@ Widget *
Widget_label_make_flag_switch_button (const char *text, char *flag)
{
Widget *w = Widget_label_new (text, TEXT_ALIGN_CENTER);
VEC4_SETI (w->background_color, 1, 1, 1, 0.1);
VEC4_SETI (w->hovered_bg_color, 1, 1, 1, 0.2);
VEC4_SETI (w->clicked_bg_color, 1, 1, 1, 0.3);
w->border_width = 2;
VEC4_SETI (w->border_color, 1, 1, 1, 0.5);
VEC4_SETI (w->background_color, 0.3, 0.3, 0.3, 1.0);
VEC4_SETI (w->hovered_bg_color, 0.5, 0.5, 0.5, 1.0);
VEC4_SETI (w->clicked_bg_color, 0.7, 0.7, 0.7, 1.0);
w->border_width = 3;
VEC4_SETI (w->border_color, 0.8, 0.8, 0.8, 1.0);
Widget_set_on_left_click (w, uicb_switch_flag, flag);
return w;
}
+1
View File
@@ -58,6 +58,7 @@ typedef struct Widget
vec2 position;
vec2 size;
float layout_weight;
float aspect_ratio;
vec4 background_color;
vec4 hovered_bg_color;