summaryrefslogtreecommitdiff
path: root/layout.c
blob: ab5e7c677404f566e89ee75bd4dfad4b86e0e470 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#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);
}