/// <summary> /// Gets current used layout definition (or null if no present definitions) /// </summary> /// <returns>Layout definition or null</returns> internal RibbonToolBarLayoutDefinition GetCurrentLayoutDefinition() { if (layoutDefinitions.Count == 0) { return(null); } if (layoutDefinitions.Count == 1) { return(layoutDefinitions[0]); } foreach (RibbonToolBarLayoutDefinition definition in layoutDefinitions) { if (RibbonAttachedProperties.GetRibbonSize(definition) == RibbonAttachedProperties.GetRibbonSize(this)) { return(definition); } } // TODO: try to find a better definition return(layoutDefinitions[0]); }
private void UpdateKeyTipPositions() { this.Log("UpdateKeyTipPositions"); if (keyTips.Count == 0) { return; } double[] rows = null; var groupBox = GetGroupBox(oneOfAssociatedElements); if (groupBox != null) { var panel = groupBox.GetPanel(); if (panel != null) { var height = groupBox.GetLayoutRoot().DesiredSize.Height; rows = new[] { groupBox.GetLayoutRoot().TranslatePoint(new Point(0, 0), AdornedElement).Y, groupBox.GetLayoutRoot().TranslatePoint(new Point(0, panel.DesiredSize.Height / 2.0), AdornedElement).Y, groupBox.GetLayoutRoot().TranslatePoint(new Point(0, panel.DesiredSize.Height), AdornedElement).Y, groupBox.GetLayoutRoot().TranslatePoint(new Point(0, height + 1), AdornedElement).Y }; } } for (var i = 0; i < keyTips.Count; i++) { // Skip invisible keytips if (keyTips[i].Visibility != Visibility.Visible) { continue; } // Update KeyTip Visibility var associatedElementIsVisible = associatedElements[i].IsVisible; var associatedElementInVisualTree = VisualTreeHelper.GetParent(associatedElements[i]) != null; keyTips[i].Visibility = associatedElementIsVisible && associatedElementInVisualTree ? Visibility.Visible : Visibility.Collapsed; if (!KeyTip.GetAutoPlacement(associatedElements[i])) { #region Custom Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].RenderSize; double x = 0, y = 0; var margin = KeyTip.GetMargin(associatedElements[i]); switch (KeyTip.GetHorizontalAlignment(associatedElements[i])) { case HorizontalAlignment.Left: x = margin.Left; break; case HorizontalAlignment.Right: x = elementSize.Width - keyTipSize.Width - margin.Right; break; case HorizontalAlignment.Center: case HorizontalAlignment.Stretch: x = elementSize.Width / 2.0 - keyTipSize.Width / 2.0 + margin.Left; break; } switch (KeyTip.GetVerticalAlignment(associatedElements[i])) { case VerticalAlignment.Top: y = margin.Top; break; case VerticalAlignment.Bottom: y = elementSize.Height - keyTipSize.Height - margin.Bottom; break; case VerticalAlignment.Center: case VerticalAlignment.Stretch: y = elementSize.Height / 2.0 - keyTipSize.Height / 2.0 + margin.Top; break; } keyTipPositions[i] = associatedElements[i].TranslatePoint(new Point(x, y), AdornedElement); #endregion } else if (((FrameworkElement)associatedElements[i]).Name == "PART_DialogLauncherButton") { // Dialog Launcher Button Exclusive Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].RenderSize; if (rows == null) { continue; } keyTipPositions[i] = associatedElements[i].TranslatePoint( new Point(elementSize.Width / 2.0 - keyTipSize.Width / 2.0, 0), AdornedElement); keyTipPositions[i].Y = rows[3]; } else if ((associatedElements[i] is InRibbonGallery && !((InRibbonGallery)associatedElements[i]).IsCollapsed)) { // InRibbonGallery Exclusive Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].RenderSize; if (rows == null) { continue; } keyTipPositions[i] = associatedElements[i].TranslatePoint( new Point(elementSize.Width - keyTipSize.Width / 2.0, 0), AdornedElement); keyTipPositions[i].Y = rows[2] - keyTipSize.Height / 2; } else if ((associatedElements[i] is RibbonTabItem) || (associatedElements[i] is Backstage)) { // Ribbon Tab Item Exclusive Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].RenderSize; keyTipPositions[i] = associatedElements[i].TranslatePoint( new Point(elementSize.Width / 2.0 - keyTipSize.Width / 2.0, elementSize.Height - keyTipSize.Height / 2.0), AdornedElement); } else if (associatedElements[i] is RibbonGroupBox) { // Ribbon Group Box Exclusive Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].DesiredSize; keyTipPositions[i] = associatedElements[i].TranslatePoint( new Point(elementSize.Width / 2.0 - keyTipSize.Width / 2.0, elementSize.Height + 1), AdornedElement); } else if (IsWithinQuickAccessToolbar(associatedElements[i])) { var translatedPoint = associatedElements[i].TranslatePoint(new Point( associatedElements[i].DesiredSize.Width / 2.0 - keyTips[i].DesiredSize.Width / 2.0, associatedElements[i].DesiredSize.Height - keyTips[i].DesiredSize.Height / 2.0), AdornedElement); keyTipPositions[i] = translatedPoint; } else if (associatedElements[i] is MenuItem) { // MenuItem Exclusive Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].DesiredSize; keyTipPositions[i] = associatedElements[i].TranslatePoint( new Point( elementSize.Height / 2.0 + 2, elementSize.Height / 2.0 + 2), AdornedElement); } else if (associatedElements[i] is BackstageTabItem) { // BackstageButton Exclusive Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].DesiredSize; keyTipPositions[i] = associatedElements[i].TranslatePoint( new Point( 5, elementSize.Height / 2.0 - keyTipSize.Height), AdornedElement); } else if (((FrameworkElement)associatedElements[i]).Parent is BackstageTabControl) { // Backstage Items Exclusive Placement var keyTipSize = keyTips[i].DesiredSize; var elementSize = associatedElements[i].DesiredSize; keyTipPositions[i] = associatedElements[i].TranslatePoint( new Point( 20, elementSize.Height / 2.0 - keyTipSize.Height), AdornedElement); } else { if ((RibbonAttachedProperties.GetRibbonSize(associatedElements[i]) != RibbonControlSize.Large) || (associatedElements[i] is Spinner) || (associatedElements[i] is ComboBox) || (associatedElements[i] is TextBox) || (associatedElements[i] is CheckBox)) { var withinRibbonToolbar = IsWithinRibbonToolbarInTwoLine(associatedElements[i]); var translatedPoint = associatedElements[i].TranslatePoint(new Point(keyTips[i].DesiredSize.Width / 2.0, keyTips[i].DesiredSize.Height / 2.0), AdornedElement); // Snapping to rows if it present if (rows != null) { var index = 0; var mindistance = Math.Abs(rows[0] - translatedPoint.Y); for (var j = 1; j < rows.Length; j++) { if (withinRibbonToolbar && j == 1) { continue; } var distance = Math.Abs(rows[j] - translatedPoint.Y); if (distance < mindistance) { mindistance = distance; index = j; } } translatedPoint.Y = rows[index] - keyTips[i].DesiredSize.Height / 2.0; } keyTipPositions[i] = translatedPoint; } else { var translatedPoint = associatedElements[i].TranslatePoint(new Point( associatedElements[i].DesiredSize.Width / 2.0 - keyTips[i].DesiredSize.Width / 2.0, associatedElements[i].DesiredSize.Height - 8), AdornedElement); if (rows != null) { translatedPoint.Y = rows[2] - keyTips[i].DesiredSize.Height / 2.0; } keyTipPositions[i] = translatedPoint; } } } }
/// <summary> /// Layout logic for the given layout definition /// </summary> /// <param name="layoutDefinition">Current layout definition</param> /// <param name="availableSize">Available or final size</param> /// <param name="measure">Pass true if measure required; pass false if arrange required</param> /// <param name="addchildren">Determines whether we have to add children to the logical and visual tree</param> /// <returns>Final size</returns> Size CustomLayout(RibbonToolBarLayoutDefinition layoutDefinition, Size availableSize, bool measure, bool addchildren) { bool arrange = !measure; double availableHeight = Double.IsPositiveInfinity(availableSize.Height) ? 0 : availableSize.Height; // Clear separator cahce if (addchildren) { separatorCache.Clear(); } // Get the first control and measure, its height accepts as row height double rowHeight = GetRowHeight(layoutDefinition); // Calculate whitespace int rowCountInColumn = Math.Min(layoutDefinition.RowCount, layoutDefinition.Rows.Count); double whitespace = (availableHeight - ((double)rowCountInColumn * rowHeight)) / (double)(rowCountInColumn + 1); double y = 0; double x = 0; double currentRowBegin = 0; double currentMaxX = 0; double maxy = 0; for (int rowIndex = 0; rowIndex < layoutDefinition.Rows.Count; rowIndex++) { RibbonToolBarRow row = layoutDefinition.Rows[rowIndex]; x = currentRowBegin; if (rowIndex % rowCountInColumn == 0) { // Reset vars at new column x = currentRowBegin = currentMaxX; y = 0; if (rowIndex != 0) { #region Add separator Separator separator = null; if (!separatorCache.TryGetValue(rowIndex, out separator)) { separator = new Separator(); separator.Style = SeparatorStyle; separatorCache.Add(rowIndex, separator); } if (measure) { separator.Height = availableHeight - separator.Margin.Bottom - separator.Margin.Top; separator.Measure(availableSize); } if (arrange) { separator.Arrange(new Rect(x, y, separator.DesiredSize.Width, separator.DesiredSize.Height)); } x += separator.DesiredSize.Width; if (addchildren) { // Add control in the children AddVisualChild(separator); AddLogicalChild(separator); actualChildren.Add(separator); } #endregion } } y += whitespace; // Measure & arrange new row for (int i = 0; i < row.Children.Count; i++) { if (row.Children[i] is RibbonToolBarControlDefinition) { // Control Definition Case RibbonToolBarControlDefinition controlDefinition = (RibbonToolBarControlDefinition)row.Children[i]; FrameworkElement control = GetControl(controlDefinition); if (control == null) { continue; } if (addchildren) { // Add control in the children AddVisualChild(control); AddLogicalChild(control); actualChildren.Add(control); } if (measure) { // Apply Control Definition Properties RibbonAttachedProperties.SetRibbonSize(control, RibbonAttachedProperties.GetRibbonSize(controlDefinition)); control.Width = controlDefinition.Width; control.Measure(availableSize); } if (arrange) { control.Arrange(new Rect(x, y, control.DesiredSize.Width, control.DesiredSize.Height)); } x += control.DesiredSize.Width; } if (row.Children[i] is RibbonToolBarControlGroupDefinition) { // Control Definition Case RibbonToolBarControlGroupDefinition controlGroupDefinition = (RibbonToolBarControlGroupDefinition)row.Children[i]; RibbonToolBarControlGroup control = GetControlGroup(controlGroupDefinition); if (addchildren) { // Add control in the children AddVisualChild(control); AddLogicalChild(control); actualChildren.Add(control); } if (measure) { // Apply Control Definition Properties control.IsFirstInRow = (i == 0); control.IsLastInRow = (i == row.Children.Count - 1); control.Measure(availableSize); } if (arrange) { control.Arrange(new Rect(x, y, control.DesiredSize.Width, control.DesiredSize.Height)); } x += control.DesiredSize.Width; } } y += rowHeight; if (currentMaxX < x) { currentMaxX = x; } if (maxy < y) { maxy = y; } } return(new Size(currentMaxX, maxy + whitespace)); }