shithub: asif

Download patch

ref: 0e233a0d60a1fcce5d12b6e926ae56e39f60cbcd
parent: aae2af6ab3d4c6433ee7713994e846621f6781ab
author: qwx <qwx@sciops.net>
date: Fri Sep 16 00:32:26 EDT 2022

path: add zoom level, optional grid

setgoalmode: this sucks but middle button will be used for panning
best would be to be able to hold the shift key or something
but, mousectl/keyboardctl

--- a/app/path/client.c
+++ b/app/path/client.c
@@ -50,7 +50,7 @@
 			break;
 		case Amouse:
 			if(mousefn(mc->Mouse))
-				updatedrw();
+				updatedrw(0);
 			break;
 		case Akbd:
 			keyfn(r);
--- a/app/path/dat.h
+++ b/app/path/dat.h
@@ -1,6 +1,3 @@
-enum{
-	Nodesz = 2,
-};
 extern Node *selected;
 extern Node *start, *goal;
 
@@ -12,3 +9,6 @@
 extern int	(*pathfn)(Node*, Node*);
 
 extern int nscen, scenid;
+
+extern int nodesz;
+extern int showgrid;
--- a/app/path/drw.c
+++ b/app/path/drw.c
@@ -8,6 +8,8 @@
 
 QLock drawlock;
 Node *selected;
+int showgrid;
+int nodesz = 1;
 
 typedef Vertex Point;
 
@@ -46,7 +48,7 @@
 		selected = nil;
 		return nil;
 	}
-	p = divpt(p, Nodesz);
+	p = divpt(p, nodesz);
 	p.x = MIN(p.x, gridwidth-1);
 	p.y = MIN(p.y, gridheight-1);
 	selected = grid + p.y * gridwidth + p.x;
@@ -81,10 +83,12 @@
 static void
 drawnodes(void)
 {
+	int sz;
 	Node *n;
 	Rectangle r;
 	Image *c;
 
+	sz = MAX(nodesz - showgrid, 1);
 	for(n=grid; n<grid+gridwidth*gridheight; n++){
 		if(isblocked(n))
 			c = col[Cblocked];
@@ -101,7 +105,7 @@
 		else
 			continue;
 		r.min = n2s(n);
-		r.max = addpt(r.min, Pt(Nodesz-1, Nodesz-1));
+		r.max = addpt(r.min, Pt(sz, sz));
 		draw(view, r, c, nil, ZP);
 	}
 }
@@ -115,8 +119,8 @@
 	for(n=grid; n<grid+gridwidth*gridheight; n++){
 		if(!n->open)
 			continue;
-		p1 = addpt(n2s(n), Pt(Nodesz / 2, Nodesz / 2));
-		p0 = addpt(n2s(n->from), Pt(Nodesz / 2, Nodesz / 2));
+		p1 = addpt(n2s(n), Pt(nodesz / 2, nodesz / 2));
+		p0 = addpt(n2s(n->from), Pt(nodesz / 2, nodesz / 2));
 		//line(view, p0, p1, Endarrow, 0, 0, col[Cgrid], ZP);
 		line(view, p0, p1, 0, 0, 0, col[Cgrid], ZP);
 	}
@@ -127,35 +131,38 @@
 {
 	Rectangle r;
 
-	draw(view, view->r, col[Cfree], nil, ZP);
 	r = viewr;
 	while(r.min.x < viewr.max.x){
 		r.max.x = r.min.x;
 		line(view, r.min, r.max, 0, 0, 0, col[Cgrid], ZP);
-		r.min.x += Nodesz;
+		r.min.x += nodesz;
 	}
 	r = viewr;
 	while(r.min.y < viewr.max.y){
 		r.max.y = r.min.y;
 		line(view, r.min, r.max, 0, 0, 0, col[Cgrid], ZP);
-		r.min.y += Nodesz;
+		r.min.y += nodesz;
 	}
-	drawnodes();
-	if(Nodesz > 8)
-		drawfrom();
 }
 
 static void
-redraw(void)
+redraw(int clear)
 {
-	drawgrid();
+	if(clear)
+		draw(screen, screen->r, col[Cbg], nil, ZP);
+	draw(view, view->r, col[Cfree], nil, ZP);
+	if(showgrid && nodesz > 1)
+		drawgrid();
+	drawnodes();
+	if(nodesz > 8)
+		drawfrom();
 }
 
 void
