From 1921862b53a908de3e87b4bd3f202f2b34404a7c Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 12 Jan 2021 21:20:08 +1100 Subject: [PATCH] Partially introduce context menu changes back --- v2/internal/ffenestri/contextmenus_darwin.c | 18 +++++++++++++----- v2/internal/ffenestri/contextmenus_darwin.h | 3 +++ .../ffenestri/contextmenustore_darwin.c | 5 ----- .../ffenestri/contextmenustore_darwin.h | 3 --- v2/internal/ffenestri/menu_darwin.c | 13 +++++++++---- v2/internal/ffenestri/menu_darwin.h | 2 +- v2/internal/ffenestri/traymenu_darwin.c | 3 +++ v2/internal/menumanager/menumanager.go | 11 ++++++++--- v2/internal/runtime/menu.go | 6 ++++++ v2/internal/subsystem/menu.go | 18 ++++++++++++++++-- v2/pkg/menu/contextmenu.go | 12 ++++++++++++ v2/test/kitchensink/contextmenus.go | 10 ---------- 12 files changed, 71 insertions(+), 33 deletions(-) diff --git a/v2/internal/ffenestri/contextmenus_darwin.c b/v2/internal/ffenestri/contextmenus_darwin.c index 6aed34c8e..bf1effcf5 100644 --- a/v2/internal/ffenestri/contextmenus_darwin.c +++ b/v2/internal/ffenestri/contextmenus_darwin.c @@ -13,7 +13,8 @@ ContextMenu* NewContextMenu(JsonNode* menuData, ContextMenuStore *store) { result->menu = NewMenu(menuData); result->nsmenu = NULL; result->menu->menuType = ContextMenuType; - result->menu->parentData = store; + result->menu->parentData = result; + result->contextMenuData = NULL; return result; } @@ -26,6 +27,11 @@ void DeleteContextMenu(ContextMenu* contextMenu) { // Free Menu DeleteMenu(contextMenu->menu); + // Delete any context menu data we may have stored + if( contextMenu->contextMenuData != NULL ) { + MEMFREE(contextMenu->contextMenuData); + } + // Free context menu free(contextMenu); } @@ -64,6 +70,7 @@ void ProcessContextMenus(ContextMenuStore* store) { } // Create a new context menu instance ContextMenu *thisContextMenu = NewContextMenu(processedMenu, store); + thisContextMenu->ID = ID; // Store the item in the context menu map hashmap_put(&store->contextMenuStore, (char*)ID, strlen(ID), thisContextMenu); @@ -85,14 +92,15 @@ void ShowContextMenu(ContextMenuStore* store, id mainWindow, const char *context if( contextMenu == NULL ) { // Free context menu data - if( contextMenuData != NULL ) {} - MEMFREE(contextMenuData); - return; + if( contextMenuData != NULL ) { + MEMFREE(contextMenuData); + return; + } } // We need to store the context menu data. Free existing data if we have it // and set to the new value. - FREE_AND_SET(store->contextMenuData, contextMenuData); + FREE_AND_SET(contextMenu->contextMenuData, contextMenuData); // Grab the content view and show the menu id contentView = msg(mainWindow, s("contentView")); diff --git a/v2/internal/ffenestri/contextmenus_darwin.h b/v2/internal/ffenestri/contextmenus_darwin.h index 05b3069cb..3091a1312 100644 --- a/v2/internal/ffenestri/contextmenus_darwin.h +++ b/v2/internal/ffenestri/contextmenus_darwin.h @@ -13,6 +13,9 @@ typedef struct { const char* ID; id nsmenu; Menu* menu; + + // The optional data that may be passed with a context menu selection + const char* contextMenuData; } ContextMenu; diff --git a/v2/internal/ffenestri/contextmenustore_darwin.c b/v2/internal/ffenestri/contextmenustore_darwin.c index 2ce512818..b2a9be579 100644 --- a/v2/internal/ffenestri/contextmenustore_darwin.c +++ b/v2/internal/ffenestri/contextmenustore_darwin.c @@ -9,7 +9,6 @@ ContextMenuStore* NewContextMenuStore(const char* contextMenusAsJSON) { // Init members result->contextMenusAsJSON = contextMenusAsJSON; result->processedContextMenus = NULL; - result->contextMenuData = NULL; // Allocate Context Menu Store if( 0 != hashmap_create((const unsigned)4, &result->contextMenuStore)) { @@ -43,8 +42,4 @@ void DeleteContextMenuStore(ContextMenuStore* store) { store->processedContextMenus = NULL; } - // Delete any context menu data we may have stored - if( store->contextMenuData != NULL ) { - MEMFREE(store->contextMenuData); - } } diff --git a/v2/internal/ffenestri/contextmenustore_darwin.h b/v2/internal/ffenestri/contextmenustore_darwin.h index 7ba128951..f7e42a11d 100644 --- a/v2/internal/ffenestri/contextmenustore_darwin.h +++ b/v2/internal/ffenestri/contextmenustore_darwin.h @@ -15,9 +15,6 @@ typedef struct { // The raw JSON defining the context menus const char* contextMenusAsJSON; - // The optional data that may be passed with a context menu selection - const char* contextMenuData; - // The processed context menus JsonNode* processedContextMenus; diff --git a/v2/internal/ffenestri/menu_darwin.c b/v2/internal/ffenestri/menu_darwin.c index fe63e5339..0ca8c8662 100644 --- a/v2/internal/ffenestri/menu_darwin.c +++ b/v2/internal/ffenestri/menu_darwin.c @@ -88,13 +88,16 @@ void DeleteMenu(Menu *menu) { } // Creates a JSON message for the given menuItemID and data -const char* createMenuClickedMessage(const char *menuItemID, const char *data, enum MenuType menuType) { +const char* createMenuClickedMessage(const char *menuItemID, const char *data, enum MenuType menuType, const char *parentID) { JsonNode *jsonObject = json_mkobject(); json_append_member(jsonObject, "menuItemID", json_mkstring(menuItemID)); json_append_member(jsonObject, "menuType", json_mkstring(MenuTypeAsString[(int)menuType])); if (data != NULL) { json_append_member(jsonObject, "data", json_mkstring(data)); } + if (parentID != NULL) { + json_append_member(jsonObject, "parentID", json_mkstring(parentID)); + } const char *payload = json_encode(jsonObject); json_delete(jsonObject); const char *result = concat("MC", payload); @@ -138,15 +141,17 @@ void menuItemCallback(id self, SEL cmd, id sender) { const char *menuID = callbackData->menuID; const char *data = NULL; enum MenuType menuType = callbackData->menu->menuType; + const char *parentID = NULL; // Generate message to send to backend if( menuType == ContextMenuType ) { // Get the context menu data from the menu - ContextMenuStore* store = (ContextMenuStore*) callbackData->menu->parentData; - data = store->contextMenuData; + ContextMenu* contextMenu = (ContextMenu*) callbackData->menu->parentData; + data = contextMenu->contextMenuData; + parentID = contextMenu->ID; } - message = createMenuClickedMessage(menuID, data, menuType); + message = createMenuClickedMessage(menuID, data, menuType, parentID); // TODO: Add other menu types here! diff --git a/v2/internal/ffenestri/menu_darwin.h b/v2/internal/ffenestri/menu_darwin.h index 62191ae3f..274a2376d 100644 --- a/v2/internal/ffenestri/menu_darwin.h +++ b/v2/internal/ffenestri/menu_darwin.h @@ -65,7 +65,7 @@ MenuItemCallbackData* CreateMenuItemCallbackData(Menu *menu, id menuItem, const void DeleteMenu(Menu *menu); // Creates a JSON message for the given menuItemID and data -const char* createMenuClickedMessage(const char *menuItemID, const char *data, enum MenuType menuType); +const char* createMenuClickedMessage(const char *menuItemID, const char *data, enum MenuType menuType, const char *parentID); // Callback for text menu items void menuItemCallback(id self, SEL cmd, id sender); id processAcceleratorKey(const char *key); diff --git a/v2/internal/ffenestri/traymenu_darwin.c b/v2/internal/ffenestri/traymenu_darwin.c index 4faa07a5a..79f3fec39 100644 --- a/v2/internal/ffenestri/traymenu_darwin.c +++ b/v2/internal/ffenestri/traymenu_darwin.c @@ -9,6 +9,9 @@ TrayMenu* NewTrayMenu(const char* menuJSON) { TrayMenu* result = malloc(sizeof(TrayMenu)); + + + return result; } diff --git a/v2/internal/menumanager/menumanager.go b/v2/internal/menumanager/menumanager.go index c8cba1506..4c85d29af 100644 --- a/v2/internal/menumanager/menumanager.go +++ b/v2/internal/menumanager/menumanager.go @@ -33,15 +33,20 @@ func (m *Manager) getMenuItemByID(menuMap *MenuItemMap, menuId string) *menu.Men return menuMap.idToMenuItemMap[menuId] } -func (m *Manager) ProcessClick(menuID string, data string, menuType string) error { +func (m *Manager) ProcessClick(menuID string, data string, menuType string, parentID string) error { var menuItemMap *MenuItemMap switch menuType { case "ApplicationMenu": menuItemMap = m.applicationMenuItemMap - //case "ContextMenu": - // // TBD + case "ContextMenu": + // TBD + contextMenu := m.contextMenus[parentID] + if contextMenu == nil { + return fmt.Errorf("unknown context menu: %s", parentID) + } + menuItemMap = contextMenu.menuItemMap //case "TrayMenu": // // TBD default: diff --git a/v2/internal/runtime/menu.go b/v2/internal/runtime/menu.go index 57abdfebe..a6ac896ed 100644 --- a/v2/internal/runtime/menu.go +++ b/v2/internal/runtime/menu.go @@ -2,11 +2,13 @@ package runtime import ( "github.com/wailsapp/wails/v2/internal/servicebus" + "github.com/wailsapp/wails/v2/pkg/menu" ) // Menu defines all Menu related operations type Menu interface { UpdateApplicationMenu() + UpdateContextMenu(contextMenu *menu.ContextMenu) } type menuRuntime struct { @@ -23,3 +25,7 @@ func newMenu(bus *servicebus.ServiceBus) Menu { func (m *menuRuntime) UpdateApplicationMenu() { m.bus.Publish("menu:updateappmenu", nil) } + +func (m *menuRuntime) UpdateContextMenu(contextMenu *menu.ContextMenu) { + m.bus.Publish("menu:updatecontextmenu", contextMenu) +} diff --git a/v2/internal/subsystem/menu.go b/v2/internal/subsystem/menu.go index 8c216dd2a..c9d234225 100644 --- a/v2/internal/subsystem/menu.go +++ b/v2/internal/subsystem/menu.go @@ -2,10 +2,11 @@ package subsystem import ( "encoding/json" + "strings" + "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/menumanager" "github.com/wailsapp/wails/v2/internal/servicebus" - "strings" ) // Menu is the subsystem that handles the operation of menus. It manages all service bus messages @@ -80,6 +81,7 @@ func (m *Menu) Start() error { MenuItemID string `json:"menuItemID"` MenuType string `json:"menuType"` Data string `json:"data"` + ParentID string `json:"parentID"` } var callbackData ClickCallbackMessage @@ -90,7 +92,7 @@ func (m *Menu) Start() error { return } - err = m.menuManager.ProcessClick(callbackData.MenuItemID, callbackData.Data, callbackData.MenuType) + err = m.menuManager.ProcessClick(callbackData.MenuItemID, callbackData.Data, callbackData.MenuType, callbackData.ParentID) if err != nil { m.logger.Trace("%s", err.Error()) } @@ -106,6 +108,18 @@ func (m *Menu) Start() error { // Notify frontend of menu change m.bus.Publish("menufrontend:updateappmenu", updatedMenu) + case "updatecontextmenu": + m.logger.Info("Update Context Menu TBD") + //contextMenu := menuMessage.Data().(*menu.ContextMenu) + //updatedMenu, err := m.menuManager.UpdateContextMenu(contextMenu) + //if err != nil { + // m.logger.Trace("%s", err.Error()) + // return + //} + // + //// Notify frontend of menu change + //m.bus.Publish("menufrontend:updatecontextmenu", updatedMenu) + default: m.logger.Error("unknown menu message: %+v", menuMessage) } diff --git a/v2/pkg/menu/contextmenu.go b/v2/pkg/menu/contextmenu.go index e15bee427..502a3829f 100644 --- a/v2/pkg/menu/contextmenu.go +++ b/v2/pkg/menu/contextmenu.go @@ -36,3 +36,15 @@ func (c *ContextMenus) RemoveByID(id string) bool { } return false } + +type ContextMenu struct { + ID string + Menu *Menu +} + +func NewContextMenu(ID string, menu *Menu) *ContextMenu { + return &ContextMenu{ + ID: ID, + Menu: menu, + } +} diff --git a/v2/test/kitchensink/contextmenus.go b/v2/test/kitchensink/contextmenus.go index 9c523d081..f8b2c8165 100644 --- a/v2/test/kitchensink/contextmenus.go +++ b/v2/test/kitchensink/contextmenus.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "sync" "github.com/wailsapp/wails/v2" @@ -20,15 +19,6 @@ func (c *ContextMenu) WailsInit(runtime *wails.Runtime) error { // Perform your setup here c.runtime = runtime - // Setup Menu Listeners - c.runtime.ContextMenu.On("Test Context Menu", func(mi *menu.MenuItem, contextData string) { - c.lock.Lock() - c.counter++ - mi.Label = fmt.Sprintf("Clicked %d times", c.counter) - c.lock.Unlock() - c.runtime.ContextMenu.Update() - }) - return nil }