using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using DevComponents.DotNetBar.Events; using System.Collections; using DevComponents.DotNetBar.Rendering; namespace DevComponents.DotNetBar { /// /// Defines Radial Menu control. /// [ToolboxItem(true), DefaultEvent("ItemClick"), System.Runtime.InteropServices.ComVisible(false), Designer("DevComponents.DotNetBar.Design.RadialMenuDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), ToolboxBitmap(typeof(ToolboxIconResFinder), "RadialMenu.ico")] public class RadialMenu : Control, IMessageHandlerClient, IOwner, IOwnerItemEvents { #region Constructor private RadialMenuContainer _MenuContainer = null; /// /// Initializes a new instance of the RadialMenu class. /// public RadialMenu() { _MenuContainer = new RadialMenuContainer(); _MenuContainer.RadialMenu = this; _MenuContainer.Opened += new EventHandler(RadialMenuOpened); _MenuContainer.Closed += new EventHandler(RadialMenuClosed); this.SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | ControlStyles.ResizeRedraw | DisplayHelp.DoubleBufferFlag | ControlStyles.SupportsTransparentBackColor, true); _MenuContainer.SetOwner(this); } protected override void Dispose(bool disposing) { _MenuContainer.Dispose(); base.Dispose(disposing); } private bool _AccessibleObjectCreated = false; protected override AccessibleObject CreateAccessibilityInstance() { _AccessibleObjectCreated = true; return new RadialMenuAccessibleObject(this); } #endregion #region Events /// /// Occurs before menu is closed and allows you to cancel closing. /// [Description("Occurs before menu is closed and allows you to cancel closing.")] public event CancelableEventSourceHandler BeforeMenuClose; /// /// Raises BeforeMenuClose event. /// /// Provides event arguments. protected virtual void OnBeforeMenuClose(CancelableEventSourceArgs e) { CancelableEventSourceHandler handler = BeforeMenuClose; if (handler != null) handler(this, e); } /// /// Occurs before menu has been opened and allows you to cancel opening /// [Description("Occurs before menu has been opened and allows you to cancel opening.")] public event CancelableEventSourceHandler BeforeMenuOpen; /// /// Raises BeforeMenuOpen event. /// /// Provides event arguments. protected virtual void OnBeforeMenuOpen(CancelableEventSourceArgs e) { CancelableEventSourceHandler handler = BeforeMenuOpen; if (handler != null) handler(this, e); } /// /// Occurs after menu has been opened. /// [Description("Occurs after menu has been opened.")] public event EventHandler MenuOpened; /// /// Raises MenuOpened event. /// /// Provides event arguments. protected virtual void OnMenuOpened(EventArgs e) { EventHandler handler = MenuOpened; if (handler != null) handler(this, e); } /// /// Occurs after menu is closed.Occurs after menu is closed. /// [Description("Occurs after menu is closed.")] public event EventHandler MenuClosed; /// /// Raises MenuClosed event. /// /// Provides event arguments. protected virtual void OnMenuClosed(EventArgs e) { EventHandler handler = MenuClosed; if (handler != null) handler(this, e); } #endregion #region Implementation /// /// Specifies the width of the sub-menu edge around the radial menu. /// [DefaultValue(18), Category("Appearance"), Description("Specifies the width of the sub-menu edge around the radial menu.")] public int SubMenuEdgeWidth { get { return _MenuContainer.SubMenuEdgeWidth; } set { _MenuContainer.SubMenuEdgeWidth = value; } } /// /// Indicates spacing between sub-menu marking edge and the item. /// [DefaultValue(3), Category("Appearance"), Description("Indicates spacing between sub-menu marking edge and the item.")] public int SubMenuEdgeItemSpacing { get { return _MenuContainer.SubMenuEdgeItemSpacing; } set { _MenuContainer.SubMenuEdgeItemSpacing = value; } } /// /// Gets or sets radial menu diameter. Minimum value is 64. /// [DefaultValue(180), Category("Appearance"), Description("Radial menu diameter.")] public int Diameter { get { return _MenuContainer.Diameter; } set { _MenuContainer.Diameter = value; } } /// /// Gets reference to colors used by the radial menu. /// [Category("Appearance"), Description("Gets reference to colors used by the radial menu."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public RadialMenuColorTable Colors { get { return _MenuContainer.Colors; } } /// /// Indicates the size of the back symbol that is displayed on center of radial menu /// [DefaultValue(18), Browsable(false), Description("Indicates the size of the back symbol that is displayed on center of radial menu")] public int BackButtonSymbolSize { get { return _MenuContainer.BackButtonSymbolSize; } set { _MenuContainer.BackButtonSymbolSize = value; } } /// /// Specifies the back button symbol. /// [DefaultValue("\uf060"), Category("Appearance"), Description("Specifies the back button symbol.")] [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] public string BackButtonSymbol { get { return _MenuContainer.BackButtonSymbol; } set { _MenuContainer.BackButtonSymbol = value; } } /// /// Gets or sets the symbol set used to represent the Symbol. /// [Browsable(false), DefaultValue(eSymbolSet.Awesome)] public eSymbolSet BackButtonSymbolSet { get { return _MenuContainer.BackButtonSymbolSet; } set { _MenuContainer.BackButtonSymbolSet = value; } } /// /// Indicates diameter of center button of radial menu. /// [DefaultValue(32), Category("Appearance"), Description("Indicates diameter of center button of radial menu.")] public int CenterButtonDiameter { get { return _MenuContainer.CenterButtonDiameter; } set { _MenuContainer.CenterButtonDiameter = value; } } /// /// Specifies the maximum pie part angle an item will occupy. Maximum is 180, minimum is 1 degree. /// [DefaultValue(90), Category("Appearance"), Description("Specifies the maximum pie part angle an item will occupy. Maximum is 180, minimum is 1 degree.")] public int MaxItemPieAngle { get { return _MenuContainer.MaxItemPieAngle; } set { _MenuContainer.MaxItemPieAngle = value; } } /// /// Indicates maximum radial angle single item in menu can consume. By default this property is set to zero which indicates that /// radial menu is equally divided between visible menu items. /// [DefaultValue(0), Category("Appearance"), Description("Indicates maximum radial angle single item in menu can consume. Max value is 180.")] public int MaxItemRadialAngle { get { return _MenuContainer.MaxItemRadialAngle; } set { _MenuContainer.MaxItemRadialAngle = value; } } /// /// Indicates the position of top-left corner of radial menu when shown in screen coordinates /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Category("Behavior"), Description("Indicates the position of top-left corner of radial menu when shown in screen coordinates")] public Point MenuLocation { get { return _MenuContainer.MenuLocation; } set { _MenuContainer.MenuLocation = value; } } /// /// Gets or sets whether radial menu is open. /// //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] //public bool IsMenuOpen //{ // get // { // return _MenuContainer.Expanded; // } // set // { // if (_MenuContainer.Expanded != value) // _MenuContainer.Expanded = value; // } //} private Image _Image = null; /// /// Indicates image displayed in center of the radial menu. /// [DefaultValue(null), Description("Indicates image displayed in center of the radial menu."), Category("Appearance")] public Image Image { get { return _Image; } set { if (value != _Image) { Image oldValue = _Image; _Image = value; OnImageChanged(oldValue, value); } } } /// /// Called when Image property has changed. /// /// Old property value /// New property value protected virtual void OnImageChanged(Image oldValue, Image newValue) { //OnPropertyChanged(new PropertyChangedEventArgs("Image")); this.Invalidate(); } /// /// Indicates symbol displayed in center of the radial menu. When set, it overrides any Image settings. /// [DefaultValue(""), Description("Indicates image displayed in center of the radial menu. When set, it overrides any Image settings."), Category("Appearance")] [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] public string Symbol { get { return _MenuContainer.Symbol; } set { _MenuContainer.Symbol = value; _SymbolTextSize = Size.Empty; this.Invalidate(); } } /// /// Gets or sets the symbol set used to represent the Symbol. /// [Browsable(false), DefaultValue(eSymbolSet.Awesome)] public eSymbolSet SymbolSet { get { return _MenuContainer.SymbolSet; } set { _MenuContainer.SymbolSet = value; } } /// /// Indicates the size of the symbol in points. /// [DefaultValue(0f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] public float SymbolSize { get { return _MenuContainer.SymbolSize; } set { _MenuContainer.SymbolSize = value; _SymbolTextSize = Size.Empty; this.Invalidate(); } } private bool _IsOpen; /// /// Gets or sets whether radial menu is open. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsOpen { get { return _IsOpen; } set { if (value != _IsOpen) { SetIsOpen(value, eEventSource.Code); } } } /// /// Called when IsOpen property has changed. /// /// Old property value /// New property value protected virtual void OnIsOpenChanged(bool oldValue, bool newValue) { //OnPropertyChanged(new PropertyChangedEventArgs("IsOpen")); } /// /// Sets whether radial menu is open and provides the source of the action. /// /// true to open menu, false to close it. /// Source of the action. public void SetIsOpen(bool isOpen, eEventSource source) { if (isOpen == _IsOpen) return; if (isOpen) { CancelableEventSourceArgs cancel = new CancelableEventSourceArgs(source); OnBeforeMenuOpen(cancel); if (cancel.Cancel) return; } else { CancelableEventSourceArgs cancel = new CancelableEventSourceArgs(source); OnBeforeMenuClose(cancel); if (cancel.Cancel) return; } bool oldValue = _IsOpen; _IsOpen = isOpen; _MenuContainer.Expanded = isOpen; OnIsOpenChanged(oldValue, isOpen); } /// /// Returns collection of items on a bar. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] public SubItemsCollection Items { get { return _MenuContainer.SubItems; } } protected override void OnClick(EventArgs e) { SetIsOpen(!this.IsOpen, eEventSource.Mouse); base.OnClick(e); } private Size _SymbolTextSize = Size.Empty; private bool _Painting = false; protected override void OnPaint(PaintEventArgs e) { if (_Painting) return; // Stops painting when using transparent backgrounds since paint on parent paints this control too _Painting = true; try { RadialMenuColorTable renderTable = RadialMenuContainer.GetColorTable(); RadialMenuColorTable localTable = _MenuContainer.Colors; Color symbolColor = ColorScheme.GetColor(0x2B579A); Color backColor = Color.White; if (!localTable.RadialMenuButtonBorder.IsEmpty) symbolColor = localTable.RadialMenuButtonBorder; else if (renderTable != null && !renderTable.RadialMenuButtonBorder.IsEmpty) symbolColor = renderTable.RadialMenuButtonBorder; if (!localTable.RadialMenuButtonBackground.IsEmpty) backColor = localTable.RadialMenuButtonBackground; else if (renderTable != null && !renderTable.RadialMenuButtonBackground.IsEmpty) backColor = renderTable.RadialMenuButtonBackground; SolidBrush backBrush = new SolidBrush(backColor); Graphics g = e.Graphics; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; g.InterpolationMode = InterpolationMode.HighQualityBicubic; Rectangle r = this.ClientRectangle; r.Inflate(1, 1); if (!this.BackColor.IsEmpty && this.BackColor != Color.Transparent) { using (SolidBrush brush = new SolidBrush(this.BackColor)) g.FillRectangle(brush, r); } else if (this.BackColor == Color.Transparent) PaintParentControlOnBackground(e.Graphics); r = this.ClientRectangle; r.Width--; r.Height--; Rectangle fill = r; fill.Inflate(-1, -1); g.FillEllipse(backBrush, fill); if (_SymbolBorderEnabled) { using (GraphicsPath path = new GraphicsPath()) { path.AddEllipse(r); r.Inflate(-2, -2); path.AddEllipse(r); using (SolidBrush brush = new SolidBrush(symbolColor)) g.FillPath(brush, path); } } if (!string.IsNullOrEmpty(_MenuContainer.SymbolRealized)) { float symbolSize = _MenuContainer.SymbolSize; Font symFont = Symbols.GetFont(symbolSize, _MenuContainer.SymbolSet); if (_SymbolTextSize.IsEmpty) { _SymbolTextSize = TextDrawing.MeasureStringLegacy(g, _MenuContainer.SymbolRealized, Symbols.GetFont(symbolSize, _MenuContainer.SymbolSet), Size.Empty, eTextFormat.Default); int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); _SymbolTextSize.Height -= descent; } TextDrawing.DrawStringLegacy(g, _MenuContainer.SymbolRealized, Symbols.GetFont(symbolSize, _MenuContainer.SymbolSet), symbolColor, new Rectangle(this.ClientRectangle.Width / 2, r.Y + (r.Height - _SymbolTextSize.Height) / 2, 0, 0), eTextFormat.HorizontalCenter); } else if (_Image != null) { r = this.ClientRectangle; ImageHelper.DrawImageCenteredDpiAware(g, _Image, r); } backBrush.Dispose(); backBrush = null; } finally { _Painting = false; } base.OnPaint(e); } private void PaintParentControlOnBackground(Graphics g) { Control parent = this.Parent; if (parent != null) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; g.InterpolationMode = InterpolationMode.HighQualityBicubic; using (Bitmap bmp = new Bitmap(parent.Width, parent.Height, g)) { parent.DrawToBitmap(bmp, parent.ClientRectangle); g.TranslateTransform(-Left, -Top); g.DrawImage(bmp, Point.Empty); g.TranslateTransform(Left, Top); } } } private bool _SymbolBorderEnabled = true; /// /// Indicates whether border, a circle is rendered around the selected symbol which represents radial menu. Default value is true. /// [DefaultValue(true), Category("Appearance"), Description("Indicates whether border, a circle is rendered around the selected symbol which represents radial menu.")] public bool SymbolBorderEnabled { get { return _SymbolBorderEnabled; } set { _SymbolBorderEnabled = value; this.Invalidate();} } protected override Size DefaultSize { get { return new Size(28, 28); } } public override System.Drawing.Size GetPreferredSize(System.Drawing.Size proposedSize) { if (proposedSize.Width <= 0) return new System.Drawing.Size(26, 26); return new System.Drawing.Size(proposedSize.Width, proposedSize.Height); } void RadialMenuClosed(object sender, EventArgs e) { _IsOpen = false; RaiseAccessibilityEvent(AccessibleEvents.SystemMenuPopupEnd); RaiseAccessibilityEvent(AccessibleEvents.SystemMenuEnd); OnMenuClosed(EventArgs.Empty); } private void RadialMenuOpened(object sender, EventArgs e) { RaiseAccessibilityEvent(AccessibleEvents.SystemMenuStart); RaiseAccessibilityEvent(AccessibleEvents.SystemMenuPopupStart); OnMenuOpened(EventArgs.Empty); } private void RaiseAccessibilityEvent(AccessibleEvents e) { if (!_AccessibleObjectCreated) return; RadialMenuAccessibleObject acc = (RadialMenuAccessibleObject)this.AccessibilityObject; acc.GenerateEvent(e); } private bool _ShortcutsEnabled = true; /// /// Gets or sets whether shortcut processing for the items hosted by this control is enabled. Default value is true. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool ShortcutsEnabled { get { return _ShortcutsEnabled; } set { _ShortcutsEnabled = value; } } private bool _CloseMenuOnAppDeactivate = true; /// /// Indicates whether radial menu is closed automatically when app is deactivated. Default value is true, if set to false /// you are responsible for closing the menu. /// [DefaultValue(true), Category("Behavior"), Description("Indicates whether radial menu is closed automatically when app is deactivated"), Browsable(false)] public bool CloseMenuOnAppDeactivate { get { return _CloseMenuOnAppDeactivate; } set { _CloseMenuOnAppDeactivate = value; } } private bool _UseHook = false; /// /// Gets or sets whether hooks are used for internal DotNetBar system functionality. Using hooks is recommended only if DotNetBar is used in hybrid environments like Visual Studio designers or IE. /// [Browsable(false), DefaultValue(false), Category("Behavior"), Description("Gets or sets whether hooks are used for internal DotNetBar system functionality. Using hooks is recommended only if DotNetBar is used in hybrid environments like Visual Studio designers or IE.")] public bool UseHook { get { return _UseHook; } set { _UseHook = value; } } private bool _MenuEventSupport = false; private Hook _Hook = null; private bool _FilterInstalled = false; protected override void OnHandleCreated(EventArgs e) { if (!_FilterInstalled && !this.DesignMode) { MessageHandler.RegisterMessageClient(this); _FilterInstalled = true; } if (!this.GetDesignMode() && !_UseHook) { if (!_MenuEventSupport) MenuEventSupportHook(); } else { if (_Hook == null) { _Hook = new Hook(this); } } UpdateScaleFactor(); base.OnHandleCreated(e); } protected override void OnHandleDestroyed(EventArgs e) { MenuEventSupportUnhook(); base.OnHandleDestroyed(e); if (_FilterInstalled) { MessageHandler.UnregisterMessageClient(this); _FilterInstalled = false; } if (_Hook != null) { _Hook.Dispose(); _Hook = null; } } private void MenuEventSupportUnhook() { if (!_MenuEventSupport) return; _MenuEventSupport = false; Form parentForm = this.FindForm(); if (parentForm == null) return; if (parentForm.IsMdiChild && parentForm.MdiParent != null) parentForm = parentForm.MdiParent; DotNetBarManager.UnRegisterParentMsgHandler(this, parentForm); parentForm.Resize -= new EventHandler(this.ParentResize); parentForm.Deactivate -= new EventHandler(this.ParentDeactivate); } /// /// Indicates the radial menu type. eRadialMenuType.Segment menu type allows for display of image, text and any sub-menu items. /// eRadialMenuType.Circular allows only for display of Symbol or Image and it does not display either text or sub-menu items. /// eRadialMenuType.Circular is designed to be used for single level menus only that don't need text. /// [DefaultValue(eRadialMenuType.Segment), Category("Appearance"), Description("Indicates the radial menu type.")] public eRadialMenuType MenuType { get { return _MenuContainer.MenuType; } set { _MenuContainer.MenuType = value; } } private bool _AutoScale = true; /// /// Indicates whether control automatically scales the items if the parent Form performs scaling due to AutoScale settings. /// [DefaultValue(true), Category("Behavior"), Description("Indicates whether control automatically scales the items if the parent Form performs scaling due to AutoScale settings.")] public bool AutoScale { get { return _AutoScale; } set { _AutoScale = value; UpdateScaleFactor(); } } private void UpdateScaleFactor() { if (!this.IsHandleCreated) return; if (_AutoScale) { using (Graphics g = this.CreateGraphics()) { SizeF factor = new SizeF(g.DpiX / 96, g.DpiY / 96); if (factor.Width != 1f) _MenuContainer.ScaleFactor = factor; } } else _MenuContainer.ScaleFactor = new SizeF(1, 1); } protected override void WndProc(ref Message m) { if (m.Msg == (int)WinApi.WindowsMessages.WM_DPICHANGED) UpdateScaleFactor(); base.WndProc(ref m); } private string _AccessibleHelp = ""; /// /// Indicates accessibility help string /// [DefaultValue(""), Category("Accessibility"), Description("Indicates accessibility help string")] public string AccessibleHelp { get { return _AccessibleHelp; } set { _AccessibleHelp = value; } } #endregion #region IMessageHandlerClient Implementation bool IMessageHandlerClient.IsModal { get { Form form = this.FindForm(); if (form != null) return form.Modal; return false; } } bool IMessageHandlerClient.OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { return OnMouseWheel(hWnd, wParam, lParam); } protected virtual bool OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { return false; } bool IMessageHandlerClient.OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { return OnKeyDown(hWnd, wParam, lParam); } /// /// Returns whether control has any popups registered. /// [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] public bool HasRegisteredPopups { get { return _MenuContainer.Expanded; } } #region OnKeyDown private bool _DesignModeInternal = false; protected bool GetDesignMode() { if (!_DesignModeInternal) return this.DesignMode; return _DesignModeInternal; } [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public void SetDesignMode(bool mode) { _DesignModeInternal = mode; _MenuContainer.SetDesignMode(mode); } protected virtual bool OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { bool designMode = this.GetDesignMode(); int wParamInt = WinApi.ToInt(wParam); if (_MenuContainer.Expanded && wParamInt == 27) // Escape { this.SetIsOpen(false, eEventSource.Keyboard); return true; } if (_MenuContainer.Expanded && _MenuContainer.Popup != null && _MenuContainer.Popup.Handle == hWnd) { Keys key = (Keys)NativeFunctions.MapVirtualKey((uint)wParam, 2); if (key == Keys.None) key = (Keys)wParamInt; _MenuContainer.InternalKeyDown(new KeyEventArgs(key)); return false; } if (!this.IsParentFormActive) return false; if (wParamInt >= 0x70 || ModifierKeys != Keys.None || (WinApi.ToInt(lParam) & 0x1000000000) != 0 || wParamInt == 0x2E || wParamInt == 0x2D) // 2E=VK_DELETE, 2D=VK_INSERT { int i = (int)ModifierKeys | wParamInt; return ProcessShortcut((eShortcut)i) && !designMode; } return false; } #endregion private bool _DispatchShortcuts = false; /// /// Indicates whether shortcuts handled by items are dispatched to the next handler or control. /// [Browsable(false), DefaultValue(false), Category("Behavior"), Description("Indicates whether shortucts handled by items are dispatched to the next handler or control.")] public bool DispatchShortcuts { get { return _DispatchShortcuts; } set { _DispatchShortcuts = value; } } private bool ProcessShortcut(eShortcut key) { if (!_ShortcutsEnabled || !this.Enabled) return false; Form form = this.FindForm(); if (form == null || (form != Form.ActiveForm && form.MdiParent == null || form.MdiParent != null && form.MdiParent.ActiveMdiChild != form) && !form.IsMdiContainer || Form.ActiveForm != null && Form.ActiveForm.Modal && Form.ActiveForm != form) return false; bool eat = BarFunctions.ProcessItemsShortcuts(key, _ShortcutTable); return !_DispatchShortcuts && eat; } protected bool IsParentFormActive { get { // Process only if parent form is active Form form = this.FindForm(); if (form == null) return false; if (form.IsMdiChild) { if (form.MdiParent == null) return false; if (form.MdiParent.ActiveMdiChild != form) return false; } else if (form != Form.ActiveForm) return false; return true; } } private PopupDelayedClose m_DelayClose = null; private PopupDelayedClose GetDelayClose() { if (m_DelayClose == null) m_DelayClose = new PopupDelayedClose(); return m_DelayClose; } [EditorBrowsable(EditorBrowsableState.Never)] public void DesignerNewItemAdded() { this.GetDelayClose().EraseDelayClose(); } private ArrayList _RegisteredPopups = new ArrayList(); protected virtual bool OnSysMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { if (!_IsOpen || this.GetDesignMode() || _MenuContainer.Popup == null) return false; if (!_MenuContainer.Popup.Bounds.Contains(MousePosition)) { SetIsOpen(false, eEventSource.Mouse); } return false; } bool IMessageHandlerClient.OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { return OnSysMouseDown(hWnd, wParam, lParam); } bool IMessageHandlerClient.OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { if (_IsOpen && _MenuContainer.Popup != null && _MenuContainer.Popup.Handle != hWnd) return true; // Eat mouse messages for other windows while popup is open return false; } bool IMessageHandlerClient.OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { return OnSysKeyDown(hWnd, wParam, lParam); } protected virtual bool OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { if (!this.GetDesignMode()) { int wParamInt = WinApi.ToInt(wParam); if (wParamInt == 18 && System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Alt) this.SetIsOpen(false, eEventSource.Keyboard); // Check Shortcuts if (ModifierKeys != Keys.None || wParamInt >= (int)eShortcut.F1 && wParamInt <= (int)eShortcut.F12) { int i = (int)ModifierKeys | wParamInt; if (ProcessShortcut((eShortcut)i)) return true; } } return false; } bool IMessageHandlerClient.OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { return OnSysKeyUp(hWnd, wParam, lParam); } protected virtual bool OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { return false; } private void MenuEventSupportHook() { if (_MenuEventSupport) return; _MenuEventSupport = true; Form parentForm = this.FindForm(); if (parentForm == null) { _MenuEventSupport = false; return; } if (parentForm.IsMdiChild && parentForm.MdiParent != null) parentForm = parentForm.MdiParent; parentForm.Resize += new EventHandler(this.ParentResize); parentForm.Deactivate += new EventHandler(this.ParentDeactivate); DotNetBarManager.RegisterParentMsgHandler(this, parentForm); } private void ParentResize(object sender, EventArgs e) { Form parentForm = this.FindForm(); if (parentForm != null && parentForm.WindowState == FormWindowState.Minimized) ((IOwner)this).OnApplicationDeactivate(); } private void ParentDeactivate(object sender, EventArgs e) { Form parentForm = this.FindForm(); if (parentForm != null && parentForm.WindowState == FormWindowState.Minimized) ((IOwner)this).OnApplicationDeactivate(); } #endregion #region IOwner Members Form IOwner.ParentForm { get { return base.FindForm(); } set { } } /// /// Returns the collection of items with the specified name. /// /// Item name to look for. /// System.Collections.ArrayList IOwner.GetItems(string ItemName) { ArrayList list = new ArrayList(15); BarFunctions.GetSubItemsByName(_MenuContainer, ItemName, list); return list; } /// /// Returns the collection of items with the specified name and type. /// /// Item name to look for. /// Item type to look for. /// System.Collections.ArrayList IOwner.GetItems(string ItemName, Type itemType) { ArrayList list = new ArrayList(15); BarFunctions.GetSubItemsByNameAndType(_MenuContainer, ItemName, list, itemType); return list; } /// /// Returns the collection of items with the specified name and type. /// /// Item name to look for. /// Item type to look for. /// Indicates whether GlobalName property is used for searching. /// System.Collections.ArrayList IOwner.GetItems(string ItemName, Type itemType, bool useGlobalName) { ArrayList list = new ArrayList(15); BarFunctions.GetSubItemsByNameAndType(_MenuContainer, ItemName, list, itemType, useGlobalName); return list; } /// /// Returns the first item that matches specified name. /// /// Item name to look for. /// BaseItem IOwner.GetItem(string ItemName) { BaseItem item = BarFunctions.GetSubItemByName(_MenuContainer, ItemName); if (item != null) return item; return null; } private BaseItem _ExpandedItem = null; void IOwner.SetExpandedItem(BaseItem objItem) { if (objItem != null && (objItem.Parent is RadialMenuContainer || objItem.Parent is RadialMenu)) return; if (_ExpandedItem != null) { if (_ExpandedItem.Expanded) _ExpandedItem.Expanded = false; _ExpandedItem = null; } _ExpandedItem = objItem; } BaseItem IOwner.GetExpandedItem() { return _ExpandedItem; } private BaseItem _FocusItem = null; // Currently we are using this to communicate "focus" when control is in // design mode. This can be used later if we decide to add focus // handling to our BaseItem class. void IOwner.SetFocusItem(BaseItem objFocusItem) { if (_FocusItem != null && _FocusItem != objFocusItem) { _FocusItem.OnLostFocus(); } OnSetFocusItem(objFocusItem); _FocusItem = objFocusItem; if (_FocusItem != null) _FocusItem.OnGotFocus(); } protected virtual void OnSetFocusItem(BaseItem objFocusItem) { } BaseItem IOwner.GetFocusItem() { return _FocusItem; } void IOwner.DesignTimeContextMenu(BaseItem objItem) { } private Hashtable _ShortcutTable = new Hashtable(); void IOwner.RemoveShortcutsFromItem(BaseItem objItem) { ShortcutTableEntry objEntry = null; if (objItem.ShortcutString != "") { foreach (eShortcut key in objItem.Shortcuts) { if (_ShortcutTable.ContainsKey(key)) { objEntry = (ShortcutTableEntry)_ShortcutTable[key]; try { objEntry.Items.Remove(objItem.Id); if (objEntry.Items.Count == 0) _ShortcutTable.Remove(objEntry.Shortcut); } catch (ArgumentException) { } } } } IOwner owner = this as IOwner; foreach (BaseItem objTmp in objItem.SubItems) owner.RemoveShortcutsFromItem(objTmp); } void IOwner.AddShortcutsFromItem(BaseItem objItem) { ShortcutTableEntry objEntry = null; if (objItem.ShortcutString != "") { foreach (eShortcut key in objItem.Shortcuts) { if (_ShortcutTable.ContainsKey(key)) objEntry = (ShortcutTableEntry)_ShortcutTable[objItem.Shortcuts[0]]; else { objEntry = new ShortcutTableEntry(key); _ShortcutTable.Add(objEntry.Shortcut, objEntry); } try { objEntry.Items.Add(objItem.Id, objItem); } catch (ArgumentException) { } } } IOwner owner = this as IOwner; foreach (BaseItem objTmp in objItem.SubItems) owner.AddShortcutsFromItem(objTmp); } ImageList IOwner.Images { get { return null; } set { } } ImageList IOwner.ImagesMedium { get { return null; } set { } } ImageList IOwner.ImagesLarge { get { return null; } set { } } void IOwner.StartItemDrag(BaseItem objItem) { throw new Exception("The method or operation is not implemented."); } BaseItem IOwner.DragItem { get { throw new Exception("The method or operation is not implemented."); } } bool IOwner.DragInProgress { get { throw new Exception("The method or operation is not implemented."); } } private bool _ShowToolTips = true; /// /// Indicates whether items show tooltips. /// [DefaultValue(true), Category("Behavior"), Description("Indicates whether items show tooltips.")] public bool ShowToolTips { get { return _ShowToolTips; } set { _ShowToolTips = value; } } private bool _ShowShortcutKeysInToolTips = false; /// /// Indicates whether item shortcut is displayed in Tooltips. /// [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether item shortcut is displayed in Tooltips.")] public virtual bool ShowShortcutKeysInToolTips { get { return _ShowShortcutKeysInToolTips; } set { _ShowShortcutKeysInToolTips = value; } } private bool _AlwaysDisplayKeyAccelerators = false; /// /// Gets or sets whether accelerator letters on buttons are underlined. Default value is false which indicates that system setting is used /// to determine whether accelerator letters are underlined. Setting this property to true /// will always display accelerator letter underlined. /// [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether accelerator letters for buttons are underlined regardless of current Windows settings.")] public bool AlwaysDisplayKeyAccelerators { get { return _AlwaysDisplayKeyAccelerators; } set { if (_AlwaysDisplayKeyAccelerators != value) { _AlwaysDisplayKeyAccelerators = value; this.Invalidate(); } } } Form IOwner.ActiveMdiChild { get { Form form = base.FindForm(); if (form == null) return null; if (form.IsMdiContainer) { return form.ActiveMdiChild; } return null; } } MdiClient IOwner.GetMdiClient(Form MdiForm) { return BarFunctions.GetMdiClient(MdiForm); } void IOwner.Customize() { throw new Exception("The method or operation is not implemented."); } void IOwner.InvokeResetDefinition(BaseItem item, EventArgs e) { } bool IOwner.ShowResetButton { get { return false; } set { throw new Exception("The method or operation is not implemented."); } } void IOwner.InvokeDefinitionLoaded(object sender, EventArgs e) { } void IOwner.InvokeUserCustomize(object sender, EventArgs e) { } void IOwner.InvokeEndUserCustomize(object sender, EndUserCustomizeEventArgs e) { } void IOwner.OnApplicationActivate() { } void IOwner.OnApplicationDeactivate() { if (this.IsOpen && _CloseMenuOnAppDeactivate) this.IsOpen = false; } void IOwner.OnParentPositionChanging() { if (this.IsOpen) this.IsOpen = false; } bool IOwner.DesignMode { get { return this.DesignMode; } } private bool _DisabledImagesGrayScale = true; /// /// Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images. Default is true. /// [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images.")] public bool DisabledImagesGrayScale { get { return _DisabledImagesGrayScale; } set { _DisabledImagesGrayScale = value; } } #endregion #region IOwnerItemEvents Members /// /// Occurs after an item has been added to items collection. /// [Description("Occurs after an item has been added to items collection.")] public event EventHandler ItemAdded; /// /// Raises ItemAdded event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemAdded(BaseItem source, EventArgs e) { EventHandler handler = ItemAdded; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeItemAdded(BaseItem item, EventArgs e) { OnItemAdded(item, e); } /// /// Occurs after an item has been removed from items collection. /// [Description("Occurs after an item has been removed from items collection.")] public event DevComponents.DotNetBar.ItemControl.ItemRemovedEventHandler ItemRemoved; /// /// Raises ItemRemoved event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemRemoved(BaseItem source, ItemRemovedEventArgs e) { DevComponents.DotNetBar.ItemControl.ItemRemovedEventHandler handler = ItemRemoved; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeItemRemoved(BaseItem item, BaseItem parent, int itemIndex) { OnItemRemoved(item, new ItemRemovedEventArgs(parent, itemIndex)); } /// /// Occurs when mouse pointer enters boundaries of an item. /// [Description("Occurs when mouse pointer enters boundaries of an item.")] public event EventHandler ItemMouseEnter; /// /// Raises ItemMouseEnter event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemMouseEnter(BaseItem source, EventArgs e) { EventHandler handler = ItemMouseEnter; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeMouseEnter(BaseItem item, EventArgs e) { OnItemMouseEnter(item, e); } /// /// Occurs when mouse pointer hovers over an item. /// [Description("Occurs when mouse pointer hovers over an item.")] public event EventHandler ItemMouseHover; /// /// Raises ItemMouseHover event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemMouseHover(BaseItem source, EventArgs e) { EventHandler handler = ItemMouseHover; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeMouseHover(BaseItem item, EventArgs e) { OnItemMouseHover(item, e); } /// /// Occurs when mouse pointer leaves boundaries of an item. /// [Description("Occurs when mouse pointer leaves boundaries of an item.")] public event EventHandler ItemMouseLeave; /// /// Raises ItemMouseLeave event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemMouseLeave(BaseItem source, EventArgs e) { EventHandler handler = ItemMouseLeave; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeMouseLeave(BaseItem item, EventArgs e) { OnItemMouseLeave(item, e); } /// /// Occurs when mouse button is pressed on item. /// [Description("Occurs when mouse button is pressed on item.")] public event MouseEventHandler ItemMouseDown; /// /// Raises ItemMouseDown event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemMouseDown(BaseItem source, MouseEventArgs e) { MouseEventHandler handler = ItemMouseDown; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeMouseDown(BaseItem item, MouseEventArgs e) { OnItemMouseDown(item, e); } /// /// Occurs when mouse button is released on item. /// [Description("Occurs when mouse button is released on item.")] public event MouseEventHandler ItemMouseUp; /// /// Raises ItemMouseUp event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemMouseUp(BaseItem source, MouseEventArgs e) { MouseEventHandler handler = ItemMouseUp; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeMouseUp(BaseItem item, MouseEventArgs e) { OnItemMouseUp(item, e); } /// /// Occurs when mouse moves over an item. /// [Description("Occurs when mouse moves over an item.")] public event MouseEventHandler ItemMouseMove; /// /// Raises ItemMouseMove event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemMouseMove(BaseItem source, MouseEventArgs e) { MouseEventHandler handler = ItemMouseMove; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeMouseMove(BaseItem item, MouseEventArgs e) { OnItemMouseMove(item, e); } /// /// Occurs when an item is clicked. /// [Description("Occurs when an item is clicked.")] public event EventHandler ItemClick; /// /// Raises ItemClick event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemClick(BaseItem source, EventArgs e) { EventHandler handler = ItemClick; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeItemClick(BaseItem objItem) { OnItemClick(objItem, EventArgs.Empty); } /// /// Occurs when an item is double-clicked. /// [Description("Occurs when an item is double-clicked.")] public event MouseEventHandler ItemDoubleClick; /// /// Raises ItemDoubleClick event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemDoubleClick(BaseItem source, MouseEventArgs e) { MouseEventHandler handler = ItemDoubleClick; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeItemDoubleClick(BaseItem objItem, MouseEventArgs e) { OnItemDoubleClick(objItem, e); } void IOwnerItemEvents.InvokeGotFocus(BaseItem item, EventArgs e) { } void IOwnerItemEvents.InvokeLostFocus(BaseItem item, EventArgs e) { } /// /// Occurs when an item Expanded property value has changed. /// [Description("Occurs when an item Expanded property value has changed.")] public event EventHandler ItemExpandedChanged; /// /// Raises ItemExpandedChanged event. /// /// Reference to item. /// Provides event arguments. protected virtual void OnItemExpandedChanged(BaseItem source, EventArgs e) { EventHandler handler = ItemExpandedChanged; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeExpandedChange(BaseItem item, EventArgs e) { OnItemExpandedChanged(item, e); } /// /// Occurs when an item Text property value has changed. /// [Description("Occurs when an item Text property value has changed.")] public event EventHandler ItemTextChanged; /// /// Raises ItemTextChanged event. /// /// Provides event arguments. protected virtual void OnItemTextChanged(BaseItem source, EventArgs e) { EventHandler handler = ItemTextChanged; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeItemTextChanged(BaseItem item, EventArgs e) { OnItemTextChanged(item, e); } void IOwnerItemEvents.InvokeContainerControlDeserialize(BaseItem item, ControlContainerSerializationEventArgs e) { } void IOwnerItemEvents.InvokeContainerControlSerialize(BaseItem item, ControlContainerSerializationEventArgs e) { } void IOwnerItemEvents.InvokeContainerLoadControl(BaseItem item, EventArgs e) { } void IOwnerItemEvents.InvokeOptionGroupChanging(BaseItem item, OptionGroupChangingEventArgs e) { } /// /// Occurs when tooltip for an item is about to be displayed. /// [Description("Occurs when tooltip for an item is about to be displayed.")] public event EventHandler ItemTooltipShowing; /// /// Raises ItemTooltipShowing event. /// /// Provides event arguments. protected virtual void OnItemTooltipShowing(object source, EventArgs e) { EventHandler handler = ItemTooltipShowing; if (handler != null) handler(source, e); } void IOwnerItemEvents.InvokeToolTipShowing(object item, EventArgs e) { OnItemTooltipShowing(item, e); } void IOwnerItemEvents.InvokeCheckedChanged(ButtonItem item, EventArgs e) { } #endregion #region RadialMenuAccessibleObject public class RadialMenuAccessibleObject : System.Windows.Forms.Control.ControlAccessibleObject { RadialMenu _Owner = null; public RadialMenuAccessibleObject(RadialMenu owner) : base(owner) { _Owner = owner; } internal void GenerateEvent(BaseItem sender, System.Windows.Forms.AccessibleEvents e) { int iChild = _Owner.Items.IndexOf(sender); if (iChild >= 0) { if (_Owner != null && !_Owner.IsDisposed) _Owner.AccessibilityNotifyClients(e, iChild); } } internal void GenerateEvent(System.Windows.Forms.AccessibleEvents e) { if (_Owner == null) return; _Owner.AccessibilityNotifyClients(e, -1); } public override AccessibleRole Role { get { if (_Owner != null && !_Owner.IsDisposed) return _Owner.AccessibleRole; return System.Windows.Forms.AccessibleRole.None; } } public override AccessibleObject Parent { get { if (_Owner != null && !_Owner.IsDisposed) return _Owner.Parent.AccessibilityObject; return null; } } public override Rectangle Bounds { get { if (_Owner != null && !_Owner.IsDisposed && _Owner.Parent != null) { return this._Owner.Parent.RectangleToScreen(_Owner.Bounds); } return Rectangle.Empty; } } public override int GetChildCount() { if (_Owner != null && !_Owner.IsDisposed && _Owner.Items != null) return _Owner.Items.Count; return 0; } public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) { if (_Owner != null && !_Owner.IsDisposed && _Owner.Items != null) return _Owner.Items[iIndex].AccessibleObject; return null; } public override AccessibleStates State { get { AccessibleStates state = AccessibleStates.Default; if (_Owner == null || _Owner.IsDisposed) return AccessibleStates.None; if (_Owner.Focused) state = AccessibleStates.Focused; if (_Owner.IsOpen) state = AccessibleStates.Expanded; return state; } } public override string DefaultAction { get { if (!string.IsNullOrEmpty(_Owner.AccessibleDefaultActionDescription)) return _Owner.AccessibleDefaultActionDescription; return "Open"; } } public override string Description { get { if (!string.IsNullOrEmpty(_Owner.AccessibleDescription)) return _Owner.AccessibleDescription; return "Radial Menu"; } } public override void DoDefaultAction() { if (_Owner != null && !_Owner.IsDisposed) _Owner.IsOpen = !_Owner.IsOpen; } public override string Help { get { if (!string.IsNullOrEmpty(_Owner.AccessibleHelp)) return _Owner.AccessibleHelp; return ""; } } public override string Name { get { return _Owner.Name; } set { _Owner.Name = value; } } public override string Value { get { return _Owner.Text; } set { _Owner.Text = value; } } public override string KeyboardShortcut { get { return ""; } } } #endregion } }