diff options
Diffstat (limited to 'src/libui_sdl/libui/windows/area.cpp')
-rw-r--r-- | src/libui_sdl/libui/windows/area.cpp | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/windows/area.cpp b/src/libui_sdl/libui/windows/area.cpp new file mode 100644 index 0000000..ab69ff1 --- /dev/null +++ b/src/libui_sdl/libui/windows/area.cpp @@ -0,0 +1,206 @@ +// 8 september 2015 +#include "uipriv_windows.hpp" +#include "area.hpp" + +// TODO handle WM_DESTROY/WM_NCDESTROY +// TODO same for other Direct2D stuff +static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + uiArea *a; + CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; + RECT client; + WINDOWPOS *wp = (WINDOWPOS *) lParam; + LRESULT lResult; + + a = (uiArea *) GetWindowLongPtrW(hwnd, GWLP_USERDATA); + if (a == NULL) { + if (uMsg == WM_CREATE) { + a = (uiArea *) (cs->lpCreateParams); + // assign a->hwnd here so we can use it immediately + a->hwnd = hwnd; + SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) a); + } + // fall through to DefWindowProcW() anyway + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + } + + // always recreate the render target if necessary + if (a->rt == NULL) + a->rt = makeHWNDRenderTarget(a->hwnd); + + if (areaDoDraw(a, uMsg, wParam, lParam, &lResult) != FALSE) + return lResult; + + if (uMsg == WM_WINDOWPOSCHANGED) { + if ((wp->flags & SWP_NOSIZE) != 0) + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + uiWindowsEnsureGetClientRect(a->hwnd, &client); + areaDrawOnResize(a, &client); + areaScrollOnResize(a, &client); + return 0; + } + + if (areaDoScroll(a, uMsg, wParam, lParam, &lResult) != FALSE) + return lResult; + if (areaDoEvents(a, uMsg, wParam, lParam, &lResult) != FALSE) + return lResult; + + // nothing done + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +// control implementation + +uiWindowsControlAllDefaults(uiArea) + +static void uiAreaMinimumSize(uiWindowsControl *c, int *width, int *height) +{ + // TODO + *width = 0; + *height = 0; +} + +ATOM registerAreaClass(HICON hDefaultIcon, HCURSOR hDefaultCursor) +{ + WNDCLASSW wc; + + ZeroMemory(&wc, sizeof (WNDCLASSW)); + wc.lpszClassName = areaClass; + wc.lpfnWndProc = areaWndProc; + wc.hInstance = hInstance; + wc.hIcon = hDefaultIcon; + wc.hCursor = hDefaultCursor; + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + // this is just to be safe; see the InvalidateRect() call in the WM_WINDOWPOSCHANGED handler for more details + wc.style = CS_HREDRAW | CS_VREDRAW; + return RegisterClassW(&wc); +} + +void unregisterArea(void) +{ + if (UnregisterClassW(areaClass, hInstance) == 0) + logLastError(L"error unregistering uiArea window class"); +} + +void uiAreaSetSize(uiArea *a, int width, int height) +{ + a->scrollWidth = width; + a->scrollHeight = height; + areaUpdateScroll(a); +} + +void uiAreaQueueRedrawAll(uiArea *a) +{ + // don't erase the background; we do that ourselves in doPaint() + invalidateRect(a->hwnd, NULL, FALSE); +} + +void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) +{ + // TODO +} + +void uiAreaBeginUserWindowMove(uiArea *a) +{ + HWND toplevel; + + // TODO restrict execution + ReleaseCapture(); // TODO use properly and reset internal data structures + toplevel = parentToplevel(a->hwnd); + if (toplevel == NULL) { + // TODO + return; + } + // see http://stackoverflow.com/questions/40249940/how-do-i-initiate-a-user-mouse-driven-move-or-resize-for-custom-window-borders-o#40250654 + SendMessageW(toplevel, WM_SYSCOMMAND, + SC_MOVE | 2, 0); +} + +void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) +{ + HWND toplevel; + WPARAM wParam; + + // TODO restrict execution + ReleaseCapture(); // TODO use properly and reset internal data structures + toplevel = parentToplevel(a->hwnd); + if (toplevel == NULL) { + // TODO + return; + } + // see http://stackoverflow.com/questions/40249940/how-do-i-initiate-a-user-mouse-driven-move-or-resize-for-custom-window-borders-o#40250654 + wParam = SC_SIZE; + switch (edge) { + case uiWindowResizeEdgeLeft: + wParam |= 1; + break; + case uiWindowResizeEdgeTop: + wParam |= 3; + break; + case uiWindowResizeEdgeRight: + wParam |= 2; + break; + case uiWindowResizeEdgeBottom: + wParam |= 6; + break; + case uiWindowResizeEdgeTopLeft: + wParam |= 4; + break; + case uiWindowResizeEdgeTopRight: + wParam |= 5; + break; + case uiWindowResizeEdgeBottomLeft: + wParam |= 7; + break; + case uiWindowResizeEdgeBottomRight: + wParam |= 8; + break; + } + SendMessageW(toplevel, WM_SYSCOMMAND, + wParam, 0); +} + +uiArea *uiNewArea(uiAreaHandler *ah) +{ + uiArea *a; + + uiWindowsNewControl(uiArea, a); + + a->ah = ah; + a->scrolling = FALSE; + clickCounterReset(&(a->cc)); + + // a->hwnd is assigned in areaWndProc() + uiWindowsEnsureCreateControlHWND(0, + areaClass, L"", + 0, + hInstance, a, + FALSE); + + return a; +} + +uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) +{ + uiArea *a; + + uiWindowsNewControl(uiArea, a); + + a->ah = ah; + a->scrolling = TRUE; + a->scrollWidth = width; + a->scrollHeight = height; + clickCounterReset(&(a->cc)); + + // a->hwnd is assigned in areaWndProc() + uiWindowsEnsureCreateControlHWND(0, + areaClass, L"", + WS_HSCROLL | WS_VSCROLL, + hInstance, a, + FALSE); + + // set initial scrolling parameters + areaUpdateScroll(a); + + return a; +} |