Plan 9 from Bell Labs’s /usr/web/sources/extra/art/curpt.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
 * Routines to track the current point, caret point
 */
#include "art.h"

Image *cur;

void movenone(Item *ip, int index, Dpoint p){
}

void track(void (*rou)(Item *, int, Dpoint), int index, Item *ip){
	Dpoint p;
	Item *s;
	extern Image *red;

	if(ip){
		setselection(0);
		itemdraw(ip, scoffs, red);
		ip->flags|=MOVING;
	}
	realign();
	svpoint=curpt;
	while(button1()){
		p=curpt;
		mvcurpt(P2D(mouse.xy));
		if(!deqpt(p, curpt))
			(*rou)(ip, index, curpt);
		getmouse();
	}
	if(ip){
		ip->flags&=~MOVING;
		itemdraw(ip, scoffs, red);
		setselection(ip);
	}
	else setselection(select());
}
/*
 * Change curpt to be p, as modified by gravity.
 * How gravity works:
 *	First first we look for an alignment point (on the alpt list) that is
 *	within the gravity radius.  If we find it, we snap to the point.
 *	Otherwise, we examine each item in scene and active looking for
 *	the closest one.  If that's within the gravity radius, we snap to
 *	the closest point on the item.
 *	Otherwise, curpt is unchanged.
 */
void mvcurpt(Dpoint testp){
	Item *p, *q, *near, *sel;
	Dpoint i[100], nearp, np;
	Flt rad, r;
	int n, j;
	Flt grav=gravity;

	if(grav==0.) grav=.02;	/* if no gravity, we still must select close objects */
	nearp=testp;
	rad=grav;
	near=0;
	sel=0;
	for(p=active->next;p!=active;p=p->next){
		p->nearpt=(*p->fn->near)(p, testp);
		if(dist(p->nearpt, testp)<rad){
			p->near=near;
			near=p;
			for(q=near;q;q=q->near){
				n=itemxitem(p, q, i);
				for(j=0;j!=n;j++){
					r=dist(i[j], testp);
					if(r<rad){
						rad=r;
						nearp=i[j];
					}
				}
			}
		}
		np=(*p->fn->nearvert)(p, testp);
		r=dist(np, testp);
		if(r<rad){
			rad=r;
			nearp=np;
		}
	}
	if(rad==grav){
		for(p=near;p;p=p->near){
			r=dist(p->nearpt, testp);
			if(r<rad){
				rad=r;
				nearp=p->nearpt;
			}
		}
	}
	if(rad==grav){
		np=neargrid(testp);
		if(dist(np, testp)<rad) nearp=np;
	}
	if(gravity==0.) nearp=testp;	/* no gravity -- don't stick to things */
	nearp=dsub(nearp, scoffs);
	if(!deqpt(nearp, curpt)){
		draw(screen, Rpt(subpt(D2P(dadd(nearp, scoffs)), Pt(7, 0)), 
		addpt(D2P(dadd(nearp, scoffs)), Pt(9, 16))), cur, 0, ZP);
		curpt=nearp;
	}
}
int drawcurpt(void){
	draw(screen, Rpt(subpt(D2P(dadd(curpt, scoffs)), Pt(7, 0)), 
		addpt(D2P(dadd(curpt, scoffs)), Pt(8, 15))), cur, 0, ZP);
}
Item *select(void){
	Item *near=0, *p;
	int nclose=0;
	Dpoint testp;

	testp=dadd(curpt, scoffs);
	for(p=active->next;p!=active;p=p->next){
		if(p->flags&FLAT){
			if(dsq((*p->fn->near)(p, testp), testp)<1./(DPI*DPI)
			|| dsq((*p->fn->nearvert)(p, testp), testp)<1./(DPI*DPI)){
				p->near=near;
				near=p;
				nclose++;
			}
		}
	}
	if(near==0) return 0;
	for(p=near;p;p=p->near)
		if(p->orig==selection)
			return p->near?p->near->orig:near->orig;
	return near->orig;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.