More UI additions
This commit is contained in:
@@ -4,6 +4,7 @@ attribute vec3 position;
|
||||
attribute vec2 uv;
|
||||
|
||||
uniform mat3 model;
|
||||
uniform mat4 projection;
|
||||
uniform float character;
|
||||
|
||||
varying vec2 f_uv;
|
||||
@@ -26,5 +27,5 @@ void main ()
|
||||
|
||||
f_uv = char_offset + uv * char_size;
|
||||
|
||||
gl_Position = vec4 (model * vec3 (position.xy, 1.0), 1.0);
|
||||
gl_Position = projection * vec4 (model * vec3 (position.xy, 1.0), 1.0);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@ void main ()
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = vec4 (1.0, 1.0, 1.0, 1.0);
|
||||
gl_FragColor = vec4 (0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,16 +164,11 @@ chunkman_render (vec3 position, vec4 planes[6])
|
||||
|
||||
program_use (RESPRG ("chunk"));
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain0"));
|
||||
glActiveTexture (GL_TEXTURE1);
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain1"));
|
||||
glActiveTexture (GL_TEXTURE2);
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain2"));
|
||||
glActiveTexture (GL_TEXTURE3);
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain3"));
|
||||
glActiveTexture (GL_TEXTURE4);
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain4"));
|
||||
texture_use (RESTEX ("terrain0"), 0);
|
||||
texture_use (RESTEX ("terrain1"), 1);
|
||||
texture_use (RESTEX ("terrain2"), 2);
|
||||
texture_use (RESTEX ("terrain3"), 3);
|
||||
texture_use (RESTEX ("terrain4"), 4);
|
||||
|
||||
n_frame_chunks = 0;
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ static GArray *entities;
|
||||
static GQueue *spawn_requests;
|
||||
|
||||
static SimpleMesh mesh_quad1, mesh_quad2, mesh_quad_x;
|
||||
static unsigned int last_program = -1;
|
||||
static unsigned int last_type = -1;
|
||||
static unsigned int last_texture = -1;
|
||||
static unsigned int last_program = 0;
|
||||
static unsigned int last_type = 0;
|
||||
static unsigned int last_texture = 0;
|
||||
|
||||
void
|
||||
character_on_tick (Entity *entity)
|
||||
@@ -224,8 +224,7 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
|
||||
if (entity->texture != last_texture)
|
||||
{
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
last_texture = texture_use (entity->texture);
|
||||
last_texture = texture_use (entity->texture, 0);
|
||||
}
|
||||
|
||||
if (entity->mesh_type != last_type)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "texture.h"
|
||||
|
||||
unsigned int
|
||||
texture_use (unsigned int texture)
|
||||
texture_use (unsigned int texture, unsigned int slot)
|
||||
{
|
||||
glActiveTexture (GL_TEXTURE0 + slot);
|
||||
glBindTexture (GL_TEXTURE_2D, texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
#include <SDL3/SDL_opengles2.h>
|
||||
|
||||
unsigned int texture_use (unsigned int texture);
|
||||
unsigned int texture_use (unsigned int texture, unsigned int slot);
|
||||
unsigned int texture_create (int width, int height, unsigned char *data);
|
||||
|
||||
+40
-67
@@ -5,6 +5,12 @@
|
||||
extern SDL_Window *sdl_window;
|
||||
extern int sdl_window_w, sdl_window_h;
|
||||
|
||||
extern float delta_time;
|
||||
extern int n_frame_ents;
|
||||
extern int n_frame_chunks;
|
||||
extern int render_distance;
|
||||
extern vec3 camera_position;
|
||||
|
||||
static Widget *ui_root;
|
||||
static mat4 projection;
|
||||
|
||||
@@ -15,11 +21,25 @@ uiman_init ()
|
||||
ui_widget_mesh_init ();
|
||||
glm_ortho (0.0, (float) sdl_window_w, (float) sdl_window_h, 0.0, -1.0, 1.0, projection);
|
||||
|
||||
Widget *debug_menu = Widget_plain_new ();
|
||||
Widget *debug_menu = Widget_container_new (FALSE);
|
||||
Widget_set_texture (debug_menu, RESTEX ("terrain4"));
|
||||
Widget_set_position (debug_menu, 32, 32);
|
||||
Widget_set_size (debug_menu, 300, 300);
|
||||
Widget_set_size (debug_menu, 300, 150);
|
||||
Widget_add_child (ui_root, debug_menu);
|
||||
|
||||
Widget_add_child (debug_menu, Widget_label_make_float ("Frame time: %.3f", &delta_time, TEXT_ALIGN_LEFT));
|
||||
Widget_add_child (debug_menu, Widget_label_make_int ("Render distance: %d", &render_distance, TEXT_ALIGN_LEFT));
|
||||
Widget_add_child (debug_menu, Widget_label_make_int ("Chunks rendered: %d", &n_frame_chunks, TEXT_ALIGN_LEFT));
|
||||
Widget_add_child (debug_menu, Widget_label_make_int ("Entities rendered: %d", &n_frame_ents, TEXT_ALIGN_LEFT));
|
||||
|
||||
Widget *poscont = Widget_container_new (TRUE);
|
||||
Widget_add_child (poscont, Widget_label_make_float ("X: %.0f", &camera_position[0], TEXT_ALIGN_LEFT));
|
||||
Widget_add_child (poscont, Widget_label_make_float ("Y: %.0f", &camera_position[1], TEXT_ALIGN_CENTER));
|
||||
Widget_add_child (poscont, Widget_label_make_float ("Z: %.0f", &camera_position[2], TEXT_ALIGN_RIGHT));
|
||||
Widget_add_child (debug_menu, poscont);
|
||||
|
||||
Widget_add_child (debug_menu, Widget_label_make_flag_switch_button ("Toggle wireframe", "wireframe_enabled"));
|
||||
Widget_add_child (debug_menu, Widget_label_make_flag_switch_button ("Toggle flight", "flight_enabled"));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -68,30 +88,11 @@ uiman_cb_key_up (SDL_Event *event, void *data)
|
||||
gboolean
|
||||
uiman_cb_mouse_motion (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
/* int win_w, win_h; */
|
||||
/* SDL_GetWindowSize (sdl_window, &win_w, &win_h); */
|
||||
UNUSED (data);
|
||||
|
||||
/* vec2 ui_pos; */
|
||||
/* screen_to_ui_coords (event->motion.x, event->motion.y, win_w, win_h, ui_pos); */
|
||||
|
||||
/* Widget *widget = Widget_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos); */
|
||||
|
||||
/* if (widget != hovered_widget) */
|
||||
/* { */
|
||||
/* if (hovered_widget) */
|
||||
/* { */
|
||||
/* hovered_widget->hovered = false; */
|
||||
/* } */
|
||||
|
||||
/* if (widget) */
|
||||
/* { */
|
||||
/* widget->hovered = true; */
|
||||
/* } */
|
||||
|
||||
/* hovered_widget = widget; */
|
||||
/* } */
|
||||
|
||||
Widget *widget = Widget_find_xy (ui_root, (vec2) { event->motion.x, event->motion.y });
|
||||
UNUSED (widget);
|
||||
|
||||
/* This callback always eats the event, because why would the game
|
||||
need mouse motion if the UI has stolen the focus? */
|
||||
return TRUE;
|
||||
@@ -102,43 +103,22 @@ uiman_cb_button_down (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
|
||||
/* int win_w, win_h; */
|
||||
/* SDL_GetWindowSize (sdl_window, &win_w, &win_h); */
|
||||
|
||||
/* vec2 ui_pos; */
|
||||
/* screen_to_ui_coords (event->motion.x, event->motion.y, win_w, win_h, ui_pos); */
|
||||
|
||||
/* Widget *widget = Widget_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos); */
|
||||
|
||||
/* if (widget != clicked_widget) */
|
||||
/* { */
|
||||
/* if (clicked_widget) */
|
||||
/* { */
|
||||
/* clicked_widget->clicked = FALSE; */
|
||||
/* } */
|
||||
|
||||
/* if (widget) */
|
||||
/* { */
|
||||
/* widget->clicked = TRUE; */
|
||||
/* } */
|
||||
|
||||
/* clicked_widget = widget; */
|
||||
/* } */
|
||||
Widget *widget = Widget_find_xy (ui_root, (vec2) { event->motion.x, event->motion.y });
|
||||
|
||||
/* if (widget) */
|
||||
/* { */
|
||||
/* if (event->button.button == SDL_BUTTON_LEFT && widget->on_left_click) */
|
||||
/* { */
|
||||
/* widget->on_left_click (widget, widget->left_click_data); */
|
||||
/* return true; */
|
||||
/* } */
|
||||
if (widget)
|
||||
{
|
||||
if (event->button.button == SDL_BUTTON_LEFT && widget->on_left_click)
|
||||
{
|
||||
widget->on_left_click (widget, widget->left_click_data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* if (event->button.button == SDL_BUTTON_RIGHT && widget->on_right_click) */
|
||||
/* { */
|
||||
/* widget->on_right_click (widget, widget->right_click_data); */
|
||||
/* return true; */
|
||||
/* } */
|
||||
/* } */
|
||||
if (event->button.button == SDL_BUTTON_RIGHT && widget->on_right_click)
|
||||
{
|
||||
widget->on_right_click (widget, widget->right_click_data);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -147,13 +127,6 @@ gboolean
|
||||
uiman_cb_button_up (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
|
||||
/* if (clicked_widget) */
|
||||
/* { */
|
||||
/* clicked_widget->clicked = FALSE; */
|
||||
/* clicked_widget = NULL; */
|
||||
/* } */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
+248
-13
@@ -1,5 +1,10 @@
|
||||
#include "widget.h"
|
||||
|
||||
/* TODO: padding */
|
||||
/* TODO: movable and resizable windows */
|
||||
/* TODO: "spinner" UI element */
|
||||
/* TODO: "checkbox" UI element */
|
||||
|
||||
static SimpleMesh quad;
|
||||
static unsigned int last_program;
|
||||
|
||||
@@ -12,6 +17,7 @@ ui_el_new_internal (WidgetKind kind)
|
||||
e->kind = kind;
|
||||
e->visible = true;
|
||||
e->children = g_array_new (false, false, sizeof (Widget *));
|
||||
e->layout_weight = 1;
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -22,6 +28,24 @@ Widget_plain_new ()
|
||||
return e;
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_container_new (gboolean horizontal)
|
||||
{
|
||||
Widget *e = ui_el_new_internal (WIDGET_CONTAINER);
|
||||
e->container.horizontal = horizontal;
|
||||
return e;
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_label_new (const char *text, TextAlignment alignment)
|
||||
{
|
||||
Widget *e = ui_el_new_internal (WIDGET_LABEL);
|
||||
e->label.text = g_string_new (text);
|
||||
e->label.text_alignment = alignment;
|
||||
glm_vec4_one (e->label.text_color);
|
||||
return e;
|
||||
}
|
||||
|
||||
void
|
||||
Widget_add_child (Widget *parent, Widget *child)
|
||||
{
|
||||
@@ -29,9 +53,16 @@ Widget_add_child (Widget *parent, Widget *child)
|
||||
g_array_append_val (parent->children, child);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_add_child_weighed (Widget *parent, Widget *child, float layout_weight)
|
||||
{
|
||||
child->layout_weight = layout_weight;
|
||||
Widget_add_child (parent, child);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_on_tick (Widget *widget,
|
||||
void (*on_tick) (struct Widget *, void *),
|
||||
void (*on_tick) (Widget *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
widget->on_tick = on_tick;
|
||||
@@ -40,7 +71,7 @@ Widget_set_on_tick (Widget *widget,
|
||||
|
||||
void
|
||||
Widget_set_on_left_click (Widget *widget,
|
||||
void (*on_left_click) (struct Widget *, void *),
|
||||
void (*on_left_click) (Widget *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
widget->on_left_click = on_left_click;
|
||||
@@ -66,19 +97,60 @@ Widget_set_texture (Widget *widget, unsigned int texture)
|
||||
widget->has_texture = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
Widget_label_set_text (Widget *widget, const char *text)
|
||||
{
|
||||
g_string_overwrite (widget->label.text, 0, text);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_label_printf (Widget *widget, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
g_string_vprintf (widget->label.text, format, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
gboolean
|
||||
Widget_hit_test (Widget *widget, vec2 point)
|
||||
{
|
||||
UNUSED (widget, point);
|
||||
/* TODO: figure out. */
|
||||
return FALSE;
|
||||
float x = point[0];
|
||||
float y = point[1];
|
||||
|
||||
float left = widget->position[0];
|
||||
float top = widget->position[1];
|
||||
float right = left + widget->size[0];
|
||||
float bottom = top + widget->size[1];
|
||||
|
||||
return (x >= left && x <= right
|
||||
&& y >= top && y <= bottom);
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_find_xy (Widget *widget, vec2 pos)
|
||||
{
|
||||
UNUSED (widget, pos);
|
||||
/* TODO: figure out. */
|
||||
if (!widget->visible)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (gint i = widget->children->len - 1; i >= 0; --i)
|
||||
{
|
||||
Widget *child = g_array_index (widget->children, Widget *, i);
|
||||
Widget *found = Widget_find_xy (child, pos);
|
||||
|
||||
if (found != NULL)
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
if (Widget_hit_test (widget, pos))
|
||||
{
|
||||
return widget;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -96,13 +168,102 @@ Widget_tick (Widget *widget)
|
||||
widget->on_tick (widget, widget->tick_data);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < widget->children->len; ++i)
|
||||
for (unsigned int i = 0; i < widget->children->len; ++i)
|
||||
{
|
||||
Widget *child = g_array_index (widget->children, Widget *, i);
|
||||
Widget_tick (child);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Widget_label_render_text (Widget *widget, mat4 projection)
|
||||
{
|
||||
if (last_program != RESPRG ("uitext"))
|
||||
{
|
||||
last_program = program_use (RESPRG ("uitext"));
|
||||
}
|
||||
|
||||
program_set_mat4 (RESPRG ("uitext"), "projection", projection);
|
||||
texture_use (RESTEX ("font0"), 0);
|
||||
|
||||
float char_width = widget->size[1] * 0.5;
|
||||
float total_width = g_utf8_strlen (widget->label.text->str, -1) * char_width;
|
||||
float offset = 0.0;
|
||||
|
||||
switch (widget->label.text_alignment)
|
||||
{
|
||||
case TEXT_ALIGN_LEFT:
|
||||
offset = -char_width;
|
||||
break;
|
||||
case TEXT_ALIGN_CENTER:
|
||||
offset = (widget->size[0] / 2) - (total_width / 2.0) -char_width;
|
||||
break;
|
||||
case TEXT_ALIGN_RIGHT:
|
||||
offset = widget->size[0] - total_width - char_width;
|
||||
break;
|
||||
}
|
||||
|
||||
const char *p = widget->label.text->str;
|
||||
while (*p)
|
||||
{
|
||||
gunichar ch = g_utf8_get_char (p);
|
||||
|
||||
program_set_float (RESPRG ("uitext"), "character", ch);
|
||||
program_set_vec4 (RESPRG ("uitext"), "text_color", widget->label.text_color);
|
||||
|
||||
mat3 model;
|
||||
glm_translate2d_make (model, (vec2) { widget->position[0] + offset + char_width, widget->position[1] });
|
||||
glm_scale2d (model, (vec2) { char_width, widget->size[1] });
|
||||
offset += char_width;
|
||||
|
||||
program_set_mat3 (RESPRG ("uitext"), "model", model);
|
||||
|
||||
SimpleMesh_render (&quad, FALSE);
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Widget_container_layout (Widget *parent, gboolean horizontal)
|
||||
{
|
||||
float total_weights = 0.0;
|
||||
for (unsigned int i = 0; i < parent->children->len; ++i)
|
||||
{
|
||||
Widget *child = g_array_index (parent->children, Widget *, i);
|
||||
total_weights += child->layout_weight;
|
||||
}
|
||||
|
||||
float offset = 0.0;
|
||||
for (unsigned int i = 0; i < parent->children->len; ++i)
|
||||
{
|
||||
Widget *child = g_array_index (parent->children, Widget *, i);
|
||||
|
||||
if (horizontal)
|
||||
{
|
||||
float weights_size = parent->size[0] / total_weights;
|
||||
child->size[0] = child->layout_weight * weights_size;
|
||||
child->size[1] = parent->size[1];
|
||||
|
||||
child->position[0] = parent->position[0] + offset;
|
||||
child->position[1] = parent->position[1];
|
||||
|
||||
offset += child->size[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
float weights_size = parent->size[1] / total_weights;
|
||||
child->size[1] = child->layout_weight * weights_size;
|
||||
child->size[0] = parent->size[0];
|
||||
|
||||
child->position[1] = parent->position[1] + offset;
|
||||
child->position[0] = parent->position[0];
|
||||
|
||||
offset += child->size[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Widget_render (Widget *widget, mat4 projection)
|
||||
{
|
||||
@@ -124,20 +285,94 @@ Widget_render (Widget *widget, mat4 projection)
|
||||
}
|
||||
|
||||
program_set_int (RESPRG ("uiwidget"), "has_texture", widget->has_texture);
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
texture_use (widget->texture); /* If it doesn't have a texture, it'll be 0 anyway. */
|
||||
texture_use (widget->texture, 0); /* If it doesn't have a texture, it'll be 0 anyway. */
|
||||
|
||||
mat3 model;
|
||||
mat3 model;
|
||||
glm_translate2d_make (model, widget->position);
|
||||
glm_scale2d (model, widget->size);
|
||||
|
||||
program_set_mat3 (RESPRG ("uiwidget"), "model", model);
|
||||
program_set_mat4 (RESPRG ("uiwidget"), "projection", projection);
|
||||
SimpleMesh_render (&quad, false);
|
||||
SimpleMesh_render (&quad, FALSE);
|
||||
|
||||
if (widget->kind == WIDGET_CONTAINER)
|
||||
{
|
||||
Widget_container_layout (widget, widget->container.horizontal);
|
||||
}
|
||||
|
||||
if (widget->kind == WIDGET_LABEL)
|
||||
{
|
||||
Widget_label_render_text (widget, projection);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < widget->children->len; ++i)
|
||||
for (unsigned int i = 0; i < widget->children->len; ++i)
|
||||
{
|
||||
Widget *child = g_array_index (widget->children, Widget *, i);
|
||||
Widget_render (child, projection);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------- */
|
||||
|
||||
LabelFormatData *
|
||||
LabelFormatData_new_int (const char *fmt, int *ptr)
|
||||
{
|
||||
LabelFormatData *data = g_new (LabelFormatData, 1);
|
||||
data->fmt = fmt;
|
||||
data->ptr_int = ptr;
|
||||
return data;
|
||||
}
|
||||
|
||||
LabelFormatData *
|
||||
LabelFormatData_new_float (const char *fmt, float *ptr)
|
||||
{
|
||||
LabelFormatData *data = g_new (LabelFormatData, 1);
|
||||
data->fmt = fmt;
|
||||
data->ptr_float = ptr;
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
uicb_label_show_int (Widget *self, void *userdata)
|
||||
{
|
||||
LabelFormatData *format_data = userdata;
|
||||
Widget_label_printf (self, format_data->fmt, *format_data->ptr_int);
|
||||
}
|
||||
|
||||
void uicb_label_show_float (Widget *self, void *userdata)
|
||||
{
|
||||
LabelFormatData *format_data = userdata;
|
||||
Widget_label_printf (self, format_data->fmt, *format_data->ptr_float);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_switch_flag (Widget *self, void *userdata)
|
||||
{
|
||||
UNUSED (self);
|
||||
char *flag = userdata;
|
||||
flags_switch (flag);
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_label_make_int (const char *fmt, int *ptr, TextAlignment alignment)
|
||||
{
|
||||
Widget *w = Widget_label_new (NULL, alignment);
|
||||
Widget_set_on_tick (w, uicb_label_show_int, LabelFormatData_new_int (fmt, ptr));
|
||||
return w;
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_label_make_float (const char *fmt, float *ptr, TextAlignment alignment)
|
||||
{
|
||||
Widget *w = Widget_label_new (NULL, alignment);
|
||||
Widget_set_on_tick (w, uicb_label_show_float, LabelFormatData_new_float (fmt, ptr));
|
||||
return w;
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_label_make_flag_switch_button (const char *text, char *flag)
|
||||
{
|
||||
Widget *w = Widget_label_new (text, TEXT_ALIGN_CENTER);
|
||||
Widget_set_on_left_click (w, uicb_switch_flag, flag);
|
||||
return w;
|
||||
}
|
||||
|
||||
+62
-5
@@ -11,21 +11,46 @@
|
||||
|
||||
typedef enum WidgetKind
|
||||
{
|
||||
WIDGET_PLAIN
|
||||
WIDGET_PLAIN,
|
||||
WIDGET_CONTAINER,
|
||||
WIDGET_LABEL
|
||||
} WidgetKind;
|
||||
|
||||
typedef struct ContainerWidget
|
||||
{
|
||||
gboolean horizontal;
|
||||
} ContainerWidget;
|
||||
|
||||
typedef enum TextAlignment
|
||||
{
|
||||
TEXT_ALIGN_LEFT,
|
||||
TEXT_ALIGN_CENTER,
|
||||
TEXT_ALIGN_RIGHT
|
||||
} TextAlignment;
|
||||
|
||||
typedef struct LabelWidget
|
||||
{
|
||||
GString *text;
|
||||
vec4 text_color;
|
||||
TextAlignment text_alignment;
|
||||
} LabelWidget;
|
||||
|
||||
typedef struct Widget
|
||||
{
|
||||
struct Widget *parent;
|
||||
GArray *children;
|
||||
|
||||
WidgetKind kind;
|
||||
union {
|
||||
ContainerWidget container;
|
||||
LabelWidget label;
|
||||
};
|
||||
|
||||
gboolean visible;
|
||||
|
||||
|
||||
vec2 position;
|
||||
vec2 size;
|
||||
float padding;
|
||||
float layout_weight;
|
||||
|
||||
gboolean has_texture;
|
||||
unsigned int texture;
|
||||
@@ -39,18 +64,50 @@ typedef struct Widget
|
||||
} Widget;
|
||||
|
||||
Widget *Widget_plain_new ();
|
||||
Widget *Widget_container_new (gboolean horizontal);
|
||||
Widget *Widget_label_new (const char *text, TextAlignment alignment);
|
||||
|
||||
void Widget_add_child (Widget *parent, Widget *child);
|
||||
void Widget_add_child_weighed (Widget *parent, Widget *child,
|
||||
float layout_weight);
|
||||
|
||||
void Widget_set_on_tick (Widget *widget, void (*on_tick) (struct Widget *, void *), void *userdata);
|
||||
void Widget_set_on_left_click (Widget *widget, void (*on_left_click) (struct Widget *, void *), void *userdata);
|
||||
void Widget_set_on_tick (Widget *widget,
|
||||
void (*on_tick) (Widget *, void *),
|
||||
void *userdata);
|
||||
void Widget_set_on_left_click (Widget *widget,
|
||||
void (*on_left_click) (Widget *, void *),
|
||||
void *userdata);
|
||||
|
||||
void Widget_set_position (Widget *widget, float x, float y);
|
||||
void Widget_set_size (Widget *widget, float x, float y);
|
||||
void Widget_set_texture (Widget *widget, unsigned int texture);
|
||||
|
||||
void Widget_label_set_text (Widget *widget, const char *text);
|
||||
void Widget_label_printf (Widget *widget, const char *format, ...);
|
||||
|
||||
Widget *Widget_find_xy (Widget *widget, vec2 point);
|
||||
|
||||
void ui_widget_mesh_init ();
|
||||
void Widget_tick (Widget *widget);
|
||||
void Widget_render (Widget *widget, mat4 projection);
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
typedef struct LabelFormatData
|
||||
{
|
||||
const char *fmt;
|
||||
union {
|
||||
int *ptr_int;
|
||||
float *ptr_float;
|
||||
};
|
||||
} LabelFormatData;
|
||||
|
||||
LabelFormatData *LabelFormatData_new_int (const char *fmt, int *ptr);
|
||||
LabelFormatData *LabelFormatData_new_float (const char *fmt, float *ptr);
|
||||
|
||||
void uicb_label_show_int (Widget *self, void *userdata);
|
||||
void uicb_label_show_float (Widget *self, void *userdata);
|
||||
void uicb_switch_flag (Widget *self, void *userdata);
|
||||
|
||||
Widget *Widget_label_make_int (const char *fmt, int *ptr, TextAlignment alignment);
|
||||
Widget *Widget_label_make_float (const char *fmt, float *ptr, TextAlignment alignment);
|
||||
Widget *Widget_label_make_flag_switch_button (const char *text, char *flag);
|
||||
|
||||
Reference in New Issue
Block a user