From 6db48088151aba82bf7ef4c680c949a9c5c1c0b2 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Fri, 3 Oct 2025 10:24:34 +0000 Subject: [PATCH] menu works i guess git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@138 b9cfdab3-6d41-4d17-bbe4-086880011989 --- examples/example.c | 15 +++++---- include/Mw/LowLevel.h | 2 ++ include/Mw/StringDefs.h | 1 + src/backend/gdi.c | 4 +++ src/backend/x11.c | 9 +++++ src/widget/menu.c | 2 ++ src/widget/submenu.c | 75 +++++++++++++++++++++++++++++++---------- 7 files changed, 84 insertions(+), 24 deletions(-) diff --git a/examples/example.c b/examples/example.c index e0a2ebe..18eec4a 100644 --- a/examples/example.c +++ b/examples/example.c @@ -46,7 +46,7 @@ void resize(MwWidget handle, void* user_data, void* call_data) { } int main() { - MwMenu m; + MwMenu m, m2; window = MwVaCreateWidget(MwWindowClass, "main", NULL, 0, 0, 400, 400, MwNtitle, "hello world", @@ -75,11 +75,14 @@ int main() { MwAddUserHandler(button4, MwNactivateHandler, handler, NULL); m = MwMenuAdd(menu, NULL, "test 1"); - MwMenuAdd(menu, m, "test 2"); - m = MwMenuAdd(menu, m, "test 3"); - MwMenuAdd(menu, m, "test 4"); - MwMenuAdd(menu, m, "test 6"); - MwMenuAdd(menu, NULL, "?test 5"); + m2 = MwMenuAdd(menu, m, "test 2"); + MwMenuAdd(menu, m2, "test 3"); + MwMenuAdd(menu, m2, "test 4"); + MwMenuAdd(menu, m2, "test 5"); + m2 = MwMenuAdd(menu, m, "test 6"); + MwMenuAdd(menu, m2, "test 7"); + MwMenuAdd(menu, m2, "test 8"); + MwMenuAdd(menu, NULL, "?test 9"); MwLoop(window); } diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index 2d1db43..db24282 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -74,6 +74,8 @@ MWDECL void MwLLDestroyPixmap(MwLLPixmap pixmap); MWDECL void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap); MWDECL void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap); +MWDECL void MwLLForceRender(MwLL handle); + #ifdef __cplusplus } #endif diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index e2aee5a..3ec853d 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -22,5 +22,6 @@ #define MwNactivateHandler "Cactivate" #define MwNresizeHandler "Cresize" #define MwNtickHandler "Ctick" +#define MwNmenuHandler "Cmenu" #endif diff --git a/src/backend/gdi.c b/src/backend/gdi.c index e1263a3..4ad1c1f 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -309,3 +309,7 @@ void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) { DestroyIcon(ico); } + +void MwLLForceRender(MwLL handle){ + InvalidateRect(handle->hWnd, NULL, FALSE); +} diff --git a/src/backend/x11.c b/src/backend/x11.c index f97f6bf..51c0c9b 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -327,3 +327,12 @@ void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) { free(icon); } + +void MwLLForceRender(MwLL handle){ + XEvent ev; + memset(&ev, 0, sizeof(ev)); + + ev.type = Expose; + ev.xexpose.window = handle->window; + XSendEvent(handle->display, handle->window, False, ExposureMask, &ev); +} diff --git a/src/widget/menu.c b/src/widget/menu.c index bdb5200..e5aa088 100644 --- a/src/widget/menu.c +++ b/src/widget/menu.c @@ -109,6 +109,8 @@ static void draw(MwWidget handle) { m->sub[i]->wsub = NULL; m->sub[i]->keep = 0; m->wait = 1; + }else if(arrlen(m->sub[i]->sub) == 0){ + MwDispatchUserHandler(handle, MwNmenuHandler, m->sub[i]); } } else if(!handle->pressed && m->sub[i]->wsub != NULL) { if(in_area) { diff --git a/src/widget/submenu.c b/src/widget/submenu.c index 159d5bf..619b3f1 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -51,11 +51,37 @@ static void draw(MwWidget handle) { int tw = MwTextWidth(handle, menu->sub[i]->name); int th = MwTextHeight(handle, menu->sub[i]->name); + if(menu->sub[i]->wsub != NULL){ + r.x = 0; + r.y = p.y - 3; + r.width = tw + 15 + 5 * 2; + r.height = th + 3 * 2; + MwDrawFrame(handle, &r, base, 0); + } + p.x = 5 + tw / 2; p.y += th / 2; MwDrawText(handle, &p, menu->sub[i]->name, 1, text); - p.y += th / 2; + + if(arrlen(menu->sub[i]->sub) > 0){ + MwPoint pl[3]; + + p.x = 5 + tw + 10; + + pl[0].x = p.x - 5; + pl[0].y = p.y - th / 2; + + pl[1].x = p.x - 5; + pl[1].y = p.y + th / 2; + + pl[2].x = p.x + 5; + pl[2].y = p.y; + + MwLLPolygon(handle->lowlevel, pl, 3, text); + } + + p.y += th / 2 + 5; } } @@ -69,42 +95,55 @@ static void click(MwWidget handle) { MwMenu menu = handle->internal; if(arrlen(menu->sub) > 0) { - int w = 0, i; + int ww = 0, i; MwRect rc; rc.x = 5; rc.y = 5; for(i = 0; i < arrlen(menu->sub); i++) { int tw = MwTextWidth(handle, menu->sub[i]->name); - if(tw > w) w = tw; + if(tw > ww) ww = tw; } - rc.width = w; + rc.width = ww + 15; for(i = 0; i < arrlen(menu->sub); i++) { int th = MwTextHeight(handle, menu->sub[i]->name); rc.height = th; - if(handle->mouse_point.x <= rc.x && handle->mouse_point.y <= rc.y && handle->mouse_point.x <= (int)(rc.x + rc.width) && handle->mouse_point.y <= (int)(rc.y + rc.height)) { - if(menu->sub[i]->wsub == NULL) { + if(rc.x <= handle->mouse_point.x && rc.y <= handle->mouse_point.y && handle->mouse_point.x <= (int)(rc.x + rc.width) && handle->mouse_point.y <= (int)(rc.y + rc.height)) { + if(menu->sub[i]->wsub == NULL && arrlen(menu->sub[i]->sub) > 0) { MwPoint p; + int j; + + for(j = 0; j < arrlen(menu->sub); j++){ + if(menu->sub[j]->wsub != NULL) MwDestroyWidget(menu->sub[j]->wsub); + menu->sub[j]->wsub = NULL; + } p.x = rc.x + rc.width + 5; - p.y = rc.y; + p.y = rc.y - 5; menu->sub[i]->wsub = MwCreateWidget(MwSubMenuClass, "submenu", handle, 0, 0, 0, 0); MwSubMenuAppear(menu->sub[i]->wsub, menu->sub[i], &p); + i = -1; + }else if(arrlen(menu->sub[i]->sub) == 0){ + while(w->parent->widget_class != MwMenuClass) w = w->parent; + MwGetBeforeStep(w, &jmp); + + MwDestroyWidget(w); + + MwLLForceRender(w->parent->lowlevel); + + MwDispatchUserHandler(w->parent, MwNmenuHandler, menu->sub[i]); + + longjmp(jmp, 1); + + break; } } - rc.y += rc.height; + rc.y += rc.height + 5; } - } else { - while(w->parent->widget_class != MwMenuClass) w = w->parent; - MwGetBeforeStep(w, &jmp); - - MwDestroyWidget(w); - - longjmp(jmp, 1); } } @@ -144,14 +183,14 @@ void MwSubMenuAppear(MwWidget handle, MwMenu menu, MwPoint* point) { for(i = 0; i < arrlen(menu->sub); i++) { int tw = MwTextWidth(handle, menu->sub[i]->name); - h += MwTextHeight(handle, menu->sub[i]->name); + h += MwTextHeight(handle, menu->sub[i]->name) + 5; if(tw > w) { w = tw; } } - w += 10; - h += 10; + w += 10 + 15; + h += 5; MwVaApply(handle, MwNwidth, w,