Implemented the H slider.
This commit is contained in:
parent
bc69da86af
commit
b226288584
|
@ -1,6 +1,8 @@
|
|||
// 16 may 2016
|
||||
#include "uipriv_windows.hpp"
|
||||
|
||||
// TODO should the d2dscratch programs capture mouse?
|
||||
|
||||
struct colorDialog {
|
||||
HWND hwnd;
|
||||
|
||||
|
@ -282,7 +284,7 @@ static void updateDialog(struct colorDialog *c, HWND whichChanged)
|
|||
|
||||
// TODO TRUE?
|
||||
invalidateRect(c->svChooser, NULL, TRUE);
|
||||
//TODO invalidateRect(c->hSlider, NULL, TRUE);
|
||||
invalidateRect(c->hSlider, NULL, TRUE);
|
||||
//TODO invalidateRect(c->preview, NULL, TRUE);
|
||||
//TODO invalidateRect(c->opacitySlider, NULL, TRUE);
|
||||
|
||||
|
@ -449,7 +451,7 @@ static void drawSVChooser(struct colorDialog *c, ID2D1RenderTarget *rt)
|
|||
bprop.opacity = 1.0; // the marker should always be opaque
|
||||
hr = rt->CreateSolidColorBrush(&mcolor, &bprop, &markerBrush);
|
||||
if (hr != S_OK)
|
||||
logHRESULT(L"error creating brush for SV chooser", hr);
|
||||
logHRESULT(L"error creating brush for SV chooser marker", hr);
|
||||
rt->DrawEllipse(&mparam, markerBrush, 2, NULL);
|
||||
markerBrush->Release();
|
||||
}
|
||||
|
@ -482,6 +484,136 @@ static LRESULT CALLBACK svChooserSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LP
|
|||
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
// the gradient stuff also comes from http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx
|
||||
#define nStops (30)
|
||||
#define degPerStop (360 / nStops)
|
||||
#define stopIncr (1.0 / ((double) nStops))
|
||||
|
||||
static void drawHSlider(struct colorDialog *c, ID2D1RenderTarget *rt)
|
||||
{
|
||||
D2D1_SIZE_F size;
|
||||
D2D1_RECT_F rect;
|
||||
D2D1_GRADIENT_STOP stops[nStops];
|
||||
double r, g, b;
|
||||
int i;
|
||||
double h;
|
||||
ID2D1GradientStopCollection *collection;
|
||||
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lprop;
|
||||
D2D1_BRUSH_PROPERTIES bprop;
|
||||
ID2D1LinearGradientBrush *brush;
|
||||
double hypot, leg;
|
||||
D2D1_POINT_2F center;
|
||||
D2D1_MATRIX_3X2_F oldtf, rotate;
|
||||
D2D1_COLOR_F mcolor;
|
||||
ID2D1SolidColorBrush *markerBrush;
|
||||
HRESULT hr;
|
||||
|
||||
size = rt->GetSize();
|
||||
rect.left = size.width / 6; // leftmost sixth for arrow
|
||||
rect.top = 0;
|
||||
rect.right = size.width;
|
||||
rect.bottom = size.height;
|
||||
|
||||
for (i = 0; i < nStops; i++) {
|
||||
h = ((double) (i * degPerStop)) / 360.0;
|
||||
if (i == (nStops - 1))
|
||||
h = 0;
|
||||
hsv2RGB(h, 1.0, 1.0, &r, &g, &b);
|
||||
stops[i].position = ((double) i) * stopIncr;
|
||||
stops[i].color.r = r;
|
||||
stops[i].color.g = g;
|
||||
stops[i].color.b = b;
|
||||
stops[i].color.a = 1.0;
|
||||
}
|
||||
// and pin the last one
|
||||
stops[i - 1].position = 1.0;
|
||||
|
||||
hr = rt->CreateGradientStopCollection(stops, nStops,
|
||||
// note that in this case this gamma is explicitly specified by the original
|
||||
D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,
|
||||
&collection);
|
||||
if (hr != S_OK)
|
||||
logHRESULT(L"error creating stop collection for H slider gradient", hr);
|
||||
ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES));
|
||||
lprop.startPoint.x = (rect.right - rect.left) / 2;
|
||||
lprop.startPoint.y = 0;
|
||||
lprop.endPoint.x = (rect.right - rect.left) / 2;
|
||||
lprop.endPoint.y = size.height;
|
||||
ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES));
|
||||
bprop.opacity = 1.0;
|
||||
bprop.transform._11 = 1;
|
||||
bprop.transform._22 = 1;
|
||||
hr = rt->CreateLinearGradientBrush(&lprop, &bprop,
|
||||
collection, &brush);
|
||||
if (hr != S_OK)
|
||||
logHRESULT(L"error creating gradient brush for H slider", hr);
|
||||
rt->FillRectangle(&rect, brush);
|
||||
brush->Release();
|
||||
collection->Release();
|
||||
|
||||
// now draw a black arrow
|
||||
// to avoid needing a geometry, this will just be a rotated square
|
||||
center.x = 0;
|
||||
center.y = c->h * size.height;
|
||||
// compute the length of each side; the diagonal of the square is 2 * offset to gradient
|
||||
hypot = rect.left;
|
||||
// a^2 + a^2 = c^2 -> 2a^2 = c^2
|
||||
// a = sqrt(c^2/2)
|
||||
hypot *= hypot;
|
||||
hypot /= 2;
|
||||
leg = sqrt(hypot);
|
||||
rect.left = -leg;
|
||||
rect.top = center.y - leg;
|
||||
rect.right = leg;
|
||||
rect.bottom = center.y + leg;
|
||||
|
||||
// now we need to rotate the render target 45° (either way works) about the center point
|
||||
rt->GetTransform(&oldtf);
|
||||
rotate = oldtf * D2D1::Matrix3x2F::Rotation(45, center);
|
||||
rt->SetTransform(&rotate);
|
||||
|
||||
// and draw
|
||||
mcolor.r = 0.0;
|
||||
mcolor.g = 0.0;
|
||||
mcolor.b = 0.0;
|
||||
mcolor.a = 1.0;
|
||||
hr = rt->CreateSolidColorBrush(&mcolor, &bprop, &markerBrush);
|
||||
if (hr != S_OK)
|
||||
logHRESULT(L"error creating brush for H slider marker", hr);
|
||||
rt->FillRectangle(&rect, markerBrush);
|
||||
markerBrush->Release();
|
||||
|
||||
// clean up
|
||||
rt->SetTransform(&oldtf);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK hSliderSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
|
||||
{
|
||||
ID2D1RenderTarget *rt;
|
||||
struct colorDialog *c;
|
||||
D2D1_POINT_2F *pos;
|
||||
D2D1_SIZE_F *size;
|
||||
|
||||
c = (struct colorDialog *) dwRefData;
|
||||
switch (uMsg) {
|
||||
case msgD2DScratchPaint:
|
||||
rt = (ID2D1RenderTarget *) lParam;
|
||||
drawHSlider(c, rt);
|
||||
return 0;
|
||||
case msgD2DScratchLButtonDown:
|
||||
pos = (D2D1_POINT_2F *) wParam;
|
||||
size = (D2D1_SIZE_F *) lParam;
|
||||
c->h = pos->y / size->height;
|
||||
updateDialog(c, NULL);
|
||||
return 0;
|
||||
case WM_NCDESTROY:
|
||||
if (RemoveWindowSubclass(hwnd, hSliderSubProc, uIdSubclass) == FALSE)
|
||||
logLastError(L"error removing color dialog H slider subclass");
|
||||
break;
|
||||
}
|
||||
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
// TODO extract into d2dscratch.cpp, use in font dialog
|
||||
HWND replaceWithD2DScratch(HWND parent, int id, SUBCLASSPROC subproc, void *data)
|
||||
{
|
||||
|
@ -608,6 +740,7 @@ static struct colorDialog *beginColorDialog(HWND hwnd, LPARAM lParam)
|
|||
c->editHex = getDlgItem(c->hwnd, rcHex);
|
||||
|
||||
c->svChooser = replaceWithD2DScratch(c->hwnd, rcColorSVChooser, svChooserSubProc, c);
|
||||
c->hSlider = replaceWithD2DScratch(c->hwnd, rcColorHSlider, hSliderSubProc, c);
|
||||
|
||||
fixupControlPositions(c);
|
||||
|
||||
|
|
Loading…
Reference in New Issue