// *********************************
// 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.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms.VisualStyles;
namespace System.Windows.Forms
{
public class RibbonCheckBox
: RibbonItem
{
public enum CheckBoxOrientationEnum
{
Left = 0,
Right = 1
}
public enum CheckBoxStyle
{
CheckBox,
RadioButton
}
#region Fields
private const int spacing = 3;
private Rectangle _labelBounds;
private Rectangle _checkboxBounds;
private int _labelWidth;
private int _checkboxSize;
private CheckBoxOrientationEnum _checkBoxOrientation;
private CheckBoxStyle _style;
#endregion
#region Events
///
/// Raised when the property value has changed
///
public event EventHandler CheckBoxCheckChanged;
///
/// Raised when the property value is changing
///
public event CancelEventHandler CheckBoxCheckChanging;
#endregion
#region Ctor
public RibbonCheckBox()
{
_checkboxSize = 16;
}
#endregion
#region Props
///
/// Gets or sets the style of the checkbox item
///
[DefaultValue(CheckBoxStyle.CheckBox)]
[Category("Appearance")]
public CheckBoxStyle Style
{
get => _style;
set { _style = value; NotifyOwnerRegionsChanged(); }
}
///
/// Gets or sets the width of the Label
///
[DefaultValue(CheckBoxOrientationEnum.Left)]
[Category("Appearance")]
public CheckBoxOrientationEnum CheckBoxOrientation
{
get => _checkBoxOrientation;
set { _checkBoxOrientation = value; NotifyOwnerRegionsChanged(); }
}
///
/// Gets the bounds of the label that is shown next to the textbox
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Rectangle LabelBounds => _labelBounds;
///
/// Gets a value indicating if the label is currently visible
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool LabelVisible { get; private set; } = true;
///
/// Gets the bounds of the text
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Rectangle CheckBoxBounds => _checkboxBounds;
///
/// Gets or sets the width of the Label
///
[DefaultValue(0)]
[Category("Appearance")]
public int LabelWidth
{
get => _labelWidth;
set { _labelWidth = value; NotifyOwnerRegionsChanged(); }
}
///
/// Gets or sets if a click on the text changes the checked state.
///
[Description("Click on text changes the checked state.")]
[Category("Behavior")]
[DefaultValue(true)]
public bool TextClickable { get; set; } = true;
#endregion
#region Methods
///
/// Measures the suposed height of the boxbox
///
///
protected virtual int MeasureHeight()
{
return _checkboxSize + Owner.ItemMargin.Vertical;
}
public override void OnPaint(object sender, RibbonElementPaintEventArgs e)
{
if (Owner != null)
{
Owner.Renderer.OnRenderRibbonItem(new RibbonItemRenderEventArgs(Owner, e.Graphics, Bounds, this));
if (Style == CheckBoxStyle.CheckBox)
{
CheckBoxState CheckState = Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
if (Selected)
CheckState += 1;
if (CheckBoxOrientation == CheckBoxOrientationEnum.Left)
CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(_checkboxBounds.Left, _checkboxBounds.Top), CheckState);
else
CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(_checkboxBounds.Left + spacing, _checkboxBounds.Top), CheckState);
}
else
{
RadioButtonState RadioState = Checked ? RadioButtonState.CheckedNormal : RadioButtonState.UncheckedNormal;
if (Selected)
RadioState += 1;
if (CheckBoxOrientation == CheckBoxOrientationEnum.Left)
RadioButtonRenderer.DrawRadioButton(e.Graphics, new Point(_checkboxBounds.Left, _checkboxBounds.Top), RadioState);
else
RadioButtonRenderer.DrawRadioButton(e.Graphics, new Point(_checkboxBounds.Left + spacing, _checkboxBounds.Top), RadioState);
}
if (LabelVisible)
{
StringFormat f = new StringFormat();
if (_checkBoxOrientation == CheckBoxOrientationEnum.Left)
f.Alignment = StringAlignment.Near;
else
f.Alignment = StringAlignment.Far;
f.LineAlignment = StringAlignment.Far; //Top
f.Trimming = StringTrimming.None;
f.FormatFlags |= StringFormatFlags.NoWrap;
Owner.Renderer.OnRenderRibbonItemText(new RibbonTextEventArgs(Owner, e.Graphics, _labelBounds, this, LabelBounds, Text, f));
}
}
}
public override void SetBounds(Rectangle bounds)
{
base.SetBounds(bounds);
if (CheckBoxOrientation == CheckBoxOrientationEnum.Left)
{
_checkboxBounds = new Rectangle(
bounds.Left + Owner.ItemMargin.Left,
bounds.Top + Owner.ItemMargin.Top + ((bounds.Height - _checkboxSize) / 2),
_checkboxSize,
_checkboxSize);
int itemImageToTextSpacing = (SizeMode == RibbonElementSizeMode.DropDown) ? Owner.ItemImageToTextSpacing : 0;
_labelBounds = Rectangle.FromLTRB(
_checkboxBounds.Right + itemImageToTextSpacing,
bounds.Top + Owner.ItemMargin.Top,
bounds.Right - Owner.ItemMargin.Right,
bounds.Bottom - Owner.ItemMargin.Bottom);
}
else
{
_checkboxBounds = new Rectangle(
bounds.Right - Owner.ItemMargin.Right - _checkboxSize,
bounds.Top + Owner.ItemMargin.Top + ((bounds.Height - _checkboxSize) / 2),
_checkboxSize,
_checkboxSize);
_labelBounds = Rectangle.FromLTRB(
bounds.Left + Owner.ItemMargin.Left,
bounds.Top + Owner.ItemMargin.Top,
_checkboxBounds.Left,
bounds.Bottom - Owner.ItemMargin.Bottom);
}
if (SizeMode == RibbonElementSizeMode.Large)
{
LabelVisible = true;
}
else if (SizeMode == RibbonElementSizeMode.Medium)
{
LabelVisible = true;
_labelBounds = Rectangle.Empty;
}
else if (SizeMode == RibbonElementSizeMode.Compact)
{
_labelBounds = Rectangle.Empty;
LabelVisible = false;
}
}
private bool checkedGlyphSize;
public override Size MeasureSize(object sender, RibbonElementMeasureSizeEventArgs e)
{
if (!checkedGlyphSize)
{
try
{
if (Style == CheckBoxStyle.CheckBox)
_checkboxSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal).Height + spacing;
else
_checkboxSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal).Height + spacing;
}
catch { /* I don't mind at all */ }
checkedGlyphSize = true;
}
if (!Visible && !Owner.IsDesignMode())
{
SetLastMeasuredSize(new Size(0, 0));
return LastMeasuredSize;
}
Size size = Size.Empty;
int w = Owner.ItemMargin.Horizontal;
int iwidth = Image != null ? Image.Width + spacing : 0;
int lwidth = string.IsNullOrEmpty(Text) ? 0 : _labelWidth > 0 ? _labelWidth : e.Graphics.MeasureString(Text, Owner.Font).ToSize().Width;
w += _checkboxSize;
switch (e.SizeMode)
{
case RibbonElementSizeMode.DropDown:
w += iwidth + lwidth + Owner.ItemImageToTextSpacing;
break;
case RibbonElementSizeMode.Large:
w += iwidth + lwidth;
break;
case RibbonElementSizeMode.Medium:
w += iwidth;
break;
}
SetLastMeasuredSize(new Size(w, MeasureHeight()));
return LastMeasuredSize;
}
public override void OnMouseEnter(MouseEventArgs e)
{
if (!Enabled) return;
base.OnMouseEnter(e);
//Canvas.Cursor = Cursors.Default;
//SetSelected(true);
}
public override void OnMouseLeave(MouseEventArgs e)
{
if (!Enabled) return;
base.OnMouseLeave(e);
Canvas.Cursor = Cursors.Default;
//SetSelected(false);
}
public override void OnMouseDown(MouseEventArgs e)
{
if (!Enabled) return;
base.OnMouseDown(e);
Rectangle clickableBounds = TextClickable ? Bounds : CheckBoxBounds;
if (clickableBounds.Contains(e.X, e.Y))
{
CancelEventArgs cev = new CancelEventArgs();
OnCheckChanging(cev);
if (!cev.Cancel)
{
Checked = !Checked;
OnCheckChanged(e);
}
}
}
public override void OnMouseMove(MouseEventArgs e)
{
if (!Enabled) return;
base.OnMouseMove(e);
Rectangle clickableBounds = TextClickable ? Bounds : CheckBoxBounds;
if (clickableBounds.Contains(e.X, e.Y))
{
Debug.WriteLine("Owner.Cursor = Cursors.Hand e.X=" + e.X + " e.Y=" + e.Y + " CheckBoxBounds (" + CheckBoxBounds + ")");
Canvas.Cursor = Cursors.Hand;
if (!Selected)
SetSelected(true);
}
else
{
Debug.WriteLine("Owner.Cursor = Cursors.Default e.X=" + e.X + " e.Y=" + e.Y + " CheckBoxBounds (" + CheckBoxBounds + ")");
Canvas.Cursor = Cursors.Default;
if (Selected)
SetSelected(false);
}
}
///
/// Raises the event
///
///
public void OnCheckChanged(EventArgs e)
{
if (!Enabled) return;
NotifyOwnerRegionsChanged();
if (CheckBoxCheckChanged != null)
{
CheckBoxCheckChanged(this, e);
}
}
///
/// Raises the event
///
///
public void OnCheckChanging(CancelEventArgs e)
{
if (!Enabled) return;
if (CheckBoxCheckChanging != null)
{
CheckBoxCheckChanging(this, e);
}
}
#endregion
}
}