From 10fd79c54c0a2e570617856c8ae2c7f91c70647d Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Wed, 22 Oct 2025 17:30:57 +0000 Subject: [PATCH] better listbox functions git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@463 b9cfdab3-6d41-4d17-bbe4-086880011989 --- examples/basic/listbox.c | 27 +++++--- include/Mw/TypeDefs.h | 6 ++ include/Mw/Widget/ListBox.h | 62 +++++++++++------- milsko.xml | 49 +++++++++++--- src/filechooser.c | 70 ++++++++++---------- src/widget/listbox.c | 123 +++++++++++++++++++++--------------- 6 files changed, 208 insertions(+), 129 deletions(-) diff --git a/examples/basic/listbox.c b/examples/basic/listbox.c index 19476ea..438fa94 100644 --- a/examples/basic/listbox.c +++ b/examples/basic/listbox.c @@ -24,30 +24,37 @@ void activate(MwWidget handle, void* user, void* call) { } int main() { - MwWidget lb; - int len = sizeof(harvard) / sizeof(harvard[0]) - 1; - char** list = malloc(sizeof(*list) * len); - int i; + MwWidget lb; + int len = sizeof(harvard) / sizeof(harvard[0]) - 1; + int i; + MwListBoxPacket* packet; + int index; wmain = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 480, MwNtitle, "listbox", NULL); lb = MwCreateWidget(MwListBoxClass, "listbox", wmain, 5, 5, 630, 470); + packet = MwListBoxCreatePacket(); + index = MwListBoxPacketInsert(packet, -1); + MwListBoxPacketSet(packet, index, 0, "Harvard sentence"); + MwListBoxPacketSet(packet, index, 1, "Length"); + for(i = 0; i < len; i++) { - list[i] = malloc(16); - sprintf(list[i], "%d", (int)strlen(harvard[i])); + char sz[16]; + sprintf(sz, "%d", (int)strlen(harvard[i])); + index = MwListBoxPacketInsert(packet, -1); + MwListBoxPacketSet(packet, index, 0, harvard[i]); + MwListBoxPacketSet(packet, index, 1, sz); } MwAddUserHandler(lb, MwNactivateHandler, activate, NULL); - MwListBoxInsert(lb, -1, NULL, "Harvard sentences", "Length", NULL); - MwListBoxInsertMultiple(lb, -1, len, NULL, (char**)harvard, (char**)list, NULL); MwVaApply(lb, MwNhasHeading, 1, NULL); MwListBoxSetWidth(lb, 0, -64); + MwListBoxInsert(lb, -1, packet); - for(i = 0; i < len; i++) free(list[i]); - free(list); + MwListBoxDestroyPacket(packet); MwLoop(wmain); } diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index dba35e2..194c19a 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -24,6 +24,7 @@ typedef struct _MwListBox* MwListBox; typedef struct _MwListBoxEntry MwListBoxEntry; typedef struct _MwSizeHints MwSizeHints; typedef struct _MwDirectoryEntry MwDirectoryEntry; +typedef struct _MwListBoxPacket MwListBoxPacket; #ifdef _MILSKO typedef struct _MwWidget* MwWidget; #else @@ -165,6 +166,11 @@ struct _MwDirectoryEntry { time_t mtime; }; +struct _MwListBoxPacket { + MwLLPixmap* pixmaps; + char*** names; +}; + #define MwCursorDataHeight 16 struct _MwCursor { int width; diff --git a/include/Mw/Widget/ListBox.h b/include/Mw/Widget/ListBox.h index b9da53f..eb372f5 100644 --- a/include/Mw/Widget/ListBox.h +++ b/include/Mw/Widget/ListBox.h @@ -19,33 +19,51 @@ extern "C" { */ MWDECL MwClass MwListBoxClass; +/*! + * %brief Creates a listbox packet + * %return Packet + */ +MWDECL MwListBoxPacket* MwListBoxCreatePacket(void); + +/*! + * %brief Destroys a listbox packet + * %param packet Packet + */ +MWDECL void MwListBoxDestroyPacket(MwListBoxPacket* packet); + +/*! + * %brief Inserts a new item to a packet + * %param packet Packet + * %param index Index + * %return Index + */ +MWDECL int MwListBoxPacketInsert(MwListBoxPacket* packet, int index); + +/*! + * %brief Sets a column of item in a packet + * %param packet Packet + * %param index Index + * %param col Column + * %param text Text + */ +MWDECL void MwListBoxPacketSet(MwListBoxPacket* packet, int index, int col, const char* text); + +/*! + * %brief Sets an icon of item in a packet + * %param packet Packet + * %param index Index + * %param icon Icon + */ +MWDECL void MwListBoxPacketSetIcon(MwListBoxPacket* packet, int index, MwLLPixmap icon); + /*! * %brief Inserts item on the listbox * %param handle Widget * %param index Index - * %param pixmap Pixmap - * %param ... Text + * %param packet Packet */ -MwInline void MwListBoxInsert(MwWidget handle, int index, MwLLPixmap pixmap, ...) { - va_list va; - va_start(va, pixmap); - MwVaWidgetExecute(handle, "mwListBoxInsert", NULL, index, pixmap, &va); - va_end(va); -} - -/*! - * %brief Inserts multiple items on the listbox - * %param handle Widget - * %param index Index - * %param count Count - * %param pixmap Pixmap - * %param ... Text - */ -MwInline void MwListBoxInsertMultiple(MwWidget handle, int index, int count, MwLLPixmap* pixmap, ...) { - va_list va; - va_start(va, pixmap); - MwVaWidgetExecute(handle, "mwListBoxInsertMultiple", NULL, index, count, pixmap, &va); - va_end(va); +MwInline void MwListBoxInsert(MwWidget handle, int index, void* packet) { + MwVaWidgetExecute(handle, "mwListBoxInsert", NULL, index, packet); } /*! diff --git a/milsko.xml b/milsko.xml index 99aeb3c..9e8053b 100644 --- a/milsko.xml +++ b/milsko.xml @@ -324,6 +324,44 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -392,16 +430,7 @@ - - - - - - - - - - + diff --git a/src/filechooser.c b/src/filechooser.c index deea908..dc08366 100644 --- a/src/filechooser.c +++ b/src/filechooser.c @@ -168,11 +168,20 @@ static void layout(MwWidget handle) { ww = 160; wh = h - 10 - 24 - 5 - 24 - 5 - 24 - 5; if(fc->nav == NULL) { + MwListBoxPacket* p = MwListBoxCreatePacket(); + int index; + + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSet(p, index, 0, "Home"); + MwListBoxPacketSetIcon(p, index, fc->computer); + fc->nav = MwVaCreateWidget(MwListBoxClass, "nav", handle, wx, wy, ww, wh, MwNleftPadding, 16, NULL); - MwListBoxInsert(fc->nav, -1, fc->computer, "Home", NULL); + MwListBoxInsert(fc->nav, -1, p); MwAddUserHandler(fc->nav, MwNactivateHandler, nav_activate, NULL); + + MwListBoxDestroyPacket(p); } else { MwVaApply(fc->nav, MwNx, wx, @@ -357,13 +366,11 @@ static int qsort_files(const void* a, const void* b) { } static void scan(MwWidget handle, const char* path, int record) { - filechooser_t* fc = handle->opaque; - void* dir = MwDirectoryOpen(path); - int i; - char** names = NULL; - char** dates = NULL; - char** sizes = NULL; - MwLLPixmap* icons = NULL; + filechooser_t* fc = handle->opaque; + void* dir = MwDirectoryOpen(path); + int i; + MwListBoxPacket* p = MwListBoxCreatePacket(); + int index; if(dir != NULL) { MwDirectoryEntry* entry; @@ -403,57 +410,50 @@ static void scan(MwWidget handle, const char* path, int record) { NULL); MwListBoxReset(fc->files); - MwListBoxInsert(fc->files, -1, NULL, "Name", "Date modified", "Size", NULL); MwListBoxSetWidth(fc->files, 0, -128 - 96); MwListBoxSetWidth(fc->files, 1, 128); MwListBoxSetWidth(fc->files, 2, 0); - icons = NULL; - names = NULL; - dates = NULL; - sizes = NULL; + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSet(p, index, -1, "Name"); + MwListBoxPacketSet(p, index, -1, "Date modified"); + MwListBoxPacketSet(p, index, -1, "Size"); + for(i = 0; i < arrlen(fc->entries); i++) { if(strcmp(fc->entries[i]->name, ".") == 0 || strcmp(fc->entries[i]->name, "..") == 0) continue; if(fc->entries[i]->type == MwDIRECTORY_DIRECTORY) { - char* date = malloc(128); + char date[128]; MwStringTime(date, fc->entries[i]->mtime); - arrput(names, fc->entries[i]->name); - arrput(dates, date); - arrput(sizes, NULL); - arrput(icons, fc->dir); + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSetIcon(p, index, fc->dir); + MwListBoxPacketSet(p, index, -1, fc->entries[i]->name); + MwListBoxPacketSet(p, index, -1, date); + MwListBoxPacketSet(p, index, -1, NULL); arrput(fc->sorted_entries, fc->entries[i]); } } for(i = 0; i < arrlen(fc->entries); i++) { if(fc->entries[i]->type == MwDIRECTORY_FILE) { - char* date = malloc(128); - char* size = malloc(128); + char date[128]; + char size[128]; MwStringTime(date, fc->entries[i]->mtime); MwStringSize(size, fc->entries[i]->size); - arrput(names, fc->entries[i]->name); - arrput(dates, date); - arrput(sizes, size); - arrput(icons, fc->file); + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSetIcon(p, index, fc->file); + MwListBoxPacketSet(p, index, -1, fc->entries[i]->name); + MwListBoxPacketSet(p, index, -1, date); + MwListBoxPacketSet(p, index, -1, size); arrput(fc->sorted_entries, fc->entries[i]); } } - MwListBoxInsertMultiple(fc->files, -1, arrlen(names), icons, names, dates, sizes, NULL); - for(i = 0; i < arrlen(dates); i++) { - if(dates[i] != NULL) free(dates[i]); - } - for(i = 0; i < arrlen(sizes); i++) { - if(sizes[i] != NULL) free(sizes[i]); - } - arrfree(sizes); - arrfree(dates); - arrfree(names); - arrfree(icons); + MwListBoxInsert(fc->files, -1, p); + MwListBoxDestroyPacket(p); } MwWidget MwFileChooser(MwWidget handle, const char* title) { diff --git a/src/widget/listbox.c b/src/widget/listbox.c index 653d06e..26fe6c6 100644 --- a/src/widget/listbox.c +++ b/src/widget/listbox.c @@ -3,6 +3,56 @@ #include "../../external/stb_ds.h" +MwListBoxPacket* MwListBoxCreatePacket(void) { + MwListBoxPacket* packet = malloc(sizeof(*packet)); + memset(packet, 0, sizeof(*packet)); + + return packet; +} + +void MwListBoxDestroyPacket(MwListBoxPacket* packet) { + int i; + + for(i = 0; i < arrlen(packet->names); i++) { + } + + arrfree(packet->names); + arrfree(packet->pixmaps); + + free(packet); +} + +int MwListBoxPacketInsert(MwListBoxPacket* packet, int index) { + int i; + + if(index == -1) index = arrlen(packet->names); + for(i = arrlen(packet->names); i < index; i++) { + arrput(packet->names, NULL); + arrput(packet->pixmaps, NULL); + } + + arrins(packet->names, index, NULL); + arrins(packet->pixmaps, index, NULL); + + return index; +} + +void MwListBoxPacketSet(MwListBoxPacket* packet, int index, int col, const char* text) { + char* t = text == NULL ? NULL : MwStringDupliacte(text); + int i; + + if(col == -1) col = arrlen(packet->names[index]); + for(i = arrlen(packet->names[index]); i < col; i++) { + arrput(packet->names[index], NULL); + } + + arrins(packet->names[index], col, t); +} + +void MwListBoxPacketSetIcon(MwListBoxPacket* packet, int index, MwLLPixmap icon) { + packet->pixmaps[index] = icon; +} + static int get_first_entry(MwWidget handle, MwListBox lb) { int st = 0; int y = MwGetInteger(handle, MwNhasHeading) ? 1 : 0; @@ -172,8 +222,12 @@ static void frame_draw(MwWidget handle) { p.y += MwTextHeight(handle, "M") / 2; p.x = MwGetInteger(handle->parent, MwNleftPadding); for(j = 0; j < arrlen(lb->list[i].name); j++) { + char* t = lb->list[i].name[j]; + + if(t == NULL) t = ""; + p.x += MwDefaultBorderWidth; - MwDrawText(handle, &p, lb->list[i].name[j], 0, MwALIGNMENT_BEGINNING, selected ? base : text); + MwDrawText(handle, &p, t, 0, MwALIGNMENT_BEGINNING, selected ? base : text); p.x += get_col_width(lb, j) - MwDefaultBorderWidth; if(j == 0) p.x -= MwGetInteger(handle->parent, MwNleftPadding); @@ -312,62 +366,39 @@ static void prop_change(MwWidget handle, const char* prop) { } } -static void mwListBoxInsertImpl(MwWidget handle, int index, MwLLPixmap pixmap, va_list va) { - MwListBox lb = handle->internal; - MwListBoxEntry entry; - char* name; - - entry.name = NULL; - while((name = va_arg(va, char*)) != NULL) { - name = MwStringDupliacte(name); - arrput(entry.name, name); - } - - entry.pixmap = pixmap; - - if(index == -1) index = arrlen(lb->list); - arrins(lb->list, index, entry); - - resize(handle); - if(index < (MwGetInteger(lb->vscroll, MwNvalue) + MwGetInteger(lb->vscroll, MwNareaShown))) { - MwForceRender(lb->frame); - } -} - -static void mwListBoxInsertMultipleImpl(MwWidget handle, int index, int count, MwLLPixmap* pixmap, va_list va) { +static void mwListBoxInsertImpl(MwWidget handle, int index, MwListBoxPacket* packet) { int i; MwListBox lb = handle->internal; int old; - char*** vlist = NULL; - char** list; + int max = 0; if(index == -1) index = arrlen(lb->list); old = index; - while((list = va_arg(va, char**)) != NULL) { - arrput(vlist, list); + for(i = 0; i < arrlen(packet->names); i++) { + if(arrlen(packet->names[i]) > max) max = arrlen(packet->names[i]); } - for(i = 0; i < count; i++) { + for(i = 0; i < arrlen(packet->names); i++) { MwListBoxEntry entry; char* name; int j; entry.name = NULL; - for(j = 0; j < arrlen(vlist); j++) { - if(vlist[j][i] == NULL) continue; - name = MwStringDupliacte(vlist[j][i]); - arrput(entry.name, name); + for(j = 0; j < max; j++) { + if(arrlen(packet->names[i]) > j && packet->names[i][j] != NULL) { + name = MwStringDupliacte(packet->names[i][j]); + arrput(entry.name, name); + } else { + arrput(entry.name, NULL); + } } - entry.pixmap = NULL; - if(pixmap != NULL) entry.pixmap = pixmap[i]; + entry.pixmap = packet->pixmaps[i]; arrins(lb->list, index, entry); index++; } - arrfree(vlist); - resize(handle); if(old < (MwGetInteger(lb->vscroll, MwNvalue) + MwGetInteger(lb->vscroll, MwNareaShown))) { MwForceRender(lb->frame); @@ -456,21 +487,9 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v mwListBoxSetWidthImpl(handle, index, width); } if(strcmp(name, "mwListBoxInsert") == 0) { - int index = va_arg(va, int); - MwLLPixmap pixmap = va_arg(va, MwLLPixmap); - va_list* pva = va_arg(va, va_list*); - va_list va; - memcpy(&va, pva, sizeof(va)); - mwListBoxInsertImpl(handle, index, pixmap, va); - } - if(strcmp(name, "mwListBoxInsertMultiple") == 0) { - int index = va_arg(va, int); - int count = va_arg(va, int); - MwLLPixmap* pixmap = va_arg(va, MwLLPixmap*); - va_list* pva = va_arg(va, va_list*); - va_list va; - memcpy(&va, pva, sizeof(va)); - mwListBoxInsertMultipleImpl(handle, index, count, pixmap, va); + int index = va_arg(va, int); + MwListBoxPacket* packet = va_arg(va, MwListBoxPacket*); + mwListBoxInsertImpl(handle, index, packet); } }