shithub: guifs

ref: c51962a648b3f38fc378ad0081b1d1aa037142d5
dir: guifs/layout.c

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>

#include "guifs.h"

Rectangle
subspacing(Rectangle r, Spacing *s)
{
	r.min.x += s->left;
	r.min.y += s->up;
	r.max.x -= s->right;
	r.max.y -= s->down;
	return r;
}

void
layout(GuiElement *g, Rectangle r0)
{
	GuiSpec spec = guispecs[g->type];

	Spacing *margin = getprop(g, Pmargin, 1).spacing;
	Spacing *border = getprop(g, Pborder, 1).spacing;
	Spacing *padding = getprop(g, Ppadding, 1).spacing;

	/* Subtract margin to get the outer border rect */
	Rectangle r1 = subspacing(r0, margin);
	
	/* Subtract border widths to get the inner border rect */
	Rectangle r2 = subspacing(r1, border);
	
	/* Subtract padding to get the content rect */
	Rectangle r3 = subspacing(r2, padding);

	wlock(&g->lock);
	g->border = r1;
	g->rect = r2;
	g->content = r3;
	wunlock(&g->lock);

	rlock(&g->lock);
	spec.layout(g, r3);
	runlock(&g->lock);
}

void
layoutcontainer(GuiElement *g, Rectangle r)
{
	if(g->nchildren == 0)
		return;

	int orientation = getprop(g, Porientation, 1).orientation;

	int dx = 0;
	int dy = 0;

	if(orientation == Horizontal){
		dx = Dx(r) / g->nchildren;
		r.max.x = r.min.x + dx;
	}else if(orientation == Vertical){
		dy = Dy(r) / g->nchildren;
		r.max.y = r.min.y + dy;
	}

	for(int i = 0; i < g->nchildren; i++){
		layout(g->children[i], r);
		r = rectaddpt(r, Pt(dx, dy));
	}
}

void
layouttextbox(GuiElement *g, Rectangle r)
{
	USED(g);
	USED(r);
}