xref: /plan9-contrib/sys/src/libframe/frselect.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <libg.h>
4 #include <frame.h>
5 
6 void
7 frselect(Frame *f, Mouse *m)	/* when called, button 1 is down */
8 {
9 	ulong p0, p1, q;
10 	Point mp, pt0, pt1, qt;
11 	int b;
12 
13 	b = m->buttons;
14 	mp = m->xy;
15 
16     Again:
17 	f->modified = 0;
18 	frselectp(f, F&~D);
19 	p0 = p1 = frcharofpt(f, mp);
20 	pt0 = frptofchar(f, p0);
21 	pt1 = frptofchar(f, p1);
22 	frselectf(f, pt0, pt1, F&~D);
23 	do{
24 		if(f->modified)	/* special hack so 8½ can frselect in parallel */
25 			goto Again;
26 		q = frcharofpt(f, m->xy);
27 		if(p1 != q){
28 			if(p0 == p1)
29 				frselectf(f, pt0, pt1, F&~D);
30 			qt = frptofchar(f, q);
31 			if(p1 < q)
32 				frselectf(f, pt1, qt, F&~D);
33 			else
34 				frselectf(f, qt, pt1, F&~D);
35 			p1 = q;
36 			pt1 = qt;
37 			if(p0 == p1)
38 				frselectf(f, pt0, pt1, F&~D);
39 		}
40 		f->modified = 0;
41 		if(p0 < p1)
42 			f->p0 = p0, f->p1 = p1;
43 		else
44 			f->p0 = p1, f->p1 = p0;
45 		frgetmouse();
46 	}while(m->buttons == b);
47 }
48 /* it is assumed p0<=p1 and both were generated by frptofchar() */
49 void
50 frselectf(Frame *f, Point p0, Point p1, Fcode c)
51 {
52 	int n;
53 	Point q0, q1;
54 
55 	if(p0.x == f->left)
56 		p0.x = f->r.min.x;
57 	if(p1.x == f->left)
58 		p1.x = f->r.min.x;
59 	q0 = p0;
60 	q1 = p1;
61 	q0.y += f->font->height;
62 	q1.y += f->font->height;
63 	n = (p1.y-p0.y)/f->font->height;
64 	if(f->b == 0)
65 		berror("frselectf b==0");
66 	if(p0.y == f->r.max.y)
67 		return;
68 	if(n == 0){
69 		if(p0.x == p1.x)
70 			if(p0.x == f->r.min.x)
71 				q1.x++;
72 			else
73 				p0.x--;
74 		bitblt(f->b, p0, f->b, Rpt(p0, q1), c);
75 	}else{
76 		if(p0.x >= f->r.max.x)
77 			p0.x = f->r.max.x-1;
78 		bitblt(f->b, p0, f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), c);
79 		if(n > 1)
80 			bitblt(f->b, Pt(f->r.min.x, q0.y),
81 				f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y), c);
82 		bitblt(f->b, Pt(f->r.min.x, p1.y),
83 				f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y), c);
84 	}
85 }
86 
87 void
88 frselectp(Frame *f, Fcode c)
89 {
90 	Point pt0, pt1;
91 
92 	pt0 = frptofchar(f, f->p0);
93 	pt1 = (f->p0==f->p1)? pt0 : frptofchar(f, f->p1);
94 	frselectf(f, pt0, pt1, c);
95 }
96