mirror of
https://github.com/taigrr/wails.git
synced 2026-04-02 05:08:54 -07:00
Support for radio menu items
This commit is contained in:
@@ -17,7 +17,11 @@ extern void SetWindowBackgroundIsTranslucent(void *);
|
||||
extern void SetMenu(void *, const char *);
|
||||
*/
|
||||
import "C"
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
)
|
||||
|
||||
func (a *Application) processPlatformSettings() error {
|
||||
|
||||
@@ -69,12 +73,113 @@ func (a *Application) processPlatformSettings() error {
|
||||
|
||||
// Process menu
|
||||
if mac.Menu != nil {
|
||||
menuJson, err := json.Marshal(mac.Menu)
|
||||
|
||||
/*
|
||||
As radio groups need to be manually managed on OSX,
|
||||
we preprocess the menu to determine the radio groups.
|
||||
This is defined as any adjacent menu item of type "RadioType".
|
||||
We keep a record of every radio group member we discover by saving
|
||||
a list of all members of the group and the number of members
|
||||
in the group (this last one is for optimisation at the C layer).
|
||||
|
||||
Example:
|
||||
{
|
||||
"RadioGroups": [
|
||||
{
|
||||
"Members": [
|
||||
"option-1",
|
||||
"option-2",
|
||||
"option-3"
|
||||
],
|
||||
"Length": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
processedMenu := NewProcessedMenu(mac.Menu)
|
||||
menuJSON, err := json.Marshal(processedMenu)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
C.SetMenu(a.app, a.string2CString(string(menuJson)))
|
||||
C.SetMenu(a.app, a.string2CString(string(menuJSON)))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessedMenu is the original menu with the addition
|
||||
// of radio groups extracted from the menu data
|
||||
type ProcessedMenu struct {
|
||||
Menu *menu.Menu
|
||||
RadioGroups []*RadioGroup
|
||||
currentRadioGroup []string
|
||||
}
|
||||
|
||||
// RadioGroup holds all the members of the same radio group
|
||||
type RadioGroup struct {
|
||||
Members []string
|
||||
Length int
|
||||
}
|
||||
|
||||
// NewProcessedMenu processed the given menu and returns
|
||||
// the original menu with the extracted radio groups
|
||||
func NewProcessedMenu(menu *menu.Menu) *ProcessedMenu {
|
||||
result := &ProcessedMenu{
|
||||
Menu: menu,
|
||||
RadioGroups: []*RadioGroup{},
|
||||
currentRadioGroup: []string{},
|
||||
}
|
||||
|
||||
result.processMenu()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (p *ProcessedMenu) processMenu() {
|
||||
// Loop over top level menus
|
||||
for _, item := range p.Menu.Items {
|
||||
// Process MenuItem
|
||||
p.processMenuItem(item)
|
||||
}
|
||||
|
||||
p.finaliseRadioGroup()
|
||||
}
|
||||
|
||||
func (p *ProcessedMenu) processMenuItem(item *menu.MenuItem) {
|
||||
|
||||
switch item.Type {
|
||||
|
||||
// We need to recurse submenus
|
||||
case menu.SubmenuType:
|
||||
|
||||
// Finalise any current radio groups as they don't trickle down to submenus
|
||||
p.finaliseRadioGroup()
|
||||
|
||||
// Process each submenu item
|
||||
for _, subitem := range item.SubMenu {
|
||||
p.processMenuItem(subitem)
|
||||
}
|
||||
case menu.RadioType:
|
||||
// Add the item to the radio group
|
||||
p.currentRadioGroup = append(p.currentRadioGroup, item.ID)
|
||||
default:
|
||||
p.finaliseRadioGroup()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ProcessedMenu) finaliseRadioGroup() {
|
||||
|
||||
// If we were processing a radio group, fix up the references
|
||||
if len(p.currentRadioGroup) > 0 {
|
||||
|
||||
// Create new radiogroup
|
||||
group := &RadioGroup{
|
||||
Members: p.currentRadioGroup,
|
||||
Length: len(p.currentRadioGroup),
|
||||
}
|
||||
p.RadioGroups = append(p.RadioGroups, group)
|
||||
|
||||
// Empty the radio group
|
||||
p.currentRadioGroup = []string{}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user