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); //!!!!betauser. can crash if (viewTab == null) { return(new Rectangle(0, 0, 0, 0)); } // 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); }