Files
wschod/game/src/ui/widget_core.h
T
2025-07-07 20:08:33 +02:00

231 lines
5.6 KiB
C

#pragma once
#include <glib-2.0/glib.h>
#include <cglm/cglm.h>
#include "widget_fw.h"
#include "widget_render.h"
#include "widget_layout.h"
#include "widget_style.h"
#include "widget_ops.h"
#include "../util.h"
#include "../resources.h"
#include "../flags.h"
#include "../gl/mesh.h"
#include "../gl/program.h"
#define WIDGET_FOREACH_CHILD(widget, i, child) \
for (unsigned int i = 0; i < widget->children->len && \
((child = g_array_index(widget->children, Widget *, i)), 1); ++i)
typedef enum WidgetKind
{
WIDGET_PLAIN,
WIDGET_LABEL,
WIDGET_SCROLLBAR,
WIDGET_PROGRESS,
WIDGET_ENTRY,
WIDGET_MULTILINE_TEXT,
WIDGET_CONTAINER,
WIDGET_SCROLLABLE,
WIDGET_FLOWBOX,
WIDGET_WINDOW
} WidgetKind;
typedef enum WidgetIcon
{
ICON_NONE = -1,
ICON_CHECKBOX_UNCHECKED = 0,
ICON_CHECKBOX_CHECKED,
ICON_MINUS,
ICON_PLUS,
ICON_ARROW_LEFT,
ICON_ARROW_RIGHT,
ICON_ARROW_UP,
ICON_ARROW_DOWN
} WidgetIcon;
typedef enum WidgetEvent
{
EVENT_TICK,
EVENT_LEFT_DOWN,
EVENT_LEFT_UP,
EVENT_RIGHT_DOWN,
EVENT_RIGHT_UP,
EVENT_MOUSE_ENTER,
EVENT_MOUSE_LEAVE,
EVENT_MOUSE_MOVE,
EVENT_SCROLL_UP,
EVENT_SCROLL_DOWN,
EVENT_FOCUS_GAINED,
EVENT_FOCUS_LOST,
EVENT_TEXT_INPUT,
EVENT_COUNT
} WidgetEvent;
typedef enum TextAlignment
{
TEXT_ALIGN_LEFT,
TEXT_ALIGN_CENTER,
TEXT_ALIGN_RIGHT
} TextAlignment;
typedef struct LabelWidget
{
GString *text;
TextAlignment text_alignment;
} LabelWidget;
typedef struct ScrollbarWidget
{
struct Widget *target;
gboolean horizontal;
/* Used for input. */
gboolean dragging;
float drag_offset;
} ScrollbarWidget;
typedef struct ProgressWidget
{
gboolean horizontal;
float min, max, *ptr;
} ProgressWidget;
typedef struct EntryWidget
{
GString *ghost_text;
GString *content;
/* cursor_position is in UTF-8 characters. */
int cursor_position;
} EntryWidget;
typedef struct MultilineTextWidget
{
GString *text;
GArray *lines;
float line_height;
TextAlignment text_alignment;
} MultilineTextWidget;
typedef struct ContainerWidget
{
gboolean horizontal;
} ContainerWidget;
typedef struct ScrollableWidget
{
gboolean layout_horizontal;
gboolean layout_vertical;
float scroll_amount;
vec2 scroll_position;
vec2 content_size;
} ScrollableWidget;
typedef struct FlowBoxWidget
{
gboolean horizontal;
} FlowBoxWidget;
typedef struct WindowWidget
{
GString *title;
float titlebar_height;
gboolean moving, resizing;
vec2 drag_offset;
gboolean resizable_h, resizable_v;
} WindowWidget;
typedef struct Widget
{
struct Widget *parent;
GArray *children;
WidgetKind kind;
union
{
LabelWidget label;
ScrollbarWidget scrollbar;
ProgressWidget progress;
MultilineTextWidget multiline_text;
EntryWidget entry;
ContainerWidget container;
ScrollableWidget scrollable;
FlowBoxWidget flowbox;
WindowWidget window;
};
gboolean visible;
gboolean layout_dirty;
gboolean hovered, clicked, focused;
vec2 position;
vec2 size;
float layout_weight, layout_padding, layout_spacing;
float aspect_ratio;
WidgetStyle *style;
WidgetIcon icon;
GString *tooltip;
void (*do_layout) (struct Widget *);
void (*do_render) (struct Widget *, mat4, int);
void (*on_event[EVENT_COUNT]) (struct Widget *, SDL_Event *sdl_event, void *);
void *event_data[EVENT_COUNT];
void (*on_key[SDL_SCANCODE_COUNT]) (struct Widget *, SDL_Event *null, void *);
void *key_data[SDL_SCANCODE_COUNT];
} Widget;
Widget *Widget_plain_new ();
Widget *Widget_test_new (float size);
Widget *Widget_label_new (const char *text, TextAlignment alignment);
Widget *Widget_scrollbar_new (Widget *target, gboolean horizontal);
Widget *Widget_progress_new (gboolean horizontal, float min, float max, float *ptr);
Widget *Widget_multiline_text_new (const char *text, float line_height, TextAlignment alignment);
Widget *Widget_entry_new (const char *ghost_text);
Widget *Widget_container_new (gboolean horizontal);
Widget *Widget_scrollable_new ();
Widget *Widget_flowbox_new (gboolean horizontal);
Widget *Widget_window_new (const char *title, float titlebar_height);
void Widget_add_child (Widget *parent, Widget *child);
void Widget_add_child_weighed (Widget *parent, Widget *child,
float layout_weight);
void Widget_add_child_flowbox (Widget *parent, Widget *child,
float layout_weight, float cross_axis_size);
void Widget_set_on_event (Widget *widget, WidgetEvent event, void (*on_event) (Widget *, SDL_Event *, void *), void *userdata);
void Widget_set_on_key (Widget *widget, SDL_Scancode key, void (*on_key) (Widget *, SDL_Event *, void *), void *userdata);
void Widget_set_style (Widget *widget, WidgetStyle style);
void Widget_set_all_backgrounds (Widget *widget, vec4 color);
void Widget_label_set_text (Widget *widget, const char *text);
void Widget_label_printf (Widget *widget, const char *format, ...);
void Widget_multiline_text_set_text (Widget *widget, const char *text);
void Widget_entry_input_text (Widget *widget, const char *text);
void Widget_scrollable_scroll (Widget *widget, vec2 direction);
gboolean wcond_tooltip (Widget *widget, void *userdata);
gboolean wcond_event (Widget *widget, void *event);
gboolean wcond_any (Widget *widget, void *userdata);
Widget *Widget_find_xy_cond (Widget *widget, vec2 point, gboolean (*cond_func) (Widget *, void *), void *userdata);
void Widget_tick (Widget *widget);
void Widget_render (Widget *widget, mat4 projection, int window_height);
void Widget_free (Widget *widget);
void Widget_dump (Widget *widget, int depth);