215 lines
4.6 KiB
C
215 lines
4.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 WFOREACH(widget, child) \
|
|
for (unsigned int _i = 0; _i < (widget)->children->len; ++_i) \
|
|
for (Widget *child = g_array_index ((widget)->children, Widget *, _i); child; child = NULL)
|
|
|
|
#define SCROLL_UP (vec2) { 0.0, -1.0 }
|
|
#define SCROLL_DOWN (vec2) { 0.0, 1.0 }
|
|
|
|
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,
|
|
ICON_CHECKBOX_UNCHECKED,
|
|
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;
|
|
int 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;
|
|
int line_height;
|
|
TextAlignment text_alignment;
|
|
} MultilineTextWidget;
|
|
|
|
typedef struct ContainerWidget
|
|
{
|
|
gboolean horizontal;
|
|
} ContainerWidget;
|
|
|
|
typedef struct ScrollableWidget
|
|
{
|
|
gboolean layout_horizontal;
|
|
gboolean layout_vertical;
|
|
|
|
int scroll_amount;
|
|
ivec2 scroll_position;
|
|
ivec2 content_size;
|
|
} ScrollableWidget;
|
|
|
|
typedef struct FlowBoxWidget
|
|
{
|
|
gboolean horizontal;
|
|
} FlowBoxWidget;
|
|
|
|
typedef struct WindowWidget
|
|
{
|
|
GString *title;
|
|
int titlebar_height;
|
|
gboolean moving, resizing;
|
|
ivec2 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; /* Unused. */
|
|
gboolean hovered, clicked, focused;
|
|
|
|
ivec2 position;
|
|
ivec2 size;
|
|
int layout_padding, layout_spacing;
|
|
float layout_weight, aspect_ratio;
|
|
|
|
const 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_new ();
|
|
|
|
void Widget_add_child (Widget *parent, Widget *child);
|
|
|
|
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_label_printf (Widget *widget, const char *format, ...);
|
|
|
|
void Widget_entry_input_text (Widget *widget, const char *text);
|
|
|
|
void Widget_scrollable_scroll (Widget *widget, ivec2 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, ivec2 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);
|