public GroupSizeWidth[] GetPossibleSizes(ViewLayoutContext context)
{
// Make changes to ensure ribbon shape is honored
UpdateShapeValues();
// Ask the normal group content for its possible sizes
IRibbonViewGroupSize viewSize = (IRibbonViewGroupSize)_layoutNormalContent;
// Get the permutations from the content area
List<GroupSizeWidth> retWidths = new List<GroupSizeWidth>();
retWidths.AddRange(viewSize.GetPossibleSizes(context));
// Grab the requested min/max sizes of the group
int minWidth = _ribbonGroup.MinimumWidth;
int maxWidth = _ribbonGroup.MaximumWidth;
bool ignoreMin = (minWidth < 0);
// If a minus number then max width is effectively as big as you like
if (maxWidth <= 0) maxWidth = int.MaxValue;
if (minWidth < 0) minWidth = 0;
// Prevent the minimum being bigger than the maximum
minWidth = Math.Min(minWidth, maxWidth);
int firstUnderMax = -1;
int lastOverMin = -1;
int smallestWidth = int.MaxValue;
for(int i=0; i<retWidths.Count; i++)
{
// Add on the fixed widths of the left and right borders so that the
// permutations all reflect the actual width of the whole group
GroupSizeWidth retWidth = retWidths[i];
retWidth.Width += _totalBorders;
// Find the first entry that is smaller than the maximum allowed
if ((retWidth.Width <= maxWidth) && (firstUnderMax == -1))
firstUnderMax = i;
// Find the last entry that is bigger than the minimum
if (retWidth.Width >= minWidth)
lastOverMin = i;
smallestWidth = Math.Min(smallestWidth, retWidth.Width);
}
// We only enforce min/max when not using the design helpers
if (!_ribbon.InDesignHelperMode)
{
// If all permutations are above the maximum
if (firstUnderMax == -1)
{
if (retWidths.Count > 0)
{
// ...then use the smallest permutation by removing all the others
retWidths.RemoveRange(0, retWidths.Count - 2);
retWidths[0].Width = maxWidth;
smallestWidth = maxWidth;
}
}
else if (lastOverMin == -1)
{
// All permutations are less than the minimum
if (retWidths.Count > 0)
{
// ...then use the largest permutation by removing all the others
retWidths.RemoveRange(1, retWidths.Count - 1);
retWidths[0].Width = minWidth;
smallestWidth = minWidth;
}
}
else if ((firstUnderMax > 0) || (smallestWidth < minWidth))
{
// Create new list list with just the allowed sizes
List<GroupSizeWidth> newWidths = new List<GroupSizeWidth>();
// If the min/max are such that they both fall betweem two of the items then switch
// to using the smaller of the two items. This can happen when max is same as min
// and does not exactly match an entry. Makes most sense to use the smaller perm.
if (firstUnderMax > lastOverMin)
lastOverMin = firstUnderMax;
// Reset smallest value which needs finding again
smallestWidth = int.MaxValue;
for (int i = firstUnderMax; i <= lastOverMin; i++)
{
// Get the original value
GroupSizeWidth retWidth = retWidths[i];
// If the last entry we override width with the minimum
if (!ignoreMin && (i == lastOverMin) && (retWidth.Width < minWidth))
retWidth.Width = minWidth;
// Append to end of the new list
newWidths.Add(retWidth);
// Remember the smallest width encountered
smallestWidth = Math.Min(smallestWidth, retWidth.Width);
}
// Use the new list
retWidths = newWidths;
}
}
// Does the group allow itself to become collapsed?
// (at design time we are never allowed to be collapsed)
if (_ribbonGroup.AllowCollapsed && !_ribbon.InDesignHelperMode)
{
// We never allow a collapsed state if that is bigger than the smallest valid permutation
if (smallestWidth > MINIMUM_GROUP_WIDTH)
{
// Find the size of the group when collapsed
bool collapsed = Collapsed;
Collapsed = true;
GroupSizeWidth retCollapsed = new GroupSizeWidth(GetPreferredSize(context).Width, null);
Collapsed = collapsed;
// We never allow a collapsed state if that is smaller than the smallest valid permutation
if (smallestWidth > retCollapsed.Width)
retWidths.Add(retCollapsed);
}
}
return retWidths.ToArray();
}