acme9k/libframe/frselect.c
Derek Stevens 2908f1ff9b add active tick indication; v9001-a02
window tag/body with keyboard focus will render tick in hilighted text color; doesn't work yet for column/row tags
2022-02-21 22:53:04 -07:00

123 lines
2.9 KiB
C

#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);
}
}