public static void LayoutButton(ButtonItem button, bool startButtonType) { Control objCtrl = button.ContainerControl as Control; if (objCtrl == null || objCtrl.Disposing || objCtrl.IsDisposed) //if(!BarFunctions.IsHandleValid(objCtrl)) return; if (objCtrl is ButtonX && button._FitContainer) { LayoutButtonX(button); return; } else if (button.FixedSize.Width > 0 && button.FixedSize.Height > 0) { button.SetDisplayRectangle(new Rectangle(button.DisplayRectangle.Location, button.FixedSize)); LayoutButtonX(button); return; } bool isOnMenu = button.IsOnMenu; if (isOnMenu && button.Parent is ItemContainer) isOnMenu = false; bool bHasImage = false; bool isSymbolImage = false; if (!string.IsNullOrEmpty(button.Symbol)) { bHasImage = true; isSymbolImage = true; } else { using (CompositeImage buttonImage = button.GetImage()) { if (buttonImage != null || startButtonType) bHasImage = true; } } eImagePosition imagePosition = button.ImagePosition; bool rightToLeft = (objCtrl.RightToLeft == RightToLeft.Yes); Rectangle textDrawRect = Rectangle.Empty; Rectangle imageDrawRect = Rectangle.Empty; Rectangle subItemsRect = Rectangle.Empty; Rectangle bounds = new Rectangle(button.DisplayRectangle.Location, Size.Empty); // Critical to preserve the location for compatibility reasons if (rightToLeft && button.Orientation == eOrientation.Horizontal) { if (imagePosition == eImagePosition.Left) imagePosition = eImagePosition.Right; else if (imagePosition == eImagePosition.Right) imagePosition = eImagePosition.Left; } int measureStringWidth = 0; if (button._FitContainer) measureStringWidth = button.DisplayRectangle.Width - 4; bounds.Width = 0; bounds.Height = 0; Graphics g = BarFunctions.CreateGraphics(objCtrl); try { eTextFormat stringFormat = GetTextFormat(button); // Get the right image size that we will use for calculation Size imageSize = Size.Empty; if (isSymbolImage) { Font symFont = Symbols.GetFontAwesome(button.SymbolSize); if(button.IsOnMenu) // Need to do this to get consistent size for the symbol since they are not all the same width we pick widest imageSize = TextDrawing.MeasureString(g, "\uF00A", symFont); else imageSize = TextDrawing.MeasureString(g, button.Symbol, symFont); int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); imageSize.Height -= descent; button.ImageSize = imageSize; } else { imageSize = GetLayoutImageSize(button, bHasImage, isOnMenu, startButtonType); } bool ribbonBarButton = false; if (button._FitContainer && bHasImage && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right)) { measureStringWidth -= (imageSize.Width + 10); } else if (button.RibbonWordWrap && bHasImage && imagePosition == eImagePosition.Top && objCtrl is RibbonBar && UseRibbonWordBreak(button)) { measureStringWidth = imageSize.Width + 4; stringFormat |= eTextFormat.WordBreak; ribbonBarButton = true; } // Measure string Font font = button.GetFont(null, true); SizeF textSize = SizeF.Empty; if ((button.Text != "" || button.TextMarkupBody != null) && (!bHasImage || isOnMenu || button.ButtonStyle != eButtonStyle.Default || button.ImagePosition != eImagePosition.Left && bHasImage)) { textSize = ButtonItemLayout.MeasureItemText(button, g, measureStringWidth, font, stringFormat, rightToLeft, ribbonBarButton, imagePosition); //if (button.HotFontBold) textSize.Width += textSize.Width * .15f; int maxItt = 0; int increase = Math.Max(14, imageSize.Width / 2); while (ribbonBarButton && textSize.Height > font.Height * 2.2 && maxItt < 3) { measureStringWidth += increase; textSize = ButtonItemLayout.MeasureItemText(button, g, measureStringWidth, font, stringFormat, rightToLeft, ribbonBarButton, imagePosition); maxItt++; } if (/*!ribbonBarButton &&*/ objCtrl is RibbonBar && bHasImage && imagePosition == eImagePosition.Top) textSize.Height += 2; } // See if this button is on menu, and do appropriate calculations if (isOnMenu) { if (imageSize.IsEmpty) imageSize = new Size(16, 16); // Add 4 pixel padding to the image size, 2 pixels on each side imageSize.Height += 2; imageSize.Width += 7; // Calculate item height if (textSize.Height > imageSize.Height) bounds.Height = (int)textSize.Height + 4; else bounds.Height = imageSize.Height + 4; // Add Vertical Padding to it bounds.Height += button.VerticalPadding; // We know the image position now, we will center it into this area if (button.IsOnCustomizeMenu && !rightToLeft) imageDrawRect = new Rectangle(bounds.Height + 2, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); else imageDrawRect = new Rectangle(0, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); bounds.Width = (int)textSize.Width; // Add short-cut size if we have short-cut if (button.DrawShortcutText != "") { Size objSizeShortcut = TextDrawing.MeasureString(g, button.DrawShortcutText, font, 0, stringFormat); bounds.Width += (objSizeShortcut.Width + 14); // 14 distance between text and shortcut } textDrawRect = new Rectangle(imageDrawRect.Right + 8, 2, bounds.Width, bounds.Height - 4); // 8 pixels distance between image and text, 22 pixels if this item has sub items bounds.Width += (imageDrawRect.Right + 8 + 26); bounds.Width += button.HorizontalPadding; } else { bool bThemed = button.IsThemed; if (button.Orientation == eOrientation.Horizontal && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right)) { // Recalc size for the Bar button // Add 8 pixel padding to the image size, 4 pixels on each side //objImageSize.Height+=4; imageSize.Width += button.ImagePaddingHorizontal; // Calculate item height if (textSize.Height > imageSize.Height) bounds.Height = (int)textSize.Height + button.ImagePaddingVertical; else bounds.Height = imageSize.Height + button.ImagePaddingVertical; // Add Vertical Padding bounds.Height += button.VerticalPadding; if (bThemed && !button.IsOnMenuBar) bounds.Height += 4; imageDrawRect = Rectangle.Empty; if (button.ButtonStyle != eButtonStyle.TextOnlyAlways && bHasImage) { // We know the image position now, we will center it into this area imageDrawRect = new Rectangle(0, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); } // Draw Text only if needed textDrawRect = Rectangle.Empty; if (button.ButtonStyle != eButtonStyle.Default || !bHasImage) { if (imageDrawRect.Right > 0) { bounds.Width = (int)textSize.Width + 1; textDrawRect = new Rectangle(imageDrawRect.Right - 2, 2, bounds.Width, bounds.Height - 4); } else { bounds.Width = (int)textSize.Width + 6; if (!bHasImage && button.IsOnMenuBar) { bounds.Width += 6; textDrawRect = new Rectangle(2, 2, bounds.Width, bounds.Height - 4); } else textDrawRect = new Rectangle(2, 2, bounds.Width + button.HorizontalPadding - 4, bounds.Height - 4); } } bounds.Width += imageDrawRect.Right; if (imagePosition == eImagePosition.Right && imageDrawRect.Right > 0 && bHasImage) { textDrawRect.X = 3; imageDrawRect.X = bounds.Width - imageDrawRect.Width; } // Add Horizontal padding bounds.Width += button.HorizontalPadding; } else { // Image is on top or bottom // Calculate width, that is easy if (button.Orientation == eOrientation.Horizontal) { if (textSize.Width > imageSize.Width) bounds.Width = (int)textSize.Width + button.ImagePaddingHorizontal; else bounds.Width = imageSize.Width + button.ImagePaddingHorizontal; // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text bounds.Height = (int)(imageSize.Height + textSize.Height + button.ImagePaddingVertical /*10*/); // Add Horizontal/Vertical padding bounds.Width += button.HorizontalPadding; bounds.Height += button.VerticalPadding; if (imagePosition == eImagePosition.Top) { imageDrawRect = new Rectangle(0, button.VerticalPadding / 2 + 2, bounds.Width, imageSize.Height/*+2*/); textDrawRect = new Rectangle((int)(bounds.Width - textSize.Width) / 2, imageDrawRect.Bottom, (int)textSize.Width, (int)textSize.Height + 5); } else { textDrawRect = new Rectangle((int)(bounds.Width - textSize.Width) / 2, button.VerticalPadding / 2, (int)textSize.Width, (int)textSize.Height + 2); imageDrawRect = new Rectangle(0, textDrawRect.Bottom, bounds.Width, imageSize.Height + 5); } } else { if (textSize.Height > imageSize.Width && button.ButtonStyle != eButtonStyle.Default) bounds.Width = (int)textSize.Height + 6; else bounds.Width = imageSize.Width + 10; // Add Horizontal Padding bounds.Width += button.HorizontalPadding; // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text if (button.ButtonStyle != eButtonStyle.Default || !bHasImage) { if (bHasImage) bounds.Height = (int)(imageSize.Height + textSize.Width + 12); else bounds.Height = (int)(textSize.Width + 6); } else bounds.Height = imageSize.Height + 6; if (imagePosition == eImagePosition.Top || imagePosition == eImagePosition.Left) { if (bHasImage) imageDrawRect = new Rectangle(0, 0, bounds.Width, imageSize.Height + 6); textDrawRect = new Rectangle((int)(bounds.Width - textSize.Height) / 2, imageDrawRect.Bottom + 2, (int)textSize.Height, (int)textSize.Width + 5); } else { textDrawRect = new Rectangle((int)(bounds.Width - textSize.Height) / 2, 5, (int)textSize.Height, (int)textSize.Width + 5); if (bHasImage) imageDrawRect = new Rectangle(0, textDrawRect.Bottom - 3, bounds.Width, imageSize.Height + 5); } // Add Vertical Padding bounds.Height += button.VerticalPadding; } } if (HasExpandPart(button)) { subItemsRect = GetSubItemsButtonBounds(button, bounds, rightToLeft); // Add small button to expand the item Rectangle rTemp = subItemsRect; rTemp.Offset(bounds.Location); if (rightToLeft && !(objCtrl is RibbonBar && (button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom))) { if (!textDrawRect.IsEmpty) textDrawRect.Offset(subItemsRect.Width + 1, 0); if (!imageDrawRect.IsEmpty && (button.Orientation == eOrientation.Horizontal && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right))) imageDrawRect.Offset(subItemsRect.Width, 0); bounds.X += subItemsRect.Width; } bounds = Rectangle.Union(bounds, rTemp); } } } finally { g.TextRenderingHint = TextRenderingHint.SystemDefault; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; g.Dispose(); } objCtrl = null; button.SetDisplayRectangle(bounds); button.ImageDrawRect = imageDrawRect; button.TextDrawRect = textDrawRect; button.SubItemsRect = subItemsRect; }