Working scrollbars
This commit is contained in:
+71
-48
@@ -14,7 +14,7 @@ extern vec3 camera_position;
|
||||
static Widget *ui_root;
|
||||
static mat4 projection;
|
||||
|
||||
static Widget *hovered_widget, *clicked_widget;
|
||||
static Widget *hovered_widget = NULL;
|
||||
|
||||
void
|
||||
uiman_init ()
|
||||
@@ -25,7 +25,7 @@ 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, 8, 4);
|
||||
Widget_set_background_image (debug_menu, RESTEX ("terrain4"));
|
||||
debug_menu->background_image = RESTEX ("terrain4");
|
||||
VEC2_SETI (debug_menu->position, 32, 32);
|
||||
VEC2_SETI (debug_menu->size, 350, 170);
|
||||
debug_menu->border_width = 4;
|
||||
@@ -50,11 +50,11 @@ uiman_init ()
|
||||
Widget_add_child_weighed (debug_menu, chkboxes, 1);
|
||||
|
||||
Widget *content = Widget_plain_new ();
|
||||
Widget_set_background_image (content, RESTEX ("terrain1"));
|
||||
content->background_image = RESTEX ("terrain1");
|
||||
VEC2_SETI (content->size, 400, 600);
|
||||
|
||||
Widget *scrollable_window = Widget_composite_scrollable_make (content);
|
||||
Widget_set_background_image (scrollable_window, RESTEX ("terrain4"));
|
||||
scrollable_window->background_image = RESTEX ("terrain4");
|
||||
VEC2_SETI (scrollable_window->position, 390, 32);
|
||||
VEC2_SETI (scrollable_window->size, 350, 350);
|
||||
scrollable_window->border_width = 4;
|
||||
@@ -109,23 +109,28 @@ uiman_cb_key_up (SDL_Event *event, void *data)
|
||||
gboolean
|
||||
uiman_cb_mouse_motion (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (data);
|
||||
UNUSED (event, data);
|
||||
|
||||
Widget *new_hover = Widget_find_xy (ui_root, (vec2) { event->motion.x, event->motion.y });
|
||||
Widget *widget = Widget_find_xy (ui_root, (vec2) { event->motion.x, event->motion.y });
|
||||
|
||||
if (new_hover != hovered_widget)
|
||||
if (widget != hovered_widget)
|
||||
{
|
||||
if (hovered_widget)
|
||||
if (hovered_widget && hovered_widget->on_mouse_leave)
|
||||
{
|
||||
hovered_widget->hovered = FALSE;
|
||||
hovered_widget->on_mouse_leave (hovered_widget, hovered_widget->mouse_leave_data);
|
||||
}
|
||||
|
||||
if (new_hover)
|
||||
if (widget && widget->on_mouse_enter)
|
||||
{
|
||||
new_hover->hovered = TRUE;
|
||||
widget->on_mouse_enter (widget, widget->mouse_enter_data);
|
||||
}
|
||||
|
||||
hovered_widget = new_hover;
|
||||
hovered_widget = widget;
|
||||
}
|
||||
|
||||
if (hovered_widget && hovered_widget->on_mouse_move)
|
||||
{
|
||||
hovered_widget->on_mouse_move (hovered_widget, hovered_widget->mouse_move_data);
|
||||
}
|
||||
|
||||
/* This callback always eats the event, because why would the game
|
||||
@@ -133,55 +138,25 @@ uiman_cb_mouse_motion (SDL_Event *event, void *data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean widget_match_bdown (Widget *self) { return self->on_left_down || self->on_right_down; };
|
||||
gboolean
|
||||
uiman_cb_button_down (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (data);
|
||||
|
||||
Widget *new_clicked = Widget_find_xy (ui_root, (vec2) { event->motion.x, event->motion.y });
|
||||
|
||||
if (new_clicked != clicked_widget)
|
||||
{
|
||||
if (clicked_widget && (clicked_widget->on_left_click || clicked_widget->on_right_click))
|
||||
{
|
||||
clicked_widget->clicked = FALSE;
|
||||
}
|
||||
Widget *widget = Widget_find_xy_matching (ui_root, (vec2) { event->button.x, event->button.y }, widget_match_bdown);
|
||||
|
||||
if (new_clicked && (new_clicked->on_left_click || new_clicked->on_right_click))
|
||||
{
|
||||
new_clicked->clicked = TRUE;
|
||||
}
|
||||
|
||||
clicked_widget = new_clicked;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
uiman_cb_button_up (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (data);
|
||||
|
||||
Widget *widget = Widget_find_xy (ui_root, (vec2) { event->motion.x, event->motion.y });
|
||||
|
||||
if (clicked_widget)
|
||||
{
|
||||
clicked_widget->clicked = FALSE;
|
||||
clicked_widget = NULL;
|
||||
}
|
||||
|
||||
if (widget)
|
||||
{
|
||||
if (event->button.button == SDL_BUTTON_LEFT && widget->on_left_click)
|
||||
if (event->button.button == SDL_BUTTON_LEFT && widget->on_left_down)
|
||||
{
|
||||
widget->on_left_click (widget, widget->left_click_data);
|
||||
widget->on_left_down (widget, widget->left_down_data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (event->button.button == SDL_BUTTON_RIGHT && widget->on_right_click)
|
||||
if (event->button.button == SDL_BUTTON_RIGHT && widget->on_right_down)
|
||||
{
|
||||
widget->on_right_click (widget, widget->right_click_data);
|
||||
widget->on_right_down (widget, widget->right_down_data);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -189,10 +164,58 @@ uiman_cb_button_up (SDL_Event *event, void *data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean widget_match_bup (Widget *self) { return self->on_left_up || self->on_right_up; };
|
||||
gboolean
|
||||
uiman_cb_button_up (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (data);
|
||||
|
||||
Widget *widget = Widget_find_xy_matching (ui_root, (vec2) { event->button.x, event->button.y }, widget_match_bup);
|
||||
|
||||
if (widget)
|
||||
{
|
||||
if (event->button.button == SDL_BUTTON_LEFT && widget->on_left_up)
|
||||
{
|
||||
widget->on_left_up (widget, widget->left_up_data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (event->button.button == SDL_BUTTON_RIGHT && widget->on_right_up)
|
||||
{
|
||||
widget->on_right_up (widget, widget->right_up_data);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean widget_match_scroll (Widget *self) { return self->on_scroll_down || self->on_scroll_up; };
|
||||
gboolean
|
||||
uiman_cb_mouse_wheel (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
|
||||
Widget *widget = Widget_find_xy_matching (ui_root, (vec2) { event->wheel.mouse_x, event->wheel.mouse_y }, widget_match_scroll);
|
||||
|
||||
if (widget)
|
||||
{
|
||||
if (event->wheel.y > 0)
|
||||
{
|
||||
if (widget->on_scroll_up)
|
||||
{
|
||||
widget->on_scroll_up (widget, widget->scroll_up_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (widget->on_scroll_down)
|
||||
{
|
||||
widget->on_scroll_down (widget, widget->scroll_down_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
+132
-54
@@ -11,6 +11,7 @@ ui_el_new_internal (WidgetKind kind)
|
||||
e->kind = kind;
|
||||
e->visible = true;
|
||||
e->children = g_array_new (false, false, sizeof (Widget *));
|
||||
e->icon = ICON_NONE;
|
||||
glm_vec4_zero (e->background_color);
|
||||
return e;
|
||||
}
|
||||
@@ -78,20 +79,6 @@ Widget_add_child_weighed (Widget *parent, Widget *child, float layout_weight)
|
||||
Widget_add_child (parent, child);
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_icon (Widget *widget, WidgetIcon icon)
|
||||
{
|
||||
widget->has_icon = TRUE;
|
||||
widget->icon = icon;
|
||||
}
|
||||
|
||||
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 *),
|
||||
@@ -102,12 +89,12 @@ Widget_set_on_tick (Widget *widget,
|
||||
}
|
||||
|
||||
void
|
||||
Widget_set_on_left_click (Widget *widget,
|
||||
void (*on_left_click) (Widget *, void *),
|
||||
void *userdata)
|
||||
Widget_set_on_left_up (Widget *widget,
|
||||
void (*on_left_up) (Widget *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
widget->on_left_click = on_left_click;
|
||||
widget->left_click_data = userdata;
|
||||
widget->on_left_up = on_left_up;
|
||||
widget->left_up_data = userdata;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -153,13 +140,18 @@ Widget_hit_test (Widget *widget, vec2 point)
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_find_xy (Widget *widget, vec2 pos)
|
||||
Widget_find_xy_matching (Widget *widget, vec2 pos, gboolean (*match_fn) (Widget *widget))
|
||||
{
|
||||
if (!widget->visible)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!Widget_hit_test (widget, pos))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vec2 pos_scrolled;
|
||||
glm_vec2_copy (pos, pos_scrolled);
|
||||
|
||||
@@ -168,15 +160,10 @@ Widget_find_xy (Widget *widget, vec2 pos)
|
||||
glm_vec2_add (pos_scrolled, widget->scrollable.scroll_position, pos_scrolled);
|
||||
}
|
||||
|
||||
if (!Widget_hit_test (widget, pos_scrolled))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = widget->children->len - 1; i >= 0; --i)
|
||||
{
|
||||
Widget *child = g_array_index (widget->children, Widget *, i);
|
||||
Widget *found = Widget_find_xy (child, pos_scrolled);
|
||||
Widget *found = Widget_find_xy_matching (child, pos_scrolled, match_fn);
|
||||
|
||||
if (found != NULL)
|
||||
{
|
||||
@@ -184,7 +171,18 @@ Widget_find_xy (Widget *widget, vec2 pos)
|
||||
}
|
||||
}
|
||||
|
||||
return widget;
|
||||
if (!match_fn || match_fn (widget))
|
||||
{
|
||||
return widget;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_find_xy (Widget *widget, vec2 pos)
|
||||
{
|
||||
return Widget_find_xy_matching (widget, pos, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -410,21 +408,12 @@ Widget_render (Widget *widget, mat4 projection, int window_height)
|
||||
program_set_vec4 (RESPRG ("uiwidget"), "border_color", widget->border_color);
|
||||
program_set_vec2 (RESPRG ("uiwidget"), "widget_size", widget->size);
|
||||
|
||||
program_set_int (RESPRG ("uiwidget"), "has_background_image", widget->has_background_image);
|
||||
program_set_int (RESPRG ("uiwidget"), "has_background_image", widget->background_image != 0);
|
||||
texture_use (widget->background_image, 0); /* If it doesn't have a texture, it'll be 0 anyway. */
|
||||
|
||||
program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->background_color);
|
||||
|
||||
if (widget->clicked)
|
||||
{
|
||||
program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->clicked_bg_color);
|
||||
}
|
||||
else if (widget->hovered)
|
||||
{
|
||||
program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->hovered_bg_color);
|
||||
}
|
||||
|
||||
program_set_int (RESPRG ("uiwidget"), "has_icon", widget->has_icon);
|
||||
program_set_int (RESPRG ("uiwidget"), "has_icon", widget->icon != -1);
|
||||
program_set_float (RESPRG ("uiwidget"), "icon_index", widget->icon);
|
||||
texture_use (RESTEX ("icons"), 1);
|
||||
|
||||
@@ -603,6 +592,78 @@ uicb_scrollable_scroll_right (Widget *self, void *userdata)
|
||||
Widget_scrollable_scroll (scrollable, (vec2) { 1.0, 0.0 });
|
||||
}
|
||||
|
||||
void
|
||||
uicb_scrollbar_start_scroll (Widget *self, void *userdata)
|
||||
{
|
||||
UNUSED (userdata);
|
||||
|
||||
Widget *scr = self->scrollbar.scrollable;
|
||||
vec2 mouse_pos;
|
||||
SDL_GetMouseState ((float*)&mouse_pos[0], (float*)&mouse_pos[1]);
|
||||
|
||||
unsigned int idx = self->scrollbar.horizontal ? 0 : 1;
|
||||
|
||||
float content_size = scr->scrollable.content_size[idx];
|
||||
float view_size = scr->size[idx];
|
||||
float track_pixels = self->size[idx];
|
||||
|
||||
float thumb_size_norm = view_size / content_size;
|
||||
float thumb_pixels = thumb_size_norm * track_pixels;
|
||||
|
||||
float max_scroll = content_size - view_size;
|
||||
float thumb_pos_norm = max_scroll > 0.0f
|
||||
? scr->scrollable.scroll_position[idx] / max_scroll
|
||||
: 0.0f;
|
||||
|
||||
float thumb_start_px = thumb_pos_norm * (track_pixels - thumb_pixels);
|
||||
|
||||
float click_axis = self->scrollbar.horizontal ? mouse_pos[0] : mouse_pos[1];
|
||||
float track_start = self->scrollbar.horizontal
|
||||
? self->position[0]
|
||||
: self->position[1];
|
||||
|
||||
self->scrollbar.drag_offset = click_axis - track_start - thumb_start_px;
|
||||
self->scrollbar.dragging = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
uicb_scrollbar_scroll (Widget *self, void *userdata)
|
||||
{
|
||||
UNUSED (userdata);
|
||||
|
||||
if (self->scrollbar.dragging == FALSE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget *scr = self->scrollbar.scrollable;
|
||||
vec2 mouse_pos;
|
||||
SDL_GetMouseState((float*) &mouse_pos[0], (float*) &mouse_pos[1]);
|
||||
|
||||
unsigned int idx = self->scrollbar.horizontal ? 0 : 1;
|
||||
float content_size = scr->scrollable.content_size[idx];
|
||||
float view_size = scr->size[idx];
|
||||
float track_pixels = self->size[idx];
|
||||
|
||||
float click_axis = self->scrollbar.horizontal ? mouse_pos[0] : mouse_pos[1];
|
||||
float track_start = self->scrollbar.horizontal ? self->position[0] : self->position[1];
|
||||
|
||||
float t = (click_axis - track_start - self->scrollbar.drag_offset)
|
||||
/ track_pixels;
|
||||
t = glm_clamp (t, 0.0f, 1.0f);
|
||||
|
||||
float max_scroll = content_size - view_size;
|
||||
scr->scrollable.scroll_position[idx] =
|
||||
glm_clamp (t * content_size, 0.0f, max_scroll > 0.0f ? max_scroll : 0.0f);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_scrollbar_stop_scroll (Widget *self, void *userdata)
|
||||
{
|
||||
UNUSED (userdata);
|
||||
self->scrollbar.dragging = FALSE;
|
||||
}
|
||||
|
||||
Widget *
|
||||
Widget_label_make_int (const char *fmt, int *ptr, TextAlignment alignment)
|
||||
{
|
||||
@@ -627,11 +688,11 @@ Widget_composite_spinner_make_int (const char *fmt, int *ptr)
|
||||
Widget *label = Widget_label_make_int (fmt, ptr, TEXT_ALIGN_CENTER);
|
||||
Widget *right = Widget_plain_new ();
|
||||
|
||||
Widget_set_on_left_click (left, uicb_decrement_int, ptr);
|
||||
Widget_set_icon (left, ICON_SPINNER_LEFT);
|
||||
Widget_set_on_left_up (left, uicb_decrement_int, ptr);
|
||||
left->icon = ICON_SPINNER_LEFT;
|
||||
left->aspect_ratio = 1.0;
|
||||
Widget_set_on_left_click (right, uicb_increment_int, ptr);
|
||||
Widget_set_icon (right, ICON_SPINNER_RIGHT);
|
||||
Widget_set_on_left_up (right, uicb_increment_int, ptr);
|
||||
right->icon = ICON_SPINNER_RIGHT;
|
||||
right->aspect_ratio = 1.0;
|
||||
|
||||
Widget_add_child_weighed (cont, left, 1);
|
||||
@@ -649,10 +710,10 @@ Widget_composite_checkbox_make (const char *label, char *flag)
|
||||
Widget *cont = Widget_container_new (TRUE, 0, 8);
|
||||
Widget *box = Widget_plain_new ();
|
||||
|
||||
Widget_set_icon (box, ICON_CHECKBOX_UNCHECKED);
|
||||
box->icon = ICON_CHECKBOX_UNCHECKED;
|
||||
box->aspect_ratio = 1.0;
|
||||
Widget_set_on_tick (box, uicb_checkbox_show_flag, flag);
|
||||
Widget_set_on_left_click (box, uicb_switch_flag, flag);
|
||||
Widget_set_on_left_up (box, uicb_switch_flag, flag);
|
||||
|
||||
Widget_add_child_weighed (cont, box, 1);
|
||||
Widget_add_child_weighed (cont, Widget_label_new (label, TEXT_ALIGN_LEFT), 1);
|
||||
@@ -666,23 +727,34 @@ Widget_composite_scrollable_make (Widget *content)
|
||||
Widget *cont_main = Widget_container_new (FALSE, 8, 4);
|
||||
Widget *scrollable = Widget_scrollable_new ();
|
||||
Widget_add_child (scrollable, content);
|
||||
|
||||
scrollable->on_scroll_down = uicb_scrollable_scroll_down;
|
||||
scrollable->scroll_down_data = scrollable;
|
||||
scrollable->on_scroll_up = uicb_scrollable_scroll_up;
|
||||
scrollable->scroll_up_data = scrollable;
|
||||
|
||||
Widget *scroll_up = Widget_plain_new ();
|
||||
Widget *scroll_down = Widget_plain_new ();
|
||||
|
||||
Widget_set_icon (scroll_up, ICON_ARROW_UP);
|
||||
Widget_set_on_left_click (scroll_up, uicb_scrollable_scroll_up, scrollable);
|
||||
scroll_up->icon = ICON_ARROW_UP;
|
||||
Widget_set_on_left_up (scroll_up, uicb_scrollable_scroll_up, scrollable);
|
||||
scroll_up->aspect_ratio = 1.0;
|
||||
|
||||
Widget_set_icon (scroll_down, ICON_ARROW_DOWN);
|
||||
Widget_set_on_left_click (scroll_down, uicb_scrollable_scroll_down, scrollable);
|
||||
scroll_down->icon = ICON_ARROW_DOWN;
|
||||
Widget_set_on_left_up (scroll_down, uicb_scrollable_scroll_down, scrollable);
|
||||
scroll_down->aspect_ratio = 1.0;
|
||||
|
||||
Widget *cont_horiz = Widget_container_new (TRUE, 0, 4);
|
||||
Widget *scrollbar_vertical = Widget_container_new (FALSE, 0, 0);
|
||||
Widget *actual_scrollbar_vertical = Widget_scrollbar_new (scrollable, FALSE);
|
||||
|
||||
actual_scrollbar_vertical->on_left_down = uicb_scrollbar_start_scroll;
|
||||
actual_scrollbar_vertical->on_left_up = uicb_scrollbar_stop_scroll;
|
||||
actual_scrollbar_vertical->on_mouse_leave = uicb_scrollbar_stop_scroll;
|
||||
actual_scrollbar_vertical->on_mouse_move = uicb_scrollbar_scroll;
|
||||
|
||||
Widget_add_child_weighed (scrollbar_vertical, scroll_up, 1);
|
||||
Widget_add_child_weighed (scrollbar_vertical, Widget_scrollbar_new (scrollable, FALSE), 1);
|
||||
Widget_add_child_weighed (scrollbar_vertical, actual_scrollbar_vertical, 1);
|
||||
Widget_add_child_weighed (scrollbar_vertical, scroll_down, 1);
|
||||
|
||||
Widget_add_child_weighed (cont_horiz, scrollable, 0.93);
|
||||
@@ -693,21 +765,27 @@ Widget_composite_scrollable_make (Widget *content)
|
||||
Widget *scroll_left = Widget_plain_new ();
|
||||
Widget *scroll_right = Widget_plain_new ();
|
||||
|
||||
Widget_set_icon (scroll_left, ICON_ARROW_LEFT);
|
||||
Widget_set_on_left_click (scroll_left, uicb_scrollable_scroll_left, scrollable);
|
||||
scroll_left->icon = ICON_ARROW_LEFT;
|
||||
Widget_set_on_left_up (scroll_left, uicb_scrollable_scroll_left, scrollable);
|
||||
scroll_left->aspect_ratio = 1.0;
|
||||
|
||||
Widget_set_icon (scroll_right, ICON_ARROW_RIGHT);
|
||||
Widget_set_on_left_click (scroll_right, uicb_scrollable_scroll_right, scrollable);
|
||||
scroll_right->icon = ICON_ARROW_RIGHT;
|
||||
Widget_set_on_left_up (scroll_right, uicb_scrollable_scroll_right, scrollable);
|
||||
scroll_right->aspect_ratio = 1.0;
|
||||
|
||||
Widget *scrollbar_horizontal = Widget_container_new (TRUE, 0, 0);
|
||||
Widget *actual_scrollbar_horizontal = Widget_scrollbar_new (scrollable, TRUE);
|
||||
|
||||
actual_scrollbar_horizontal->on_left_down = uicb_scrollbar_start_scroll;
|
||||
actual_scrollbar_horizontal->on_left_up = uicb_scrollbar_stop_scroll;
|
||||
actual_scrollbar_horizontal->on_mouse_leave = uicb_scrollbar_stop_scroll;
|
||||
actual_scrollbar_horizontal->on_mouse_move = uicb_scrollbar_scroll;
|
||||
|
||||
Widget *padding = Widget_plain_new ();
|
||||
padding->aspect_ratio = 1.0;
|
||||
|
||||
Widget_add_child_weighed (scrollbar_horizontal, scroll_left, 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, Widget_scrollbar_new (scrollable, TRUE), 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, actual_scrollbar_horizontal, 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, scroll_right, 1);
|
||||
Widget_add_child_weighed (scrollbar_horizontal, padding, 1);
|
||||
|
||||
|
||||
+33
-17
@@ -24,6 +24,7 @@ typedef enum WidgetKind
|
||||
|
||||
typedef enum WidgetIcon
|
||||
{
|
||||
ICON_NONE = -1,
|
||||
ICON_CHECKBOX_UNCHECKED = 0,
|
||||
ICON_CHECKBOX_CHECKED,
|
||||
ICON_SPINNER_LEFT,
|
||||
@@ -64,9 +65,11 @@ typedef struct ScrollableWidget
|
||||
|
||||
typedef struct ScrollbarWidget
|
||||
{
|
||||
struct Widget *scrollable;
|
||||
struct Widget *scrollable; /* Rename to target. */
|
||||
gboolean horizontal;
|
||||
float bar_size;
|
||||
/* Used for input. */
|
||||
gboolean dragging;
|
||||
float drag_offset;
|
||||
} ScrollbarWidget;
|
||||
|
||||
typedef struct Widget
|
||||
@@ -83,30 +86,40 @@ typedef struct Widget
|
||||
};
|
||||
|
||||
gboolean visible;
|
||||
gboolean hovered, clicked;
|
||||
|
||||
|
||||
vec2 position;
|
||||
vec2 size;
|
||||
float layout_weight;
|
||||
float aspect_ratio;
|
||||
|
||||
vec4 background_color;
|
||||
vec4 hovered_bg_color;
|
||||
vec4 clicked_bg_color;
|
||||
|
||||
gboolean has_background_image;
|
||||
unsigned int background_image;
|
||||
|
||||
gboolean has_icon;
|
||||
WidgetIcon icon;
|
||||
|
||||
float border_width;
|
||||
vec4 border_color;
|
||||
|
||||
void (*on_left_click) (struct Widget *, void *);
|
||||
void *left_click_data;
|
||||
void (*on_right_click) (struct Widget *, void *);
|
||||
void *right_click_data;
|
||||
void (*on_left_down) (struct Widget *, void *);
|
||||
void *left_down_data;
|
||||
void (*on_left_up) (struct Widget *, void *);
|
||||
void *left_up_data;
|
||||
void (*on_right_down) (struct Widget *, void *);
|
||||
void *right_down_data;
|
||||
void (*on_right_up) (struct Widget *, void *);
|
||||
void *right_up_data;
|
||||
|
||||
void (*on_mouse_enter) (struct Widget *, void *);
|
||||
void *mouse_enter_data;
|
||||
void (*on_mouse_leave) (struct Widget *, void *);
|
||||
void *mouse_leave_data;
|
||||
void (*on_mouse_move) (struct Widget *, void *);
|
||||
void *mouse_move_data;
|
||||
|
||||
void (*on_scroll_down) (struct Widget *, void *);
|
||||
void *scroll_down_data;
|
||||
void (*on_scroll_up) (struct Widget *, void *);
|
||||
void *scroll_up_data;
|
||||
|
||||
void (*on_tick) (struct Widget *, void *);
|
||||
void *tick_data;
|
||||
} Widget;
|
||||
@@ -121,16 +134,15 @@ 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_icon (Widget *widget, WidgetIcon icon);
|
||||
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_on_left_up (Widget *widget, void (*on_left_up) (Widget *, void *), void *userdata);
|
||||
|
||||
void Widget_label_set_text (Widget *widget, const char *text);
|
||||
void Widget_label_printf (Widget *widget, const char *format, ...);
|
||||
|
||||
void Widget_scrollable_scroll (Widget *widget, vec2 direction);
|
||||
|
||||
Widget *Widget_find_xy_matching (Widget *widget, vec2 pos, gboolean (*match_fn) (Widget *widget));
|
||||
Widget *Widget_find_xy (Widget *widget, vec2 point);
|
||||
|
||||
void ui_widget_mesh_init ();
|
||||
@@ -162,6 +174,10 @@ void uicb_scrollable_scroll_up (Widget *self, void *userdata);
|
||||
void uicb_scrollable_scroll_left (Widget *self, void *userdata);
|
||||
void uicb_scrollable_scroll_right (Widget *self, void *userdata);
|
||||
|
||||
void uicb_scrollbar_start_scroll (Widget *self, void *userdata);
|
||||
void uicb_scrollbar_scroll (Widget *self, void *userdata);
|
||||
void uicb_scrollbar_stop_scroll (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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user