Parcourir la source

Added support for mouse wheel scroll events

Marko Pintera il y a 12 ans
Parent
commit
0d59d8caf2

+ 4 - 0
BansheeEngine/Include/BsGUIMouseEvent.h

@@ -12,6 +12,7 @@ namespace BansheeEngine
 		MouseDown,
 		MouseUp,
 		MouseMove,
+		MouseWheelScroll,
 		MouseDrag,
 		MouseDragStart,
 		MouseDragEnd
@@ -32,6 +33,7 @@ namespace BansheeEngine
 		GUIMouseEventType getType() const { return mType; }
 		GUIMouseButton getButton() const { return mButton; }
 		CM::Int2 getDragAmount() const { return mDragAmount; }
+		float getWheelScrollAmount() const { return mWheelScrollAmount; }
 		bool isButtonDown(GUIMouseButton button) const { return mButtonStates[(int)button]; }
 		GUIElement* getMouseOverElement() const { return mMouseOverElement; }
 
@@ -44,6 +46,7 @@ namespace BansheeEngine
 		bool mButtonStates[GUIMouseButton::Count];
 		CM::Int2 mPosition;
 		CM::Int2 mDragAmount;
+		float mWheelScrollAmount;
 		GUIMouseEventType mType;
 		GUIMouseButton mButton;
 		GUIElement* mMouseOverElement;
@@ -55,6 +58,7 @@ namespace BansheeEngine
 		void setMouseOverData(GUIElement* mouseOverElement, const CM::Int2& position);
 		void setMouseOutData(GUIElement* mouseOverElement, const CM::Int2& position);
 		void setMouseMoveData(GUIElement* mouseOverElement, const CM::Int2& position);
+		void setMouseWheelScrollData(GUIElement* mouseOverElement, float scrollAmount);
 		void setMouseUpData(GUIElement* mouseOverElement, const CM::Int2& position, GUIMouseButton button);
 		void setMouseDownData(GUIElement* mouseOverElement, const CM::Int2& position, GUIMouseButton button);
 

+ 2 - 0
BansheeEngine/Include/BsGUIScrollArea.h

@@ -67,6 +67,8 @@ namespace BansheeEngine
 		static const CM::UINT32 ScrollBarWidth;
 		static const CM::UINT32 MinHandleSize;
 
+		virtual bool mouseEvent(const GUIMouseEvent& ev);
+
 		void vertScrollUpdate(float pct);
 		void horzScrollUpdate(float pct);
 		void _updateLayoutInternal(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height,

+ 6 - 2
BansheeEngine/Source/BsGUIManager.cpp

@@ -766,13 +766,17 @@ 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);
 
 					mLastCursorLocalPos = localPos;
 				}
+
+				if(Math::Abs(event.mouseWheelScrollAmount) > 0.00001f)
+				{
+					mMouseEvent.setMouseWheelScrollData(topMostElement, event.mouseWheelScrollAmount);
+					widgetInFocus->_mouseEvent(topMostElement, mMouseEvent);
+				}
 			}
 		}
 

+ 19 - 1
BansheeEngine/Source/BsGUIMouseEvent.cpp

@@ -6,7 +6,7 @@ namespace BansheeEngine
 {
 	GUIMouseEvent::GUIMouseEvent()
 		:mType(GUIMouseEventType::MouseMove), mButton(GUIMouseButton::Left), mMouseOverElement(nullptr),
-		mShift(false), mCtrl(false), mAlt(false)
+		mShift(false), mCtrl(false), mAlt(false), mWheelScrollAmount(0.0f)
 	{
 
 	}
@@ -25,6 +25,7 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = GUIMouseButton::Left;
 		mDragAmount = Int2();
+		mWheelScrollAmount = 0.0f;
 	}
 
 	void GUIMouseEvent::setMouseOutData(GUIElement* mouseOverElement, const Int2& position)
@@ -34,6 +35,7 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = GUIMouseButton::Left;
 		mDragAmount = Int2();
+		mWheelScrollAmount = 0.0f;
 	}
 
 	void GUIMouseEvent::setMouseMoveData(GUIElement* mouseOverElement, const Int2& position)
@@ -43,6 +45,17 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = GUIMouseButton::Left;
 		mDragAmount = Int2();
+		mWheelScrollAmount = 0.0f;
+	}
+
+	void GUIMouseEvent::setMouseWheelScrollData(GUIElement* mouseOverElement, float scrollAmount)
+	{
+		mType = GUIMouseEventType::MouseWheelScroll;
+		mPosition = Int2();
+		mMouseOverElement = mouseOverElement;
+		mButton = GUIMouseButton::Left;
+		mDragAmount = Int2();
+		mWheelScrollAmount = scrollAmount;
 	}
 
 	void GUIMouseEvent::setMouseUpData(GUIElement* mouseOverElement, const Int2& position, GUIMouseButton button)
@@ -52,6 +65,7 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = button;
 		mDragAmount = Int2();
+		mWheelScrollAmount = 0.0f;
 	}
 
 	void GUIMouseEvent::setMouseDownData(GUIElement* mouseOverElement, const Int2& position, GUIMouseButton button)
