/// <summary> /// Update the group with the provided sizing solution. /// </summary> /// <param name="size">Solution size.</param> public void SetSolutionSize(ItemSizeWidth[] size) { // Should we become collapsed? Collapsed = (size == null); // Pass solution onto the contained view IRibbonViewGroupSize viewSize = (IRibbonViewGroupSize)_layoutNormalContent; viewSize.SetSolutionSize(size); }
/// <summary> /// Get an array of available widths for the group with associated sizing values. /// </summary> /// <param name="context">Context used to calculate the sizes.</param> /// <returns>Array of size values.</returns> 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()); }
private int AdjustGroupStateToMatchSpace(ViewLayoutContext context) { List <GroupSizeWidth[]> listWidths = new List <GroupSizeWidth[]>(); List <IRibbonViewGroupSize> listGroups = new List <IRibbonViewGroupSize>(); // Scan all groups int pixelGaps = 0; int maxEntries = 0; foreach (ViewBase child in this) { if (child.Visible) { // Only interested in children that are actually groups if (child is IRibbonViewGroupSize) { // Cast child view to correct interface IRibbonViewGroupSize childSize = (IRibbonViewGroupSize)child; // Find list of possible sizes for this group GroupSizeWidth[] widths = childSize.GetPossibleSizes(context); // Track how many extra pixels are needed for inter group gaps pixelGaps += SEP_LENGTH_2007; // Add into list of all container values listWidths.Add(widths); listGroups.Add(childSize); // Track the longest list found maxEntries = Math.Max(maxEntries, widths.Length); } } } int bestWidth = 0; int availableWidth = context.DisplayRectangle.Width; int[] bestIndexes = null; List <int> permIndexes = new List <int>(); // Scan each horizontal slice of the 2D array of values for (int i = 0; i < maxEntries; i++) { // Move from right to left creating a permutation each time for (int j = listWidths.Count - 1; j >= 0; j--) { // Does this cell actually exist? if (listWidths[j].Length > i) { // Starting width is the pixel gaps int permTotalWidth = pixelGaps; permIndexes.Clear(); // Generate permutation by taking cell values for (int k = listWidths.Count - 1; k >= 0; k--) { // If we are on the left of the 'j' cell then move up a level int index = i + (k > j ? 1 : 0); // Limit check the index to available height index = Math.Min(index, listWidths[k].Length - 1); permIndexes.Insert(0, index); // Find width and size of the entry int width = listWidths[k][index].Width; // Track the total width of this permutation permTotalWidth += width; } // We record this as the best match so far, if either it is the first permutation // tried or if closest to filling the entire available width of the client area if ((permTotalWidth > bestWidth) && (permTotalWidth <= availableWidth)) { bestWidth = permTotalWidth; bestIndexes = permIndexes.ToArray(); } } } } // If we have a best fit solution if (bestWidth > 0) { // Use the best discovered solution and push it back to the groups _groupWidths = new int[listGroups.Count]; for (int i = 0; i < listGroups.Count; i++) { _groupWidths[i] = (listWidths[i][bestIndexes[i]].Width); listGroups[i].SetSolutionSize(listWidths[i][bestIndexes[i]].Sizing); } } else { // Use the smallest solution and push it back to the groups _groupWidths = new int[listGroups.Count]; for (int i = 0; i < listGroups.Count; i++) { _groupWidths[i] = (listWidths[i][listWidths[i].Length - 1].Width); listGroups[i].SetSolutionSize(listWidths[i][listWidths[i].Length - 1].Sizing); } } return(bestWidth); }