frselect.c (2611B)
1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 #include <mouse.h> 5 #include <frame.h> 6 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 } 17 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; 24 25 mp = mc->m.xy; 26 b = mc->m.buttons; 27 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); 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 }