shithub: libnate

Download patch

ref: a0b15f88e6274b4892061a7dfe790d85eb211078
parent: 6ff9ef0c4bef23bfd91f33f0c2f5cab0b88c0307
author: sirjofri <sirjofri@sirjofri.de>
date: Fri Jan 31 18:09:05 EST 2025

adds image, button, vbox

needs to rething slots etc

--- a/mkfile
+++ b/mkfile
@@ -9,6 +9,9 @@
 	n_label.$O \
 	n_box.$O \
 	n_hbox.$O \
+	n_vbox.$O \
+	n_button.$O \
+	n_image.$O \
 
 HFILES=nate.h \
 	nate_construct.h \
@@ -16,5 +19,14 @@
 	n_label.h \
 	n_box.h \
 	n_hbox.h \
+	n_vbox.h \
+	n_button.h \
+	n_image.h \
 
 </sys/src/cmd/mksyslib
+
+install:V: headers
+
+headers:V:
+	mkdir -p /sys/include/nate
+	cp *.h /sys/include/nate/
--- a/n_box.c
+++ b/n_box.c
@@ -13,6 +13,9 @@
 {
 	NBox* b = (NBox*)nelem;
 	GUARD(b);
+	if (!b->sizetocontent) {
+		return b->size;
+	}
 	if (!lgetfirst(&b->child)) {
 		return Pt(0, 0);
 	}
@@ -34,6 +37,8 @@
 
 	if (b->sizetocontent) {
 		r.max = addpt(r.min, ncallcalcsize(nelem, img));
+	} else {
+		r.max = addpt(r.min, b->size);
 	}
 
 	border(img, r, b->borderwidth, b->bordercolor, ZP);
@@ -146,6 +151,15 @@
 	return b;
 }
 
