github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/internal/menumanager/menumanager.go (about)

     1  package menumanager
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/AlpineAIO/wails/v2/pkg/menu"
     7  )
     8  
     9  type Manager struct {
    10  	// The application menu.
    11  	applicationMenu          *menu.Menu
    12  	applicationMenuJSON      string
    13  	processedApplicationMenu *WailsMenu
    14  
    15  	// Our application menu mappings
    16  	applicationMenuItemMap *MenuItemMap
    17  
    18  	// Context menus
    19  	contextMenus        map[string]*ContextMenu
    20  	contextMenuPointers map[*menu.ContextMenu]string
    21  
    22  	// Tray menu stores
    23  	trayMenus        map[string]*TrayMenu
    24  	trayMenuPointers map[*menu.TrayMenu]string
    25  
    26  	// Radio groups
    27  	radioGroups map[*menu.MenuItem][]*menu.MenuItem
    28  }
    29  
    30  func NewManager() *Manager {
    31  	return &Manager{
    32  		applicationMenuItemMap: NewMenuItemMap(),
    33  		contextMenus:           make(map[string]*ContextMenu),
    34  		contextMenuPointers:    make(map[*menu.ContextMenu]string),
    35  		trayMenus:              make(map[string]*TrayMenu),
    36  		trayMenuPointers:       make(map[*menu.TrayMenu]string),
    37  		radioGroups:            make(map[*menu.MenuItem][]*menu.MenuItem),
    38  	}
    39  }
    40  
    41  func (m *Manager) getMenuItemByID(menuMap *MenuItemMap, menuId string) *menu.MenuItem {
    42  	return menuMap.idToMenuItemMap[menuId]
    43  }
    44  
    45  func (m *Manager) ProcessClick(menuID string, data string, menuType string, parentID string) error {
    46  	var menuItemMap *MenuItemMap
    47  
    48  	switch menuType {
    49  	case "ApplicationMenu":
    50  		menuItemMap = m.applicationMenuItemMap
    51  	case "ContextMenu":
    52  		contextMenu := m.contextMenus[parentID]
    53  		if contextMenu == nil {
    54  			return fmt.Errorf("unknown context menu: %s", parentID)
    55  		}
    56  		menuItemMap = contextMenu.menuItemMap
    57  	case "TrayMenu":
    58  		trayMenu := m.trayMenus[parentID]
    59  		if trayMenu == nil {
    60  			return fmt.Errorf("unknown tray menu: %s", parentID)
    61  		}
    62  		menuItemMap = trayMenu.menuItemMap
    63  	default:
    64  		return fmt.Errorf("unknown menutype: %s", menuType)
    65  	}
    66  
    67  	// Get the menu item
    68  	menuItem := menuItemMap.getMenuItemByID(menuID)
    69  	if menuItem == nil {
    70  		return fmt.Errorf("Cannot process menuid %s - unknown", menuID)
    71  	}
    72  
    73  	// Is the menu item a checkbox?
    74  	if menuItem.Type == menu.CheckboxType {
    75  		// Toggle state
    76  		menuItem.Checked = !menuItem.Checked
    77  	}
    78  
    79  	if menuItem.Type == menu.RadioType {
    80  		println("Toggle radio")
    81  		// Get my radio group
    82  		for _, radioMenuItem := range m.radioGroups[menuItem] {
    83  			radioMenuItem.Checked = (radioMenuItem == menuItem)
    84  		}
    85  	}
    86  
    87  	if menuItem.Click == nil {
    88  		// No callback
    89  		return fmt.Errorf("No callback for menu '%s'", menuItem.Label)
    90  	}
    91  
    92  	// Create new Callback struct
    93  	callbackData := &menu.CallbackData{
    94  		MenuItem: menuItem,
    95  		// ContextData: data,
    96  	}
    97  
    98  	// Call back!
    99  	go menuItem.Click(callbackData)
   100  
   101  	return nil
   102  }
   103  
   104  func (m *Manager) processRadioGroups(processedMenu *WailsMenu, itemMap *MenuItemMap) {
   105  	for _, group := range processedMenu.RadioGroups {
   106  		radioGroupMenuItems := []*menu.MenuItem{}
   107  		for _, member := range group.Members {
   108  			item := m.getMenuItemByID(itemMap, member)
   109  			radioGroupMenuItems = append(radioGroupMenuItems, item)
   110  		}
   111  		for _, radioGroupMenuItem := range radioGroupMenuItems {
   112  			m.radioGroups[radioGroupMenuItem] = radioGroupMenuItems
   113  		}
   114  	}
   115  }