shithub: libnate

Download patch

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);