Prechádzať zdrojové kódy

GUIManager can now handle multiple drop down boxes

Marko Pintera 12 rokov pred
rodič
commit
e7bee38c97

+ 4 - 3
BansheeEngine/Include/BsGUIManager.h

@@ -105,9 +105,9 @@ namespace BansheeEngine
 		// Drop down box
 		bool mDropDownBoxOpenScheduled;
 		bool mDropDownBoxActive;
-		CM::HSceneObject mDropDownSO;
-		CM::GameObjectHandle<GUIDropDownBox> mDropDownBox;
-		std::function<void(CM::UINT32)> mDropDownSelectionMade;
+		CM::Vector<CM::HSceneObject>::type mDropDownSOs;
+		CM::Vector<CM::GameObjectHandle<GUIDropDownBox>>::type mDropDownBoxes;
+		std::function<void(CM::UINT32)> mListBoxSelectionMade;
 
 		boost::signals::connection mOnButtonDownConn;
 		boost::signals::connection mOnButtonUpConn;
@@ -144,6 +144,7 @@ namespace BansheeEngine
 		bool handleMouseOver(GUIWidget* widget, GUIElement* element, const CM::Int2& screenMousePos, float wheelScrollAmount = 0.0f);
 
 		void closeDropDownListBox(CM::INT32 selectedIdx);
+		void closeAllDropDownBoxes();
 
 		GUIMouseButton buttonToMouseButton(CM::ButtonCode code) const;
 		CM::Int2 getWidgetRelativePos(const GUIWidget& widget, const CM::Int2& screenPos) const;

+ 31 - 9
BansheeEngine/Source/BsGUIManager.cpp

@@ -508,8 +508,9 @@ namespace BansheeEngine
 		if(mDropDownBoxOpenScheduled || mDropDownBoxActive)
 			closeDropDownListBox(-1);
 
-		mDropDownSO = SceneObject::create("DropDownBox");
-		mDropDownBox = mDropDownSO->addComponent<GUIDropDownBox>();
+		CM::HSceneObject so = SceneObject::create("DropDownBox");
+		mDropDownSOs.push_back(so);
+		mDropDownBoxes.push_back(so->addComponent<GUIDropDownBox>());
 
 		GUIWidget& widget = parentList->_getParentWidget();
 
@@ -521,20 +522,29 @@ namespace BansheeEngine
 			i++;
 		}
 
-		mDropDownBox->initialize(widget.getTarget(), widget.getOwnerWindow(), parentList, dropDownData, skin, GUIDropDownType::ListBox);
+		mDropDownBoxes.back()->initialize(widget.getTarget(), widget.getOwnerWindow(), parentList, dropDownData, skin, GUIDropDownType::ListBox);
 
 		mDropDownBoxOpenScheduled = true;
-		mDropDownSelectionMade = selectedCallback;
+		mListBoxSelectionMade = selectedCallback;
 	}
 
 	void GUIManager::closeDropDownListBox(INT32 selectedIdx)
 	{
 		if(selectedIdx != -1)
-			mDropDownSelectionMade(selectedIdx);
+			mListBoxSelectionMade(selectedIdx);
+
+		closeAllDropDownBoxes();
+	}
+
+	void GUIManager::closeAllDropDownBoxes()
+	{
+		for(auto& dropDownSO : mDropDownSOs)
+			dropDownSO->destroy();
 
 		mDropDownBoxActive = false;
 
-		mDropDownSO->destroy();
+		mDropDownSOs.clear();
+		mDropDownBoxes.clear();
 	}
 
 	void GUIManager::updateCaretTexture()
@@ -639,13 +649,25 @@ namespace BansheeEngine
 				event.markAsUsed();
 			}
 
-			// Close drop down box if user clicks outside the drop down box
+			// Close drop down box(es) if user clicks outside of one
 			if(mDropDownBoxActive)
 			{
-				if(mMouseOverElement == nullptr || (&mMouseOverElement->_getParentWidget() != mDropDownBox.get()))
+				bool clickedOnDropDownBox = false;
+
+				if(mMouseOverElement != nullptr)
 				{
-					closeDropDownListBox(-1);
+					for(auto& dropDownBox : mDropDownBoxes)
+					{
+						if(&mMouseOverElement->_getParentWidget() == dropDownBox.get())
+						{
+							clickedOnDropDownBox = true;
+							break;
+						}
+					}
 				}
+
+				if(!clickedOnDropDownBox)
+					closeAllDropDownBoxes();
 			}
 		}
 	}

+ 0 - 2
DropDown.txt

@@ -2,8 +2,6 @@ GUI ignores image in GUIContent for most elements.
 
 Immediate TODO:
  - Hook up ScrollUp and ScrollDown events in GUIDropDownBox
- - Add support for different skins for context menu, drop down list and drop down menu
-    - Just add a prefix to GUIDropDownBox constructor
  - Add support to GUIManager to deal with multiple different GUIDropDownBoxes
 
 Figure out how to deal with sub-menus