From 2ed6053819da58155fc56dda2f8cc04b170dca52 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Wed, 19 Nov 2025 14:06:56 +0000 Subject: [PATCH] almost git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@758 b9cfdab3-6d41-4d17-bbe4-086880011989 --- include/Mw/TypeDefs.h | 16 ++-- src/dialog/messagebox.c | 2 +- src/draw.c | 2 +- src/widget/scrollbar.c | 1 + src/widget/treeview.c | 165 +++++++++++++++++++++++++--------------- 5 files changed, 114 insertions(+), 72 deletions(-) diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index 2745c44..213dca4 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -21,7 +21,7 @@ typedef struct _MwListBox* MwListBox; typedef struct _MwComboBox* MwComboBox; typedef struct _MwTreeView* MwTreeView; typedef struct _MwListBoxEntry MwListBoxEntry; -typedef struct _MwTreeViewEntry MwTreeViewEntry; +typedef struct _MwTreeViewEntry MwTreeViewEntry; typedef struct _MwDirectoryEntry MwDirectoryEntry; typedef struct _MwListBoxPacket MwListBoxPacket; #ifdef _MILSKO @@ -140,17 +140,19 @@ struct _MwComboBox { }; struct _MwTreeViewEntry { - char* label; - MwLLPixmap pixmap; + char* label; + MwLLPixmap pixmap; MwTreeViewEntry* tree; - int opened; + int opened; }; struct _MwTreeView { - MwWidget frame; - MwWidget vscroll; - int changed; + MwWidget frame; + MwWidget vscroll; + int changed; MwTreeViewEntry* tree; + + MwPoint pressed; }; struct _MwDirectoryEntry { diff --git a/src/dialog/messagebox.c b/src/dialog/messagebox.c index 2685a4d..bdae35c 100644 --- a/src/dialog/messagebox.c +++ b/src/dialog/messagebox.c @@ -48,7 +48,7 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi sh.min_width = sh.max_width = w; sh.min_height = sh.max_height = h; - window = MwVaCreateWidget(MwWindowClass, "messagebox", window, wx, wy, w, h, + window = MwVaCreateWidget(MwWindowClass, "messagebox", NULL, wx, wy, w, h, MwNtitle, title, MwNsizeHints, &sh, NULL); diff --git a/src/draw.c b/src/draw.c index 5283bb3..fd3541f 100644 --- a/src/draw.c +++ b/src/draw.c @@ -132,7 +132,7 @@ void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { } else { int diff = get_color_diff(handle) / 3 * 2; - MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle) / 2, -diff, (handle->parent == NULL || handle->parent->lowlevel == NULL) ? 1 : 0); + MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle) / 2, -diff, (handle->parent == NULL || handle->parent->lowlevel == NULL) ? 1 : 0); MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle) / 2, diff, 0); } } diff --git a/src/widget/scrollbar.c b/src/widget/scrollbar.c index 9586af0..a26e1b1 100644 --- a/src/widget/scrollbar.c +++ b/src/widget/scrollbar.c @@ -212,6 +212,7 @@ static void mouse_down(MwWidget handle, void* ptr) { static void prop_change(MwWidget handle, const char* key) { if(strcmp(key, MwNminValue) == 0 || strcmp(key, MwNvalue) == 0 || strcmp(key, MwNmaxValue) == 0 || strcmp(key, MwNareaShown) == 0) { + if(MwGetInteger(handle, MwNvalue) > MwGetInteger(handle, MwNmaxValue)) MwSetInteger(handle, MwNvalue, MwGetInteger(handle, MwNmaxValue)); if(handle->prop_event) MwDispatchUserHandler(handle, MwNchangedHandler, NULL); MwForceRender(handle); } diff --git a/src/widget/treeview.c b/src/widget/treeview.c index e3aae36..1a34923 100644 --- a/src/widget/treeview.c +++ b/src/widget/treeview.c @@ -15,52 +15,58 @@ static void vscroll_changed(MwWidget handle, void* user, void* call) { tv->changed = 1; } -static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwLLColor base, MwLLColor text, MwPoint* p, int next, int shift, int* skip, int* shared){ - int i; +static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwLLColor base, MwLLColor text, MwPoint* p, int next, int shift, int* skip, int* shared, int draw, MwPoint* mouse) { + int i; MwPoint l[2]; - int skipped = 0; - if((*skip) > 0){ + int skipped = 0; + if((*skip) > 0) { (*skip)--; skipped = 1; if(p->y == MwDefaultBorderWidth(handle)) p->y -= MwTextHeight(handle, "M"); - }else if((*shared) < (MwGetInteger(handle, MwNheight) / MwTextHeight(handle, "M") + 2)){ - MwRect r; + } else if((*shared) < (MwGetInteger(handle, MwNheight) / MwTextHeight(handle, "M") + 2)) { + MwRect r; p->x += shift; p->y += MwTextHeight(handle, "M") / 2; - if(shift > 0){ + if(shift > 0) { l[0] = *p; l[0].x -= LineSpace / 2; l[1] = *p; - MwLLLine(handle->lowlevel, &l[0], text); - + if(draw) MwLLLine(handle->lowlevel, &l[0], text); + l[0] = *p; l[0].x -= LineSpace / 2; l[1] = l[0]; l[0].y -= MwTextHeight(handle, "M") / 2; - if(next){ + if(next) { l[1].y += MwTextHeight(handle, "M") / 2; } - MwLLLine(handle->lowlevel, &l[0], text); + if(draw) MwLLLine(handle->lowlevel, &l[0], text); } - if(tree->tree != NULL){ - r.width = OpenerSize; + if(tree->tree != NULL) { + r.width = OpenerSize; r.height = OpenerSize; - r.x = p->x - LineSpace + (LineSpace - r.width) / 2; - r.y = p->y - MwTextHeight(handle, "M") / 2 + (MwTextHeight(handle, "M") - r.height) / 2; - MwDrawWidgetBack(handle, &r, base, tree->opened, 1); + r.x = p->x - LineSpace + (LineSpace - r.width) / 2; + r.y = p->y - MwTextHeight(handle, "M") / 2 + (MwTextHeight(handle, "M") - r.height) / 2; + if(draw) { + MwDrawWidgetBack(handle, &r, base, tree->opened, 1); + } else if(shift != 0) { + if(r.x <= mouse->x && mouse->x <= (r.x + r.width) && r.y <= mouse->y && mouse->y <= (r.y + r.height)) { + tree->opened = tree->opened ? 0 : 1; + } + } } - if(tree->pixmap != NULL){ + if(tree->pixmap != NULL) { r.height = MwTextHeight(handle, "M"); - r.width = r.height * tree->pixmap->common.width / tree->pixmap->common.height; - r.x = p->x; - r.y = p->y - MwTextHeight(handle, "M") / 2; + r.width = r.height * tree->pixmap->common.width / tree->pixmap->common.height; + r.x = p->x; + r.y = p->y - MwTextHeight(handle, "M") / 2; - MwLLDrawPixmap(handle->lowlevel, &r, tree->pixmap); + if(draw) MwLLDrawPixmap(handle->lowlevel, &r, tree->pixmap); } p->x += MwGetInteger(handle->parent, MwNleftPadding); - MwDrawText(handle, p, tree->label, 0, MwALIGNMENT_BEGINNING, text); + if(draw) MwDrawText(handle, p, tree->label, 0, MwALIGNMENT_BEGINNING, text); p->x -= MwGetInteger(handle->parent, MwNleftPadding); p->y += MwTextHeight(handle, "M") / 2; @@ -69,63 +75,94 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwLLColor base, Mw (*shared)++; } if(!tree->opened) return; - for(i = 0; i < arrlen(tree->tree); i++){ + for(i = 0; i < arrlen(tree->tree); i++) { l[0] = *p; l[0].x += shift + LineSpace / 2; l[0].y += MwTextHeight(handle, "M") - (MwTextHeight(handle, "M") - OpenerSize) / 2; - recursion(handle, &tree->tree[i], base, text, p, i != (arrlen(tree->tree) - 1) ? 1 : 0, shift + LineSpace, skip, shared); + recursion(handle, &tree->tree[i], base, text, p, i != (arrlen(tree->tree) - 1) ? 1 : 0, shift + LineSpace, skip, shared, draw, mouse); l[1] = *p; l[1].x += shift + LineSpace / 2; - if(skipped && p->y > l[0].y){ + if(skipped && p->y > l[0].y) { skipped = 0; } - if(!skipped && i != (arrlen(tree->tree) - 1)) MwLLLine(handle->lowlevel, &l[0], text); - + if(draw && !skipped && i != (arrlen(tree->tree) - 1)) MwLLLine(handle->lowlevel, &l[0], text); } } static void frame_draw(MwWidget handle) { - MwRect r; - MwTreeView tv = handle->parent->internal; - MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); - MwPoint p; - int shared = 0; - int i; - int skip = MwGetInteger(tv->vscroll, MwNvalue) * (MwGetInteger(tv->vscroll, MwNmaxValue) - MwGetInteger(tv->vscroll, MwNareaShown)) / MwGetInteger(tv->vscroll, MwNmaxValue); + MwRect r; + MwTreeView tv = handle->parent->internal; + MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); + MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); + MwPoint p; + int shared = 0; + int i; + int skip = MwGetInteger(tv->vscroll, MwNvalue) * (MwGetInteger(tv->vscroll, MwNmaxValue) - MwGetInteger(tv->vscroll, MwNareaShown)) / MwGetInteger(tv->vscroll, MwNmaxValue); - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); + r.x = 0; + r.y = 0; + r.width = MwGetInteger(handle, MwNwidth); + r.height = MwGetInteger(handle, MwNheight); p.x = MwDefaultBorderWidth(handle); p.y = MwDefaultBorderWidth(handle); - for(i = 0; i < arrlen(tv->tree); i++){ + for(i = 0; i < arrlen(tv->tree); i++) { if(shared > (r.height / MwTextHeight(handle, "M"))) break; - recursion(handle, &tv->tree[i], base, text, &p, 0, 0, &skip, &shared); + recursion(handle, &tv->tree[i], base, text, &p, 0, 0, &skip, &shared, 1, NULL); } - MwDrawFrame(handle, &r, base, 1); + MwDrawFrame(handle, &r, base, 1); MwLLFreeColor(text); - MwLLFreeColor(base); + MwLLFreeColor(base); } -static int recursive_length(MwTreeViewEntry* e){ +static int recursive_length(MwTreeViewEntry* e) { int l = 0; int i; - for(i = 0; i < arrlen(e); i++){ + for(i = 0; i < arrlen(e); i++) { if(e[i].opened && e[i].tree != NULL) l += recursive_length(e[i].tree); l++; } return l; } +static void frame_mouse_down(MwWidget handle, void* user, void* call) { + MwTreeView tv = handle->parent->internal; + MwLLMouse* mouse = call; + + (void)user; + + if(mouse->button == MwLLMouseLeft) tv->pressed = mouse->point; +} + +static void resize(MwWidget handle); + +static void frame_mouse_up(MwWidget handle, void* user, void* call) { + MwTreeView tv = handle->parent->internal; + int shared = 0; + int skip = MwGetInteger(tv->vscroll, MwNvalue) * (MwGetInteger(tv->vscroll, MwNmaxValue) - MwGetInteger(tv->vscroll, MwNareaShown)) / MwGetInteger(tv->vscroll, MwNmaxValue); + MwPoint p; + MwLLMouse* mouse = call; + + (void)user; + + if(mouse->button == MwLLMouseLeft) { + int i; + p.x = MwDefaultBorderWidth(tv->frame); + p.y = MwDefaultBorderWidth(tv->frame); + for(i = 0; i < arrlen(tv->tree); i++) { + if(shared > (MwGetInteger(tv->frame, MwNheight) / MwTextHeight(tv->frame, "M"))) break; + recursion(tv->frame, &tv->tree[i], NULL, NULL, &p, 0, 0, &skip, &shared, 0, &tv->pressed); + } + resize(handle->parent); + } +} + static void resize(MwWidget handle) { MwTreeView tv = handle->internal; int w = MwGetInteger(handle, MwNwidth); @@ -135,7 +172,7 @@ static void resize(MwWidget handle) { if(tv->vscroll == NULL) { tv->vscroll = MwCreateWidget(MwScrollBarClass, "vscroll", handle, w - 16, 0, 16, h); MwAddUserHandler(tv->vscroll, MwNchangedHandler, vscroll_changed, NULL); - MwSetInteger(tv->vscroll, MwNvalue, 7); + MwSetInteger(tv->vscroll, MwNvalue, 5); } else { MwVaApply(tv->vscroll, MwNx, w - 16, @@ -151,6 +188,8 @@ static void resize(MwWidget handle) { MwNinverted, 1, NULL); tv->frame->draw_inject = frame_draw; + MwAddUserHandler(tv->frame, MwNmouseDownHandler, frame_mouse_down, NULL); + MwAddUserHandler(tv->frame, MwNmouseUpHandler, frame_mouse_up, NULL); } else { MwVaApply(tv->frame, MwNx, 0, @@ -168,50 +207,50 @@ static void resize(MwWidget handle) { MwNmaxValue, ih, NULL); - if(ih <= (h / MwTextHeight(handle, "M"))){ + if(ih <= (h / MwTextHeight(handle, "M"))) { MwLLShow(tv->vscroll->lowlevel, 0); MwSetInteger(tv->frame, MwNwidth, w); - }else{ + } else { MwLLShow(tv->vscroll->lowlevel, 1); } } static int create(MwWidget handle) { - MwTreeView tv = malloc(sizeof(*tv)); + MwTreeView tv = malloc(sizeof(*tv)); MwTreeViewEntry e; - int i, j, k, l, c = 0; - MwLLPixmap p = MwLoadIcon(handle, MwIconFile); + int i, j, k, l, c = 0; + MwLLPixmap p = MwLoadIcon(handle, MwIconFile); memset(tv, 0, sizeof(*tv)); - for(i = 0; i < 10; i++){ + for(i = 0; i < 10; i++) { char str[32]; sprintf(str, "hello %d", ++c); - e.label = MwStringDupliacte(str); + e.label = MwStringDupliacte(str); e.pixmap = p; - e.tree = NULL; + e.tree = NULL; e.opened = 1; - for(j = 0; j < 3; j++){ + for(j = 0; j < 3; j++) { MwTreeViewEntry e2; sprintf(str, "hello %d", ++c); - e2.label = MwStringDupliacte(str); + e2.label = MwStringDupliacte(str); e2.pixmap = p; - e2.tree = NULL; + e2.tree = NULL; e2.opened = j == 1 ? 0 : 1; - for(k = 0; k < 3; k++){ + for(k = 0; k < 3; k++) { MwTreeViewEntry e3; sprintf(str, "hello %d", ++c); - e3.label = MwStringDupliacte(str); + e3.label = MwStringDupliacte(str); e3.pixmap = p; - e3.tree = NULL; + e3.tree = NULL; e3.opened = 1; - for(l = 0; l < 3; l++){ + for(l = 0; l < 3; l++) { MwTreeViewEntry e4; sprintf(str, "hello %d", ++c); - e4.label = MwStringDupliacte(str); + e4.label = MwStringDupliacte(str); e4.pixmap = p; - e4.tree = NULL; + e4.tree = NULL; e4.opened = 1; arrput(e3.tree, e4); }