|
@@ -13,6 +13,7 @@ namespace BansheeEngine
|
|
|
UINT32 totalOptimalSize = 0;
|
|
UINT32 totalOptimalSize = 0;
|
|
|
UINT32 numNonClampedElements = 0;
|
|
UINT32 numNonClampedElements = 0;
|
|
|
UINT32 numFlexibleSpaces = 0;
|
|
UINT32 numFlexibleSpaces = 0;
|
|
|
|
|
+ UINT32 numLayouts = 0;
|
|
|
|
|
|
|
|
bool* processedElements = CM_NEW_ARRAY(bool, (UINT32)mChildren.size(), ScratchAlloc);
|
|
bool* processedElements = CM_NEW_ARRAY(bool, (UINT32)mChildren.size(), ScratchAlloc);
|
|
|
memset(processedElements, 0, mChildren.size() * sizeof(bool));
|
|
memset(processedElements, 0, mChildren.size() * sizeof(bool));
|
|
@@ -20,6 +21,9 @@ namespace BansheeEngine
|
|
|
UINT32* elementSizes = CM_NEW_ARRAY(UINT32, (UINT32)mChildren.size(), ScratchAlloc);
|
|
UINT32* elementSizes = CM_NEW_ARRAY(UINT32, (UINT32)mChildren.size(), ScratchAlloc);
|
|
|
memset(elementSizes, 0, mChildren.size() * sizeof(UINT32));
|
|
memset(elementSizes, 0, mChildren.size() * sizeof(UINT32));
|
|
|
|
|
|
|
|
|
|
+ float* elementScaleWeights = CM_NEW_ARRAY(float, (UINT32)mChildren.size(), ScratchAlloc);
|
|
|
|
|
+ memset(elementScaleWeights, 0, mChildren.size() * sizeof(float));
|
|
|
|
|
+
|
|
|
// Set fixed-size elements and determine optimal size
|
|
// Set fixed-size elements and determine optimal size
|
|
|
UINT32 childIdx = 0;
|
|
UINT32 childIdx = 0;
|
|
|
for(auto& child : mChildren)
|
|
for(auto& child : mChildren)
|
|
@@ -57,7 +61,7 @@ namespace BansheeEngine
|
|
|
}
|
|
}
|
|
|
else if(child.isLayout())
|
|
else if(child.isLayout())
|
|
|
{
|
|
{
|
|
|
- // Layout use any size that's available (quite possibly none), but it might be better to give them a certain minimum size.
|
|
|
|
|
|
|
+ numLayouts++;
|
|
|
numNonClampedElements++;
|
|
numNonClampedElements++;
|
|
|
}
|
|
}
|
|
|
else if(child.isFlexibleSpace())
|
|
else if(child.isFlexibleSpace())
|
|
@@ -69,6 +73,30 @@ namespace BansheeEngine
|
|
|
childIdx++;
|
|
childIdx++;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Determine layout size. We could just calculate optimal size of all elements in the layout
|
|
|
|
|
+ // but I feel that's an overkill. Instead I just use the average size.
|
|
|
|
|
+ childIdx = 0;
|
|
|
|
|
+ UINT32 layoutSize = (UINT32)Math::CeilToInt(totalOptimalSize / (float)numLayouts);
|
|
|
|
|
+ for(auto& child : mChildren)
|
|
|
|
|
+ {
|
|
|
|
|
+ if(child.isLayout())
|
|
|
|
|
+ {
|
|
|
|
|
+ elementSizes[childIdx] += layoutSize;
|
|
|
|
|
+ totalOptimalSize += layoutSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ childIdx++;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Determine weight scale for every element
|
|
|
|
|
+ childIdx = 0;
|
|
|
|
|
+ float invOptimalSize = 1.0f / totalOptimalSize;
|
|
|
|
|
+ for(auto& child : mChildren)
|
|
|
|
|
+ {
|
|
|
|
|
+ elementScaleWeights[childIdx] = invOptimalSize * elementSizes[childIdx];
|
|
|
|
|
+
|
|
|
|
|
+ childIdx++;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Our optimal size is larger than maximum allowed, so we need to reduce size of some elements
|
|
// Our optimal size is larger than maximum allowed, so we need to reduce size of some elements
|
|
|
if(totalOptimalSize > width)
|
|
if(totalOptimalSize > width)
|
|
|
{
|
|
{
|
|
@@ -79,7 +107,7 @@ namespace BansheeEngine
|
|
|
// equal average sizes
|
|
// equal average sizes
|
|
|
while(remainingSize > 0 && numNonClampedElements > 0)
|
|
while(remainingSize > 0 && numNonClampedElements > 0)
|
|
|
{
|
|
{
|
|
|
- float avgSize = remainingSize / (float)numNonClampedElements;
|
|
|
|
|
|
|
+ UINT32 totalRemainingSize = remainingSize;
|
|
|
|
|
|
|
|
childIdx = 0;
|
|
childIdx = 0;
|
|
|
for(auto& child : mChildren)
|
|
for(auto& child : mChildren)
|
|
@@ -87,6 +115,8 @@ namespace BansheeEngine
|
|
|
if(processedElements[childIdx])
|
|
if(processedElements[childIdx])
|
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
|
|
+ float avgSize = totalRemainingSize * elementScaleWeights[childIdx];
|
|
|
|
|
+
|
|
|
UINT32 extraWidth = std::min((UINT32)Math::CeilToInt(avgSize), remainingSize);
|
|
UINT32 extraWidth = std::min((UINT32)Math::CeilToInt(avgSize), remainingSize);
|
|
|
UINT32 elementWidth = (UINT32)std::max(0, (INT32)elementSizes[childIdx] - (INT32)extraWidth);
|
|
UINT32 elementWidth = (UINT32)std::max(0, (INT32)elementSizes[childIdx] - (INT32)extraWidth);
|
|
|
|
|
|
|
@@ -172,7 +202,7 @@ namespace BansheeEngine
|
|
|
// equal average sizes
|
|
// equal average sizes
|
|
|
while(remainingSize > 0 && numNonClampedElements > 0)
|
|
while(remainingSize > 0 && numNonClampedElements > 0)
|
|
|
{
|
|
{
|
|
|
- float avgSize = remainingSize / (float)numNonClampedElements;
|
|
|
|
|
|
|
+ UINT32 totalRemainingSize = remainingSize;
|
|
|
|
|
|
|
|
childIdx = 0;
|
|
childIdx = 0;
|
|
|
for(auto& child : mChildren)
|
|
for(auto& child : mChildren)
|
|
@@ -180,6 +210,7 @@ namespace BansheeEngine
|
|
|
if(processedElements[childIdx])
|
|
if(processedElements[childIdx])
|
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
|
|
+ float avgSize = totalRemainingSize * elementScaleWeights[childIdx];
|
|
|
UINT32 extraWidth = std::min((UINT32)Math::CeilToInt(avgSize), remainingSize);
|
|
UINT32 extraWidth = std::min((UINT32)Math::CeilToInt(avgSize), remainingSize);
|
|
|
UINT32 elementWidth = elementSizes[childIdx] + extraWidth;
|
|
UINT32 elementWidth = elementSizes[childIdx] + extraWidth;
|
|
|
|
|
|
|
@@ -267,6 +298,7 @@ namespace BansheeEngine
|
|
|
|
|
|
|
|
CM_DELETE_ARRAY(processedElements, bool, (UINT32)mChildren.size(), ScratchAlloc);
|
|
CM_DELETE_ARRAY(processedElements, bool, (UINT32)mChildren.size(), ScratchAlloc);
|
|
|
CM_DELETE_ARRAY(elementSizes, UINT32, (UINT32)mChildren.size(), ScratchAlloc);
|
|
CM_DELETE_ARRAY(elementSizes, UINT32, (UINT32)mChildren.size(), ScratchAlloc);
|
|
|
|
|
+ CM_DELETE_ARRAY(elementScaleWeights, float, (UINT32)mChildren.size(), ScratchAlloc);
|
|
|
|
|
|
|
|
//// Calculate flexible space sizes
|
|
//// Calculate flexible space sizes
|
|
|
//std::vector<UINT32> flexibleSpaceSizes;
|
|
//std::vector<UINT32> flexibleSpaceSizes;
|