Browse Source

Window resize works

Marko Pintera 12 years ago
parent
commit
e6fcc7f191

+ 10 - 0
BansheeEngine/Source/BsGUIManager.cpp

@@ -438,6 +438,16 @@ namespace BansheeEngine
 
 
 			GUIMouseButton guiButton = buttonToMouseButton(event.buttonCode);
 			GUIMouseButton guiButton = buttonToMouseButton(event.buttonCode);
 
 
+			// HACK: This should never happen, as MouseUp was meant to happen before another MouseDown,
+			// and MouseUp will clear the active element. HOWEVER Windows doesn't send a MouseUp message when resizing
+			// a window really fast. My guess is that the cursor gets out of bounds and message is sent to another window.
+			if(mActiveMouseButton == guiButton && mActiveElement != nullptr) 
+			{
+				mActiveElement = nullptr;
+				mActiveWidget = nullptr;
+				mActiveMouseButton = GUIMouseButton::Left;
+			}
+
 			// We only check for mouse down if mouse isn't already being held down, and we are hovering over an element
 			// We only check for mouse down if mouse isn't already being held down, and we are hovering over an element
 			bool acceptMouseDown = mActiveElement == nullptr && mMouseOverElement != nullptr;
 			bool acceptMouseDown = mActiveElement == nullptr && mMouseOverElement != nullptr;
 			if(acceptMouseDown)
 			if(acceptMouseDown)

+ 36 - 6
BansheeEngine/Source/BsGUIWindowFrame.cpp

@@ -260,17 +260,47 @@ namespace BansheeEngine
 
 
 				return true;
 				return true;
 			}
 			}
+		}
+
+		if(ev.getType() == GUIMouseEventType::MouseDown)
+		{
+			Rect contentBounds = getContentBounds();
 
 
-			Int2 dragAmount = ev.getDragAmount();
-			if(dragAmount.x != 0 || dragAmount.y != 0)
+			FrameSubArea subArea = getFrameSubArea(ev.getPosition(), contentBounds);
+			if(subArea != FrameSubArea::None && subArea != FrameSubArea::Middle)
 			{
 			{
 				RenderWindow* window = _getParentWidget().getOwnerWindow();
 				RenderWindow* window = _getParentWidget().getOwnerWindow();
+				RenderWindowPtr windowPtr = std::static_pointer_cast<RenderWindow>(window->getThisPtr());
 
 
-				UINT32 newWidth = window->getWidth() + dragAmount.x;
-				UINT32 newHeight = window->getHeight() + dragAmount.y;
+				switch (subArea)
+				{
+				case BansheeEngine::FrameSubArea::TopLeft:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::TopLeft);
+					break;
+				case BansheeEngine::FrameSubArea::TopCenter:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::Top);
+					break;
+				case BansheeEngine::FrameSubArea::TopRight:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::TopRight);
+					break;
+				case BansheeEngine::FrameSubArea::MiddleLeft:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::Left);
+					break;
+				case BansheeEngine::FrameSubArea::MiddleRight:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::Right);
+					break;
+				case BansheeEngine::FrameSubArea::BottomLeft:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::BottomLeft);
+					break;
+				case BansheeEngine::FrameSubArea::BottomCenter:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::Bottom);
+					break;
+				case BansheeEngine::FrameSubArea::BottomRight:
+					gMainCA().startResize(windowPtr, WindowResizeDirection::BottomRight);
+					break;
+				}
 
 
-				RenderWindowPtr windowPtr = std::static_pointer_cast<RenderWindow>(window->getThisPtr());
-				gMainCA().resizeWindow(windowPtr, newWidth, newHeight);
+				return true;
 			}
 			}
 		}
 		}
 
 

+ 0 - 2
CamelotClient/CmEditorWindow.cpp

@@ -94,8 +94,6 @@ namespace BansheeEditor
 		//titleBarBackgroundArea->getLayout().addElement(GUITexture::create(*mGUI, GUIImageScaleMode::RepeatToFit, GUILayoutOptions::expandableXY(), mGUI->getGUISkin()->getStyle("TitleBarBg")));
 		//titleBarBackgroundArea->getLayout().addElement(GUITexture::create(*mGUI, GUIImageScaleMode::RepeatToFit, GUILayoutOptions::expandableXY(), mGUI->getGUISkin()->getStyle("TitleBarBg")));
 		//titleBarBackgroundArea->getLayout().addSpace(1);
 		//titleBarBackgroundArea->getLayout().addSpace(1);
 		
 		