-updatedrw(void)
+updatedrw(int clear)
 {
 	qlock(&drawlock);
-	redraw();
+	redraw(clear);
 	qunlock(&drawlock);
 	drawhud();
 	flushdrw();
@@ -164,19 +171,20 @@
 void
 resetdrw(void)
 {
-	viewr = Rpt(ZP, Pt(gridwidth*Nodesz+1, gridheight*Nodesz+1));
+	viewr = Rpt(ZP, Pt(gridwidth*nodesz+1, gridheight*nodesz+1));
 	viewΔ = divpt(addpt(subpt(ZP, subpt(screen->r.max, screen->r.min)), viewr.max), 2);
 	hudr.min = addpt(screen->r.min, subpt(Pt(2, viewr.max.y+2), viewΔ));
 	hudr.max = addpt(hudr.min, Pt(screen->r.max.x, font->height*3));
 	freeimage(view);
 	view = eallocimage(viewr, 0, DNofill);
-	draw(screen, screen->r, col[Cbg], nil, ZP);
-	updatedrw();
+	updatedrw(1);
 }
 
 void
 initdrw(void)
 {
+	int z, zx, zy;
+
 	if(initdraw(nil, nil, "path") < 0)
 		sysfatal("initdraw: %r");
 	col[Cbg] = display->black;
@@ -188,5 +196,9 @@
 	col[Cpath] = eallocimage(Rect(0,0,1,1), 1, 0xcccc00ff);
 	col[Cstart] = eallocimage(Rect(0,0,1,1), 1, 0x00cc00ff);
 	col[Cgoal] = eallocimage(Rect(0,0,1,1), 1, 0xcc0000ff);
+	zx = Dx(screen->r) / gridwidth;
+	zy = Dy(screen->r) / gridheight;
+	z = MIN(zx, zy);
+	nodesz = z <= 1 ? 1 : z > 2 ? z & ~1 : z;
 	resetdrw();
 }
--- a/app/path/fns.h
+++ b/app/path/fns.h
@@ -1,6 +1,6 @@
 void	init(char*, char*, Vertex, int, int, int);
 Node*	scrselect(Point);
-void	updatedrw(void);
+void	updatedrw(int);
 int	menter(char*, char*, int);
 void	evloop(void);
 void	showscen(int);
--- a/app/path/map.c
+++ b/app/path/map.c
@@ -14,8 +14,8 @@
 	Vertex v;
 
 	v = n2p(n);
-	v.x = v.x * Nodesz + 1;
-	v.y = v.y * Nodesz + 1;
+	v.x = v.x * nodesz + 1;
+	v.y = v.y * nodesz + 1;
 	return v;
 }
 
--- a/app/path/path.c
+++ b/app/path/path.c
@@ -17,6 +17,8 @@
 
 Node *start, *goal;
 
+static setgoalmode;
+
 static int
 grmouse(Mouse m)
 {
@@ -31,16 +33,19 @@
 		return 0;
 	switch(m.buttons & 7){
 	case 1:
-		if(goal != n && !isblocked(n))
-			start = n;
+		if(old == nil || isblocked(n) ^ isblocked(old))
+			toggleblocked(n);
 		break;
 	case 2:
-		if(start != n && !isblocked(n))
-			goal = n;
 		break;
 	case 4:
-		if(old == nil || isblocked(n) ^ isblocked(old))
-			toggleblocked(n);
+		if(setgoalmode){
+			if(start != n && !isblocked(n))
+				goal = n;
+		}else{
+			if(goal != n && !isblocked(n))
+				start = n;
+		}
 		break;
 	}
 	old = n;
@@ -77,7 +82,8 @@
 {
 	switch(r){
 	case Kdel:
-	case 'q': threadexitsall(nil);
+	case 'q':
+		threadexitsall(nil);
 	case 'r':
 		if(doprof){
 			reloadscen();
@@ -84,10 +90,36 @@
 			showscen(scenid);
 		}else
 			cleargrid();
-		updatedrw();
+		updatedrw(0);
 		break;
 	case ' ':
-	case '\n': if(setscen() >= 0) updatedrw(); break;
+	case '\n':
+		setgoalmode ^= 1;
+		break;
+	case 'g':
+		showgrid ^= 1;
+		updatedrw(0);
+		break;
+	case '0': case '1': case '2': case '3': case '4':
+	case '5': case '6': case '7': case '8': case '9':
+		if(!doprof)
+			break;
+		if(setscen() >= 0)
+			updatedrw(0);
+		break;
+	case '+':
+	case '=':
+		if(nodesz < 1<<16){
+			nodesz <<= 1;
+			resetdrw();
+		}
+		break;
+	case '-':
+		if(nodesz > 1){
+			nodesz >>= 1;
+			resetdrw();
+		}
+		break;
 	}
 	return 0;
 }
@@ -149,7 +181,6 @@
 		break;
 	case 'm':
 		scenmap = EARGF(usage());
-		doprof = 1;
 		break;
 	case 'r':
 		scenres = EARGF(usage());