From 9644f3c05b808a3cac3892aae36ffca2cce9357d Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 2 Dec 2021 16:48:23 +0100 Subject: Resize list widgets to the list width for vertical lists --- TODO | 1 + include/mgui/button.h | 1 + include/mgui/list.h | 5 ++++- include/mgui/widget.h | 3 +++ src/mgui/button.c | 21 +++++++++++++++++---- src/mgui/list.c | 33 +++++++++++++++++++++++++++++++-- src/mgui/widget.c | 11 +++++++++++ tests/main.c | 7 +++++-- 8 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..98651c3 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +Destroy widgets when the container is destroyed. \ No newline at end of file diff --git a/include/mgui/button.h b/include/mgui/button.h index 864d3c6..aefc3fe 100644 --- a/include/mgui/button.h +++ b/include/mgui/button.h @@ -16,6 +16,7 @@ mgui_widget* mgui_button_to_widget(mgui_button *list); mgui_button* mgui_widget_to_button(mgui_widget *widget); void mgui_button_set_position(mgui_button *self, mgl_vec2i position); +void mgui_button_set_width(mgui_button *self, int width); void mgui_button_on_event(mgui_button *self, mgl_window *window, mgl_event *event); /* Returns the size of the widget */ mgl_vec2i mgui_button_draw(mgui_button *self, mgl_window *window); diff --git a/include/mgui/list.h b/include/mgui/list.h index 82efaf8..6f359c9 100644 --- a/include/mgui/list.h +++ b/include/mgui/list.h @@ -16,16 +16,19 @@ typedef struct { mgui_widget widget; mgui_list_direction direction; mgl_vec2i position; + mgl_vec2i size; mgui_widget **items; size_t num_items; size_t items_capacity; } mgui_list; -mgui_list* mgui_list_create(mgui_list_direction direction); +mgui_list* mgui_list_create(mgui_list_direction direction, mgl_vec2i size); mgui_widget* mgui_list_to_widget(mgui_list *list); mgui_list* mgui_widget_to_list(mgui_widget *widget); void mgui_list_set_position(mgui_list *self, mgl_vec2i position); +void mgui_list_set_size(mgui_list *self, mgl_vec2i size); +void mgui_list_set_width(mgui_list *self, int width); void mgui_list_append(mgui_list *self, mgui_widget *widget); void mgui_list_on_event(mgui_list *self, mgl_window *window, mgl_event *event); /* Returns the size of the widget */ diff --git a/include/mgui/widget.h b/include/mgui/widget.h index 4ff394c..c831325 100644 --- a/include/mgui/widget.h +++ b/include/mgui/widget.h @@ -25,8 +25,11 @@ struct mgui_widget { }; void mgui_widget_init(mgui_widget *self, mgui_widget_type type); + void mgui_widget_set_margin(mgui_widget *self, int left, int top, int right, int bottom); void mgui_widget_set_position(mgui_widget *self, mgl_vec2i position); +void mgui_widget_set_width(mgui_widget *self, int width); + void mgui_widget_on_event(mgui_widget *self, mgl_window *window, mgl_event *event); /* Returns the size of the widget */ mgl_vec2i mgui_widget_draw(mgui_widget *self, mgl_window *window); diff --git a/src/mgui/button.c b/src/mgui/button.c index c6b65d5..b548140 100644 --- a/src/mgui/button.c +++ b/src/mgui/button.c @@ -13,6 +13,7 @@ mgui_button* mgui_button_create() { button->background.size = (mgl_vec2f){ 0.0f, 0.0f }; button->background.color = (mgl_color){ 45, 45, 45, 255 }; mgl_text_init(&button->label, mgui_get_font(MGUI_FONT_LATIN, 32), "Label", 5); + button->background.size = mgl_text_get_bounds(&button->label); return button; } @@ -26,9 +27,22 @@ mgui_button* mgui_widget_to_button(mgui_widget *widget) { } void mgui_button_set_position(mgui_button *self, mgl_vec2i position) { - const mgl_vec2f position_f = (mgl_vec2f){ position.x, position.y }; - self->background.position = position_f; - mgl_text_set_position(&self->label, position_f); + const mgl_vec2f label_bounds = mgl_text_get_bounds(&self->label); + self->background.position = (mgl_vec2f){ position.x, position.y }; + mgl_text_set_position(&self->label, (mgl_vec2f){ + (int)(self->background.position.x + self->background.size.x * 0.5f - label_bounds.x * 0.5f), + (int)(self->background.position.y + self->background.size.y * 0.5f - label_bounds.y * 0.5f) + }); +} + +static int max_int(int a, int b) { + return a >= b ? a : b; +} + +void mgui_button_set_width(mgui_button *self, int width) { + mgl_vec2f label_bounds = mgl_text_get_bounds(&self->label); + self->background.size.x = max_int(label_bounds.x, width); + mgui_button_set_position(self, (mgl_vec2i){ self->background.position.x, self->background.position.y }); } void mgui_button_on_event(mgui_button *self, mgl_window *window, mgl_event *event) { @@ -49,7 +63,6 @@ void mgui_button_on_event(mgui_button *self, mgl_window *window, mgl_event *even mgl_vec2i mgui_button_draw(mgui_button *self, mgl_window *window) { (void)window; - self->background.size = mgl_text_get_bounds(&self->label); mgl_rectangle_draw(mgl_get_context(), &self->background); mgl_text_draw(mgl_get_context(), &self->label); return (mgl_vec2i){ self->background.size.x, self->background.size.y }; diff --git a/src/mgui/list.c b/src/mgui/list.c index 320b448..9923c4f 100644 --- a/src/mgui/list.c +++ b/src/mgui/list.c @@ -1,12 +1,14 @@ #include "../../include/mgui/list.h" #include "../../include/alloc.h" +#include #include -mgui_list* mgui_list_create(mgui_list_direction direction) { +mgui_list* mgui_list_create(mgui_list_direction direction, mgl_vec2i size) { 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->size = size; list->items = NULL; list->num_items = 0; list->items_capacity = 0; @@ -26,6 +28,22 @@ void mgui_list_set_position(mgui_list *self, mgl_vec2i position) { self->position = position; } +void mgui_list_set_size(mgui_list *self, mgl_vec2i size) { + self->size = size; + /* 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], size.x); + } + } +} + +void mgui_list_set_width(mgui_list *self, int width) { + mgui_list_set_size(self, (mgl_vec2i){ width, self->size.y }); +} + static void mgui_list_ensure_capacity(mgui_list *self, size_t new_capacity) { if(self->items_capacity >= new_capacity) return; @@ -59,9 +77,19 @@ static int max_int(int a, int b) { } mgl_vec2i mgui_list_draw(mgui_list *self, mgl_window *window) { - mgl_vec2i position = self->position; + mgl_vec2i position = (mgl_vec2i){ 0, 0 }; + /* TODO: */ mgl_vec2i size = (mgl_vec2i){ 0, 0 }; + mgl_view prev_view; + mgl_window_get_view(window, &prev_view); + + mgl_view new_view = { + .position = { self->position.x, self->position.y }, + .size = self->size + }; + mgl_window_set_view(window, &new_view); + switch(self->direction) { case MGUI_LIST_HORIZONITAL: { for(size_t i = 0; i < self->num_items; ++i) { @@ -85,5 +113,6 @@ mgl_vec2i mgui_list_draw(mgui_list *self, mgl_window *window) { } } + mgl_window_set_view(window, &prev_view); /* TODO: Remove */ return size; } diff --git a/src/mgui/widget.c b/src/mgui/widget.c index f35ff05..195d253 100644 --- a/src/mgui/widget.c +++ b/src/mgui/widget.c @@ -25,6 +25,17 @@ void mgui_widget_set_position(mgui_widget *self, mgl_vec2i position) { } } +void mgui_widget_set_width(mgui_widget *self, int width) { + switch(self->type) { + case MGUI_WIDGET_LIST: + mgui_list_set_width(mgui_widget_to_list(self), width); + break; + case MGUI_WIDGET_BUTTON: + mgui_button_set_width(mgui_widget_to_button(self), width); + break; + } +} + void mgui_widget_on_event(mgui_widget *self, mgl_window *window, mgl_event *event) { switch(self->type) { case MGUI_WIDGET_LIST: diff --git a/tests/main.c b/tests/main.c index 79afbea..5f07558 100644 --- a/tests/main.c +++ b/tests/main.c @@ -9,16 +9,19 @@ int main() { return 1; mgl_window window; - if(mgl_window_create(&window, "mgl", &(mgl_window_create_params){ .size = {1280, 720} }) != 0) + if(mgl_window_create(&window, "mgl", &(mgl_window_create_params){ .size = { 1280, 720 } }) != 0) return 1; - mgui_list *list = mgui_list_create(MGUI_LIST_VERTICAL); + mgui_list *list = mgui_list_create(MGUI_LIST_VERTICAL, (mgl_vec2i){ 1280, 720 }); mgui_list_append(list, mgui_button_to_widget(mgui_button_create())); mgui_list_append(list, mgui_button_to_widget(mgui_button_create())); mgl_event event; while(mgl_window_is_open(&window)) { while(mgl_window_poll_event(&window, &event)) { + if(event.type == MGL_EVENT_RESIZED) { + mgui_list_set_size(list, (mgl_vec2i){ event.size.width, event.size.height }); + } mgui_list_on_event(list, &window, &event); } -- cgit v1.2.3