-		gMainCA().resizeWindow(mRenderWindow, 400, 300);
-
 		//mRenderWindow->resize(300, 250);
 		//mRenderWindow->resize(300, 250);
 		//mRenderWindow->setVisible(false);
 		//mRenderWindow->setVisible(false);
 	}
 	}

+ 10 - 0
CamelotCore/Include/CmCoreThreadAccessor.h

@@ -242,6 +242,16 @@ namespace CamelotFramework
 			mCommandQueue->queue(boost::bind(&RenderWindow::reposition, renderWindow.get(), left, top));
 			mCommandQueue->queue(boost::bind(&RenderWindow::reposition, renderWindow.get(), left, top));
 		}
 		}
 
 
+		void startResize(RenderWindowPtr& renderWindow, WindowResizeDirection direction)
+		{
+			mCommandQueue->queue(boost::bind(&RenderWindow::startResize, renderWindow.get(), direction));
+		}
+
+		void endResize(RenderWindowPtr& renderWindow)
+		{
+			mCommandQueue->queue(boost::bind(&RenderWindow::endResize, renderWindow.get()));
+		}
+
 		/**
 		/**
 		 * @brief	Makes all the currently queued commands available to the core thread. They will be executed
 		 * @brief	Makes all the currently queued commands available to the core thread. They will be executed
 		 * 			as soon as the core thread is ready.
 		 * 			as soon as the core thread is ready.

+ 13 - 0
CamelotCore/Include/CmRenderWindow.h

@@ -40,6 +40,12 @@ namespace CamelotFramework
 		Fixed
 		Fixed
 	};
 	};
 
 
+	enum class WindowResizeDirection
+	{
+		Left, TopLeft, Top, TopRight,
+		Right, BottomRight, Bottom, BottomLeft
+	};
+
 	struct CM_EXPORT RENDER_WINDOW_DESC
 	struct CM_EXPORT RENDER_WINDOW_DESC
 	{
 	{
 		RENDER_WINDOW_DESC()
 		RENDER_WINDOW_DESC()
@@ -153,6 +159,9 @@ namespace CamelotFramework
 		*/
 		*/
         virtual bool isFullScreen() const;
         virtual bool isFullScreen() const;
 
 
+		INT32 getLeft() const { return mLeft; }
+		INT32 getTop() const { return mTop; }
+
 		/**
 		/**
 		 * @brief	Indicates whether the window currently has keyboard focus.
 		 * @brief	Indicates whether the window currently has keyboard focus.
 		 */
 		 */
@@ -181,6 +190,10 @@ namespace CamelotFramework
 		virtual void _windowFocusLost();
 		virtual void _windowFocusLost();
 
 
 		virtual Int2 screenToWindowPos(const Int2& screenPos) const = 0;
 		virtual Int2 screenToWindowPos(const Int2& screenPos) const = 0;
+		virtual Int2 windowToScreenPos(const Int2& windowPos) const = 0;
+
+		virtual void startResize(WindowResizeDirection direction) = 0;
+		virtual void endResize() = 0;
 
 
 		virtual void destroy();
 		virtual void destroy();
 
 

+ 8 - 0
CamelotD3D11RenderSystem/Include/CmD3D11RenderWindow.h

@@ -60,6 +60,11 @@ namespace CamelotFramework
 		 */
 		 */
 		Int2 screenToWindowPos(const Int2& screenPos) const;
 		Int2 screenToWindowPos(const Int2& screenPos) const;
 
 
+		/**
+		 * @copydoc RenderWindow::windowToScreenPos
+		 */
+		Int2 windowToScreenPos(const Int2& windowPos) const;
+
 		/**
 		/**
 		 * @copydoc RenderWindow::getCustomAttribute
 		 * @copydoc RenderWindow::getCustomAttribute
 		 */
 		 */
