aboutsummaryrefslogtreecommitdiff
path: root/src/mgui/scrollview.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mgui/scrollview.c')
-rw-r--r--src/mgui/scrollview.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/src/mgui/scrollview.c b/src/mgui/scrollview.c
index 3c5850c..c7a4075 100644
--- a/src/mgui/scrollview.c
+++ b/src/mgui/scrollview.c
@@ -4,18 +4,35 @@
#include <mgl/mgl.h>
#include <mgl/window/window.h>
#include <mgl/window/event.h>
+#include <limits.h>
#include <assert.h>
#define SCROLL_ACCEL 20.0f
#define SCROLL_DEACCEL 10.0f
+#define WIDGET_NATURAL_SIZE INT_MAX
+
+static float max_float(float a, float b) {
+ return a >= b ? a : b;
+}
+
+static int max_int(int a, int b) {
+ return a >= b ? a : b;
+}
+
+static int min_int(int a, int b) {
+ return a <= b ? a : b;
+}
+
+static float abs_float(float value) {
+ return value >= 0.0f ? value : -value;
+}
+
mgui_scrollview* mgui_scrollview_create() {
mgui_scrollview *scrollview = mgui_alloc(sizeof(mgui_scrollview));
mgui_widget_init(&scrollview->widget, MGUI_WIDGET_SCROLLVIEW);
scrollview->child = NULL;
- scrollview->child_size = (mgl_vec2i){ 0, 0 };
scrollview->position = (mgl_vec2i){ 0, 0 };
- scrollview->size = (mgl_vec2i){ 0, 0 };
scrollview->scroll = (mgl_vec2i){ 0, 0 };
scrollview->mouse_scroll = (mgl_vec2f){ 0.0f, 0.0f };
return scrollview;
@@ -39,22 +56,26 @@ mgui_scrollview* mgui_widget_to_scrollview(mgui_widget *widget) {
void mgui_scrollview_set_child(mgui_scrollview *self, mgui_widget *child) {
assert(child != mgui_scrollview_to_widget(self));
self->child = child;
- mgui_scrollview_set_width(self, self->size.x);
+ if(self->child) {
+ mgui_widget_set_has_parent(self->child);
+ mgui_widget_calculate_size(self->child, self->widget.size);
+ }
}
void mgui_scrollview_set_position(mgui_scrollview *self, mgl_vec2i position) {
self->position = position;
}
-void mgui_scrollview_set_size(mgui_scrollview *self, mgl_vec2i size) {
- self->size = size;
- mgui_scrollview_set_width(self, self->size.x);
-}
+void mgui_scrollview_calculate_size(mgui_scrollview *self, mgl_vec2i max_size) {
+ self->widget.size = max_size;
+ if(self->widget.size.x == WIDGET_NATURAL_SIZE)
+ self->widget.size.x = 500;
+
+ if(self->widget.size.y == WIDGET_NATURAL_SIZE)
+ self->widget.size.y = 600;
-void mgui_scrollview_set_width(mgui_scrollview *self, int width) {
- /* TODO: Call for child so text can wordwrap? but only if wordwrap is enabled in this scrollview */
if(self->child)
- mgui_widget_set_width(self->child, width);
+ mgui_widget_calculate_size(self->child, (mgl_vec2i){ WIDGET_NATURAL_SIZE, WIDGET_NATURAL_SIZE });
}
void mgui_scrollview_on_event(mgui_scrollview *self, mgl_window *window, mgl_event *event) {
@@ -66,25 +87,9 @@ void mgui_scrollview_on_event(mgui_scrollview *self, mgl_window *window, mgl_eve
mgui_widget_on_event(self->child, window, event);
}
-static float max_float(float a, float b) {
- return a >= b ? a : b;
-}
-
-static int max_int(int a, int b) {
- return a >= b ? a : b;
-}
-
-static int min_int(int a, int b) {
- return a <= b ? a : b;
-}
-
-static float abs_float(float value) {
- return value >= 0.0f ? value : -value;
-}
-
/* TODO: Check if visible in scissor */
-mgl_vec2i mgui_scrollview_draw(mgui_scrollview *self, mgl_window *window) {
+void mgui_scrollview_draw(mgui_scrollview *self, mgl_window *window) {
const double frame_time = mgui_get_seconds_since_last_update();
self->mouse_scroll.x *= max_float(0.0f, (1.0f - frame_time * SCROLL_DEACCEL));
self->mouse_scroll.y *= max_float(0.0f, (1.0f - frame_time * SCROLL_DEACCEL));
@@ -98,16 +103,22 @@ mgl_vec2i mgui_scrollview_draw(mgui_scrollview *self, mgl_window *window) {
self->scroll.x += (int)self->mouse_scroll.x;
self->scroll.y += (int)self->mouse_scroll.y;
- if(self->child_size.x > self->size.x) {
+ mgl_vec2i child_size;
+ if(self->child)
+ child_size = self->child->size;
+ else
+ child_size = (mgl_vec2i){ 0, 0 };
+
+ if(child_size.x > self->widget.size.x) {
self->scroll.x = min_int(self->scroll.x, 0);
- self->scroll.x = max_int(self->scroll.x, -self->child_size.x + self->size.x);
+ self->scroll.x = max_int(self->scroll.x, -child_size.x + self->widget.size.x);
} else {
self->scroll.x = 0;
}
- if(self->child_size.y > self->size.y) {
+ if(child_size.y > self->widget.size.y) {
self->scroll.y = min_int(self->scroll.y, 0);
- self->scroll.y = max_int(self->scroll.y, -self->child_size.y + self->size.y);
+ self->scroll.y = max_int(self->scroll.y, -child_size.y + self->widget.size.y);
} else {
self->scroll.y = 0;
}
@@ -118,17 +129,13 @@ mgl_vec2i mgui_scrollview_draw(mgui_scrollview *self, mgl_window *window) {
mgl_scissor new_scissor = {
.position = self->position,
- .size = self->size
+ .size = self->widget.size
};
mgl_window_set_scissor(window, &new_scissor);
mgui_widget_set_position(self->child, (mgl_vec2i){ self->position.x + self->scroll.x, self->position.y + self->scroll.y });
- self->child_size = mgui_widget_draw(self->child, window);
+ mgui_widget_draw(self->child, window);
mgl_window_set_scissor(window, &prev_scissor);
- } else {
- self->child_size = (mgl_vec2i){ 0, 0 };
}
-
- return self->child_size;
}