瀏覽代碼

Move/resize work adequately

Marko Pintera 12 年之前
父節點
當前提交
63b75b834b

+ 6 - 2
BansheeEngine/Source/BsGUIManager.cpp

@@ -13,6 +13,7 @@
 #include "CmException.h"
 #include "CmInput.h"
 #include "CmPass.h"
+#include "CmDebug.h"
 
 using namespace CamelotFramework;
 
@@ -44,8 +45,8 @@ namespace BansheeEngine
 		:mMouseOverElement(nullptr), mMouseOverWidget(nullptr), mSeparateMeshesByWidget(true), mActiveElement(nullptr), 
 		mActiveWidget(nullptr), mActiveMouseButton(GUIMouseButton::Left), mKeyboardFocusElement(nullptr), mKeyboardFocusWidget(nullptr)
 	{
-		mOnButtonDownConn = gInput().onKeyDown.connect(boost::bind(&GUIManager::onButtonDown, this, _1));
-		mOnButtonUpConn = gInput().onKeyUp.connect(boost::bind(&GUIManager::onButtonUp, this, _1));
+		mOnButtonDownConn = gInput().onButtonDown.connect(boost::bind(&GUIManager::onButtonDown, this, _1));
+		mOnButtonUpConn = gInput().onButtonUp.connect(boost::bind(&GUIManager::onButtonUp, this, _1));
 		mOnMouseMovedConn = gInput().onMouseMoved.connect(boost::bind(&GUIManager::onMouseMoved, this, _1));
 		mOnTextInputConn = gInput().onCharInput.connect(boost::bind(&GUIManager::onTextInput, this, _1)); 
 
@@ -605,6 +606,7 @@ namespace BansheeEngine
 						{
 							topMostElement = element;
 							topMostDepth = element->_getDepth();
+							widgetInFocus = widget;
 
 							break;
 						}
@@ -660,6 +662,8 @@ namespace BansheeEngine
 				// Send MouseMove event
 				if(mLastCursorLocalPos != localPos)
 				{
+					LOGWRN(toString(event.screenPos.x) + " - " + toString(event.screenPos.y) + " - " + toString((UINT32)widgetInFocus));
+
 					mMouseEvent.setMouseMoveData(topMostElement, localPos);
 					widgetInFocus->_mouseEvent(topMostElement, mMouseEvent);
 

+ 12 - 3
CamelotCore/Include/CmInput.h

@@ -15,8 +15,8 @@ namespace CamelotFramework
 		Input();
 		~Input();
 
-		boost::signal<void(const ButtonEvent&)> onKeyDown;
-		boost::signal<void(const ButtonEvent&)> onKeyUp;
+		boost::signal<void(const ButtonEvent&)> onButtonDown;
+		boost::signal<void(const ButtonEvent&)> onButtonUp;
 		boost::signal<void(const TextInputEvent&)> onCharInput;
 
 		boost::signal<void(const MouseEvent&)> onMouseMoved;
@@ -28,7 +28,6 @@ namespace CamelotFramework
 		 */
 		void update();
 
-
 		/**
 		 * @brief	Returns smoothed mouse/joystick input in the horizontal axis.
 		 *
@@ -47,10 +46,20 @@ namespace CamelotFramework
 
 		Int2 getMousePosition() const { return mMouseAbsPos; }
 
+		// Thread safe. Will only be processed on next "update".
+		void simulateButtonDown(ButtonCode code);
+
+		// Thread safe. Will only be processed on next "update".
+		void simulateButtonUp(ButtonCode code);
+
 	private:
 		std::shared_ptr<RawInputHandler> mRawInputHandler;
 		std::shared_ptr<OSInputHandler> mOSInputHandler;
 
+		CM_MUTEX(mSimulatedInputMutex);
+		Vector<ButtonCode>::type mSimulatedButtonUp;
+		Vector<ButtonCode>::type mSimulatedButtonDown;
+
 		float mSmoothHorizontalAxis;
 		float mSmoothVerticalAxis;
 

+ 37 - 4
CamelotCore/Source/CmInput.cpp

@@ -78,6 +78,25 @@ namespace CamelotFramework
 		else
 			mRawInputHandler->update();
 
+		Vector<ButtonCode>::type simulatedUp;
+		Vector<ButtonCode>::type simulatedDown;
+
+		{
+			CM_LOCK_MUTEX(mSimulatedInputMutex);
+
+			simulatedUp = mSimulatedButtonUp;
+			simulatedDown = mSimulatedButtonDown;
+
+			mSimulatedButtonUp.clear();
+			mSimulatedButtonDown.clear();
+		}
+
+		for(auto& buttonCode : simulatedDown)
+			buttonDown(buttonCode);
+
+		for(auto& buttonCode : simulatedUp)
+			buttonUp(buttonCode);
+
 		updateSmoothInput();
 	}
 
@@ -94,12 +113,12 @@ namespace CamelotFramework
 	{
 		mKeyState[code & 0x0000FFFF] = true;
 
-		if(!onKeyDown.empty())
+		if(!onButtonDown.empty())
 		{
 			ButtonEvent btnEvent;
 			btnEvent.buttonCode = code;
 
-			onKeyDown(btnEvent);
+			onButtonDown(btnEvent);
 		}
 	}
 
@@ -107,12 +126,12 @@ namespace CamelotFramework
 	{
 		mKeyState[code & 0x0000FFFF] = false;
 
-		if(!onKeyUp.empty())
+		if(!onButtonUp.empty())
 		{
 			ButtonEvent btnEvent;
 			btnEvent.buttonCode = code;
 
-			onKeyUp(btnEvent);
+			onButtonUp(btnEvent);
 		}
 	}
 
@@ -163,6 +182,20 @@ namespace CamelotFramework
 		return mKeyState[button & 0x0000FFFF];
 	}
 
+	void Input::simulateButtonDown(ButtonCode code)
+	{
+		CM_LOCK_MUTEX(mSimulatedInputMutex);
+
+		mSimulatedButtonDown.push_back(code);
+	}
+
+	void Input::simulateButtonUp(ButtonCode code)
+	{
+		CM_LOCK_MUTEX(mSimulatedInputMutex);
+
+		mSimulatedButtonUp.push_back(code);
+	}
+
 	void Input::updateSmoothInput()
 	{
 		float currentTime = gTime().getTime();

+ 10 - 0
CamelotCore/Source/CmWindowEventUtilities.cpp

@@ -207,6 +207,16 @@ LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wPa
 
 		return 0;
 	}
+	case WM_NCLBUTTONUP:
+		{
+			int b = 5;
+			break;
+		}
+	case WM_LBUTTONUP:
+		{
+			int a = 5;
+			break;
+		}
 	case WM_MOUSEMOVE:
 		{
 			POINT mousePos;

+ 14 - 6
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -8,10 +8,16 @@
 #include "CmTextureManager.h"
 #include "CmD3D11DriverList.h"
 #include "CmD3D11Driver.h"
+#include "CmInput.h"
 #include "CmException.h"
 
 namespace CamelotFramework
 {
+	void HACK_SendLMBUpEvent()
+	{
+		gInput().simulateButtonUp(BC_MOUSE_LEFT);
+	}
+
 	D3D11RenderWindow::D3D11RenderWindow(const RENDER_WINDOW_DESC& desc,D3D11Device& device, IDXGIFactory* DXGIFactory)
 		: RenderWindow(desc)
 		, mDevice(device)
@@ -581,7 +587,11 @@ namespace CamelotFramework
 			break;
 		}
 
-		SendMessage(mHWnd, WM_NCLBUTTONDOWN, dir, 0);
+		SendMessage(mHWnd, WM_SYSCOMMAND, SC_SIZE + 8, 0 );
+		//SetCapture(mHWnd);
+		//SendMessage(mHWnd, WM_NCLBUTTONDOWN, dir, 0);
+		HACK_SendLMBUpEvent();
+		//ReleaseCapture();
 	}
 
 	void D3D11RenderWindow::endResize()
@@ -592,6 +602,7 @@ namespace CamelotFramework
 	void D3D11RenderWindow::startMove()
 	{
 		SendMessage(mHWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
+		HACK_SendLMBUpEvent();
 	}
 
 	void D3D11RenderWindow::endMove()
@@ -693,9 +704,6 @@ namespace CamelotFramework
 		D3D11_TEXTURE2D_DESC BBDesc;
 		mBackBuffer->GetDesc(&BBDesc);
 
-		mWidth = BBDesc.Width;
-		mHeight = BBDesc.Height;
-
 		// create the render target view
 		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
 		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
@@ -743,8 +751,8 @@ namespace CamelotFramework
 			CM_EXCEPT(InternalErrorException, "Call to ResizeBuffers failed.");
 
 		mSwapChain->GetDesc(&mSwapChainDesc);
-		//mWidth = mSwapChainDesc.BufferDesc.Width;
-		//mHeight = mSwapChainDesc.BufferDesc.Height;
+		mWidth = mSwapChainDesc.BufferDesc.Width;
+		mHeight = mSwapChainDesc.BufferDesc.Height;
 		mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state
 
 		createSizeDependedD3DResources();

+ 13 - 0
CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp

@@ -26,6 +26,7 @@ THE SOFTWARE.
 -----------------------------------------------------------------------------
 */
 #include "CmD3D9RenderWindow.h"
+#include "CmInput.h"
 #include "CmCoreThread.h"
 #include "CmViewport.h"
 #include "CmException.h"
@@ -37,6 +38,16 @@ THE SOFTWARE.
 
 namespace CamelotFramework
 {
+	// HACK: During the move/resize modal loop no mouse messages will be posted, which means we will
+	// never receive a "mouse up" event, even though user had to release the mouse to stop the loop. But our GUI system
+	// relies on mouse down being followed by mouse up otherwise things end start to break a bit. So here we simulate 
+	// the mouse release. 
+	// Note: This is possible because SendMessage won't return until user releases the mouse and modal loop is done.
+	void HACK_SendLMBUpEvent()
+	{
+		gInput().simulateButtonUp(BC_MOUSE_LEFT);
+	}
+
 	D3D9RenderWindow::D3D9RenderWindow(const RENDER_WINDOW_DESC& desc, HINSTANCE instance)
         : RenderWindow(desc), mInstance(instance), mIsDepthBuffered(true)  
 	{
@@ -507,6 +518,7 @@ namespace CamelotFramework
 		}
 
 		SendMessage(mHWnd, WM_NCLBUTTONDOWN, dir, 0);
+		HACK_SendLMBUpEvent();
 	}
 
 	void D3D9RenderWindow::endResize()
@@ -517,6 +529,7 @@ namespace CamelotFramework
 	void D3D9RenderWindow::startMove()
 	{
 		SendMessage(mHWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
+		HACK_SendLMBUpEvent();
 	}
 
 	void D3D9RenderWindow::endMove()

+ 14 - 1
CamelotGLRenderer/Source/CmWin32Window.cpp

@@ -30,6 +30,7 @@ THE SOFTWARE.
 #define _WIN32_WINNT 0x0500
 #endif
 #include "CmWin32Window.h"
+#include "CmInput.h"
 #include "CmRenderSystem.h"
 #include "CmCoreThread.h"
 #include "CmException.h"
@@ -38,7 +39,17 @@ THE SOFTWARE.
 #include "CmWindowEventUtilities.h"
 #include "CmGLPixelFormat.h"
 
-namespace CamelotFramework {
+namespace CamelotFramework 
+{
+	// HACK: During the move/resize modal loop no mouse messages will be posted, which means we will
+	// never receive a "mouse up" event, even though user had to release the mouse to stop the loop. But our GUI system
+	// relies on mouse down being followed by mouse up otherwise things end start to break a bit. So here we simulate 
+	// the mouse release. 
+	// Note: This is possible because SendMessage won't return until user releases the mouse and modal loop is done.
+	void HACK_SendLMBUpEvent()
+	{
+		gInput().simulateButtonUp(BC_MOUSE_LEFT);
+	}
 
 	#define _MAX_CLASS_NAME_ 128
 
@@ -756,6 +767,7 @@ namespace CamelotFramework {
 		}
 
 		SendMessage(mHWnd, WM_NCLBUTTONDOWN, dir, 0);
+		HACK_SendLMBUpEvent();
 	}
 
 	void Win32Window::endResize()
@@ -766,6 +778,7 @@ namespace CamelotFramework {
 	void Win32Window::startMove()
 	{
 		SendMessage(mHWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
+		HACK_SendLMBUpEvent();
 	}
 
 	void Win32Window::endMove()

+ 16 - 0
CamelotUtility/Source/CmLog.cpp

@@ -1,6 +1,8 @@
 #include "CmLog.h"
 #include "boost/signal.hpp"
 
+void dbg_VSLog(const CamelotFramework::String& message);
+
 namespace CamelotFramework
 {
 	LogEntry::LogEntry(const String& msg, const String& level)
@@ -27,6 +29,8 @@ namespace CamelotFramework
 
 		doOnEntryAdded(*newEntry);
 
+		dbg_VSLog(message);
+
 		if(mAutoSave)
 			flush();
 	}
@@ -58,4 +62,16 @@ namespace CamelotFramework
 	{
 		onEntryAdded(entry);
 	}
+
+
 }
+
+// TODO: Debug only - Remove later
+
+#include <windows.h>
+
+void dbg_VSLog(const CamelotFramework::String& message)
+{
+	OutputDebugString(message.c_str());
+	OutputDebugString("\n");
+}