Esempio n. 1
0
    internal void OperateSubMenu(DrawCommand dc, bool selectFirst, bool trackRemove)
    {
      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 - 1));
        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 + _lengthGap + 1));
        else
          aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Bottom + _lengthGap));
      }
      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;

      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
        _popupMenu.TrackPopup(screenPos, 
          aboveScreenPos,
          _direction,
          mcc, 
          borderGap,
          selectFirst,
          this,
          ref returnDir);
      }
      else
      {
        // Generate event so that caller has chance to modify MenuCommand contents
        OnPopupStart(dc.MenuCommand);

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

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

      // Remove unwanted object
      _popupMenu = null;

      // Was arrow key used to dismiss the submenu?
      if (returnDir != 0)
      {
        // Using keyboard movements means we should have the focus
        if (!_manualFocus)
        {
          _manualFocus = true;

          GrabTheFocus();
        }

        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
      {
        // 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
          _selected = false;
          _drawUpwards = false;

          // Should we stop tracking this item
          if (trackRemove)
          {
            ReturnTheFocus();

            // Unselect the current item
            _trackItem = SwitchTrackingItem(_trackItem, -1);
          }
          else
          {
            // Repaint the item
            DrawCommand(_trackItem, true);
          }
        }
        else
        {
          // Do not change _selected status
          _dismissTransfer = false;
        }
      }
    }