mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 15:00:21 +08:00
Fixed and refactored context menu support
This commit is contained in:
parent
de06fc7dcc
commit
e65118e962
@ -63,10 +63,8 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
|||||||
|
|
||||||
// Process context menus
|
// Process context menus
|
||||||
contextMenus := options.GetContextMenus(appoptions)
|
contextMenus := options.GetContextMenus(appoptions)
|
||||||
if contextMenus != nil {
|
for _, contextMenu := range contextMenus {
|
||||||
for contextMenuID, contextMenu := range contextMenus.Items {
|
menuManager.AddContextMenu(contextMenu)
|
||||||
menuManager.AddContextMenu(contextMenuID, contextMenu)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process tray menus
|
// Process tray menus
|
||||||
|
@ -8,9 +8,20 @@
|
|||||||
#include "contextmenus_darwin.h"
|
#include "contextmenus_darwin.h"
|
||||||
#include "menu_darwin.h"
|
#include "menu_darwin.h"
|
||||||
|
|
||||||
ContextMenu* NewContextMenu(JsonNode* menuData, ContextMenuStore *store) {
|
ContextMenu* NewContextMenu(const char* contextMenuJSON) {
|
||||||
ContextMenu* result = malloc(sizeof(ContextMenu));
|
ContextMenu* result = malloc(sizeof(ContextMenu));
|
||||||
result->menu = NewMenu(menuData);
|
|
||||||
|
JsonNode* processedJSON = json_decode(contextMenuJSON);
|
||||||
|
if( processedJSON == NULL ) {
|
||||||
|
ABORT("[NewTrayMenu] Unable to parse TrayMenu JSON: %s", contextMenuJSON);
|
||||||
|
}
|
||||||
|
// Save reference to this json
|
||||||
|
result->processedJSON = processedJSON;
|
||||||
|
|
||||||
|
result->ID = mustJSONString(processedJSON, "ID");
|
||||||
|
JsonNode* processedMenu = mustJSONObject(processedJSON, "ProcessedMenu");
|
||||||
|
|
||||||
|
result->menu = NewMenu(processedMenu);
|
||||||
result->nsmenu = NULL;
|
result->nsmenu = NULL;
|
||||||
result->menu->menuType = ContextMenuType;
|
result->menu->menuType = ContextMenuType;
|
||||||
result->menu->parentData = result;
|
result->menu->parentData = result;
|
||||||
@ -18,9 +29,8 @@ ContextMenu* NewContextMenu(JsonNode* menuData, ContextMenuStore *store) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ContextMenu* GetContextMenuByID(ContextMenuStore* store, const char *contextMenuID) {
|
ContextMenu* GetContextMenuByID(ContextMenuStore* store, const char *contextMenuID) {
|
||||||
return (ContextMenu*)hashmap_get(&store->contextMenuStore, (char*)contextMenuID, strlen(contextMenuID));
|
return (ContextMenu*)hashmap_get(&store->contextMenuMap, (char*)contextMenuID, strlen(contextMenuID));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteContextMenu(ContextMenu* contextMenu) {
|
void DeleteContextMenu(ContextMenu* contextMenu) {
|
||||||
@ -32,6 +42,12 @@ void DeleteContextMenu(ContextMenu* contextMenu) {
|
|||||||
MEMFREE(contextMenu->contextMenuData);
|
MEMFREE(contextMenu->contextMenuData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free JSON
|
||||||
|
if (contextMenu->processedJSON != NULL ) {
|
||||||
|
json_delete(contextMenu->processedJSON);
|
||||||
|
contextMenu->processedJSON = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Free context menu
|
// Free context menu
|
||||||
free(contextMenu);
|
free(contextMenu);
|
||||||
}
|
}
|
||||||
@ -41,43 +57,6 @@ int freeContextMenu(void *const context, struct hashmap_element_s *const e) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessContextMenus(ContextMenuStore* store) {
|
|
||||||
|
|
||||||
// Decode the context menus JSON
|
|
||||||
store->processedContextMenus = json_decode(store->contextMenusAsJSON);
|
|
||||||
if( store->processedContextMenus == NULL ) {
|
|
||||||
ABORT("[ProcessContextMenus] Unable to parse Context Menus JSON: %s", store->contextMenusAsJSON);
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Get the context menu items
|
|
||||||
// JsonNode *contextMenuItems = json_find_member(store->processedContextMenus, "Items");
|
|
||||||
// if( contextMenuItems == NULL ) {
|
|
||||||
// ABORT("[ProcessContextMenus] Unable to find Items in processedContextMenus!");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Iterate context menus
|
|
||||||
JsonNode *contextMenu;
|
|
||||||
json_foreach(contextMenu, store->processedContextMenus) {
|
|
||||||
|
|
||||||
const char* ID = getJSONString(contextMenu, "ID");
|
|
||||||
if ( ID == NULL ) {
|
|
||||||
ABORT("Unable to read ID of contextMenu\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonNode* processedMenu = json_find_member(contextMenu, "ProcessedMenu");
|
|
||||||
if ( processedMenu == NULL ) {
|
|
||||||
ABORT("Unable to read ProcessedMenu of contextMenu\n");
|
|
||||||
}
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShowContextMenu(ContextMenuStore* store, id mainWindow, const char *contextMenuID, const char *contextMenuData) {
|
void ShowContextMenu(ContextMenuStore* store, id mainWindow, const char *contextMenuID, const char *contextMenuData) {
|
||||||
|
|
||||||
// If no context menu ID was given, abort
|
// If no context menu ID was given, abort
|
||||||
|
@ -14,17 +14,19 @@ typedef struct {
|
|||||||
id nsmenu;
|
id nsmenu;
|
||||||
Menu* menu;
|
Menu* menu;
|
||||||
|
|
||||||
// The optional data that may be passed with a context menu selection
|
JsonNode* processedJSON;
|
||||||
|
|
||||||
|
// Context menu data is given by the frontend when clicking a context menu.
|
||||||
|
// We send this to the backend when an item is selected
|
||||||
const char* contextMenuData;
|
const char* contextMenuData;
|
||||||
} ContextMenu;
|
} ContextMenu;
|
||||||
|
|
||||||
|
|
||||||
ContextMenu* NewContextMenu(JsonNode* menuData, ContextMenuStore* store);
|
ContextMenu* NewContextMenu(const char* contextMenuJSON);
|
||||||
|
|
||||||
ContextMenu* GetContextMenuByID( ContextMenuStore* store, const char *contextMenuID);
|
ContextMenu* GetContextMenuByID( ContextMenuStore* store, const char *contextMenuID);
|
||||||
void DeleteContextMenu(ContextMenu* contextMenu);
|
void DeleteContextMenu(ContextMenu* contextMenu);
|
||||||
int freeContextMenu(void *const context, struct hashmap_element_s *const e);
|
int freeContextMenu(void *const context, struct hashmap_element_s *const e);
|
||||||
void ProcessContextMenus( ContextMenuStore* store);
|
|
||||||
|
|
||||||
void ShowContextMenu(ContextMenuStore* store, id mainWindow, const char *contextMenuID, const char *contextMenuData);
|
void ShowContextMenu(ContextMenuStore* store, id mainWindow, const char *contextMenuID, const char *contextMenuData);
|
||||||
|
|
||||||
|
@ -2,22 +2,48 @@
|
|||||||
#include "contextmenus_darwin.h"
|
#include "contextmenus_darwin.h"
|
||||||
#include "contextmenustore_darwin.h"
|
#include "contextmenustore_darwin.h"
|
||||||
|
|
||||||
ContextMenuStore* NewContextMenuStore(const char* contextMenusAsJSON) {
|
ContextMenuStore* NewContextMenuStore() {
|
||||||
|
|
||||||
ContextMenuStore* result = malloc(sizeof(ContextMenuStore));
|
ContextMenuStore* result = malloc(sizeof(ContextMenuStore));
|
||||||
|
|
||||||
// Init members
|
|
||||||
result->contextMenusAsJSON = contextMenusAsJSON;
|
|
||||||
result->processedContextMenus = NULL;
|
|
||||||
|
|
||||||
// Allocate Context Menu Store
|
// Allocate Context Menu Store
|
||||||
if( 0 != hashmap_create((const unsigned)4, &result->contextMenuStore)) {
|
if( 0 != hashmap_create((const unsigned)4, &result->contextMenuMap)) {
|
||||||
ABORT("[NewContextMenus] Not enough memory to allocate contextMenuStore!");
|
ABORT("[NewContextMenus] Not enough memory to allocate contextMenuStore!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddContextMenuToStore(ContextMenuStore* store, const char* contextMenuJSON) {
|
||||||
|
ContextMenu* newMenu = NewContextMenu(contextMenuJSON);
|
||||||
|
|
||||||
|
//TODO: check if there is already an entry for this menu
|
||||||
|
hashmap_put(&store->contextMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextMenu* GetContextMenuFromStore(ContextMenuStore* store, const char* menuID) {
|
||||||
|
// Get the current menu
|
||||||
|
return hashmap_get(&store->contextMenuMap, menuID, strlen(menuID));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateContextMenuInStore(ContextMenuStore* store, const char* menuJSON) {
|
||||||
|
ContextMenu* newContextMenu = NewContextMenu(menuJSON);
|
||||||
|
|
||||||
|
// Get the current menu
|
||||||
|
ContextMenu *currentMenu = GetContextMenuFromStore(store, newContextMenu->ID);
|
||||||
|
if ( currentMenu == NULL ) {
|
||||||
|
ABORT("Attempted to update unknown context menu with ID '%s'.", newContextMenu->ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashmap_remove(&store->contextMenuMap, newContextMenu->ID, strlen(newContextMenu->ID));
|
||||||
|
|
||||||
|
// Save the status bar reference
|
||||||
|
DeleteContextMenu(currentMenu);
|
||||||
|
|
||||||
|
hashmap_put(&store->contextMenuMap, newContextMenu->ID, strlen(newContextMenu->ID), newContextMenu);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DeleteContextMenuStore(ContextMenuStore* store) {
|
void DeleteContextMenuStore(ContextMenuStore* store) {
|
||||||
|
|
||||||
@ -27,19 +53,13 @@ void DeleteContextMenuStore(ContextMenuStore* store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete context menus
|
// Delete context menus
|
||||||
if( hashmap_num_entries(&store->contextMenuStore) > 0 ) {
|
if( hashmap_num_entries(&store->contextMenuMap) > 0 ) {
|
||||||
if (0 != hashmap_iterate_pairs(&store->contextMenuStore, freeContextMenu, NULL)) {
|
if (0 != hashmap_iterate_pairs(&store->contextMenuMap, freeContextMenu, NULL)) {
|
||||||
ABORT("[DeleteContextMenuStore] Failed to release contextMenuStore entries!");
|
ABORT("[DeleteContextMenuStore] Failed to release contextMenuStore entries!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free context menu hashmap
|
// Free context menu hashmap
|
||||||
hashmap_destroy(&store->contextMenuStore);
|
hashmap_destroy(&store->contextMenuMap);
|
||||||
|
|
||||||
// Destroy processed Context Menus
|
|
||||||
if( store->processedContextMenus != NULL) {
|
|
||||||
json_delete(store->processedContextMenus);
|
|
||||||
store->processedContextMenus = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,19 +8,20 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
|
||||||
// This is our context menu store which keeps track
|
// This is our context menu store which keeps track
|
||||||
// of all instances of ContextMenus
|
// of all instances of ContextMenus
|
||||||
struct hashmap_s contextMenuStore;
|
struct hashmap_s contextMenuMap;
|
||||||
|
|
||||||
// The raw JSON defining the context menus
|
|
||||||
const char* contextMenusAsJSON;
|
|
||||||
|
|
||||||
// The processed context menus
|
|
||||||
JsonNode* processedContextMenus;
|
|
||||||
|
|
||||||
} ContextMenuStore;
|
} ContextMenuStore;
|
||||||
|
|
||||||
ContextMenuStore* NewContextMenuStore(const char* contextMenusAsJSON);
|
ContextMenuStore* NewContextMenuStore();
|
||||||
|
|
||||||
void DeleteContextMenuStore(ContextMenuStore* store);
|
void DeleteContextMenuStore(ContextMenuStore* store);
|
||||||
|
void UpdateContextMenuInStore(ContextMenuStore* store, const char* menuJSON);
|
||||||
|
|
||||||
|
void AddContextMenuToStore(ContextMenuStore* store, const char* contextMenuJSON);
|
||||||
|
|
||||||
#endif //CONTEXTMENUSTORE_DARWIN_H
|
#endif //CONTEXTMENUSTORE_DARWIN_H
|
||||||
|
@ -35,11 +35,9 @@ extern void SaveDialog(struct Application*, char *callbackID, char *title, char
|
|||||||
extern void MessageDialog(struct Application*, char *callbackID, char *type, char *title, char *message, char *icon, char *button1, char *button2, char *button3, char *button4, char *defaultButton, char *cancelButton);
|
extern void MessageDialog(struct Application*, char *callbackID, char *type, char *title, char *message, char *icon, char *button1, char *button2, char *button3, char *button4, char *defaultButton, char *cancelButton);
|
||||||
extern void DarkModeEnabled(struct Application*, char *callbackID);
|
extern void DarkModeEnabled(struct Application*, char *callbackID);
|
||||||
extern void SetApplicationMenu(struct Application*, const char *);
|
extern void SetApplicationMenu(struct Application*, const char *);
|
||||||
extern void UpdateTray(struct Application*, char *menuAsJSON);
|
extern void AddTrayMenu(struct Application*, const char *menuTrayJSON);
|
||||||
extern void UpdateContextMenus(struct Application*, char *contextMenusAsJSON);
|
extern void UpdateTrayMenu(struct Application*, const char *menuTrayJSON);
|
||||||
extern void UpdateTrayLabel(struct Application*, const char *label);
|
extern void AddContextMenu(struct Application*, char *contextMenuJSON);
|
||||||
extern void UpdateTrayIcon(struct Application*, const char *label);
|
extern void UpdateContextMenu(struct Application*, char *contextMenuJSON);
|
||||||
extern void AddTrayMenu(struct Application*, const char *trayAsJSON);
|
|
||||||
extern void UpdateTrayMenu(struct Application*, const char *trayAsJSON);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,7 +12,6 @@ package ffenestri
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
@ -193,17 +192,6 @@ func (c *Client) UpdateTrayMenu(trayMenuJSON string) {
|
|||||||
C.UpdateTrayMenu(c.app.app, c.app.string2CString(trayMenuJSON))
|
C.UpdateTrayMenu(c.app.app, c.app.string2CString(trayMenuJSON))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) UpdateContextMenus(contextMenus *menu.ContextMenus) {
|
func (c *Client) UpdateContextMenu(contextMenuJSON string) {
|
||||||
//
|
C.UpdateContextMenu(c.app.app, c.app.string2CString(contextMenuJSON))
|
||||||
// // Guard against nil contextMenus
|
|
||||||
// if contextMenus == nil {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// // Process the menu
|
|
||||||
// contextMenusJSON, err := processContextMenus(contextMenus)
|
|
||||||
// if err != nil {
|
|
||||||
// c.app.logger.Error("Error processing updated Context Menu: %s", err.Error())
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// C.UpdateContextMenus(c.app.app, c.app.string2CString(contextMenusJSON))
|
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,6 @@ struct Application {
|
|||||||
|
|
||||||
// Context Menus
|
// Context Menus
|
||||||
ContextMenuStore *contextMenuStore;
|
ContextMenuStore *contextMenuStore;
|
||||||
const char *contextMenusAsJSON;
|
|
||||||
JsonNode *processedContextMenus;
|
|
||||||
|
|
||||||
// Callback
|
// Callback
|
||||||
ffenestriCallback sendMessageToBackend;
|
ffenestriCallback sendMessageToBackend;
|
||||||
@ -427,9 +425,12 @@ void DestroyApplication(struct Application *app) {
|
|||||||
DeleteMenu(app->applicationMenu);
|
DeleteMenu(app->applicationMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the tray menu store
|
// Delete the tray menu store
|
||||||
DeleteTrayMenuStore(app->trayMenuStore);
|
DeleteTrayMenuStore(app->trayMenuStore);
|
||||||
|
|
||||||
|
// Delete the context menu store
|
||||||
|
DeleteContextMenuStore(app->contextMenuStore);
|
||||||
|
|
||||||
// Destroy the context menus
|
// Destroy the context menus
|
||||||
destroyContextMenus(app);
|
destroyContextMenus(app);
|
||||||
|
|
||||||
@ -439,11 +440,6 @@ void DestroyApplication(struct Application *app) {
|
|||||||
// Unload the tray Icons
|
// Unload the tray Icons
|
||||||
UnloadTrayIcons();
|
UnloadTrayIcons();
|
||||||
|
|
||||||
// Clear context menu data if we have it
|
|
||||||
if( contextMenuData != NULL ) {
|
|
||||||
MEMFREE(contextMenuData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove script handlers
|
// Remove script handlers
|
||||||
msg(app->manager, s("removeScriptMessageHandlerForName:"), str("contextMenu"));
|
msg(app->manager, s("removeScriptMessageHandlerForName:"), str("contextMenu"));
|
||||||
msg(app->manager, s("removeScriptMessageHandlerForName:"), str("windowDrag"));
|
msg(app->manager, s("removeScriptMessageHandlerForName:"), str("windowDrag"));
|
||||||
@ -916,17 +912,20 @@ void SetDebug(void *applicationPointer, int flag) {
|
|||||||
|
|
||||||
|
|
||||||
// SetContextMenus sets the context menu map for this application
|
// SetContextMenus sets the context menu map for this application
|
||||||
void SetContextMenus(struct Application *app, const char *contextMenusAsJSON) {
|
void AddContextMenu(struct Application *app, const char *contextMenuJSON) {
|
||||||
app->contextMenuStore = NewContextMenuStore(contextMenusAsJSON);
|
AddContextMenuToStore(app->contextMenuStore, contextMenuJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateContextMenu(struct Application *app, const char* contextMenuJSON) {
|
||||||
void AddTrayMenu(struct Application *app, const char *trayJSON) {
|
UpdateContextMenuInStore(app->contextMenuStore, contextMenuJSON);
|
||||||
AddTrayMenuToStore(app->trayMenuStore, trayJSON);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateTrayMenu(struct Application *app, const char* trayJSON) {
|
void AddTrayMenu(struct Application *app, const char *trayMenuJSON) {
|
||||||
UpdateTrayMenuInStore(app->trayMenuStore, trayJSON);
|
AddTrayMenuToStore(app->trayMenuStore, trayMenuJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateTrayMenu(struct Application *app, const char* trayMenuJSON) {
|
||||||
|
UpdateTrayMenuInStore(app->trayMenuStore, trayMenuJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBindings(struct Application *app, const char *bindings) {
|
void SetBindings(struct Application *app, const char *bindings) {
|
||||||
@ -1428,84 +1427,6 @@ void SetApplicationMenu(struct Application *app, const char *menuAsJSON) {
|
|||||||
updateMenu(app, menuAsJSON);
|
updateMenu(app, menuAsJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void dumpContextMenus(struct Application *app) {
|
|
||||||
// dumpHashmap("menuItemMapForContextMenus", &menuItemMapForContextMenus);
|
|
||||||
// printf("&menuItemMapForContextMenus = %p\n", &menuItemMapForContextMenus);
|
|
||||||
//
|
|
||||||
// //Free radio groups hashmap
|
|
||||||
// dumpHashmap("radioGroupMapForContextMenus", &radioGroupMapForContextMenus);
|
|
||||||
// printf("&radioGroupMapForContextMenus = %p\n", &radioGroupMapForContextMenus);
|
|
||||||
//
|
|
||||||
// //Free context menu map
|
|
||||||
// dumpHashmap("contextMenuMap", &contextMenuMap);
|
|
||||||
// printf("&contextMenuMap = %p\n", &contextMenuMap);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//void parseContextMenus(struct Application *app) {
|
|
||||||
//
|
|
||||||
// // Parse the context menu json
|
|
||||||
// app->processedContextMenus = json_decode(app->contextMenusAsJSON);
|
|
||||||
//
|
|
||||||
// if( app->processedContextMenus == NULL ) {
|
|
||||||
// // Parse error!
|
|
||||||
// Fatal(app, "Unable to parse Context Menus JSON: %s", app->contextMenusAsJSON);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// JsonNode *contextMenuItems = json_find_member(app->processedContextMenus, "Items");
|
|
||||||
// if( contextMenuItems == NULL ) {
|
|
||||||
// // Parse error!
|
|
||||||
// Fatal(app, "Unable to find Items:", app->processedContextMenus);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // Iterate context menus
|
|
||||||
// JsonNode *contextMenu;
|
|
||||||
// json_foreach(contextMenu, contextMenuItems) {
|
|
||||||
// // Create a new menu
|
|
||||||
// id menu = createMenu(str(""));
|
|
||||||
//
|
|
||||||
// // parse the menu
|
|
||||||
// parseMenu(app, menu, contextMenu, &menuItemMapForContextMenus,
|
|
||||||
// "checkboxMenuCallbackForContextMenus:", "radioMenuCallbackForContextMenus:", "menuCallbackForContextMenus:");
|
|
||||||
//
|
|
||||||
// // Store the item in the context menu map
|
|
||||||
// hashmap_put(&contextMenuMap, (char*)contextMenu->key, strlen(contextMenu->key), menu);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//// dumpContextMenus(app);
|
|
||||||
//}
|
|
||||||
|
|
||||||
void UpdateTrayLabel(struct Application *app, const char *label) {
|
|
||||||
// TBD
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateTrayIcon(struct Application *app, const char *name) {
|
|
||||||
// TBD
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateTray replaces the current tray menu with the given one
|
|
||||||
void UpdateTray(struct Application *app, const char *trayMenuAsJSON) {
|
|
||||||
ON_MAIN_THREAD (
|
|
||||||
// TBD
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateContextMenus(struct Application *app, const char *contextMenusAsJSON) {
|
|
||||||
|
|
||||||
ON_MAIN_THREAD (
|
|
||||||
|
|
||||||
// Free up memory
|
|
||||||
DeleteContextMenuStore(app->contextMenuStore);
|
|
||||||
|
|
||||||
// Recreate Context Menus
|
|
||||||
app->contextMenuStore = NewContextMenuStore(contextMenusAsJSON);
|
|
||||||
|
|
||||||
// Process them
|
|
||||||
ProcessContextMenus(app->contextMenuStore);
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void processDialogIcons(struct hashmap_s *hashmap, const unsigned char *dialogIcons[]) {
|
void processDialogIcons(struct hashmap_s *hashmap, const unsigned char *dialogIcons[]) {
|
||||||
|
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
@ -1727,11 +1648,6 @@ void Run(struct Application *app, int argc, char **argv) {
|
|||||||
// Setup initial trays
|
// Setup initial trays
|
||||||
ShowTrayMenusInStore(app->trayMenuStore);
|
ShowTrayMenusInStore(app->trayMenuStore);
|
||||||
|
|
||||||
// If we have context menus, process them
|
|
||||||
if( app->contextMenuStore != NULL ) {
|
|
||||||
ProcessContextMenus(app->contextMenuStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process dialog icons
|
// Process dialog icons
|
||||||
processUserDialogIcons(app);
|
processUserDialogIcons(app);
|
||||||
|
|
||||||
@ -1793,10 +1709,7 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
|
|||||||
result->trayMenuStore = NewTrayMenuStore();
|
result->trayMenuStore = NewTrayMenuStore();
|
||||||
|
|
||||||
// Context Menus
|
// Context Menus
|
||||||
result->contextMenuStore = NULL;
|
result->contextMenuStore = NewContextMenuStore();
|
||||||
result->contextMenusAsJSON = NULL;
|
|
||||||
result->processedContextMenus = NULL;
|
|
||||||
contextMenuData = NULL;
|
|
||||||
|
|
||||||
// Window Appearance
|
// Window Appearance
|
||||||
result->titlebarAppearsTransparent = 0;
|
result->titlebarAppearsTransparent = 0;
|
||||||
|
@ -72,20 +72,20 @@ func (a *Application) processPlatformSettings() error {
|
|||||||
}
|
}
|
||||||
if trays != nil {
|
if trays != nil {
|
||||||
for _, tray := range trays {
|
for _, tray := range trays {
|
||||||
println("Adding tray menu: " + tray)
|
|
||||||
C.AddTrayMenu(a.app, a.string2CString(tray))
|
C.AddTrayMenu(a.app, a.string2CString(tray))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process context menus
|
// Process context menus
|
||||||
//contextMenus := options.GetContextMenus(a.config)
|
contextMenus, err := a.menuManager.GetContextMenus()
|
||||||
//if contextMenus != nil {
|
if err != nil {
|
||||||
// contextMenusJSON, err := processContextMenus(contextMenus)
|
return err
|
||||||
// if err != nil {
|
}
|
||||||
// return err
|
if contextMenus != nil {
|
||||||
// }
|
for _, contextMenu := range contextMenus {
|
||||||
// C.SetContextMenus(a.app, a.string2CString(contextMenusJSON))
|
C.AddContextMenu(a.app, a.string2CString(contextMenu))
|
||||||
//}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@ void DumpTrayMenuStore(TrayMenuStore* store) {
|
|||||||
|
|
||||||
void AddTrayMenuToStore(TrayMenuStore* store, const char* menuJSON) {
|
void AddTrayMenuToStore(TrayMenuStore* store, const char* menuJSON) {
|
||||||
TrayMenu* newMenu = NewTrayMenu(menuJSON);
|
TrayMenu* newMenu = NewTrayMenu(menuJSON);
|
||||||
|
|
||||||
|
//TODO: check if there is already an entry for this menu
|
||||||
hashmap_put(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu);
|
hashmap_put(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,60 @@
|
|||||||
package menumanager
|
package menumanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContextMenu struct {
|
type ContextMenu struct {
|
||||||
ID string
|
ID string
|
||||||
JSON string
|
ProcessedMenu *WailsMenu
|
||||||
menuItemMap *MenuItemMap
|
menuItemMap *MenuItemMap
|
||||||
menu *menu.Menu
|
menu *menu.Menu
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContextMenu(ID string, menu *menu.Menu) *ContextMenu {
|
func (t *ContextMenu) AsJSON() (string, error) {
|
||||||
|
data, err := json.Marshal(t)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewContextMenu(contextMenu *menu.ContextMenu) *ContextMenu {
|
||||||
|
|
||||||
result := &ContextMenu{
|
result := &ContextMenu{
|
||||||
ID: ID,
|
ID: contextMenu.ID,
|
||||||
JSON: "",
|
menu: contextMenu.Menu,
|
||||||
menu: menu,
|
|
||||||
menuItemMap: NewMenuItemMap(),
|
menuItemMap: NewMenuItemMap(),
|
||||||
}
|
}
|
||||||
|
|
||||||
result.menuItemMap.AddMenu(menu)
|
result.menuItemMap.AddMenu(contextMenu.Menu)
|
||||||
|
result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) AddContextMenu(menuID string, menu *menu.Menu) error {
|
func (m *Manager) AddContextMenu(contextMenu *menu.ContextMenu) {
|
||||||
contextMenu := NewContextMenu(menuID, menu)
|
|
||||||
m.contextMenus[menuID] = contextMenu
|
newContextMenu := NewContextMenu(contextMenu)
|
||||||
return contextMenu.process()
|
|
||||||
|
// Save the references
|
||||||
|
m.contextMenus[contextMenu.ID] = newContextMenu
|
||||||
|
m.contextMenuPointers[contextMenu] = contextMenu.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ContextMenu) process() error {
|
func (m *Manager) UpdateContextMenu(contextMenu *menu.ContextMenu) (string, error) {
|
||||||
|
contextMenuID, contextMenuKnown := m.contextMenuPointers[contextMenu]
|
||||||
// Process the menu
|
if !contextMenuKnown {
|
||||||
processedApplicationMenu := NewWailsMenu(c.menuItemMap, c.menu)
|
return "", fmt.Errorf("unknown Context Menu '%s'. Please add the context menu using AddContextMenu()", contextMenu.ID)
|
||||||
JSON, err := processedApplicationMenu.AsJSON()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
c.JSON = JSON
|
|
||||||
fmt.Printf("Processed context menu '%s':", c.ID)
|
// Create the updated context menu
|
||||||
println(JSON)
|
updatedContextMenu := NewContextMenu(contextMenu)
|
||||||
return nil
|
|
||||||
|
// Save the reference
|
||||||
|
m.contextMenus[contextMenuID] = updatedContextMenu
|
||||||
|
|
||||||
|
return updatedContextMenu.AsJSON()
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ type Manager struct {
|
|||||||
applicationMenuItemMap *MenuItemMap
|
applicationMenuItemMap *MenuItemMap
|
||||||
|
|
||||||
// Context menus
|
// Context menus
|
||||||
contextMenus map[string]*ContextMenu
|
contextMenus map[string]*ContextMenu
|
||||||
|
contextMenuPointers map[*menu.ContextMenu]string
|
||||||
|
|
||||||
// Tray menu stores
|
// Tray menu stores
|
||||||
trayMenus map[string]*TrayMenu
|
trayMenus map[string]*TrayMenu
|
||||||
@ -26,6 +27,7 @@ func NewManager() *Manager {
|
|||||||
return &Manager{
|
return &Manager{
|
||||||
applicationMenuItemMap: NewMenuItemMap(),
|
applicationMenuItemMap: NewMenuItemMap(),
|
||||||
contextMenus: make(map[string]*ContextMenu),
|
contextMenus: make(map[string]*ContextMenu),
|
||||||
|
contextMenuPointers: make(map[*menu.ContextMenu]string),
|
||||||
trayMenus: make(map[string]*TrayMenu),
|
trayMenus: make(map[string]*TrayMenu),
|
||||||
trayMenuPointers: make(map[*menu.TrayMenu]string),
|
trayMenuPointers: make(map[*menu.TrayMenu]string),
|
||||||
}
|
}
|
||||||
|
@ -90,3 +90,16 @@ func (m *Manager) GetTrayMenus() ([]string, error) {
|
|||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetContextMenus() ([]string, error) {
|
||||||
|
result := []string{}
|
||||||
|
for _, contextMenu := range m.contextMenus {
|
||||||
|
JSON, err := contextMenu.AsJSON()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result = append(result, JSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
@ -2,8 +2,6 @@ package messagedispatcher
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
||||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||||
@ -33,8 +31,8 @@ type Client interface {
|
|||||||
WindowSetColour(colour int)
|
WindowSetColour(colour int)
|
||||||
DarkModeEnabled(callbackID string)
|
DarkModeEnabled(callbackID string)
|
||||||
SetApplicationMenu(menuJSON string)
|
SetApplicationMenu(menuJSON string)
|
||||||
UpdateTrayMenu(menuJSON string)
|
UpdateTrayMenu(trayMenuJSON string)
|
||||||
UpdateContextMenus(contextMenus *menu.ContextMenus)
|
UpdateContextMenu(contextMenuJSON string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DispatchClient is what the frontends use to interface with the
|
// DispatchClient is what the frontends use to interface with the
|
||||||
|
@ -2,7 +2,6 @@ package messagedispatcher
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -17,15 +16,14 @@ import (
|
|||||||
// Dispatcher translates messages received from the frontend
|
// Dispatcher translates messages received from the frontend
|
||||||
// and publishes them onto the service bus
|
// and publishes them onto the service bus
|
||||||
type Dispatcher struct {
|
type Dispatcher struct {
|
||||||
quitChannel <-chan *servicebus.Message
|
quitChannel <-chan *servicebus.Message
|
||||||
resultChannel <-chan *servicebus.Message
|
resultChannel <-chan *servicebus.Message
|
||||||
eventChannel <-chan *servicebus.Message
|
eventChannel <-chan *servicebus.Message
|
||||||
windowChannel <-chan *servicebus.Message
|
windowChannel <-chan *servicebus.Message
|
||||||
dialogChannel <-chan *servicebus.Message
|
dialogChannel <-chan *servicebus.Message
|
||||||
systemChannel <-chan *servicebus.Message
|
systemChannel <-chan *servicebus.Message
|
||||||
menuChannel <-chan *servicebus.Message
|
menuChannel <-chan *servicebus.Message
|
||||||
contextMenuChannel <-chan *servicebus.Message
|
running bool
|
||||||
running bool
|
|
||||||
|
|
||||||
servicebus *servicebus.ServiceBus
|
servicebus *servicebus.ServiceBus
|
||||||
logger logger.CustomLogger
|
logger logger.CustomLogger
|
||||||
@ -77,23 +75,17 @@ func New(servicebus *servicebus.ServiceBus, logger *logger.Logger) (*Dispatcher,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMenuChannel, err := servicebus.Subscribe("contextmenufrontend:")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := &Dispatcher{
|
result := &Dispatcher{
|
||||||
servicebus: servicebus,
|
servicebus: servicebus,
|
||||||
eventChannel: eventChannel,
|
eventChannel: eventChannel,
|
||||||
logger: logger.CustomLogger("Message Dispatcher"),
|
logger: logger.CustomLogger("Message Dispatcher"),
|
||||||
clients: make(map[string]*DispatchClient),
|
clients: make(map[string]*DispatchClient),
|
||||||
resultChannel: resultChannel,
|
resultChannel: resultChannel,
|
||||||
quitChannel: quitChannel,
|
quitChannel: quitChannel,
|
||||||
windowChannel: windowChannel,
|
windowChannel: windowChannel,
|
||||||
dialogChannel: dialogChannel,
|
dialogChannel: dialogChannel,
|
||||||
systemChannel: systemChannel,
|
systemChannel: systemChannel,
|
||||||
menuChannel: menuChannel,
|
menuChannel: menuChannel,
|
||||||
contextMenuChannel: contextMenuChannel,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
@ -125,8 +117,6 @@ func (d *Dispatcher) Start() error {
|
|||||||
d.processSystemMessage(systemMessage)
|
d.processSystemMessage(systemMessage)
|
||||||
case menuMessage := <-d.menuChannel:
|
case menuMessage := <-d.menuChannel:
|
||||||
d.processMenuMessage(menuMessage)
|
d.processMenuMessage(menuMessage)
|
||||||
case contextMenuMessage := <-d.contextMenuChannel:
|
|
||||||
d.processContextMenuMessage(contextMenuMessage)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,25 +458,10 @@ func (d *Dispatcher) processMenuMessage(result *servicebus.Message) {
|
|||||||
for _, client := range d.clients {
|
for _, client := range d.clients {
|
||||||
client.frontend.UpdateTrayMenu(updatedTrayMenu)
|
client.frontend.UpdateTrayMenu(updatedTrayMenu)
|
||||||
}
|
}
|
||||||
|
case "updatecontextmenu":
|
||||||
default:
|
updatedContextMenu, ok := result.Data().(string)
|
||||||
d.logger.Error("Unknown menufrontend command: %s", command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (d *Dispatcher) processContextMenuMessage(result *servicebus.Message) {
|
|
||||||
splitTopic := strings.Split(result.Topic(), ":")
|
|
||||||
if len(splitTopic) < 2 {
|
|
||||||
d.logger.Error("Invalid contextmenu message : %#v", result.Data())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
command := splitTopic[1]
|
|
||||||
switch command {
|
|
||||||
case "update":
|
|
||||||
|
|
||||||
updatedContextMenus, ok := result.Data().(*menu.ContextMenus)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
d.logger.Error("Invalid data for 'contextmenufrontend:update' : %#v",
|
d.logger.Error("Invalid data for 'menufrontend:updatecontextmenu' : %#v",
|
||||||
result.Data())
|
result.Data())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -494,10 +469,10 @@ func (d *Dispatcher) processContextMenuMessage(result *servicebus.Message) {
|
|||||||
// TODO: Work out what we mean in a multi window environment...
|
// TODO: Work out what we mean in a multi window environment...
|
||||||
// For now we will just pick the first one
|
// For now we will just pick the first one
|
||||||
for _, client := range d.clients {
|
for _, client := range d.clients {
|
||||||
client.frontend.UpdateContextMenus(updatedContextMenus)
|
client.frontend.UpdateContextMenu(updatedContextMenu)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
d.logger.Error("Unknown contextmenufrontend command: %s", command)
|
d.logger.Error("Unknown menufrontend command: %s", command)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,16 +110,16 @@ func (m *Menu) Start() error {
|
|||||||
m.bus.Publish("menufrontend:updateappmenu", updatedMenu)
|
m.bus.Publish("menufrontend:updateappmenu", updatedMenu)
|
||||||
|
|
||||||
case "updatecontextmenu":
|
case "updatecontextmenu":
|
||||||
m.logger.Info("Update Context Menu TBD")
|
contextMenu := menuMessage.Data().(*menu.ContextMenu)
|
||||||
//contextMenu := menuMessage.Data().(*menu.ContextMenu)
|
updatedMenu, err := m.menuManager.UpdateContextMenu(contextMenu)
|
||||||
//updatedMenu, err := m.menuManager.UpdateContextMenu(contextMenu)
|
if err != nil {
|
||||||
//if err != nil {
|
m.logger.Trace("%s", err.Error())
|
||||||
// m.logger.Trace("%s", err.Error())
|
return
|
||||||
// return
|
}
|
||||||
//}
|
|
||||||
//
|
// Notify frontend of menu change
|
||||||
//// Notify frontend of menu change
|
m.bus.Publish("menufrontend:updatecontextmenu", updatedMenu)
|
||||||
//m.bus.Publish("menufrontend:updatecontextmenu", updatedMenu)
|
|
||||||
case "updatetraymenu":
|
case "updatetraymenu":
|
||||||
trayMenu := menuMessage.Data().(*menu.TrayMenu)
|
trayMenu := menuMessage.Data().(*menu.TrayMenu)
|
||||||
updatedMenu, err := m.menuManager.UpdateTrayMenu(trayMenu)
|
updatedMenu, err := m.menuManager.UpdateTrayMenu(trayMenu)
|
||||||
|
@ -1,19 +1,5 @@
|
|||||||
package menu
|
package menu
|
||||||
|
|
||||||
type ContextMenus struct {
|
|
||||||
Items map[string]*Menu
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewContextMenus() *ContextMenus {
|
|
||||||
return &ContextMenus{
|
|
||||||
Items: make(map[string]*Menu),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ContextMenus) AddMenu(ID string, menu *Menu) {
|
|
||||||
c.Items[ID] = menu
|
|
||||||
}
|
|
||||||
|
|
||||||
type ContextMenu struct {
|
type ContextMenu struct {
|
||||||
ID string
|
ID string
|
||||||
Menu *Menu
|
Menu *Menu
|
||||||
|
@ -10,5 +10,5 @@ type Options struct {
|
|||||||
WindowBackgroundIsTranslucent bool
|
WindowBackgroundIsTranslucent bool
|
||||||
Menu *menu.Menu
|
Menu *menu.Menu
|
||||||
TrayMenus []*menu.TrayMenu
|
TrayMenus []*menu.TrayMenu
|
||||||
ContextMenus *menu.ContextMenus
|
ContextMenus []*menu.ContextMenu
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ type App struct {
|
|||||||
StartHidden bool
|
StartHidden bool
|
||||||
DevTools bool
|
DevTools bool
|
||||||
RGBA int
|
RGBA int
|
||||||
ContextMenus *menu.ContextMenus
|
ContextMenus []*menu.ContextMenu
|
||||||
TrayMenus []*menu.TrayMenu
|
TrayMenus []*menu.TrayMenu
|
||||||
Menu *menu.Menu
|
Menu *menu.Menu
|
||||||
Mac *mac.Options
|
Mac *mac.Options
|
||||||
@ -89,15 +89,13 @@ func GetApplicationMenu(appoptions *App) *menu.Menu {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetContextMenus(appoptions *App) *menu.ContextMenus {
|
func GetContextMenus(appoptions *App) []*menu.ContextMenu {
|
||||||
var result *menu.ContextMenus
|
var result []*menu.ContextMenu
|
||||||
|
|
||||||
result = appoptions.ContextMenus
|
|
||||||
var contextMenuOverrides *menu.ContextMenus
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "darwin":
|
case "darwin":
|
||||||
if appoptions.Mac != nil {
|
if appoptions.Mac != nil {
|
||||||
contextMenuOverrides = appoptions.Mac.ContextMenus
|
result = appoptions.Mac.ContextMenus
|
||||||
}
|
}
|
||||||
//case "linux":
|
//case "linux":
|
||||||
// if appoptions.Linux != nil {
|
// if appoptions.Linux != nil {
|
||||||
@ -109,11 +107,8 @@ func GetContextMenus(appoptions *App) *menu.ContextMenus {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite defaults with OS Specific context menus
|
if result == nil {
|
||||||
if contextMenuOverrides != nil {
|
result = appoptions.ContextMenus
|
||||||
for id, contextMenu := range contextMenuOverrides.Items {
|
|
||||||
result.AddMenu(id, contextMenu)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
"github.com/wailsapp/wails/v2"
|
||||||
@ -9,9 +10,11 @@ import (
|
|||||||
|
|
||||||
// ContextMenu struct
|
// ContextMenu struct
|
||||||
type ContextMenu struct {
|
type ContextMenu struct {
|
||||||
runtime *wails.Runtime
|
runtime *wails.Runtime
|
||||||
counter int
|
counter int
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
testContextMenu *menu.ContextMenu
|
||||||
|
clickedMenu *menu.MenuItem
|
||||||
}
|
}
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
// WailsInit is called at application startup
|
||||||
@ -22,10 +25,19 @@ func (c *ContextMenu) WailsInit(runtime *wails.Runtime) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createContextMenus() *menu.ContextMenus {
|
// Setup Menu Listeners
|
||||||
result := menu.NewContextMenus()
|
func (c *ContextMenu) updateContextMenu(_ *menu.CallbackData) {
|
||||||
result.AddMenu("test", menu.NewMenuFromItems(
|
c.lock.Lock()
|
||||||
menu.Text("Clicked 0 times", nil, nil),
|
c.counter++
|
||||||
|
c.clickedMenu.Label = fmt.Sprintf("Clicked %d times", c.counter)
|
||||||
|
c.lock.Unlock()
|
||||||
|
c.runtime.Menu.UpdateContextMenu(c.testContextMenu)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ContextMenu) createContextMenus() []*menu.ContextMenu {
|
||||||
|
c.clickedMenu = menu.Text("Clicked 0 times", nil, c.updateContextMenu)
|
||||||
|
c.testContextMenu = menu.NewContextMenu("test", menu.NewMenuFromItems(
|
||||||
|
c.clickedMenu,
|
||||||
menu.Separator(),
|
menu.Separator(),
|
||||||
menu.Checkbox("I am a checkbox", false, nil, nil),
|
menu.Checkbox("I am a checkbox", false, nil, nil),
|
||||||
menu.Separator(),
|
menu.Separator(),
|
||||||
@ -37,5 +49,7 @@ func createContextMenus() *menu.ContextMenus {
|
|||||||
menu.Text("Hello", nil, nil),
|
menu.Text("Hello", nil, nil),
|
||||||
)),
|
)),
|
||||||
))
|
))
|
||||||
return result
|
return []*menu.ContextMenu{
|
||||||
|
c.testContextMenu,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ func main() {
|
|||||||
|
|
||||||
Menu := &Menu{}
|
Menu := &Menu{}
|
||||||
Tray := &Tray{}
|
Tray := &Tray{}
|
||||||
|
ContextMenu := &ContextMenu{}
|
||||||
|
|
||||||
// Create application with options
|
// Create application with options
|
||||||
app, err := wails.CreateAppWithOptions(&options.App{
|
app, err := wails.CreateAppWithOptions(&options.App{
|
||||||
@ -23,7 +24,7 @@ func main() {
|
|||||||
//Tray: menu.NewMenuFromItems(menu.AppMenu()),
|
//Tray: menu.NewMenuFromItems(menu.AppMenu()),
|
||||||
//Menu: menu.NewMenuFromItems(menu.AppMenu()),
|
//Menu: menu.NewMenuFromItems(menu.AppMenu()),
|
||||||
//StartHidden: true,
|
//StartHidden: true,
|
||||||
ContextMenus: createContextMenus(),
|
ContextMenus: ContextMenu.createContextMenus(),
|
||||||
Mac: &mac.Options{
|
Mac: &mac.Options{
|
||||||
WebviewIsTransparent: true,
|
WebviewIsTransparent: true,
|
||||||
WindowBackgroundIsTranslucent: true,
|
WindowBackgroundIsTranslucent: true,
|
||||||
@ -47,7 +48,7 @@ func main() {
|
|||||||
app.Bind(&Window{})
|
app.Bind(&Window{})
|
||||||
app.Bind(Menu)
|
app.Bind(Menu)
|
||||||
app.Bind(Tray)
|
app.Bind(Tray)
|
||||||
app.Bind(&ContextMenu{})
|
app.Bind(ContextMenu)
|
||||||
|
|
||||||
err = app.Run()
|
err = app.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user