Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <mouse.h>
5 #include <frame.h>
7 static
8 int
9 region(int a, int b)
10 {
11 if(a < b)
12 return -1;
13 if(a == b)
14 return 0;
15 return 1;
16 }
18 void
19 frselect(Frame *f, Mousectl *mc) /* when called, button 1 is down */
20 {
21 ulong p0, p1, q;
22 Point mp, pt0, pt1, qt;
23 int reg, b, scrled;
25 mp = mc->m.xy;
26 b = mc->m.buttons;
28 f->modified = 0;
29 frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
30 p0 = p1 = frcharofpt(f, mp);
31 f->p0 = p0;
32 f->p1 = p1;
33 pt0 = frptofchar(f, p0);
34 pt1 = frptofchar(f, p1);
35 frdrawsel(f, pt0, p0, p1, 1);
36 reg = 0;
37 do{
38 scrled = 0;
39 if(f->scroll){
40 if(mp.y < f->r.min.y){
41 (*f->scroll)(f, -(f->r.min.y-mp.y)/(int)f->font->height-1);
42 p0 = f->p1;
43 p1 = f->p0;
44 scrled = 1;
45 }else if(mp.y > f->r.max.y){
46 (*f->scroll)(f, (mp.y-f->r.max.y)/(int)f->font->height+1);
47 p0 = f->p0;
48 p1 = f->p1;
49 scrled = 1;
50 }
51 if(scrled){
52 if(reg != region(p1, p0))
53 q = p0, p0 = p1, p1 = q; /* undo the swap that will happen below */
54 pt0 = frptofchar(f, p0);
55 pt1 = frptofchar(f, p1);
56 reg = region(p1, p0);
57 }
58 }
59 q = frcharofpt(f, mp);
60 if(p1 != q){
61 if(reg != region(q, p0)){ /* crossed starting point; reset */
62 if(reg > 0)
63 frdrawsel(f, pt0, p0, p1, 0);
64 else if(reg < 0)
65 frdrawsel(f, pt1, p1, p0, 0);
66 p1 = p0;
67 pt1 = pt0;
68 reg = region(q, p0);
69 if(reg == 0)
70 frdrawsel(f, pt0, p0, p1, 1);
71 }
72 qt = frptofchar(f, q);
73 if(reg > 0){
74 if(q > p1)
75 frdrawsel(f, pt1, p1, q, 1);
76 else if(q < p1)
77 frdrawsel(f, qt, q, p1, 0);
78 }else if(reg < 0){
79 if(q > p1)
80 frdrawsel(f, pt1, p1, q, 0);
81 else
82 frdrawsel(f, qt, q, p1, 1);
83 }
84 p1 = q;
85 pt1 = qt;
86 }
87 f->modified = 0;
88 if(p0 < p1) {
89 f->p0 = p0;
90 f->p1 = p1;
91 }
92 else {
93 f->p0 = p1;
94 f->p1 = p0;
95 }
96 if(scrled)
97 (*f->scroll)(f, 0);
98 flushimage(f->display, 1);
99 if(!scrled)
100 readmouse(mc);
101 mp = mc->m.xy;
102 }while(mc->m.buttons == b);
105 void
106 frselectpaint(Frame *f, Point p0, Point p1, Image *col)
108 int n;
109 Point q0, q1;
111 q0 = p0;
112 q1 = p1;
113 q0.y += f->font->height;
114 q1.y += f->font->height;
115 n = (p1.y-p0.y)/f->font->height;
116 if(f->b == nil)
117 drawerror(f->display, "frselectpaint b==0");
118 if(p0.y == f->r.max.y)
119 return;
120 if(n == 0)
121 draw(f->b, Rpt(p0, q1), col, nil, ZP);
122 else{
123 if(p0.x >= f->r.max.x)
124 p0.x = f->r.max.x-1;
125 draw(f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), col, nil, ZP);
126 if(n > 1)
127 draw(f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y),
128 col, nil, ZP);
129 draw(f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y),
130 col, nil, ZP);