milsko/src/widget/box.c

158 lines
4 KiB
C
Raw Normal View History

2025-12-15 14:09:30 +09:00
#include <Mw/Milsko.h>
#include "../../external/stb_ds.h"
2026-04-15 20:21:20 -07:00
static int wcreate(MwWidget handle) {
2026-03-27 16:41:32 +09:00
MwBox b = malloc(sizeof(*b));
memset(b, 0, sizeof(*b));
handle->internal = b;
2025-12-15 14:09:30 +09:00
MwSetDefault(handle);
MwSetInteger(handle, MwNorientation, MwHORIZONTAL);
2025-12-15 15:41:19 +09:00
MwSetInteger(handle, MwNmargin, 0);
2025-12-15 14:09:30 +09:00
MwSetInteger(handle, MwNpadding, 0);
2025-12-21 15:33:48 +09:00
MwSetInteger(handle, MwNhasBorder, 0);
MwSetInteger(handle, MwNinverted, 1);
2025-12-15 14:09:30 +09:00
2026-03-27 16:41:32 +09:00
b->layout = 0;
2025-12-15 14:09:30 +09:00
return 0;
}
2026-03-29 09:42:34 +09:00
static void destroy(MwWidget handle) {
2026-03-27 16:41:32 +09:00
MwBox b = handle->internal;
free(b);
2025-12-15 14:09:30 +09:00
}
2025-12-15 15:45:53 +09:00
#define Margin ((i != (arrlen(handle->children) - 1)) ? MwGetInteger(handle, MwNmargin) : 0)
2025-12-15 14:09:30 +09:00
static void layout(MwWidget handle) {
int i;
int sum = 0;
int horiz = MwGetInteger(handle, MwNorientation) == MwHORIZONTAL ? 1 : 0;
2025-12-21 15:33:48 +09:00
int sz = MwGetInteger(handle, horiz ? MwNwidth : MwNheight) - (MwGetInteger(handle, MwNpadding) + (MwGetInteger(handle, MwNhasBorder) ? MwDefaultBorderWidth(handle) : 0)) * 2;
int fsz = MwGetInteger(handle, horiz ? MwNheight : MwNwidth) - (MwGetInteger(handle, MwNpadding) + (MwGetInteger(handle, MwNhasBorder) ? MwDefaultBorderWidth(handle) : 0)) * 2;
int sk = MwGetInteger(handle, MwNpadding) + (MwGetInteger(handle, MwNhasBorder) ? MwDefaultBorderWidth(handle) : 0);
2025-12-15 14:09:30 +09:00
for(i = 0; i < arrlen(handle->children); i++) {
2025-12-15 14:30:59 +09:00
int n = MwGetInteger(handle->children[i], MwNratio);
int s = MwGetInteger(handle->children[i], MwNfixedSize);
2025-12-15 14:09:30 +09:00
if(n == MwDEFAULT) n = 1;
2025-12-28 18:03:37 +09:00
if(handle->children[i]->destroyed) continue;
2025-12-15 14:30:59 +09:00
if(s != MwDEFAULT) {
2025-12-15 15:45:53 +09:00
sz -= s + Margin;
2025-12-15 14:30:59 +09:00
} else {
sum += n;
2026-03-27 11:05:15 +09:00
sz -= Margin;
2025-12-15 14:30:59 +09:00
}
2025-12-15 14:09:30 +09:00
}
for(i = 0; i < arrlen(handle->children); i++) {
2025-12-15 14:30:59 +09:00
int n = MwGetInteger(handle->children[i], MwNratio);
int s = MwGetInteger(handle->children[i], MwNfixedSize);
2025-12-15 14:09:30 +09:00
int wsz;
if(n == MwDEFAULT) n = 1;
2025-12-28 18:03:37 +09:00
if(handle->children[i]->destroyed) continue;
2025-12-15 14:30:59 +09:00
if(s != MwDEFAULT) {
wsz = s;
} else {
2025-12-15 15:05:36 +09:00
wsz = sz * n / sum;
2025-12-15 14:30:59 +09:00
}
2025-12-15 14:09:30 +09:00
MwVaApply(handle->children[i],
2025-12-21 15:33:48 +09:00
horiz ? MwNx : MwNy, sk, /* this is what gets changed */
horiz ? MwNy : MwNx, MwGetInteger(handle, MwNpadding) + (MwGetInteger(handle, MwNhasBorder) ? MwDefaultBorderWidth(handle) : 0), /* fixed between widgets */
horiz ? MwNwidth : MwNheight, wsz, /* this is what gets changed */
horiz ? MwNheight : MwNwidth, fsz, /* fixed between widgets */
2025-12-15 14:09:30 +09:00
NULL);
2025-12-15 15:45:53 +09:00
sk += wsz + Margin;
2025-12-15 14:09:30 +09:00
}
}
2026-03-27 16:41:32 +09:00
static void draw(MwWidget handle) {
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
2026-03-29 09:42:34 +09:00
MwBox b = handle->internal;
2026-03-27 16:41:32 +09:00
r.x = 0;
r.y = 0;
r.width = MwGetInteger(handle, MwNwidth);
r.height = MwGetInteger(handle, MwNheight);
if(MwGetInteger(handle, MwNhasBorder)) {
2026-04-14 13:34:49 -07:00
MwDrawFrame(handle, &r, base, MwGetInteger(handle, MwNinverted));
2026-03-27 16:41:32 +09:00
}
MwDrawRect(handle, &r, base);
MwLLFreeColor(base);
2026-03-29 09:42:34 +09:00
if(b->layout) {
2026-03-27 16:41:32 +09:00
layout(handle);
b->layout = 0;
}
}
2025-12-15 14:09:30 +09:00
static void prop_change(MwWidget handle, const char* key) {
2026-03-29 09:42:34 +09:00
if(strcmp(key, MwNorientation) == 0) {
MwBox b = handle->internal;
2026-03-27 16:41:32 +09:00
b->layout = 1;
MwForceRender(handle);
}
2025-12-15 14:09:30 +09:00
}
static void children_prop_change(MwWidget handle, MwWidget child, const char* key) {
(void)child;
2026-03-29 09:42:34 +09:00
if(strcmp(key, MwNratio) == 0 || strcmp(key, MwNfixedSize) == 0) {
MwBox b = handle->internal;
2026-03-27 16:41:32 +09:00
b->layout = 1;
MwForceRender(handle);
}
2025-12-15 14:09:30 +09:00
}
static void resize(MwWidget handle) {
2026-03-29 09:42:34 +09:00
MwBox b = handle->internal;
2026-03-27 16:41:32 +09:00
b->layout = 1;
MwForceRender(handle);
2025-12-15 14:09:30 +09:00
}
static void children_update(MwWidget handle) {
2026-03-29 09:42:34 +09:00
MwBox b = handle->internal;
2026-03-27 16:41:32 +09:00
b->layout = 1;
MwForceRender(handle);
2025-12-15 14:09:30 +09:00
}
MwClassRec MwBoxClassRec = {
2026-04-15 21:41:16 -07:00
wcreate, /* create */
2026-03-27 16:41:32 +09:00
destroy, /* destroy */
2025-12-15 14:09:30 +09:00
draw, /* draw */
NULL, /* click */
NULL, /* parent_resize */
prop_change, /* prop_change */
NULL, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
NULL, /* execute */
NULL, /* tick */
resize, /* resize */
children_update, /* children_update */
children_prop_change, /* children_prop_change */
2025-12-31 04:35:10 +09:00
NULL, /* clipboard */
2025-12-15 14:09:30 +09:00
NULL,
NULL,
NULL,
NULL};
MwClass MwBoxClass = &MwBoxClassRec;