@@ -70,6 +75,9 @@ namespace CamelotFramework
 		 */
 		 */
 		bool requiresTextureFlipping() const { return false; }
 		bool requiresTextureFlipping() const { return false; }
 
 
+		void startResize(WindowResizeDirection direction);
+		void endResize();
+
 		/**
 		/**
 		 * @copydoc RenderWindow::reposition
 		 * @copydoc RenderWindow::reposition
 		 */
 		 */

+ 50 - 2
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -532,8 +532,6 @@ namespace CamelotFramework
 	Int2 D3D11RenderWindow::screenToWindowPos(const Int2& screenPos) const
 	Int2 D3D11RenderWindow::screenToWindowPos(const Int2& screenPos) const
 	{
 	{
 		POINT pos;
 		POINT pos;
-
-		// Convert client coordinates to screen coordinates
 		pos.x = screenPos.x;
 		pos.x = screenPos.x;
 		pos.y = screenPos.y;
 		pos.y = screenPos.y;
 
 
@@ -541,6 +539,56 @@ namespace CamelotFramework
 		return Int2(pos.x, pos.y);
 		return Int2(pos.x, pos.y);
 	}
 	}
 
 
+	Int2 D3D11RenderWindow::windowToScreenPos(const Int2& windowPos) const
+	{
+		POINT pos;
+		pos.x = windowPos.x;
+		pos.y = windowPos.y;
+
+		ClientToScreen(mHWnd, &pos);
+		return Int2(pos.x, pos.y);
+	}
+
+
+	void D3D11RenderWindow::startResize(WindowResizeDirection direction)
+	{
+		WPARAM dir = HTLEFT;
+		switch(direction)
+		{
+		case WindowResizeDirection::Left:
+			dir = HTLEFT;
+			break;
+		case WindowResizeDirection::TopLeft:
+			dir = HTTOPLEFT;
+			break;
+		case WindowResizeDirection::Top:
+			dir = HTTOP;
+			break;
+		case WindowResizeDirection::TopRight:
+			dir = HTTOPRIGHT;
+			break;
+		case WindowResizeDirection::Right:
+			dir = HTRIGHT;
+			break;
+		case WindowResizeDirection::BottomRight:
+			dir = HTBOTTOMRIGHT;
+			break;
+		case WindowResizeDirection::Bottom:
+			dir = HTBOTTOM;
+			break;
+		case WindowResizeDirection::BottomLeft:
+			dir = HTBOTTOMLEFT;
+			break;
+		}
+
+		SendMessage(mHWnd, WM_NCLBUTTONDOWN, dir, 0);
+	}
+
+	void D3D11RenderWindow::endResize()
+	{
+
+	}
+
 	void D3D11RenderWindow::_windowMovedOrResized()
 	void D3D11RenderWindow::_windowMovedOrResized()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;

+ 8 - 0
CamelotD3D9Renderer/Include/CmD3D9RenderWindow.h

@@ -98,6 +98,14 @@ namespace CamelotFramework
 		 */
 		 */
 		Int2 screenToWindowPos(const Int2& screenPos) const;
 		Int2 screenToWindowPos(const Int2& screenPos) const;
 
 
+		/**
+		 * @copydoc RenderWindow::windowToScreenPos
+		 */
+		Int2 windowToScreenPos(const Int2& windowPos) const;
+
+		void startResize(WindowResizeDirection direction);
+		void endResize();
+
 		/**
 		/**
 		 * @copydoc RenderWindow::_windowMovedOrResized
 		 * @copydoc RenderWindow::_windowMovedOrResized
 		 */
 		 */

+ 49 - 2
CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp

@@ -451,8 +451,6 @@ namespace CamelotFramework
 	Int2 D3D9RenderWindow::screenToWindowPos(const Int2& screenPos) const
 	Int2 D3D9RenderWindow::screenToWindowPos(const Int2& screenPos) const
 	{
 	{
 		POINT pos;
 		POINT pos;
-
-		// Convert client coordinates to screen coordinates
 		pos.x = screenPos.x;
 		pos.x = screenPos.x;
 		pos.y = screenPos.y;
 		pos.y = screenPos.y;
 
 
@@ -460,6 +458,16 @@ namespace CamelotFramework
 		return Int2(pos.x, pos.y);
 		return Int2(pos.x, pos.y);
 	}
 	}
 
 
