diff --git a/game/src/ui/uiman.c b/game/src/ui/uiman.c index d47ca34..b7b8b0e 100644 --- a/game/src/ui/uiman.c +++ b/game/src/ui/uiman.c @@ -35,41 +35,46 @@ 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_container_new (FALSE); + Widget *debug_menu = Widget_flowbox_new (TRUE); debug_menu->style->layout_padding = 8; debug_menu->style->background_image = RESTEX ("terrain4"); VEC2_SETI (debug_menu->position, 32, 32); - VEC2_SETI (debug_menu->size, 350, 200); + debug_menu->size[0] = 350; + + Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("Frame time: %.2f", &delta_time, TEXT_ALIGN_LEFT), 1, 20); + Widget_add_child_flowbox (debug_menu, Widget_label_make_int ("Chunks: %d", &n_frame_chunks, TEXT_ALIGN_LEFT), 1./2., 20); + Widget_add_child_flowbox (debug_menu, Widget_label_make_int ("Entities: %d", &n_frame_ents, TEXT_ALIGN_LEFT), 1./2., 20); + + Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("X: %.1f", &camera_position[0], TEXT_ALIGN_LEFT), 1./3., 20); + Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("Y: %.1f", &camera_position[1], TEXT_ALIGN_CENTER), 1./3., 20); + Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("Z: %.1f", &camera_position[2], TEXT_ALIGN_RIGHT), 1./3., 20); + + Widget_add_child_flowbox (debug_menu, Widget_composite_spinner_make_int ("Render distance: %d", &render_distance), 1, 20); + + Widget_add_child_flowbox (debug_menu, Widget_composite_checkbox_make ("Wireframe", "wireframe_enabled"), 1./2., 20); + Widget_add_child_flowbox (debug_menu, Widget_composite_checkbox_make ("Flight", "flight_enabled"), 1./2., 20); + 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); - Widget_add_child_weighed (debug_menu, Widget_label_make_int ("Chunks rendered: %d", &n_frame_chunks, TEXT_ALIGN_LEFT), 1); - Widget_add_child_weighed (debug_menu, Widget_label_make_int ("Entities rendered: %d", &n_frame_ents, TEXT_ALIGN_LEFT), 1); - - Widget *poscont = Widget_container_new (TRUE); - Widget_add_child_weighed (poscont, Widget_label_make_float ("X: %.1f", &camera_position[0], TEXT_ALIGN_LEFT), 1); - 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_composite_spinner_make_int ("Render distance: %d", &render_distance), 1); - - Widget *chkboxes = Widget_container_new (TRUE); - Widget_add_child_weighed (chkboxes, Widget_composite_checkbox_make ("Wireframe", "wireframe_enabled"), 1); - Widget_add_child_weighed (chkboxes, Widget_composite_checkbox_make ("Flight", "flight_enabled"), 1); - Widget_add_child_weighed (debug_menu, chkboxes, 1); - Widget *console = Widget_container_new (FALSE); VEC2_SETI (console->position, 418, 32); VEC2_SETI (console->size, 350, 200); console->style->layout_padding = 8; - console->style->background_image = RESTEX ("terrain3"); + console->style->background_image = RESTEX ("terrain4"); + + Widget *scrollable_container = Widget_container_new (TRUE); Widget *scrollable = Widget_scrollable_new (); + scrollable->scrollable.layout_horizontal = TRUE; + Widget_add_child_weighed (scrollable, Widget_multiline_text_new (lorem_ipsum, 20, TEXT_ALIGN_LEFT), 1); + Widget *scrollbar = Widget_scrollbar_new (scrollable, FALSE); + scrollbar->size[0] = 20; + Widget_add_child_weighed (scrollable_container, scrollable, 1); + Widget_add_child (scrollable_container, scrollbar); + Widget_add_child_weighed (console, scrollable_container, 1); + Widget *entry = Widget_entry_new ("Command..."); entry->style->background_image = RESTEX ("terrain2"); entry->size[1] = 20; - - Widget_add_child_weighed (console, scrollable, 1); Widget_add_child (console, entry); Widget_add_child (ui_root, console); @@ -202,6 +207,9 @@ uiman_cb_mouse_motion (SDL_Event *event, void *data) } _uiman_call_on_event (hovered_widget, event, EVENT_MOUSE_MOVE); + /* Even if it isn't the hovered widget, this is useful for stuff + like scrollbars. */ + _uiman_call_on_event (clicked_widget, event, EVENT_MOUSE_MOVE); /* This callback always eats the event, because why would the game need mouse motion if the UI has stolen the focus? */ diff --git a/game/src/ui/widget_core.c b/game/src/ui/widget_core.c index 09f0bf2..ec32eae 100644 --- a/game/src/ui/widget_core.c +++ b/game/src/ui/widget_core.c @@ -191,6 +191,13 @@ Widget_add_child_weighed (Widget *parent, Widget *child, float layout_weight) Widget_add_child (parent, child); } +void Widget_add_child_flowbox (Widget *parent, Widget *child, + float layout_weight, float cross_axis_size) +{ + child->size[parent->flowbox.horizontal ? 1 : 0] = cross_axis_size; + Widget_add_child_weighed (parent, child, layout_weight); +} + void Widget_set_on_event (Widget *widget, WidgetEvent event, void (*on_event) (Widget *, SDL_Event *, void *), diff --git a/game/src/ui/widget_core.h b/game/src/ui/widget_core.h index c57b102..718693d 100644 --- a/game/src/ui/widget_core.h +++ b/game/src/ui/widget_core.h @@ -186,6 +186,8 @@ Widget *Widget_flowbox_new (gboolean horizontal); void Widget_add_child (Widget *parent, Widget *child); void Widget_add_child_weighed (Widget *parent, Widget *child, float layout_weight); +void Widget_add_child_flowbox (Widget *parent, Widget *child, + float layout_weight, float cross_axis_size); 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); diff --git a/game/src/ui/widget_layout.c b/game/src/ui/widget_layout.c index 2ffb4ba..0667d1e 100644 --- a/game/src/ui/widget_layout.c +++ b/game/src/ui/widget_layout.c @@ -252,13 +252,20 @@ Widget_layout_flowbox (Widget *self) Widget *child; WIDGET_FOREACH_CHILD (self, i, child) { + /* It works like a percentage here; identically like in the + ScrollableWidget. */ + if (child->layout_weight > 0.0) + { + child->size[main_axis] = child->layout_weight * self->size[main_axis] - pad * 2; + } + float size_main = child->size[main_axis]; float size_cross = child->size[cross_axis]; /* If our current width/height on the main axis and the width/height of the widget are bigger than the container size (minus the padding), then we move on to the next row. */ - if (offset_main + size_main > self->size[main_axis] - pad * 2) + if (offset_main > pad && offset_main + size_main > self->size[main_axis] - pad * 2) { /* The offset on the cross axis is incremented by the biggest element in the last row (so that the elements are