This commit is contained in:
2025-06-16 09:34:42 +02:00
parent 3875e6ab57
commit 5320c69f7d
6 changed files with 154 additions and 54 deletions
+25 -4
View File
@@ -47,8 +47,6 @@ uiman_init ()
Widget_add_child_weighed (chkboxes, Widget_composite_checkbox_make ("Wireframe", "wireframe_enabled"), 1);
Widget_add_child_weighed (chkboxes, Widget_composite_checkbox_make ("Flight", "flight_enabled"), 1);
Widget_add_child_weighed (debug_menu, chkboxes, 1);
Widget_add_child_weighed (debug_menu, Widget_progress_new (TRUE, 0.0, 0.1, &delta_time), 1);
}
void
@@ -81,6 +79,24 @@ _uiman_call_on_event (Widget *widget, WidgetEvent event)
return FALSE;
}
static inline void
_uiman_set_clicked (Widget *widget, gboolean state)
{
if (widget)
{
widget->clicked = state;
}
}
static inline void
_uiman_set_hovered (Widget *widget, gboolean state)
{
if (widget)
{
widget->hovered = state;
}
}
gboolean
uiman_cb_switch_focus (SDL_Event *event, void *data)
{
@@ -123,7 +139,10 @@ uiman_cb_mouse_motion (SDL_Event *event, void *data)
if (new_hover != hovered_widget)
{
_uiman_call_on_event (hovered_widget, EVENT_MOUSE_LEAVE);
_uiman_set_hovered (hovered_widget, FALSE);
_uiman_set_clicked (hovered_widget, FALSE);
_uiman_call_on_event (new_hover, EVENT_MOUSE_ENTER);
_uiman_set_hovered (new_hover, TRUE);
hovered_widget = new_hover;
}
@@ -140,7 +159,8 @@ uiman_cb_button_down (SDL_Event *event, void *data)
UNUSED (data);
WidgetEvent e = event->button.button == SDL_BUTTON_LEFT ? EVENT_LEFT_DOWN : EVENT_RIGHT_DOWN;
Widget *widget = Widget_find_xy_event (ui_root, (vec2) { event->button.x, event->button.y }, e);
Widget *widget = Widget_find_xy (ui_root, (vec2) { event->button.x, event->button.y });
_uiman_set_clicked (widget, TRUE);
return _uiman_call_on_event (widget, e);
}
@@ -150,7 +170,8 @@ uiman_cb_button_up (SDL_Event *event, void *data)
UNUSED (data);
WidgetEvent e = event->button.button == SDL_BUTTON_LEFT ? EVENT_LEFT_UP : EVENT_RIGHT_UP;
Widget *widget = Widget_find_xy_event (ui_root, (vec2) { event->button.x, event->button.y }, e);
Widget *widget = Widget_find_xy (ui_root, (vec2) { event->button.x, event->button.y });
_uiman_set_clicked (widget, FALSE);
return _uiman_call_on_event (widget, e);
}
+32 -2
View File
@@ -1,5 +1,30 @@
#include "widget_composites.h"
WidgetStyle widget_style_icon_button =
{
.background_color = { 0.0, 0.0, 0.0, 0.0 },
.background_color_hovered = { 0.0, 0.0, 0.0, 0.0 },
.background_color_clicked = { 0.0, 0.0, 0.0, 0.0 },
.text_color = { 1.0, 1.0, 1.0, 1.0 },
.text_color_hovered = { 1.0, 1.0, 1.0, 1.0 },
.text_color_clicked = { 1.0, 1.0, 1.0, 1.0 },
.icon_color = { 1.0, 1.0, 1.0, 1.0 },
.icon_color_hovered = { 1.0, 1.0, 0.0, 1.0 },
.icon_color_clicked = { 1.0, 0.0, 0.0, 1.0 },
.border_color = { 1.0, 1.0, 1.0, 1.0 },
.progress_color = { 1.0, 1.0, 1.0, 1.0 },
.border_width = 0,
.layout_padding = 0,
.layout_child_spacing = 8,
.background_image = 0,
.font_bitmap = 0
};
Widget *
Widget_label_make_int (const char *fmt, int *ptr, TextAlignment alignment)
{
@@ -24,10 +49,13 @@ Widget_composite_spinner_make_int (const char *fmt, int *ptr)
Widget *label = Widget_label_make_int (fmt, ptr, TEXT_ALIGN_CENTER);
Widget *right = Widget_plain_new ();
Widget_set_on_event (left, EVENT_LEFT_UP, uicb_widget_op, WidgetOpData_new (OP_MODIFY_INT, ptr, -1.0));
Widget_set_style (left, widget_style_icon_button);
Widget_set_style (right, widget_style_icon_button);
Widget_set_on_event (left, EVENT_LEFT_DOWN, uicb_widget_op, WidgetOpData_new (OP_MODIFY_INT, ptr, -1.0));
left->icon = ICON_SPINNER_LEFT;
left->aspect_ratio = 1.0;
Widget_set_on_event (right, EVENT_LEFT_UP, uicb_widget_op, WidgetOpData_new (OP_MODIFY_INT, ptr, 1.0));
Widget_set_on_event (right, EVENT_LEFT_DOWN, uicb_widget_op, WidgetOpData_new (OP_MODIFY_INT, ptr, 1.0));
right->icon = ICON_SPINNER_RIGHT;
right->aspect_ratio = 1.0;
@@ -46,6 +74,8 @@ Widget_composite_checkbox_make (const char *label, char *flag)
Widget *cont = Widget_container_new (TRUE);
Widget *box = Widget_plain_new ();
Widget_set_style (box, widget_style_icon_button);
box->icon = ICON_CHECKBOX_UNCHECKED;
box->aspect_ratio = 1.0;
Widget_set_on_tick (box, uicb_widget_op, WidgetOpData_new (OP_CHECKBOX_SHOW_FLAG, flag));
+45 -28
View File
@@ -11,11 +11,20 @@ static const Widget DEFAULT_WIDGET =
.icon = ICON_NONE
};
WidgetStyle DEFAULT_STYLE =
WidgetStyle widget_style_default =
{
.background_color = { 0.0, 0.0, 0.0, 0.0 },
.text_color = { 1.0, 1.0, 1.0, 1.0 },
.icon_color = { 1.0, 1.0, 1.0, 1.0 },
.background_color = { 0.0, 0.0, 0.0, 0.0 },
.background_color_hovered = { 0.0, 0.0, 0.0, 0.0 },
.background_color_clicked = { 0.0, 0.0, 0.0, 0.0 },
.text_color = { 1.0, 1.0, 1.0, 1.0 },
.text_color_hovered = { 1.0, 1.0, 1.0, 1.0 },
.text_color_clicked = { 1.0, 1.0, 1.0, 1.0 },
.icon_color = { 1.0, 1.0, 1.0, 1.0 },
.icon_color_hovered = { 1.0, 1.0, 1.0, 1.0 },
.icon_color_clicked = { 1.0, 1.0, 1.0, 1.0 },
.border_color = { 1.0, 1.0, 1.0, 1.0 },
.progress_color = { 1.0, 1.0, 1.0, 1.0 },
@@ -23,7 +32,8 @@ WidgetStyle DEFAULT_STYLE =
.layout_padding = 0,
.layout_child_spacing = 8,
.background_image = 0
.background_image = 0,
.font_bitmap = 0
};
static inline Widget *
@@ -35,7 +45,8 @@ ui_el_new_internal (WidgetKind kind)
*e = DEFAULT_WIDGET;
e->kind = kind;
e->children = g_array_new (false, false, sizeof (Widget *));
e->style = g_memdup2 (&DEFAULT_STYLE, sizeof (WidgetStyle));
Widget_set_style (e, widget_style_default);
e->style->font_bitmap = RESTEX ("font0");
return e;
}
@@ -45,15 +56,6 @@ Widget_plain_new ()
return ui_el_new_internal (WIDGET_PLAIN);
}
Widget *
Widget_container_new (gboolean horizontal)
{
Widget *e = ui_el_new_internal (WIDGET_CONTAINER);
e->do_layout = Widget_layout_container;
e->container.horizontal = horizontal;
return e;
}
Widget *
Widget_label_new (const char *text, TextAlignment alignment)
{
@@ -64,19 +66,6 @@ Widget_label_new (const char *text, TextAlignment alignment)
return e;
}
Widget *
Widget_scrollable_new ()
{
Widget *e = ui_el_new_internal (WIDGET_SCROLLABLE);
e->do_layout = Widget_layout_scrollable;
e->scrollable.scroll_amount = 10.0;
Widget_set_on_event (e, EVENT_SCROLL_UP, uicb_widget_op,
WidgetOpData_new (OP_SCROLLABLE_SCROLL, e, (vec2) { 0.0, -1.0 }));
Widget_set_on_event (e, EVENT_SCROLL_DOWN, uicb_widget_op,
WidgetOpData_new (OP_SCROLLABLE_SCROLL, e, (vec2) { 0.0, 1.0 }));
return e;
}
Widget *
Widget_scrollbar_new (Widget *target, gboolean horizontal)
{
@@ -103,6 +92,28 @@ Widget_progress_new (gboolean horizontal, float min, float max, float *ptr)
return e;
}
Widget *
Widget_container_new (gboolean horizontal)
{
Widget *e = ui_el_new_internal (WIDGET_CONTAINER);
e->do_layout = Widget_layout_container;
e->container.horizontal = horizontal;
return e;
}
Widget *
Widget_scrollable_new ()
{
Widget *e = ui_el_new_internal (WIDGET_SCROLLABLE);
e->do_layout = Widget_layout_scrollable;
e->scrollable.scroll_amount = 10.0;
Widget_set_on_event (e, EVENT_SCROLL_UP, uicb_widget_op,
WidgetOpData_new (OP_SCROLLABLE_SCROLL, e, (vec2) { 0.0, -1.0 }));
Widget_set_on_event (e, EVENT_SCROLL_DOWN, uicb_widget_op,
WidgetOpData_new (OP_SCROLLABLE_SCROLL, e, (vec2) { 0.0, 1.0 }));
return e;
}
void
Widget_add_child (Widget *parent, Widget *child)
{
@@ -139,6 +150,12 @@ Widget_set_on_event (Widget *widget, WidgetEvent event,
widget->event_data[event] = userdata;
}
void
Widget_set_style (Widget *widget, WidgetStyle style)
{
widget->style = g_memdup2 (&style, sizeof (WidgetStyle));
}
void
Widget_label_set_text (Widget *widget, const char *text)
{
+18 -16
View File
@@ -64,24 +64,12 @@ typedef enum TextAlignment
TEXT_ALIGN_RIGHT
} TextAlignment;
typedef struct ContainerWidget
{
gboolean horizontal;
} ContainerWidget;
typedef struct LabelWidget
{
GString *text;
TextAlignment text_alignment;
} LabelWidget;
typedef struct ScrollableWidget
{
float scroll_amount;
vec2 scroll_position;
vec2 content_size;
} ScrollableWidget;
typedef struct ScrollbarWidget
{
struct Widget *target;
@@ -97,6 +85,18 @@ typedef struct ProgressWidget
float min, max, *ptr;
} ProgressWidget;
typedef struct ContainerWidget
{
gboolean horizontal;
} ContainerWidget;
typedef struct ScrollableWidget
{
float scroll_amount;
vec2 scroll_position;
vec2 content_size;
} ScrollableWidget;
typedef struct Widget
{
struct Widget *parent;
@@ -104,11 +104,12 @@ typedef struct Widget
WidgetKind kind;
union {
ContainerWidget container;
LabelWidget label;
ScrollableWidget scrollable;
ScrollbarWidget scrollbar;
ProgressWidget progress;
ContainerWidget container;
ScrollableWidget scrollable;
};
gboolean visible;
@@ -134,11 +135,11 @@ typedef struct Widget
} Widget;
Widget *Widget_plain_new ();
Widget *Widget_container_new (gboolean horizontal);
Widget *Widget_label_new (const char *text, TextAlignment alignment);
Widget *Widget_scrollable_new ();
Widget *Widget_scrollbar_new (Widget *target, gboolean horizontal);
Widget *Widget_progress_new (gboolean horizontal, float min, float max, float *ptr);
Widget *Widget_container_new (gboolean horizontal);
Widget *Widget_scrollable_new ();
void Widget_add_child (Widget *parent, Widget *child);
void Widget_add_child_weighed (Widget *parent, Widget *child,
@@ -146,6 +147,7 @@ void Widget_add_child_weighed (Widget *parent, Widget *child,
void Widget_set_on_tick (Widget *widget, void (*on_tick) (Widget *, void *), void *userdata);
void Widget_set_on_event (Widget *widget, WidgetEvent event, void (*on_event) (Widget *, void *), void *userdata);
void Widget_set_style (Widget *widget, WidgetStyle style);
void Widget_label_set_text (Widget *widget, const char *text);
void Widget_label_printf (Widget *widget, const char *format, ...);
+24 -4
View File
@@ -31,13 +31,24 @@ Widget_render_base (Widget *self, mat4 projection, int window_height)
program_set_int (RESPRG ("uiwidget"), "has_background_image", style->background_image != 0);
texture_use (style->background_image, 0); /* If it doesn't have a texture, it'll be 0 anyway. */
program_set_vec4 (RESPRG ("uiwidget"), "background_color", style->background_color);
program_set_int (RESPRG ("uiwidget"), "has_icon", self->icon != -1);
program_set_float (RESPRG ("uiwidget"), "icon_index", self->icon);
program_set_vec4 (RESPRG ("uiwidget"), "icon_color", style->icon_color);
texture_use (RESTEX ("icons"), 1);
program_set_vec4 (RESPRG ("uiwidget"), "background_color", style->background_color);
program_set_vec4 (RESPRG ("uiwidget"), "icon_color", style->icon_color);
if (self->clicked)
{
program_set_vec4 (RESPRG ("uiwidget"), "background_color", style->background_color_clicked);
program_set_vec4 (RESPRG ("uiwidget"), "icon_color", style->icon_color_clicked);
}
else if (self->hovered)
{
program_set_vec4 (RESPRG ("uiwidget"), "background_color", style->background_color_hovered);
program_set_vec4 (RESPRG ("uiwidget"), "icon_color", style->icon_color_hovered);
}
mat3 model;
glm_translate2d_make (model, self->position);
glm_scale2d (model, self->size);
@@ -87,7 +98,16 @@ Widget_render_label (Widget *self, mat4 projection, int window_height)
program_use (RESPRG ("uitext"));
program_set_mat4 (RESPRG ("uitext"), "projection", projection);
program_set_vec4 (RESPRG ("uitext"), "color", style->text_color);
texture_use (RESTEX ("font0"), 0);
texture_use (self->style->font_bitmap, 0);
if (self->clicked)
{
program_set_vec4 (RESPRG ("uitext"), "color", style->text_color_clicked);
}
else if (self->hovered)
{
program_set_vec4 (RESPRG ("uitext"), "color", style->text_color_hovered);
}
float char_width = self->size[1] * 0.5;
float total_width = g_utf8_strlen (self->label.text->str, -1) * char_width;
+10
View File
@@ -6,8 +6,17 @@
typedef struct WidgetStyle
{
vec4 background_color;
vec4 background_color_hovered;
vec4 background_color_clicked;
vec4 text_color;
vec4 text_color_hovered;
vec4 text_color_clicked;
vec4 icon_color;
vec4 icon_color_hovered;
vec4 icon_color_clicked;
vec4 border_color;
vec4 progress_color;
@@ -17,5 +26,6 @@ typedef struct WidgetStyle
float layout_child_spacing;
unsigned int background_image;
unsigned int font_bitmap;
} WidgetStyle;