2022-02-20 20:43:24 +00:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
|
|
|
#include <draw.h>
|
|
|
|
#include <mouse.h>
|
2022-02-22 05:52:56 +00:00
|
|
|
#include "frame.h"
|
2022-02-20 20:43:24 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|