From 06b2178ecc5af46817a9e0b60c785d45760daf57 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Fri, 3 Oct 2025 16:13:11 +0000 Subject: [PATCH] menu works on windows git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@139 b9cfdab3-6d41-4d17-bbe4-086880011989 --- examples/example.c | 9 ++++-- src/backend/gdi.c | 8 +++++- src/backend/x11.c | 4 +-- src/widget/menu.c | 2 +- src/widget/submenu.c | 66 ++++++++++++++++++++++++++++++-------------- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/examples/example.c b/examples/example.c index 18eec4a..215ee50 100644 --- a/examples/example.c +++ b/examples/example.c @@ -74,7 +74,7 @@ int main() { MwAddUserHandler(button3, MwNactivateHandler, handler, NULL); MwAddUserHandler(button4, MwNactivateHandler, handler, NULL); - m = MwMenuAdd(menu, NULL, "test 1"); + m = MwMenuAdd(menu, NULL, "test 1"); m2 = MwMenuAdd(menu, m, "test 2"); MwMenuAdd(menu, m2, "test 3"); MwMenuAdd(menu, m2, "test 4"); @@ -82,7 +82,12 @@ int main() { m2 = MwMenuAdd(menu, m, "test 6"); MwMenuAdd(menu, m2, "test 7"); MwMenuAdd(menu, m2, "test 8"); - MwMenuAdd(menu, NULL, "?test 9"); + m2 = MwMenuAdd(menu, m, "test 9"); + MwMenuAdd(menu, m2, "test 10"); + m2 = MwMenuAdd(menu, m2, "test 11"); + MwMenuAdd(menu, m2, "test 12"); + MwMenuAdd(menu, m2, "test 13"); + MwMenuAdd(menu, NULL, "?test 14"); MwLoop(window); } diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 4ad1c1f..e608a86 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -56,6 +56,12 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { SetCapture(NULL); MwLLDispatch(u->ll, up, &p); InvalidateRect(hWnd, NULL, FALSE); + } else if(msg == WM_MOUSEMOVE) { + MwPoint p; + p.x = LOWORD(lp); + p.y = HIWORD(lp); + + MwLLDispatch(u->ll, move, &p); } else if(msg == WM_SIZE) { MwLLDispatch(u->ll, resize, NULL); } else if(msg == WM_ERASEBKGND) { @@ -310,6 +316,6 @@ void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) { DestroyIcon(ico); } -void MwLLForceRender(MwLL handle){ +void MwLLForceRender(MwLL handle) { InvalidateRect(handle->hWnd, NULL, FALSE); } diff --git a/src/backend/x11.c b/src/backend/x11.c index 51c0c9b..bc983e1 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -328,11 +328,11 @@ void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) { free(icon); } -void MwLLForceRender(MwLL handle){ +void MwLLForceRender(MwLL handle) { XEvent ev; memset(&ev, 0, sizeof(ev)); - ev.type = Expose; + 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 e5aa088..06b3fb3 100644 --- a/src/widget/menu.c +++ b/src/widget/menu.c @@ -109,7 +109,7 @@ 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){ + } else if(arrlen(m->sub[i]->sub) == 0) { MwDispatchUserHandler(handle, MwNmenuHandler, m->sub[i]); } } else if(!handle->pressed && m->sub[i]->wsub != NULL) { diff --git a/src/widget/submenu.c b/src/widget/submenu.c index 619b3f1..b18eeaa 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -45,16 +45,16 @@ static void draw(MwWidget handle) { int i; p.x = 0; - p.y = 5; + p.y = 3; for(i = 0; i < arrlen(menu->sub); i++) { 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; + 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); } @@ -64,7 +64,7 @@ static void draw(MwWidget handle) { p.y += th / 2; MwDrawText(handle, &p, menu->sub[i]->name, 1, text); - if(arrlen(menu->sub[i]->sub) > 0){ + if(arrlen(menu->sub[i]->sub) > 0) { MwPoint pl[3]; p.x = 5 + tw + 10; @@ -81,7 +81,7 @@ static void draw(MwWidget handle) { MwLLPolygon(handle->lowlevel, pl, 3, text); } - p.y += th / 2 + 5; + p.y += th / 2 + 3; } } @@ -99,7 +99,7 @@ static void click(MwWidget handle) { MwRect rc; rc.x = 5; - rc.y = 5; + rc.y = 3; for(i = 0; i < arrlen(menu->sub); i++) { int tw = MwTextWidth(handle, menu->sub[i]->name); if(tw > ww) ww = tw; @@ -113,36 +113,45 @@ static void click(MwWidget handle) { 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; + int j; - for(j = 0; j < arrlen(menu->sub); 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 - 5; + p.x = rc.x + rc.width + 3; + p.y = rc.y - 3; 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){ + } else if(menu->sub[i]->wsub != NULL && arrlen(menu->sub[i]->sub) > 0) { + MwDestroyWidget(menu->sub[i]->wsub); + menu->sub[i]->wsub = NULL; + + MwLLForceRender(handle->lowlevel); + } else if(arrlen(menu->sub[i]->sub) == 0) { + MwWidget p; + while(w->parent->widget_class != MwMenuClass) w = w->parent; MwGetBeforeStep(w, &jmp); - + + p = w->parent; + MwDestroyWidget(w); - MwLLForceRender(w->parent->lowlevel); + MwLLForceRender(p->lowlevel); + + MwDispatchUserHandler(p, MwNmenuHandler, menu->sub[i]); - MwDispatchUserHandler(w->parent, MwNmenuHandler, menu->sub[i]); - longjmp(jmp, 1); break; } } - rc.y += rc.height + 5; + rc.y += rc.height + 3; } } } @@ -159,6 +168,23 @@ MwClass MwSubMenuClass = &MwSubMenuClassRec; void MwSubMenuAppear(MwWidget handle, MwMenu menu, MwPoint* point) { int i, w = 0, h = 0; #ifdef _WIN32 + RECT rc; + + SetWindowLongPtr(handle->lowlevel->hWnd, GWL_STYLE, (LONG_PTR)WS_POPUP); + + GetWindowRect(handle->parent->lowlevel->hWnd, &rc); + + SetParent(handle->lowlevel->hWnd, NULL); + + rc.left += point->x; + rc.top += point->y; + + SetWindowPos(handle->lowlevel->hWnd, NULL, rc.left, rc.top, 1, 1, SWP_NOREDRAW); + + ShowWindow(handle->lowlevel->hWnd, SW_NORMAL); + UpdateWindow(handle->lowlevel->hWnd); + + SetFocus(handle->lowlevel->hWnd); #else Atom wndtype = XInternAtom(handle->lowlevel->display, "_NET_WM_WINDOW_TYPE", False); Atom wndmenu = XInternAtom(handle->lowlevel->display, "_NET_WM_WINDOW_TYPE_MENU", False); @@ -183,14 +209,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) + 5; + h += MwTextHeight(handle, menu->sub[i]->name) + 3; if(tw > w) { w = tw; } } w += 10 + 15; - h += 5; + h += 3; MwVaApply(handle, MwNwidth, w,