rsc | b599070 | 2003-09-30 17:47:43 +0000 | [diff] [blame] | 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 | } |