Browse Source

Fixed GUIElement flags so they're set correctly when re-parenting elements
GUIElement custom cursor, context menu and drag and drop will now be ignored when element is disabled
Fix for a crash in GUI dictionary when adding an element to a non-empty dictionary

BearishSun 10 years ago
parent
commit
4df60970a4

+ 1 - 1
BansheeEditor/Source/BsGUIDockSlider.cpp

@@ -36,7 +36,7 @@ namespace BansheeEngine
 
 	bool GUIDockSlider::_hasCustomCursor(const Vector2I position, CursorType& type) const
 	{
-		if(_isInBounds(position))
+		if (_isInBounds(position) && !_isDisabled())
 		{
 			type = mHorizontal ? CursorType::SizeNS : CursorType::SizeWE;
 			return true;

+ 1 - 1
BansheeEditor/Source/BsGUIDropButton.cpp

@@ -88,6 +88,6 @@ namespace BansheeEngine
 
 	bool GUIDropButton::_acceptDragAndDrop(const Vector2I position, UINT32 typeId) const
 	{
-		return typeId == mDragType;
+		return typeId == mDragType && !_isDisabled();
 	}
 }

+ 10 - 7
BansheeEditor/Source/BsGUIFloatField.cpp

@@ -44,15 +44,18 @@ namespace BansheeEngine
 
 	bool GUIFloatField::_hasCustomCursor(const Vector2I position, CursorType& type) const
 	{
-		Rect2I draggableArea;
+		if (!_isDisabled())
+		{
+			Rect2I draggableArea;
 
-		if(mLabel != nullptr)
-			draggableArea = mLabel->_getLayoutData().area;
+			if (mLabel != nullptr)
+				draggableArea = mLabel->_getLayoutData().area;
 
-		if(draggableArea.contains(position))
-		{
-			type = CursorType::ArrowLeftRight;
-			return true;
+			if (draggableArea.contains(position))
+			{
+				type = CursorType::ArrowLeftRight;
+				return true;
+			}
 		}
 
 		return false;

+ 10 - 7
BansheeEditor/Source/BsGUIIntField.cpp

@@ -45,15 +45,18 @@ namespace BansheeEngine
 
 	bool GUIIntField::_hasCustomCursor(const Vector2I position, CursorType& type) const
 	{
-		Rect2I draggableArea;
+		if (!_isDisabled())
+		{
+			Rect2I draggableArea;
 
-		if(mLabel != nullptr)
-			draggableArea = mLabel->_getLayoutData().area;
+			if (mLabel != nullptr)
+				draggableArea = mLabel->_getLayoutData().area;
 
-		if(draggableArea.contains(position))
-		{
-			type = CursorType::ArrowLeftRight;
-			return true;
+			if (draggableArea.contains(position))
+			{
+				type = CursorType::ArrowLeftRight;
+				return true;
+			}
 		}
 
 		return false;

+ 1 - 1
BansheeEditor/Source/BsGUIResourceTreeView.cpp

@@ -468,7 +468,7 @@ namespace BansheeEngine
 
 	bool GUIResourceTreeView::_acceptDragAndDrop(const Vector2I position, UINT32 typeId) const
 	{
-		return typeId == (UINT32)DragAndDropType::Resources;
+		return typeId == (UINT32)DragAndDropType::Resources && !_isDisabled();
 	}
 
 	void GUIResourceTreeView::selectionChanged()

+ 1 - 1
BansheeEditor/Source/BsGUISceneTreeView.cpp

@@ -359,7 +359,7 @@ namespace BansheeEngine
 
 	bool GUISceneTreeView::_acceptDragAndDrop(const Vector2I position, UINT32 typeId) const
 	{
-		return typeId == (UINT32)DragAndDropType::SceneObject || typeId == (UINT32)DragAndDropType::Resources;
+		return (typeId == (UINT32)DragAndDropType::SceneObject || typeId == (UINT32)DragAndDropType::Resources) && !_isDisabled();
 	}
 
 	void GUISceneTreeView::selectionChanged()

+ 1 - 1
BansheeEngine/Include/BsGUIElement.h

@@ -308,7 +308,7 @@ namespace BansheeEngine
 		 *
 		 * @note	Internal method.
 		 */
-		virtual GUIContextMenuPtr _getContextMenu() const { return mContextMenu; }
+		virtual GUIContextMenuPtr _getContextMenu() const;
 
 		/**
 		 * @brief	Returns a clip rectangle relative to the element, used for offsetting

+ 8 - 0
BansheeEngine/Source/BsGUIElement.cpp

@@ -191,6 +191,14 @@ namespace BansheeEngine
 		return contentBounds.contains(position);
 	}
 
+	GUIContextMenuPtr GUIElement::_getContextMenu() const
+	{
+		if (!_isDisabled())
+			return mContextMenu;
+
+		return nullptr;
+	}
+
 	void GUIElement::_refreshStyle()
 	{
 		const GUIElementStyle* newStyle = nullptr;

+ 81 - 69
BansheeEngine/Source/BsGUIElementBase.cpp

@@ -231,104 +231,110 @@ namespace BansheeEngine
 			// If making an element visible make sure to mark layout as dirty, as we didn't track any dirty flags while the element was inactive
 			if (!visible)
 			{
-				if (_isVisible())
-					_markMeshAsDirty();
-
-				mFlags |= GUIElem_Hidden | GUIElem_HiddenSelf;
+				mFlags |= GUIElem_HiddenSelf;
+				_setVisible(false);
 			}
 			else
 			{
-				if (mParentElement != nullptr && !mParentElement->_isVisible())
-					mFlags &= ~GUIElem_HiddenSelf;
-				else
-				{
-					mFlags &= ~(GUIElem_Hidden | GUIElem_HiddenSelf);
-					_markLayoutAsDirty();
-				}
-			}
+				mFlags &= ~GUIElem_HiddenSelf;
 
-			_setVisible(visible);
+				if (mParentElement == nullptr || mParentElement->_isVisible())
+					_setVisible(true);
+			}
 		}
 	}
 
 	void GUIElementBase::_setVisible(bool visible)
 	{
-		for (auto& child : mChildren)
+		bool isVisible = (mFlags & GUIElem_Hidden) == 0;
+		if (isVisible == visible)
+			return;
+
+		if (!visible)
 		{
-			if (!visible)
-			{
-				child->mFlags |= GUIElem_Hidden;
+			_markMeshAsDirty();
+
+			mFlags |= GUIElem_Hidden;
+
+			for (auto& child : mChildren)
 				child->_setVisible(false);
-			}
-			else
+		}
+		else
+		{
+			bool childVisibleSelf = (mFlags & GUIElem_HiddenSelf) == 0;
+			if (childVisibleSelf)
 			{
-				bool childVisibleSelf = (child->mFlags & GUIElem_HiddenSelf) == 0;
-				if (childVisibleSelf)
-				{
-					child->mFlags &= ~GUIElem_Hidden;
+				mFlags &= ~GUIElem_Hidden;
+				_markLayoutAsDirty();
+
+				for (auto& child : mChildren)
 					child->_setVisible(true);
-				}
 			}
 		}
 	}
 
 	void GUIElementBase::setActive(bool active)
 	{
-		static const UINT8 ACTIVE_FLAGS = GUIElem_Inactive | GUIElem_Hidden | GUIElem_InactiveSelf | GUIElem_HiddenSelf;
+		static const UINT8 ACTIVE_FLAGS = GUIElem_InactiveSelf | GUIElem_HiddenSelf;
 
 		bool activeSelf = (mFlags & GUIElem_InactiveSelf) == 0;
 		if (activeSelf != active)
 		{
 			if (!active)
 			{
-				if (_isActive())
-					_markLayoutAsDirty();
-
 				mFlags |= ACTIVE_FLAGS;
+
+				_setActive(false);
+				_setVisible(false);
 			}
 			else
 			{
+				mFlags &= ~ACTIVE_FLAGS;
+
 				if (mParentElement != nullptr)
 				{
-					if (!mParentElement->_isActive())
-						mFlags &= ~(GUIElem_InactiveSelf | GUIElem_HiddenSelf);
-					else
+					if (mParentElement->_isActive())
 					{
-						if (!mParentElement->_isVisible())
-							mFlags &= ~(GUIElem_Inactive | GUIElem_InactiveSelf | GUIElem_HiddenSelf);
-						else
-							mFlags &= ~ACTIVE_FLAGS;
+						_setActive(true);
+
+						if (mParentElement->_isVisible())
+							_setVisible(true);
 					}
 				}
 				else
-					mFlags &= ~ACTIVE_FLAGS;
-
-				if (_isActive())
-					_markLayoutAsDirty();
+				{
+					_setActive(true);
+					_setVisible(true);
+				}
 			}
-
-			_setActive(active);
-			_setVisible(active);
 		}
 	}
 
 	void GUIElementBase::_setActive(bool active)
 	{
-		for (auto& child : mChildren)
+		bool isActive = (mFlags & GUIElem_Inactive) == 0;
+		if (isActive == active)
+			return;
+		
+		if (!active)
 		{
-			if (!active)
-			{
-				child->mFlags |= GUIElem_Inactive;
+			_markLayoutAsDirty();
+
+			mFlags |= GUIElem_Inactive;
+
+			for (auto& child : mChildren)
 				child->_setActive(false);
-			}
-			else
+		}
+		else
+		{
+			bool childActiveSelf = (mFlags & GUIElem_InactiveSelf) == 0;
+			if (childActiveSelf)
 			{
-				bool childActiveSelf = (child->mFlags & GUIElem_InactiveSelf) == 0;
-				if (childActiveSelf)
-				{
-					child->mFlags &= ~GUIElem_Inactive;
+				mFlags &= ~GUIElem_Inactive;
+				_markLayoutAsDirty();
+
+				for (auto& child : mChildren)
 					child->_setActive(true);
-				}
 			}
 		}
 	}
@@ -339,12 +345,9 @@ namespace BansheeEngine
 		if (disabledSelf != disabled)
 		{
 			if (!disabled)
-				mFlags &= ~(GUIElem_Disabled | GUIElem_DisabledSelf);
+				mFlags &= ~GUIElem_DisabledSelf;
 			else
-				mFlags |= (GUIElem_Disabled | GUIElem_DisabledSelf);
-
-			if (_isVisible())
-				_markContentAsDirty();
+				mFlags |= GUIElem_DisabledSelf;
 
 			_setDisabled(disabled);
 		}
@@ -352,23 +355,31 @@ namespace BansheeEngine
 
 	void GUIElementBase::_setDisabled(bool disabled)
 	{
-		for (auto& child : mChildren)
+		bool isDisabled = (mFlags & GUIElem_Disabled) == 0;
+		if (isDisabled == disabled)
+			return;
+
+		if (!disabled)
 		{
-			if (!disabled)
+			bool disabledSelf = (mFlags & GUIElem_DisabledSelf) != 0;
+			if (!disabledSelf)
 			{
-				bool disabledSelf = (child->mFlags & GUIElem_DisabledSelf) != 0;
-				if (!disabledSelf)
-				{
-					child->mFlags &= ~GUIElem_Disabled;
+				mFlags &= ~GUIElem_Disabled;
+
+				for (auto& child : mChildren)
 					child->_setDisabled(false);
-				}
 			}
-			else
-			{
-				child->mFlags |= GUIElem_Disabled;
+		}
+		else
+		{
+			mFlags |= GUIElem_Disabled;
+
+			for (auto& child : mChildren)
 				child->_setDisabled(true);
-			}
 		}
+
+		if (_isVisible())
+			_markContentAsDirty();
 	}
 
 	void GUIElementBase::_updateLayout(const GUILayoutData& data)
@@ -442,6 +453,7 @@ namespace BansheeEngine
 
 		element->_setActive(_isActive());
 		element->_setVisible(_isVisible());
+		element->_setDisabled(_isDisabled());
 
 		_markLayoutAsDirty();
 	}

+ 5 - 2
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -377,7 +377,7 @@ namespace BansheeEngine
 
 	bool GUIInputBox::_hasCustomCursor(const Vector2I position, CursorType& type) const
 	{
-		if(_isInBounds(position))
+		if(_isInBounds(position) && !_isDisabled())
 		{
 			type = CursorType::IBeam;
 			return true;
@@ -1172,7 +1172,10 @@ namespace BansheeEngine
 			contextMenu->setLocalizedName(L"Paste", HString(L"Paste"));
 		}
 
-		return contextMenu;
+		if (!_isDisabled())
+			return contextMenu;
+
+		return nullptr;
 	}
 
 	void GUIInputBox::cutText()

+ 1 - 0
BansheeEngine/Source/BsGUILayout.cpp

@@ -50,6 +50,7 @@ namespace BansheeEngine
 		
 		element->_setActive(_isActive());
 		element->_setVisible(_isVisible());
+		element->_setDisabled(_isDisabled());
 
 		_markLayoutAsDirty();
 	}

+ 5 - 5
MBansheeEditor/GUI/GUIDictionaryField.cs

@@ -719,6 +719,11 @@ namespace BansheeEditor
                 for (int i = 0; i < newNumRows; i++)
                     newKeys.Add(GetKey(i), i);
 
+                // Hidden dependency: BuildGUI must be called after all elements are 
+                // in the dictionary so we do it in two steps
+                for (int i = oldNumRows; i < newNumRows; i++)
+                    rows[i] = CreateRow();
+
                 foreach (var KVP in oldKeys)
                 {
                     int newRowIdx;
@@ -739,11 +744,6 @@ namespace BansheeEditor
                     rows.Remove(i);
                 }
 
-                // Hidden dependency: BuildGUI must be called after all elements are 
-                // in the dictionary so we do it in two steps
-                for (int i = oldNumRows; i < newNumRows; i++)
-                    rows[i] = CreateRow();
-
                 BuildRows();
 
                 editKey = CreateKey();