From 60a6ed5ac319488ce42274ef914edc30a0f56a0e Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Thu, 19 May 2016 11:59:21 +0300 Subject: [PATCH] window state and position change support for win32 -- issue #258 --- src/dlangui/platforms/common/platform.d | 32 ++++++++-- src/dlangui/platforms/windows/winapp.d | 81 +++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 6 deletions(-) diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index dc803517..d62508a0 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -53,8 +53,8 @@ enum WindowFlag : uint { /// Window states enum WindowState : int { - /// state is unknown (not supported by platform?) - unknown, + /// state is unknown (not supported by platform?), as well for using in setWindowState when only want to activate window or change its size/position + unspecified, /// normal state normal, /// window is maximized @@ -65,6 +65,8 @@ enum WindowState : int { fullscreen, /// application is paused (e.g. on Android) paused, + /// window is hidden + hidden, /// closed closed, } @@ -240,18 +242,36 @@ class Window : CustomEventTarget { } /// window state change signal Signal!OnWindowStateHandler windowStateChanged; - protected void handleWindowStateChange(WindowState newState, Rect newWindowRect) { + /// update and signal window state changes - for using in platform inplementations + protected void handleWindowStateChange(WindowState newState, Rect newWindowRect = RECT_VALUE_IS_NOT_SET) { _windowState = newState; - _windowRect = newWindowRect; + if (newWindowRect != RECT_VALUE_IS_NOT_SET) + _windowRect = newWindowRect; if (windowStateChanged.assigned) windowStateChanged(this, newState, newWindowRect); } /// change window state, position, or size; returns true if successful, false if not supported by platform - bool setWindowState(WindowState newState, Rect newWindowRect = RECT_VALUE_IS_NOT_SET) { + bool setWindowState(WindowState newState, bool activate = false, Rect newWindowRect = RECT_VALUE_IS_NOT_SET) { + // override for particular platforms return false; } - + /// maximize window + bool maximizeWindow(bool activate = false) { return setWindowState(WindowState.maximized, activate); } + /// minimize window + bool minimizeWindow() { return setWindowState(WindowState.minimized); } + /// restore window if maximized/minimized/hidden + bool restoreWindow(bool activate = false) { return setWindowState(WindowState.normal, activate); } + /// restore window if maximized/minimized/hidden + bool hideWindow() { return setWindowState(WindowState.hidden); } + /// just activate window + bool activateWindow() { return setWindowState(WindowState.unspecified, true); } + /// change window position only + bool moveWindow(Point topLeft, bool activate = false) { return setWindowState(WindowState.unspecified, activate, Rect(topLeft.x, topLeft.y, int.min, int.min)); } + /// change window size only + bool resizeWindow(Point sz, bool activate = false) { return setWindowState(WindowState.unspecified, activate, Rect(int.min, int.min, sz.x, sz.y)); } + /// set window rectangle + bool moveAndResizeWindow(Rect rc, bool activate = false) { return setWindowState(WindowState.unspecified, activate, rc); } /// requests layout for main widget and popups void requestLayout() { diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index e69bbad2..81bf89e1 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -431,6 +431,87 @@ class Win32Window : Window { SetWindowTextW(_hwnd, toUTF16z(_caption)); } } + + /// change window state, position, or size; returns true if successful, false if not supported by platform + override bool setWindowState(WindowState newState, bool activate = false, Rect newWindowRect = RECT_VALUE_IS_NOT_SET) { + if (!_hwnd) + return false; + bool res = false; + // change state and activate support + switch(newState) { + case WindowState.unspecified: + if (activate) { + switch (_windowState) { + case WindowState.hidden: + // show hidden window + ShowWindow(_hwnd, SW_SHOW); + res = true; + break; + case WindowState.normal: + ShowWindow(_hwnd, SW_SHOWNORMAL); + res = true; + break; + case WindowState.minimized: + ShowWindow(_hwnd, SW_SHOWMINIMIZED); + res = true; + break; + case WindowState.maximized: + ShowWindow(_hwnd, SW_SHOWMAXIMIZED); + res = true; + break; + default: + break; + } + } + return true; + case WindowState.maximized: + if (_windowState != WindowState.maximized || activate) + ShowWindow(_hwnd, activate ? SW_SHOWMAXIMIZED : SW_MAXIMIZE); + return true; + case WindowState.minimized: + if (_windowState != WindowState.minimized || activate) + ShowWindow(_hwnd, activate ? SW_SHOWMINIMIZED : SW_MINIMIZE); + return true; + case WindowState.hidden: + if (_windowState != WindowState.hidden) + ShowWindow(_hwnd, SW_HIDE); + return true; + case WindowState.normal: + if (_windowState != WindowState.normal || activate) { + ShowWindow(_hwnd, activate ? SW_SHOWNORMAL : SW_SHOWNA); // SW_RESTORE + } + res = true; + break; + default: + break; + } + // change size and/or position + if (newWindowRect != RECT_VALUE_IS_NOT_SET && (newState == WindowState.normal || newState == WindowState.unspecified)) { + UINT flags = SWP_NOOWNERZORDER | SWP_NOZORDER; + if (!activate) + flags |= SWP_NOACTIVATE; + if (newWindowRect.top == int.min || newWindowRect.left == int.min) { + // no position specified + if (newWindowRect.bottom != int.min && newWindowRect.right != int.min) { + // change size only + SetWindowPos(_hwnd, NULL, 0, 0, newWindowRect.right, newWindowRect.bottom, flags | SWP_NOMOVE); + return true; + } + } else { + if (newWindowRect.bottom != int.min && newWindowRect.right != int.min) { + // change size and position + SetWindowPos(_hwnd, NULL, newWindowRect.left, newWindowRect.top, newWindowRect.width, newWindowRect.height, flags); + return true; + } else { + // change position only + SetWindowPos(_hwnd, NULL, newWindowRect.left, newWindowRect.top, 0, 0, flags | SWP_NOSIZE); + return true; + } + } + } + return res; + } + void onCreate() { Log.d("Window onCreate"); _platform.onWindowCreated(_hwnd, this);