5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-04 23:11:53 +08:00
wails/v2/internal/ffenestri/contextmenus_darwin.h
2021-01-11 07:03:59 +11:00

253 lines
7.1 KiB
C

////
//// Created by Lea Anthony on 6/1/21.
////
//
#ifndef CONTEXTMENU_DARWIN_H
#define CONTEXTMENU_DARWIN_H
#include "common.h"
#include "menu_darwin.h"
#include "contextmenustore_darwin.h"
typedef struct {
const char* ID;
id nsmenu;
Menu* menu;
} ContextMenu;
ContextMenu* NewContextMenu(JsonNode* menuData, ContextMenuStore *store) {
ContextMenu* result = malloc(sizeof(ContextMenu));
result->menu = NewMenu(menuData);
result->nsmenu = NULL;
result->menu->menuType = ContextMenuType;
result->menu->parentData = store;
return result;
}
ContextMenuStore* NewContextMenuStore(const char* contextMenusAsJSON) {
ContextMenuStore* result = malloc(sizeof(ContextMenuStore));
// Init members
result->contextMenusAsJSON = contextMenusAsJSON;
result->processedContextMenus = NULL;
result->contextMenuData = NULL;
// Allocate Context Menu Store
if( 0 != hashmap_create((const unsigned)4, &result->contextMenuStore)) {
ABORT("[NewContextMenus] Not enough memory to allocate contextMenuStore!");
}
return result;
}
ContextMenu* GetContextMenuByID(ContextMenuStore* store, const char *contextMenuID) {
return (ContextMenu*)hashmap_get(&store->contextMenuStore, (char*)contextMenuID, strlen(contextMenuID));
}
void DeleteContextMenu(ContextMenu* contextMenu) {
// Free Menu
DeleteMenu(contextMenu->menu);
// Free context menu
free(contextMenu);
}
int freeContextMenu(void *const context, struct hashmap_element_s *const e) {
DeleteContextMenu(e->data);
return -1;
}
void DeleteContextMenuStore(ContextMenuStore* store) {
// Guard against NULLs
if( store == NULL ) {
return;
}
// Delete context menus
if( hashmap_num_entries(&store->contextMenuStore) > 0 ) {
if (0 != hashmap_iterate_pairs(&store->contextMenuStore, freeContextMenu, NULL)) {
ABORT("[DeleteContextMenuStore] Failed to release contextMenuStore entries!");
}
}
// Free context menu hashmap
hashmap_destroy(&store->contextMenuStore);
// Destroy processed Context Menus
if( store->processedContextMenus != NULL) {
json_delete(store->processedContextMenus);
store->processedContextMenus = NULL;
}
// Delete any context menu data we may have stored
if( store->contextMenuData != NULL ) {
MEMFREE(store->contextMenuData);
}
}
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);
// Store the item in the context menu map
hashmap_put(&store->contextMenuStore, (char*)ID, strlen(ID), thisContextMenu);
}
}
//
//
//bool ContextMenuExists(ContextMenus *contextMenus, const char* contextMenuID) {
// return hashmap_get(&contextMenus->contextMenuStore, contextMenuID, strlen(contextMenuID)) != NULL;
//}
//
//bool AddContextMenu(ContextMenu* contextMenu) {
//
// // Check if we already have this
// if( ContextMenuExists(contextMenu->ID) ) {
// return false;
// }
//
// // Store the context menu
// if (0 != hashmap_put(&contextMenus->contextMenuStore, contextMenu->ID, strlen(contextMenu->ID), contextMenu)) {
// ABORT("Unable to add context menu with ID '%s'", contextMenu->ID);
// }
//
// return true;
//}
//
//ContextMenus* NewContextMenus(const char* contextMenusAsJSON) {
//
// ContextMenus* result = malloc(sizeof(ContextMenus));
//
// // Allocate Context Menu Store
// if( 0 != hashmap_create((const unsigned)4, &result->contextMenuStore)) {
// ABORT("[NewContextMenus] Not enough memory to allocate contextMenuStore!");
// }
//
// //
//
// return result;
//}
//
//void ProcessContextMenus() {
// // Parse the context menu json
// processedContextMenus = json_decode(contextMenusAsJSON);
// if( processedContextMenus == NULL ) {
// // Parse error!
// ABORT("Unable to parse Context Menus JSON: %s", contextMenusAsJSON);
// }
//
// JsonNode *contextMenuItems = json_find_member(processedContextMenus, "Items");
// if( contextMenuItems == NULL ) {
// // Parse error!
// ABORT("Unable to find Items in Context menus");
// }
// // Iterate context menus
// JsonNode *contextMenu;
// json_foreach(contextMenu, contextMenuItems) {
// Menu *contextMenu = NewMenu()
//
// // Store the item in the context menu map
// hashmap_put(&contextMenuMap, (char*)contextMenu->key, strlen(contextMenu->key), menu);
// }
//
//}
//
//ContextMenu* NewContextMenu() {
// ContextMenu* result = malloc(sizeof(ContextMenu));
//
// result->menu = NewMenu(contextMenuAsJSON);
//
// return result;
//}
//
//
//void InitContextMenuStore() {
//
//}
//
//
//void DeleteContextMenuStore() {
// // Free radio group members
// if( hashmap_num_entries(&contextMenuStore) > 0 ) {
// if (0 != hashmap_iterate_pairs(&contextMenuStore, freeContextMenu, NULL)) {
// ABORT("[DeleteContextMenuStore] Failed to release contextMenuStore entries!");
// }
// }
//}
//
void ShowContextMenu(ContextMenuStore* store, id mainWindow, const char *contextMenuID, const char *contextMenuData) {
// If no context menu ID was given, abort
if( contextMenuID == NULL ) {
return;
}
ContextMenu* contextMenu = GetContextMenuByID(store, contextMenuID);
// We don't need the ID now
MEMFREE(contextMenuID);
if( contextMenu == NULL ) {
// Free context menu data
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);
// Grab the content view and show the menu
id contentView = msg(mainWindow, s("contentView"));
// Get the triggering event
id menuEvent = msg(mainWindow, s("currentEvent"));
if( contextMenu->nsmenu == NULL ) {
// GetMenu creates the NSMenu
contextMenu->nsmenu = GetMenu(contextMenu->menu);
}
// Show popup
msg(c("NSMenu"), s("popUpContextMenu:withEvent:forView:"), contextMenu->nsmenu, menuEvent, contentView);
}
#endif //CONTEXTMENU_DARWIN_H