Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kuznetsov <kuzsasha@gmail.com>2013-04-09 21:21:05 +0400
committerAlexander Kuznetsov <kuzsasha@gmail.com>2013-04-09 21:21:05 +0400
commitf652b11ed13b4d9e6705ede9cc990042a2fad4b4 (patch)
treebba6d8fe597c75d3f92fb5bf7db40f9d3703935f /intern/ghost
parent13780935dc600d35ee9887bbe759c45beaf99170 (diff)
Live window resizing on Windows
Custom implementation for resizing (GHOST_SizerWin32) Some things still don't work: * esc cancel * max windows size * aero (sizing) snap on win7 hbrBackground = 0 to disable clear screen. Thanks to dfelinto for help in finding of root cause.
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/CMakeLists.txt2
-rw-r--r--intern/ghost/intern/GHOST_SizerWin32.cpp202
-rw-r--r--intern/ghost/intern/GHOST_SizerWin32.h61
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp32
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp3
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h3
6 files changed, 298 insertions, 5 deletions
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 12dd4c0d3eb..5bad9922d15 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -296,6 +296,7 @@ elseif(WIN32)
intern/GHOST_SystemPathsWin32.cpp
intern/GHOST_WindowWin32.cpp
intern/GHOST_DropTargetWin32.cpp
+ intern/GHOST_SizerWin32.cpp
intern/GHOST_DisplayManagerWin32.h
intern/GHOST_DropTargetWin32.h
@@ -303,6 +304,7 @@ elseif(WIN32)
intern/GHOST_SystemPathsWin32.h
intern/GHOST_WindowWin32.h
intern/GHOST_TaskbarWin32.h
+ intern/GHOST_SizerWin32.h
)
if(WITH_INPUT_NDOF)
diff --git a/intern/ghost/intern/GHOST_SizerWin32.cpp b/intern/ghost/intern/GHOST_SizerWin32.cpp
new file mode 100644
index 00000000000..9aa9ba313e6
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SizerWin32.cpp
@@ -0,0 +1,202 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Alexandr Kuznetsov
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ghost/intern/GHOST_SizerWin32.cpp
+ * \ingroup GHOST
+ */
+
+#ifndef __GHOST_SIZERWIN32_CPP__
+#define __GHOST_SIZERWIN32_CPP__
+
+
+#include "GHOST_SizerWin32.h"
+#include <Windowsx.h>
+
+#define T_NONE (0)
+#define T_SIZE (1)
+#define T_MOVE (2)
+#define T_MOVESIZE (3)
+
+
+static void RectCopyH(RECT * t, RECT * f)
+{
+ t->left = f->left;
+ t->right = f->right;
+}
+
+static void RectCopyV(RECT * t, RECT * f)
+{
+ t->top = f->top;
+ t->bottom = f->bottom;
+}
+
+static void RectCopy(RECT * t, RECT * f)
+{
+ RectCopyH(t,f);
+ RectCopyV(t,f);
+}
+
+
+GHOST_SizerWin32::GHOST_SizerWin32(void)
+{
+ hortransf = vertransf = 0;
+ minsize[0] = minsize[1] = 0;
+ hwnd = 0;
+}
+
+GHOST_SizerWin32::~GHOST_SizerWin32(void)
+{
+ if(isWinChanges())
+ cancel();
+}
+
+void GHOST_SizerWin32::setMinSize(int minx, int miny)
+{
+ minsize[0] = minx;
+ minsize[1] = miny;
+
+
+}
+
+bool GHOST_SizerWin32::isWinChanges(void)
+{
+ return hortransf||vertransf;
+}
+
+
+void GHOST_SizerWin32::startSizing(unsigned short type)
+{
+ //SetCapture(hwnd);
+ POINT coord;
+
+ switch(type & 0xf)
+ {
+
+ case WMSZ_LEFT: hortransf = T_MOVESIZE;
+ vertransf = T_NONE; break;
+ case WMSZ_RIGHT: hortransf = T_SIZE;
+ vertransf = T_NONE; break;
+ case WMSZ_TOP: hortransf = T_NONE;
+ vertransf = T_MOVESIZE; break;
+ case WMSZ_TOPLEFT: hortransf = T_MOVESIZE;
+ vertransf = T_MOVESIZE; break;
+ case WMSZ_TOPRIGHT: hortransf = T_SIZE;
+ vertransf = T_MOVESIZE; break;
+ case WMSZ_BOTTOM: hortransf = T_NONE;
+ vertransf = T_SIZE; break;
+ case WMSZ_BOTTOMLEFT: hortransf = T_MOVESIZE;
+ vertransf = T_SIZE; break;
+ case WMSZ_BOTTOMRIGHT: hortransf = T_SIZE;
+ vertransf = T_SIZE; break;
+
+ }
+
+
+
+ POINT mp;
+ GetCursorPos(&mp);
+ startpos[0]=mp.x;
+ startpos[1]=mp.y;
+
+ GetWindowRect(hwnd, &initrect);
+ initrect.bottom-=initrect.top;
+ initrect.right-=initrect.left;
+ RectCopy(&goodrect,&initrect);
+
+}
+
+void GHOST_SizerWin32::setHWND(HWND hWnd)
+{
+ this->hwnd = hWnd;
+}
+
+
+void GHOST_SizerWin32::updateWindowSize(void)
+{
+ if(!isWinChanges())
+ return;
+ if(hortransf||vertransf){
+ POINT mp;
+ GetCursorPos(&mp);
+ int hordelta = mp.x-startpos[0];
+ int verdelta = mp.y-startpos[1];
+
+ RECT newrect;
+ RectCopy(&newrect, &initrect);
+
+ switch(hortransf)
+ {
+ case T_SIZE:
+ newrect.right+=hordelta;
+ break;
+ case T_MOVESIZE:
+ newrect.right-=hordelta;
+ case T_MOVE:
+ newrect.left+=hordelta;
+ break;
+ }
+
+ switch(vertransf)
+ {
+ case T_SIZE:
+ newrect.bottom+=verdelta;
+ break;
+ case T_MOVESIZE:
+ newrect.bottom-=verdelta;
+ case T_MOVE:
+ newrect.top+=verdelta;
+ break;
+ }
+
+
+ if(newrect.right<minsize[0])
+ RectCopyH(&newrect,&goodrect);
+ if(newrect.bottom<minsize[1])
+ RectCopyV(&newrect,&goodrect);
+
+ SetWindowPos(hwnd,0,newrect.left, newrect.top,
+ newrect.right, newrect.bottom,
+ 0);
+
+ RectCopy(&goodrect, &newrect);
+
+
+}
+}
+
+void GHOST_SizerWin32::cancel(void)
+{
+ accept();
+ SetWindowPos(hwnd,0,initrect.left, initrect.top,
+ initrect.right, initrect.bottom, 0);
+}
+
+void GHOST_SizerWin32::accept(void)
+{
+ hortransf=vertransf=0;
+}
+
+
+#endif /* __GHOST_SIZERWIN32_CPP__*/ \ No newline at end of file
diff --git a/intern/ghost/intern/GHOST_SizerWin32.h b/intern/ghost/intern/GHOST_SizerWin32.h
new file mode 100644
index 00000000000..f7d11e78ad7
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SizerWin32.h
@@ -0,0 +1,61 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Alexandr Kuznetsov
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ghost/intern/GHOST_SizerWin32.h
+ * \ingroup GHOST
+ */
+#ifndef __GHOST_SIZERWIN32_H__
+#define __GHOST_SIZERWIN32_H__
+
+#include <windows.h>
+class GHOST_SizerWin32
+{
+ private:
+ HWND hwnd;
+ int startpos[2];
+ int minsize[2];
+ RECT initrect;
+ RECT goodrect;
+ unsigned char hortransf, vertransf;
+
+
+ public:
+ GHOST_SizerWin32(void);
+ ~GHOST_SizerWin32(void);
+
+ bool isWinChanges(void);
+ void startSizing(unsigned short type);
+ void updateWindowSize(void);
+
+ void setHWND(HWND hWnd);
+ void setMinSize(int minx, int miny);
+
+ void cancel(void);
+ void accept(void);
+
+
+};
+
+#endif /*#ifndef __GHOST_SIZERWIN32_H__*/ \ No newline at end of file
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index a6e14ac362e..f19f4a67732 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -400,7 +400,7 @@ GHOST_TSuccess GHOST_SystemWin32::init()
}
if (success) {
- WNDCLASSW wc;
+ WNDCLASSW wc = {0};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = s_wndProc;
wc.cbClsExtra = 0;
@@ -412,7 +412,7 @@ GHOST_TSuccess GHOST_SystemWin32::init()
::LoadIcon(NULL, IDI_APPLICATION);
}
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
- wc.hbrBackground = (HBRUSH) ::GetStockObject(BLACK_BRUSH);
+ wc.hbrBackground = 0;
wc.lpszMenuName = 0;
wc.lpszClassName = L"GHOST_WindowClass";
@@ -979,7 +979,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* maximize, minimize or close the window are triggered. Also it is sent when ALT
* button is press for menu. To prevent this we must return preventing DefWindowProc.
*/
- if (wParam == SC_KEYMENU) return 0;
+ if (wParam == SC_KEYMENU)
+ {
+ eventHandled = true;
+ } else
+ if((wParam&0xfff0)==SC_SIZE)
+ {
+ window->registerMouseClickEvent(0);
+ window->m_wsh.startSizing(wParam);
+ eventHandled = true;
+ }
break;
////////////////////////////////////////////////////////////////////////
// Tablet events, processed
@@ -1017,7 +1026,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
case WM_LBUTTONUP:
window->registerMouseClickEvent(1);
- event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
+ if(window->m_wsh.isWinChanges())
+ window->m_wsh.accept();
+ else
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
break;
case WM_MBUTTONUP:
window->registerMouseClickEvent(1);
@@ -1037,7 +1049,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
break;
case WM_MOUSEMOVE:
- event = processCursorEvent(GHOST_kEventCursorMove, window);
+ if(window->m_wsh.isWinChanges())
+ window->m_wsh.updateWindowSize();
+ else
+ event = processCursorEvent(GHOST_kEventCursorMove, window);
break;
case WM_MOUSEWHEEL:
/* The WM_MOUSEWHEEL message is sent to the focus window
@@ -1105,6 +1120,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
* will not be dispatched to OUR active window if we minimize one of OUR windows. */
+ if(LOWORD(wParam)==WA_INACTIVE)
+ window->lostMouseCapture();
+
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
@@ -1235,6 +1253,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* In GHOST, we let DefWindowProc call the timer callback.
*/
break;
+ case WM_CANCELMODE:
+ if(window->m_wsh.isWinChanges())
+ window->m_wsh.cancel();
+
}
}
else {
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 2b1bdfa78f0..e5e734e4e57 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -272,6 +272,9 @@ GHOST_WindowWin32::GHOST_WindowWin32(
// Store a pointer to this class in the window structure
::SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG_PTR) this);
+ m_wsh.setHWND(m_hWnd);
+ m_wsh.setMinSize(320, 240);
+
// Store the device context
m_hDC = ::GetDC(m_hWnd);
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 2af4b703930..d46f1b61493 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -38,6 +38,7 @@
#endif // WIN32
#include "GHOST_Window.h"
+#include "GHOST_SizerWin32.h"
#include "GHOST_TaskbarWin32.h"
#define _WIN32_WINNT 0x501 // require Windows XP or newer
@@ -280,6 +281,8 @@ public:
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
+ GHOST_SizerWin32 m_wsh;
+
protected:
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);