Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <draw.h>
4
#include <memdraw.h>
5
#include <thread.h>
6
#include <cursor.h>
7
#include <mouse.h>
8
#include <keyboard.h>
9
#include <frame.h>
10
#include <plumb.h>
11
#include <html.h>
12
#include "dat.h"
13
#include "fns.h"
14
 
15
void
16
rowinit(Row *row, Rectangle r)
17
{
18
	Rectangle r1;
19
	Text *t;
20
 
21
	draw(screen, r, display->white, nil, ZP);
22
	row->r = r;
23
	row->col = nil;
24
	row->ncol = 0;
25
	r1 = r;
26
	r1.max.y = r1.min.y + font->height;
27
	t = &row->tag;
28
	textinit(t, screen, r1, font, tagcols);
29
	t->what = Rowtag;
30
	t->row = row;
31
	t->w = nil;
32
	t->col = nil;
33
	r1.min.y = r1.max.y;
34
	r1.max.y += Border;
35
	draw(screen, r1, display->black, nil, ZP);
36
	textinsert(t, 0, L"Newcol Google Exit ", 19);
37
	textsetselect(t, t->rs.nr, t->rs.nr);
38
}
39
 
40
Column*
41
rowadd(Row *row, Column *c, int x)
42
{
43
	Rectangle r, r1;
44
	Column *d;
45
	int i;
46
 
47
	d = nil;
48
	r = row->r;
49
	r.min.y = row->tag.r.max.y+Border;
50
	if(x<r.min.x && row->ncol>0){	/*steal 40% of last column by default */
51
		d = row->col[row->ncol-1];
52
		x = d->r.min.x + 3*Dx(d->r)/5;
53
	}
54
	/* look for column we'll land on */
55
	for(i=0; i<row->ncol; i++){
56
		d = row->col[i];
57
		if(x < d->r.max.x)
58
			break;
59
	}
60
	if(row->ncol > 0){
61
		if(i < row->ncol)
62
			i++;	/* new column will go after d */
63
		r = d->r;
64
		if(Dx(r) < 100)
65
			return nil;
66
		draw(screen, r, display->white, nil, ZP);
67
		r1 = r;
68
		r1.max.x = min(x, r.max.x-50);
69
		if(Dx(r1) < 50)
70
			r1.max.x = r1.min.x+50;
71
		colresize(d, r1);
72
		r1.min.x = r1.max.x;
73
		r1.max.x = r1.min.x+Border;
74
		draw(screen, r1, display->black, nil, ZP);
75
		r.min.x = r1.max.x;
76
	}
77
	if(c == nil){
78
		c = emalloc(sizeof(Column));
79
		colinit(c, r);
80
	}else
81
		colresize(c, r);
82
	c->row = row;
83
	c->tag.row = row;
84
	row->col = realloc(row->col, (row->ncol+1)*sizeof(Column*));
85
	memmove(row->col+i+1, row->col+i, (row->ncol-i)*sizeof(Column*));
86
	row->col[i] = c;
87
	row->ncol++;
88
	clearmouse();
89
	return c;
90
}
91
 
92
void
93
rowresize(Row *row, Rectangle r)
94
{
95
	int i, dx, odx;
96
	Rectangle r1, r2;
97
	Column *c;
98
 
99
	dx = Dx(r);
100
	odx = Dx(row->r);
101
	row->r = r;
102
	r1 = r;
103
	r1.max.y = r1.min.y + font->height;
104
	textresize(&row->tag, screen, r1);
105
	r1.min.y = r1.max.y;
106
	r1.max.y += Border;
107
	draw(screen, r1, display->black, nil, ZP);
108
	r.min.y = r1.max.y;
109
	r1 = r;
110
	r1.max.x = r1.min.x;
111
	for(i=0; i<row->ncol; i++){
112
		c = row->col[i];
113
		r1.min.x = r1.max.x;
114
		if(i == row->ncol-1)
115
			r1.max.x = r.max.x;
116
		else
117
			r1.max.x = r1.min.x+Dx(c->r)*dx/odx;
118
		if(i > 0){
119
			r2 = r1;
120
			r2.max.x = r2.min.x+Border;
121
			draw(screen, r2, display->black, nil, ZP);
122
			r1.min.x = r2.max.x;
123
		}
124
		colresize(c, r1);
125
	}
126
}
127
 
