Unified · Split
| @@ -93,84 +93,88 @@ static Mode modes[] = { · 92 unmodified lines | ||
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | 95 | static double *colors; |
| 96 | −static int ncolors, alpha; | |
| 96 | +static int ncolors, curcolor, alpha; | |
| 97 | 97 | static Mode *mode; |
| 98 | 98 | |
| 99 | 99 | static Image * |
| 100 | −gradient(double *color, int w, int e) | |
| 100 | +slider(int si, int w) | |
| 101 | 101 | { |
| 102 | + static Image *s, *sliders[3]; | |
| 103 | + static u8int *b, *buf[3]; | |
| 102 | 104 | Rectangle rect; |
| 103 | − u8int *data; | |
| 104 | − Image *im; | |
| 105 | 105 | double c[3]; |
| 106 | − double r, g, b, x; | |
| 106 | + double rgb[3], dt; | |
| 107 | 107 | int i, mi; |
| 108 | 108 | |
| 109 | 109 | rect = Rect(0, 0, w, 1); |
| 110 | − if ((im = allocimage(display, rect, BGR24, 1, DNofill)) == nil) | |
| 111 | − sysfatal("allocimage: %r"); | |
| 112 | − | |
| 113 | − memmove(c, color, sizeof(c)); | |
| 114 | − data = malloc(3*w); | |
| 115 | − x = mode->max[e] / w; | |
| 116 | − mi = c[e] / x; | |
| 117 | − c[e] = 0.0; | |
| 110 | + s = sliders[si]; | |
| 111 | + if (s == nil || Dx(s->r) != w) { | |
| 112 | + buf[si] = realloc(buf[si], 3*w); | |
| 113 | + if (s != nil) | |
| 114 | + freeimage(s); | |
| 115 | + if ((s = sliders[si] = allocimage(display, rect, BGR24, 1, DNofill)) == nil) | |
| 116 | + sysfatal("allocimage: %r"); | |
| 117 | + } | |
| 118 | + b = buf[si]; | |
| 119 | + | |
| 120 | + memmove(c, &colors[4*curcolor], sizeof(c)); | |
| 121 | + dt = mode->max[si] / w; | |
| 122 | + mi = c[si] / dt; | |
| 123 | + c[si] = 0.0; | |
| 118 | 124 | for (i = 0; i < w; i++) { |
| 119 | − mode->torgb(c, &r, &g, &b); | |
| 120 | − data[i*3+0] = r*255.0; | |
| 121 | − data[i*3+1] = g*255.0; | |
| 122 | − data[i*3+2] = b*255.0; | |
| 125 | + mode->torgb(c, &rgb[0], &rgb[1], &rgb[2]); | |
| 126 | + b[i*3+0] = rgb[0]*255.0; | |
| 127 | + b[i*3+1] = rgb[1]*255.0; | |
| 128 | + b[i*3+2] = rgb[2]*255.0; | |
| 123 | 129 | if (mi == i) { |
| 124 | − data[i*3+0] = ~data[i*3+0]; | |
| 125 | − data[i*3+1] = ~data[i*3+1]; | |
| 126 | − data[i*3+2] = ~data[i*3+2]; | |
| 130 | + b[i*3+0] = ~b[i*3+0]; | |
| 131 | + b[i*3+1] = ~b[i*3+1]; | |
| 132 | + b[i*3+2] = ~b[i*3+2]; | |
| 127 | 133 | } |
| 128 | − c[e] += x; | |
| 129 | − if (c[e] > mode->max[e]) | |
| 130 | − c[e] = mode->max[e]; | |
| 134 | + c[si] = MIN(mode->max[si], c[si] + dt); | |
| 131 | 135 | } |
| 132 | − loadimage(im, rect, data, 3*w); | |
| 133 | − free(data); | |
| 136 | + loadimage(s, rect, b, 3*w); | |
| 134 | 137 | |
| 135 | − return im; | |
| 138 | + return s; | |
| 136 | 139 | } |
| 137 | 140 | |
| 138 | 141 | static void |
| 139 | 142 | redraw(void) |
| 140 | 143 | { |
| 141 | − Rectangle re; | |
| 144 | + Rectangle r; | |
| 142 | 145 | int dh, i; |
| 143 | 146 | Image *im; |
| 144 | − double r, g, b; | |
| 147 | + double rgb[3]; | |
| 145 | 148 | ulong u; |
| 146 | 149 | char hex[8]; |
| 147 | 150 | |
| 148 | 151 | lockdisplay(display); |
| 149 | 152 | |
| 150 | − //draw(screen, screen->r, display->white, nil, ZP); | |
| 151 | − re = screen->r; | |
| 152 | − dh = Dy(re) / 4; | |
| 153 | − re.max.y = re.min.y + dh; | |
| 153 | + //draw(screen, screen->r, display->black, nil, ZP); | |
| 154 | + r = screen->r; | |
| 155 | + dh = Dy(r) / 4; | |
| 156 | + r.max.y = r.min.y + dh; | |
| 154 | 157 | |
| 155 | 158 | for (i = 0; i < 3; i++) { |
| 156 | − im = gradient(&colors[4*0], Dx(screen->r), i); | |
| 157 | − draw(screen, re, im, nil, ZP); | |
| 158 | − freeimage(im); | |
| 159 | − re.min.y += dh; | |
| 160 | − re.max.y += dh; | |
| 159 | + im = slider(i, Dx(screen->r)); | |
| 160 | + draw(screen, r, im, nil, ZP); | |
| 161 | + r.min.y += dh; | |
| 162 | + r.max.y += dh; | |
| 161 | 163 | } |
| 162 | 164 | |
| 163 | − mode->torgb(&colors[4*0], &r, &g, &b); | |
| 164 | − u = (int)(r*255.0)<<24 | (int)(r*255.0)<<24 | (int)(g*255.0)<<16 | (int)(b*255.0)<<8 | 0xff; | |
| 165 | + mode->torgb(&colors[4*curcolor], &rgb[0], &rgb[1], &rgb[2]); | |
| 166 | + for (i = 0; i < 3; i++) | |
| 167 | + rgb[i] = MAX(0.0, MIN(255.0, rgb[i]*255.0)); | |
| 168 | + u = (ulong)rgb[0]<<24 | (ulong)rgb[1]<<16 | (ulong)rgb[2]<<8 | 0xff; | |
| 165 | 169 | im = allocimage(display, Rect(0, 0, 1, 1), BGR24, 1, u); |
| 166 | − draw(screen, re, im, nil, ZP); | |
| 170 | + draw(screen, r, im, nil, ZP); | |
| 167 | 171 | freeimage(im); |
| 168 | 172 | |
| 169 | 173 | im = allocimage(display, Rect(0, 0, 1, 1), BGR24, 1, ~u); |
| 170 | 174 | sprint(hex, "#%06lux", u>>8); |
| 171 | − re.min.x += Dx(re)/2 - 7*stringwidth(font, "#")/2; | |
| 172 | − re.max.x += dh/2 - font->height/2; | |
| 173 | − string(screen, re.min, im, ZP, font, hex); | |
| 175 | + r.min.x += Dx(r)/2 - 7*stringwidth(font, "#")/2; | |
| 176 | + r.min.y += dh/2 - font->height/2; | |
| 177 | + string(screen, r.min, im, ZP, font, hex); | |
| 174 | 178 | freeimage(im); |
| 175 | 179 | |
| 176 | 180 | flushimage(display, 1); |
| @@ -271,6 +275,14 @@ threadmain(int argc, char **argv) · 94 unmodified lines | ||
| 271 | 275 | |
| 272 | 276 | case Ckey: |
| 273 | 277 | switch (r) { |
| 278 | + case Kleft: | |
| 279 | + curcolor = MAX(0, curcolor-1); | |
| 280 | + redraw(); | |
| 281 | + break; | |
| 282 | + case Kright: | |
| 283 | + curcolor = MIN(ncolors-1, curcolor+1); | |
| 284 | + redraw(); | |
| 285 | + break; | |
| 274 | 286 | case Kdel: |
| 275 | 287 | goto end; |
| 276 | 288 | } |
| @@ -285,7 +297,7 @@ threadmain(int argc, char **argv) · 8 unmodified lines | ||
| 285 | 297 | m.xy.x = MAX(screen->r.min.x, MIN(screen->r.max.x, m.xy.x)); |
| 286 | 298 | for (i = 0; i < 3; i++) { |
| 287 | 299 | if (m.xy.y >= p.y && m.xy.y < p.y+dh) { |
| 288 | − colors[4*0 + i] = MIN(mode->max[i], (m.xy.x - screen->r.min.x) * mode->max[i]/Dx(screen->r)); | |
| 300 | + colors[4*curcolor+i] = MIN(mode->max[i], (m.xy.x - screen->r.min.x) * mode->max[i]/Dx(screen->r)); | |
| 289 | 301 | redraw(); |
| 290 | 302 | break; |
| 291 | 303 | } |