ref: db3441295e5660984a4a4f13f419d5f119c06d7b
parent: 3897a967274ce9d36bb9ea10432bb7bec5de8b16
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Fri Mar 13 14:53:01 EDT 2020
actually support multiple colors
--- a/picker.c
+++ b/picker.c
@@ -93,84 +93,88 @@
};
static double *colors;
-static int ncolors, alpha;
+static int ncolors, curcolor, alpha;
static Mode *mode;
static Image *
-gradient(double *color, int w, int e)
+slider(int si, int w)
{
+ static Image *s, *sliders[3];
+ static u8int *b, *buf[3];
Rectangle rect;
- u8int *data;
- Image *im;
double c[3];
- double r, g, b, x;
+ double rgb[3], dt;
int i, mi;
rect = Rect(0, 0, w, 1);
- if ((im = allocimage(display, rect, BGR24, 1, DNofill)) == nil)
- sysfatal("allocimage: %r");
+ s = sliders[si];
+ if (s == nil || Dx(s->r) != w) {
+ buf[si] = realloc(buf[si], 3*w);
+ if (s != nil)
+ freeimage(s);
+ if ((s = sliders[si] = allocimage(display, rect, BGR24, 1, DNofill)) == nil)
+ sysfatal("allocimage: %r");
+ }
+ b = buf[si];
- memmove(c, color, sizeof(c));
- data = malloc(3*w);
- x = mode->max[e] / w;
- mi = c[e] / x;
- c[e] = 0.0;
+ memmove(c, &colors[4*curcolor], sizeof(c));
+ dt = mode->max[si] / w;
+ mi = c[si] / dt;
+ c[si] = 0.0;
for (i = 0; i < w; i++) {
- mode->torgb(c, &r, &g, &b);
- data[i*3+0] = r*255.0;
- data[i*3+1] = g*255.0;
- data[i*3+2] = b*255.0;
+ mode->torgb(c, &rgb[0], &rgb[1], &rgb[2]);
+ b[i*3+0] = rgb[0]*255.0;
+ b[i*3+1] = rgb[1]*255.0;
+ b[i*3+2] = rgb[2]*255.0;
if (mi == i) {
- data[i*3+0] = ~data[i*3+0];
- data[i*3+1] = ~data[i*3+1];
- data[i*3+2] = ~data[i*3+2];
+ b[i*3+0] = ~b[i*3+0];
+ b[i*3+1] = ~b[i*3+1];
+ b[i*3+2] = ~b[i*3+2];
}
- c[e] += x;
- if (c[e] > mode->max[e])
- c[e] = mode->max[e];
+ c[si] = MIN(mode->max[si], c[si] + dt);
}
- loadimage(im, rect, data, 3*w);
- free(data);
+ loadimage(s, rect, b, 3*w);
- return im;
+ return s;
}
static void
redraw(void)
{
- Rectangle re;
+ Rectangle r;
int dh, i;
Image *im;
- double r, g, b;
+ double rgb[3];
ulong u;
char hex[8];
lockdisplay(display);
- //draw(screen, screen->r, display->white, nil, ZP);
- re = screen->r;
- dh = Dy(re) / 4;
- re.max.y = re.min.y + dh;
+ //draw(screen, screen->r, display->black, nil, ZP);
+ r = screen->r;
+ dh = Dy(r) / 4;
+ r.max.y = r.min.y + dh;
for (i = 0; i < 3; i++) {
- im = gradient(&colors[4*0], Dx(screen->r), i);
- draw(screen, re, im, nil, ZP);
- freeimage(im);
- re.min.y += dh;
- re.max.y += dh;
+ im = slider(i, Dx(screen->r));
+ draw(screen, r, im, nil, ZP);
+ r.min.y += dh;
+ r.max.y += dh;
}
- mode->torgb(&colors[4*0], &r, &g, &b);
- u = (int)(r*255.0)<<24 | (int)(r*255.0)<<24 | (int)(g*255.0)<<16 | (int)(b*255.0)<<8 | 0xff;
+ mode->torgb(&colors[4*curcolor], &rgb[0], &rgb[1], &rgb[2]);
+ for (i = 0; i < 3; i++)
+ rgb[i] = MAX(0.0, MIN(255.0, rgb[i]*255.0));
+ u = (ulong)rgb[0]<<24 | (ulong)rgb[1]<<16 | (ulong)rgb[2]<<8 | 0xff;
im = allocimage(display, Rect(0, 0, 1, 1), BGR24, 1, u);
- draw(screen, re, im, nil, ZP);
+ draw(screen, r, im, nil, ZP);
freeimage(im);
im = allocimage(display, Rect(0, 0, 1, 1), BGR24, 1, ~u);
sprint(hex, "#%06lux", u>>8);
- re.min.x += Dx(re)/2 - 7*stringwidth(font, "#")/2;
- re.max.x += dh/2 - font->height/2;
- string(screen, re.min, im, ZP, font, hex);
+ r.min.x += Dx(r)/2 - 7*stringwidth(font, "#")/2;
+ r.min.y += dh/2 - font->height/2;
+ string(screen, r.min, im, ZP, font, hex);
freeimage(im);
flushimage(display, 1);
@@ -271,6 +275,14 @@
case Ckey:
switch (r) {
+ case Kleft:
+ curcolor = MAX(0, curcolor-1);
+ redraw();
+ break;
+ case Kright:
+ curcolor = MIN(ncolors-1, curcolor+1);
+ redraw();
+ break;
case Kdel:
goto end;
}
@@ -285,7 +297,7 @@
m.xy.x = MAX(screen->r.min.x, MIN(screen->r.max.x, m.xy.x));
for (i = 0; i < 3; i++) {
if (m.xy.y >= p.y && m.xy.y < p.y+dh) {
- colors[4*0 + i] = MIN(mode->max[i], (m.xy.x - screen->r.min.x) * mode->max[i]/Dx(screen->r));
+ colors[4*curcolor+i] = MIN(mode->max[i], (m.xy.x - screen->r.min.x) * mode->max[i]/Dx(screen->r));
redraw();
break;
}