[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55925] trunk/blender/intern/ghost: Live window resizing on Windows

Alexander Kuznetsov kuzsasha at gmail.com
Tue Apr 9 19:21:05 CEST 2013


Revision: 55925
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55925
Author:   alexk
Date:     2013-04-09 17:21:05 +0000 (Tue, 09 Apr 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/intern/ghost/CMakeLists.txt
    trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h

Added Paths:
-----------
    trunk/blender/intern/ghost/intern/GHOST_SizerWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_SizerWin32.h

Modified: trunk/blender/intern/ghost/CMakeLists.txt
===================================================================
--- trunk/blender/intern/ghost/CMakeLists.txt	2013-04-09 16:20:24 UTC (rev 55924)
+++ trunk/blender/intern/ghost/CMakeLists.txt	2013-04-09 17:21:05 UTC (rev 55925)
@@ -296,6 +296,7 @@
 		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 @@
 		intern/GHOST_SystemPathsWin32.h
 		intern/GHOST_WindowWin32.h
 		intern/GHOST_TaskbarWin32.h
+		intern/GHOST_SizerWin32.h
 	)
 
 	if(WITH_INPUT_NDOF)

Added: trunk/blender/intern/ghost/intern/GHOST_SizerWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SizerWin32.cpp	                        (rev 0)
+++ trunk/blender/intern/ghost/intern/GHOST_SizerWin32.cpp	2013-04-09 17:21:05 UTC (rev 55925)
@@ -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

Added: trunk/blender/intern/ghost/intern/GHOST_SizerWin32.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SizerWin32.h	                        (rev 0)
+++ trunk/blender/intern/ghost/intern/GHOST_SizerWin32.h	2013-04-09 17:21:05 UTC (rev 55925)
@@ -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

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2013-04-09 16:20:24 UTC (rev 55924)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2013-04-09 17:21:05 UTC (rev 55925)
@@ -400,7 +400,7 @@
 	}
 
 	if (success) {
-		WNDCLASSW wc;
+		WNDCLASSW wc = {0};
 		wc.style = CS_HREDRAW | CS_VREDRAW;
 		wc.lpfnWndProc = s_wndProc;
 		wc.cbClsExtra = 0;
@@ -412,7 +412,7 @@
 			::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 @@
 					 * 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 @@
 					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 @@
 					}
 					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 @@
 					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 @@
 					 * In GHOST, we let DefWindowProc call the timer callback.
 					 */
 					break;
+				case WM_CANCELMODE:
+					if(window->m_wsh.isWinChanges())
+						window->m_wsh.cancel();
+
 			}
 		}
 		else {

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp	2013-04-09 16:20:24 UTC (rev 55924)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp	2013-04-09 17:21:05 UTC (rev 55925)
@@ -272,6 +272,9 @@
 		// Store a pointer to this class in the window structure

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list