gui/pkg/menu/menu.go
Virgil 0423f3058d
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
chore(gui): add AX usage examples
2026-04-02 19:54:47 +00:00

77 lines
2 KiB
Go

// pkg/menu/menu.go
package menu
// MenuItem describes a menu item for construction (structure only — no handlers).
// Use: item := menu.MenuItem{Label: "Quit", OnClick: func() {}}
type MenuItem struct {
Label string
Accelerator string
Type string // "normal", "separator", "checkbox", "radio", "submenu"
Checked bool
Disabled bool
Tooltip string
Children []MenuItem
Role *MenuRole
OnClick func() // Injected by orchestrator, not by menu package consumer
}
// Manager builds application menus via a Platform backend.
// Use: mgr := menu.NewManager(platform)
type Manager struct {
platform Platform
}
// NewManager creates a menu Manager.
// Use: mgr := menu.NewManager(platform)
func NewManager(platform Platform) *Manager {
return &Manager{platform: platform}
}
// Build constructs a PlatformMenu from a tree of MenuItems.
// Use: built := mgr.Build([]menu.MenuItem{{Label: "File"}})
func (m *Manager) Build(items []MenuItem) PlatformMenu {
menu := m.platform.NewMenu()
m.buildItems(menu, items)
return menu
}
func (m *Manager) buildItems(menu PlatformMenu, items []MenuItem) {
for _, item := range items {
if item.Role != nil {
menu.AddRole(*item.Role)
continue
}
if item.Type == "separator" {
menu.AddSeparator()
continue
}
if len(item.Children) > 0 {
sub := menu.AddSubmenu(item.Label)
m.buildItems(sub, item.Children)
continue
}
mi := menu.Add(item.Label)
if item.Accelerator != "" {
mi.SetAccelerator(item.Accelerator)
}
if item.Tooltip != "" {
mi.SetTooltip(item.Tooltip)
}
if item.OnClick != nil {
mi.OnClick(item.OnClick)
}
}
}
// SetApplicationMenu builds and sets the application menu.
// Use: mgr.SetApplicationMenu([]menu.MenuItem{{Label: "Quit"}})
func (m *Manager) SetApplicationMenu(items []MenuItem) {
menu := m.Build(items)
m.platform.SetApplicationMenu(menu)
}
// Platform returns the underlying platform.
// Use: backend := mgr.Platform()
func (m *Manager) Platform() Platform {
return m.platform
}