a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
549 lines
16 KiB
C#
549 lines
16 KiB
C#
//
|
|
// ToolStripMenuItem.cs
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
// Copyright (c) 2006 Jonathan Pobst
|
|
//
|
|
// Authors:
|
|
// Jonathan Pobst (monkey@jpobst.com)
|
|
//
|
|
|
|
using System;
|
|
using System.Drawing;
|
|
using System.ComponentModel;
|
|
using System.Windows.Forms.Design;
|
|
using System.ComponentModel.Design.Serialization;
|
|
|
|
namespace System.Windows.Forms
|
|
{
|
|
[ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.MenuStrip | ToolStripItemDesignerAvailability.ContextMenuStrip)]
|
|
[DesignerSerializer ("System.Windows.Forms.Design.ToolStripMenuItemCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
|
|
public class ToolStripMenuItem : ToolStripDropDownItem
|
|
{
|
|
private CheckState checked_state;
|
|
private bool check_on_click;
|
|
private bool close_on_mouse_release;
|
|
private string shortcut_display_string;
|
|
private Keys shortcut_keys = Keys.None;
|
|
private bool show_shortcut_keys = true;
|
|
private Form mdi_client_form;
|
|
|
|
#region Public Constructors
|
|
public ToolStripMenuItem ()
|
|
: this (null, null, null, string.Empty)
|
|
{
|
|
}
|
|
|
|
public ToolStripMenuItem (Image image)
|
|
: this (null, image, null, string.Empty)
|
|
{
|
|
}
|
|
|
|
public ToolStripMenuItem (string text)
|
|
: this (text, null, null, string.Empty)
|
|
{
|
|
}
|
|
|
|
public ToolStripMenuItem (string text, Image image)
|
|
: this (text, image, null, string.Empty)
|
|
{
|
|
}
|
|
|
|
public ToolStripMenuItem (string text, Image image, EventHandler onClick)
|
|
: this (text, image, onClick, string.Empty)
|
|
{
|
|
}
|
|
|
|
public ToolStripMenuItem (string text, Image image, params ToolStripItem[] dropDownItems)
|
|
: this (text, image, null, string.Empty)
|
|
{
|
|
if (dropDownItems != null)
|
|
foreach (ToolStripItem tsi in dropDownItems)
|
|
this.DropDownItems.Add (tsi);
|
|
}
|
|
|
|
public ToolStripMenuItem (string text, Image image, EventHandler onClick, Keys shortcutKeys)
|
|
: this (text, image, onClick, string.Empty)
|
|
{
|
|
}
|
|
|
|
public ToolStripMenuItem (string text, Image image, EventHandler onClick, string name)
|
|
: base (text, image, onClick, name)
|
|
{
|
|
base.Overflow = ToolStripItemOverflow.Never;
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
[Bindable (true)]
|
|
[DefaultValue (false)]
|
|
[RefreshProperties (RefreshProperties.All)]
|
|
public bool Checked {
|
|
get {
|
|
switch (this.checked_state) {
|
|
case CheckState.Unchecked:
|
|
default:
|
|
return false;
|
|
case CheckState.Checked:
|
|
case CheckState.Indeterminate:
|
|
return true;
|
|
}
|
|
}
|
|
set {
|
|
CheckState = value ? CheckState.Checked : CheckState.Unchecked;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (false)]
|
|
public bool CheckOnClick {
|
|
get { return this.check_on_click; }
|
|
set {
|
|
if (this.check_on_click != value) {
|
|
this.check_on_click = value;
|
|
OnUIACheckOnClickChangedEvent (EventArgs.Empty);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Bindable (true)]
|
|
[DefaultValue (CheckState.Unchecked)]
|
|
[RefreshProperties (RefreshProperties.All)]
|
|
public CheckState CheckState {
|
|
get { return this.checked_state; }
|
|
set
|
|
{
|
|
if (!Enum.IsDefined (typeof (CheckState), value))
|
|
throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for CheckState", value));
|
|
|
|
if (value == checked_state)
|
|
return;
|
|
|
|
this.checked_state = value;
|
|
this.Invalidate ();
|
|
this.OnCheckedChanged (EventArgs.Empty);
|
|
this.OnCheckStateChanged (EventArgs.Empty);
|
|
}
|
|
}
|
|
|
|
public override bool Enabled {
|
|
get { return base.Enabled; }
|
|
set { base.Enabled = value; }
|
|
}
|
|
|
|
[Browsable (false)]
|
|
public bool IsMdiWindowListEntry {
|
|
get { return this.mdi_client_form != null; }
|
|
}
|
|
|
|
[DefaultValue (ToolStripItemOverflow.Never)]
|
|
public new ToolStripItemOverflow Overflow {
|
|
get { return base.Overflow; }
|
|
set { base.Overflow = value; }
|
|
}
|
|
|
|
[Localizable (true)]
|
|
[DefaultValue (true)]
|
|
public bool ShowShortcutKeys {
|
|
get { return this.show_shortcut_keys; }
|
|
set { this.show_shortcut_keys = value; }
|
|
}
|
|
|
|
[Localizable (true)]
|
|
[DefaultValue (null)]
|
|
public string ShortcutKeyDisplayString {
|
|
get { return this.shortcut_display_string; }
|
|
set { this.shortcut_display_string = value; }
|
|
}
|
|
|
|
[Localizable (true)]
|
|
[DefaultValue (Keys.None)]
|
|
public Keys ShortcutKeys {
|
|
get { return this.shortcut_keys; }
|
|
set {
|
|
if (this.shortcut_keys != value) {
|
|
this.shortcut_keys = value;
|
|
|
|
if (this.Parent != null)
|
|
ToolStripManager.AddToolStripMenuItem (this);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Protected Properties
|
|
protected internal override Padding DefaultMargin {
|
|
get { return new Padding (0); }
|
|
}
|
|
|
|
protected override Padding DefaultPadding {
|
|
get { return new Padding (4, 0, 4, 0); }
|
|
}
|
|
|
|
protected override Size DefaultSize {
|
|
get { return new Size (32, 19); }
|
|
}
|
|
#endregion
|
|
|
|
#region Protected Methods
|
|
[EditorBrowsable (EditorBrowsableState.Advanced)]
|
|
protected override AccessibleObject CreateAccessibilityInstance ()
|
|
{
|
|
return new ToolStripMenuItemAccessibleObject ();
|
|
}
|
|
|
|
protected override ToolStripDropDown CreateDefaultDropDown ()
|
|
{
|
|
ToolStripDropDownMenu tsddm = new ToolStripDropDownMenu ();
|
|
tsddm.OwnerItem = this;
|
|
return tsddm;
|
|
}
|
|
|
|
protected override void Dispose (bool disposing)
|
|
{
|
|
base.Dispose (disposing);
|
|
}
|
|
|
|
protected virtual void OnCheckedChanged (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler)Events [CheckedChangedEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
protected virtual void OnCheckStateChanged (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler)Events [CheckStateChangedEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
protected override void OnClick (EventArgs e)
|
|
{
|
|
if (!this.Enabled)
|
|
return;
|
|
|
|
if (this.HasDropDownItems) {
|
|
base.OnClick (e);
|
|
return;
|
|
}
|
|
|
|
if (this.OwnerItem is ToolStripDropDownItem)
|
|
(this.OwnerItem as ToolStripDropDownItem).OnDropDownItemClicked (new ToolStripItemClickedEventArgs (this));
|
|
|
|
if (this.IsOnDropDown) {
|
|
ToolStrip ts = this.GetTopLevelToolStrip ();
|
|
|
|
if (ts != null)
|
|
ts.Dismiss (ToolStripDropDownCloseReason.ItemClicked);
|
|
}
|
|
|
|
if (this.IsMdiWindowListEntry) {
|
|
this.mdi_client_form.MdiParent.MdiContainer.ActivateChild (this.mdi_client_form);
|
|
return;
|
|
}
|
|
|
|
if (this.check_on_click)
|
|
this.Checked = !this.Checked;
|
|
|
|
base.OnClick (e);
|
|
|
|
if (!this.IsOnDropDown && !this.HasDropDownItems) {
|
|
ToolStrip ts = this.GetTopLevelToolStrip ();
|
|
|
|
if (ts != null)
|
|
ts.Dismiss (ToolStripDropDownCloseReason.ItemClicked);
|
|
}
|
|
}
|
|
|
|
protected override void OnDropDownHide (EventArgs e)
|
|
{
|
|
base.OnDropDownHide (e);
|
|
}
|
|
|
|
protected override void OnDropDownShow (EventArgs e)
|
|
{
|
|
base.OnDropDownShow (e);
|
|
}
|
|
|
|
protected override void OnFontChanged (EventArgs e)
|
|
{
|
|
base.OnFontChanged (e);
|
|
}
|
|
|
|
protected override void OnMouseDown (MouseEventArgs e)
|
|
{
|
|
if (!this.IsOnDropDown && this.HasDropDownItems && this.DropDown.Visible)
|
|
this.close_on_mouse_release = true;
|
|
|
|
if (Enabled && !this.DropDown.Visible)
|
|
this.ShowDropDown ();
|
|
|
|
base.OnMouseDown (e);
|
|
}
|
|
|
|
protected override void OnMouseEnter (EventArgs e)
|
|
{
|
|
if (this.IsOnDropDown && this.HasDropDownItems && Enabled)
|
|
this.ShowDropDown ();
|
|
|
|
base.OnMouseEnter (e);
|
|
}
|
|
|
|
protected override void OnMouseLeave (EventArgs e)
|
|
{
|
|
base.OnMouseLeave (e);
|
|
}
|
|
|
|
protected override void OnMouseUp (MouseEventArgs e)
|
|
{
|
|
if (this.close_on_mouse_release) {
|
|
this.Parent.Dismiss (ToolStripDropDownCloseReason.ItemClicked);
|
|
this.Invalidate ();
|
|
this.close_on_mouse_release = false;
|
|
}
|
|
|
|
if (!this.HasDropDownItems && Enabled)
|
|
base.OnMouseUp (e);
|
|
}
|
|
|
|
protected override void OnOwnerChanged (EventArgs e)
|
|
{
|
|
base.OnOwnerChanged (e);
|
|
}
|
|
|
|
protected override void OnPaint (System.Windows.Forms.PaintEventArgs e)
|
|
{
|
|
base.OnPaint (e);
|
|
|
|
// Can't render without an owner
|
|
if (this.Owner == null)
|
|
return;
|
|
|
|
// If DropDown.ShowImageMargin is false, we don't display the image
|
|
Image draw_image = this.UseImageMargin ? this.Image : null;
|
|
|
|
// Disable this color detection until we do the color detection for ToolStrip *completely*
|
|
// Color font_color = this.ForeColor == SystemColors.ControlText ? SystemColors.MenuText : this.ForeColor;
|
|
Color font_color = ForeColor;
|
|
|
|
if ((this.Selected || this.Pressed) && this.IsOnDropDown && font_color == SystemColors.MenuText)
|
|
font_color = SystemColors.HighlightText;
|
|
|
|
if (!this.Enabled && this.ForeColor == SystemColors.ControlText)
|
|
font_color = SystemColors.GrayText;
|
|
|
|
// Gray stuff out if we're disabled
|
|
draw_image = this.Enabled ? draw_image : ToolStripRenderer.CreateDisabledImage (draw_image);
|
|
|
|
// Draw our background
|
|
this.Owner.Renderer.DrawMenuItemBackground (new ToolStripItemRenderEventArgs (e.Graphics, this));
|
|
|
|
// Figure out where our text and image go
|
|
Rectangle text_layout_rect;
|
|
Rectangle image_layout_rect;
|
|
|
|
this.CalculateTextAndImageRectangles (out text_layout_rect, out image_layout_rect);
|
|
|
|
if (this.IsOnDropDown) {
|
|
if (!this.UseImageMargin) {
|
|
image_layout_rect = Rectangle.Empty;
|
|
text_layout_rect = new Rectangle (8, text_layout_rect.Top, text_layout_rect.Width, text_layout_rect.Height);
|
|
} else {
|
|
text_layout_rect = new Rectangle (35, text_layout_rect.Top, text_layout_rect.Width, text_layout_rect.Height);
|
|
|
|
if (image_layout_rect != Rectangle.Empty)
|
|
image_layout_rect = new Rectangle (new Point (4, 3), base.GetImageSize ());
|
|
}
|
|
|
|
if (this.Checked && this.ShowMargin)
|
|
this.Owner.Renderer.DrawItemCheck (new ToolStripItemImageRenderEventArgs (e.Graphics, this, new Rectangle (2, 1, 19, 19)));
|
|
}
|
|
if (text_layout_rect != Rectangle.Empty)
|
|
this.Owner.Renderer.DrawItemText (new ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign));
|
|
|
|
string key_string = GetShortcutDisplayString ();
|
|
|
|
if (!string.IsNullOrEmpty (key_string) && !this.HasDropDownItems) {
|
|
int offset = 15;
|
|
Size key_string_size = TextRenderer.MeasureText (key_string, this.Font);
|
|
Rectangle key_string_rect = new Rectangle (this.ContentRectangle.Right - key_string_size.Width - offset, text_layout_rect.Top, key_string_size.Width, text_layout_rect.Height);
|
|
this.Owner.Renderer.DrawItemText (new ToolStripItemTextRenderEventArgs (e.Graphics, this, key_string, key_string_rect, font_color, this.Font, this.TextAlign));
|
|
}
|
|
|
|
if (image_layout_rect != Rectangle.Empty)
|
|
this.Owner.Renderer.DrawItemImage (new ToolStripItemImageRenderEventArgs (e.Graphics, this, draw_image, image_layout_rect));
|
|
|
|
if (this.IsOnDropDown && this.HasDropDownItems && this.Parent is ToolStripDropDownMenu)
|
|
this.Owner.Renderer.DrawArrow (new ToolStripArrowRenderEventArgs (e.Graphics, this, new Rectangle (this.Bounds.Width - 17, 2, 10, 20), Color.Black, ArrowDirection.Right));
|
|
|
|
return;
|
|
}
|
|
|
|
protected internal override bool ProcessCmdKey (ref Message m, Keys keyData)
|
|
{
|
|
Control source = Control.FromHandle (m.HWnd);
|
|
Form f = source == null ? null : (Form)source.TopLevelControl;
|
|
|
|
if (this.Enabled && keyData == this.shortcut_keys && GetTopLevelControl () == f) {
|
|
this.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click);
|
|
return true;
|
|
}
|
|
|
|
return base.ProcessCmdKey (ref m, keyData);
|
|
}
|
|
|
|
Control GetTopLevelControl ()
|
|
{
|
|
ToolStripItem item = this;
|
|
while (item.OwnerItem != null)
|
|
item = item.OwnerItem;
|
|
|
|
if (item.Owner == null)
|
|
return null;
|
|
|
|
if (item.Owner is ContextMenuStrip) {
|
|
Control container = ((ContextMenuStrip)item.Owner).container;
|
|
return container == null ? null : container.TopLevelControl;
|
|
}
|
|
|
|
// MainMenuStrip
|
|
return item.Owner.TopLevelControl;
|
|
}
|
|
|
|
protected internal override bool ProcessMnemonic (char charCode)
|
|
{
|
|
if (!this.Selected)
|
|
this.Parent.ChangeSelection (this);
|
|
|
|
if (this.HasDropDownItems) {
|
|
ToolStripManager.SetActiveToolStrip (this.Parent, true);
|
|
this.ShowDropDown ();
|
|
this.DropDown.SelectNextToolStripItem (null, true);
|
|
} else
|
|
this.PerformClick ();
|
|
|
|
return true;
|
|
}
|
|
|
|
protected internal override void SetBounds (Rectangle rect)
|
|
{
|
|
base.SetBounds (rect);
|
|
}
|
|
#endregion
|
|
|
|
#region Public Events
|
|
static object CheckedChangedEvent = new object ();
|
|
static object CheckStateChangedEvent = new object ();
|
|
|
|
public event EventHandler CheckedChanged {
|
|
add { Events.AddHandler (CheckedChangedEvent, value); }
|
|
remove {Events.RemoveHandler (CheckedChangedEvent, value); }
|
|
}
|
|
|
|
public event EventHandler CheckStateChanged {
|
|
add { Events.AddHandler (CheckStateChangedEvent, value); }
|
|
remove {Events.RemoveHandler (CheckStateChangedEvent, value); }
|
|
}
|
|
#endregion
|
|
|
|
#region UIA Framework Events
|
|
static object UIACheckOnClickChangedEvent = new object ();
|
|
|
|
internal event EventHandler UIACheckOnClickChanged {
|
|
add { Events.AddHandler (UIACheckOnClickChangedEvent, value); }
|
|
remove { Events.RemoveHandler (UIACheckOnClickChangedEvent, value); }
|
|
}
|
|
|
|
internal void OnUIACheckOnClickChangedEvent (EventArgs args)
|
|
{
|
|
EventHandler eh
|
|
= (EventHandler) Events [UIACheckOnClickChangedEvent];
|
|
if (eh != null)
|
|
eh (this, args);
|
|
}
|
|
#endregion
|
|
|
|
#region Internal Properties
|
|
internal Form MdiClientForm {
|
|
get { return this.mdi_client_form; }
|
|
set { this.mdi_client_form = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Internal Methods
|
|
internal override Size CalculatePreferredSize (Size constrainingSize)
|
|
{
|
|
Size base_size = base.CalculatePreferredSize (constrainingSize);
|
|
|
|
string key_string = GetShortcutDisplayString ();
|
|
|
|
if (string.IsNullOrEmpty (key_string))
|
|
return base_size;
|
|
|
|
Size text_size = TextRenderer.MeasureText (key_string, this.Font);
|
|
|
|
return new Size (base_size.Width + text_size.Width - 25, base_size.Height);
|
|
}
|
|
|
|
internal string GetShortcutDisplayString ()
|
|
{
|
|
if (this.show_shortcut_keys == false)
|
|
return string.Empty;
|
|
if (this.Parent == null || !(this.Parent is ToolStripDropDownMenu))
|
|
return string.Empty;
|
|
|
|
string key_string = string.Empty;
|
|
|
|
if (!string.IsNullOrEmpty (this.shortcut_display_string))
|
|
key_string = this.shortcut_display_string;
|
|
else if (this.shortcut_keys != Keys.None) {
|
|
KeysConverter kc = new KeysConverter ();
|
|
key_string = kc.ConvertToString (this.shortcut_keys);
|
|
}
|
|
|
|
return key_string;
|
|
}
|
|
|
|
internal void HandleAutoExpansion ()
|
|
{
|
|
if (this.HasDropDownItems) {
|
|
this.ShowDropDown ();
|
|
this.DropDown.SelectNextToolStripItem (null, true);
|
|
}
|
|
}
|
|
|
|
internal override void HandleClick (int mouse_clicks, EventArgs e)
|
|
{
|
|
this.OnClick (e);
|
|
|
|
if (Parent != null)
|
|
Parent.Invalidate ();
|
|
}
|
|
#endregion
|
|
|
|
#region ToolStripMenuItemAccessibleObject
|
|
private class ToolStripMenuItemAccessibleObject : AccessibleObject
|
|
{
|
|
}
|
|
#endregion
|
|
}
|
|
}
|