private Rectangle CalculatePopupRect(ViewLayoutRibbonTabsArea tabsArea,
ViewDrawPanel drawMinimizedPanel)
{
Size popupSize;
// Get the preferred size of the groups area, we only really want the height
using (ViewLayoutContext context = new ViewLayoutContext(_ribbon, Renderer))
popupSize = drawMinimizedPanel.GetPreferredSize(context);
// The width should default to being the same width as the ribbon control
popupSize.Width = _ribbon.Width;
// Get the screen rectangles for the ribbon and the tabs area of the ribbon
Rectangle parentRibbonRect = _ribbon.RectangleToScreen(_ribbon.ClientRectangle);
Rectangle parentTabsRect = _ribbon.RectangleToScreen(tabsArea.ClientRectangle);
// Default popup is placed below the ribbon
Rectangle popupRect = new Rectangle(parentRibbonRect.X, parentTabsRect.Bottom - 1, popupSize.Width, popupSize.Height);
// Get the view element for the currently selected tab
ViewDrawRibbonTab viewTab = tabsArea.LayoutTabs.GetViewForRibbonTab(_ribbon.SelectedTab);
// Convert the view tab client area to screen coordinates
Rectangle viewTabRect = _ribbon.RectangleToScreen(viewTab.ClientRectangle);
// Get the screen that the tab is mostly within
Screen screen = Screen.FromRectangle(viewTabRect);
Rectangle workingArea = screen.WorkingArea;
workingArea.Width -= BOTTOMRIGHT_GAP;
workingArea.Height -= BOTTOMRIGHT_GAP;
// Is the right side of the popup extending over the right edge of the screen...
if (popupRect.Right > workingArea.Right)
{
// Reduce width to bring it back onto the screen
popupRect.Width -= (popupRect.Right - workingArea.Right);
// Enforce a minimum useful width for the popup
if (popupRect.Width < MINIMUM_WIDTH)
{
popupRect.X -= (MINIMUM_WIDTH - popupRect.Width);
popupRect.Width = MINIMUM_WIDTH;
}
}
else
{
// Is the left side of the popup extending over left edge of screen...
if (popupRect.Left < workingArea.Left)
{
// Reduce left side of popup to start at screen left edge
int reduce = (workingArea.Left - popupRect.Left);
popupRect.Width -= reduce;
popupRect.X += reduce;
// Enforce a minimum useful width for the popup
if (popupRect.Width < MINIMUM_WIDTH)
popupRect.Width = MINIMUM_WIDTH;
}
}
// If there is not enough room to place the popup below the tabs area
if (popupRect.Bottom > workingArea.Bottom)
{
// Is there enough room above the parent for the entire popup height?
if ((parentTabsRect.Top - popupRect.Height) >= workingArea.Top)
{
// Place the popup above the parent
popupRect.Y = parentTabsRect.Top - popupSize.Height;
}
else
{
// Cannot show entire popup above or below, find which has most space
int spareAbove = parentTabsRect.Top - workingArea.Top;
int spareBelow = workingArea.Bottom - parentTabsRect.Bottom;
// Place it in the area with the most space
if (spareAbove > spareBelow)
popupRect.Y = workingArea.Top;
else
popupRect.Y = parentTabsRect.Bottom;
}
}
return popupRect;
}