From 4e58b7697a9f59fd5e34c856858229e0d4e8cfe2 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 11 Jan 2021 14:19:01 +1100 Subject: [PATCH] Add context menu to menumanager. Slight refactor. --- v2/internal/app/desktop.go | 10 +++++ v2/internal/menumanager/applicationmenu.go | 46 +++++++++++++++++++++ v2/internal/menumanager/contextmenu.go | 47 ++++++++++++++++++++++ v2/internal/menumanager/menumanager.go | 45 ++------------------- v2/internal/menumanager/processedMenu.go | 12 +++--- v2/internal/subsystem/menu.go | 10 ----- v2/test/kitchensink/contextmenus.go | 26 ++++++------ v2/test/kitchensink/main.go | 2 +- v2/test/kitchensink/menu.go | 3 +- 9 files changed, 129 insertions(+), 72 deletions(-) create mode 100644 v2/internal/menumanager/applicationmenu.go create mode 100644 v2/internal/menumanager/contextmenu.go diff --git a/v2/internal/app/desktop.go b/v2/internal/app/desktop.go index 3629cc998..749729b80 100644 --- a/v2/internal/app/desktop.go +++ b/v2/internal/app/desktop.go @@ -59,8 +59,18 @@ func CreateApp(appoptions *options.App) (*App, error) { // Create the menu manager menuManager := menumanager.NewManager() + + // Process the application menu menuManager.SetApplicationMenu(options.GetApplicationMenu(appoptions)) + // Process context menus + contextMenus := options.GetContextMenus(appoptions) + if contextMenus != nil { + for contextMenuID, contextMenu := range contextMenus.Items { + menuManager.AddContextMenu(contextMenuID, contextMenu) + } + } + window := ffenestri.NewApplicationWithConfig(appoptions, myLogger, menuManager) result := &App{ diff --git a/v2/internal/menumanager/applicationmenu.go b/v2/internal/menumanager/applicationmenu.go new file mode 100644 index 000000000..3ebb8f934 --- /dev/null +++ b/v2/internal/menumanager/applicationmenu.go @@ -0,0 +1,46 @@ +package menumanager + +import "github.com/wailsapp/wails/v2/pkg/menu" + +func (m *Manager) SetApplicationMenu(applicationMenu *menu.Menu) error { + + if applicationMenu == nil { + return nil + } + + m.applicationMenu = applicationMenu + + // Reset the menu map + m.applicationMenuItemMap = NewMenuItemMap() + + // Add the menu to the menu map + m.applicationMenuItemMap.AddMenu(applicationMenu) + + return m.processApplicationMenu() +} + +func (m *Manager) GetApplicationMenuJSON() string { + return m.applicationMenuJSON +} + +// UpdateApplicationMenu reprocesses the application menu to pick up structure +// changes etc +// Returns the JSON representation of the updated menu +func (m *Manager) UpdateApplicationMenu() (string, error) { + m.applicationMenuItemMap = NewMenuItemMap() + m.applicationMenuItemMap.AddMenu(m.applicationMenu) + err := m.processApplicationMenu() + return m.applicationMenuJSON, err +} + +func (m *Manager) processApplicationMenu() error { + + // Process the menu + processedApplicationMenu := NewWailsMenu(m.applicationMenuItemMap, m.applicationMenu) + applicationMenuJSON, err := processedApplicationMenu.AsJSON() + if err != nil { + return err + } + m.applicationMenuJSON = applicationMenuJSON + return nil +} diff --git a/v2/internal/menumanager/contextmenu.go b/v2/internal/menumanager/contextmenu.go new file mode 100644 index 000000000..5067f767b --- /dev/null +++ b/v2/internal/menumanager/contextmenu.go @@ -0,0 +1,47 @@ +package menumanager + +import ( + "fmt" + "github.com/wailsapp/wails/v2/pkg/menu" +) + +type ContextMenu struct { + ID string + JSON string + menuItemMap *MenuItemMap + menu *menu.Menu +} + +func NewContextMenu(ID string, menu *menu.Menu) *ContextMenu { + + result := &ContextMenu{ + ID: ID, + JSON: "", + menu: menu, + menuItemMap: NewMenuItemMap(), + } + + result.menuItemMap.AddMenu(menu) + + return result +} + +func (m *Manager) AddContextMenu(menuID string, menu *menu.Menu) error { + contextMenu := NewContextMenu(menuID, menu) + m.contextMenus[menuID] = contextMenu + return contextMenu.process() +} + +func (c *ContextMenu) process() error { + + // Process the menu + processedApplicationMenu := NewWailsMenu(c.menuItemMap, c.menu) + JSON, err := processedApplicationMenu.AsJSON() + if err != nil { + return err + } + c.JSON = JSON + fmt.Printf("Processed context menu '%s':", c.ID) + println(JSON) + return nil +} diff --git a/v2/internal/menumanager/menumanager.go b/v2/internal/menumanager/menumanager.go index 9572f2c00..e63224091 100644 --- a/v2/internal/menumanager/menumanager.go +++ b/v2/internal/menumanager/menumanager.go @@ -13,55 +13,18 @@ type Manager struct { // Our application menu mappings applicationMenuItemMap *MenuItemMap + + // Context menus + contextMenus map[string]*ContextMenu } func NewManager() *Manager { return &Manager{ applicationMenuItemMap: NewMenuItemMap(), + contextMenus: make(map[string]*ContextMenu), } } -func (m *Manager) SetApplicationMenu(applicationMenu *menu.Menu) error { - if applicationMenu == nil { - return nil - } - m.applicationMenu = applicationMenu - - // Reset the menu map - m.applicationMenuItemMap = NewMenuItemMap() - - // Add the menu to the menu map - m.applicationMenuItemMap.AddMenu(applicationMenu) - - return m.processApplicationMenu() -} - -func (m *Manager) GetApplicationMenuJSON() string { - return m.applicationMenuJSON -} - -// UpdateApplicationMenu reprocesses the application menu to pick up structure -// changes etc -// Returns the JSON representation of the updated menu -func (m *Manager) UpdateApplicationMenu() (string, error) { - m.applicationMenuItemMap = NewMenuItemMap() - m.applicationMenuItemMap.AddMenu(m.applicationMenu) - err := m.processApplicationMenu() - return m.applicationMenuJSON, err -} - -func (m *Manager) processApplicationMenu() error { - - // Process the menu - processedApplicationMenu := m.NewWailsMenu(m.applicationMenuItemMap, m.applicationMenu) - applicationMenuJSON, err := processedApplicationMenu.AsJSON() - if err != nil { - return err - } - m.applicationMenuJSON = applicationMenuJSON - return nil -} - func (m *Manager) getMenuItemByID(menuMap *MenuItemMap, menuId string) *menu.MenuItem { return menuMap.idToMenuItemMap[menuId] } diff --git a/v2/internal/menumanager/processedMenu.go b/v2/internal/menumanager/processedMenu.go index 408faed13..4f98c347e 100644 --- a/v2/internal/menumanager/processedMenu.go +++ b/v2/internal/menumanager/processedMenu.go @@ -33,7 +33,7 @@ type ProcessedMenuItem struct { Background int } -func (m *Manager) NewProcessedMenuItem(menuItemMap *MenuItemMap, menuItem *menu.MenuItem) *ProcessedMenuItem { +func NewProcessedMenuItem(menuItemMap *MenuItemMap, menuItem *menu.MenuItem) *ProcessedMenuItem { ID := menuItemMap.menuItemToIDMap[menuItem] result := &ProcessedMenuItem{ @@ -50,7 +50,7 @@ func (m *Manager) NewProcessedMenuItem(menuItemMap *MenuItemMap, menuItem *menu. } if menuItem.SubMenu != nil { - result.SubMenu = m.NewProcessedMenu(menuItemMap, menuItem.SubMenu) + result.SubMenu = NewProcessedMenu(menuItemMap, menuItem.SubMenu) } return result @@ -60,11 +60,11 @@ type ProcessedMenu struct { Items []*ProcessedMenuItem } -func (m *Manager) NewProcessedMenu(menuItemMap *MenuItemMap, menu *menu.Menu) *ProcessedMenu { +func NewProcessedMenu(menuItemMap *MenuItemMap, menu *menu.Menu) *ProcessedMenu { result := &ProcessedMenu{} for _, item := range menu.Items { - processedMenuItem := m.NewProcessedMenuItem(menuItemMap, item) + processedMenuItem := NewProcessedMenuItem(menuItemMap, item) result.Items = append(result.Items, processedMenuItem) } @@ -85,11 +85,11 @@ type RadioGroup struct { Length int } -func (m *Manager) NewWailsMenu(menuItemMap *MenuItemMap, menu *menu.Menu) *WailsMenu { +func NewWailsMenu(menuItemMap *MenuItemMap, menu *menu.Menu) *WailsMenu { result := &WailsMenu{} // Process the menus - result.Menu = m.NewProcessedMenu(menuItemMap, menu) + result.Menu = NewProcessedMenu(menuItemMap, menu) // Process the radio groups result.processRadioGroups() diff --git a/v2/internal/subsystem/menu.go b/v2/internal/subsystem/menu.go index 5e57338a3..df2e0b06f 100644 --- a/v2/internal/subsystem/menu.go +++ b/v2/internal/subsystem/menu.go @@ -11,16 +11,6 @@ import ( "github.com/wailsapp/wails/v2/pkg/menu" ) -// eventListener holds a callback function which is invoked when -// the event listened for is emitted. It has a counter which indicates -// how the total number of events it is interested in. A value of zero -// means it does not expire (default). -// type eventListener struct { -// callback func(...interface{}) // Function to call with emitted event data -// counter int // The number of times this callback may be called. -1 = infinite -// delete bool // Flag to indicate that this listener should be deleted -// } - // Menu is the subsystem that handles the operation of menus. It manages all service bus messages // starting with "menu". type Menu struct { diff --git a/v2/test/kitchensink/contextmenus.go b/v2/test/kitchensink/contextmenus.go index 0fd12ddd8..9c523d081 100644 --- a/v2/test/kitchensink/contextmenus.go +++ b/v2/test/kitchensink/contextmenus.go @@ -34,18 +34,18 @@ func (c *ContextMenu) WailsInit(runtime *wails.Runtime) error { func createContextMenus() *menu.ContextMenus { result := menu.NewContextMenus() - //result.AddMenu("test", menu.NewMenuFromItems( - // menu.Text("Clicked 0 times", "Test Context Menu", nil), - // menu.Separator(), - // menu.Checkbox("I am a checkbox", "checkbox", false, nil), - // menu.Separator(), - // menu.Radio("Radio Option 1", "Radio Option 1", true, nil), - // menu.Radio("Radio Option 2", "Radio Option 2", false, nil), - // menu.Radio("Radio Option 3", "Radio Option 3", false, nil), - // menu.Separator(), - // menu.SubMenu("A Submenu", menu.NewMenuFromItems( - // menu.Text("Hello", "Hello", nil), - // )), - //)) + result.AddMenu("test", menu.NewMenuFromItems( + menu.Text("Clicked 0 times", "Test Context Menu", nil, nil), + menu.Separator(), + menu.Checkbox("I am a checkbox", "checkbox", false, nil, nil), + menu.Separator(), + menu.Radio("Radio Option 1", "Radio Option 1", true, nil, nil), + menu.Radio("Radio Option 2", "Radio Option 2", false, nil, nil), + menu.Radio("Radio Option 3", "Radio Option 3", false, nil, nil), + menu.Separator(), + menu.SubMenu("A Submenu", menu.NewMenuFromItems( + menu.Text("Hello", "Hello", nil, nil), + )), + )) return result } diff --git a/v2/test/kitchensink/main.go b/v2/test/kitchensink/main.go index e91301c9e..419e6d8ed 100644 --- a/v2/test/kitchensink/main.go +++ b/v2/test/kitchensink/main.go @@ -22,7 +22,7 @@ func main() { //Tray: menu.NewMenuFromItems(menu.AppMenu()), //Menu: menu.NewMenuFromItems(menu.AppMenu()), //StartHidden: true, - //ContextMenus: createContextMenus(), + ContextMenus: createContextMenus(), Mac: &mac.Options{ WebviewIsTransparent: true, WindowBackgroundIsTranslucent: true, diff --git a/v2/test/kitchensink/menu.go b/v2/test/kitchensink/menu.go index 40dc60579..016cbe392 100644 --- a/v2/test/kitchensink/menu.go +++ b/v2/test/kitchensink/menu.go @@ -80,10 +80,11 @@ func (m *Menu) removeDynamicMenuOneMenu(_ *menu.CallbackData) { // Get the last menu we added lastItemIndex := len(m.dynamicMenuOneItems) - 1 lastMenuAdded := m.dynamicMenuOneItems[lastItemIndex] + // Remove from slice m.dynamicMenuOneItems = m.dynamicMenuOneItems[:lastItemIndex] - // Remove the item from the + // Remove the item from the menu lastMenuAdded.Remove() // Update the counter