+	Int2 D3D9RenderWindow::windowToScreenPos(const Int2& windowPos) const
+	{
+		POINT pos;
+		pos.x = windowPos.x;
+		pos.y = windowPos.y;
+
+		ClientToScreen(mHWnd, &pos);
+		return Int2(pos.x, pos.y);
+	}
+
 	void D3D9RenderWindow::copyContentsToMemory(const PixelData &dst, FrameBuffer buffer)
 	void D3D9RenderWindow::copyContentsToMemory(const PixelData &dst, FrameBuffer buffer)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
@@ -467,6 +475,45 @@ namespace CamelotFramework
 		mDevice->copyContentsToMemory(this, dst, buffer);
 		mDevice->copyContentsToMemory(this, dst, buffer);
 	}
 	}
 
 
+	void D3D9RenderWindow::startResize(WindowResizeDirection direction)
+	{
+		WPARAM dir = HTLEFT;
+		switch(direction)
+		{
+		case WindowResizeDirection::Left:
+			dir = HTLEFT;
+			break;
+		case WindowResizeDirection::TopLeft:
+			dir = HTTOPLEFT;
+			break;
+		case WindowResizeDirection::Top:
+			dir = HTTOP;
+			break;
+		case WindowResizeDirection::TopRight:
+			dir = HTTOPRIGHT;
+			break;
+		case WindowResizeDirection::Right:
+			dir = HTRIGHT;
+			break;
+		case WindowResizeDirection::BottomRight:
+			dir = HTBOTTOMRIGHT;
+			break;
+		case WindowResizeDirection::Bottom:
+			dir = HTBOTTOM;
+			break;
+		case WindowResizeDirection::BottomLeft:
+			dir = HTBOTTOMLEFT;
+			break;
+		}
+
+		SendMessage(mHWnd, WM_NCLBUTTONDOWN, dir, 0);
+	}
+
+	void D3D9RenderWindow::endResize()
+	{
+
+	}
+
 	void D3D9RenderWindow::_windowMovedOrResized()
 	void D3D9RenderWindow::_windowMovedOrResized()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;

+ 8 - 0
CamelotGLRenderer/Include/CmWin32Window.h

@@ -88,6 +88,11 @@ namespace CamelotFramework
 		 */
 		 */
 		Int2 screenToWindowPos(const Int2& screenPos) const;
 		Int2 screenToWindowPos(const Int2& screenPos) const;
 
 
+		/**
+		 * @copydoc RenderWindow::windowToScreenPos
+		 */
+		Int2 windowToScreenPos(const Int2& windowPos) const;
+
 		/**
 		/**
 		 * @copydoc RenderWindow::getCustomAttribute
 		 * @copydoc RenderWindow::getCustomAttribute
 		 */
 		 */
@@ -103,6 +108,9 @@ namespace CamelotFramework
 		 */
 		 */
 		void _windowMovedOrResized(void);
 		void _windowMovedOrResized(void);
 
 
+		void startResize(WindowResizeDirection direction);
+		void endResize();
+
 		HWND _getWindowHandle() const { return mHWnd; }
 		HWND _getWindowHandle() const { return mHWnd; }
 		HDC _getHDC() const { return mHDC; }
 		HDC _getHDC() const { return mHDC; }
 		
 		

+ 49 - 2
CamelotGLRenderer/Source/CmWin32Window.cpp

