Browse Source

Layouts properly respect minimal element sizes
GUIPanel properly calculates actual bounds

Marko Pintera 10 years ago
parent
commit
0423fab921

+ 17 - 2
BansheeEngine/Source/BsGUILayoutX.cpp

@@ -16,21 +16,29 @@ namespace BansheeEngine
 			return LayoutSizeRange();
 
 		Vector2I optimalSize;
+		Vector2I minSize;
 		for (auto& child : mChildren)
 		{
 			LayoutSizeRange sizeRange = child->_calculateLayoutSizeRange();
 
 			if (child->_getType() == GUIElementBase::Type::FixedSpace)
-				sizeRange.optimal.y = 0;
+				sizeRange.optimal.y = sizeRange.min.y = 0;
 
 			UINT32 paddingX = child->_getPadding().left + child->_getPadding().right;
 			UINT32 paddingY = child->_getPadding().top + child->_getPadding().bottom;
 
 			optimalSize.x += sizeRange.optimal.x + paddingX;
 			optimalSize.y = std::max((UINT32)optimalSize.y, sizeRange.optimal.y + paddingY);
+
+			minSize.x += sizeRange.min.x + paddingX;
+			minSize.y = std::max((UINT32)minSize.y, sizeRange.min.y + paddingY);
 		}
 
-		return _getDimensions().calculateSizeRange(optimalSize);
+		LayoutSizeRange sizeRange = _getDimensions().calculateSizeRange(optimalSize);
+		sizeRange.min.x = std::max(sizeRange.min.x, minSize.x);
+		sizeRange.min.y = std::max(sizeRange.min.y, minSize.y);
+
+		return sizeRange;
 	}
 
 	void GUILayoutX::_updateOptimalLayoutSizes()
@@ -42,6 +50,7 @@ namespace BansheeEngine
 			mChildSizeRanges.resize(mChildren.size());
 
 		Vector2I optimalSize;
+		Vector2I minSize;
 
 		UINT32 childIdx = 0;
 		for(auto& child : mChildren)
@@ -54,6 +63,7 @@ namespace BansheeEngine
 
 				childSizeRange = fixedSpace->_calculateLayoutSizeRange();
 				childSizeRange.optimal.y = 0;
+				childSizeRange.min.y = 0;
 			}
 			else if (child->_getType() == GUIElementBase::Type::Element)
 			{
@@ -71,10 +81,15 @@ namespace BansheeEngine
 			optimalSize.x += childSizeRange.optimal.x + paddingX;
 			optimalSize.y = std::max((UINT32)optimalSize.y, childSizeRange.optimal.y + paddingY);
 
+			minSize.x += childSizeRange.min.x + paddingX;
+			minSize.y = std::max((UINT32)minSize.y, childSizeRange.min.y + paddingY);
+
 			childIdx++;
 		}
 
 		mSizeRange = _getDimensions().calculateSizeRange(optimalSize);
+		mSizeRange.min.x = std::max(mSizeRange.min.x, minSize.x);
+		mSizeRange.min.y = std::max(mSizeRange.min.y, minSize.y);
 	}
 
 	void GUILayoutX::_getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements,

+ 17 - 2
BansheeEngine/Source/BsGUILayoutY.cpp

@@ -16,21 +16,29 @@ namespace BansheeEngine
 			return LayoutSizeRange();
 
 		Vector2I optimalSize;
+		Vector2I minSize;
 		for (auto& child : mChildren)
 		{
 			LayoutSizeRange sizeRange = child->_calculateLayoutSizeRange();
 			
 			if (child->_getType() == GUIElementBase::Type::FixedSpace)
-				sizeRange.optimal.x = 0;
+				sizeRange.optimal.x = sizeRange.min.x = 0;
 
 			UINT32 paddingX = child->_getPadding().left + child->_getPadding().right;
 			UINT32 paddingY = child->_getPadding().top + child->_getPadding().bottom;
 
 			optimalSize.y += sizeRange.optimal.y + paddingY;
 			optimalSize.x = std::max((UINT32)optimalSize.x, sizeRange.optimal.x + paddingX);
+
+			minSize.y += sizeRange.min.y + paddingY;
+			minSize.x = std::max((UINT32)minSize.x, sizeRange.min.x + paddingX);
 		}
 
-		return _getDimensions().calculateSizeRange(optimalSize);
+		LayoutSizeRange sizeRange = _getDimensions().calculateSizeRange(optimalSize);
+		sizeRange.min.x = std::max(sizeRange.min.x, minSize.x);
+		sizeRange.min.y = std::max(sizeRange.min.y, minSize.y);
+
+		return sizeRange;
 	}
 
 	void GUILayoutY::_updateOptimalLayoutSizes()
@@ -42,6 +50,7 @@ namespace BansheeEngine
 			mChildSizeRanges.resize(mChildren.size());
 
 		Vector2I optimalSize;
+		Vector2I minSize;
 
 		UINT32 childIdx = 0;
 		for(auto& child : mChildren)
@@ -54,6 +63,7 @@ namespace BansheeEngine
 
 				childSizeRange = fixedSpace->_calculateLayoutSizeRange();
 				childSizeRange.optimal.x = 0;
