UI borders
This commit is contained in:
@@ -3,21 +3,26 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D background_image;
|
||||
uniform bool has_texture;
|
||||
uniform bool has_background_image;
|
||||
uniform vec4 background_color;
|
||||
|
||||
uniform float border_width;
|
||||
uniform vec4 border_color;
|
||||
uniform vec2 widget_size;
|
||||
|
||||
varying vec2 f_uv;
|
||||
|
||||
void main ()
|
||||
{
|
||||
vec4 tex_color = texture2D (background_image, f_uv);
|
||||
vec2 border_uv = vec2 (border_width) / widget_size;
|
||||
|
||||
float x_border = step (f_uv.x, border_uv.x) + step (1.0 - border_uv.x, f_uv.x);
|
||||
float y_border = step (f_uv.y, border_uv.y) + step (1.0 - border_uv.y, f_uv.y);
|
||||
float is_border = clamp (x_border + y_border, 0.0, 1.0);
|
||||
|
||||
if (has_texture)
|
||||
{
|
||||
gl_FragColor = vec4 (background_color.xyz, 1.0) * tex_color;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = background_color;
|
||||
}
|
||||
vec4 bgc = has_background_image
|
||||
? mix (texture2D (background_image, f_uv), background_color, 0.5)
|
||||
: background_color;
|
||||
|
||||
gl_FragColor = mix (bgc, border_color, is_border);
|
||||
}
|
||||
|
||||
@@ -78,6 +78,12 @@ program_create (const char *v_src, const char *f_src)
|
||||
return program;
|
||||
}
|
||||
|
||||
void
|
||||
program_set_vec2 (int program, const char *name, vec2 value)
|
||||
{
|
||||
glUniform2f (glGetUniformLocation (program, name), value[0], value[1]);
|
||||
}
|
||||
|
||||
void
|
||||
program_set_vec3 (int program, const char *name, vec3 value)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ unsigned int program_create (const char *v_src, const char *f_src);
|
||||
void program_set_int (int program, const char *name, int value);
|
||||
void program_set_float (int program, const char *name, float value);
|
||||
void program_set_int_array (int program, const char *name, size_t count, int *value);
|
||||
void program_set_vec2 (int program, const char *name, vec2 value);
|
||||
void program_set_vec3 (int program, const char *name, vec3 value);
|
||||
void program_set_vec3_ind (int program, const char *name, float x, float y, float z);
|
||||
void program_set_vec4 (int program, const char *name, vec4 value);
|
||||
|
||||
+9
-3
@@ -24,9 +24,12 @@ uiman_init ()
|
||||
glm_ortho (0.0, (float) sdl_window_w, (float) sdl_window_h, 0.0, -1.0, 1.0, projection);
|
||||
|
||||
Widget *debug_menu = Widget_container_new (FALSE);
|
||||
Widget_set_background_color (debug_menu, 0, 0, 0, 0.7);
|
||||
Widget_set_position (debug_menu, 32, 32);
|
||||
Widget_set_size (debug_menu, 350, 125);
|
||||
Widget_set_background_image (debug_menu, RESTEX ("terrain1"));
|
||||
VEC4_SETI (debug_menu->background_color, 0, 0, 0, 0.7);
|
||||
VEC2_SETI (debug_menu->position, 32, 32);
|
||||
VEC2_SETI (debug_menu->size, 350, 150);
|
||||
debug_menu->border_width = 2;
|
||||
VEC4_SETI (debug_menu->border_color, 0, 0, 0, 1);
|
||||
Widget_add_child (ui_root, debug_menu);
|
||||
|
||||
Widget_add_child_weighed (debug_menu, Widget_label_make_float ("Frame time: %.3f", &delta_time, TEXT_ALIGN_LEFT), 1);
|
||||
@@ -39,6 +42,9 @@ uiman_init ()
|
||||
Widget_add_child_weighed (poscont, Widget_label_make_float ("Y: %.1f", &camera_position[1], TEXT_ALIGN_CENTER), 1);
|
||||
Widget_add_child_weighed (poscont, Widget_label_make_float ("Z: %.1f", &camera_position[2], TEXT_ALIGN_RIGHT), 1);
|
||||
Widget_add_child_weighed (debug_menu, poscont, 1);
|
||||
|
||||
Widget_add_child_weighed (debug_menu, Widget_label_make_flag_switch_button ("Toggle wireframe", "wireframe_enabled"), 1);
|
||||
Widget_add_child_weighed (debug_menu, Widget_label_make_flag_switch_button ("Toggle flying", "flight_enabled"), 1);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+65
-93
@@ -55,6 +55,13 @@ Widget_add_child_weighed (Widget *parent, Widget *child, float layout_weight)
|
||||
Widget_add_child (parent, child);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_background_image (Widget *widget, unsigned int image)
|
||||
{
|
||||
widget->has_background_image = TRUE;
|
||||
widget->background_image = image;
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_on_tick (Widget *widget,
|
||||
void (*on_tick) (Widget *, void *),
|
||||
@@ -73,43 +80,6 @@ Widget_set_on_left_click (Widget *widget,
|
||||
widget->left_click_data = userdata;
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_position (Widget *widget, float x, float y)
|
||||
{
|
||||
glm_vec2_copy ((vec2) { x, y }, widget->position);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_size (Widget *widget, float x, float y)
|
||||
{
|
||||
glm_vec2_copy ((vec2) { x, y }, widget->size);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_background_image (Widget *widget, unsigned int image)
|
||||
{
|
||||
widget->background_image = image;
|
||||
widget->has_background_image = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_background_color (Widget *widget, float r, float g, float b, float a)
|
||||
{
|
||||
glm_vec4_copy ((vec4) { r, g, b, a }, widget->background_color);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_hovered_bg_color (Widget *widget, float r, float g, float b, float a)
|
||||
{
|
||||
glm_vec4_copy ((vec4) { r, g, b, a }, widget->hovered_bg_color);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_clicked_bg_color (Widget *widget, float r, float g, float b, float a)
|
||||
{
|
||||
glm_vec4_copy ((vec4) { r, g, b, a }, widget->clicked_bg_color);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_label_set_text (Widget *widget, const char *text)
|
||||
{
|
||||
@@ -242,20 +212,19 @@ Widget_container_layout (Widget *parent, gboolean horizontal)
|
||||
{
|
||||
float total_weights = 0.0;
|
||||
float total_fixed = 0.0;
|
||||
|
||||
for (unsigned int i = 0; i < parent->children->len; ++i)
|
||||
{
|
||||
Widget *child = g_array_index (parent->children, Widget *, i);
|
||||
|
||||
if (child->layout_weight == 0.0)
|
||||
{
|
||||
total_fixed += horizontal ? child->size[0] : child->size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
total_weights += child->layout_weight;
|
||||
}
|
||||
}
|
||||
Widget *child;
|
||||
|
||||
WIDGET_FOREACH_CHILD (parent, i, child) {
|
||||
if (child->layout_weight == 0.0)
|
||||
{
|
||||
total_fixed += horizontal ? child->size[0] : child->size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
total_weights += child->layout_weight;
|
||||
}
|
||||
}
|
||||
|
||||
float weights_size = ((horizontal ? parent->size[0] : parent->size[1]) - total_fixed) / total_weights;
|
||||
|
||||
@@ -265,41 +234,39 @@ Widget_container_layout (Widget *parent, gboolean horizontal)
|
||||
}
|
||||
|
||||
float offset = 0.0;
|
||||
for (unsigned int i = 0; i < parent->children->len; ++i)
|
||||
{
|
||||
Widget *child = g_array_index (parent->children, Widget *, i);
|
||||
|
||||
if (child->layout_weight == 0.0)
|
||||
{
|
||||
if (horizontal)
|
||||
{
|
||||
Widget_set_position (child, parent->position[0] + offset, parent->position[1]);
|
||||
child->size[1] = parent->size[1];
|
||||
offset += child->size[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
Widget_set_position (child, parent->position[0], parent->position[1] + offset);
|
||||
child->size[0] = parent->size[0];
|
||||
offset += child->size[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (horizontal)
|
||||
{
|
||||
Widget_set_position (child, parent->position[0] + offset, parent->position[1]);
|
||||
Widget_set_size (child, child->layout_weight * weights_size, parent->size[1]);
|
||||
offset += child->size[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
Widget_set_position (child, parent->position[0], parent->position[1] + offset);
|
||||
Widget_set_size (child, parent->size[0], child->layout_weight * weights_size);
|
||||
offset += child->size[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
WIDGET_FOREACH_CHILD (parent, i, child) {
|
||||
if (child->layout_weight == 0.0)
|
||||
{
|
||||
if (horizontal)
|
||||
{
|
||||
VEC2_SETI (child->position, parent->position[0] + offset, parent->position[1]);
|
||||
child->size[1] = parent->size[1];
|
||||
offset += child->size[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
VEC2_SETI (child->position, parent->position[0], parent->position[1] + offset);
|
||||
child->size[0] = parent->size[0];
|
||||
offset += child->size[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (horizontal)
|
||||
{
|
||||
VEC2_SETI (child->position, parent->position[0] + offset, parent->position[1]);
|
||||
VEC2_SETI (child->size, child->layout_weight * weights_size, parent->size[1]);
|
||||
offset += child->size[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
VEC2_SETI (child->position, parent->position[0], parent->position[1] + offset);
|
||||
VEC2_SETI (child->size, parent->size[0], child->layout_weight * weights_size);
|
||||
offset += child->size[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -327,6 +294,10 @@ Widget_render (Widget *widget, mat4 projection, int window_height)
|
||||
|
||||
program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->background_color);
|
||||
|
||||
program_set_float (RESPRG ("uiwidget"), "border_width", widget->border_width);
|
||||
program_set_vec4 (RESPRG ("uiwidget"), "border_color", widget->border_color);
|
||||
program_set_vec2 (RESPRG ("uiwidget"), "widget_size", widget->size);
|
||||
|
||||
if (widget->clicked)
|
||||
{
|
||||
program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->clicked_bg_color);
|
||||
@@ -358,12 +329,11 @@ Widget_render (Widget *widget, mat4 projection, int window_height)
|
||||
{
|
||||
Widget_label_render_text (widget, projection);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < widget->children->len; ++i)
|
||||
{
|
||||
Widget *child = g_array_index (widget->children, Widget *, i);
|
||||
Widget_render (child, projection, window_height);
|
||||
}
|
||||
|
||||
Widget *child;
|
||||
WIDGET_FOREACH_CHILD (widget, i, child) {
|
||||
Widget_render (child, projection, window_height);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------- */
|
||||
@@ -428,9 +398,11 @@ Widget *
|
||||
Widget_label_make_flag_switch_button (const char *text, char *flag)
|
||||
{
|
||||
Widget *w = Widget_label_new (text, TEXT_ALIGN_CENTER);
|
||||
Widget_set_background_color (w, 1, 1, 1, 0.1);
|
||||
Widget_set_hovered_bg_color (w, 1, 1, 1, 0.2);
|
||||
Widget_set_clicked_bg_color (w, 1, 1, 1, 0.3);
|
||||
VEC4_SETI (w->background_color, 1, 1, 1, 0.1);
|
||||
VEC4_SETI (w->hovered_bg_color, 1, 1, 1, 0.2);
|
||||
VEC4_SETI (w->clicked_bg_color, 1, 1, 1, 0.3);
|
||||
w->border_width = 2;
|
||||
VEC4_SETI (w->border_color, 1, 1, 1, 0.5);
|
||||
Widget_set_on_left_click (w, uicb_switch_flag, flag);
|
||||
return w;
|
||||
}
|
||||
|
||||
@@ -9,12 +9,15 @@
|
||||
#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_CONTAINER,
|
||||
WIDGET_LABEL,
|
||||
WIDGET_CHECKBOX
|
||||
WIDGET_LABEL
|
||||
} WidgetKind;
|
||||
|
||||
typedef struct ContainerWidget
|
||||
@@ -62,6 +65,9 @@ typedef struct Widget
|
||||
gboolean has_background_image;
|
||||
unsigned int background_image;
|
||||
|
||||
unsigned int border_width;
|
||||
vec4 border_color;
|
||||
|
||||
void (*on_left_click) (struct Widget *, void *);
|
||||
void *left_click_data;
|
||||
void (*on_right_click) (struct Widget *, void *);
|
||||
@@ -78,16 +84,10 @@ void Widget_add_child (Widget *parent, Widget *child);
|
||||
void Widget_add_child_weighed (Widget *parent, Widget *child,
|
||||
float layout_weight);
|
||||
|
||||
void Widget_set_background_image (Widget *widget, unsigned int image);
|
||||
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_background_image (Widget *widget, unsigned int image);
|
||||
void Widget_set_background_color (Widget *widget, float r, float g, float b, float a);
|
||||
void Widget_set_hovered_bg_color (Widget *widget, float r, float g, float b, float a);
|
||||
void Widget_set_clicked_bg_color (Widget *widget, float r, float g, float b, float a);
|
||||
|
||||
void Widget_label_set_text (Widget *widget, const char *text);
|
||||
void Widget_label_printf (Widget *widget, const char *format, ...);
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#define UNUSED_2(arg, ...) (void) arg, UNUSED_3 (__VA_ARGS__, 0)
|
||||
#define UNUSED_3(arg, ...) (void) arg
|
||||
|
||||
#define VEC2_SETI(v, x, y) glm_vec2_copy((vec2) { x, y }, v)
|
||||
#define VEC4_SETI(v, r, g, b, a) glm_vec4_copy((vec4) { r, g, b, a }, v)
|
||||
|
||||
/*
|
||||
|
||||
GLib log levels:
|
||||
|
||||
Reference in New Issue
Block a user