@@ -644,8 +644,6 @@ namespace CamelotFramework {
 	Int2 Win32Window::screenToWindowPos(const Int2& screenPos) const
 	Int2 Win32Window::screenToWindowPos(const Int2& screenPos) const
 	{
 	{
 		POINT pos;
 		POINT pos;
-
-		// Convert client coordinates to screen coordinates
 		pos.x = screenPos.x;
 		pos.x = screenPos.x;
 		pos.y = screenPos.y;
 		pos.y = screenPos.y;
 
 
@@ -653,6 +651,16 @@ namespace CamelotFramework {
 		return Int2(pos.x, pos.y);
 		return Int2(pos.x, pos.y);
 	}
 	}
 
 
+	Int2 Win32Window::windowToScreenPos(const Int2& windowPos) const
+	{
+		POINT pos;
+		pos.x = windowPos.x;
+		pos.y = windowPos.y;
+
+		ClientToScreen(mHWnd, &pos);
+		return Int2(pos.x, pos.y);
+	}	
+
 	void Win32Window::getCustomAttribute( const String& name, void* pData ) const
 	void Win32Window::getCustomAttribute( const String& name, void* pData ) const
 	{
 	{
 		if( name == "GLCONTEXT" ) {
 		if( name == "GLCONTEXT" ) {
@@ -716,6 +724,45 @@ namespace CamelotFramework {
 		}
 		}
 	}
 	}
 
 
+	void Win32Window::startResize(WindowResizeDirection direction)
+	{
+		WPARAM dir = HTLEFT;
+		switch(direction)
+		{
+		case WindowResizeDirection::Left:
+			dir = HTLEFT;
+			break;
+		case WindowResizeDirection::TopLeft:
+			dir = HTTOPLEFT;
+			break;
+		case WindowResizeDirection::Top:
+			dir = HTTOP;
+			break;
+		case WindowResizeDirection::TopRight:
+			dir = HTTOPRIGHT;
+			break;
+		case WindowResizeDirection::Right:
+			dir = HTRIGHT;
+			break;
+		case WindowResizeDirection::BottomRight:
+			dir = HTBOTTOMRIGHT;
+			break;
+		case WindowResizeDirection::Bottom:
+			dir = HTBOTTOM;
+			break;
+		case WindowResizeDirection::BottomLeft:
+			dir = HTBOTTOMLEFT;
+			break;
+		}
+
+		SendMessage(mHWnd, WM_NCLBUTTONDOWN, dir, 0);
+	}
+
+	void Win32Window::endResize()
+	{
+
+	}
+
 	void Win32Window::_windowMovedOrResized()
 	void Win32Window::_windowMovedOrResized()
 	{
 	{
 		if (!mHWnd || IsIconic(mHWnd))
 		if (!mHWnd || IsIconic(mHWnd))

+ 2 - 14
TODO.txt

@@ -1,15 +1,5 @@
 ----------------------- CAMELOT 2D / GUI -----------------------------------------------------------
 ----------------------- CAMELOT 2D / GUI -----------------------------------------------------------
 
 
-----------------------------------------------------------------------------------------------
-
-When I'm canceling command queue commands I might be canceling important user commands.
- - (e.g. user schedules a resource update and I cancel the command)
- - render commands can be cancelled with no repercussions?
- - maybe I should someone block sim thread if its running too fast?
-   - input lag?
-
---------
-
 DebugDraw
 DebugDraw
  - DebugDraw support for AA lines
  - DebugDraw support for AA lines
  - Add DX9 and GL debug draw shaders
  - Add DX9 and GL debug draw shaders
@@ -22,12 +12,10 @@ I call waitUntilLoaded too many times. Sometimes 5-6 times in a single function.
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 
 
 IMMEDIATE:
 IMMEDIATE:
+ - Resizing twice in a row doesn't work because ButtonUp event apparently doesn't register
+ - Add startMove/endMove
  - It's possible to resize smaller than 0 and cause an exception
  - It's possible to resize smaller than 0 and cause an exception
  - Cursor doesn't stay inside the window we're resizing, window seems to resize slower than the cursor moves
  - Cursor doesn't stay inside the window we're resizing, window seems to resize slower than the cursor moves
- - OpenGL resize doesn't work - I believe its because its render thread works too slow and we call "cancelAll" on the command queue. Check out why is the render thread slow, and get rid of cancelAll(), it's not a valid approach
-  - Add special flag for commands that can or can't be dropped so I can still use "cancelAll"
-  - But just getting rid of "cancelAll" altogether is probably a better solution to get better performance, at the lost of some input lag
-    - Core and main threads should run in lockstep
  - Update debug camera so it uses callbacks
  - Update debug camera so it uses callbacks
  - Add support for diacritical marks
  - Add support for diacritical marks
  - onMovedOrResized is still used by Viewport
  - onMovedOrResized is still used by Viewport