示例#1
0
        protected MenuCommand InternalTrackPopup(Point screenPosTR, 
                                                 Point screenPosTL, 
                                                 MenuCommandCollection menuCollection, 
                                                 PopupMenu parentMenu, 
                                                 bool selectFirst, 
                                                 MenuControl parentControl, 
                                                 bool popupRight,
                                                 bool popupDown, 
                                                 bool animateIn,
                                                 ref int returnDir)
        {
            // Default the drawing direction
            _direction = Direction.Horizontal;

            // Remember the MenuControl that initiated us
            _parentControl = parentControl;

            // We have a parent popup menu that should be consulted about operation
            _parentMenu = parentMenu;

            // Is this the first time a menu at this level has been animated
            _animateIn = animateIn;

            // Remember any currect menu item collection
            MenuCommandCollection oldCollection = _menuCommands;

            // Use the passed in collection of menu commands
            _menuCommands = menuCollection;

            // Remember screen positions
            _screenPos = screenPosTR;
            _aboveScreenPos = screenPosTR;
            _leftScreenPos = screenPosTL;

            // Remember display directions
            _popupRight = popupRight;
            _popupDown = popupDown;

            MenuCommand ret = InternalTrackPopup(selectFirst);

            // Restore to original collection
            _menuCommands = oldCollection;

            // Remove references no longer required
            _parentControl = null;
            _parentMenu = null;

            // Return the direction key that caused dismissal
            returnDir = _returnDir;

            return ret;
        }
示例#2
0
        protected void OnWM_OPERATE_SUBMENU(ref Message m)
        {
            int popupItem = (int)m.WParam;
            bool selectFirst = (m.LParam != IntPtr.Zero);

            _popupItem = popupItem;
            _childMenu = new PopupMenu();

            DrawCommand dc = _drawCommands[popupItem] as DrawCommand;

            // Find screen coordinate of Top right of item cell
            Win32.POINT screenPosTR;
            screenPosTR.x = dc.DrawRect.Right;
            screenPosTR.y = dc.DrawRect.Top;
            User32.ClientToScreen(this.Handle, ref screenPosTR);

            // Find screen coordinate of top left of item cell
            Win32.POINT screenPosTL;
            screenPosTL.x = dc.DrawRect.Left;
            screenPosTL.y = dc.DrawRect.Top;
            User32.ClientToScreen(this.Handle, ref screenPosTL);

            // Ensure the child has the same properties as ourself
            _childMenu.Style = this.Style;
            _childMenu.Font = this.Font;
            _childMenu.BackColor = this.BackColor;
            _childMenu.TextColor = this.TextColor;
            _childMenu.HighlightTextColor = this.HighlightTextColor;
            _childMenu.HighlightColor = this.HighlightColor;
            _childMenu.Animate = this.Animate;
            _childMenu.AnimateStyle = this.AnimateStyle;
            _childMenu.AnimateTime = this.AnimateTime;

            // Record keyboard direction
            int returnDir = 0;

            // Propogate the remembering of expansion state
            _childMenu.RememberExpansion = _rememberExpansion;

            // Honour the collections request for showing infrequent items
            _childMenu._showInfrequent = dc.MenuCommand.MenuCommands.ShowInfrequent;

            // Propogate the highlight property
            _childMenu.HighlightInfrequent = _highlightInfrequent;

            // Generate event so that caller has chance to modify MenuCommand contents
            dc.MenuCommand.OnPopupStart();

            _returnCommand = _childMenu.InternalTrackPopup(new Point(screenPosTR.x, screenPosTR.y),
                                                           new Point(screenPosTL.x, screenPosTL.y),
                                                           dc.MenuCommand.MenuCommands,
                                                           this,
                                                           selectFirst,
                                                           _parentControl,
                                                           _popupRight,
                                                           _popupDown,
                                                           _animateFirst,
                                                           ref returnDir);

            // Generate event so that caller has chance to modify MenuCommand contents
            dc.MenuCommand.OnPopupEnd();

            _popupItem = -1;;
            _childMenu = null;

            // Subsequent times a submenu is shown we do not want it to animate
            _animateFirst = false;

            if ((_returnCommand != null) || (returnDir != 0))
            {
                // Finish processing messages
                _timer.Stop();
                _exitLoop = true;
                _returnDir = returnDir;
            }
        }
