shithub: pain

Download patch

ref: d63e7e5714f4f42a38372fcd57f56e0129fb4c14
parent: ee5d653d61460a31666dc0bf8c9b011832a0e431
author: jmq <jmq@jmq.sh>
date: Thu Apr 10 03:20:38 EDT 2025

Add color picker and fix hsv2rgb

--- a/pill/pill.c
+++ b/pill/pill.c
@@ -4,11 +4,17 @@
 #include <event.h>
 
 #define STEPS 3600
-#define RADIUS .95
+#define RADIUS .60
+#define MAXSATURATION 1.0
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 #define RAD2DEG(r_) ((180.0)/PI * (r_))
 #define DEG2RAD(r_) (PI/(180.0) * (r_))
 #define BACKGROUNDCOLOR 0x22272EFF
+#define CIRCLESLICE (2*PI/5)
+#define CIRCLESHIFT (PI/2 + CIRCLESLICE/2)
+#define CIRCLEDIAMETER (2*PI - CIRCLESLICE)
+#define COLORPICKERPADDING .10
+#define COLORPICKERRADIUS .25
 #define RECTANGLE(w, h) ((Rectangle){(Point){(0),(0)}, (Point){(w),(h)}})
 
 Image * Circle = nil;
@@ -16,7 +22,11 @@
 u32int * RawCircle = nil;
 uint RawCircleSize = 0;
 Image * Background = nil;
+float SaturationStart = .50;
+float HueStart = PI*.35;
+float Value = 1.0;
 int RunApp = 1;
+int UpdateCircle = 1;
 
 static unsigned int
 hsv2rgb(float h, float s, float v)
@@ -27,9 +37,6 @@
 	int i;
 	
 	h = RAD2DEG(h);
-	if (h == 360.0)
-		h = 0.0;
-
 	h /= 60.0;
 	i = (int)floor(h);
 	f = h - i;
@@ -67,23 +74,25 @@
 		case 5:
 			r = v;
 			g = p;
-			b = t;
+			b = q;
 			break;
 		default:
 			break;
 	}
 
-	rgb = (0xff & (uint)(b));
-	rgb |= (0xff & (uint)(g)) << 8;
-	rgb |= (0xff & (uint)(r)) << 16;
-	return rgb << 8;
+	rgb = (0xff & (uint)(b*255));
+	rgb |= (0xff & (uint)(g*255)) << 8;
+	rgb |= (0xff & (uint)(r*255)) << 16;
+	return (rgb << 8) | 0xff;
 }
 
 static void
 updatecircle(void)
 {
-	float t, i, l, s;
-	Point c, e;
+	float t, i, l, s, u, g, ct, st;
+	Point c, e, k;
+	int w;
+	uint h;
 
 	if (Circle != nil) {
 		freeimage(Circle);
@@ -106,14 +115,41 @@
 	l *= RADIUS/2.0;
 	
 	i = 1/(l*2);
-	for(t = 0.0; t < (2*PI); t += i) {
+	for (t = 0.0; t < CIRCLEDIAMETER; t += i) {
+		u = t/CIRCLEDIAMETER;
 		for (s = 0; s < l; s += 0.1) {
-			e.x = c.x + s * cos(t);
-			e.y = c.y + s * sin(t);
-			RawCircle[Dx(Circle->r) * e.y + e.x] = hsv2rgb(t, 1, (s/l)*100.0);
+			e.x = c.x + s * cos(t + CIRCLESHIFT);
+			e.y = c.y + s * sin(t + CIRCLESHIFT);
+			RawCircle[Dx(Circle->r) * e.y + e.x] = hsv2rgb(
+				HueStart + u, 
+				(SaturationStart)+(s/l)*(MAXSATURATION - SaturationStart),
+				Value);
 		}
 	}
 
+	s = l * (1+COLORPICKERPADDING);
+	u = s + (l*COLORPICKERRADIUS);
+	i = 1/(u*2);
+	for (t = .0; t < 2*PI; t+=i) {
+		ct = cos(t);
+		st = sin(t);
+		k.x = c.x + s * ct;
+		k.y = c.y + s * st;
+		e.x = c.x + u * ct;
+		e.y = c.y + u * st;
+
+		if (e.x < k.x) {
+			w = e.x;
+			e.x = k.x;
+			k.x = w;
+		}
+		
+		h = hsv2rgb(t, 1.0, 1.0);
+		for (g = s; g < u; g++) {
+				RawCircle[Dx(Circle->r) * (c.y + ((int)(g * st))) + (c.x + ((int)(g * ct)))] = h;
+		}
+	}
+
 	loadimage(Circle, Circle->r, (uchar *)RawCircle, RawCircleSize);
 }
 
@@ -120,6 +156,10 @@
 static void
 drawcanvas(void)
 {
+	if (UpdateCircle) {
+		updatecircle();
+		UpdateCircle = 0;
+	}
 	draw(screen, screen->r, Background, nil, ZP);
 	draw(screen, screen->r, Circle, nil, ZP);
 }
@@ -138,7 +178,7 @@
 static void
 initcanvas(void)
 {
-	updatecircle();
+	UpdateCircle = 1;
 	setbackground(BACKGROUNDCOLOR);
 	drawcanvas();
 }
--