xref: /plan9/sys/src/libframe/frselect.c (revision 5d459b5a09e427ae1acd4e6afcf028853c73946e)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <mouse.h>
63e12c5d1SDavid du Colombier #include <frame.h>
73e12c5d1SDavid du Colombier 
87dd7cddfSDavid du Colombier static
97dd7cddfSDavid du Colombier int
region(int a,int b)107dd7cddfSDavid du Colombier region(int a, int b)
117dd7cddfSDavid du Colombier {
127dd7cddfSDavid du Colombier 	if(a < b)
137dd7cddfSDavid du Colombier 		return -1;
147dd7cddfSDavid du Colombier 	if(a == b)
157dd7cddfSDavid du Colombier 		return 0;
167dd7cddfSDavid du Colombier 	return 1;
177dd7cddfSDavid du Colombier }
187dd7cddfSDavid du Colombier 
193e12c5d1SDavid du Colombier void
frselect(Frame * f,Mousectl * mc)207dd7cddfSDavid du Colombier frselect(Frame *f, Mousectl *mc)	/* when called, button 1 is down */
213e12c5d1SDavid du Colombier {
223e12c5d1SDavid du Colombier 	ulong p0, p1, q;
233e12c5d1SDavid du Colombier 	Point mp, pt0, pt1, qt;
247dd7cddfSDavid du Colombier 	int reg, b, scrled;
253e12c5d1SDavid du Colombier 
267dd7cddfSDavid du Colombier 	mp = mc->xy;
277dd7cddfSDavid du Colombier 	b = mc->buttons;
283e12c5d1SDavid du Colombier 
293e12c5d1SDavid du Colombier 	f->modified = 0;
307dd7cddfSDavid du Colombier 	frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
313e12c5d1SDavid du Colombier 	p0 = p1 = frcharofpt(f, mp);
327dd7cddfSDavid du Colombier 	f->p0 = p0;
337dd7cddfSDavid du Colombier 	f->p1 = p1;
343e12c5d1SDavid du Colombier 	pt0 = frptofchar(f, p0);
353e12c5d1SDavid du Colombier 	pt1 = frptofchar(f, p1);
367dd7cddfSDavid du Colombier 	frdrawsel(f, pt0, p0, p1, 1);
377dd7cddfSDavid du Colombier 	reg = 0;
383e12c5d1SDavid du Colombier 	do{
397dd7cddfSDavid du Colombier 		scrled = 0;
407dd7cddfSDavid du Colombier 		if(f->scroll){
41*5d459b5aSDavid du Colombier 			if(mp.y < f->r.min.y){
42*5d459b5aSDavid du Colombier 				(*f->scroll)(f, -(f->r.min.y-mp.y)/(int)f->font->height-1);
437dd7cddfSDavid du Colombier 				p0 = f->p1;
447dd7cddfSDavid du Colombier 				p1 = f->p0;
457dd7cddfSDavid du Colombier 				scrled = 1;
46*5d459b5aSDavid du Colombier 			}else if(mp.y > f->r.max.y){
47*5d459b5aSDavid du Colombier 				(*f->scroll)(f, (mp.y-f->r.max.y)/(int)f->font->height+1);
487dd7cddfSDavid du Colombier 				p0 = f->p0;
497dd7cddfSDavid du Colombier 				p1 = f->p1;
507dd7cddfSDavid du Colombier 				scrled = 1;
517dd7cddfSDavid du Colombier 			}
527dd7cddfSDavid du Colombier 			if(scrled){
53*5d459b5aSDavid du Colombier 				if(reg != region(p1, p0))
54*5d459b5aSDavid du Colombier 					q = p0, p0 = p1, p1 = q;	/* undo the swap that will happen below */
557dd7cddfSDavid du Colombier 				pt0 = frptofchar(f, p0);
567dd7cddfSDavid du Colombier 				pt1 = frptofchar(f, p1);
577dd7cddfSDavid du Colombier 				reg = region(p1, p0);
587dd7cddfSDavid du Colombier 			}
597dd7cddfSDavid du Colombier 		}
60*5d459b5aSDavid du Colombier 		q = frcharofpt(f, mp);
613e12c5d1SDavid du Colombier 		if(p1 != q){
627dd7cddfSDavid du Colombier 			if(reg != region(q, p0)){	/* crossed starting point; reset */
637dd7cddfSDavid du Colombier 				if(reg > 0)
647dd7cddfSDavid du Colombier 					frdrawsel(f, pt0, p0, p1, 0);
657dd7cddfSDavid du Colombier 				else if(reg < 0)
667dd7cddfSDavid du Colombier 					frdrawsel(f, pt1, p1, p0, 0);
677dd7cddfSDavid du Colombier 				p1 = p0;
687dd7cddfSDavid du Colombier 				pt1 = pt0;
697dd7cddfSDavid du Colombier 				reg = region(q, p0);
707dd7cddfSDavid du Colombier 				if(reg == 0)
717dd7cddfSDavid du Colombier 					frdrawsel(f, pt0, p0, p1, 1);
727dd7cddfSDavid du Colombier 			}
733e12c5d1SDavid du Colombier 			qt = frptofchar(f, q);
747dd7cddfSDavid du Colombier 			if(reg > 0){
757dd7cddfSDavid du Colombier 				if(q > p1)
767dd7cddfSDavid du Colombier 					frdrawsel(f, pt1, p1, q, 1);
777dd7cddfSDavid du Colombier 				else if(q < p1)
787dd7cddfSDavid du Colombier 					frdrawsel(f, qt, q, p1, 0);
797dd7cddfSDavid du Colombier 			}else if(reg < 0){
807dd7cddfSDavid du Colombier 				if(q > p1)
817dd7cddfSDavid du Colombier 					frdrawsel(f, pt1, p1, q, 0);
823e12c5d1SDavid du Colombier 				else
837dd7cddfSDavid du Colombier 					frdrawsel(f, qt, q, p1, 1);
847dd7cddfSDavid du Colombier 			}
853e12c5d1SDavid du Colombier 			p1 = q;
863e12c5d1SDavid du Colombier 			pt1 = qt;
873e12c5d1SDavid du Colombier 		}
883e12c5d1SDavid du Colombier 		f->modified = 0;
897dd7cddfSDavid du Colombier 		if(p0 < p1) {
907dd7cddfSDavid du Colombier 			f->p0 = p0;
917dd7cddfSDavid du Colombier 			f->p1 = p1;
923e12c5d1SDavid du Colombier 		}
937dd7cddfSDavid du Colombier 		else {
947dd7cddfSDavid du Colombier 			f->p0 = p1;
957dd7cddfSDavid du Colombier 			f->p1 = p0;
967dd7cddfSDavid du Colombier 		}
977dd7cddfSDavid du Colombier 		if(scrled)
987dd7cddfSDavid du Colombier 			(*f->scroll)(f, 0);
997dd7cddfSDavid du Colombier 		flushimage(f->display, 1);
1007dd7cddfSDavid du Colombier 		if(!scrled)
1017dd7cddfSDavid du Colombier 			readmouse(mc);
102*5d459b5aSDavid du Colombier 		mp = mc->xy;
1037dd7cddfSDavid du Colombier 	}while(mc->buttons == b);
1047dd7cddfSDavid du Colombier }
1057dd7cddfSDavid du Colombier 
1063e12c5d1SDavid du Colombier void
frselectpaint(Frame * f,Point p0,Point p1,Image * col)1077dd7cddfSDavid du Colombier frselectpaint(Frame *f, Point p0, Point p1, Image *col)
1083e12c5d1SDavid du Colombier {
1093e12c5d1SDavid du Colombier 	int n;
1103e12c5d1SDavid du Colombier 	Point q0, q1;
1113e12c5d1SDavid du Colombier 
1123e12c5d1SDavid du Colombier 	q0 = p0;
1133e12c5d1SDavid du Colombier 	q1 = p1;
1143e12c5d1SDavid du Colombier 	q0.y += f->font->height;
1153e12c5d1SDavid du Colombier 	q1.y += f->font->height;
1163e12c5d1SDavid du Colombier 	n = (p1.y-p0.y)/f->font->height;
1177dd7cddfSDavid du Colombier 	if(f->b == nil)
1187dd7cddfSDavid du Colombier 		drawerror(f->display, "frselectpaint b==0");
1193e12c5d1SDavid du Colombier 	if(p0.y == f->r.max.y)
1203e12c5d1SDavid du Colombier 		return;
1217dd7cddfSDavid du Colombier 	if(n == 0)
1227dd7cddfSDavid du Colombier 		draw(f->b, Rpt(p0, q1), col, nil, ZP);
1237dd7cddfSDavid du Colombier 	else{
1243e12c5d1SDavid du Colombier 		if(p0.x >= f->r.max.x)
1253e12c5d1SDavid du Colombier 			p0.x = f->r.max.x-1;
1267dd7cddfSDavid du Colombier 		draw(f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), col, nil, ZP);
1273e12c5d1SDavid du Colombier 		if(n > 1)
1287dd7cddfSDavid du Colombier 			draw(f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y),
1297dd7cddfSDavid du Colombier 				col, nil, ZP);
1307dd7cddfSDavid du Colombier 		draw(f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y),
1317dd7cddfSDavid du Colombier 			col, nil, ZP);
1323e12c5d1SDavid du Colombier 	}
1333e12c5d1SDavid du Colombier }
134