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;
}
}
}