![cinap_lenrek](/assets/img/avatar_default.png)
- remove redundant flushimage() calls before readmouse() - remove flushimage() calls for allocimage(),freeimage() and originwindow() this is experimental. it will break allocimage() error handling unless the caller does explicit flushimage() calls, tho the gains in usability over high latency connections is huge. in most cases, programs will just terminate when encountering these errors.
133 lines
2.5 KiB
C
133 lines
2.5 KiB
C
#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);
|
|
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);
|
|
}
|
|
}
|