diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-12-14 23:48:34 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-12-15 10:30:34 +0100 |
commit | 0417619b36dc7f4b004caa64a65570f1344d1c8d (patch) | |
tree | 10c4b9bbe5bd7c16322495890c3324cd76d584c8 /src/mgui/list.c | |
parent | 396686a09ef471499c11256b8516c2702f761060 (diff) |
Layout, expand, etc
Diffstat (limited to 'src/mgui/list.c')
-rw-r--r-- | src/mgui/list.c | 130 |
1 files changed, 84 insertions, 46 deletions
diff --git a/src/mgui/list.c b/src/mgui/list.c index 58fc964..687906d 100644 --- a/src/mgui/list.c +++ b/src/mgui/list.c @@ -8,12 +8,15 @@ if num_items <= 2. */ +static int max_int(int a, int b) { + return a >= b ? a : b; +} + mgui_list* mgui_list_create(mgui_list_direction direction) { mgui_list *list = mgui_alloc(sizeof(mgui_list)); mgui_widget_init(&list->widget, MGUI_WIDGET_LIST); list->direction = direction; list->position = (mgl_vec2i){ 0, 0 }; - list->background_color = (mgl_color){ 0, 0, 0, 0 }; list->items = NULL; list->items_capacity = 0; list->num_items = 0; @@ -22,7 +25,7 @@ mgui_list* mgui_list_create(mgui_list_direction direction) { void mgui_list_destroy(mgui_list *list) { for(size_t i = 0; i < list->num_items; ++i) { - mgui_widget_destroy(list->items[i]); + mgui_widget_destroy(list->items[i].widget); } mgui_free(list->items); mgui_free(list); @@ -41,19 +44,71 @@ void mgui_list_set_position(mgui_list *self, mgl_vec2i position) { self->position = position; } -void mgui_list_set_width(mgui_list *self, int width) { - /* TODO: if direction is horizontal then put the widget in the center of its area */ - /* TODO: put the widget in the center for vertical as well, for items with a max size */ - /* TODO: support max size for widgets */ - if(self->direction == MGUI_LIST_VERTICAL) { - for(size_t i = 0; i < self->num_items; ++i) { - mgui_widget_set_width(self->items[i], width); +void mgui_list_calculate_size(mgui_list *self, mgl_vec2i max_size) { + mgl_vec2i size = (mgl_vec2i){ 0, 0 }; + switch(self->direction) { + case MGUI_LIST_HORIZONITAL: { + int num_expanded_widgets = 0; + for(size_t i = 0; i < self->num_items; ++i) { + mgui_widget *widget = self->items[i].widget; + if(widget->flags & MGUI_WIDGET_EXPAND_HORIZONTAL) { + ++num_expanded_widgets; + } else { + mgui_widget_calculate_size(widget, max_size); + size.x += widget->size.x; + size.y = max_int(size.y, widget->size.y); + max_size.x -= widget->size.x; + } + } + + if(num_expanded_widgets == 0) + break; + + max_size.x = max_size.x / num_expanded_widgets; + + for(size_t i = 0; i < self->num_items; ++i) { + mgui_widget *widget = self->items[i].widget; + if(widget->flags & MGUI_WIDGET_EXPAND_HORIZONTAL) { + mgui_widget_calculate_size(widget, max_size); + widget->size = max_size; + size.x += widget->size.x; + size.y = max_int(size.y, widget->size.y); + } + } + break; } - } -} + case MGUI_LIST_VERTICAL: { + int num_expanded_widgets = 0; + for(size_t i = 0; i < self->num_items; ++i) { + mgui_widget *widget = self->items[i].widget; + if(widget->flags & MGUI_WIDGET_EXPAND_VERTICAL) { + ++num_expanded_widgets; + } else { + mgui_widget_calculate_size(widget, max_size); + size.x = max_int(size.x, widget->size.x); + size.y += widget->size.y; + max_size.y -= widget->size.y; + } + } + + if(num_expanded_widgets == 0) + break; -void mgui_list_set_background_color(mgui_list *self, mgl_color color) { - self->background_color = color; + max_size.y = max_size.y / num_expanded_widgets; + + for(size_t i = 0; i < self->num_items; ++i) { + mgui_widget *widget = self->items[i].widget; + if(widget->flags & MGUI_WIDGET_EXPAND_VERTICAL) { + mgui_widget_calculate_size(widget, max_size); + widget->size = max_size; + size.x = max_int(size.x, widget->size.x); + size.y += widget->size.y; + } + } + break; + } + } + self->widget.size = size; } static void mgui_list_ensure_capacity(mgui_list *self, size_t new_capacity) { @@ -73,63 +128,46 @@ static void mgui_list_ensure_capacity(mgui_list *self, size_t new_capacity) { } void mgui_list_append(mgui_list *self, mgui_widget *widget) { - mgui_list_ensure_capacity(self, (self->num_items + 1) * sizeof(mgui_widget*)); - self->items[self->num_items] = widget; + mgui_widget_set_has_parent(widget); + mgui_list_ensure_capacity(self, (self->num_items + 1) * sizeof(mgui_list_item)); + self->items[self->num_items].widget = widget; ++self->num_items; } void mgui_list_on_event(mgui_list *self, mgl_window *window, mgl_event *event) { for(size_t i = 0; i < self->num_items; ++i) { - mgui_widget_on_event(self->items[i], window, event); + mgui_widget_on_event(self->items[i].widget, window, event); } } -static int max_int(int a, int b) { - return a >= b ? a : b; -} - /* TODO: Check if visible in scissor */ -mgl_vec2i mgui_list_draw(mgui_list *self, mgl_window *window) { +void mgui_list_draw(mgui_list *self, mgl_window *window) { mgl_vec2i position = self->position; - /* TODO: */ - mgl_vec2i size = (mgl_vec2i){ 0, 0 }; - - /* TODO: - if(self->background_color.a > 0) { - mgl_rectangle rect = { - .position = { self->position.x, self->position.y }, - .size = { self->size.x, self->size.y }, - .color = self->background_color - }; - mgl_rectangle_draw(mgl_get_context(), &rect); - } - */ /* TODO: Set scissor for each draw widget */ + /* TODO: Only do this when a direct child widget is dirty */ + //mgui_list_calculate_size(self); + switch(self->direction) { case MGUI_LIST_HORIZONITAL: { for(size_t i = 0; i < self->num_items; ++i) { - mgui_widget_set_position(self->items[i], position); - const mgl_vec2i widget_size = mgui_widget_draw(self->items[i], window); - size.x += widget_size.x; - size.y = max_int(size.y, widget_size.y); - position.x += widget_size.x; + mgui_widget *widget = self->items[i].widget; + mgui_widget_set_position(widget, position); + mgui_widget_draw(widget, window); + position.x += widget->size.x; } break; } case MGUI_LIST_VERTICAL: { for(size_t i = 0; i < self->num_items; ++i) { - mgui_widget_set_position(self->items[i], position); - const mgl_vec2i widget_size = mgui_widget_draw(self->items[i], window); - size.x = max_int(size.x, widget_size.x); - size.y += widget_size.y; - position.y += widget_size.y; + mgui_widget *widget = self->items[i].widget; + mgui_widget_set_position(widget, position); + mgui_widget_draw(widget, window); + position.y += widget->size.y; } break; } } - - return size; } |