From fef5fceea9d7bd0dfa149f3bb7dbae0b21145075 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Wed, 12 Nov 2025 19:18:15 +0000 Subject: [PATCH] seems to work git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@677 b9cfdab3-6d41-4d17-bbe4-086880011989 --- include/Mw/StringDefs.h | 3 +- include/Mw/TypeDefs.h | 7 ++-- include/Mw/Widget/ComboBox.h | 15 +++++++- milsko.xml | 3 ++ src/widget/combobox.c | 66 ++++++++++++++++++++++++++++++++++-- src/widget/listbox.c | 5 +-- src/widget/submenu.c | 2 -- 7 files changed, 90 insertions(+), 11 deletions(-) diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index f180d2e..262e38a 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -27,6 +27,7 @@ #define MwNmodernLook "ImodernLook" #define MwNwaitMS "IwaitMS" #define MwNhideInput "IhideInput" +#define MwNsingleClickSelectable "IsingleClickSelectable" #define MwNtitle "Stitle" #define MwNtext "Stext" @@ -46,7 +47,7 @@ #define MwNmouseDownHandler "CmouseDown" /* MwLLMouse* */ #define MwNmouseUpHandler "CmouseUp" /* same as MwNmouseDownHandler */ #define MwNmouseMoveHandler "CmouseMove" /* MwPoint* */ -#define MwNchangedHandler "Cchanged" /* NULL */ +#define MwNchangedHandler "Cchanged" /* NULL/int* (MwComboBox) */ #define MwNkeyHandler "Ckey" /* int* (MwLLKeyEnum or character code) */ #define MwNkeyReleaseHandler "CkeyRelease" /* same as MwNkeyHandler */ #define MwNcloseHandler "Cclose" /* NULL */ diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index 093a179..2767b3f 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -131,9 +131,10 @@ struct _MwListBox { }; struct _MwComboBox { - char** list; - int opened; - int selected; + char** list; + int opened; + int selected; + MwWidget listbox; }; struct _MwDirectoryEntry { diff --git a/include/Mw/Widget/ComboBox.h b/include/Mw/Widget/ComboBox.h index 1918c98..24362f6 100644 --- a/include/Mw/Widget/ComboBox.h +++ b/include/Mw/Widget/ComboBox.h @@ -19,7 +19,7 @@ extern "C" { MWDECL MwClass MwComboBoxClass; /*! - * @brief Adds the entry to ComboBox + * @brief Adds the entry to combobox * @param handle Widget * @param index Index * @param text Text @@ -28,6 +28,19 @@ MwInline void MwComboBoxAdd(MwWidget handle, int index, const char* text) { MwVaWidgetExecute(handle, "mwComboBoxAdd", NULL, index, text); } +/*! + * @brief Gets the entry from combobox + * @param handle Widget + * @param index Index + * @return Text + */ +MwInline const char* MwComboBoxGet(MwWidget handle, int index) { + const char* text; + MwVaWidgetExecute(handle, "mwComboBoxGet", (void*)&text, index); + + return text; +} + #ifdef __cplusplus } #endif diff --git a/milsko.xml b/milsko.xml index af5d12b..bc81928 100644 --- a/milsko.xml +++ b/milsko.xml @@ -63,6 +63,7 @@ + @@ -459,6 +460,8 @@ + + diff --git a/src/widget/combobox.c b/src/widget/combobox.c index 98c7aeb..62a1084 100644 --- a/src/widget/combobox.c +++ b/src/widget/combobox.c @@ -9,6 +9,7 @@ static int create(MwWidget handle) { cb->list = NULL; cb->opened = 0; cb->selected = 0; + cb->listbox = NULL; handle->internal = cb; MwSetDefault(handle); @@ -49,7 +50,7 @@ static void draw(MwWidget handle) { p.x = MwDefaultBorderWidth(handle) * 2; p.y = MwGetInteger(handle, MwNheight) / 2; - MwDrawText(handle, &p, cb->list[0], 0, MwALIGNMENT_BEGINNING, text); + MwDrawText(handle, &p, cb->list[cb->selected], 0, MwALIGNMENT_BEGINNING, text); } r = rc; @@ -76,14 +77,66 @@ static void draw(MwWidget handle) { MwLLFreeColor(base); } +static void listbox_activate(MwWidget handle, void* user, void* client) { + MwComboBox cb = handle->parent->internal; + + (void)user; + + cb->selected = *(int*)client; + cb->opened = 0; + cb->listbox = NULL; + + MwForceRender(handle->parent); + + MwDispatchUserHandler(handle->parent, MwNchangedHandler, client); + + MwDestroyWidget(handle); +} + static void click(MwWidget handle) { MwComboBox cb = handle->internal; cb->opened = cb->opened ? 0 : 1; if(cb->opened) { + MwPoint p; + int i; + void* packet; + int width = MwGetInteger(handle, MwNwidth); + MwLLSetCursor(handle->lowlevel, &MwCursorArrow, &MwCursorArrowMask); + + for(i = 0; i < arrlen(cb->list); i++) { + int l = MwTextWidth(handle, cb->list[i]) + MwDefaultBorderWidth(handle) * 2; + if(l > width) width = l; + } + + cb->listbox = MwVaCreateWidget(MwListBoxClass, "listbox", handle, 0, 0, width, MwTextHeight(handle, "M") * 6 + MwDefaultBorderWidth(handle) * 2, + MwNsingleClickSelectable, 1, + NULL); + MwLLShow(cb->listbox->lowlevel, 0); + + packet = MwListBoxCreatePacket(); + for(i = 0; i < arrlen(cb->list); i++) { + int index = MwListBoxPacketInsert(packet, -1); + MwListBoxPacketSet(packet, index, 0, cb->list[i]); + } + MwListBoxInsert(cb->listbox, -1, packet); + MwListBoxDestroyPacket(packet); + + MwAddUserHandler(cb->listbox, MwNactivateHandler, listbox_activate, NULL); + + p.x = 0; + p.y = MwGetInteger(handle, MwNheight); + MwLLDetach(cb->listbox->lowlevel, &p); + MwLLMakeToolWindow(cb->listbox->lowlevel); + MwLLShow(cb->listbox->lowlevel, 1); } else { MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask); + + if(cb->listbox != NULL) { + MwDestroyWidget(cb->listbox); + cb->listbox = NULL; + } } MwForceRender(handle); @@ -100,13 +153,22 @@ static void mwComboBoxAddImpl(MwWidget handle, int index, const char* text) { if(index <= cb->selected) MwForceRender(handle); } +static const char* mwComboBoxGetImpl(MwWidget handle, int index) { + MwComboBox cb = handle->internal; + + return cb->list[index]; +} + static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { - (void)out; if(strcmp(name, "mwComboBoxAdd") == 0) { int index = va_arg(va, int); const char* text = va_arg(va, const char*); mwComboBoxAddImpl(handle, index, text); } + if(strcmp(name, "mwComboBoxGet") == 0) { + int index = va_arg(va, int); + *(const char**)out = mwComboBoxGetImpl(handle, index); + } } MwClassRec MwComboBoxClassRec = { diff --git a/src/widget/listbox.c b/src/widget/listbox.c index 448efa0..4eccee1 100644 --- a/src/widget/listbox.c +++ b/src/widget/listbox.c @@ -135,7 +135,7 @@ static void frame_mouse_down(MwWidget handle, void* user, void* call) { lb->selected = st + i; - if(((t = MwTimeGetTick()) - lb->click_time) < 250 && old == st + i) { + if((((t = MwTimeGetTick()) - lb->click_time) < 250 && old == st + i) || MwGetInteger(handle->parent, MwNsingleClickSelectable)) { MwDispatchUserHandler(handle->parent, MwNactivateHandler, &lb->selected); } @@ -307,7 +307,8 @@ static int create(MwWidget handle) { MwSetDefault(handle); - MwSetInteger(handle, MwNleftPadding, 0); + MwSetInteger(handle, MwNsingleClickSelectable, 0); + MwSetInteger(handle, MwNhasHeading, 0); MwSetInteger(handle, MwNhasHeading, 0); resize(handle); diff --git a/src/widget/submenu.c b/src/widget/submenu.c index 09938d5..bd116db 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -166,9 +166,7 @@ static void mwSubMenuAppearImpl(MwWidget handle, MwMenu menu, MwPoint* point) { handle->internal = menu; MwLLDetach(handle->lowlevel, point); - MwLLMakeToolWindow(handle->lowlevel); - MwLLShow(handle->lowlevel, 1); for(i = 0; i < arrlen(menu->sub); i++) {