Started making the color dialog editable. I'm going to have to store HSV and alpha instead of RGB and alpha...
This commit is contained in:
parent
7c34acc2b7
commit
d892a8f710
|
@ -6,6 +6,7 @@ struct colorDialog {
|
||||||
|
|
||||||
HWND svChooser;
|
HWND svChooser;
|
||||||
HWND hSlider;
|
HWND hSlider;
|
||||||
|
HWND preview;
|
||||||
HWND opacitySlider;
|
HWND opacitySlider;
|
||||||
HWND editH;
|
HWND editH;
|
||||||
HWND editS;
|
HWND editS;
|
||||||
|
@ -21,6 +22,8 @@ struct colorDialog {
|
||||||
double b;
|
double b;
|
||||||
double a;
|
double a;
|
||||||
struct colorDialogRGBA *out;
|
struct colorDialogRGBA *out;
|
||||||
|
|
||||||
|
BOOL updating;
|
||||||
};
|
};
|
||||||
|
|
||||||
// both of these are from the wikipedia page on HSV
|
// both of these are from the wikipedia page on HSV
|
||||||
|
@ -77,16 +80,18 @@ static void rgb2HSV(double r, double g, double b, double *h, double *s, double *
|
||||||
static void hsv2RGB(double h, double s, double v, double *r, double *g, double *b)
|
static void hsv2RGB(double h, double s, double v, double *r, double *g, double *b)
|
||||||
{
|
{
|
||||||
double c;
|
double c;
|
||||||
int hPrime;
|
double hPrime;
|
||||||
|
int h60;
|
||||||
double x;
|
double x;
|
||||||
double m;
|
double m;
|
||||||
double c1, c2;
|
double c1, c2;
|
||||||
|
|
||||||
c = v * s;
|
c = v * s;
|
||||||
hPrime = (int) (h * 6); // equivalent to splitting into 60° chunks
|
hPrime = h * 6;
|
||||||
x = c * (1 - abs(hPrime % 2 - 1));
|
h60 = (int) hPrime; // equivalent to splitting into 60° chunks
|
||||||
|
x = c * (1.0 - fabs(fmod(hPrime, 2) - 1.0));
|
||||||
m = v - c;
|
m = v - c;
|
||||||
switch (hPrime) {
|
switch (h60) {
|
||||||
case 0:
|
case 0:
|
||||||
*r = c + m;
|
*r = c + m;
|
||||||
*g = x + m;
|
*g = x + m;
|
||||||
|
@ -121,6 +126,75 @@ static void hsv2RGB(double h, double s, double v, double *r, double *g, double *
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void updateDouble(HWND hwnd, double d, HWND whichChanged)
|
||||||
|
{
|
||||||
|
WCHAR *str;
|
||||||
|
|
||||||
|
if (whichChanged == hwnd)
|
||||||
|
return;
|
||||||
|
str = ftoutf16(d);
|
||||||
|
setWindowText(hwnd, str);
|
||||||
|
uiFree(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDialog(struct colorDialog *c, HWND whichChanged)
|
||||||
|
{
|
||||||
|
double h, s, v;
|
||||||
|
uint8_t rb, gb, bb, ab;
|
||||||
|
WCHAR *str;
|
||||||
|
|
||||||
|
c->updating = TRUE;
|
||||||
|
|
||||||
|
rgb2HSV(c->r, c->g, c->b, &h, &s, &v);
|
||||||
|
|
||||||
|
updateDouble(c->editH, h, whichChanged);
|
||||||
|
updateDouble(c->editS, s, whichChanged);
|
||||||
|
updateDouble(c->editV, v, whichChanged);
|
||||||
|
|
||||||
|
updateDouble(c->editRDouble, c->r, whichChanged);
|
||||||
|
updateDouble(c->editGDouble, c->g, whichChanged);
|
||||||
|
updateDouble(c->editBDouble, c->b, whichChanged);
|
||||||
|
updateDouble(c->editADouble, c->a, whichChanged);
|
||||||
|
|
||||||
|
rb = (uint8_t) (c->r * 255);
|
||||||
|
gb = (uint8_t) (c->g * 255);
|
||||||
|
bb = (uint8_t) (c->b * 255);
|
||||||
|
ab = (uint8_t) (c->a * 255);
|
||||||
|
|
||||||
|
if (whichChanged != c->editRInt) {
|
||||||
|
str = itoutf16(rb);
|
||||||
|
setWindowText(c->editRInt, str);
|
||||||
|
uiFree(str);
|
||||||
|
}
|
||||||
|
if (whichChanged != c->editGInt) {
|
||||||
|
str = itoutf16(gb);
|
||||||
|
setWindowText(c->editGInt, str);
|
||||||
|
uiFree(str);
|
||||||
|
}
|
||||||
|
if (whichChanged != c->editBInt) {
|
||||||
|
str = itoutf16(bb);
|
||||||
|
setWindowText(c->editBInt, str);
|
||||||
|
uiFree(str);
|
||||||
|
}
|
||||||
|
if (whichChanged != c->editAInt) {
|
||||||
|
str = itoutf16(ab);
|
||||||
|
setWindowText(c->editAInt, str);
|
||||||
|
uiFree(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whichChanged != c->editHex) {
|
||||||
|
// TODO hex
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO TRUE?
|
||||||
|
invalidateRect(c->svChooser, NULL, TRUE);
|
||||||
|
//TODO invalidateRect(c->hSlider, NULL, TRUE);
|
||||||
|
//TODO invalidateRect(c->preview, NULL, TRUE);
|
||||||
|
//TODO invalidateRect(c->opacitySlider, NULL, TRUE);
|
||||||
|
|
||||||
|
c->updating = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// this interesting approach comes from http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx
|
// this interesting approach comes from http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx
|
||||||
static void drawSVChooser(struct colorDialog *c, ID2D1RenderTarget *rt)
|
static void drawSVChooser(struct colorDialog *c, ID2D1RenderTarget *rt)
|
||||||
{
|
{
|
||||||
|
@ -436,9 +510,60 @@ static struct colorDialog *beginColorDialog(HWND hwnd, LPARAM lParam)
|
||||||
|
|
||||||
fixupControlPositions(c);
|
fixupControlPositions(c);
|
||||||
|
|
||||||
|
// and get the ball rolling
|
||||||
|
updateDialog(c, NULL);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double editDouble(HWND hwnd)
|
||||||
|
{
|
||||||
|
WCHAR *s;
|
||||||
|
double d;
|
||||||
|
|
||||||
|
s = windowText(hwnd);
|
||||||
|
d = _wtof(s);
|
||||||
|
uiFree(s);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hChanged(struct colorDialog *c)
|
||||||
|
{
|
||||||
|
double h, s, v;
|
||||||
|
|
||||||
|
rgb2HSV(c->r, c->g, c->b, &h, &s, &v);
|
||||||
|
h = editDouble(c->editH);
|
||||||
|
if (h < 0 || h >= 1.0) // note the >=
|
||||||
|
return;
|
||||||
|
printf("%g %g %g | ", c->r, c->g, c->b);
|
||||||
|
hsv2RGB(h, s, v, &(c->r), &(c->g), &(c->b));
|
||||||
|
printf("%g %g %g\n", c->r, c->g, c->b);
|
||||||
|
updateDialog(c, c->editH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sChanged(struct colorDialog *c)
|
||||||
|
{
|
||||||
|
double h, s, v;
|
||||||
|
|
||||||
|
rgb2HSV(c->r, c->g, c->b, &h, &s, &v);
|
||||||
|
s = editDouble(c->editS);
|
||||||
|
if (s < 0 || s > 1)
|
||||||
|
return;
|
||||||
|
hsv2RGB(h, s, v, &(c->r), &(c->g), &(c->b));
|
||||||
|
updateDialog(c, c->editS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vChanged(struct colorDialog *c)
|
||||||
|
{
|
||||||
|
double h, s, v;
|
||||||
|
|
||||||
|
rgb2HSV(c->r, c->g, c->b, &h, &s, &v);
|
||||||
|
v = editDouble(c->editV);
|
||||||
|
if (v < 0 || v > 1)
|
||||||
|
return;
|
||||||
|
hsv2RGB(h, s, v, &(c->r), &(c->g), &(c->b));
|
||||||
|
updateDialog(c, c->editV);
|
||||||
|
}
|
||||||
|
|
||||||
static void endColorDialog(struct colorDialog *c, INT_PTR code)
|
static void endColorDialog(struct colorDialog *c, INT_PTR code)
|
||||||
{
|
{
|
||||||
if (EndDialog(c->hwnd, code) == 0)
|
if (EndDialog(c->hwnd, code) == 0)
|
||||||
|
@ -446,12 +571,13 @@ static void endColorDialog(struct colorDialog *c, INT_PTR code)
|
||||||
uiFree(c);
|
uiFree(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL tryFinishDialog(struct colorDialog *c, WPARAM wParam)
|
// TODO make this void on the font dialog too
|
||||||
|
static void tryFinishDialog(struct colorDialog *c, WPARAM wParam)
|
||||||
{
|
{
|
||||||
// cancelling
|
// cancelling
|
||||||
if (LOWORD(wParam) != IDOK) {
|
if (LOWORD(wParam) != IDOK) {
|
||||||
endColorDialog(c, 1);
|
endColorDialog(c, 1);
|
||||||
return TRUE;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK
|
// OK
|
||||||
|
@ -460,9 +586,16 @@ static BOOL tryFinishDialog(struct colorDialog *c, WPARAM wParam)
|
||||||
c->out->b = c->b;
|
c->out->b = c->b;
|
||||||
c->out->a = c->a;
|
c->out->a = c->a;
|
||||||
endColorDialog(c, 2);
|
endColorDialog(c, 2);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO change fontdialog to use this
|
||||||
|
// note that if we make this const, we get lots of weird compiler errors
|
||||||
|
static std::map<int, void (*)(struct colorDialog *)> changed = {
|
||||||
|
{ rcH, hChanged },
|
||||||
|
{ rcS, sChanged },
|
||||||
|
{ rcV, vChanged },
|
||||||
|
};
|
||||||
|
|
||||||
static INT_PTR CALLBACK colorDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
static INT_PTR CALLBACK colorDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
struct colorDialog *c;
|
struct colorDialog *c;
|
||||||
|
@ -485,7 +618,17 @@ static INT_PTR CALLBACK colorDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,
|
||||||
case IDCANCEL:
|
case IDCANCEL:
|
||||||
if (HIWORD(wParam) != BN_CLICKED)
|
if (HIWORD(wParam) != BN_CLICKED)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return tryFinishDialog(c, wParam);
|
tryFinishDialog(c, wParam);
|
||||||
|
return TRUE;
|
||||||
|
case rcH:
|
||||||
|
case rcS:
|
||||||
|
case rcV:
|
||||||
|
if (HIWORD(wParam) != EN_CHANGE)
|
||||||
|
return FALSE;
|
||||||
|
if (c->updating) // prevent infinite recursion during an update
|
||||||
|
return FALSE;
|
||||||
|
(*(changed[LOWORD(wParam)]))(c);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue