浏览代码

Submenu drop down box buttons now have hover
Submenus close once you mouse over other sub-menu elements
GUIManager blocks input while drop down box is open

Marko Pintera 12 年之前
父节点
当前提交
51e037acb2

+ 1 - 0
BansheeEngine/Include/BsGUIManager.h

@@ -107,6 +107,7 @@ namespace BansheeEngine
 		// Drop down box
 		// Drop down box
 		bool mDropDownBoxOpenScheduled;
 		bool mDropDownBoxOpenScheduled;
 		bool mDropDownBoxActive;
 		bool mDropDownBoxActive;
+		bool mDropDownBoxCloseScheduled;
 		CM::HSceneObject mDropDownSO;
 		CM::HSceneObject mDropDownSO;
 		CM::GameObjectHandle<GUIDropDownBox> mDropDownBox;
 		CM::GameObjectHandle<GUIDropDownBox> mDropDownBox;
 		std::function<void(CM::UINT32)> mListBoxSelectionMade;
 		std::function<void(CM::UINT32)> mListBoxSelectionMade;

+ 1 - 1
BansheeEngine/Source/BsEngineGUI.cpp

@@ -560,7 +560,7 @@ namespace BansheeEngine
 
 
 		// DropDown entry button with expand
 		// DropDown entry button with expand
 		HTexture dropDownExpEntryBtnNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxEntryExpNormalTex));
 		HTexture dropDownExpEntryBtnNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxEntryExpNormalTex));
-		HTexture dropDownExpEntryBtnHover = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxEntryExpNormalTex));
+		HTexture dropDownExpEntryBtnHover = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxEntryExpHoverTex));
 
 
 		GUIElementStyle dropDownEntryExpBtnStyle;
 		GUIElementStyle dropDownEntryExpBtnStyle;
 		dropDownEntryExpBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownExpEntryBtnNormal));
 		dropDownEntryExpBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownExpEntryBtnNormal));

+ 1 - 0
BansheeEngine/Source/BsGUIDropDownBox.cpp

@@ -331,6 +331,7 @@ namespace BansheeEngine
 				else
 				else
 				{
 				{
 					entryBtn = GUIButton::create(*this, mElements[i].getLabel(), mEntryBtnStyle);
 					entryBtn = GUIButton::create(*this, mElements[i].getLabel(), mEntryBtnStyle);
+					entryBtn->onHover.connect(boost::bind(&GUIDropDownBox::closeSubMenu, this));
 					entryBtn->onClick.connect(boost::bind(&GUIDropDownBox::elementClicked, this,  i));
 					entryBtn->onClick.connect(boost::bind(&GUIDropDownBox::elementClicked, this,  i));
 				}
 				}
 
 

+ 40 - 13
BansheeEngine/Source/BsGUIManager.cpp

@@ -55,7 +55,8 @@ namespace BansheeEngine
 		:mMouseOverElement(nullptr), mMouseOverWidget(nullptr), mSeparateMeshesByWidget(true), mActiveElement(nullptr), 
 		:mMouseOverElement(nullptr), mMouseOverWidget(nullptr), mSeparateMeshesByWidget(true), mActiveElement(nullptr), 
 		mActiveWidget(nullptr), mActiveMouseButton(GUIMouseButton::Left), mKeyboardFocusElement(nullptr), mKeyboardFocusWidget(nullptr),
 		mActiveWidget(nullptr), mActiveMouseButton(GUIMouseButton::Left), mKeyboardFocusElement(nullptr), mKeyboardFocusWidget(nullptr),
 		mCaretTexture(nullptr), mCaretBlinkInterval(0.5f), mCaretLastBlinkTime(0.0f), mCaretColor(1.0f, 0.6588f, 0.0f), mIsCaretOn(false),
 		mCaretTexture(nullptr), mCaretBlinkInterval(0.5f), mCaretLastBlinkTime(0.0f), mCaretColor(1.0f, 0.6588f, 0.0f), mIsCaretOn(false),
-		mTextSelectionColor(1.0f, 0.6588f, 0.0f), mInputCaret(nullptr), mInputSelection(nullptr), mDropDownBoxActive(false), mDropDownBoxOpenScheduled(false)
+		mTextSelectionColor(1.0f, 0.6588f, 0.0f), mInputCaret(nullptr), mInputSelection(nullptr), mDropDownBoxActive(false), mDropDownBoxOpenScheduled(false),
+		mDropDownBoxCloseScheduled(false)
 	{
 	{
 		mOnButtonDownConn = gInput().onButtonDown.connect(boost::bind(&GUIManager::onButtonDown, this, _1));
 		mOnButtonDownConn = gInput().onButtonDown.connect(boost::bind(&GUIManager::onButtonDown, this, _1));
 		mOnButtonUpConn = gInput().onButtonUp.connect(boost::bind(&GUIManager::onButtonUp, this, _1));
 		mOnButtonUpConn = gInput().onButtonUp.connect(boost::bind(&GUIManager::onButtonUp, this, _1));
@@ -174,6 +175,12 @@ namespace BansheeEngine
 			mDropDownBoxOpenScheduled = false;
 			mDropDownBoxOpenScheduled = false;
 		}
 		}
 
 
+		if(mDropDownBoxCloseScheduled)
+		{
+			closeDropDownBox();
+			mDropDownBoxCloseScheduled = false;
+		}
+
 		// Update layouts
 		// Update layouts
 		for(auto& widgetInfo : mWidgets)
 		for(auto& widgetInfo : mWidgets)
 		{
 		{
@@ -646,6 +653,21 @@ namespace BansheeEngine
 
 
 			GUIMouseButton guiButton = buttonToMouseButton(event.buttonCode);
 			GUIMouseButton guiButton = buttonToMouseButton(event.buttonCode);
 
 
+			// Close drop down box(es) if user clicks outside of one
+			if(mDropDownBoxActive)
+			{
+				bool clickedOnDropDownBox = false;
+
+				if(mMouseOverElement != nullptr && (&mMouseOverElement->_getParentWidget() == mDropDownBox.get()))
+					clickedOnDropDownBox = true;
+
+				if(!clickedOnDropDownBox)
+				{
+					mDropDownBoxCloseScheduled = true;
+					return;
+				}
+			}
+
 			// 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)
@@ -686,19 +708,10 @@ namespace BansheeEngine
 				const GUIContextMenu* menu = mMouseOverElement->getContextMenu();
 				const GUIContextMenu* menu = mMouseOverElement->getContextMenu();
 
 
 				if(menu != nullptr)
 				if(menu != nullptr)
+				{
 					openContextMenu(menu, gInput().getMousePosition(), *mMouseOverWidget);
 					openContextMenu(menu, gInput().getMousePosition(), *mMouseOverWidget);
-			}
-
-			// Close drop down box(es) if user clicks outside of one
-			if(mDropDownBoxActive)
-			{
-				bool clickedOnDropDownBox = false;
-
-				if(mMouseOverElement != nullptr && (&mMouseOverElement->_getParentWidget() == mDropDownBox.get()))
-					clickedOnDropDownBox = true;
-
-				if(!clickedOnDropDownBox)
-					closeDropDownBox();
+					event.markAsUsed();
+				}
 			}
 			}
 		}
 		}
 	}
 	}
@@ -733,6 +746,13 @@ namespace BansheeEngine
 
 
 			mMouseEvent = GUIMouseEvent(buttonStates, shiftDown, ctrlDown, altDown);
 			mMouseEvent = GUIMouseEvent(buttonStates, shiftDown, ctrlDown, altDown);
 
 
+			// Ignore input if drop box is active and we're not interacting with its elements
+			if(mDropDownBoxActive)
+			{
+				if(mMouseOverElement == nullptr || (&mMouseOverElement->_getParentWidget() != mDropDownBox.get()))
+					return;	
+			}
+
 			Int2 localPos;
 			Int2 localPos;
 			if(mMouseOverWidget != nullptr)
 			if(mMouseOverWidget != nullptr)
 			{
 			{
@@ -891,6 +911,13 @@ namespace BansheeEngine
 	{
 	{
 		bool eventProcessed = false;
 		bool eventProcessed = false;
 
 
+		// Ignore input if drop box is active and we're not interacting with its elements
+		if(mDropDownBoxActive)
+		{
+			if(element == nullptr || (&element->_getParentWidget() != mDropDownBox.get()))
+				return false;	
+		}
+
 		Int2 localPos;
 		Int2 localPos;
 		if(widget != nullptr)
 		if(widget != nullptr)
 		{
 		{

+ 1 - 0
CamelotClient/Source/CmTestTextSprite.cpp

@@ -38,6 +38,7 @@ namespace CamelotFramework
 	void TestTextSprite::init(const HCamera& camera, const String& text, CM::RenderTexturePtr sceneView)
 	void TestTextSprite::init(const HCamera& camera, const String& text, CM::RenderTexturePtr sceneView)
 	{
 	{
 		setSkin(EngineGUI::instance().getSkin());
 		setSkin(EngineGUI::instance().getSkin());
+		setDepth(128);
 
 
 		GUIArea* area = GUIArea::createStretchedXY(*this, 0, 0, 0, 0);
 		GUIArea* area = GUIArea::createStretchedXY(*this, 0, 0, 0, 0);