示例#3
0
        public PopupMenu()
        {
            // Create collection objects
            _drawCommands = new ArrayList();
            _menuCommands = new MenuCommandCollection();

            // Default the properties
            _returnDir = 0;
            _extraSize = 0;
            _popupItem = -1;
            _trackItem = -1;
            _childMenu = null;
            _exitLoop = false;
            _popupDown = true;
            _mouseOver = false;
            _excludeTop = true;
            _popupRight = true;
            _parentMenu = null;
            _excludeOffset = 0;
            _parentControl = null;
            _returnCommand = null;
            _controlLBrush = null;
            _controlEBrush = null;
            _controlLLBrush = null;
            _highlightInfrequent = false;
            _showInfrequent = false;
            _style = VisualStyle.IDE;
            _rememberExpansion = true;
            _lastMousePos = new Point(-1,-1);
            _direction = Direction.Horizontal;
            _textFont = SystemInformation.MenuFont;

            // Animation details
            _animateTime = 100;
            _animate = Animate.System;
            _animateStyle = Animation.System;
            _animateFirst = true;
            _animateIn = true;

            // Create and initialise the timer object (but do not start it running!)
            _timer = new Timer();
            _timer.Interval = _selectionDelay;
            _timer.Tick += new EventHandler(OnTimerExpire);

            // Define default colors
            _textColor = SystemColors.MenuText;
            _highlightTextColor = SystemColors.HighlightText;
            DefineHighlightColors(SystemColors.Highlight);
            DefineColors(SystemColors.Control);
        }
示例#4
0
        protected void OnProcessMouseDown(int xPos, int yPos)
        {
            Point pos = new Point(xPos, yPos);

            for(int i=0; i<_drawCommands.Count; i++)
            {
                DrawCommand dc = _drawCommands[i] as DrawCommand;

                // Find the DrawCommand this is over
                if (dc.SelectRect.Contains(pos) && dc.Enabled)
                {
                    // Is an item already selected?
                    if (_selected)
                    {
                        // Is it this item that is already selected?
                        if (_trackItem == i)
                        {
                            // Is a popupMenu showing
                            if (_popupMenu != null)
                            {
                                // Dismiss the submenu
                                _popupMenu.Dismiss();

                                // No reference needed
                                _popupMenu = null;
                            }
                        }
                    }
                    else
                    {
                        // Select the tracked item
                        _selected = true;
                        _drawUpwards = false;

                        // Is there a change in tracking?
                        if (_trackItem != i)
                        {
                            // Modify the display of the two items
                            _trackItem = SwitchTrackingItem(_trackItem, i);
                        }
                        else
                        {
                            // Update display to show as selected
                            DrawCommand(_trackItem, true);
                        }

                        // Is there a submenu to show?
                        if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0))
                            User32.PostMessage(this.Handle, WM_OPERATEMENU, 1, 0);
                    }

                    break;
                }
            }
        }
示例#5
0
        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            // Have we become disabled?
            if (!this.Enabled)
            {
                // Is an item selected?
                if (_selected)
                {
                    // Is a popupMenu showing?
                    if (_popupMenu != null)
                    {
                        // Dismiss the submenu
                        _popupMenu.Dismiss();

                        // No reference needed
                        _popupMenu = null;
                    }

                    // Reset state
                    Deselect();
                    _drawUpwards = false;

                    SimulateReturnFocus();
                }
            }

            // Do not draw any item as being tracked
            RemoveItemTracking();

            // Change in state changes the way items are drawn
            Invalidate();
        }
示例#6
0
        public MenuControl()
        {
            // Set default values
            _trackItem = -1;
            _oldFocus = IntPtr.Zero;
            _minButton = null;
            _popupMenu = null;
            _activeChild = null;
            _closeButton = null;
            _controlLPen = null;
            _mdiContainer = null;
            _restoreButton = null;
            _controlLBrush = null;
            _chevronStartCommand = null;
            _animateFirst = true;
            _exitLoop = false;
            _selected = false;
            _multiLine = false;
            _mouseOver = false;
            _defaultFont = true;
            _manualFocus = false;
            _drawUpwards = false;
            _plainAsBlock = false;
            _clientSubclass = null;
            _ignoreMouseMove = false;
            _deselectReset = true;
            _expandAllTogether = true;
            _rememberExpansion = true;
            _highlightInfrequent = true;
            _dismissTransfer = false;
            _style = VisualStyle.IDE;
            _direction = Direction.Horizontal;
            _menuCommands = new MenuCommandCollection();
            this.Dock = DockStyle.Top;
            this.Cursor = System.Windows.Forms.Cursors.Arrow;

            // Animation details
            _animateTime = 100;
            _animate = Animate.System;
            _animateStyle = Animation.System;

            // Prevent flicker with double buffering and all painting inside WM_PAINT
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);

            // Should not be allowed to select this control
            SetStyle(ControlStyles.Selectable, false);

            // Hookup to collection events
            _menuCommands.Cleared += new CollectionClear(OnCollectionCleared);
            _menuCommands.Inserted += new CollectionChange(OnCollectionInserted);
            _menuCommands.Removed += new CollectionChange(OnCollectionRemoved);

            // Need notification when the MenuFont is changed
            Microsoft.Win32.SystemEvents.UserPreferenceChanged +=
                new UserPreferenceChangedEventHandler(OnPreferenceChanged);

            DefineColors();

            // Set the starting Font
            DefineFont(SystemInformation.MenuFont);

            // Do not allow tab key to select this control
            this.TabStop = false;

            // Default to one line of items
            this.Height = _rowHeight;

            // Add ourself to the application filtering list
            Application.AddMessageFilter(this);
        }
示例#7
0
        internal void OperateSubMenu(DrawCommand dc, bool selectFirst, bool trackRemove)
        {
            if (this.IsDisposed)
                return;

            Rectangle drawRect = dc.DrawRect;

            // Find screen positions for popup menu
            Point screenPos;

            if (_style == VisualStyle.IDE)
            {
                if (_direction == Direction.Horizontal)
                    screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom - _lengthGap - 2));
                else
                    screenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Top + _boxExpandSides - 1));
            }
            else
            {
                if (_direction == Direction.Horizontal)
                    screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom));
                else
                    screenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Top));
            }

            Point aboveScreenPos;

            if (_style == VisualStyle.IDE)
            {
                if (_direction == Direction.Horizontal)
                    aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top + _breadthGap + _lengthGap - 1));
                else
                    aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Bottom + _lengthGap + 1));
            }
            else
            {
                if (_direction == Direction.Horizontal)
                    aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top));
                else
                    aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Bottom));
            }

            int borderGap;

            // Calculate the missing gap in the PopupMenu border
            if (_direction == Direction.Horizontal)
                borderGap = dc.DrawRect.Width - _subMenuBorderAdjust;
            else
                borderGap = dc.DrawRect.Height - _subMenuBorderAdjust;

            _popupMenu = new PopupMenu();

            // Define the correct visual style based on ours
            _popupMenu.Style = this.Style;

            // Key direction when keys cause dismissal
            int returnDir = 0;

            // Command selected by the PopupMenu
            MenuCommand returnCommand = null;

            // Should the PopupMenu tell the collection to remember expansion state
            _popupMenu.RememberExpansion = _rememberExpansion;

            // Propogate our highlight setting
            _popupMenu.HighlightInfrequent = _highlightInfrequent;

            // Might need to define custom colors
            if (!_defaultSelectedBackColor)
                _popupMenu.BackColor = _selectedBackColor;

            if (!_defaultSelectedTextColor)
                _popupMenu.TextColor = _selectedTextColor;

            if (!_defaultHighlightTextColor)
                _popupMenu.HighlightTextColor = _highlightTextColor;

            if (!_defaultHighlightBackColor)
                _popupMenu.HighlightColor = _highlightBackColor;

            if (!_defaultFont)
                _popupMenu.Font = base.Font;

            // Pass on the animation values
            _popupMenu.Animate = _animate;
            _popupMenu.AnimateStyle = _animateStyle;
            _popupMenu.AnimateTime = _animateTime;

            if (dc.Chevron)
            {
                MenuCommandCollection mcc = new MenuCommandCollection();

                bool addCommands = false;

                // Generate a collection of menu commands for those not visible
                foreach(MenuCommand command in _menuCommands)
                {
                    if (!addCommands && (command == _chevronStartCommand))
                        addCommands = true;

                    if (addCommands)
                        mcc.Add(command);
                }

                // Track the popup using provided menu item collection
                returnCommand = _popupMenu.TrackPopup(screenPos,
                                                      aboveScreenPos,
                                                      _direction,
                                                      mcc,
                                                      borderGap,
                                                      selectFirst,
                                                      this,
                                                      _animateFirst,
                                                      ref returnDir);
            }
            else
            {
                // Generate event so that caller has chance to modify MenuCommand contents
                dc.MenuCommand.OnPopupStart();

                // Honour the collections request for showing infrequent items
                _popupMenu.ShowInfrequent = dc.MenuCommand.MenuCommands.ShowInfrequent;

                // Track the popup using provided menu item collection
                returnCommand = _popupMenu.TrackPopup(screenPos,
                                                      aboveScreenPos,
                                                      _direction,
                                                      dc.MenuCommand.MenuCommands,
                                                      borderGap,
                                                      selectFirst,
                                                      this,
                                                      _animateFirst,
                                                      ref returnDir);
            }

            // No more animation till simulation ends
            _animateFirst = false;

            // If we are supposed to expand all items at the same time
            if (_expandAllTogether)
            {
                // Is anything we have shown now in the expanded state
                if (AnythingExpanded(_menuCommands))
                {
                    // Set everything to expanded
                    SetAllCommandsExpansion(_menuCommands, true);
                }
            }

            // Was arrow key not used to dismiss the submenu?
            if (returnDir == 0)
            {
                // The submenu may have eaten the mouse leave event
                _mouseOver = false;

                // Only if the submenu was dismissed at the request of the submenu
                // should the selection mode be cancelled, otherwise keep selection mode
                if (!_dismissTransfer)
                {
                    // This item is no longer selected
                    Deselect();
                    _drawUpwards = false;

                    if (!this.IsDisposed)
                    {
                        // Should we stop tracking this item
                        if (trackRemove)
                        {
                            // Unselect the current item
                            _trackItem = SwitchTrackingItem(_trackItem, -1);
                        }
                        else
                        {
                            if (_trackItem != -1)
                            {
                                // Repaint the item
                                DrawCommand(_trackItem, true);
                            }
                        }
                    }
                }
                else
                {
                    // Do not change _selected status
                    _dismissTransfer = false;
                }
            }

            if (!dc.Chevron)
            {
                // Generate event so that caller has chance to modify MenuCommand contents
                dc.MenuCommand.OnPopupEnd();
            }

            // Spin the message loop so the messages dealing with destroying
            // the PopupMenu window are processed and cause it to disappear from
            // view before events are generated
            Application.DoEvents();

            // Remove unwanted object
            _popupMenu = null;

            // Was arrow key used to dismiss the submenu?
            if (returnDir != 0)
            {
                if (returnDir < 0)
                {
                    // Shift selection left one
                    ProcessMoveLeft(true);
                }
                else
                {
                    // Shift selection right one
                    ProcessMoveRight(true);
                }

                // A WM_MOUSEMOVE is generated when we open up the new submenu for
                // display, ignore this as it causes the selection to move
                _ignoreMouseMove = true;
            }
            else
            {
                // Was a MenuCommand returned?
                if (returnCommand != null)
                {
                    // Remove

                    // Are we simulating having the focus?
                    if (_manualFocus)
                    {
                        // Always return focus to original when a selection is made
                        SimulateReturnFocus();
                    }

                    // Pulse the selected event for the command
                    returnCommand.OnClick(EventArgs.Empty);
                }
            }
        }