using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.Data;
using System.Windows.Forms;
namespace AnticipatingMinds.CommonUIControls{
/// <summary>
/// Represents an Office like Menu item.
/// </summary>
public class RichMenuItem : System.Windows.Forms.MenuItem
{
private static Color backgroundColor;
private static Color stripeColor;
private static Color selectionColor;
private static Color borderColor;
private static Size stripeSize;
private static Brush backgroundBrush;
private static Brush stripeBrush;
private static Brush selectionBrush;
private static Pen separatorPen;
private static Pen borderPen;
private static Pen checkMarkPen;
static RichMenuItem()
{
backgroundColor = SystemColors.Menu;
stripeColor = SystemColors.Control;
selectionColor = Color.FromArgb(198,211,239);
borderColor = SystemColors.Highlight;
backgroundBrush = new SolidBrush(backgroundColor);
stripeBrush = new SolidBrush(stripeColor);
selectionBrush = new SolidBrush(selectionColor);
separatorPen = new Pen(SystemColors.ControlDark,1);
borderPen = new Pen(borderColor);
checkMarkPen = new Pen(Color.Black,1);
stripeSize = new Size(SystemInformation.SmallIconSize.Width,SystemInformation.MenuHeight);
stripeSize.Width += 5;
}
/// <summary>
/// Initializes new instance of the <see cref="RichMenuItem"/> class.
/// </summary>
public RichMenuItem() : base()
{
OwnerDraw = true;
}
/// <summary>
/// Initializes new instance of the <see cref="RichMenuItem"/> class.
/// </summary>
public RichMenuItem(string text,int index) : this()
{
this.Text = text;
this.Index = index;
}
/// <summary>
/// Gets or sets menu image.
/// </summary>
[CategoryAttribute("Appearance")]
[BrowsableAttribute(true)]
public Image MenuIcon
{
get
{
return menuIcon;
}
set
{
menuIcon = value;
}
}
private Image menuIcon;
private string GetShortcutText()
{
string shortcutText = string.Empty;
if (Shortcut != Shortcut.None)
{
int key = (int)Shortcut;
int ch = key & 0xFF;
if (((int)Keys.Control & key) > 0) shortcutText += "Ctrl+";
if (((int)Keys.Shift & key) > 0) shortcutText += "Shift+";
if (((int)Keys.Alt & key) > 0) shortcutText += "Alt+";
if (ch >= (int)Shortcut.F1 && ch <= (int)Shortcut.F12)
shortcutText += "F" + (ch - (int)Shortcut.F1 + 1);
else
{
if ( Shortcut == Shortcut.Del)
{
shortcutText += "Del";
}
else
{
shortcutText += (char)ch;
}
}
}
return shortcutText;
}
/// <summary>
/// Determines mesurements of the menu items.
/// </summary>
/// <param name="e">A <see cref="MeasureItemEventArgs"/> that contains the event data. </param>
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem(e);
//Is it a separator?
if(Text == "-")
{
e.ItemHeight = 3;
e.ItemWidth = 1; //Does not matter
return;
}
//menu Item size is:
//Image + Text + ShortCut + Glyph
//Get Shortcut text
string shortcutText = GetShortcutText();;
int textwidth = (int)(e.Graphics.MeasureString(Text + shortcutText, SystemInformation.MenuFont).Width);
e.ItemHeight = SystemInformation.MenuHeight;
e.ItemWidth = stripeSize.Width + 5 + textwidth;
}
/// <summary>
/// Draws menu item.
/// </summary>
/// <param name="e">A <see cref="DrawItemEventArgs"/> that contains the event data. </param>
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem (e);
DrawBackground(e.Graphics,e.Bounds,e.State);
//If separator - than draw line and exit.
if((Text == "-"))
{
DrawSeparator(e.Graphics,e.Bounds);
return;
}
DrawIcon(e.Graphics,e.Bounds,e.State);
DrawMenuText(e.Graphics,e.Bounds,e.State);
return;
}
private void DrawIcon(Graphics g, Rectangle bounds, DrawItemState state)
{
if(Checked)
{
Rectangle checkMarkBounds = new Rectangle(bounds.Location,stripeSize);
checkMarkBounds.Offset(1,1);
checkMarkBounds.Width-=4;
checkMarkBounds.Height-=3;
g.FillRectangle(selectionBrush,checkMarkBounds);
g.DrawRectangle(borderPen,checkMarkBounds);
if(RadioCheck)
{
checkMarkBounds.Inflate(-5,-5);
g.FillEllipse(Brushes.Black,checkMarkBounds);
}
else
{
int centerX = checkMarkBounds.X + checkMarkBounds.Width/2;
int centerY = checkMarkBounds.Y + checkMarkBounds.Height/2 +3;
g.DrawLines(checkMarkPen,new Point[] {new Point(centerX-2,centerY-3),new Point(centerX,centerY),new Point(centerX+3,centerY-7)});
}
}
if(MenuIcon == null)
return;
Point iconStartPoint = new Point();
iconStartPoint.X = bounds.Left + (stripeSize.Width - MenuIcon.Size.Width)/2;
iconStartPoint.Y = bounds.Top + (bounds.Height - MenuIcon.Size.Height)/2;
//If item is disabled - just draw disabled image and leave.
if((state & DrawItemState.Disabled) != 0)
{
ControlPaint.DrawImageDisabled(g, MenuIcon, iconStartPoint.X + 1, iconStartPoint.Y, backgroundColor);
return;
}
//If Item is selected move icon a little bit
//just like VS.NET does
if((state & DrawItemState.Selected) != 0)
{
ControlPaint.DrawImageDisabled(g, MenuIcon, iconStartPoint.X + 1, iconStartPoint.Y, Color.Black);
g.DrawImage(MenuIcon, iconStartPoint.X, iconStartPoint.Y-1);
}
else
{
g.DrawImage(MenuIcon, iconStartPoint.X + 1, iconStartPoint.Y);
}
}
private void DrawSeparator(Graphics g, Rectangle bounds)
{
Point ptStart = new Point(bounds.X + stripeSize.Width + 7,bounds.Y + bounds.Height/2);
Point ptEnd = new Point(bounds.Width,ptStart.Y);
g.DrawLine(separatorPen, ptStart,ptEnd);
}
private void DrawBackground(Graphics g, Rectangle bounds, DrawItemState state)
{
g.FillRectangle(backgroundBrush, bounds);
g.FillRectangle(stripeBrush, bounds.X,bounds.Y,stripeSize.Width,stripeSize.Height);
if(((state & DrawItemState.Selected) != 0 || (state & DrawItemState.HotLight) != 0) && (state & DrawItemState.Disabled) == 0)
{
Rectangle border = new Rectangle(bounds.Location,bounds.Size);
border.Width -= 1;
g.FillRectangle(selectionBrush, bounds);
border.Height -= 1;
g.DrawRectangle(borderPen,border);
}
}
private void DrawMenuText(Graphics g, Rectangle bounds, DrawItemState state )
{
StringFormat stringformat = new StringFormat();
stringformat.HotkeyPrefix = ((state & DrawItemState.NoAccelerator) > 0) ? HotkeyPrefix.Hide : HotkeyPrefix.Show;
int textwidth = (int)(g.MeasureString(Text, SystemInformation.MenuFont).Width);
int x = bounds.Left + stripeSize.Width + 5;
int topGap = 4;
int y = bounds.Top + topGap;
Brush brush = null;
if ((state & DrawItemState.Disabled) != 0)
brush = new SolidBrush(SystemColors.GrayText);
else
brush = new SolidBrush(SystemColors.MenuText);
g.DrawString(Text, SystemInformation.MenuFont, brush, x, y, stringformat);
stringformat.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
g.DrawString(GetShortcutText(), SystemInformation.MenuFont, brush, bounds.Width - 10 , bounds.Top + topGap, stringformat);
}
}
}
|