add table widget
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
This commit is contained in:
parent
0628250631
commit
32266c7656
11 changed files with 336 additions and 95 deletions
|
|
@ -95,18 +95,7 @@ static void draw(MwWidget handle) {
|
|||
}
|
||||
|
||||
static void prop_change(MwWidget handle, const char* key) {
|
||||
if(strcmp(key, MwNorientation) == 0) {
|
||||
MwBox b = handle->internal;
|
||||
b->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void children_prop_change(MwWidget handle, MwWidget child, const char* key) {
|
||||
(void)child;
|
||||
|
||||
if(strcmp(key, MwNratio) == 0 || strcmp(key, MwNfixedSize) == 0) {
|
||||
if(strcmp(key, MwNorientation) == 0 || strcmp(key, MwNpadding) == 0 || strcmp(key, MwNmargin) == 0) {
|
||||
MwBox b = handle->internal;
|
||||
b->layout = 1;
|
||||
|
||||
|
|
@ -131,13 +120,28 @@ static void resize(MwWidget handle) {
|
|||
MwForceRender(handle);
|
||||
}
|
||||
|
||||
static void children_update(MwWidget handle) {
|
||||
MwBox b = handle->internal;
|
||||
static void children_update(MwWidget handle, MwWidget child, int new) {
|
||||
MwBox b = handle->internal;
|
||||
|
||||
(void)child;
|
||||
(void)new;
|
||||
|
||||
b->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
|
||||
static void children_prop_change(MwWidget handle, MwWidget child, const char* key) {
|
||||
(void)child;
|
||||
|
||||
if(strcmp(key, MwNratio) == 0 || strcmp(key, MwNfixedSize) == 0) {
|
||||
MwBox b = handle->internal;
|
||||
b->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
}
|
||||
|
||||
MwClassRec MwBoxClassRec = {
|
||||
wcreate, /* create */
|
||||
destroy, /* destroy */
|
||||
|
|
|
|||
228
src/widget/table.c
Normal file
228
src/widget/table.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
#include <Mw/Milsko.h>
|
||||
|
||||
#include "../../external/stb_ds.h"
|
||||
|
||||
static int wcreate(MwWidget handle) {
|
||||
MwTable t = malloc(sizeof(*t));
|
||||
memset(t, 0, sizeof(*t));
|
||||
|
||||
handle->internal = t;
|
||||
|
||||
MwSetDefault(handle);
|
||||
|
||||
MwSetInteger(handle, MwNcolumns, 1);
|
||||
MwSetInteger(handle, MwNmargin, 0);
|
||||
MwSetInteger(handle, MwNpadding, 0);
|
||||
MwSetInteger(handle, MwNhasBorder, 0);
|
||||
MwSetInteger(handle, MwNinverted, 1);
|
||||
MwSetInteger(handle, MwNwaitLayout, 0);
|
||||
|
||||
t->layout = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy(MwWidget handle) {
|
||||
MwTable t = handle->internal;
|
||||
|
||||
arrfree(t->widgets);
|
||||
|
||||
free(t);
|
||||
}
|
||||
|
||||
typedef struct intkv {
|
||||
int key;
|
||||
int value;
|
||||
} intkv_t;
|
||||
|
||||
static void put_intkv(intkv_t** kv, int x, int y, int c, int r) {
|
||||
int k = (x << 16) | y;
|
||||
int v = (c << 16) | r;
|
||||
|
||||
hmput(*kv, k, v);
|
||||
}
|
||||
|
||||
static int get_intkv(intkv_t* kv, int x, int y) {
|
||||
int k = (x << 16) | y;
|
||||
|
||||
return hmget(kv, k);
|
||||
}
|
||||
|
||||
#define LAYOUT_BEGIN \
|
||||
hmfree(kv); \
|
||||
hmdefault(kv, 0); \
|
||||
n = 0; \
|
||||
x = bw; \
|
||||
y = bw; \
|
||||
for(i = 0; i < arrlen(handle->children); i++) { \
|
||||
MwRect rc; \
|
||||
MwWidget hc = handle->children[i]; \
|
||||
int cs = MwGetInteger(hc, MwNcolumnSpan); \
|
||||
int rs = MwGetInteger(hc, MwNrowSpan); \
|
||||
int w, h; \
|
||||
int cy; \
|
||||
int s = MwGetInteger(handle, MwNmargin); \
|
||||
int v = n; \
|
||||
\
|
||||
if(cs == MwDEFAULT) cs = 1; \
|
||||
if(rs == MwDEFAULT) rs = 1; \
|
||||
\
|
||||
w = cs * cw + (cs - 1) * s; \
|
||||
h = rs * ch + (rs - 1) * s; \
|
||||
\
|
||||
MwGetFrame(hc, &rc); \
|
||||
\
|
||||
if(hc == child || rc.x != x || rc.y != y || rc.width != w || rc.height != h) {
|
||||
|
||||
#define LAYOUT_END(label) \
|
||||
} \
|
||||
\
|
||||
put_intkv(&kv, n % c, n / c, cs, rs); \
|
||||
\
|
||||
n += cs; \
|
||||
repeat_##label :; \
|
||||
if((n % c) == 0) { \
|
||||
x = bw; \
|
||||
y += ch + s; \
|
||||
} else { \
|
||||
for(; v < n; v++) { \
|
||||
x += cw + s; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for(cy = (n / c); cy >= 0; cy--) { \
|
||||
int v = get_intkv(kv, n % c, cy) & 0xffff; \
|
||||
\
|
||||
if(cy <= (n / c) && (n / c) <= (cy + v - 1)) { \
|
||||
v = n; \
|
||||
n += get_intkv(kv, n % c, cy) >> 16; \
|
||||
goto repeat_##label; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
static void layout_widget(MwWidget handle, MwWidget child) {
|
||||
int i;
|
||||
int c = MwGetInteger(handle, MwNcolumns);
|
||||
int bw = (MwGetInteger(handle, MwNhasBorder) ? MwDefaultBorderWidth(handle) : 0) + MwGetInteger(handle, MwNpadding);
|
||||
int m = MwGetInteger(handle, MwNmargin);
|
||||
int n, x, y, cw = 0, ch = 0;
|
||||
int gcs, grs;
|
||||
intkv_t* kv = NULL;
|
||||
|
||||
LAYOUT_BEGIN;
|
||||
LAYOUT_END(1);
|
||||
|
||||
gcs = (n + c - 1) / c;
|
||||
grs = n % c;
|
||||
cw = (MwGetInteger(handle, MwNwidth) - bw * 2 - (m * (c - 1))) / c;
|
||||
ch = (MwGetInteger(handle, MwNheight) - m * (gcs - 1) - bw * 2) / gcs;
|
||||
|
||||
LAYOUT_BEGIN;
|
||||
MwVaApply(hc,
|
||||
MwNx, x,
|
||||
MwNy, y,
|
||||
MwNwidth, w,
|
||||
MwNheight, h,
|
||||
NULL);
|
||||
LAYOUT_END(2);
|
||||
|
||||
hmfree(kv);
|
||||
}
|
||||
|
||||
static void layout(MwWidget handle) {
|
||||
MwTable t = handle->internal;
|
||||
int i;
|
||||
|
||||
if(arrlen(t->widgets) > 0) {
|
||||
for(i = 0; i < arrlen(t->widgets); i++) layout_widget(handle, t->widgets[i]);
|
||||
} else {
|
||||
for(i = 0; i < arrlen(handle->children[i]); i++) layout_widget(handle, handle->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw(MwWidget handle) {
|
||||
MwBoxClass->draw(handle);
|
||||
}
|
||||
|
||||
static void tick(MwWidget handle) {
|
||||
MwTable t = handle->internal;
|
||||
|
||||
if(t->layout && !MwGetInteger(handle, MwNwaitLayout)) {
|
||||
layout(handle);
|
||||
|
||||
t->layout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void prop_change(MwWidget handle, const char* key) {
|
||||
if(strcmp(key, MwNcolumns) == 0 || strcmp(key, MwNpadding) == 0 || strcmp(key, MwNmargin) == 0) {
|
||||
MwTable t = handle->internal;
|
||||
t->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void resize(MwWidget handle) {
|
||||
MwTable t = handle->internal;
|
||||
t->layout = 1;
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
|
||||
static void children_update(MwWidget handle, MwWidget child, int new) {
|
||||
MwTable t = handle->internal;
|
||||
t->layout = 1;
|
||||
|
||||
if(new) {
|
||||
arrput(t->widgets, child);
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < arrlen(t->widgets); i++) {
|
||||
if(t->widgets[i] == child) {
|
||||
arrdel(t->widgets, i);
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
|
||||
static void children_prop_change(MwWidget handle, MwWidget child, const char* key) {
|
||||
(void)child;
|
||||
|
||||
if(strcmp(key, MwNcolumnSpan) == 0 || strcmp(key, MwNrowSpan) == 0) {
|
||||
MwTable t = handle->internal;
|
||||
t->layout = 1;
|
||||
|
||||
arrput(t->widgets, child);
|
||||
|
||||
MwForceRender(handle);
|
||||
}
|
||||
}
|
||||
|
||||
MwClassRec MwTableClassRec = {
|
||||
wcreate, /* create */
|
||||
destroy, /* destroy */
|
||||
draw, /* draw */
|
||||
NULL, /* click */
|
||||
NULL, /* parent_resize */
|
||||
prop_change, /* prop_change */
|
||||
NULL, /* mouse_move */
|
||||
NULL, /* mouse_up */
|
||||
NULL, /* mouse_down */
|
||||
NULL, /* key */
|
||||
NULL, /* execute */
|
||||
tick, /* tick */
|
||||
resize, /* resize */
|
||||
children_update, /* children_update */
|
||||
children_prop_change, /* children_prop_change */
|
||||
NULL, /* clipboard */
|
||||
NULL, /* props_change */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL};
|
||||
MwClass MwTableClass = &MwTableClassRec;
|
||||
Loading…
Add table
Add a link
Reference in a new issue