diff options
Diffstat (limited to 'src/libframe/frselect.c')
-rw-r--r-- | src/libframe/frselect.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/libframe/frselect.c b/src/libframe/frselect.c new file mode 100644 index 00000000..b319c576 --- /dev/null +++ b/src/libframe/frselect.c @@ -0,0 +1,132 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <mouse.h> +#include <frame.h> + +static +int +region(int a, int b) +{ + if(a < b) + return -1; + if(a == b) + return 0; + return 1; +} + +void +frselect(Frame *f, Mousectl *mc) /* when called, button 1 is down */ +{ + ulong p0, p1, q; + Point mp, pt0, pt1, qt; + int reg, b, scrled; + + mp = mc->m.xy; + b = mc->m.buttons; + + f->modified = 0; + frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0); + p0 = p1 = frcharofpt(f, mp); + f->p0 = p0; + f->p1 = p1; + pt0 = frptofchar(f, p0); + pt1 = frptofchar(f, p1); + frdrawsel(f, pt0, p0, p1, 1); + reg = 0; + do{ + scrled = 0; + if(f->scroll){ + if(mp.y < f->r.min.y){ + (*f->scroll)(f, -(f->r.min.y-mp.y)/(int)f->font->height-1); + p0 = f->p1; + p1 = f->p0; + scrled = 1; + }else if(mp.y > f->r.max.y){ + (*f->scroll)(f, (mp.y-f->r.max.y)/(int)f->font->height+1); + p0 = f->p0; + p1 = f->p1; + scrled = 1; + } + if(scrled){ + if(reg != region(p1, p0)) + q = p0, p0 = p1, p1 = q; /* undo the swap that will happen below */ + pt0 = frptofchar(f, p0); + pt1 = frptofchar(f, p1); + reg = region(p1, p0); + } + } + q = frcharofpt(f, mp); + if(p1 != q){ + if(reg != region(q, p0)){ /* crossed starting point; reset */ + if(reg > 0) + frdrawsel(f, pt0, p0, p1, 0); + else if(reg < 0) + frdrawsel(f, pt1, p1, p0, 0); + p1 = p0; + pt1 = pt0; + reg = region(q, p0); + if(reg == 0) + frdrawsel(f, pt0, p0, p1, 1); + } + qt = frptofchar(f, q); + if(reg > 0){ + if(q > p1) + frdrawsel(f, pt1, p1, q, 1); + else if(q < p1) + frdrawsel(f, qt, q, p1, 0); + }else if(reg < 0){ + if(q > p1) + frdrawsel(f, pt1, p1, q, 0); + else + frdrawsel(f, qt, q, p1, 1); + } + p1 = q; + pt1 = qt; + } + f->modified = 0; + if(p0 < p1) { + f->p0 = p0; + f->p1 = p1; + } + else { + f->p0 = p1; + f->p1 = p0; + } + if(scrled) + (*f->scroll)(f, 0); + flushimage(f->display, 1); + if(!scrled) + readmouse(mc); + mp = mc->m.xy; + }while(mc->m.buttons == b); +} + +void +frselectpaint(Frame *f, Point p0, Point p1, Image *col) +{ + int n; + Point q0, q1; + + q0 = p0; + q1 = p1; + q0.y += f->font->height; + q1.y += f->font->height; + n = (p1.y-p0.y)/f->font->height; + if(f->b == nil) + drawerror(f->display, "frselectpaint b==0"); + if(p0.y == f->r.max.y) + return; + if(n == 0) + draw(f->b, Rpt(p0, q1), col, nil, ZP); + else{ + if(p0.x >= f->r.max.x) + p0.x = f->r.max.x-1; + draw(f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), col, nil, ZP); + if(n > 1) + draw(f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y), + col, nil, ZP); + draw(f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y), + col, nil, ZP); + } +} |