231 lines
5.6 KiB
C
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);
|