+static NBox*
+box_size(Point size)
+{
+	NBox *b = (NBox*)nc_get();
+	GUARD(b);
+	b->size = size;
+	return b;
+}
+
 NBox*
 box_onclick(int (*f)(Mouse, Nelem*, void*), void* aux)
 {
@@ -168,10 +182,12 @@
 	b->Slot = box_slot;
 	b->Border = box_border;
 	b->SizeToContent = box_sizetocontent;
+	b->Size = box_size;
 	b->OnClick = box_onclick;
 	
 	linit(&b->child);
 	b->sizetocontent = 0;
+	b->size = ZP;
 	b->hitfunc = nil;
 	b->hitaux = nil;
 	b->borderwidth = 0;
--- a/n_box.h
+++ b/n_box.h
@@ -6,10 +6,12 @@
 	DECL_ACCESSOR_OneParam(NBox, Slot, Nelem*);
 	DECL_ACCESSOR_TwoParams(NBox, Border, int, Image*);
 	DECL_ACCESSOR_OneParam(NBox, SizeToContent, int);
+	DECL_ACCESSOR_OneParam(NBox, Size, Point);
 	DECL_ACCESSOR_TwoParams(NBox, OnClick, int (*f)(Mouse, Nelem*, void*), void*);
 	
 	// private members
 	Nlist child;
+	Point size;
 	int sizetocontent;
 	int borderwidth;
 	Image* bordercolor;
--- /dev/null
+++ b/n_button.c
@@ -1,0 +1,156 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include "nate_construct.h"
+#include "n_box.h"
+#include "n_label.h"
+#include "n_button.h"
+
+#define N_TYPE NButton_Type
+char *NButton_Type = "NButton";
+
+static Point
+button_calcsize(Nelem *nelem, Image *screen)
+{
+	NButton *b = (NButton*)nelem;
+	GUARD(b);
+	return b->box->funcs->calcsize(b->box, screen);
+}
+
+static void
+button_draw(Nelem *nelem, Image *img, Rectangle r)
+{
+	NButton *b = (NButton*)nelem;
+	GUARD(b);
+	b->box->funcs->draw(b->box, img, r);
+}
+
+static Nelem*
+button_checkhit(Nelem *nelem, Image *screen, Rectangle r, Mouse m)
+{
+	NButton *b = (NButton*)nelem;
+	GUARD(b);
+	return b->box->funcs->checkhit(b->box, screen, r, m);
+}
+
+static void
+button_free(Nelem *nelem)
+{
+	NButton *b = (NButton*)nelem;
+	GUARD(b);
+	if (nisroot(b) || nisroot(b->box))
+		return;
+	b->box->funcs->free(b->box);
+	free(b);
+}
+
+static Nlist*
+button_getchildren(Nelem *nelem)
+{
+	NButton *b = (NButton*)nelem;
+	GUARD(b);
+	return &b->box->child;
+}
+
+static Nelemfunctions Nbuttonfunctions = {
+	.calcsize = button_calcsize,
+	.draw = button_draw,
+	.checkhit = button_checkhit,
+	.free = button_free,
+	.getchildren = button_getchildren,
+};
+
+static NButton*
+button_slot(Nelem* child)
+{
+	if (child == nc_get())
+		nc_pop();
+	NButton *c = (NButton*)nc_get();
+	GUARD(c);
+	nc_push(c->box);
+	c->box->Slot(child);
+	nc_pop();
+	return c;
+}
+
+static NButton*
+button_border(int w, Image *i)
+{
+	NButton *c = (NButton*)nc_get();
+	GUARD(c);
+	nc_push(c->box);
+	c->box->Border(w, i);
+	nc_pop();
+	return c;
+}
+
+static NButton*
+button_sizetocontent(int n)
+{
+	NButton *c = (NButton*)nc_get();
+	GUARD(c);
+	nc_push(c->box);
+	c->box->SizeToContent(n);
+	nc_pop();
+	return c;
+}
+
+static NButton*
+button_onclick(int (*f)(Mouse, Nelem*, void*), void *aux)
+{
+	NButton *c = (NButton*)nc_get();
+	GUARD(c);
+	nc_push(c->box);
+	c->box->OnClick(f, aux);
+	nc_pop();
+	return c;
+}
+
+static NButton*
+button_label(char *l)
+{
+	NButton *c = (NButton*)nc_get();
+	GUARD(c);
+	nc_push(c->label);
+	c->label->Label(l);
+	nc_pop();
+	return c;
+}
+
+static NButton*
+button_labelfunc(char* (*f)(void))
+{
+	NButton *c = (NButton*)nc_get();
+	GUARD(c);
+	nc_push(c->label);
+	c->label->LabelFunc(f);
+	nc_pop();
+	return c;
+}
+
+NButton*
+New_Button(void)
+{
+	NButton* b = malloc(sizeof(NButton));
+	assert(b);
+	
+	b->box = New_Box()
+		->Slot(NAssign(NLabel, &b->label, New_Label()));
+	/* pop box from stack */
+	nc_pop();
+	
+	b->type = NButton_Type;
+	b->funcs = &Nbuttonfunctions;
+	
+	b->Slot = button_slot;
+	b->Border = button_border;
+	b->SizeToContent = button_sizetocontent;
+	b->OnClick = button_onclick;
+	
+	b->Label = button_label;
+	b->LabelFunc = button_labelfunc;
+	
+	nc_push(b);
+	return b;
+}
--- /dev/null
+++ b/n_button.h
@@ -1,0 +1,21 @@
+extern char* NButton_Type;
+
+typedef struct NButton NButton;
+struct NButton {
+	Nelem;
+	DECL_ACCESSOR_OneParam(NButton, Slot, Nelem*);
+	DECL_ACCESSOR_TwoParams(NButton, Border, int, Image*);
+	DECL_ACCESSOR_OneParam(NButton, SizeToContent, int);
+	DECL_ACCESSOR_TwoParams(NButton, OnClick, int (*f)(Mouse, Nelem*, void*), void*);
+	
+	DECL_ACCESSOR_OneParam(NButton, Label, char*);
+	DECL_ACCESSOR_OneParam(NButton, LabelFunc, char* (*f)(void));
+	DECL_ACCESSOR_OneParam(NButton, Font, Font*);
+	DECL_ACCESSOR_OneParam(NButton, Color, Image*);
+	
+	// private members
+	NBox *box;
+	NLabel *label;
+};
+
+NButton* New_Button(void);
--- /dev/null
+++ b/n_image.c
@@ -1,0 +1,106 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include "nate_construct.h"
+#include "n_image.h"
+
+#define N_TYPE NImage_Type
+char *NImage_Type = "NImage";
+
+static Point
+image_calcsize(Nelem *nelem, Image*)
+{
+	NImage *i = (NImage*)nelem;
+	GUARD(i);
+	
+	if (i->image)
+		return Pt(Dx(i->image->r), Dy(i->image->r));
+	return ZP;
+}
+
+static void
+image_draw(Nelem *nelem, Image *img, Rectangle r)
+{
+	NImage *i = (NImage*)nelem;
+	GUARD(i);
+	
+	if (!i->image) {
+		draw(img, r, display->white, nil, ZP);
+		return;
+	}
+	draw(img, r, i->image, nil, i->offset);
+}
+
+static Nelem*
+image_checkhit(Nelem *nelem, Image *screen, Rectangle r, Mouse m)
+{
+	GUARD(nelem);
+	return nil;
+}
+
+static int
+image_hit(Nelem *nelem, Mouse m)
+{
+	GUARD(nelem);
+	return -1;
+}
+
+static void
+image_free(Nelem *nelem)
+{
+	GUARD(nelem);
+	if (nisroot(nelem))
+		return;
+	free(nelem);
+}
+
+static Nlist*
+image_getchildren(Nelem*)
+{
+	return nil;
+}
+
+static Nelemfunctions Nimagefunctions = {
+	.calcsize = image_calcsize,
+	.draw = image_draw,
+	.checkhit = image_checkhit,
+	.hit = image_hit,
+	.free = image_free,
+	.getchildren = image_getchildren,
+};
+
+static NImage*
+setimage(Image *img)
+{
+	NImage *i = (NImage*)nc_get();
+	GUARD(i);
+	i->image = img;
+	return i;
+}
+
+static NImage*
+setimageoffset(Point p)
+{
+	NImage *i = (NImage*)nc_get();
+	GUARD(i);
+	i->offset = p;
+	return i;
+}
+
+NImage*
+New_Image()
+{
+	NImage *i = malloc(sizeof(NImage));
+	assert(i);
+	i->type = NImage_Type;
+	i->funcs = &Nimagefunctions;
+	
+	i->image = nil;
+	i->offset = ZP;
+	
+	i->Image = setimage;
+	i->ImageOffset = setimageoffset;
+	nc_push(i);
+	return i;
+}
--- /dev/null
+++ b/n_image.h
@@ -1,0 +1,14 @@
+extern char* NImage_Type;
+
+typedef struct NImage NImage;
+struct NImage {
+	Nelem;
+	DECL_ACCESSOR_OneParam(NImage, Image, Image*);
+	DECL_ACCESSOR_OneParam(NImage, ImageOffset, Point);
+	
+	// private members
+	Image *image;
+	Point offset;
+};
+
+NImage* New_Image(void);
--- /dev/null
+++ b/n_vbox.c
@@ -1,0 +1,181 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include "nate_construct.h"
+#include "n_vbox.h"
+
+#define N_TYPE NVBox_Type
+char* NVBox_Type = "NVBox";
+
+Point currentsize;
+Image* currentscreen;
+
+void
+vbox_childsize(Nelem* nelem, int)
+{
+	Point p = ncallcalcsize(nelem, currentscreen);
+	currentsize.x = currentsize.x > p.x ? currentsize.x : p.x;
+	currentsize.y += p.y;
+}
+
+Point
+vbox_calcsize(Nelem* nelem, Image* screen)
+{
+	NVBox* b = (NVBox*)nelem;
+	GUARD(b);
+	
+	currentsize = Pt(0, 0);
+	currentscreen = screen;
+	
+	lforeach(&b->children, vbox_childsize);
+
+	return currentsize;
+}
+
+Rectangle currentrect;
+Image* currentimg;
+
+void
+vbox_childdraw(Nelem* elem, int)
+{
+	Point p = ncallcalcsize(elem, currentimg);
+	currentrect.max.y = currentrect.min.y + p.y;
+	ncalldraw(elem, currentimg, currentrect);
+	currentrect.min.y = currentrect.max.y;
+}
+
+void
+vbox_draw(Nelem* nelem, Image* img, Rectangle r)
+{
+	NVBox* b = (NVBox*)nelem;
+	GUARD(b);
+
+	if (b->sizetocontent) {
+		r.max = addpt(r.min, ncallcalcsize(b, img));
+	}
+	
+	currentrect = r;
+	currentimg = img;
+	lforeach(&b->children, vbox_childdraw);
+}
+
+Nelem* ch_ret;
+Image* ch_screen;
+Rectangle ch_rect;
+Mouse ch_mouse;
+
+void
+vbox_fe_checkhit(Nelem* nelem, int)
+{
+	Point s;
+	Nelem* e;
+	Rectangle r;
+	
+	s = ncallcalcsize(nelem, ch_screen);
+	r.min = ch_rect.min;
+	r.max = addpt(r.min, s);
+	
+	if (!ptinrect(ch_mouse.xy, r)) {
+		ch_rect.min.y += s.y;
+		return;
+	}
+	
+	e = ncallcheckhit(nelem, ch_screen, r, ch_mouse);
+	ch_rect.min.y += s.y;
+	if (e) {
+		ch_ret = e;
+	}
+}
+
+Nelem*
+vbox_checkhit(Nelem* nelem, Image* screen, Rectangle r, Mouse m)
+{
+	NVBox* b = (NVBox*)nelem;
+	GUARD(b);
+	
+	ch_ret = nil;
+	ch_screen = screen;
+	ch_rect = r;
+	ch_mouse = m;
+	
+	ch_rect.max.y = ch_rect.min.y;
+	
+	lforeach(&b->children, vbox_fe_checkhit);
+	return ch_ret;
+}
+
+int
+vbox_hit(Nelem* nelem, Mouse m)
+{
+	GUARD(nelem);
+	return -1;
+}
+
+void
+vbox_free(Nelem* nelem)
+{
+	NVBox* b = (NVBox*)nelem;
+	if (nisroot(b))
+		return;
+	
+	lfreelist(&b->children);
+	free(b);
+}
+
+Nlist*
+vbox_getchildren(Nelem* nelem)
+{
+	NVBox* b = (NVBox*)nelem;
+	GUARD(b);
+	return &b->children;
+}
+
+static Nelemfunctions Nvboxfunctions = {
+	.calcsize = vbox_calcsize,
+	.draw = vbox_draw,
+	.checkhit = vbox_checkhit,
+	.hit = vbox_hit,
+	.free = vbox_free,
+	.getchildren = vbox_getchildren,
+};
+
+NVBox*
+vbox_slot(Nelem* child)
+{
+	if (child == nc_get()) {
+		nc_pop();
+	}
+	NVBox* b = (NVBox*)nc_get();
+	GUARD(b);
+	
+	ladd(&b->children, child);
+	return b;
+}
+
+NVBox*
+vbox_sizetocontent(int stc)
+{
+	NVBox* b = (NVBox*)nc_get();
+	GUARD(b);
+	b->sizetocontent = stc;
+	return b;
+}
+
+NVBox*
+New_VBox(void)
+{
+	NVBox* b = malloc(sizeof(NVBox));
+	assert(b);
+	
+	b->type = NVBox_Type;
+	b->funcs = &Nvboxfunctions;
+	
+	b->Slot = vbox_slot;
+	b->SizeToContent = vbox_sizetocontent;
+	
+	linit(&b->children);
+	b->sizetocontent = 0;
+	nc_push(b);
+	return b;
+}
--- /dev/null
+++ b/n_vbox.h
@@ -1,0 +1,14 @@
+extern char* NVBox_Type;
+
+typedef struct NVBox NVBox;
+struct NVBox {
+	Nelem;
+	DECL_ACCESSOR_OneParam(NVBox, Slot, Nelem*);
+	DECL_ACCESSOR_OneParam(NVBox, SizeToContent, int);
+	
+	// private members
+	Nlist children;
+	int sizetocontent;
+};
+
+NVBox* New_VBox(void);