Overview

Namespace: TheTechIdea.Beep.Winform.Controls.Menus
BeepMenuBar is a full-featured menu bar control decomposed across 13 partial files. It handles menu bar layout, popup submenus with drift-corrected hover persistence (via the SubmenuTriangleTracker), theming, accessibility, keyboard navigation with mnemonics, and high-contrast rendering. The SubmenuTriangleTracker is a classic Amazon-style drift heuristic based on Bret Victor's "Pull-Down Menus, Faster" (2005) research.

Partial File Layout (13 Files)

FileResponsibility
.csMain control definition: constructor, internal fields (items list, popup tracking, timer state)
.Theming.csTheme token application, style resolution, color mapping from IBeepTheme to menu elements
.Properties.csItems collection, Orientation (Horizontal/Vertical), Style, ShowIcons, background appearance
.Layout.csMenu item position calculation, bar sizing, overflow handling, item width measurement
.Popup.csSubmenu popup lifecycle: create, open with delay, close with delay, position anchoring, z-order
.Keyboard.csArrow key navigation (up/down/left/right), Enter key activation, Escape dismiss, mnemonics (Alt+letter)
.Input.csMouse hover/click handling, hit testing for item detection, hover-open timer management
.Drawing.csPaint overrides: background, item text/icon/shortcut rendering, selection highlight, separator lines
.Activation.csMenu activation/deactivation, focus management, dismissal on outside click
.HighContrast.csHigh contrast mode detection and palette override, system contrast colors for borders and focus
.Lifecycle.csControl lifecycle: initialization, Dispose, resource cleanup, event unsubscription
.Utility.csShared utilities: color blending, rectangle calculations, text measurement helpers
.Accessibility.csUIAutomation provider pattern, screen reader support, role/name/value properties per item

SubmenuTriangleTracker

Visibility: internal static in Menus/Helpers/SubmenuTriangleTracker.cs. A stateless geometry helper that solves the classic "submenu flicker" problem. When the cursor moves diagonally from a parent menu item toward an open submenu, this tracker determines whether the cursor is "heading toward" the submenu.

internal static class SubmenuTriangleTracker
{
    public static bool IsHeadingTowardSubmenu(
        Point lastPos,          // previous cursor position (screen coords)
        Point currentPos,       // current cursor position (screen coords)
        Point submenuTopLeft,   // submenu window top-left corner
        Point submenuBottomLeft // submenu window bottom-left corner
    );
    // Returns true when currentPos is inside the triangle formed by
    // lastPos, submenuTopLeft, and submenuBottomLeft
    // -> cursor is plausibly moving toward the submenu
    // -> should NOT dismiss the submenu
}

This is based on the same research used in WPF's MenuItem.IsSubmenuOpen heuristic and Amazon's retail mega-menu analysis. The tracker allows users to move the cursor diagonally to a submenu without the timer closing it prematurely.

  Menu Item        Submenu
  [File]----------+
  [Edit]       +--+  Open Recent
  [View]       |     +--------------+
               +---->| LastFile1.cs |
  cursor moves        | LastFile2.cs |
  diagonally ->       +--------------+
  Tracker keeps
  submenu open

Keyboard Navigation

BeepMenuBar.Keyboard.cs routes all keyboard input:

  • Arrow keys -- Left/Right navigate between top-level items. Up/Down navigate within submenu items. Right on a parent item opens the submenu. Left on a submenu item closes it and returns to parent.
  • Enter -- Invokes the active menu item command or opens its submenu
  • Escape -- Closes the current submenu level, or dismisses the entire menu bar
  • Mnemonics -- Alt+letter activates the menu item with matching mnemonic character
  • Tab -- Cycles focus away from the menu bar

Helper Classes

ClassNamespaceRole
SubmenuTriangleTrackerHelpersDrift heuristic for submenu persistence during diagonal cursor transit
MenuThemeHelpersHelpersTheme token resolution for menu items: resolves active/inactive/hover/disabled colors, font, icon colors from IBeepTheme
MenuIconHelpersHelpersIcon loading with caching, sizing (16, 20, 24px), SVG rendering via StyledImagePainter, fallback placeholder generation
MenuFontHelpersHelpersFont resolution from theme, measurement for layout (text width, height), mnemonic underline positioning

High Contrast

BeepMenuBar.HighContrast.cs detects system high contrast mode via SystemInformation.HighContrast. When active:

  • All theme colors are overridden with system-defined contrast colors
  • Borders use SystemColors.ControlDark (2px thickness)
  • Focus rectangles use SystemColors.Highlight
  • Selection uses SystemColors.Highlight / SystemColors.HighlightText
  • Icons are rendered in high-contrast-compatible mode (outline style)

Code Examples

var menu = new BeepMenuBar();
menu.Items.Add(new BeepMenuItem("File", null,
    new List<BeepMenuItem>
    {
        new BeepMenuItem("New", Icons.NewFile, () => NewFile()),
        new BeepMenuItem("Open", Icons.OpenFolder, () => OpenFile()),
        new BeepMenuSeparator(),
        new BeepMenuItem("Save", Icons.Save, () => SaveFile())
            { Shortcut = "Ctrl+S" },
        new BeepMenuItem("Exit", null, () => Application.Exit())
    }));
menu.Items.Add(new BeepMenuItem("Help", null,
    new List<BeepMenuItem>
    {
        new BeepMenuItem("About", Icons.Info, () => ShowAbout())
    }));