@@ -61,6 +75,7 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = button;
 		mDragAmount = Int2();
+		mWheelScrollAmount = 0.0f;
 	}
 
 	void GUIMouseEvent::setMouseDragData(GUIElement* mouseOverElement, const Int2& position, const Int2& dragAmount)
@@ -70,6 +85,7 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = GUIMouseButton::Left;
 		mDragAmount = dragAmount;
+		mWheelScrollAmount = 0.0f;
 	}
 
 	void GUIMouseEvent::setMouseDragStartData(GUIElement* mouseOverElement, const Int2& position)
@@ -79,6 +95,7 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = GUIMouseButton::Left;
 		mDragAmount = Int2();
+		mWheelScrollAmount = 0.0f;
 	}
 
 	void GUIMouseEvent::setMouseDragEndData(GUIElement* mouseOverElement, const Int2& position)
@@ -88,5 +105,6 @@ namespace BansheeEngine
 		mMouseOverElement = mouseOverElement;
 		mButton = GUIMouseButton::Left;
 		mDragAmount = Int2();
+		mWheelScrollAmount = 0.0f;
 	}
 }

+ 12 - 0
BansheeEngine/Source/BsGUIScrollArea.cpp

@@ -7,6 +7,7 @@
 #include "BsGUISkin.h"
 #include "BsGUIScrollBarVert.h"
 #include "BsGUIScrollBarHorz.h"
+#include "BsGUIMouseEvent.h"
 #include "CmException.h"
 
 using namespace CamelotFramework;
@@ -215,6 +216,17 @@ namespace BansheeEngine
 		markContentAsDirty();
 	}
 
+	bool GUIScrollArea::mouseEvent(const GUIMouseEvent& ev)
+	{
+		if(ev.getType() == GUIMouseEventType::MouseWheelScroll)
+		{
+			// TODO
+			int a = 5;
+		}
+
+		return false;
+	}
+
 	GUIScrollArea* GUIScrollArea::create(GUIWidget& parent, const GUIElementStyle* style)
 	{
 		if(style == nullptr)

+ 1 - 1
CamelotCore/Include/CmInput.h

@@ -87,7 +87,7 @@ namespace CamelotFramework
 		/**
 		 * @brief	Mouse movement as OS reports it. Used for screen cursor position.
 		 */
-		void mouseMoved(const Int2& screenPos);
+		void mouseMoved(const Int2& screenPos, float mouseWheelScrollAmount);
 		
 		/**
 		 * @brief	Updates the axis input values that need smoothing.

+ 2 - 1
CamelotCore/Include/CmInputFwd.h

@@ -252,10 +252,11 @@ namespace CamelotFramework
 	{
 	public:
 		MouseEvent()
-			:mIsUsed(false)
+			:mIsUsed(false), mouseWheelScrollAmount(0.0f)
 		{ }
 
 		Int2 screenPos;
+		float mouseWheelScrollAmount;
 
 		bool isUsed() const { return mIsUsed; }
 		void markAsUsed() const { mIsUsed = true; }

+ 8 - 1
CamelotCore/Include/CmOSInputHandler.h

@@ -20,7 +20,7 @@ namespace CamelotFramework
 		virtual ~OSInputHandler();
 
 		boost::signal<void(UINT32)> onCharInput;
-		boost::signal<void(const Int2&)> onMouseMoved;
+		boost::signal<void(const Int2&, float)> onMouseMoved;
 
 		/**
 			* @brief	Called every frame by InputManager. Capture input here if needed.
@@ -36,10 +36,12 @@ namespace CamelotFramework
 		CM_MUTEX(mOSInputMutex);
 		Int2 mLastMousePos;
 		Int2 mMousePosition;
+		float mMouseScroll;
 		WString mInputString;
 
 		boost::signals::connection mCharInputConn;
 		boost::signals::connection mMouseMovedConn;
+		boost::signals::connection mMouseWheelScrolledConn;
 
 		/**
 		 * @brief	Called from the message loop.
@@ -50,5 +52,10 @@ namespace CamelotFramework
 		 * @brief	Called from the message loop.
 		 */
 		void mouseMoved(const Int2& mousePos);
+
+		/**
+		 * @brief	Called from the message loop.
+		 */
+		void mouseWheelScrolled(float scrollPos);
 	};
 }

+ 1 - 0
CamelotCore/Include/CmWindowEventUtilities.h

@@ -91,6 +91,7 @@ namespace CamelotFramework
 		static Windows _msWindows;
 
 		static boost::signal<void(const Int2&)> onMouseMoved;
+		static boost::signal<void(float)> onMouseWheelScrolled;
 		static boost::signal<void(UINT32)> onCharInput;
 	};
 	/** @} */

+ 3 - 2
CamelotCore/Source/CmInput.cpp

@@ -32,7 +32,7 @@ namespace CamelotFramework
 		mOSInputHandler = cm_shared_ptr<OSInputHandler>();
 
 		mOSInputHandler->onCharInput.connect(boost::bind(&Input::charInput, this, _1));
