77 lines
2 KiB
Go
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
|
|
}
|