Scrollbar improvements
This commit is contained in:
@@ -11,6 +11,10 @@ uniform vec2 widget_size;
|
||||
|
||||
uniform bool has_icon;
|
||||
|
||||
uniform bool has_scrollbar;
|
||||
uniform vec2 scrollbar_position;
|
||||
uniform vec2 scrollbar_size;
|
||||
|
||||
uniform sampler2D background_image;
|
||||
uniform sampler2D icons;
|
||||
|
||||
@@ -28,9 +32,23 @@ void main ()
|
||||
vec4 bgc = has_background_image ? texture2D (background_image, f_uv) : background_color;
|
||||
vec4 base_color = mix (bgc, border_color, is_border);
|
||||
|
||||
if (is_border > 0.5) {
|
||||
gl_FragColor = base_color;
|
||||
return;
|
||||
if (is_border > 0.5)
|
||||
{
|
||||
gl_FragColor = base_color;
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_scrollbar) {
|
||||
bool in_scrollbar =
|
||||
f_uv.x >= scrollbar_position.x &&
|
||||
f_uv.x <= (scrollbar_position.x + scrollbar_size.x) &&
|
||||
f_uv.y >= scrollbar_position.y &&
|
||||
f_uv.y <= (scrollbar_position.y + scrollbar_size.y);
|
||||
|
||||
if (in_scrollbar) {
|
||||
gl_FragColor = vec4 (1, 1, 1, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_icon)
|
||||
@@ -39,6 +57,6 @@ void main ()
|
||||
gl_FragColor = mix (base_color, fg, fg.a);
|
||||
base_color = mix (base_color, fg, fg.a);
|
||||
}
|
||||
|
||||
|
||||
gl_FragColor = base_color;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ void
|
||||
main ()
|
||||
{
|
||||
float tex_w = 40.0;
|
||||
float tex_h = 40.0;
|
||||
float tex_h = 80.0;
|
||||
|
||||
float icon_w = 20.0;
|
||||
float icon_h = 20.0;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 337 B After Width: | Height: | Size: 533 B |
Binary file not shown.
+16
-16
@@ -146,23 +146,23 @@ resources_init ()
|
||||
#define RAT resources_add_texture
|
||||
#define RLT resources_load_texture
|
||||
|
||||
RAP ("default", RLP ("res/shaders/default.vert", "res/shaders/default.frag"));
|
||||
RAP ("chunk", RLP ("res/shaders/chunk.vert", "res/shaders/chunk.frag"));
|
||||
RAP ("clouds", RLP ("res/shaders/clouds.vert", "res/shaders/clouds.frag"));
|
||||
RAP ("uiwidget", RLP ("res/shaders/uiwidget.vert", "res/shaders/uiwidget.frag"));
|
||||
RAP ("uitext", RLP ("res/shaders/uitext.vert", "res/shaders/uitext.frag"));
|
||||
RAP ("default", RLP ("res/shaders/default.vert", "res/shaders/default.frag"));
|
||||
RAP ("chunk", RLP ("res/shaders/chunk.vert", "res/shaders/chunk.frag"));
|
||||
RAP ("clouds", RLP ("res/shaders/clouds.vert", "res/shaders/clouds.frag"));
|
||||
RAP ("uiwidget", RLP ("res/shaders/uiwidget.vert", "res/shaders/uiwidget.frag"));
|
||||
RAP ("uitext", RLP ("res/shaders/uitext.vert", "res/shaders/uitext.frag"));
|
||||
|
||||
RAT ("terrain0", RLT ("res/textures/dirt.png"));
|
||||
RAT ("terrain1", RLT ("res/textures/drygrass.png"));
|
||||
RAT ("terrain2", RLT ("res/textures/grass.png"));
|
||||
RAT ("terrain3", RLT ("res/textures/rock_cement.png"));
|
||||
RAT ("terrain4", RLT ("res/textures/asphalt_gravel.png"));
|
||||
RAT ("tree0", RLT ("res/textures/tree.png"));
|
||||
RAT ("grass0", RLT ("res/textures/grass0.png"));
|
||||
RAT ("clouds", RLT ("res/textures/clouds.png"));
|
||||
|
||||
RAT ("font0", RLT ("res/textures/font_9x20.png"));
|
||||
RAT ("icons", RLT ("res/textures/icons.png"));
|
||||
RAT ("terrain0", RLT ("res/textures/dirt.png"));
|
||||
RAT ("terrain1", RLT ("res/textures/drygrass.png"));
|
||||
RAT ("terrain2", RLT ("res/textures/grass.png"));
|
||||
RAT ("terrain3", RLT ("res/textures/rock_cement.png"));
|
||||
RAT ("terrain4", RLT ("res/textures/asphalt_gravel.png"));
|
||||
RAT ("tree0", RLT ("res/textures/tree.png"));
|
||||
RAT ("grass0", RLT ("res/textures/grass0.png"));
|
||||
RAT ("clouds", RLT ("res/textures/clouds.png"));
|
||||
|
||||
RAT ("font0", RLT ("res/textures/font_9x20.png"));
|
||||
RAT ("icons", RLT ("res/textures/icons.png"));
|
||||
|
||||
#undef RAP
|
||||
#undef RLP
|
||||
|
||||
+3
-2
@@ -49,8 +49,9 @@ uiman_init ()
|
||||
Widget_add_child_weighed (chkboxes, Widget_composite_checkbox_make ("Flight", "flight_enabled"), 1);
|
||||
Widget_add_child_weighed (debug_menu, chkboxes, 1);
|
||||
|
||||
Widget *content = Widget_label_new ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", TEXT_ALIGN_LEFT);
|
||||
VEC2_SETI (content->size, 3000, 500);
|
||||
Widget *content = Widget_plain_new ();
|
||||
Widget_set_background_image (content, RESTEX ("terrain1"));
|
||||
VEC2_SETI (content->size, 400, 600);
|
||||
|
||||
Widget *scrollable_window = Widget_composite_scrollable_make (content);
|
||||
Widget_set_background_image (scrollable_window, RESTEX ("terrain4"));
|
||||
|
||||
+59
-19
@@ -45,7 +45,16 @@ Widget *
|
||||
Widget_scrollable_new ()
|
||||
{
|
||||
Widget *e = ui_el_new_internal (WIDGET_SCROLLABLE);
|
||||
e->scrollable.scroll_amount = 5.0;
|
||||
e->scrollable.scroll_amount = 10.0;
|
||||
return e;
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_scrollbar_new (Widget *scrollable, gboolean horizontal)
|
||||
{
|
||||
Widget *e = ui_el_new_internal (WIDGET_SCROLLBAR);
|
||||
e->scrollbar.scrollable = scrollable;
|
||||
e->scrollbar.horizontal = horizontal;
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -252,17 +261,20 @@ Widget_scrollable_layout (Widget *parent)
|
||||
|
||||
WIDGET_FOREACH_CHILD (parent, i, child)
|
||||
{
|
||||
child->position[0] = parent->position[0] - parent->scrollable.scroll_position[0];
|
||||
child->position[1] = parent->position[1] - parent->scrollable.scroll_position[1];
|
||||
float logical_x = 0.0f;
|
||||
float logical_y = 0.0f;
|
||||
|
||||
child->position[0] = parent->position[0] + logical_x - parent->scrollable.scroll_position[0];
|
||||
child->position[1] = parent->position[1] + logical_y - parent->scrollable.scroll_position[1];
|
||||
|
||||
if (child->layout_weight > 0.0)
|
||||
{
|
||||
child->size[0] = child->layout_weight * parent->size[0];
|
||||
child->size[1] = child->layout_weight * parent->size[1];
|
||||
}
|
||||
|
||||
float right = child->position[0] + child->size[0];
|
||||
float bottom = child->position[1] + child->size[1];
|
||||
|
||||
float right = logical_x + child->size[0];
|
||||
float bottom = logical_y + child->size[1];
|
||||
|
||||
if (right > content_size[0])
|
||||
{
|
||||
@@ -415,6 +427,33 @@ Widget_render (Widget *widget, mat4 projection, int window_height)
|
||||
program_set_int (RESPRG ("uiwidget"), "has_icon", widget->has_icon);
|
||||
program_set_float (RESPRG ("uiwidget"), "icon_index", widget->icon);
|
||||
texture_use (RESTEX ("icons"), 1);
|
||||
|
||||
if (widget->kind == WIDGET_SCROLLBAR)
|
||||
{
|
||||
program_set_int (RESPRG ("uiwidget"), "has_scrollbar", TRUE);
|
||||
/* Calculate the scrollbar size. */
|
||||
unsigned int idx = widget->scrollbar.horizontal ? 0 : 1;
|
||||
|
||||
Widget *scr = widget->scrollbar.scrollable;
|
||||
|
||||
float content_size = scr->scrollable.content_size[idx];
|
||||
float scroll_pos = scr->scrollable.scroll_position[idx];
|
||||
float view_size = scr->size[idx];
|
||||
float thumb_size_norm = view_size / content_size;
|
||||
float thumb_pos_norm = scroll_pos / content_size;
|
||||
|
||||
program_set_vec2 (RESPRG ("uiwidget"), "scrollbar_position", widget->scrollbar.horizontal
|
||||
? (vec2) { thumb_pos_norm, 0.0f }
|
||||
: (vec2) { 0.0f, thumb_pos_norm });
|
||||
|
||||
program_set_vec2 (RESPRG ("uiwidget"), "scrollbar_size", widget->scrollbar.horizontal
|
||||
? (vec2) { thumb_size_norm, 1.0f }
|
||||
: (vec2) { 1.0f, thumb_size_norm });
|
||||
}
|
||||
else
|
||||
{
|
||||
program_set_int (RESPRG ("uiwidget"), "has_scrollbar", FALSE);
|
||||
}
|
||||
|
||||
mat3 model;
|
||||
glm_translate2d_make (model, widget->position);
|
||||
@@ -445,10 +484,10 @@ Widget_render (Widget *widget, mat4 projection, int window_height)
|
||||
vec2 clipped_aabb[2];
|
||||
glm_aabb2d_crop (widget_aabb, parent_aabb, clipped_aabb);
|
||||
|
||||
int x = floor (clipped_aabb[0][0]);
|
||||
int y = floor (window_height - clipped_aabb[1][1]);
|
||||
int w = ceil (clipped_aabb[1][0] - clipped_aabb[0][0]);
|
||||
int h = ceil (clipped_aabb[1][1] - clipped_aabb[0][1]);
|
||||
int x = roundf (clipped_aabb[0][0]);
|
||||
int y = roundf (window_height - clipped_aabb[1][1]);
|
||||
int w = roundf (clipped_aabb[1][0] - clipped_aabb[0][0]);
|
||||
int h = roundf (clipped_aabb[1][1] - clipped_aabb[0][1]);
|
||||
|
||||
/* X, Y is the lower left corner of the box. */
|
||||
glScissor (x, y, w, h);
|
||||
@@ -461,9 +500,10 @@ Widget_render (Widget *widget, mat4 projection, int window_height)
|
||||
}
|
||||
|
||||
Widget *child;
|
||||
WIDGET_FOREACH_CHILD (widget, i, child) {
|
||||
Widget_render (child, projection, window_height);
|
||||
}
|
||||
WIDGET_FOREACH_CHILD (widget, i, child)
|
||||
{
|
||||
Widget_render (child, projection, window_height);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------- */
|
||||
@@ -630,11 +670,11 @@ Widget_composite_scrollable_make (Widget *content)
|
||||
Widget *scroll_up = Widget_plain_new ();
|
||||
Widget *scroll_down = Widget_plain_new ();
|
||||
|
||||
Widget_set_icon (scroll_up, ICON_SPINNER_LEFT);
|
||||
Widget_set_icon (scroll_up, ICON_ARROW_UP);
|
||||
Widget_set_on_left_click (scroll_up, uicb_scrollable_scroll_up, scrollable);
|
||||
scroll_up->aspect_ratio = 1.0;
|
||||
|
||||
Widget_set_icon (scroll_down, ICON_SPINNER_RIGHT);
|
||||
Widget_set_icon (scroll_down, ICON_ARROW_DOWN);
|
||||
Widget_set_on_left_click (scroll_down, uicb_scrollable_scroll_down, scrollable);
|
||||
scroll_down->aspect_ratio = 1.0;
|
||||
|
||||
@@ -642,7 +682,7 @@ Widget_composite_scrollable_make (Widget *content)
|
||||
Widget *scrollbar_vertical = Widget_container_new (FALSE, 0, 0);
|
||||
|
||||
Widget_add_child_weighed (scrollbar_vertical, scroll_up, 1);
|
||||
Widget_add_child_weighed (scrollbar_vertical, Widget_plain_new (), 1);
|
||||
Widget_add_child_weighed (scrollbar_vertical, Widget_scrollbar_new (scrollable, FALSE), 1);
|
||||
Widget_add_child_weighed (scrollbar_vertical, scroll_down, 1);
|
||||
|
||||
Widget_add_child_weighed (cont_horiz, scrollable, 0.93);
|
||||
@@ -653,11 +693,11 @@ Widget_composite_scrollable_make (Widget *content)
|
||||
Widget *scroll_left = Widget_plain_new ();
|
||||
Widget *scroll_right = Widget_plain_new ();
|
||||
|
||||
Widget_set_icon (scroll_left, ICON_SPINNER_LEFT);
|
||||
Widget_set_icon (scroll_left, ICON_ARROW_LEFT);
|
||||
Widget_set_on_left_click (scroll_left, uicb_scrollable_scroll_left, scrollable);
|
||||
scroll_left->aspect_ratio = 1.0;
|
||||
|
||||
Widget_set_icon (scroll_right, ICON_SPINNER_RIGHT);
|
||||
Widget_set_icon (scroll_right, ICON_ARROW_RIGHT);
|
||||
Widget_set_on_left_click (scroll_right, uicb_scrollable_scroll_right, scrollable);
|
||||
scroll_right->aspect_ratio = 1.0;
|
||||
|
||||
@@ -667,7 +707,7 @@ Widget_composite_scrollable_make (Widget *content)
|
||||
padding->aspect_ratio = 1.0;
|
||||
|
||||
Widget_add_child_weighed (scrollbar_horizontal, scroll_left, 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, Widget_plain_new (), 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, Widget_scrollbar_new (scrollable, TRUE), 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, scroll_right, 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, padding, 1);
|
||||
|
||||
|
||||
+22
-10
@@ -13,16 +13,27 @@
|
||||
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_SCROLLABLE
|
||||
WIDGET_SCROLLABLE,
|
||||
WIDGET_SCROLLBAR
|
||||
} WidgetKind;
|
||||
|
||||
typedef enum WidgetIcon
|
||||
{
|
||||
ICON_CHECKBOX_UNCHECKED = 0,
|
||||
ICON_CHECKBOX_CHECKED,
|
||||
ICON_SPINNER_LEFT,
|
||||
ICON_SPINNER_RIGHT,
|
||||
ICON_ARROW_LEFT,
|
||||
ICON_ARROW_RIGHT,
|
||||
ICON_ARROW_UP,
|
||||
ICON_ARROW_DOWN
|
||||
} WidgetIcon;
|
||||
|
||||
typedef struct ContainerWidget
|
||||
{
|
||||
gboolean horizontal;
|
||||
@@ -51,13 +62,12 @@ typedef struct ScrollableWidget
|
||||
vec2 content_size;
|
||||
} ScrollableWidget;
|
||||
|
||||
typedef enum WidgetIcon
|
||||
{
|
||||
ICON_CHECKBOX_UNCHECKED = 0,
|
||||
ICON_CHECKBOX_CHECKED,
|
||||
ICON_SPINNER_LEFT,
|
||||
ICON_SPINNER_RIGHT
|
||||
} WidgetIcon;
|
||||
typedef struct ScrollbarWidget
|
||||
{
|
||||
struct Widget *scrollable;
|
||||
gboolean horizontal;
|
||||
float bar_size;
|
||||
} ScrollbarWidget;
|
||||
|
||||
typedef struct Widget
|
||||
{
|
||||
@@ -69,6 +79,7 @@ typedef struct Widget
|
||||
ContainerWidget container;
|
||||
LabelWidget label;
|
||||
ScrollableWidget scrollable;
|
||||
ScrollbarWidget scrollbar;
|
||||
};
|
||||
|
||||
gboolean visible;
|
||||
@@ -104,6 +115,7 @@ Widget *Widget_plain_new ();
|
||||
Widget *Widget_container_new (gboolean horizontal, float padding, float child_spacing);
|
||||
Widget *Widget_label_new (const char *text, TextAlignment alignment);
|
||||
Widget *Widget_scrollable_new ();
|
||||
Widget *Widget_scrollbar_new (Widget *scrollable, gboolean horizontal);
|
||||
|
||||
void Widget_add_child (Widget *parent, Widget *child);
|
||||
void Widget_add_child_weighed (Widget *parent, Widget *child,
|
||||
|
||||
Reference in New Issue
Block a user