]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libframe/frselect.c
upas/*: cleanup mkfiles (thanks amavect)
[plan9front.git] / sys / src / libframe / frselect.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <mouse.h>
6 #include <frame.h>
7
8 static
9 int
10 region(int a, int b)
11 {
12         if(a < b)
13                 return -1;
14         if(a == b)
15                 return 0;
16         return 1;
17 }
18
19 void
20 frselect(Frame *f, Mousectl *mc)        /* when called, button 1 is down */
21 {
22         ulong p0, p1, q;
23         Point mp, pt0, pt1, qt;
24         int reg, b, scrled;
25
26         mp = mc->xy;
27         b = mc->buttons;
28
29         f->modified = 0;
30         frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
31         p0 = p1 = frcharofpt(f, mp);
32         f->p0 = p0;
33         f->p1 = p1;
34         pt0 = frptofchar(f, p0);
35         pt1 = frptofchar(f, p1);
36         frdrawsel(f, pt0, p0, p1, 1);
37         reg = 0;
38         do{
39                 scrled = 0;
40                 if(f->scroll){
41                         if(mp.y < f->r.min.y){
42                                 (*f->scroll)(f, -(f->r.min.y-mp.y)/(int)f->font->height-1);
43                                 p0 = f->p1;
44                                 p1 = f->p0;
45                                 scrled = 1;
46                         }else if(mp.y > f->r.max.y){
47                                 (*f->scroll)(f, (mp.y-f->r.max.y)/(int)f->font->height+1);
48                                 p0 = f->p0;
49                                 p1 = f->p1;
50                                 scrled = 1;
51                         }
52                         if(scrled){
53                                 if(reg != region(p1, p0))
54                                         q = p0, p0 = p1, p1 = q;        /* undo the swap that will happen below */
55                                 pt0 = frptofchar(f, p0);
56                                 pt1 = frptofchar(f, p1);
57                                 reg = region(p1, p0);
58                         }
59                 }
60                 q = frcharofpt(f, mp);
61                 if(p1 != q){
62                         if(reg != region(q, p0)){       /* crossed starting point; reset */
63                                 if(reg > 0)
64                                         frdrawsel(f, pt0, p0, p1, 0);
65                                 else if(reg < 0)
66                                         frdrawsel(f, pt1, p1, p0, 0);
67                                 p1 = p0;
68                                 pt1 = pt0;
69                                 reg = region(q, p0);
70                                 if(reg == 0)
71                                         frdrawsel(f, pt0, p0, p1, 1);
72                         }
73                         qt = frptofchar(f, q);
74                         if(reg > 0){
75                                 if(q > p1)
76                                         frdrawsel(f, pt1, p1, q, 1);
77                                 else if(q < p1)
78                                         frdrawsel(f, qt, q, p1, 0);
79                         }else if(reg < 0){
80                                 if(q > p1)
81                                         frdrawsel(f, pt1, p1, q, 0);
82                                 else
83                                         frdrawsel(f, qt, q, p1, 1);
84                         }
85                         p1 = q;
86                         pt1 = qt;
87                 }
88                 f->modified = 0;
89                 if(p0 < p1) {
90                         f->p0 = p0;
91                         f->p1 = p1;
92                 }
93                 else {
94                         f->p0 = p1;
95                         f->p1 = p0;
96                 }
97                 if(scrled)
98                         (*f->scroll)(f, 0);
99                 if(!scrled)
100                         readmouse(mc);
101                 mp = mc->xy;
102         }while(mc->buttons == b);
103 }
104
105 void
106 frselectpaint(Frame *f, Point p0, Point p1, Image *col)
107 {
108         int n;
109         Point q0, q1;
110
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);
131         }
132 }