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 flushimage(f->display, 1); 100 if(!scrled) 101 readmouse(mc); 102 mp = mc->xy; 103 }while(mc->buttons == b); 104 } 105 106 void 107 frselectpaint(Frame *f, Point p0, Point p1, Image *col) 108 { 109 int n; 110 Point q0, q1; 111 112 q0 = p0; 113 q1 = p1; 114 q0.y += f->font->height; 115 q1.y += f->font->height; 116 n = (p1.y-p0.y)/f->font->height; 117 if(f->b == nil) 118 drawerror(f->display, "frselectpaint b==0"); 119 if(p0.y == f->r.max.y) 120 return; 121 if(n == 0) 122 draw(f->b, Rpt(p0, q1), col, nil, ZP); 123 else{ 124 if(p0.x >= f->r.max.x) 125 p0.x = f->r.max.x-1; 126 draw(f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), col, nil, ZP); 127 if(n > 1) 128 draw(f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y), 129 col, nil, ZP); 130 draw(f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y), 131 col, nil, ZP); 132 } 133 } 134