-		mOSInputHandler->onMouseMoved.connect(boost::bind(&Input::mouseMoved, this, _1));
+		mOSInputHandler->onMouseMoved.connect(boost::bind(&Input::mouseMoved, this, _1, _2));
 
 		RenderWindowManager::instance().onFocusGained.connect(boost::bind(&Input::inputWindowChanged, this, _1));
 	}
@@ -143,7 +143,7 @@ namespace CamelotFramework
 		mAxes[(int)axis] = state;
 	}
 
-	void Input::mouseMoved(const Int2& screenPos)
+	void Input::mouseMoved(const Int2& screenPos, float mouseWheelScrollAmount)
 	{
 		mMouseAbsPos = screenPos;
 
@@ -151,6 +151,7 @@ namespace CamelotFramework
 		{
 			MouseEvent mouseEvent;
 			mouseEvent.screenPos = screenPos;
+			mouseEvent.mouseWheelScrollAmount = mouseWheelScrollAmount;
 
 			onMouseMoved(mouseEvent);
 		}

+ 16 - 2
CamelotCore/Source/CmOSInputHandler.cpp

@@ -1,24 +1,29 @@
 #include "CmOSInputHandler.h"
 #include "CmWindowEventUtilities.h"
+#include "CmMath.h"
 
 namespace CamelotFramework
 {
 	OSInputHandler::OSInputHandler()
+		:mMouseScroll(0.0f)
 	{
 		mCharInputConn = WindowEventUtilities::onCharInput.connect(boost::bind(&OSInputHandler::charInput, this, _1));
 		mMouseMovedConn = WindowEventUtilities::onMouseMoved.connect(boost::bind(&OSInputHandler::mouseMoved, this, _1));
+		mMouseWheelScrolledConn  = WindowEventUtilities::onMouseWheelScrolled.connect(boost::bind(&OSInputHandler::mouseWheelScrolled, this, _1));
 	}
 
 	OSInputHandler::~OSInputHandler()
 	{
 		mCharInputConn.disconnect();
 		mMouseMovedConn.disconnect();
+		mMouseWheelScrolledConn.disconnect();
 	}
 
 	void OSInputHandler::update()
 	{
 		WString inputString;
 		Int2 mousePosition;
+		float mouseScroll;
 
 		{
 			CM_LOCK_MUTEX(mOSInputMutex);
@@ -26,12 +31,14 @@ namespace CamelotFramework
 			mInputString.clear();
 
 			mousePosition = mMousePosition;
+			mouseScroll = mMouseScroll;
+			mMouseScroll = 0.0f;
 		}
 
-		if(mousePosition != mLastMousePos)
+		if(mousePosition != mLastMousePos || (Math::Abs(mouseScroll) > 0.00001f))
 		{
 			if(!onMouseMoved.empty())
-				onMouseMoved(mousePosition);
+				onMouseMoved(mousePosition, mouseScroll);
 
 			mLastMousePos = mousePosition;
 		}
@@ -58,4 +65,11 @@ namespace CamelotFramework
 
 		mMousePosition = mousePos;
 	}
+
+	void OSInputHandler::mouseWheelScrolled(float scrollPos)
+	{
+		CM_LOCK_MUTEX(mOSInputMutex);
+
+		mMouseScroll = scrollPos;
+	}
 }

+ 11 - 0
CamelotCore/Source/CmWindowEventUtilities.cpp

@@ -41,6 +41,7 @@ using namespace CamelotFramework;
 
 WindowEventUtilities::Windows WindowEventUtilities::_msWindows;
 boost::signal<void(const Int2&)> WindowEventUtilities::onMouseMoved;
+boost::signal<void(float)> WindowEventUtilities::onMouseWheelScrolled;
 boost::signal<void(CamelotFramework::UINT32)> WindowEventUtilities::onCharInput;
 
 //--------------------------------------------------------------------------------//
@@ -229,6 +230,16 @@ LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wPa
 			if(!onMouseMoved.empty())
 				onMouseMoved(Int2(mousePos.x, mousePos.y));
 
+			return true;
+		}
+	case WM_MOUSEWHEEL:
+		{
+			INT16 wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
+
+			float wheelDeltaFlt = wheelDelta / (float)WHEEL_DELTA;
+			if(!onMouseWheelScrolled.empty())
+				onMouseWheelScrolled(wheelDeltaFlt);
+
 			return true;
 		}
 	case WM_DEADCHAR:

+ 2 - 0
TODO.txt

@@ -33,6 +33,8 @@ IMMEDIATE:
     - Make sure GUI system uses a dummy texture if one isn't available
 	- SpriteTexture keeps a static reference to DUmmyTexture which I need to release before shutdown
 
+- When the scroll contents dont fit vertically because of the horz scrollbar, the right side of the window frame gets cut off
+  - ScrollArea has no way of receiving mouse events
 - Scrolling the window shouldn't remove text selection
 - Hover colors of the scroll bar are wrong
 - Ability to scroll by just mousing over and moving the scroll wheel