Added a Direct2D scratch control that will be used by the font and color dialogs we will implement.
This commit is contained in:
parent
cc7675ab5a
commit
3bb2a0ab21
|
@ -14,6 +14,7 @@ CFILES += \
|
|||
windows/combobox.c \
|
||||
windows/container.c \
|
||||
windows/control.c \
|
||||
windows/d2dscratch.c \
|
||||
windows/datetimepicker.c \
|
||||
windows/debug.c \
|
||||
windows/draw.c \
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
// 17 april 2016
|
||||
#include "uipriv_windows.h"
|
||||
|
||||
// The Direct2D scratch window is a utility for libui internal use to do quick things with Direct2D.
|
||||
// To use, call newD2DScratch() passing in a subclass procedure. This subclass procedure should handle the msgD2DScratchPaint message, which has the following usage:
|
||||
// - wParam - 0
|
||||
// - lParam - ID2D1RenderTarget *
|
||||
// - lResult - 0
|
||||
// Other messages can also be handled here.
|
||||
|
||||
// TODO allow resize
|
||||
|
||||
#define d2dScratchClass L"libui_d2dScratchClass"
|
||||
|
||||
// TODO clip rect
|
||||
static HRESULT d2dScratchDoPaint(HWND hwnd, ID2D1RenderTarget *rt)
|
||||
{
|
||||
COLORREF bgcolorref;
|
||||
D2D1_COLOR_F bgcolor;
|
||||
|
||||
ID2D1RenderTarget_BeginDraw(rt);
|
||||
|
||||
// TODO only clear the clip area
|
||||
// TODO clear with actual background brush
|
||||
bgcolorref = GetSysColor(COLOR_BTNFACE);
|
||||
bgcolor.r = ((float) GetRValue(bgcolorref)) / 255.0;
|
||||
// due to utter apathy on Microsoft's part, GetGValue() does not work with MSVC's Run-Time Error Checks
|
||||
// it has not worked since 2008 and they have *never* fixed it
|
||||
bgcolor.g = ((float) ((BYTE) ((bgcolorref & 0xFF00) >> 8))) / 255.0;
|
||||
bgcolor.b = ((float) GetBValue(bgcolorref)) / 255.0;
|
||||
bgcolor.a = 1.0;
|
||||
ID2D1RenderTarget_Clear(rt, &bgcolor);
|
||||
|
||||
SendMessageW(hwnd, msgD2DScratchPaint, 0, (LPARAM) rt);
|
||||
|
||||
return ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK d2dScratchWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LONG_PTR init;
|
||||
ID2D1HwndRenderTarget *rt;
|
||||
HRESULT hr;
|
||||
|
||||
init = GetWindowLongPtrW(hwnd, 0);
|
||||
if (!init) {
|
||||
if (uMsg == WM_CREATE)
|
||||
SetWindowLongPtrW(hwnd, 0, (LONG_PTR) TRUE);
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
rt = (ID2D1HwndRenderTarget *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
|
||||
if (rt == NULL) {
|
||||
rt = makeHWNDRenderTarget(hwnd);
|
||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) rt);
|
||||
}
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_DESTROY:
|
||||
ID2D1HwndRenderTarget_Release(rt);
|
||||
SetWindowLongPtrW(hwnd, 0, (LONG_PTR) FALSE);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
hr = d2dScratchDoPaint(hwnd, (ID2D1RenderTarget *) rt);
|
||||
switch (hr) {
|
||||
case S_OK:
|
||||
if (ValidateRect(hwnd, NULL) == 0)
|
||||
logLastError("error validating D2D scratch control rect in d2dScratchWndProc()");
|
||||
break;
|
||||
case D2DERR_RECREATE_TARGET:
|
||||
// DON'T validate the rect
|
||||
// instead, simply drop the render target
|
||||
// we'll get another WM_PAINT and make the render target again
|
||||
// TODO would this require us to invalidate the entire client area?
|
||||
ID2D1HwndRenderTarget_Release(rt);
|
||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) NULL);
|
||||
break;
|
||||
default:
|
||||
logHRESULT("error drawing D2D scratch window in d2dScratchWndProc()", hr);
|
||||
}
|
||||
return 0;
|
||||
case WM_PRINTCLIENT:
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
ATOM registerD2DScratchClass(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
|
||||
ZeroMemory(&wc, sizeof (WNDCLASSW));
|
||||
wc.lpszClassName = d2dScratchClass;
|
||||
wc.lpfnWndProc = d2dScratchWndProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = hDefaultIcon;
|
||||
wc.hCursor = hDefaultCursor;
|
||||
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||||
return RegisterClassW(&wc);
|
||||
}
|
||||
|
||||
void unregisterD2DScratchClass(void)
|
||||
{
|
||||
if (UnregisterClassW(d2dScratchClass, hInstance) == 0)
|
||||
logLastError("error unregistering D2D scratch window class in unregisterD2DScratchClass()");
|
||||
}
|
||||
|
||||
HWND newD2DScratch(HWND parent, RECT *rect, HMENU controlID, SUBCLASSPROC subclass, DWORD_PTR subclassData)
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = CreateWindowExW(0,
|
||||
d2dScratchClass, L"",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
rect->left, rect->top,
|
||||
rect->right - rect->left, rect->bottom - rect->top,
|
||||
parent, controlID, hInstance, NULL);
|
||||
if (hwnd == NULL)
|
||||
logLastError("error creating D2D scratch window in newD2DScratch()");
|
||||
if (SetWindowSubclass(hwnd, subclass, 0, subclassData) == FALSE)
|
||||
logLastError("error subclassing D2D scratch window in newD2DScratch()");
|
||||
return hwnd;
|
||||
}
|
|
@ -130,6 +130,7 @@ const char *uiInit(uiInitOptions *o)
|
|||
if (hMessageFont == NULL)
|
||||
return loadLastError("loading default messagebox font; this is the default UI font");
|
||||
|
||||
// TODO rewrite this error message
|
||||
if (initContainer(hDefaultIcon, hDefaultCursor) == 0)
|
||||
return loadLastError("initializing uiMakeContainer() window class");
|
||||
|
||||
|
@ -165,12 +166,16 @@ const char *uiInit(uiInitOptions *o)
|
|||
if (registerAreaFilter() == 0)
|
||||
return loadLastError("registering uiArea message filter");
|
||||
|
||||
if (registerD2DScratchClass(hDefaultIcon, hDefaultCursor) == 0)
|
||||
return loadLastError("initializing D2D scratch window class");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void uiUninit(void)
|
||||
{
|
||||
uninitMenus();
|
||||
unregisterD2DScratchClass();
|
||||
unregisterArea();
|
||||
uninitDrawText();
|
||||
uninitDraw();
|
||||
|
|
|
@ -18,6 +18,7 @@ enum {
|
|||
msgHSCROLL,
|
||||
msgConsoleEndSession,
|
||||
msgQueued,
|
||||
msgD2DScratchPaint,
|
||||
};
|
||||
|
||||
// init.c
|
||||
|
@ -159,6 +160,11 @@ extern void doDrawText(ID2D1RenderTarget *rt, ID2D1Brush *black, double x, doubl
|
|||
// fontdialog.cpp
|
||||
extern void showFontDialog(HWND parent);
|
||||
|
||||
// d2dscratch.c
|
||||
extern ATOM registerD2DScratchClass(HICON, HCURSOR);
|
||||
extern void unregisterD2DScratchClass(void);
|
||||
extern HWND newD2DScratch(HWND parent, RECT *rect, HMENU controlID, SUBCLASSPROC subclass, DWORD_PTR subclassData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue