public MenuCommand Add(MenuCommand value)
        {
            // Use base class to process actual collection operation
            base.List.Add(value as object);

            return value;
        }
Example #2
0
 public DrawCommand(Rectangle drawRect, bool expansion)
 {
     _row = -1;
     _col = -1;
     _mnemonic = '0';
     _enabled = true;
     _subMenu = false;
     _expansion = expansion;
     _separator = !expansion;
     _vertSeparator = !expansion;
     _topBorder = false;
     _bottomBorder = false;
     _infrequent = false;
     _chevron = false;
     _drawRect = drawRect;
     _selectRect = drawRect;
     _command = null;
 }
Example #3
0
        protected MenuCommand InternalTrackPopup(bool selectFirst)
        {
            // MenuCommand to return as method result
            _returnCommand = null;

            // No item is being tracked
            _trackItem = -1;

            // Flag to indicate when to exit the message loop
            _exitLoop = false;

            // Assume the mouse does not start over our window
            _mouseOver = false;

            // Direction of key press if this caused dismissal
            _returnDir = 0;

            // Flag to indicate if the message should be dispatched
            bool leaveMsg = false;

            // First time a submenu is shown we pass in our value
            _animateFirst = true;

            // Create and show the popup window (without taking the focus)
            CreateAndShowWindow();

            // Create an object for storing windows message information
            Win32.MSG msg = new Win32.MSG();

            // Pretend user pressed key down to get the first valid item selected
            if (selectFirst)
                ProcessKeyDown();

            // Always use the arrow cursor
            User32.SetCursor(User32.LoadCursor(IntPtr.Zero, (uint)Win32.Cursors.IDC_ARROW));

            // Must hide caret so user thinks focus has changed
            bool hideCaret = User32.HideCaret(IntPtr.Zero);

            // Process messages until exit condition recognised
            while(!_exitLoop)
            {
                // Suspend thread until a windows message has arrived
                if (User32.WaitMessage())
                {
                    // Take a peek at the message details without removing from queue
                    while(!_exitLoop && User32.PeekMessage(ref msg, 0, 0, 0, (int)Win32.PeekMessageFlags.PM_NOREMOVE))
                    {
            //						Console.WriteLine("Track {0} {1}", this.Handle, ((Win32.Msgs)msg.message).ToString());

                        bool eatMessage = false;

                        int localWidth = _currentSize.Width - _position[(int)_style, (int)PI.ShadowWidth];
                        int localHeight = _currentSize.Height - _position[(int)_style, (int)PI.ShadowHeight];

                        // Mouse was pressed in a window of this application
                        if ((msg.message == (int)Win32.Msgs.WM_LBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_MBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_RBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_XBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCLBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCMBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCRBUTTONUP) ||
                            (msg.message == (int)Win32.Msgs.WM_NCXBUTTONUP))
                        {
                            Win32.POINT screenPos = MousePositionToScreen(msg);

                            // Is the POINT inside the Popup window rectangle
                            if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) &&
                                (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight)))
                            {
                                OnWM_YBUTTONUP(screenPos.x, screenPos.y);

                                // Eat the message to prevent the intended destination getting it
                                eatMessage = true;
                            }
                            else
                            {
                                PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg);

                                // Let the parent chain of PopupMenu's decide if they want it
                                if (target != null)
                                {
                                    target.OnWM_YBUTTONUP(screenPos.x, screenPos.y);

                                    // Eat the message to prevent the intended destination getting it
                                    eatMessage = true;
                                }
                            }
                        }

                        // Mouse was pressed in a window of this application
                        if ((msg.message == (int)Win32.Msgs.WM_LBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_MBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_RBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_XBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCLBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCMBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCRBUTTONDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_NCXBUTTONDOWN))
                        {
                            Win32.POINT screenPos = MousePositionToScreen(msg);

                            // Is the POINT inside the Popup window rectangle
                            if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) &&
                                (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight)))
                            {
                                // Eat the message to prevent the intended destination getting it
                                eatMessage = true;
                            }
                            else
                            {
                                // Let the parent chain of PopupMenu's decide if they want it
                                if (ParentPopupMenuWantsMouseMessage(screenPos, ref msg) == null)
                                {
                                    if (ParentControlWantsMouseMessage(screenPos, ref msg))
                                    {
                                        // Let the MenuControl do its business
                                        _parentControl.OnWM_MOUSEDOWN(screenPos);

                                        // Eat the message to prevent the intended destination getting it
                                        eatMessage = true;
                                    }
                                    else
                                    {
                                        // No, then we need to exit the popup menu tracking
                                        _exitLoop = true;

                                        // DO NOT process the message, leave it on the queue
                                        // and let the real destination window handle it.
                                        leaveMsg = true;

                                        // Is a parent control specified?
                                        if (_parentControl != null)
                                        {
                                            // Is the mouse event destination the parent control?
                                            if (msg.hwnd == _parentControl.Handle)
                                            {
                                                // Then we want to consume the message so it does not get processed
                                                // by the parent control. Otherwise, pressing down will cause this
                                                // popup to disappear but the message will then get processed by
                                                // the parent and cause a popup to reappear again. When we actually
                                                // want the popup to disappear and nothing more.
                                                leaveMsg = false;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // Eat the message to prevent the intended destination getting it
                                    eatMessage = true;
                                }
                            }
                        }

                        // Mouse move occured
                        if (msg.message == (int)Win32.Msgs.WM_MOUSEMOVE)
                        {
                            Win32.POINT screenPos = MousePositionToScreen(msg);

                            // Is the POINT inside the Popup window rectangle
                            if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) &&
                                (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight)))
                            {
                                OnWM_MOUSEMOVE(screenPos.x, screenPos.y);
                            }
                            else
                            {
                                // Do we still think the mouse is over our window?
                                if (_mouseOver)
                                {
                                    // Process mouse leaving situation
                                    OnWM_MOUSELEAVE();
                                }

                                // Let the parent chain of PopupMenu's decide if they want it
                                PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg);

                                if (target != null)
                                {
                                    // Let parent target process the message
                                    target.OnWM_MOUSEMOVE(screenPos.x, screenPos.y);
                                }
                                else
                                {
                                    if (ParentControlWantsMouseMessage(screenPos, ref msg))
                                    {
                                        // Let the MenuControl do its business
                                        _parentControl.OnWM_MOUSEMOVE(screenPos);
                                    }
                                }
                            }

                            // Eat the message to prevent the intended destination getting it
                            eatMessage = true;
                        }

                        if (msg.message == (int)Win32.Msgs.WM_SETCURSOR)
                        {
                            OnWM_SETCURSOR();

                            // Eat the message to prevent the intended destination getting it
                            eatMessage = true;
                        }

                        // Was the alt key pressed?
                        if (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN)
                        {
                            // Alt key pressed on its own
                            if((int)msg.wParam == (int)Win32.VirtualKeys.VK_MENU)	// ALT key
                            {
                                // Then we should dimiss ourself
                                _exitLoop = true;
                            }
                            else
                            {
                                // Pretend it is a normal keypress for processing
                                msg.message = (int)Win32.Msgs.WM_KEYDOWN;
                            }
                        }

                        // Was a non-alt key pressed?
                        if (msg.message == (int)Win32.Msgs.WM_KEYDOWN)
                        {
                            switch((int)msg.wParam)
                            {
                                case (int)Win32.VirtualKeys.VK_UP:
                                    ProcessKeyUp();
                                    break;
                                case (int)Win32.VirtualKeys.VK_DOWN:
                                    ProcessKeyDown();
                                    break;
                                case (int)Win32.VirtualKeys.VK_LEFT:
                                    ProcessKeyLeft();
                                    break;
                                case (int)Win32.VirtualKeys.VK_RIGHT:
                                    if(ProcessKeyRight())
                                    {
                                        // Do not attempt to pull a message off the queue as the
                                        // ProcessKeyRight has eaten the message for us
                                        leaveMsg = true;
                                    }
                                    break;
                                case (int)Win32.VirtualKeys.VK_RETURN:
                                    // Is an item currently selected
                                    if (_trackItem != -1)
                                    {
                                        DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

                                        // Does this item have a submenu?
                                        if (dc.SubMenu)
                                        {
                                            // Handle the submenu
                                            OperateSubMenu(_trackItem, false);

                                            // Do not attempt to pull a message off the queue as it has already
                                            // been eaten by us in the above code
                                            leaveMsg = true;
                                        }
                                        else
                                        {
                                            // Is this item the expansion command?
                                            if (dc.Expansion)
                                            {
                                                RegenerateExpansion();
                                            }
                                            else
                                            {
                                                // Define the selection to return to caller
                                                _returnCommand = dc.MenuCommand;

                                                // Finish processing messages
                                                _exitLoop = true;
                                            }
                                        }
                                    }
                                    break;
                                case (int)Win32.VirtualKeys.VK_ESCAPE:
                                    // User wants to exit the menu, so set the flag to exit the message loop but
                                    // let the message get processed. This way the key press is thrown away.
                                    _exitLoop = true;
                                    break;
                                default:
                                    // Any other key is treated as a possible mnemonic
                                    int selectItem = ProcessMnemonicKey((char)msg.wParam);

                                    if (selectItem != -1)
                                    {
                                        DrawCommand dc = _drawCommands[selectItem] as DrawCommand;

                                        // Define the selection to return to caller
                                        _returnCommand = dc.MenuCommand;

                                        // Finish processing messages
                                        _exitLoop = true;

                                        // Do not attempt to pull a message off the queue as it has already
                                        // been eaten by us in the above code
                                        leaveMsg = true;
                                    }
                                    break;
                            }
                        }

                        // We consume all keyboard input
                        if ((msg.message == (int)Win32.Msgs.WM_KEYDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_KEYUP) ||
                            (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN) ||
                            (msg.message == (int)Win32.Msgs.WM_SYSKEYUP))
                        {
                            // Eat the message to prevent the intended destination getting it
                            eatMessage = true;
                        }

                        // Should the message be eaten to prevent intended destination getting it?
                        if (eatMessage)
                        {
                            Win32.MSG eat = new Win32.MSG();
                            User32.GetMessage(ref eat, 0, 0, 0);
                        }
                        else
                        {
                            // Should the message we pulled from the queue?
                            if (!leaveMsg)
                            {
                                if (User32.GetMessage(ref msg, 0, 0, 0))
                                {
                                    User32.TranslateMessage(ref msg);
                                    User32.DispatchMessage(ref msg);
                                }
                            }
                            else
                                leaveMsg = false;
                        }
                    }
                }
            }

            // If caret was hidden then show it again now
            if (hideCaret)
                User32.ShowCaret(IntPtr.Zero);

            // Remove tracking of any item, this ensure 'Deselected' event is generated if required
            SwitchSelection(_trackItem, -1, false, false);

            // Hide the window from view before killing it, as sometimes there is a
            // short delay between killing it and it disappearing because of the time
            // it takes for the destroy messages to get processed
            HideMenuWindow();

            // Commit suicide
            DestroyHandle();

            // Was a command actually selected in a top level PopupMenu AND we
            // are not here at the request of a MenuControl
            if ((_parentMenu == null) && (_returnCommand != null) && (_parentControl == null))
            {
                // Pulse the selected event for the command
                _returnCommand.OnClick(EventArgs.Empty);
            }

            return _returnCommand;
        }
Example #4
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);
        }
Example #5
0
 public virtual void OnSelected(MenuCommand mc)
 {
     // Any attached event handlers?
     if (Selected != null)
         Selected(mc);
 }
Example #6
0
        protected void Recalculate()
        {
            int length;

            if (_direction == Direction.Horizontal)
                length = this.Width;
            else
                length = this.Height;

            // Is there space for any commands?
            if (length > 0)
            {
                // Count the number of rows needed
                int rows = 0;

                // Number of items on this row
                int columns = 0;

                // Create a collection of drawing objects
                _drawCommands = new ArrayList();

                // Minimum length is a gap on either side of the text
                int cellMinLength = _lengthGap * 2;

                // Each cell is as broad as the whole control
                int cellBreadth = this.Height;

                // Accumulate starting position of each cell
                int lengthStart = 0;

                // Allow enough space to draw a chevron
                length -= (cellMinLength + _chevronLength);

                bool showPendant = ((rows == 0) && (_activeChild != null));

                // If we are showing on a single line but the active child is not
                // currently maximized then we can show a menu item in pendant space
                if (showPendant && !_multiLine && (_activeChild.WindowState != FormWindowState.Maximized))
                    showPendant = false;

                // Pendant positioning information
                int xPos = 0;
                int yPos = 0;
                int xInc = 0;
                int yInc = 0;

                // First line needs extra space for pendant
                if (showPendant)
                {
                    length -= (_pendantLength + _pendantOffset + _shadowGap);

                    bool popupStyle = (_style == VisualStyle.IDE);
                    int borderWidth = (_style == VisualStyle.IDE) ? 1 : 2;

                    // Define the correct visual style
                    _minButton.PopupStyle = popupStyle;
                    _restoreButton.PopupStyle = popupStyle;
                    _closeButton.PopupStyle = popupStyle;

                    // Define correct border width
                    _minButton.BorderWidth = borderWidth;
                    _restoreButton.BorderWidth = borderWidth;
                    _closeButton.BorderWidth = borderWidth;

                    if (_direction == Direction.Horizontal)
                    {
                        xPos = this.Width - _pendantOffset - _buttonLength;
                        yPos = _pendantOffset;
                        xInc = -_buttonLength;
                    }
                    else
                    {
                        xPos = _pendantOffset;
                        yPos = this.Height - _pendantOffset - _buttonLength;
                        yInc = -_buttonLength;
                    }
                }

                // Assume chevron is not needed by default
                _chevronStartCommand = null;

                using(Graphics g = this.CreateGraphics())
                {
                    // Count the item we are processing
                    int index = 0;

                    foreach(MenuCommand command in _menuCommands)
                    {
                        // Give the command a chance to update its state
                        command.OnUpdate(EventArgs.Empty);

                        // Ignore items that are marked as hidden
                        if (!command.Visible)
                            continue;

                        int cellLength = 0;

                        // Is this a separator?
                        if (command.Text == "-")
                            cellLength = _separatorWidth;
                        else
                        {
                            // Calculate the text width of the cell
                            SizeF dimension = g.MeasureString(command.Text, this.Font);

                            // Always add 1 to ensure that rounding is up and not down
                            cellLength = cellMinLength + (int)dimension.Width + 1;
                        }

                        Rectangle cellRect;

                        // Create a new position rectangle
                        if (_direction == Direction.Horizontal)
                            cellRect = new Rectangle(lengthStart, _rowHeight * rows, cellLength, _rowHeight);
                        else
                            cellRect = new Rectangle(_rowWidth * rows, lengthStart, _rowWidth, cellLength);

                        lengthStart += cellLength;
                        columns++;

                        // If this item is overlapping the control edge and it is not the first
                        // item on the line then we should wrap around to the next row.
                        if ((lengthStart > length) && (columns > 1))
                        {
                            if (_multiLine)
                            {
                                // Move to next row
                                rows++;

                                // Reset number of items on this column
                                columns = 1;

                                // Reset starting position of next item
                                lengthStart = cellLength;

                                // Reset position of this item
                                if (_direction == Direction.Horizontal)
                                {
                                    cellRect.X = 0;
                                    cellRect.Y += _rowHeight;
                                }
                                else
                                {
                                    cellRect.X += _rowWidth;
                                    cellRect.Y = 0;
                                }

                                // Only the first line needs extra space for pendant
                                if (showPendant && (rows == 1))
                                    length += (_pendantLength + _pendantOffset);
                            }
                            else
                            {
                                // Is a tracked item being make invisible
                                if (index <= _trackItem)
                                {
                                    // Need to remove tracking of this item
                                    RemoveItemTracking();
                                }

                                // Remember which item is first for the chevron submenu
                                _chevronStartCommand = command;

                                if (_direction == Direction.Horizontal)
                                {
                                    cellRect.Y = 0;
                                    cellRect.Width = cellMinLength + _chevronLength;
                                    cellRect.X = this.Width - cellRect.Width;
                                    cellRect.Height = _rowHeight;
                                    xPos -= cellRect.Width;
                                }
                                else
                                {
                                    cellRect.X = 0;
                                    cellRect.Height = cellMinLength + _chevronLength;
                                    cellRect.Y = this.Height - (cellMinLength + _chevronLength);
                                    cellRect.Width = _rowWidth;
                                    yPos -= cellRect.Height;
                                }

                                // Create a draw command for this chevron
                                _drawCommands.Add(new DrawCommand(cellRect));

                                // Exit, do not add the current item or any afterwards
                                break;
                            }
                        }

                        Rectangle selectRect = cellRect;

                        // Selection rectangle differs from drawing rectangle with IDE, because pressing the
                        // mouse down causes the menu to appear and because the popup menu appears drawn slightly
                        // over the drawing area the mouse up might select the first item in the popup.
                        if (_style == VisualStyle.IDE)
                        {
                            // Modify depending on orientation
                            if (_direction == Direction.Horizontal)
                                selectRect.Height -= (_lengthGap + 2);
                            else
                                selectRect.Width -= _breadthGap;
                        }

                        // Create a drawing object
                        _drawCommands.Add(new DrawCommand(command, cellRect, selectRect));

                        index++;
                    }
                }

                // Position the pendant buttons
                if (showPendant)
                {
                    if (_activeChild.WindowState == FormWindowState.Maximized)
                    {
                        // Window maximzied, must show the buttons
                        if (!_minButton.Visible)
                        {
                            _minButton.Show();
                            _restoreButton.Show();
                            _closeButton.Show();
                        }

                        // Only enabled minimize box if child is allowed to be minimized
                        _minButton.Enabled = _activeChild.MinimizeBox;

                        _closeButton.Location = new Point(xPos, yPos);

                        xPos += xInc; yPos += yInc;
                        _restoreButton.Location = new Point(xPos, yPos);

                        xPos += xInc; yPos += yInc;
                        _minButton.Location = new Point(xPos, yPos);
                    }
                    else
                    {
                        // No window is maximized, so hide the buttons
                        if (_minButton.Visible)
                        {
                            _minButton.Hide();
                            _restoreButton.Hide();
                            _closeButton.Hide();
                        }
                    }
                }
                else
                {
                    // No window is maximized, so hide the buttons
                    if ((_minButton != null) && _minButton.Visible)
                    {
                        _minButton.Hide();
                        _restoreButton.Hide();
                        _closeButton.Hide();
                    }
                }

                if (_direction == Direction.Horizontal)
                {
                    int controlHeight = (rows + 1) * _rowHeight;

                    // Ensure the control is the correct height
                    if (this.Height != controlHeight)
                        this.Height = controlHeight;
                }
                else
                {
                    int controlWidth = (rows + 1) * _rowWidth;

                    // Ensure the control is the correct width
                    if (this.Width != controlWidth)
                        this.Width = controlWidth;
                }
            }
        }
Example #7
0
        protected bool ProcessKeyRight()
        {
            // Are we the first submenu of a parent control?
            bool autoRight = (_parentControl != null);
            bool checkKeys = false;
            bool ret = false;

            // Is an item currently selected?
            if (_trackItem != -1)
            {
                DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

                // Does this item have a submenu?
                if (dc.SubMenu)
                {
                    // Handle the submenu
                    OperateSubMenu(_trackItem, true);

                    ret = true;
                }
                else
                {
                    // Grab the current column/row values
                    int col = dc.Col;
                    int row = dc.Row;

                    // If not in the first column then move left one
                    int newItem = -1;
                    int newRow = -1;
                    int findCol = col + 1;
                    DrawCommand newDc = null;

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

                        // Interesting in cells in the required column
                        if (listDc.Col == findCol)
                        {
                            // Is this Row nearer to the one required than those found so far?
                            if ((listDc.Row <= row) && (listDc.Row > newRow) &&
                                !listDc.Separator && listDc.Enabled)
                            {
                                // Remember this item
                                newRow = listDc.Row;
                                newDc = listDc;
                                newItem = i;
                            }
                        }
                    }

                    if (newDc != null)
                    {
                        // Track the new item
                        // Modify the display of the two items
                        SwitchSelection(_trackItem, newItem, false, false);
                    }
                    else
                        checkKeys = true;
                }
            }
            else
            {
                if (_parentMenu != null)
                {
                    if (!ProcessKeyDown())
                        checkKeys = true;
                }
                else
                    checkKeys = true;
            }

            // If we have a parent control and nothing to move right into
            if (autoRight && checkKeys)
            {
                _returnCommand = null;

                // Finish processing messages
                _timer.Stop();
                _exitLoop = true;

                _returnDir = 1;
            }

            return ret;
        }
Example #8
0
        protected void OnWM_YBUTTONUP(int xPos, int yPos)
        {
            // Convert from screen to client coordinates
            xPos -= _currentPoint.X;
            yPos -= _currentPoint.Y;

            Point pos = new Point(xPos, yPos);

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

                if (dc.DrawRect.Contains(pos))
                {
                    // Is there a change in selected item?
                    if (_trackItem != i)
                    {
                        // Modify the display of the two items
                        SwitchSelection(_trackItem, i, false, false);
                    }
                }
            }

            // Is an item selected?
            if (_trackItem != -1)
            {
                DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

                // Does this item have a submenu?
                if (dc.SubMenu)
                {
                    // If we are not already showing this submenu...
                    if (_popupItem != _trackItem)
                    {
                        // Is a submenu for a different item showing?
                        if (_childMenu != null)
                        {
                            // Inform the child menu it is no longer needed
                            User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0);
                        }

                        // Handle the submenu
                        OperateSubMenu(_trackItem, false);
                    }
                }
                else
                {
                    if (dc.Expansion)
                        RegenerateExpansion();
                    else
                    {
                        // Kill any child menus open
                        if (_childMenu != null)
                        {
                            // Inform the child menu it is no longer needed
                            User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0);
                        }

                        // Define the selection to return to caller
                        _returnCommand = dc.MenuCommand;

                        // Finish processing messages
                        _timer.Stop();
                        _exitLoop = true;
                    }
                }
            }
        }
 public void Insert(int index, MenuCommand value)
 {
     // Use base class to process actual collection operation
     base.List.Insert(index, value as object);
 }
 public int IndexOf(MenuCommand value)
 {
     // Find the 0 based index of the requested entry
     return base.List.IndexOf(value);
 }
 public bool Contains(MenuCommand value)
 {
     // Use base class to process actual collection operation
     return base.List.Contains(value as object);
 }
 public void AddRange(MenuCommand[] values)
 {
     // Use existing method to add each array entry
     foreach(MenuCommand page in values)
         Add(page);
 }
Example #13
0
 public DrawCommand(MenuCommand command, Rectangle drawRect, int row, int col)
 {
     InternalConstruct(command, drawRect, drawRect, row, col);
 }
Example #14
0
 public DrawCommand(MenuCommand command, Rectangle drawRect, Rectangle selectRect)
 {
     InternalConstruct(command, drawRect, selectRect, -1, -1);
 }
Example #15
0
        protected void OnWM_DISMISS()
        {
            // Pass on to any child menu of ours
            if (_childMenu != null)
            {
                // Inform the child menu it is no longer needed
                User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0);
            }

            // Define the selection to return to caller
            _returnCommand = null;

            // Finish processing messages
            _timer.Stop();
            _exitLoop = true;

            // Hide ourself
            HideMenuWindow();

            // Kill ourself
            DestroyHandle();
        }
 public void Remove(MenuCommand value)
 {
     // Use base class to process actual collection operation
     base.List.Remove(value as object);
 }
Example #17
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;
            }
        }
Example #18
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);
        }
Example #19
0
        protected void ProcessKeyLeft()
        {
            // Are we the first submenu of a parent control?
            bool autoLeft = (_parentMenu != null) || (_parentControl != null);
            bool checkKeys = false;

            if (_trackItem != -1)
            {
                // Get the col this item is in
                DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

                // Grab the current column/row values
                int col = dc.Col;
                int row = dc.Row;

                // If not in the first column then move left one
                if (col > 0)
                {
                    int newItem = -1;
                    int newRow = -1;
                    int findCol = col - 1;
                    DrawCommand newDc = null;

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

                        // Interested in cells in the required column
                        if (listDc.Col == findCol)
                        {
                            // Is this Row nearer to the one required than those found so far?
                            if ((listDc.Row <= row) && (listDc.Row > newRow) &&
                                !listDc.Separator && listDc.Enabled)
                            {
                                // Remember this item
                                newRow = listDc.Row;
                                newDc = listDc;
                                newItem = i;
                            }
                        }
                    }

                    if (newDc != null)
                    {
                        // Track the new item
                        // Modify the display of the two items
                        SwitchSelection(_trackItem, newItem, false, false);
                    }
                    else
                        checkKeys = true;
                }
                else
                    checkKeys = true;
            }
            else
            {
                if (_parentMenu != null)
                {
                    if (!ProcessKeyUp())
                        checkKeys = true;
                }
                else
                    checkKeys = true;
            }

            // If we have a parent control and nothing to move right into
            if (autoLeft && checkKeys)
            {
                _returnCommand = null;

                // Finish processing messages
                _timer.Stop();
                _exitLoop = true;

                // Only a top level PopupMenu should cause the MenuControl to select the
                // next left menu command. A submenu should just become dismissed.
                if (_parentMenu == null)
                    _returnDir = -1;
            }
        }
Example #20
0
 protected void OnCommandChanged(MenuCommand item, MenuCommand.Property prop)
 {
     Recalculate();
     Invalidate();
 }
Example #21
0
 public virtual void OnSelected(MenuCommand mc)
 {
     // If initiated by a MenuControl item then let the control handle this
     if (_parentControl != null)
         _parentControl.OnSelected(mc);
     else
     {
         // If we have an event defined then fire it
         if (Selected != null)
             Selected(mc);
         else
         {
             // Maybe our parent has an event defined instead
             if (_parentMenu != null)
                 _parentMenu.OnSelected(mc);
         }
     }
 }
Example #22
0
        public void InternalConstruct(MenuCommand command, Rectangle drawRect, Rectangle selectRect, int row, int col)
        {
            _row = row;
            _col = col;
            _enabled = command.Enabled;
            _expansion = false;
            _vertSeparator = false;
            _drawRect = drawRect;
            _selectRect = selectRect;
            _command = command;
            _topBorder = false;
            _bottomBorder = false;
            _infrequent = command.Infrequent;

            _chevron = false;

            // Is this MenuCommand a separator?
            _separator = (_command.Text == "-");

            // Does this MenuCommand contain a submenu?
            _subMenu = (_command.MenuCommands.Count > 0);

            // Find position of first mnemonic character
            int position = -1;

            if (command.Text != null)
                position = command.Text.IndexOf('&');

            // Did we find a mnemonic indicator?
            if (position != -1)
            {
                // Must be a character after the indicator
                if (position < (command.Text.Length - 1))
                {
                    // Remember the character
                    _mnemonic = char.ToUpper(command.Text[position + 1]);
                }
            }
        }