Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.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->xy;
        b = mc->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->xy;
        }while(mc->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);
        }
}