// ********************************* // Message from Original Author: // // 2008 Jose Menendez Poo // Please give me credit if you use this code. It's all I ask. // Contact me for more info: menendezpoo@gmail.com // ********************************* // // Original project from http://ribbon.codeplex.com/ // Continue to support and maintain by http://officeribbon.codeplex.com/ using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Text; using System.Text.RegularExpressions; namespace System.Windows.Forms { [Designer(typeof(RibbonButtonDesigner))] public class RibbonButton : RibbonItem, IContainsRibbonComponents { #region Fields private const int arrowWidth = 5; private RibbonButtonStyle _style; private Image _smallImage; private Image _flashSmallImage; private Size _dropDownArrowSize; private Padding _dropDownMargin; private Point _lastMousePos; private RibbonArrowDirection _dropDownArrowDirection; //Kevin - Tracks the selected item when it has dropdownitems assigned private RibbonItem _selectedItem; private readonly Set _assignedHandlers; private Size _minimumSize; private Size _maximumSize; #endregion #region Events /// /// Occurs when the dropdown is about to be displayed /// public event EventHandler DropDownShowing; public event RibbonItemEventHandler DropDownItemClicked; public delegate void RibbonItemEventHandler(object sender, RibbonItemEventArgs e); public virtual void OnDropDownItemClicked(ref RibbonItemEventArgs e) { if (DropDownItemClicked != null) { DropDownItemClicked(this, e); } } #endregion #region Ctors /// /// Creates a new button /// ///// Image of the button (32 x 32 suggested) ///// Image of the button when in medium of compact mode (16 x 16 suggested) ///// Style of the button ///// Text of the button public RibbonButton() { _style = RibbonButtonStyle.Normal; _dropDownArrowDirection = RibbonArrowDirection.Down; _assignedHandlers = new Set(); DropDownItems = new RibbonItemCollection(); DropDownItems.SetOwnerItem(this); _dropDownArrowSize = new Size(5, 3); _dropDownMargin = new Padding(6); Image = CreateImage(32); SmallImage = CreateImage(16); DrawDropDownIconsBar = true; } public RibbonButton(string text) : this() { Text = text; } public RibbonButton(Image smallImage) : this() { SmallImage = smallImage; } /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && RibbonDesigner.Current == null) { RemoveHandlers(); //Dont Dispose Image, could be an Ressource Image //if (SmallImage != null) // SmallImage.Dispose(); //if (FlashSmallImage != null) // FlashSmallImage.Dispose(); } base.Dispose(disposing); } #endregion #region Props /// /// Gets the last DropDown Item that was clicked /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public RibbonItem SelectedItem { get { if (_selectedItem == null) { return null; } if (DropDownItems.Contains(_selectedItem)) { return _selectedItem; } _selectedItem = null; return null; } set { if (value.GetType().BaseType == typeof(RibbonItem)) { if (DropDownItems.Contains(value)) { _selectedItem = value; } else { DropDownItems.Add(value); _selectedItem = value; } } } } /// /// Gets or sets the value of selected item on the dropdown. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string SelectedValue { get { if (_selectedItem == null) { return null; } return _selectedItem.Value; } set { foreach (RibbonItem item in DropDownItems) { if (item.Value == value) { _selectedItem = item; } } } } /// /// Gets the DropDown of the button /// internal RibbonDropDown DropDown { get; private set; } /// /// Gets or sets if the icon bar on a drop down should be drawn /// [Category("Drop Down")] [DefaultValue(true)] [Description("Gets or sets if the icon bar on a drop down should be drawn")] public bool DrawDropDownIconsBar { get; set; } /// /// Gets or sets a value indicating if the property should be toggled /// when button is clicked /// [DefaultValue(false)] [Category("Behavior")] [Description("Toggles the Checked property of the button when clicked")] public bool CheckOnClick { get; set; } /// /// Gets or sets a value indicating if the DropDown should be resizable /// [Category("Drop Down")] [DefaultValue(false)] [Description("Makes the DropDown resizable with a grip on the corner")] public bool DropDownResizable { get; set; } /// /// Gets the bounds where the or will be drawn. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle ImageBounds { get; private set; } /// /// Gets the bounds where the of the button will be drawn /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle TextBounds { get; private set; } /// /// Gets if the DropDown is currently visible /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool DropDownVisible { get; private set; } /// /// Gets or sets the size of the dropdown arrow /// [Browsable(false)] [DefaultValue(typeof(Size), "5, 3")] public Size DropDownArrowSize { get => _dropDownArrowSize; set { _dropDownArrowSize = value; NotifyOwnerRegionsChanged(); } } /// /// Gets or sets the direction where drop down's arrow should be pointing to /// [Category("Drop Down")] [DefaultValue(RibbonArrowDirection.Down)] public RibbonArrowDirection DropDownArrowDirection { get => _dropDownArrowDirection; set { _dropDownArrowDirection = value; NotifyOwnerRegionsChanged(); } } /// /// Gets the style of the button /// [DefaultValue(RibbonButtonStyle.Normal)] [Category("Appearance")] [Description("Indicates the visual style of the button.")] public RibbonButtonStyle Style { get => _style; set { _style = value; if (Canvas is RibbonPopup || (OwnerItem != null && OwnerItem.Canvas is RibbonPopup)) { DropDownArrowDirection = RibbonArrowDirection.Left; } NotifyOwnerRegionsChanged(); } } /// /// Gets the collection of items shown on the dropdown pop-up when Style allows it /// [Category("Drop Down")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public RibbonItemCollection DropDownItems { get; } /// /// Gets the bounds of the button face /// /// When Style is different from SplitDropDown and SplitBottomDropDown, ButtonFaceBounds is the same area than DropDownBounds [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public Rectangle ButtonFaceBounds { get; private set; } /// /// Gets the bounds of the dropdown button /// /// When Style is different from SplitDropDown and SplitBottomDropDown, ButtonFaceBounds is the same area than DropDownBounds [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public Rectangle DropDownBounds { get; private set; } /// /// Gets if the dropdown part of the button is selected /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool DropDownSelected { get; private set; } /// /// Gets if the dropdown part of the button is pressed /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool DropDownPressed { get; private set; } /// /// Gets or sets the image of the button when in large size mode. /// [DefaultValue(null)] [Category("Appearance")] [Description("sets the image of the button when in large size mode.")] public virtual Image LargeImage { get => base.Image; set => base.Image = value; } /// /// Gets or sets the image of the button when in large size mode. /// [Browsable(false)] [Category("Appearance")] public override Image Image { get => base.Image; set => base.Image = value; } /// /// Gets or sets the image of the button when in compact, medium or dropdown size modes /// [DefaultValue(null)] [Category("Appearance")] [Description("sets the image of the button when in compact, medium or dropdown size modes.")] public virtual Image SmallImage { get => _smallImage; set { if (_smallImage != value) { _smallImage = value; NotifyOwnerRegionsChanged(); } } } [Category("Flash")] [DefaultValue(null)] public virtual Image FlashSmallImage { get => _flashSmallImage; set { if (_flashSmallImage != value) { _flashSmallImage = value; } } } /// /// Gets or sets the minimum size for this Item. Only applies when in Large Size Mode. /// [DefaultValue(typeof(Size), "0, 0")] [Category("Appearance")] [Description("Sets the minimum size for this Item. Only applies when in Large Size Mode.")] public Size MinimumSize { get => _minimumSize; set { _minimumSize = value; NotifyOwnerRegionsChanged(); } } /// /// Gets or sets the maximum size for this Item. Only applies when in Large Size Mode. /// [DefaultValue(typeof(Size), "0, 0")] [Category("Appearance")] [Description("Sets the maximum size for this Item. Only applies when in Large Size Mode.")] public Size MaximumSize { get => _maximumSize; set { _maximumSize = value; NotifyOwnerRegionsChanged(); } } #endregion #region Methods /// /// Sets the value of the property /// /// protected void SetDropDownMargin(Padding p) { _dropDownMargin = p; } /// /// Performs a click on the button /// public void PerformClick() { OnClick(EventArgs.Empty); } /// /// Creates a new Transparent, empty image /// /// /// private Image CreateImage(int size) { Bitmap bmp = new Bitmap(size, size); //using (Graphics g = Graphics.FromImage(bmp)) //{ // g.Clear(Color.FromArgb(50, Color.Navy)); //} return bmp; } /// /// Creates the DropDown menu /// protected virtual void CreateDropDown() { DropDown = new RibbonDropDown(this, DropDownItems, Owner); } internal override void SetPressed(bool pressed) { base.SetPressed(pressed); } internal override void SetOwner(Ribbon owner) { base.SetOwner(owner); if (DropDownItems != null) DropDownItems.SetOwner(owner); } internal override void SetOwnerPanel(RibbonPanel ownerPanel) { base.SetOwnerPanel(ownerPanel); if (DropDownItems != null) DropDownItems.SetOwnerPanel(ownerPanel); } internal override void SetOwnerTab(RibbonTab ownerTab) { base.SetOwnerTab(ownerTab); if (DropDownItems != null) DropDownItems.SetOwnerTab(ownerTab); } internal override void SetOwnerItem(RibbonItem ownerItem) { base.SetOwnerItem(ownerItem); } internal override void ClearOwner() { List oldItems = DropDownItems == null ? null : new List(DropDownItems); base.ClearOwner(); if (oldItems != null) { foreach (RibbonItem item in oldItems) { item.ClearOwner(); } } } /// /// Raises the Paint event. /// /// /// public override void OnPaint(object sender, RibbonElementPaintEventArgs e) { if (Owner == null) return; OnPaintBackground(e); OnPaintImage(e); OnPaintText(e); } /// /// Renders text of the button /// /// protected virtual void OnPaintText(RibbonElementPaintEventArgs e) { if (SizeMode != RibbonElementSizeMode.Compact) { StringFormat sf = StringFormatFactory.NearCenter(); if (Owner.AltPressed || Owner.OrbDropDown.MenuItems.Contains(this)) { sf.HotkeyPrefix = HotkeyPrefix.Show; } else { sf.HotkeyPrefix = HotkeyPrefix.Hide; } if (SizeMode == RibbonElementSizeMode.Large) { sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Near; } if (Style == RibbonButtonStyle.DropDownListItem) { sf.LineAlignment = StringAlignment.Near; Owner.Renderer.OnRenderRibbonItemText( new RibbonTextEventArgs(Owner, e.Graphics, e.Clip, this, Bounds, Text, sf)); } else { var newText = Text; if (!String.IsNullOrEmpty(AltKey) && Text.Contains(AltKey)) { var regex = new Regex(Regex.Escape(AltKey), RegexOptions.IgnoreCase); newText = regex.Replace(Text.Replace("&", ""), "&" + AltKey, 1).Replace("&&", "&"); } Owner.Renderer.OnRenderRibbonItemText( new RibbonTextEventArgs(Owner, e.Graphics, e.Clip, this, TextBounds, newText, sf)); } } } /// /// Renders the image of the button /// /// private void OnPaintImage(RibbonElementPaintEventArgs e) { RibbonElementSizeMode theSize = GetNearestSize(e.Mode); if (_showFlashImage) { if ((theSize == RibbonElementSizeMode.Large && FlashImage != null) || FlashSmallImage != null) { Owner.Renderer.OnRenderRibbonItemImage( new RibbonItemBoundsEventArgs(Owner, e.Graphics, e.Clip, this, OnGetImageBounds(theSize, Bounds))); } } else { if ((theSize == RibbonElementSizeMode.Large && Image != null) || SmallImage != null) { Owner.Renderer.OnRenderRibbonItemImage( new RibbonItemBoundsEventArgs(Owner, e.Graphics, e.Clip, this, OnGetImageBounds(theSize, Bounds))); } } } /// /// Renders the background of the buton /// /// private void OnPaintBackground(RibbonElementPaintEventArgs e) { Owner.Renderer.OnRenderRibbonItem(new RibbonItemRenderEventArgs(Owner, e.Graphics, e.Clip, this)); } /// /// Sets the bounds of the button /// /// public override void SetBounds(Rectangle bounds) { base.SetBounds(bounds); RibbonElementSizeMode sMode = GetNearestSize(SizeMode); ImageBounds = OnGetImageBounds(sMode, bounds); TextBounds = OnGetTextBounds(sMode, bounds); if (Style == RibbonButtonStyle.SplitDropDown) { DropDownBounds = OnGetDropDownBounds(sMode, bounds); ButtonFaceBounds = OnGetButtonFaceBounds(sMode, bounds); } } /// /// Sets the bounds of the image of the button when SetBounds is called. /// Override this method to change image bounds /// /// Mode which is being measured /// Bounds of the button /// /// The measuring occours in the following order: /// /// OnSetImageBounds /// OnSetTextBounds /// OnSetDropDownBounds /// OnSetButtonFaceBounds /// /// internal virtual Rectangle OnGetImageBounds(RibbonElementSizeMode sMode, Rectangle bounds) { if (sMode == RibbonElementSizeMode.Large)// || this is RibbonOrbMenuItem) { if (Image != null) { int marginTop = Owner == null ? 0 : Owner.ItemMargin.Top; return new Rectangle( Bounds.Left + ((Bounds.Width - Image.Width) / 2), Bounds.Top + marginTop, Image.Width, Image.Height); } return new Rectangle(ContentBounds.Location, new Size(32, 32)); } if (SmallImage != null) { if (SmallImage.PixelFormat != PixelFormat.DontCare) { return new Rectangle( Bounds.Left + Owner.ItemMargin.Left, Bounds.Top + ((Bounds.Height - SmallImage.Height) / 2), SmallImage.Width, SmallImage.Height); } } return new Rectangle(ContentBounds.Location, new Size(0, 0)); } /// /// Sets the bounds of the text of the button when SetBounds is called. /// Override this method to change image bounds /// /// Mode which is being measured /// Bounds of the button /// /// The measuring occours in the following order: /// /// OnSetImageBounds /// OnSetTextBounds /// OnSetDropDownBounds /// OnSetButtonFaceBounds /// /// internal virtual Rectangle OnGetTextBounds(RibbonElementSizeMode sMode, Rectangle bounds) { int imgw = ImageBounds.Width; int imgh = ImageBounds.Height; if (sMode == RibbonElementSizeMode.Large) { if (Owner == null) { return Rectangle.FromLTRB( Bounds.Left, Bounds.Top + imgh, Bounds.Right, Bounds.Bottom); } else { return Rectangle.FromLTRB( Bounds.Left + Owner.ItemMargin.Left, Bounds.Top + Owner.ItemMargin.Top + imgh, Bounds.Right - Owner.ItemMargin.Right, Bounds.Bottom - Owner.ItemMargin.Bottom); } } // ddw is the dropdown arrow width int ddw = (Style == RibbonButtonStyle.Normal || Style == RibbonButtonStyle.DropDownListItem) ? 0 : _dropDownMargin.Horizontal; int imageToTextSpacing = (sMode == RibbonElementSizeMode.DropDown) ? Owner.ItemImageToTextSpacing : 0; return Rectangle.FromLTRB( Bounds.Left + imgw + Owner.ItemMargin.Horizontal + Owner.ItemMargin.Left + imageToTextSpacing, Bounds.Top + Owner.ItemMargin.Top, Bounds.Right - ddw, Bounds.Bottom - Owner.ItemMargin.Bottom); } /// /// Sets the bounds of the dropdown part of the button when SetBounds is called. /// Override this method to change image bounds /// /// Mode which is being measured /// Bounds of the button /// /// The measuring occours in the following order: /// /// OnSetImageBounds /// OnSetTextBounds /// OnSetDropDownBounds /// OnSetButtonFaceBounds /// /// internal virtual Rectangle OnGetDropDownBounds(RibbonElementSizeMode sMode, Rectangle bounds) { Rectangle sideBounds = Rectangle.FromLTRB( bounds.Right - _dropDownMargin.Horizontal - 2, bounds.Top, bounds.Right, bounds.Bottom); switch (sMode) { case RibbonElementSizeMode.Large: case RibbonElementSizeMode.Overflow: return Rectangle.FromLTRB(bounds.Left, bounds.Top + Image.Height + Owner.ItemMargin.Vertical, bounds.Right, bounds.Bottom); case RibbonElementSizeMode.DropDown: case RibbonElementSizeMode.Medium: case RibbonElementSizeMode.Compact: return sideBounds; } return Rectangle.Empty; } /// /// Sets the bounds of the button face part of the button when SetBounds is called. /// Override this method to change image bounds /// /// Mode which is being measured /// Bounds of the button /// /// The measuring occours in the following order: /// /// OnSetImageBounds /// OnSetTextBounds /// OnSetDropDownBounds /// OnSetButtonFaceBounds /// /// internal virtual Rectangle OnGetButtonFaceBounds(RibbonElementSizeMode sMode, Rectangle bounds) { Rectangle sideBounds = Rectangle.FromLTRB( bounds.Right - _dropDownMargin.Horizontal - 2, bounds.Top, bounds.Right, bounds.Bottom); switch (sMode) { case RibbonElementSizeMode.Large: case RibbonElementSizeMode.Overflow: return Rectangle.FromLTRB(bounds.Left, bounds.Top, bounds.Right, DropDownBounds.Top); case RibbonElementSizeMode.DropDown: case RibbonElementSizeMode.Medium: case RibbonElementSizeMode.Compact: return Rectangle.FromLTRB(bounds.Left, bounds.Top, DropDownBounds.Left, bounds.Bottom); } return Rectangle.Empty; } /// /// Measures the string for the large size /// /// /// /// /// public static Size MeasureStringLargeSize(Graphics g, string text, Font font) { if (string.IsNullOrEmpty(text)) { return Size.Empty; } Size sz = g.MeasureString(text, font).ToSize(); string[] words = text.Split(' '); string longestWord = string.Empty; int width = sz.Width; for (int i = 0; i < words.Length; i++) { if (words[i].Length > longestWord.Length) { longestWord = words[i]; } } if (words.Length > 1) { width = Math.Max(sz.Width / 2, g.MeasureString(longestWord, font).ToSize().Width) + 1; } else { return g.MeasureString(text, font).ToSize(); } Size rs = g.MeasureString(text, font, width).ToSize(); return new Size(rs.Width, rs.Height); } /// /// Measures the size of the button /// /// /// /// public override Size MeasureSize(object sender, RibbonElementMeasureSizeEventArgs e) { if (Owner == null || (!Visible && !Owner.IsDesignMode())) { SetLastMeasuredSize(new Size(0, 0)); return LastMeasuredSize; } RibbonElementSizeMode theSize = GetNearestSize(e.SizeMode); int widthSum = Owner.ItemMargin.Horizontal; int heightSum = Owner.ItemMargin.Vertical; int largeHeight = OwnerPanel == null ? 0 : OwnerPanel.ContentBounds.Height - Owner.ItemPadding.Vertical;// -Owner.ItemMargin.Vertical; //58; Size simg = SmallImage != null ? SmallImage.Size : Size.Empty; Size img = Image != null ? Image.Size : Size.Empty; Size sz = Size.Empty; switch (theSize) { case RibbonElementSizeMode.Large: case RibbonElementSizeMode.Overflow: sz = MeasureStringLargeSize(e.Graphics, Text, Owner.Font); if (!string.IsNullOrEmpty(Text)) { widthSum += Math.Max(sz.Width + 1, img.Width); //Got off the patch site from logicalerror //heightSum = largeHeight; heightSum = Math.Max(0, largeHeight); } else { widthSum += img.Width; heightSum += img.Height; } break; case RibbonElementSizeMode.DropDown: sz = Size.Ceiling(e.Graphics.MeasureString(Text, Owner.Font)); if (!string.IsNullOrEmpty(Text)) widthSum += sz.Width + 1; widthSum += simg.Width + Owner.ItemMargin.Horizontal + Owner.ItemImageToTextSpacing; heightSum += Math.Max(sz.Height, simg.Height); break; case RibbonElementSizeMode.Medium: sz = Size.Ceiling(e.Graphics.MeasureString(Text, Owner.Font)); if (!string.IsNullOrEmpty(Text)) widthSum += sz.Width + 1; widthSum += simg.Width + Owner.ItemMargin.Horizontal; heightSum += Math.Max(sz.Height, simg.Height); break; case RibbonElementSizeMode.Compact: widthSum += simg.Width; heightSum += simg.Height; break; default: throw new ArgumentException("SizeMode not supported: " + e.SizeMode); } //if (theSize == RibbonElementSizeMode.DropDown) //{ // heightSum += 2; //} switch (Style) { case RibbonButtonStyle.DropDown: case RibbonButtonStyle.SplitDropDown: // drawing size calculation for DropDown and SplitDropDown is identical widthSum += arrowWidth + _dropDownMargin.Horizontal; break; case RibbonButtonStyle.DropDownListItem: break; } //check the minimum and mazimum size properties but only in large mode if (theSize == RibbonElementSizeMode.Large) { //Minimum Size if (MinimumSize.Height > 0 && heightSum < MinimumSize.Height) heightSum = MinimumSize.Height; if (MinimumSize.Width > 0 && widthSum < MinimumSize.Width) widthSum = MinimumSize.Width; //Maximum Size if (MaximumSize.Height > 0 && heightSum > MaximumSize.Height) heightSum = MaximumSize.Height; if (MaximumSize.Width > 0 && widthSum > MaximumSize.Width) widthSum = MaximumSize.Width; } SetLastMeasuredSize(new Size(widthSum, heightSum)); return LastMeasuredSize; } /// /// Sets the value of the DropDownPressed property /// /// Value that indicates if the dropdown button is pressed internal void SetDropDownPressed(bool pressed) { throw new NotSupportedException(); } /// /// Sets the value of the DropDownSelected property /// /// Value that indicates if the dropdown part of the button is selected internal void SetDropDownSelected(bool selected) { //Dont use, an overflow occours throw new NotSupportedException(); } /// /// Shows the drop down items of the button, as if the dropdown part has been clicked /// public void ShowDropDown() { if (Style == RibbonButtonStyle.Normal) { if (DropDown != null) RibbonPopupManager.DismissChildren(DropDown, RibbonPopupManager.DismissReason.NewPopup); return; } if (Style == RibbonButtonStyle.DropDown) { SetPressed(true); } else { DropDownPressed = true; } OnDropDownShowing(EventArgs.Empty); if (DropDownItems.Count == 0) { if (DropDown != null) RibbonPopupManager.DismissChildren(DropDown, RibbonPopupManager.DismissReason.NewPopup); return; } AssignHandlers(); CreateDropDown(); DropDown.MouseEnter += DropDown_MouseEnter; DropDown.Closed += DropDown_Closed; DropDown.ShowSizingGrip = DropDownResizable; DropDown.DrawIconsBar = DrawDropDownIconsBar; RibbonPopup canvasdd = Canvas as RibbonPopup; Point location = OnGetDropDownMenuLocation(); Size minsize = OnGetDropDownMenuSize(); if (!minsize.IsEmpty) DropDown.MinimumSize = minsize; SetDropDownVisible(true); DropDown.SelectionService = GetService(typeof(ISelectionService)) as ISelectionService; DropDown.Show(location); } private void DropDownItem_Click(object sender, EventArgs e) { _selectedItem = (sender as RibbonItem); RibbonItemEventArgs ev = new RibbonItemEventArgs(sender as RibbonItem); OnDropDownItemClicked(ref ev); } private void AssignHandlers() { foreach (RibbonItem item in DropDownItems) { if (_assignedHandlers.Contains(item) == false) { item.Click += DropDownItem_Click; _assignedHandlers.Add(item); } } } private void RemoveHandlers() { // ADDED if (DropDown != null) { DropDown.MouseEnter -= DropDown_MouseEnter; DropDown.Closed -= DropDown_Closed; } foreach (RibbonItem item in _assignedHandlers) { item.Click -= DropDownItem_Click; } _assignedHandlers.Clear(); } private void DropDown_MouseEnter(object sender, EventArgs e) { SetSelected(true); RedrawItem(); } /// /// Gets the location where the dropdown menu will be shown /// /// internal virtual Point OnGetDropDownMenuLocation() { Point location = Point.Empty; if (Canvas is RibbonDropDown) { location = Canvas.PointToScreen(new Point(Bounds.Right, Bounds.Top)); } else { location = Canvas.PointToScreen(new Point(Bounds.Left, Bounds.Bottom)); } return location; } /// /// Gets the size of the dropdown. If Size.Empty is returned, /// size will be measured automatically /// /// internal virtual Size OnGetDropDownMenuSize() { return Size.Empty; } /// /// Handles the closing of the dropdown /// /// /// private void DropDown_Closed(object sender, EventArgs e) { SetPressed(false); DropDownPressed = false; SetDropDownVisible(false); SetSelected(false); DropDownSelected = false; RedrawItem(); } /// /// Ignores deactivation of canvas if it is a volatile window /// private void IgnoreDeactivation() { if (Canvas is RibbonPanelPopup) { (Canvas as RibbonPanelPopup).IgnoreNextClickDeactivation(); } if (Canvas is RibbonDropDown) { (Canvas as RibbonDropDown).IgnoreNextClickDeactivation(); } } /// /// Closes the DropDown if opened /// public void CloseDropDown() { if (DropDown != null) { RibbonPopupManager.Dismiss(DropDown, RibbonPopupManager.DismissReason.NewPopup); RemoveHandlers(); DropDown = null; } SetDropDownVisible(false); } /// /// Overriden. Informs the button text /// /// public override string ToString() { return string.Format("{1}: {0}", Text, GetType().Name); } /// /// Sets the value of DropDownVisible /// /// internal void SetDropDownVisible(bool visible) { DropDownVisible = visible; } /// /// Raises the DropDownShowing event /// /// public void OnDropDownShowing(EventArgs e) { if (DropDownShowing != null) { DropDownShowing(this, e); } } #endregion #region Overrides public override void OnCanvasChanged(EventArgs e) { base.OnCanvasChanged(e); if (Canvas is RibbonDropDown) { DropDownArrowDirection = RibbonArrowDirection.Left; } } protected override bool ClosesDropDownAt(Point p) { if (Style == RibbonButtonStyle.DropDown) { return false; } if (Style == RibbonButtonStyle.SplitDropDown) { return ButtonFaceBounds.Contains(p); } return true; } internal override void SetSizeMode(RibbonElementSizeMode sizeMode) { if (sizeMode == RibbonElementSizeMode.Overflow) { base.SetSizeMode(RibbonElementSizeMode.Large); } else { base.SetSizeMode(sizeMode); } } internal override void SetSelected(bool selected) { base.SetSelected(selected); SetPressed(false); } public override void OnMouseDown(MouseEventArgs e) { if (!Enabled) return; if ((DropDownSelected || Style == RibbonButtonStyle.DropDown) && DropDownItems.Count > 0) { if (DropDownVisible == false) { DropDownPressed = true; ShowDropDown(); } else { //Hack: Workaround to close DropDown if it stays open.... DropDownPressed = false; CloseDropDown(); } } base.OnMouseDown(e); } public override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); } public override void OnMouseMove(MouseEventArgs e) { if (!Enabled) return; //Detect mouse on dropdwon if (Style == RibbonButtonStyle.SplitDropDown) { bool lastState = DropDownSelected; if (DropDownBounds.Contains(e.X, e.Y)) { DropDownSelected = true; } else { DropDownSelected = false; } if (lastState != DropDownSelected) RedrawItem(); lastState = DropDownSelected; } _lastMousePos = new Point(e.X, e.Y); base.OnMouseMove(e); } public override void OnMouseLeave(MouseEventArgs e) { base.OnMouseLeave(e); DropDownSelected = false; } public override void OnClick(EventArgs e) { if (Style != RibbonButtonStyle.Normal && Style != RibbonButtonStyle.DropDownListItem && !ButtonFaceBounds.Contains(_lastMousePos)) { //Clicked the dropdown area, don't raise Click() return; } if (CheckOnClick) Checked = !Checked; base.OnClick(e); } #endregion #region IContainsRibbonItems Members public IEnumerable GetItems() { return DropDownItems; } #endregion #region IContainsRibbonComponents Members public IEnumerable GetAllChildComponents() { return DropDownItems.ToArray(); } #endregion } }