ref: c9e889a6d73bcfcd63a93a8f74732411304ef257
parent: 08aef1095811c8f436a469208b088002e8f4ed21
author: sirjofri <sirjofri@sirjofri.de>
date: Tue Apr 22 12:09:20 EDT 2025
adds vlist, fixes window drawing
--- a/mkfile
+++ b/mkfile
@@ -12,6 +12,7 @@
n_vbox.$O \
n_button.$O \
n_image.$O \
+ n_vlist.$O \
HFILES=nate.h \
nate_construct.h \
@@ -22,6 +23,7 @@
n_vbox.h \
n_button.h \
n_image.h \
+ n_vlist.h \
</sys/src/cmd/mksyslib
--- /dev/null
+++ b/n_vlist.c
@@ -1,0 +1,154 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include "nate.h"
+#include "nate_construct.h"
+#include "n_vbox.h"
+#include "n_vlist.h"
+
+#define N_TYPE NVList_Type
+char *NVList_Type = "NVList";
+
+static void
+updatechildren(NVList *l)
+{
+ Nelem *n;
+ long i;
+ uchar *it;
+ Nlist *list;
+
+ if (!(l && l->box))
+ return;
+
+ list = ncallgetchildren(l->box);
+ if (!list)
+ return;
+ lfreelist(list);
+
+ if (!l->items)
+ return;
+ if (!l->genwidget)
+ return;
+
+ it = l->items->data;
+ for (i = 0; i < l->items->num; i++) {
+ n = l->genwidget(&it[i * l->items->size], i, l->aux);
+ if (n) {
+ ladd(list, n);
+ }
+ }
+ nsetdirty(l, DRAW);
+}
+
+static Rectangle
+calcrect(Nelem *nel, Image *screen, Rectangle r)
+{
+ NVList *v = (NVList*)nel;
+ GUARD(v);
+ v->box->slot = v->slot;
+ v->slot.r = ncallcalcrect(v->box, screen, r);
+ return v->slot.r;
+}
+
+static Point
+desiredsize(Nelem *nel, Image *screen)
+{
+ NVList *v = (NVList*)nel;
+ GUARD(v);
+ v->box->slot = v->slot;
+ return ncalldesiredsize(v->box, screen);
+}
+
+static void
+vdraw(Nelem *nel, Image *img)
+{
+ NVList *v = (NVList*)nel;
+ GUARD(v);
+ v->box->slot = v->slot;
+ ncalldraw(v->box, img);
+}
+
+static Nelem*
+checkhit(Nelem *nel, Image *screen, Mouse m)
+{
+ NVList *v = (NVList*)nel;
+ GUARD(v);
+ v->box->slot = v->slot;
+ return ncallcheckhit(v->box, screen, m);
+}
+
+static void
+vfree(Nelem *nel)
+{
+ NVList *v = (NVList*)nel;
+ GUARD(v);
+ if (nisroot(v) || nisroot(v->box))
+ return;
+ v->box->funcs->free(v->box);
+ free(v);
+}
+
+static Nlist*
+getchildren(Nelem *nel)
+{
+ NVList *v = (NVList*)nel;
+ GUARD(v);
+ return ncallgetchildren(v->box);
+}
+
+static Nelemfunctions Nvlistfunctions = {
+ .calcrect = calcrect,
+ .desiredsize = desiredsize,
+ .draw = vdraw,
+ .checkhit = checkhit,
+ .free = vfree,
+ .getchildren = getchildren,
+};
+
+#define NTYPE NVList
+#define NACCS NVListAccessors
+
+static NACCS*
+vgenwidget(NelemGetter getter, void *aux)
+{
+ NVList *v = (NVList*)nc_get();
+ GUARD(v);
+ v->genwidget = getter;
+ v->aux = aux;
+ return (NACCS*)v->accs;
+}
+
+static NACCS*
+vsource(NArray *arr)
+{
+ NVList *v = (NVList*)nc_get();
+ GUARD(v);
+ v->items = arr;
+ return (NACCS*)v->accs;
+}
+
+static NACCS accs = {
+ .GenerateWidget = vgenwidget,
+ .Source = vsource,
+};
+
+static void
+notifyupdate(NTYPE *v)
+{
+ updatechildren(v);
+}
+
+NACCS*
+New_VList(char *name)
+{
+ NVList *v = MakeNelem(NVList, NVList_Type, &Nvlistfunctions, &accs, name, 0);
+
+ NAssign(NVBoxAccessors, &v->box, New_VBox(name));
+ nc_pop();
+
+ v->notifyupdate = notifyupdate;
+
+ nc_push(v);
+ return &accs;
+}
--- /dev/null
+++ b/n_vlist.h
@@ -1,0 +1,27 @@
+extern char* NVList_Type;
+
+#define NTYPE NVList
+#define NACCS NVListAccessors
+
+typedef struct NACCS NACCS;
+struct NACCS {
+ Nelemaccessors;
+ DECL_ACCESSOR_TwoParams(GenerateWidget, NelemGetter, void*);
+ DECL_ACCESSOR_OneParam(Source, NArray*);
+};
+
+typedef struct NTYPE NTYPE;
+struct NTYPE {
+ Nelem;
+ NelemGetter genwidget;
+ NArray *items;
+ void *aux;
+ void (*notifyupdate)(NTYPE*);
+
+ NVBox *box;
+};
+
+NACCS* New_VList(char*);
+
+#undef NTYPE
+#undef NACCS
--- a/nate.c
+++ b/nate.c
@@ -261,7 +261,7 @@
if (nelem->funcs && nelem->funcs->getchildren)
return nelem->funcs->getchildren(nelem);
- if (nelem->children.num)
+ if (nelem->nchildren != 0)
return &nelem->children;
return nil;
}
--- a/nate.h
+++ b/nate.h
@@ -7,6 +7,8 @@
typedef struct Nlist Nlist;
typedef struct Nlistelem Nlistelem;
+typedef struct NArray NArray;
+
/**************/
/* list types */
/**************/
@@ -26,6 +28,13 @@
typedef int (*OnclickHandler)(Mouse, Nelem*, void*);
typedef char* (*StringGetter)(void);
+typedef Nelem* (*NelemGetter)(void*,int,void*);
+
+struct NArray {
+ void *data;
+ long size;
+ long num;
+};
typedef struct Nmargin Nmargin;
--- a/nate_construct.c
+++ b/nate_construct.c
@@ -118,6 +118,7 @@
nel->funcs = funcs;
nel->accs = accs;
nel->nchildren = nchildren;
+ nsetdirty(nel, 0xff);
linit(&nel->children);
return nel;
}
--- a/test/ntest.c
+++ b/test/ntest.c
@@ -9,11 +9,13 @@
#include "../n_box.h"
#include "../n_label.h"
#include "../n_image.h"
+#include "../n_vlist.h"
//#define T_VBOX
//#define T_HBOX
-#define T_BOX
+//#define T_BOX
//#define T_GRID
+#define T_LIST
char*
getlabel(void)
@@ -24,6 +26,40 @@
NBox *box1;
NBox *box2;
+NArray listsource;
+
+typedef struct Item Item;
+struct Item {
+ char *label;
+ char *num;
+};
+
+Item items[] = {
+ { "ABC", "5" },
+ { "DEF", "8" },
+ { "GHI", "100" },
+};
+
+Nelem*
+generatelistitem(void *item, int n, void*)
+{
+ Nelem *el;
+ Item *it = item;
+
+ NAssign(NHBoxAccessors, &el, New_HBox(nil))
+ ->Slot(NSlot(),
+ New_Label(nil)
+ ->Label(it->label)
+ )
+ ->Slot(NSlot(),
+ New_Label(nil)
+ ->Label(it->num)
+ );
+ return el;
+}
+
+NVList *vlist;
+
int
callclick(Mouse, Nelem* el, void*)
{
@@ -195,54 +231,21 @@
);
#endif
- /*
- NAssign(NWindow, &mainwindow, New_Window("window"))
+#ifdef T_LIST
+ listsource.data = items;
+ listsource.size = sizeof(Item);
+ listsource.num = sizeof(items)/sizeof(*items);
+
+ NAssign(NWindowAccessors, &mainwindow, New_Window("window"))
->MakeRoot()
->Slot(NSlot(),
- New_VBox("outer_vbox")
- ->Slot(NSlot(),
- New_HBox("first_hbox")
- ->Slot(NSlotx(LEFT, FILLX),
- NAssign(NBox, &box1, New_Box("first_box"))
- ->Border(1, green)
- ->AutoSize(1)
- ->Padding(NMargin2(5, 3))
- ->OnClick(callclick, nil)
- ->Slot(NSlot(),
- New_Label("first_label")
- ->LabelFunc(getlabel)
- ->Margin(NMargin2(5, 5))
- )
- )
- ->Slot(NSlotx(LEFT, FILLX),
- NAssign(NBox, &box2, New_Box("second_box"))
- ->Border(1, blue)
- ->OnClick(callclick, nil)
- ->Slot(NSlot(),
- New_Label("second_label")
- ->Label("DEF")
- ->Align(BOTRIGHT)
- ->Margin(NMargin2(5, 5))
- )
- )
- ->Slot(NSlotx(LEFT, FILLX),
- New_Box("image_box")
- ->Size(Pt(50, 50))
- ->Slot(NSlot(),
- New_Image("image")
- ->Image(display->black)
- )
- )
- )
- ->Slot(NSlotx(LEFT, FILLX),
- New_HBox("second_hbox")
- ->Slot(NSlot(),
- New_Label("third_label")
- ->Label("abc")
- )
- )
+ NAssign(NVListAccessors, &vlist, New_VList("vlist"))
+ ->Source(&listsource)
+ ->GenerateWidget(generatelistitem, nil)
);
- */
+
+ vlist->notifyupdate(vlist);
+#endif
eresized(0);