+				childSizeRange.min.x = 0;
 			}
 			else if(child->_getType() == GUIElementBase::Type::Element)
 			{
@@ -71,10 +81,15 @@ namespace BansheeEngine
 			optimalSize.y += childSizeRange.optimal.y + paddingY;
 			optimalSize.x = std::max((UINT32)optimalSize.x, childSizeRange.optimal.x + paddingX);
 
+			minSize.y += childSizeRange.min.y + paddingY;
+			minSize.x = std::max((UINT32)minSize.x, childSizeRange.min.x + paddingX);
+
 			childIdx++;
 		}
 
 		mSizeRange = _getDimensions().calculateSizeRange(optimalSize);
+		mSizeRange.min.x = std::max(mSizeRange.min.x, minSize.x);
+		mSizeRange.min.y = std::max(mSizeRange.min.y, minSize.y);
 	}
 
 	void GUILayoutY::_getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements,

+ 17 - 7
BansheeEngine/Source/BsGUIPanel.cpp

@@ -233,19 +233,29 @@ namespace BansheeEngine
 
 	Vector2I GUIPanel::_calcActualSize(INT32 x, INT32 y, Rect2I* elementAreas, UINT32 numElements) const
 	{
-		Vector2I actualArea;
-		for (UINT32 i = 0; i < numElements; i++)
+		Vector2I min;
+		Vector2I max;
+
+		if (numElements > 0)
+		{
+			Rect2I childArea = elementAreas[0];
+
+			min = Vector2I(childArea.x, childArea.y);
+			max = Vector2I(childArea.x + childArea.width, childArea.y + childArea.height);
+		}
+
+		for (UINT32 i = 1; i < numElements; i++)
 		{
 			Rect2I childArea = elementAreas[i];
 
-			INT32 diffX = (childArea.x - childArea.width) - x;
-			INT32 diffY = (childArea.y - childArea.height) - y;
+			min.x = std::min(min.x, childArea.x);
+			min.y = std::min(min.y, childArea.y);
 
-			actualArea.x = std::max(actualArea.x, diffX);
-			actualArea.y = std::max(actualArea.y, diffY);
+			max.x = std::max(max.x, childArea.x + childArea.width);
+			max.y = std::max(max.y, childArea.y + childArea.height);
 		}
 
-		return actualArea;
+		return max - min;
 	}
 
 	GUIPanel* GUIPanel::create(INT16 depth, UINT16 depthRangeMin, UINT16 depthRangeMax)

+ 20 - 11
MBansheeEditor/ProjectWindow.cs

@@ -33,7 +33,7 @@ namespace BansheeEditor
         private bool hasContentFocus = false;
         private bool HasContentFocus { get { return HasFocus && hasContentFocus; } } // TODO - This is dummy and never set
 
-        private ProjectViewType viewType = ProjectViewType.Grid32;
+        private ProjectViewType viewType = ProjectViewType.Grid64;
 
         private string currentDirectory = "";
         private List<string> selectionPaths = new List<string>();
@@ -324,30 +324,39 @@ namespace BansheeEditor
                 }
 
                 GUILayoutX rowLayout = contentLayout.AddLayoutX();
-
                 rowLayout.AddFlexibleSpace();
-                int currentWidth = GRID_ENTRY_SPACING * 2;
-                bool addedAny = false;
+
+                int elemSize = tileSize + GRID_ENTRY_SPACING;
+                int elemsPerRow = (scrollBounds.width - GRID_ENTRY_SPACING*2)/elemSize;
+
+                int elemsInRow = 0;
 
                 for (int i = 0; i < childEntries.Length; i++)
                 {
-                    if (currentWidth >= scrollBounds.width && addedAny) // We force at least one entry per row, even if it doesn't fit
+                    if (elemsInRow == elemsPerRow && elemsInRow > 0)
                     {
                         rowLayout = contentLayout.AddLayoutX();
-                        contentLayout.AddFlexibleSpace();
+                        contentLayout.AddSpace(GRID_ENTRY_SPACING);
 
                         rowLayout.AddFlexibleSpace();
-
-                        currentWidth = GRID_ENTRY_SPACING * 2;
+                        elemsInRow = 0;
                     }
 
                     LibraryEntry currentEntry = childEntries[i];
                     CreateEntryGUI(rowLayout, tileSize, true, currentEntry);
                     rowLayout.AddFlexibleSpace();
 
-                    addedAny = true;
-                    currentWidth += tileSize + GRID_ENTRY_SPACING;
+                    elemsInRow++;
+                }
+
+                int extraElements = elemsPerRow - elemsInRow;
+                for (int i = 0; i < extraElements; i++)
+                {
+                    rowLayout.AddSpace(tileSize);
+                    rowLayout.AddFlexibleSpace();
                 }
+
+                contentLayout.AddFlexibleSpace();
             }
 
             for (int i = 0; i < childEntries.Length; i++)
@@ -545,7 +554,7 @@ namespace BansheeEditor
         private ProjectWindow parent;
 
         public ProjectDropDown()
-            :base(100, 50)
+            :base(150, 30)
         { }
 
         internal void SetParent(ProjectWindow parent)

+ 1 - 4
TODO.txt

@@ -36,10 +36,7 @@ Crash when opening and closing the context menu many times, trying to delete a G
    that doesn't solve my issue as elements will go out of scope during assembly refresh
 
 Other:
- - Double click doesn't seem to work
- - Elements in the options drop down don't have proper style and are ugly in general
- - List view doesn't look right
-
+ - In larger icon views scrollbar doesn't show, and view elements can overlap the input box
 
 Test context menu
 Test drop down window