128
void
129
rowdragcol(Row *row, Column *c, int)
130
{
131
	Rectangle r;
132
	int i, b, x;
133
	Point p, op;
134
	Column *d;
135
 
136
	clearmouse();
137
	setcursor(mousectl, &boxcursor);
138
	b = mouse->buttons;
139
	op = mouse->xy;
140
	while(mouse->buttons == b)
141
		readmouse(mousectl);
142
	setcursor(mousectl, nil);
143
	if(mouse->buttons){
144
		while(mouse->buttons)
145
			readmouse(mousectl);
146
		return;
147
	}
148
 
149
	for(i=0; i<row->ncol; i++)
150
		if(row->col[i] == c)
151
			goto Found;
152
	error("can't find column");
153
 
154
  Found:
155
	if(i == 0)
156
		return;
157
	p = mouse->xy;
158
	if((abs(p.x-op.x)<5 && abs(p.y-op.y)<5))
159
		return;
160
	if((i>0 && p.x<row->col[i-1]->r.min.x) || (i<row->ncol-1 && p.x>c->r.max.x)){
161
		/* shuffle */
162
		x = c->r.min.x;
163
		rowclose(row, c, FALSE);
164
		if(rowadd(row, c, p.x) == nil)	/* whoops! */
165
		if(rowadd(row, c, x) == nil)		/* WHOOPS! */
166
		if(rowadd(row, c, -1)==nil){		/* shit! */
167
			rowclose(row, c, TRUE);
168
			return;
169
		}
170
		colmousebut(c);
171
		return;
172
	}
173
	d = row->col[i-1];
174
	if(p.x < d->r.min.x+80+Scrollsize)
175
		p.x = d->r.min.x+80+Scrollsize;
176
	if(p.x > c->r.max.x-80-Scrollsize)
177
		p.x = c->r.max.x-80-Scrollsize;
178
	r = d->r;
179
	r.max.x = c->r.max.x;
180
	draw(screen, r, display->white, nil, ZP);
181
	r.max.x = p.x;
182
	colresize(d, r);
183
	r = c->r;
184
	r.min.x = p.x;
185
	r.max.x = r.min.x;
186
	r.max.x += Border;
187
	draw(screen, r, display->black, nil, ZP);
188
	r.min.x = r.max.x;
189
	r.max.x = c->r.max.x;
190
	colresize(c, r);
191
	colmousebut(c);
192
}
193
 
194
void
195
rowclose(Row *row, Column *c, int dofree)
196
{
197
	Rectangle r;
198
	int i;
199
 
200
	for(i=0; i<row->ncol; i++)
201
		if(row->col[i] == c)
202
			goto Found;
203
	error("can't find column");
204
  Found:
205
	r = c->r;
206
	if(dofree)
207
		colcloseall(c);
208
	memmove(row->col+i, row->col+i+1, (row->ncol-i)*sizeof(Column*));
209
	row->ncol--;
210
	row->col = realloc(row->col, row->ncol*sizeof(Column*));
211
	if(row->ncol == 0){
212
		draw(screen, r, display->white, nil, ZP);
213
		return;
214
	}
215
	if(i == row->ncol){		/* extend last column right */
216
		c = row->col[i-1];
217
		r.min.x = c->r.min.x;
218
		r.max.x = row->r.max.x;
219
	}else{			/* extend next window left */
220
		c = row->col[i];
221
		r.max.x = c->r.max.x;
222
	}
223
	draw(screen, r, display->white, nil, ZP);
224
	colresize(c, r);
225
}
226
 
227
Column*
228
rowwhichcol(Row *row, Point p)
229
{
230
	int i;
231
	Column *c;
232
 
233
	for(i=0; i<row->ncol; i++){
234
		c = row->col[i];
235
		if(ptinrect(p, c->r))
236
			return c;
237
	}
238
	return nil;
239
}
240
 
241
Text*
242
rowwhich(Row *row, Point p, Rune r, int key)
243
{
244
	Column *c;
245
 
246
	if(ptinrect(p, row->tag.all))
247
		return &row->tag;
248
	c = rowwhichcol(row, p);
249
	if(c)
250
		return colwhich(c, p, r, key);
251
	return nil;
252
}