// *********************************
// 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.Drawing;
namespace System.Windows.Forms
{
[DesignTimeVisible(false)]
[Designer(typeof(RibbonPanelDesigner))]
public class RibbonPanel :
Component, IRibbonElement, IContainsSelectableRibbonItems, IContainsRibbonComponents
{
#region Fields
private bool? _isopeninvisualstudiodesigner;
private bool _enabled;
private Image _image;
private string _text;
private bool _selected;
private RibbonPanelFlowDirection _flowsTo;
private bool _buttonMoreVisible;
private bool _buttonMoreEnabled;
internal Rectangle overflowBoundsBuffer;
private bool _visible = true;
#endregion
#region Events
///
/// Occurs when the mouse pointer enters the panel
///
public event MouseEventHandler MouseEnter;
///
/// Occurs when the mouse pointer leaves the panel
///
public event MouseEventHandler MouseLeave;
///
/// Occurs when the mouse pointer is moved inside the panel
///
public event MouseEventHandler MouseMove;
///
/// Occurs when the panel is redrawn
///
public event PaintEventHandler Paint;
///
/// Occurs when the panel is resized
///
public event EventHandler Resize;
public event EventHandler ButtonMoreClick;
public virtual event EventHandler Click;
public virtual event EventHandler DoubleClick;
public virtual event MouseEventHandler MouseDown;
public virtual event MouseEventHandler MouseUp;
#endregion
#region Ctor
///
/// Creates a new RibbonPanel
///
public RibbonPanel()
{
Items = new RibbonItemCollection();
Items.SetOwnerPanel(this);
SizeMode = RibbonElementSizeMode.None;
_flowsTo = RibbonPanelFlowDirection.Bottom;
_buttonMoreEnabled = true;
_buttonMoreVisible = true;
_enabled = true;
}
///
/// Creates a new RibbonPanel with the specified text
///
/// Text of the panel
public RibbonPanel(string text)
: this(text, RibbonPanelFlowDirection.Bottom)
{
}
///
/// Creates a new RibbonPanel with the specified text and panel flow direction
///
/// Text of the panel
/// Flow direction of the content items
public RibbonPanel(string text, RibbonPanelFlowDirection flowsTo)
: this(text, flowsTo, new RibbonItem[] { })
{
}
///
/// Creates a new RibbonPanel with the specified text and panel flow direction
///
/// Text of the panel
/// Flow direction of the content items
/// content items
public RibbonPanel(string text, RibbonPanelFlowDirection flowsTo, IEnumerable items)
: this()
{
_text = text;
_flowsTo = flowsTo;
Items.AddRange(items);
}
///
/// RibbonPanel is open in Visual Studio Designer
///
protected bool IsOpenInVisualStudioDesigner()
{
if (!_isopeninvisualstudiodesigner.HasValue)
{
_isopeninvisualstudiodesigner = LicenseManager.UsageMode == LicenseUsageMode.Designtime ||
this.DesignMode;
if (!_isopeninvisualstudiodesigner.Value)
{
try
{
using (var process = System.Diagnostics.Process.GetCurrentProcess())
{
_isopeninvisualstudiodesigner = process.ProcessName.ToLowerInvariant().Contains("devenv");
}
}
catch
{
}
}
}
return _isopeninvisualstudiodesigner.Value;
}
///
/// 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)
{
try
{
foreach (RibbonItem ri in Items)
ri.Dispose();
}
catch (InvalidOperationException)
{
if (!IsOpenInVisualStudioDesigner())
{
throw;
}
}
}
base.Dispose(disposing);
}
#endregion
#region Props
private string _Name = string.Empty;
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public virtual string Name
{
get
{
if (Site != null)
{
_Name = Site.Name;
}
return _Name;
}
set => _Name = value;
}
[DefaultValue(true)]
[Category("Behavior")]
[Description("Sets if the panel should be enabled")]
public bool Enabled
{
get
{
if (OwnerTab != null)
{
return _enabled && OwnerTab.Enabled;
}
return _enabled;
}
set
{
_enabled = value;
Owner.Invalidate();
foreach (RibbonItem item in Items)
{
item.Enabled = value;
}
}
}
[DefaultValue(true)]
[Category("Behavior")]
[Description("Sets if the panel should be Visible")]
public virtual bool Visible
{
get
{
if (Owner != null && !Owner.IsDesignMode() && OwnerTab != null && !OwnerTab.Visible)
return false;
return _visible;
}
set
{
_visible = value;
//this.OwnerTab.UpdatePanelsRegions();
if (Owner != null)
{
Owner.PerformLayout();
Owner.Invalidate();
}
}
}
///
/// Gets if this panel is currenlty collapsed
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Collapsed => SizeMode == RibbonElementSizeMode.Overflow;
///
/// Gets or sets the visibility of the "More" button
///
[Description("Sets the visibility of the \"More...\" button")]
[Category("Appearance")]
[DefaultValue(true)]
public bool ButtonMoreVisible
{
get => _buttonMoreVisible;
set { _buttonMoreVisible = value; if (Owner != null) Owner.OnRegionsChanged(); }
}
///
/// Gets or sets a value indicating if the "More" button should be enabled
///
[Description(@"Enables/Disables the ""More..."" button")]
[Category("Appearance")]
[DefaultValue(true)]
public bool ButtonMoreEnabled
{
get => _buttonMoreEnabled;
set { _buttonMoreEnabled = value; if (Owner != null) Owner.OnRegionsChanged(); }
}
///
/// Gets if the "More" button is currently selected
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool ButtonMoreSelected { get; private set; }
///
/// Gets if the "More" button is currently pressed
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool ButtonMorePressed { get; private set; }
///
/// Gets the bounds of the "More" button
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Rectangle ButtonMoreBounds { get; private set; }
///
/// Gets if the panel is currently on overflow and pressed
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Pressed { get; private set; }
///
/// Gets or sets the pop up where the panel is being drawn (if any)
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal Control PopUp { get; set; }
///
/// Gets the current size mode of the panel
///
[Browsable(false)]
public RibbonElementSizeMode SizeMode { get; private set; }
///
/// Gets the collection of RibbonItem elements of this panel
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public RibbonItemCollection Items { get; }
///
/// Gets or sets the text that is to be displayed on the bottom of the panel
///
[Category("Appearance")]
[Localizable(true)]
public string Text
{
get => _text;
set
{
_text = value;
if (Owner != null) Owner.OnRegionsChanged();
}
}
///
/// Gets or sets the image that is to be displayed on the panel when shown as an overflow button
///
[DefaultValue(null)]
[Category("Appearance")]
public Image Image
{
get => _image;
set
{
_image = value;
if (Owner != null) Owner.OnRegionsChanged();
}
}
///
/// Gets if the panel is in overflow mode
///
/// Overflow mode is when the available space to draw the panel is not enough to draw components, so panel is drawn as a button that shows the full content of the panel in a pop-up window when clicked
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool OverflowMode => SizeMode == RibbonElementSizeMode.Overflow;
///
/// Gets the Ribbon that contains this panel
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Ribbon Owner { get; private set; }
///
/// Gets the bounds of the panel relative to the Ribbon control
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Rectangle Bounds { get; private set; }
///
/// Gets a value indicating whether the panel is selected
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual bool Selected
{
get => _selected;
set => _selected = value;
}
///
/// Gets a value indicating whether the panel is the first panel on the tab
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual bool IsFirstPanel { get; set; } = false;
///
/// Gets a value indicating whether the panel is the last panel on the tab
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual bool IsLastPanel { get; set; } = false;
///
/// Gets a value indicating what the index of the panel is in the Tabs panel collection
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual int Index { get; set; } = -1;
///
/// Gets or sets the object that contains data about the control
///
[Description("An Object field for associating custom data for this control")]
[DefaultValue(null)]
[Category("Data")]
[TypeConverter(typeof(StringConverter))]
public object Tag { get; set; }
///
/// Gets the bounds of the content of the panel
///
[Browsable(false)]
public Rectangle ContentBounds { get; private set; }
///
/// Gets the RibbonTab that contains this panel
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonTab OwnerTab { get; private set; }
///
/// Gets or sets the flow direction to layout items
///
[DefaultValue(RibbonPanelFlowDirection.Bottom)]
[Category("Layout")]
public RibbonPanelFlowDirection FlowsTo
{
get => _flowsTo;
set
{
_flowsTo = value;
if (Owner != null) Owner.OnRegionsChanged();
}
}
///
/// Gets or sets if the popup is currently showing
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal bool PopupShowed { get; set; }
#endregion
#region IRibbonElement Members
public Size SwitchToSize(Control ctl, Graphics g, RibbonElementSizeMode size)
{
Size s = MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, size));
Rectangle r = new Rectangle(0, 0, s.Width, s.Height);
//if (!(ctl is Ribbon))
// r = boundsBuffer;
//else
// r = new Rectangle(0, 0, 0, 0);
SetBounds(r);
UpdateItemsRegions(g, size);
return s;
}
///
/// Raises the paint event and draws the
///
///
///
public virtual void OnPaint(object sender, RibbonElementPaintEventArgs e)
{
if (Paint != null)
{
Paint(this, new PaintEventArgs(e.Graphics, e.Clip));
}
if (PopupShowed && e.Control == Owner)
{
//Draw a fake collapsed and pressed panel
#region Create fake panel
RibbonPanel fakePanel = new RibbonPanel(Text)
{
Image = Image
};
fakePanel.SetOwner(Owner);
fakePanel.SetSizeMode(RibbonElementSizeMode.Overflow);
fakePanel.SetBounds(overflowBoundsBuffer);
fakePanel.SetPressed(true);
#endregion
Owner.Renderer.OnRenderRibbonPanelBackground(new RibbonPanelRenderEventArgs(Owner, e.Graphics, e.Clip, fakePanel, e.Control));
Owner.Renderer.OnRenderRibbonPanelText(new RibbonPanelRenderEventArgs(Owner, e.Graphics, e.Clip, fakePanel, e.Control));
}
else
{
//Draw normal
Owner.Renderer.OnRenderRibbonPanelBackground(new RibbonPanelRenderEventArgs(Owner, e.Graphics, e.Clip, this, e.Control));
Owner.Renderer.OnRenderRibbonPanelText(new RibbonPanelRenderEventArgs(Owner, e.Graphics, e.Clip, this, e.Control));
}
if (e.Mode != RibbonElementSizeMode.Overflow ||
(e.Control != null && e.Control == PopUp))
{
foreach (RibbonItem item in Items)
{
if (item.Visible || Owner.IsDesignMode())
item.OnPaint(this, new RibbonElementPaintEventArgs(item.Bounds, e.Graphics, item.SizeMode));
}
}
}
///
/// Sets the bounds of the panel
///
///
public void SetBounds(Rectangle bounds)
{
bool trigger = Bounds != bounds;
Bounds = bounds;
OnResize(EventArgs.Empty);
if (Owner != null)
{
//Update contentBounds
ContentBounds = Rectangle.FromLTRB(
bounds.X + Owner.PanelMargin.Left + 0,
bounds.Y + Owner.PanelMargin.Top + 0,
bounds.Right - Owner.PanelMargin.Right,
bounds.Bottom - Owner.PanelMargin.Bottom);
}
//"More" bounds
if (ButtonMoreVisible)
{
SetMoreBounds(
Rectangle.FromLTRB(
bounds.Right - Owner.PanelMoreMargin.Right - 15,
bounds.Bottom - Owner.PanelMoreMargin.Bottom - 14,
bounds.Right - Owner.PanelMoreMargin.Right,
bounds.Bottom - Owner.PanelMoreMargin.Bottom)
);
}
else
{
SetMoreBounds(Rectangle.Empty);
}
}
///
/// Measures the size of the panel on the mode specified by the event object
///
///
///
///
public Size MeasureSize(object sender, RibbonElementMeasureSizeEventArgs e)
{
Size result = Size.Empty;
Size minSize = Size.Empty;
if (!Visible && !Owner.IsDesignMode()) return new Size(0, 0);
int panelHeight = OwnerTab.TabContentBounds.Height - Owner.PanelPadding.Vertical;
#region Measure width of minSize
minSize.Width = e.Graphics.MeasureString(Text, Owner.Font).ToSize().Width + Owner.PanelMargin.Horizontal + 1;
if (ButtonMoreVisible)
{
minSize.Width += ButtonMoreBounds.Width + 3;
}
#endregion
if (e.SizeMode == RibbonElementSizeMode.Overflow)
{
Size textSize = RibbonButton.MeasureStringLargeSize(e.Graphics, Text, Owner.Font);
return new Size(textSize.Width + Owner.PanelMargin.Horizontal, panelHeight);
}
switch (FlowsTo)
{
case RibbonPanelFlowDirection.Left:
result = MeasureSizeFlowsToBottom(sender, e);
break;
case RibbonPanelFlowDirection.Right:
result = MeasureSizeFlowsToRight(sender, e);
break;
case RibbonPanelFlowDirection.Bottom:
result = MeasureSizeFlowsToBottom(sender, e);
break;
default:
result = Size.Empty;
break;
}
return new Size(Math.Max(result.Width, minSize.Width), panelHeight);
}
///
/// Sets the value of the Owner Property
///
internal void SetOwner(Ribbon owner)
{
Owner = owner;
Items.SetOwner(owner);
}
///
/// When an item is removed from the RibbonItemCollection remove all its references.
///
internal virtual void ClearOwner()
{
OwnerTab = null;
Owner = null;
}
///
/// Sets the value of the Selected property
///
/// Value that indicates if the element is selected
internal void SetSelected(bool selected)
{
_selected = selected;
}
#endregion
#region Methods
///
/// Raises the method
///
///
protected virtual void OnResize(EventArgs e)
{
if (Resize != null)
{
Resize(this, e);
}
}
///
/// Shows the panel in a popup
///
private void ShowOverflowPopup()
{
Rectangle b = Bounds;
RibbonPanelPopup f = new RibbonPanelPopup(this);
Point p = Owner.PointToScreen(new Point(b.Left, b.Bottom));
PopupShowed = true;
f.Show(p);
}
///
/// Measures the size when flow direction is to right
///
///
///
///
private Size MeasureSizeFlowsToRight(object sender, RibbonElementMeasureSizeEventArgs e)
{
int widthSum = Owner.PanelMargin.Horizontal;
int maxWidth = 0;
int maxHeight = 0;
int dividedWidth = 0;
foreach (RibbonItem item in Items)
{
if (item.Visible || Owner.IsDesignMode())
{
Size itemSize = item.MeasureSize(this, e);
widthSum += itemSize.Width + Owner.ItemPadding.Horizontal + 1;
maxWidth = Math.Max(maxWidth, itemSize.Width);
maxHeight = Math.Max(maxHeight, itemSize.Height);
}
}
switch (e.SizeMode)
{
case RibbonElementSizeMode.Large:
dividedWidth = widthSum / 1; //Show items on one row
break;
case RibbonElementSizeMode.Medium:
dividedWidth = widthSum / 2; //Show items on two rows
break;
case RibbonElementSizeMode.Compact:
dividedWidth = widthSum / 3; //Show items on three rows
break;
default:
break;
}
//Add padding
dividedWidth += Owner.PanelMargin.Horizontal;
return new Size(Math.Max(maxWidth, dividedWidth) + Owner.PanelMargin.Horizontal, 0); //Height is provided by MeasureSize
}
///
/// Measures the size when flow direction is to bottom
///
///
///
///
private Size MeasureSizeFlowsToBottom(object sender, RibbonElementMeasureSizeEventArgs e)
{
int curRight = Owner.PanelMargin.Left + Owner.ItemPadding.Horizontal;
int curBottom = ContentBounds.Top + Owner.ItemPadding.Vertical;
int lastRight = 0;
int lastBottom = 0;
int availableHeight = OwnerTab.TabContentBounds.Height - Owner.TabContentMargin.Vertical - Owner.PanelPadding.Vertical - Owner.PanelMargin.Vertical;
int maxRight = 0;
int maxBottom = 0;
foreach (RibbonItem item in Items)
{
if (item.Visible || Owner.IsDesignMode() || item.GetType() == typeof(RibbonSeparator))
{
Size itemSize = item.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(e.Graphics, e.SizeMode));
if (curBottom + itemSize.Height > ContentBounds.Bottom)
{
curBottom = ContentBounds.Top + Owner.ItemPadding.Vertical + 0;
curRight = maxRight + Owner.ItemPadding.Horizontal + 0;
}
Rectangle bounds = new Rectangle(curRight, curBottom, itemSize.Width, itemSize.Height);
lastRight = bounds.Right;
lastBottom = bounds.Bottom;
curBottom = bounds.Bottom + Owner.ItemPadding.Vertical + 1;
maxRight = Math.Max(maxRight, lastRight);
maxBottom = Math.Max(maxBottom, lastBottom);
}
}
return new Size(maxRight + Owner.ItemPadding.Right + Owner.PanelMargin.Right + 1, 0); //Height is provided by MeasureSize
}
///
/// Sets the value of the SizeMode property
///
///
internal void SetSizeMode(RibbonElementSizeMode sizeMode)
{
SizeMode = sizeMode;
foreach (RibbonItem item in Items)
{
item.SetSizeMode(sizeMode);
}
}
///
/// Sets the value of the ContentBounds property
///
/// Bounds of the content on the panel
internal void SetContentBounds(Rectangle contentBounds)
{
ContentBounds = contentBounds;
}
///
/// Sets the value of the OwnerTab property
///
/// RibbonTab where this item is located
internal void SetOwnerTab(RibbonTab ownerTab)
{
OwnerTab = ownerTab;
Items.SetOwnerTab(OwnerTab);
}
///
/// Updates the bounds of child elements
///
internal void UpdateItemsRegions(Graphics g, RibbonElementSizeMode mode)
{
switch (FlowsTo)
{
case RibbonPanelFlowDirection.Right:
UpdateRegionsFlowsToRight(g, mode);
break;
case RibbonPanelFlowDirection.Bottom:
UpdateRegionsFlowsToBottom(g, mode);
break;
case RibbonPanelFlowDirection.Left:
UpdateRegionsFlowsToLeft(g, mode);
break;
}
//Center items on the panel
CenterItems();
}
///
/// Updates the bounds of child elements when flow is to bottom
///
private void UpdateRegionsFlowsToBottom(Graphics g, RibbonElementSizeMode mode)
{
int curRight = ContentBounds.Left + Owner.ItemPadding.Horizontal + 0;
int curBottom = ContentBounds.Top + Owner.ItemPadding.Vertical + 0;
int lastRight = curRight;
int lastBottom = 0;
List lastColumn = new List();
//Iterate thru items on panel
foreach (RibbonItem item in Items)
{
//Gets the last measured size (to avoid re-measuring calculations)
Size itemSize;
if (item.Visible || Owner.IsDesignMode())
itemSize = item.LastMeasuredSize;
else
itemSize = new Size(0, 0);
//If not enough space available, reset curBottom and advance curRight
if (curBottom + itemSize.Height > ContentBounds.Bottom)
{
curBottom = ContentBounds.Top + Owner.ItemPadding.Vertical + 0;
curRight = lastRight + Owner.ItemPadding.Horizontal + 0;
Items.CenterItemsVerticallyInto(lastColumn, ContentBounds);
lastColumn.Clear();
}
//Set the item's bounds
item.SetBounds(new Rectangle(curRight, curBottom, itemSize.Width, itemSize.Height));
//save last right and bottom
lastRight = Math.Max(item.Bounds.Right, lastRight);
lastBottom = item.Bounds.Bottom;
//update current bottom
curBottom = item.Bounds.Bottom + Owner.ItemPadding.Vertical + 1;
//Add to the collection of items of the last column
lastColumn.Add(item);
}
//Center the items vertically on the last column
Items.CenterItemsVerticallyInto(lastColumn, ContentBounds);
}
///
/// Updates the bounds of child elements when flow is to Left.
///
private void UpdateRegionsFlowsToLeft(Graphics g, RibbonElementSizeMode mode)
{
int curRight = ContentBounds.Left + Owner.ItemPadding.Horizontal + 0;
int curBottom = ContentBounds.Top + Owner.ItemPadding.Vertical + 0;
int lastRight = curRight;
int lastBottom = 0;
List lastColumn = new List();
//Iterate thru items on panel
for (int i = Items.Count - 1; i >= 0; i--)
{
RibbonItem item = Items[i];
//Gets the last measured size (to avoid re-measuring calculations)
Size itemSize;
if (item.Visible)
itemSize = item.LastMeasuredSize;
else
itemSize = new Size(0, 0);
//If not enough space available, reset curBottom and advance curRight
if (curBottom + itemSize.Height > ContentBounds.Bottom)
{
curBottom = ContentBounds.Top + Owner.ItemPadding.Vertical + 0;
curRight = lastRight + Owner.ItemPadding.Horizontal + 0;
Items.CenterItemsVerticallyInto(lastColumn, ContentBounds);
lastColumn.Clear();
}
//Set the item's bounds
item.SetBounds(new Rectangle(curRight, curBottom, itemSize.Width, itemSize.Height));
//save last right and bottom
lastRight = Math.Max(item.Bounds.Right, lastRight);
lastBottom = item.Bounds.Bottom;
//update current bottom
curBottom = item.Bounds.Bottom + Owner.ItemPadding.Vertical + 1;
//Add to the collection of items of the last column
lastColumn.Add(item);
}
//Center the items vertically on the last column
Items.CenterItemsVerticallyInto(lastColumn, Items.GetItemsBounds());
}
///
/// Updates the bounds of child elements when flow is to bottom
///
private void UpdateRegionsFlowsToRight(Graphics g, RibbonElementSizeMode mode)
{
int curLeft = ContentBounds.Left;
int curTop = ContentBounds.Top;
int padding = mode == RibbonElementSizeMode.Medium ? 7 : 0;
int maxBottom = 0;
#region Sorts from larger to smaller
RibbonItem[] array = Items.ToArray();
for (int i = (array.Length - 1); i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
if (array[j - 1].LastMeasuredSize.Width < array[j].LastMeasuredSize.Width)
{
RibbonItem temp = array[j - 1];
array[j - 1] = array[j];
array[j] = temp;
}
}
}
#endregion
List list = new List(array);
//Attend elements, deleting every attended element from the list
while (list.Count > 0)
{
//Extract item and delete it
RibbonItem item = list[0];
list.Remove(item);
//If not enough space left, reset left and advance top
if (curLeft + item.LastMeasuredSize.Width > ContentBounds.Right)
{
curLeft = ContentBounds.Left;
curTop = maxBottom + Owner.ItemPadding.Vertical + 1 + padding;
}
//Set item's bounds
item.SetBounds(new Rectangle(new Point(curLeft, curTop), item.LastMeasuredSize));
//Increment reminders
curLeft += item.Bounds.Width + Owner.ItemPadding.Horizontal;
maxBottom = Math.Max(maxBottom, item.Bounds.Bottom);
//Check available space after placing item
int spaceAvailable = ContentBounds.Right - curLeft;
//Check for elements that fit on available space
for (int i = 0; i < list.Count; i++)
{
//If item fits on the available space
if (list[i].LastMeasuredSize.Width < spaceAvailable)
{
//Place the item there and reset the counter to check for further items
list[i].SetBounds(new Rectangle(new Point(curLeft, curTop), list[i].LastMeasuredSize));
curLeft += list[i].Bounds.Width + Owner.ItemPadding.Horizontal;
maxBottom = Math.Max(maxBottom, list[i].Bounds.Bottom);
spaceAvailable = ContentBounds.Right - curLeft;
list.RemoveAt(i);
i = 0;
}
}
}
}
///
/// Centers the items on the tab conent
///
private void CenterItems()
{
Items.CenterItemsInto(ContentBounds);
}
///
/// Overriden. Gives info about the panel as a string
///
///
public override string ToString()
{
return string.Format("Panel: {0} ({1})", Text, SizeMode);
}
///
/// Sets the value of the Pressed property
///
///
public void SetPressed(bool pressed)
{
Pressed = pressed;
}
///
/// Sets the value of the ButtonMorePressed property
///
/// property value
internal void SetMorePressed(bool pressed)
{
ButtonMorePressed = pressed;
}
///
/// Sets the value of the ButtonMoreSelected property
///
/// property value
internal void SetMoreSelected(bool selected)
{
ButtonMoreSelected = selected;
}
///
/// Sets the value of the ButtonMoreBounds property
///
/// property value
internal void SetMoreBounds(Rectangle bounds)
{
ButtonMoreBounds = bounds;
}
///
/// Raised the event
///
///
protected void OnButtonMoreClick(EventArgs e)
{
if (ButtonMoreClick != null)
{
ButtonMoreClick(this, e);
}
}
#endregion
#region IContainsRibbonItems Members
public IEnumerable GetItems()
{
return Items;
}
public Rectangle GetContentBounds()
{
return ContentBounds;
}
///
/// Raises the MouseEnter event
///
/// Event data
public virtual void OnMouseEnter(MouseEventArgs e)
{
if (!Enabled) return;
if (MouseEnter != null)
{
MouseEnter(this, e);
}
}
///
/// Raises the MouseLeave event
///
/// Event data
public virtual void OnMouseLeave(MouseEventArgs e)
{
if (!Enabled) return;
if (MouseLeave != null)
{
MouseLeave(this, e);
}
}
///
/// Raises the MouseMove event
///
/// Event data
public virtual void OnMouseMove(MouseEventArgs e)
{
if (!Enabled) return;
if (MouseMove != null)
{
MouseMove(this, e);
}
bool redraw = false;
if (ButtonMoreEnabled && ButtonMoreVisible && ButtonMoreBounds.Contains(e.X, e.Y) && !Collapsed)
{
SetMoreSelected(true);
redraw = true;
}
else
{
redraw = ButtonMoreSelected;
SetMoreSelected(false);
}
if (redraw)
{
Owner.Invalidate(Bounds);
}
}
///
/// Raises the Click event
///
/// Event data
public virtual void OnClick(EventArgs e)
{
if (!Enabled) return;
if (Click != null)
{
Click(this, e);
}
if (Collapsed && PopUp == null)
{
ShowOverflowPopup();
}
}
///
/// Raises the DoubleClick event
///
/// Event data
public virtual void OnDoubleClick(EventArgs e)
{
if (!Enabled) return;
if (DoubleClick != null)
{
DoubleClick(this, e);
}
}
///
/// Raises the MouseDown event
///
/// Event data
public virtual void OnMouseDown(MouseEventArgs e)
{
if (!Enabled) return;
if (MouseDown != null)
{
MouseDown(this, e);
}
SetPressed(true);
bool redraw = false;
if (ButtonMoreEnabled && ButtonMoreVisible && ButtonMoreBounds.Contains(e.X, e.Y) && !Collapsed)
{
SetMorePressed(true);
redraw = true;
}
else
{
redraw = ButtonMoreSelected;
SetMorePressed(false);
}
if (redraw)
{
Owner.Invalidate(Bounds);
}
}
///
/// Raises the MouseUp event
///
/// Event data
public virtual void OnMouseUp(MouseEventArgs e)
{
if (!Enabled) return;
if (MouseUp != null)
{
MouseUp(this, e);
}
if (ButtonMoreEnabled && ButtonMoreVisible && ButtonMorePressed && !Collapsed)
{
OnButtonMoreClick(EventArgs.Empty);
}
SetPressed(false);
SetMorePressed(false);
}
#endregion
#region IContainsRibbonComponents Members
public IEnumerable GetAllChildComponents()
{
return Items.ToArray();
}
#endregion
}
}