theme/devtools/menu.go

Functions Structs

Functions

func PaintMenu

PaintMenu renders a popup menu panel with DevTools elevated surface styling.

func (p MenuPainter) PaintMenu(canvas widget.Canvas, st *menu.MenuPaintState) {
	if st.Bounds.IsEmpty() {
		return
	}

	colors := p.effectiveMenuColors(st.ColorScheme)

	// Elevation shadow.
	shadowRect := geometry.Rect{
		Min:	geometry.Pt(st.Bounds.Min.X+dtMenuShadowOffset, st.Bounds.Min.Y+dtMenuShadowOffset),
		Max:	geometry.Pt(st.Bounds.Max.X+dtMenuShadowOffset, st.Bounds.Max.Y+dtMenuShadowOffset),
	}
	canvas.DrawRoundRect(shadowRect, dtMenuShadowColor, dtMenuRadius)

	// Menu surface.
	canvas.DrawRoundRect(st.Bounds, colors.MenuBackground, dtMenuRadius)
	canvas.StrokeRoundRect(st.Bounds, colors.MenuBorder, dtMenuRadius, dtMenuBorderWidth)

	// Clip to menu bounds.
	canvas.PushClip(st.Bounds)
	defer canvas.PopClip()

	// Draw items.
	y := st.Bounds.Min.Y + dtMenuPaddingV
	for i, item := range st.Items {
		if item.IsSeparator() {
			dtPaintMenuSeparator(canvas, st.Bounds.Min.X, y, st.Bounds.Width(), st.SeparatorHeight, colors.SeparatorColor)
			y += st.SeparatorHeight
			continue
		}

		itemRect := geometry.Rect{
			Min:	geometry.Pt(st.Bounds.Min.X, y),
			Max:	geometry.Pt(st.Bounds.Max.X, y+st.ItemHeight),
		}

		// Highlight.
		if i == st.HighlightedIndex && !item.Disabled {
			canvas.DrawRect(itemRect, colors.ItemHover)
		}

		// Label.
		textColor := colors.ItemText
		if item.Disabled {
			textColor = colors.ItemDisabledText
		}
		labelRect := geometry.Rect{
			Min:	geometry.Pt(itemRect.Min.X+dtMenuItemPaddingH, itemRect.Min.Y),
			Max:	geometry.Pt(itemRect.Max.X-dtMenuShortcutWidth-dtMenuItemPaddingH, itemRect.Max.Y),
		}
		canvas.DrawText(item.Label, labelRect, dtMenuFontSize, textColor, false, widget.TextAlignLeft)

		// Shortcut text or submenu arrow.
		rightRect := geometry.Rect{
			Min:	geometry.Pt(itemRect.Max.X-dtMenuShortcutWidth, itemRect.Min.Y),
			Max:	geometry.Pt(itemRect.Max.X-dtMenuItemPaddingH, itemRect.Max.Y),
		}
		if item.HasChildren() {
			arrowColor := colors.SubMenuArrow
			if item.Disabled {
				arrowColor = colors.ItemDisabledText
			}
			canvas.DrawText(dtMenuRightArrow, rightRect, dtMenuFontSize, arrowColor, false, widget.TextAlignRight)
		} else if item.Shortcut != "" {
			shortcutColor := colors.ShortcutText
			if item.Disabled {
				shortcutColor = colors.ItemDisabledText
			}
			canvas.DrawText(item.Shortcut, rightRect, dtMenuShortcutFontSize, shortcutColor, false, widget.TextAlignRight)
		}

		y += st.ItemHeight
	}
}

func PaintMenuBar

PaintMenuBar renders a menu bar with DevTools surface and border styling.

func (p MenuPainter) PaintMenuBar(canvas widget.Canvas, st *menu.MenuBarPaintState) {
	if st.Bounds.IsEmpty() {
		return
	}

	colors := p.effectiveBarColors(st.ColorScheme)

	// Bar background.
	canvas.DrawRect(st.Bounds, colors.BarBackground)

	// Bottom border.
	borderRect := geometry.Rect{
		Min:	geometry.Pt(st.Bounds.Min.X, st.Bounds.Max.Y-dtMenuBorderWidth),
		Max:	st.Bounds.Max,
	}
	canvas.DrawRect(borderRect, colors.MenuBorder)

	// Draw each top-level menu label.
	for i, m := range st.Menus {
		if i >= len(st.MenuRects) {
			break
		}
		r := st.MenuRects[i]

		// Highlight background.
		switch i {
		case st.OpenIndex:
			canvas.DrawRect(r, colors.ItemHover)
		case st.HoveredIndex:
			canvas.DrawRect(r, colors.BarHover)
		}

		// Label text.
		textColor := colors.BarText
		if i == st.OpenIndex {
			textColor = colors.BarActiveText
		}
		textBounds := geometry.Rect{
			Min:	geometry.Pt(r.Min.X+dtMenuBarPaddingH, r.Min.Y),
			Max:	geometry.Pt(r.Max.X-dtMenuBarPaddingH, r.Max.Y),
		}
		canvas.DrawText(m.Label, textBounds, dtMenuFontSize, textColor, false, widget.TextAlignCenter)
	}
}

Structs

type MenuPainter struct

MenuPainter renders menus and menu bars using DevTools design tokens.

DevTools menus use a dark popup (SurfaceElevated #393B40) with 8px radius,

1px border, 28px item height, right-aligned keyboard shortcut text in Gray9,

and a ControlHover (#43454A) highlight, matching JetBrains IDE menu styling.

 

If Theme is nil, MenuPainter falls back to the default DevTools dark palette.

type MenuPainter struct {
	Theme *Theme	// nil uses default DevTools dark fallback
}