void textsetselect(Text *t, uint q0, uint q1) { int p0, p1, ticked; /* t->fr.p0 and t->fr.p1 are always right; t->q0 and t->q1 may be off */ t->q0 = q0; t->q1 = q1; /* compute desired p0,p1 from q0,q1 */ p0 = q0-t->org; p1 = q1-t->org; ticked = 1; if(p0 < 0){ ticked = 0; p0 = 0; } if(p1 < 0) p1 = 0; if(p0 > t->fr.nchars) p0 = t->fr.nchars; if(p1 > t->fr.nchars){ ticked = 0; p1 = t->fr.nchars; } if(p0==t->fr.p0 && p1==t->fr.p1){ if(p0 == p1 && ticked != t->fr.ticked) frtick(&t->fr, frptofchar(&t->fr, p0), ticked); return; } if(p0 > p1) sysfatal("acme: textsetselect p0=%d p1=%d q0=%ud q1=%ud t->org=%d nchars=%d", p0, p1, q0, q1, (int)t->org, (int)t->fr.nchars); /* screen disagrees with desired selection */ if(t->fr.p1<=p0 || p1<=t->fr.p0 || p0==p1 || t->fr.p1==t->fr.p0){ /* no overlap or too easy to bother trying */ frdrawsel(&t->fr, frptofchar(&t->fr, t->fr.p0), t->fr.p0, t->fr.p1, 0); if(p0 != p1 || ticked) frdrawsel(&t->fr, frptofchar(&t->fr, p0), p0, p1, 1); goto Return; } /* overlap; avoid unnecessary painting */ if(p0 < t->fr.p0){ /* extend selection backwards */ frdrawsel(&t->fr, frptofchar(&t->fr, p0), p0, t->fr.p0, 1); }else if(p0 > t->fr.p0){ /* trim first part of selection */ frdrawsel(&t->fr, frptofchar(&t->fr, t->fr.p0), t->fr.p0, p0, 0); } if(p1 > t->fr.p1){ /* extend selection forwards */ frdrawsel(&t->fr, frptofchar(&t->fr, t->fr.p1), t->fr.p1, p1, 1); }else if(p1 < t->fr.p1){ /* trim last part of selection */ frdrawsel(&t->fr, frptofchar(&t->fr, p1), p1, t->fr.p1, 0); } Return: t->fr.p0 = p0; t->fr.p1 = p1; }
void frredraw(Frame *f) { int ticked; Point pt; if(f->p0 == f->p1) { ticked = f->ticked; if(ticked) frtick(f, frptofchar(f, f->p0), 0); frdrawsel0(f, frptofchar(f, 0), 0, f->nchars, f->cols[BACK], f->cols[TEXT]); if(ticked) frtick(f, frptofchar(f, f->p0), 1); return; } pt = frptofchar(f, 0); pt = frdrawsel0(f, pt, 0, f->p0, f->cols[BACK], f->cols[TEXT]); pt = frdrawsel0(f, pt, f->p0, f->p1, f->cols[HIGH], f->cols[HTEXT]); pt = frdrawsel0(f, pt, f->p1, f->nchars, f->cols[BACK], f->cols[TEXT]); }
void frdrawsel(Frame *f, Point pt, uint32_t p0, uint32_t p1, int issel) { Image *back, *text; if(f->ticked) frtick(f, frptofchar(f, f->p0), 0); if(p0 == p1) { frtick(f, pt, issel); return; } if(issel) { back = f->cols[HIGH]; text = f->cols[HTEXT]; } else { back = f->cols[BACK]; text = f->cols[TEXT]; } frdrawsel0(f, pt, p0, p1, back, text); }
uint xselect(Frame *f, Mousectl *mc, Image *col, uint *p1p) /* when called, button is down */ { uint p0, p1, q, tmp; ulong msec; Point mp, pt0, pt1, qt; int reg, b; mp = mc->xy; b = mc->buttons; msec = mc->msec; /* remove tick */ if(f->p0 == f->p1) frtick(f, frptofchar(f, f->p0), 0); p0 = p1 = frcharofpt(f, mp); pt0 = frptofchar(f, p0); pt1 = frptofchar(f, p1); reg = 0; frtick(f, pt0, 1); do{ q = frcharofpt(f, mc->xy); if(p1 != q){ if(p0 == p1) frtick(f, pt0, 0); if(reg != region(q, p0)){ /* crossed starting point; reset */ if(reg > 0) selrestore(f, pt0, p0, p1); else if(reg < 0) selrestore(f, pt1, p1, p0); p1 = p0; pt1 = pt0; reg = region(q, p0); if(reg == 0) frdrawsel0(f, pt0, p0, p1, col, display->white); } qt = frptofchar(f, q); if(reg > 0){ if(q > p1) frdrawsel0(f, pt1, p1, q, col, display->white); else if(q < p1) selrestore(f, qt, q, p1); }else if(reg < 0){ if(q > p1) selrestore(f, pt1, p1, q); else frdrawsel0(f, qt, q, p1, col, display->white); } p1 = q; pt1 = qt; } if(p0 == p1) frtick(f, pt0, 1); flushimage(f->display, 1); readmouse(mc); }while(mc->buttons == b); if(mc->msec-msec < DELAY && p0!=p1 && abs(mp.x-mc->xy.x)<MINMOVE && abs(mp.y-mc->xy.y)<MINMOVE) { if(reg > 0) selrestore(f, pt0, p0, p1); else if(reg < 0) selrestore(f, pt1, p1, p0); p1 = p0; } if(p1 < p0){ tmp = p0; p0 = p1; p1 = tmp; } pt0 = frptofchar(f, p0); if(p0 == p1) frtick(f, pt0, 0); selrestore(f, pt0, p0, p1); /* restore tick */ if(f->p0 == f->p1) frtick(f, frptofchar(f, f->p0), 1); flushimage(f->display, 1); *p1p = p1; return p0; }