From cb46c5ba340ccb4a46d780bc8a35d16200be6a9f Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Wed, 1 Oct 2025 16:28:48 +0000 Subject: [PATCH] menu buttons git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@106 b9cfdab3-6d41-4d17-bbe4-086880011989 --- examples/example.c | 6 +++ include/Mw/Menu.h | 9 +++++ include/Mw/TypeDefs.h | 1 + src/button.c | 3 +- src/core.c | 4 ++ src/frame.c | 3 +- src/menu.c | 91 ++++++++++++++++++++++++++++++++++++++++--- src/opengl.c | 3 +- src/vulkan.c | 3 +- src/window.c | 3 +- 10 files changed, 116 insertions(+), 10 deletions(-) diff --git a/examples/example.c b/examples/example.c index 5ad0652..5b9f84f 100644 --- a/examples/example.c +++ b/examples/example.c @@ -72,5 +72,11 @@ int main() { MwAddUserHandler(button3, MwNactivateHandler, handler, NULL); MwAddUserHandler(button4, MwNactivateHandler, handler, NULL); + MwMenuAdd(menu, NULL, "test 1"); + MwMenuAdd(menu, NULL, "test 2"); + MwMenuAdd(menu, NULL, "test 3"); + MwMenuAdd(menu, NULL, "test 4"); + MwMenuAdd(menu, NULL, "test 5"); + MwLoop(window); } diff --git a/include/Mw/Menu.h b/include/Mw/Menu.h index a792fc8..b94507b 100644 --- a/include/Mw/Menu.h +++ b/include/Mw/Menu.h @@ -18,6 +18,15 @@ extern "C" { */ MWDECL MwClass MwMenuClass; +/*! + * %brief Adds a menu + * %param handle Widget + * %param menu Menu + * %param name Menu name + * %return Menu + */ +MWDECL void* MwMenuAdd(MwWidget handle, void* menu, const char* name); + #ifdef __cplusplus } #endif diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index 887de00..c44dad0 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -89,6 +89,7 @@ struct _MwClass { MwHandler destroy; MwHandler draw; MwHandler click; + MwHandler parent_resize; }; struct _MwFont { diff --git a/src/button.c b/src/button.c index fa5a865..6f8bf54 100644 --- a/src/button.c +++ b/src/button.c @@ -63,6 +63,7 @@ MwClassRec MwButtonClassRec = { create, /* create */ NULL, /* destroy */ draw, /* draw */ - click /* click */ + click, /* click */ + NULL /* parent_resize */ }; MwClass MwButtonClass = &MwButtonClassRec; diff --git a/src/core.c b/src/core.c index a198715..fe289d0 100644 --- a/src/core.c +++ b/src/core.c @@ -22,8 +22,12 @@ static void lldownhandler(MwLL handle) { static void llresizehandler(MwLL handle) { MwWidget h = (MwWidget)handle->user; + int i; MwDispatchUserHandler(h, MwNresizeHandler, NULL); + for(i = 0; i < arrlen(h->children); i++) { + MwDispatch(h->children[i], parent_resize); + } } static void llclosehandler(MwLL handle) { diff --git a/src/frame.c b/src/frame.c index 0fc1889..4458f04 100644 --- a/src/frame.c +++ b/src/frame.c @@ -25,6 +25,7 @@ MwClassRec MwFrameClassRec = { create, /* create */ NULL, /* destroy */ draw, /* draw */ - NULL /* click */ + NULL, /* click */ + NULL /* parent_resize */ }; MwClass MwFrameClass = &MwFrameClassRec; diff --git a/src/menu.c b/src/menu.c index f51b7aa..ce3fa95 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1,8 +1,26 @@ /* $Id$ */ #include +#include "stb_ds.h" + +typedef struct menu menu_t; + +struct menu { + char* name; + menu_t** sub; +}; + static void set_xywh(MwWidget handle) { - int height = 0; + int height = 0; + int i; + menu_t* m = handle->internal; + + for(i = 0; i < arrlen(m->sub); i++) { + int h = MwTextHeight(handle, m->sub[i]->name); + if(height < h) { + height = h; + } + } height += 20; @@ -15,14 +33,45 @@ static void set_xywh(MwWidget handle) { } static void create(MwWidget handle) { + menu_t* m = malloc(sizeof(*m)); + + m->name = NULL; + m->sub = NULL; + handle->internal = m; + MwSetDefault(handle); set_xywh(handle); } +static void recursive_free(menu_t* m) { + int i; + + for(i = 0; i < arrlen(m->sub); i++) { + recursive_free(m->sub[i]); + } + + if(m->sub != NULL) arrfree(m->sub); + if(m->name != NULL) free(m->name); + free(m); +} + +static void destroy(MwWidget handle) { + menu_t* m = handle->internal; + + recursive_free(m); +} + static void draw(MwWidget handle) { MwRect r; + MwPoint p; MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); + MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); + menu_t* m = handle->internal; + int i; + + p.x = 10; + p.y = MwGetInteger(handle, MwNheight) / 2; r.x = 0; r.y = 0; @@ -31,12 +80,44 @@ static void draw(MwWidget handle) { MwDrawFrame(handle, &r, base, 0); MwDrawRect(handle, &r, base); + for(i = 0; i < arrlen(m->sub); i++) { + int tw = MwTextWidth(handle, m->sub[i]->name); + + p.x += tw / 2; + + MwDrawText(handle, &p, m->sub[i]->name, text); + + p.x += tw / 2 + 20; + } + + MwLLFreeColor(text); + MwLLFreeColor(base); +} + +static void parent_resize(MwWidget handle) { + set_xywh(handle); } MwClassRec MwMenuClassRec = { - create, /* create */ - NULL, /* destroy */ - draw, /* draw */ - NULL /* click */ + create, /* create */ + destroy, /* destroy */ + draw, /* draw */ + NULL, /* click */ + parent_resize /* parent_resize */ }; MwClass MwMenuClass = &MwMenuClassRec; + +void* MwMenuAdd(MwWidget handle, void* menu, const char* name) { + menu_t* m = menu == NULL ? handle->internal : menu; + menu_t* new = malloc(sizeof(*new)); + new->name = malloc(strlen(name) + 1); + new->sub = NULL; + + strcpy(new->name, name); + + arrput(m->sub, new); + + set_xywh(handle); + + return new; +} diff --git a/src/opengl.c b/src/opengl.c index 018cdb4..60c073e 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -130,7 +130,8 @@ MwClassRec MwOpenGLClassRec = { create, /* create */ destroy, /* destroy */ NULL, /* draw */ - NULL /* click */ + NULL, /* click */ + NULL /* parent_resize */ }; MwClass MwOpenGLClass = &MwOpenGLClassRec; diff --git a/src/vulkan.c b/src/vulkan.c index ffb52e4..8caf498 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -379,6 +379,7 @@ MwClassRec MwVulkanClassRec = { create, /* create */ destroy, /* destroy */ NULL, /* draw */ - NULL /* click */ + NULL, /* click */ + NULL /* parent_resize */ }; MwClass MwVulkanClass = &MwVulkanClassRec; diff --git a/src/window.c b/src/window.c index a26ec67..30ece11 100644 --- a/src/window.c +++ b/src/window.c @@ -23,7 +23,8 @@ MwClassRec MwWindowClassRec = { create, /* create */ NULL, /* destroy */ draw, /* draw */ - NULL /* click */ + NULL, /* click */ + NULL /* parent_resize */ }; MwClass MwWindowClass = &MwWindowClassRec;