plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

frselect.c (2611B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <draw.h>
      4 #include <mouse.h>
      5 #include <frame.h>
      6 
      7 static
      8 int
      9 region(int a, int b)
     10 {
     11 	if(a < b)
     12 		return -1;
     13 	if(a == b)
     14 		return 0;
     15 	return 1;
     16 }
     17 
     18 void
     19 frselect(Frame *f, Mousectl *mc)	/* when called, button 1 is down */
     20 {
     21 	ulong p0, p1, q;
     22 	Point mp, pt0, pt1, qt;
     23 	int reg, b, scrled;
     24 
     25 	mp = mc->m.xy;
     26 	b = mc->m.buttons;
     27 
     28 	f->modified = 0;
     29 	frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
     30 	p0 = p1 = frcharofpt(f, mp);
     31 	f->p0 = p0;
     32 	f->p1 = p1;
     33 	pt0 = frptofchar(f, p0);
     34 	pt1 = frptofchar(f, p1);
     35 	frdrawsel(f, pt0, p0, p1, 1);
     36 	reg = 0;
     37 	do{
     38 		scrled = 0;
     39 		if(f->scroll){
     40 			if(mp.y < f->r.min.y){
     41 				(*f->scroll)(f, -(f->r.min.y-mp.y)/(int)f->font->height-1);
     42 				p0 = f->p1;
     43 				p1 = f->p0;
     44 				scrled = 1;
     45 			}else if(mp.y > f->r.max.y){
     46 				(*f->scroll)(f, (mp.y-f->r.max.y)/(int)f->font->height+1);
     47 				p0 = f->p0;
     48 				p1 = f->p1;
     49 				scrled = 1;
     50 			}
     51 			if(scrled){
     52 				if(reg != region(p1, p0))
     53 					q = p0, p0 = p1, p1 = q;	/* undo the swap that will happen below */
     54 				pt0 = frptofchar(f, p0);
     55 				pt1 = frptofchar(f, p1);
     56 				reg = region(p1, p0);
     57 			}
     58 		}
     59 		q = frcharofpt(f, mp);
     60 		if(p1 != q){
     61 			if(reg != region(q, p0)){	/* crossed starting point; reset */
     62 				if(reg > 0)
     63 					frdrawsel(f, pt0, p0, p1, 0);
     64 				else if(reg < 0)
     65 					frdrawsel(f, pt1, p1, p0, 0);
     66 				p1 = p0;
     67 				pt1 = pt0;
     68 				reg = region(q, p0);
     69 				if(reg == 0)
     70 					frdrawsel(f, pt0, p0, p1, 1);
     71 			}
     72 			qt = frptofchar(f, q);
     73 			if(reg > 0){
     74 				if(q > p1)
     75 					frdrawsel(f, pt1, p1, q, 1);
     76 				else if(q < p1)
     77 					frdrawsel(f, qt, q, p1, 0);
     78 			}else if(reg < 0){
     79 				if(q > p1)
     80 					frdrawsel(f, pt1, p1, q, 0);
     81 				else
     82 					frdrawsel(f, qt, q, p1, 1);
     83 			}
     84 			p1 = q;
     85 			pt1 = qt;
     86 		}
     87 		f->modified = 0;
     88 		if(p0 < p1) {
     89 			f->p0 = p0;
     90 			f->p1 = p1;
     91 		}
     92 		else {
     93 			f->p0 = p1;
     94 			f->p1 = p0;
     95 		}
     96 		if(scrled)
     97 			(*f->scroll)(f, 0);
     98 		flushimage(f->display, 1);
     99 		if(!scrled)
    100 			readmouse(mc);
    101 		mp = mc->m.xy;
    102 	}while(mc->m.buttons == b);
    103 }
    104 
    105 void
    106 frselectpaint(Frame *f, Point p0, Point p1, Image *col)
    107 {
    108 	int n;
    109 	Point q0, q1;
    110 
    111 	q0 = p0;
    112 	q1 = p1;
    113 	q0.y += f->font->height;
    114 	q1.y += f->font->height;
    115 	n = (p1.y-p0.y)/f->font->height;
    116 	if(f->b == nil)
    117 		drawerror(f->display, "frselectpaint b==0");
    118 	if(p0.y == f->r.max.y)
    119 		return;
    120 	if(n == 0)
    121 		draw(f->b, Rpt(p0, q1), col, nil, ZP);
    122 	else{
    123 		if(p0.x >= f->r.max.x)
    124 			p0.x = f->r.max.x-1;
    125 		draw(f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), col, nil, ZP);
    126 		if(n > 1)
    127 			draw(f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y),
    128 				col, nil, ZP);
    129 		draw(f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y),
    130 			col, nil, ZP);
    131 	}
    132 }