From ab903ed4c0599ba8a3768d3d9e25f7ba1a7ca070 Mon Sep 17 00:00:00 2001 From: mid <> Date: Sat, 10 May 2025 18:21:51 +0300 Subject: [PATCH] k3Menu CSS-style properties --- src/k3font.c | 3 +- src/k3menu.c | 101 ++++++++++++++++++++++++++------------------------- src/k3menu.h | 20 ++++++++++ 3 files changed, 73 insertions(+), 51 deletions(-) diff --git a/src/k3font.c b/src/k3font.c index 8538c83..146ada1 100644 --- a/src/k3font.c +++ b/src/k3font.c @@ -131,6 +131,7 @@ void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const struct k3Tex *tex = this->pages[g->page]; size_t texW = this->texW; size_t texH = this->texH; + k3BatchAdd(tex, (struct k3RectF) {(float) g->x / texW, (float) g->y / texH, (float) g->width / texW, (float) g->height / texH}, (struct k3RectF) { @@ -138,7 +139,7 @@ void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const y + ((-g->height - g->yoffset) * this->lineScale + 1) * sz, g->width * this->lineScale * sz, g->height * this->lineScale * sz - }, 0, color); + }, 0, color, 0); x += g->xadvance * this->lineScale * sz; } diff --git a/src/k3menu.c b/src/k3menu.c index 0ebcee3..d233336 100644 --- a/src/k3menu.c +++ b/src/k3menu.c @@ -70,9 +70,30 @@ bool k3MEventSend(struct k3MEvent *ev) { return true; } +static void obj_draw(struct k3MObj *this) { + struct k3MProperty *borderRadiusProp = k3MFindProperty(this, k3M_PROP_BORDER_RADIUS, false); + float borderRadius = borderRadiusProp ? borderRadiusProp->si[0] : 0; + + struct k3MProperty *bgColorProp = k3MFindProperty(this, k3M_PROP_BG_COLOR, false); + vec4 bgColor = {0, 0, 0, 0}; + if(bgColorProp) { + bgColor[0] = bgColorProp->si[0] / 255.0; + bgColor[1] = bgColorProp->si[1] / 255.0; + bgColor[2] = bgColorProp->si[2] / 255.0; + bgColor[3] = bgColorProp->si[3] / 255.0; + } + + k3BatchAdd(NULL, (struct k3RectF) {0, 0, 1, 1}, (struct k3RectF) { + this->x, this->y, + this->w, this->h + }, 0, bgColor, borderRadius); +} + static bool label_draw(struct k3MEvent *ev, uint8_t *ud) { struct k3MLabel *this = (void*) ev->target; + obj_draw((void*) this); + if(this->txt) { k3FontDraw(this->font, this->x, this->y, this->sz, this->txt, (vec4) {1, 1, 1, 1}); } @@ -118,51 +139,29 @@ void k3MAddChild(struct k3MObj *parent, struct k3MObj *child) { child->parent = parent; } -/*static struct k3Menu *k3ScreenFuncMouse(struct k3Menu *_, int16_t x, int16_t y, int ev) { - struct k3Screen *this = (void*) _; +void k3MOverrideProperty(struct k3MObj *obj, struct k3MProperty n) { + struct k3MProperty *o = k3MFindProperty(obj, n.type, true); - if(ev == k3_MENU_MOUSE_MOVE) { - struct k3Menu *newHovered = k3ContainerFuncMouse(_, x, y, k3_MENU_MOUSE_TEST); - if(this->hovered != newHovered) { - if(this->hovered && this->hovered->funcmouse) { - this->hovered->funcmouse(this->hovered, x, y, k3_MENU_MOUSE_OUT); - } - - this->hovered = newHovered; - - if(this->hovered && this->hovered->funcmouse) { - this->hovered->funcmouse(this->hovered, x, y, k3_MENU_MOUSE_IN); - } - } else { - if(this->hovered && this->hovered->funcmouse) { - return this->hovered->funcmouse(this->hovered, x, y, k3_MENU_MOUSE_MOVE); - } + if(!o) { + obj->properties = realloc(obj->properties, ++obj->propertyCount * sizeof(*obj->properties)); + o = &obj->properties[obj->propertyCount - 1]; + } + + memcpy(o, &n, sizeof(n)); +} + +struct k3MProperty *k3MFindProperty(struct k3MObj *obj, enum k3MPropertyType t, bool direct) { + for(size_t i = 0; i < obj->propertyCount; i++) { + if(obj->properties[i].type == t) { + return &obj->properties[i]; } - } else if(this->hovered && this->hovered->funcmouse) { - struct k3Menu *ret = this->hovered->funcmouse(this->hovered, x, y, ev); - this->keyboardFocus = ret; - return ret; } - - return NULL; + if(direct || !obj->parent) { + return NULL; + } + return k3MFindProperty(obj->parent, t, direct); } -static void k3ScreenFuncKey(struct k3Menu *_, int key, int action, int modifiers) { - struct k3Screen *this = (void*) _; - - if(this->keyboardFocus && this->keyboardFocus->funckey) { - this->keyboardFocus->funckey(this->keyboardFocus, key, action, modifiers); - } -} - -static void k3ScreenFuncChar(struct k3Menu *_, uint32_t codepoint) { - struct k3Screen *this = (void*) _; - - if(this->keyboardFocus && this->keyboardFocus->funcchar) { - this->keyboardFocus->funcchar(this->keyboardFocus, codepoint); - } -}*/ - static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) { struct k3MScreen *this = (void*) ev->target; @@ -194,6 +193,12 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) { } + if(innermost != this->lastHover) { + this->lastHover->hovered = false; + innermost->hovered = true; + this->lastHover = innermost; + } + if(innermost != (void*) this) { if(ev->code == k3M_EVENT_MOUSE_PRESS) { @@ -242,6 +247,8 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) { struct k3MScreen *k3MScreen() { struct k3MScreen *ret = calloc(1, sizeof(*ret)); + ret->lastHover = (void*) ret; + k3MRegisterEventHandler(ret, k3M_EVENT_ALL, screen_ev, NULL, 0); return ret; @@ -250,12 +257,9 @@ struct k3MScreen *k3MScreen() { static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) { struct k3MTextButton *this = (void*) ev->target; + obj_draw((void*) this); + if(this->txt) { - k3BatchAdd(NULL, (struct k3RectF) {}, (struct k3RectF) { - this->x, this->y, - this->w, this->h - }, 0, (vec4) {1, 1, 1, 0.2 + 0.1 * this->hovered}); - struct k3RectF txtsz; k3FontSz(this->font, this->sz, this->txt, &txtsz); @@ -280,12 +284,9 @@ struct k3MTextButton *k3MTextButton(struct k3Font *font, float sz, const char *t static bool textinput_draw(struct k3MEvent *ev, uint8_t *ud) { struct k3MTextInput *this = (void*) ev->target; + obj_draw((void*) this); + if(this->txt) { - k3BatchAdd(NULL, (struct k3RectF) {}, (struct k3RectF) { - this->x, this->y, - this->w, this->h - }, 0, (vec4) {1, 1, 1, 0.2}); - int isPlaceholder = strlen(this->txt) == 0; const char *txt = isPlaceholder ? this->placeholder : this->txt; diff --git a/src/k3menu.h b/src/k3menu.h index f50f391..684dda0 100644 --- a/src/k3menu.h +++ b/src/k3menu.h @@ -61,6 +61,19 @@ typedef struct k3MEventHandler { uint16_t code; } k3MEventHandler; +enum k3MPropertyType { + k3M_PROP_BG_COLOR, + k3M_PROP_BORDER_RADIUS, +}; +struct k3MProperty { + enum k3MPropertyType type; + union { + intmax_t si[4]; + void *ptr; + uint8_t buf[32]; + }; +}; + struct k3MObj { struct k3MObj *parent; @@ -76,6 +89,9 @@ struct k3MObj { k3MEventHandler *handlers; size_t handlerCount; + + struct k3MProperty *properties; + size_t propertyCount; }; #define k3MenuSetBounds(a, x, y, w, h) k3MenuSetBounds_((struct k3MObj*) (a), (x), (y), (w), (h)) @@ -89,6 +105,9 @@ bool k3MEventSend(struct k3MEvent *ev); int k3MRemoveChild(struct k3MObj *parent, struct k3MObj *child); void k3MAddChild(struct k3MObj *parent, struct k3MObj *child); +void k3MOverrideProperty(struct k3MObj *obj, struct k3MProperty); +struct k3MProperty *k3MFindProperty(struct k3MObj *obj, enum k3MPropertyType, bool direct); + struct k3MLabel { struct k3MObj; @@ -102,6 +121,7 @@ struct k3MScreen { struct k3MObj; struct k3MObj *keyboardFocus; + struct k3MObj *lastHover; }; struct k3MScreen *k3MScreen();