From 5f2c437136ae98f74a45e93a6ef686d22cc30c3a Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Wed, 6 Jan 2021 12:53:11 +1100 Subject: [PATCH] Bugfix dealloc contextmenus. Create common.h. WIP: new menu handling --- v2/internal/ffenestri/common.h | 20 ++++ v2/internal/ffenestri/ffenestri_darwin.c | 15 ++- v2/internal/ffenestri/menu_darwin.h | 111 +++++++++++++++++++++++ 3 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 v2/internal/ffenestri/common.h create mode 100644 v2/internal/ffenestri/menu_darwin.h diff --git a/v2/internal/ffenestri/common.h b/v2/internal/ffenestri/common.h new file mode 100644 index 000000000..6b50fe9b7 --- /dev/null +++ b/v2/internal/ffenestri/common.h @@ -0,0 +1,20 @@ +// +// Created by Lea Anthony on 6/1/21. +// + +#ifndef COMMON_H +#define COMMON_H + +#include "hashmap.h" + +void ABORT(const char *message) { + printf("%s\n", message); + exit(1); +} + +int freeHashmapItem(void *const context, struct hashmap_element_s *const e) { + free(e->data); + return -1; +} + +#endif //ASSETS_C_COMMON_H diff --git a/v2/internal/ffenestri/ffenestri_darwin.c b/v2/internal/ffenestri/ffenestri_darwin.c index e4c60b889..807d39b0d 100644 --- a/v2/internal/ffenestri/ffenestri_darwin.c +++ b/v2/internal/ffenestri/ffenestri_darwin.c @@ -2,6 +2,8 @@ #ifdef FFENESTRI_DARWIN #include "ffenestri_darwin.h" +#include "menu_darwin.h" + // References to assets #include "assets.h" @@ -145,6 +147,7 @@ struct Application { int windowBackgroundIsTranslucent; // Menu + Menu *applicationMenu; const char *menuAsJSON; JsonNode *processedMenu; @@ -759,6 +762,7 @@ void* NewApplication(const char *title, int width, int height, int resizable, in result->delegate = NULL; // Menu + result->applicationMenu = NULL; result->menuAsJSON = NULL; result->processedMenu = NULL; @@ -772,6 +776,7 @@ void* NewApplication(const char *title, int width, int height, int resizable, in // Context Menus result->contextMenusAsJSON = NULL; + result->processedContextMenus = NULL; contextMenuData = NULL; // Window Appearance @@ -783,10 +788,6 @@ void* NewApplication(const char *title, int width, int height, int resizable, in return (void*) result; } -int freeHashmapItem(void *const context, struct hashmap_element_s *const e) { - free(e->data); - return -1; -} int releaseNSObject(void *const context, struct hashmap_element_s *const e) { msg(e->data, s("release")); @@ -935,6 +936,11 @@ void DestroyApplication(struct Application *app) { // Destroy the menu destroyMenu(app); + // Delete the application menu if we have one + if( app->applicationMenu != NULL ) { + DeleteMenu(app->applicationMenu); + } + // Destroy the tray destroyTray(app); @@ -1420,6 +1426,7 @@ void SetDebug(void *applicationPointer, int flag) { // SetMenu sets the initial menu for the application void SetMenu(struct Application *app, const char *menuAsJSON) { app->menuAsJSON = menuAsJSON; + app->applicationMenu = NewMenu(menuAsJSON); } // SetTray sets the initial tray menu for the application diff --git a/v2/internal/ffenestri/menu_darwin.h b/v2/internal/ffenestri/menu_darwin.h new file mode 100644 index 000000000..fcfa49937 --- /dev/null +++ b/v2/internal/ffenestri/menu_darwin.h @@ -0,0 +1,111 @@ +// +// Created by Lea Anthony on 6/1/21. +// + +#ifndef MENU_DARWIN_H +#define MENU_DARWIN_H + +#include "common.h" + +typedef struct { + + /*** Internal ***/ + + const char *menuAsJSON; + + struct hashmap_s menuItemMap; + struct hashmap_s radioGroupMap; + +} Menu; + +// NewMenu creates a new Menu struct, saving the given menu structure as JSON +Menu* NewMenu(const char *menuAsJSON) { + + Menu *result = malloc(sizeof(Menu)); + + // menuAsJSON is allocated and freed by Go + result->menuAsJSON = menuAsJSON; + + // Allocate MenuItem Map + if( 0 != hashmap_create((const unsigned)16, &result->menuItemMap)) { + ABORT("[NewMenu] Not enough memory to allocate menuItemMap!"); + } + // Allocate the Radio Group Map + if( 0 != hashmap_create((const unsigned)4, &result->radioGroupMap)) { + ABORT("[NewMenu] Not enough memory to allocate radioGroupMap!"); + } + + return result; +} + +void DeleteMenu(Menu *menu) { + + // Free menu item hashmap + hashmap_destroy(&menu->menuItemMap); + + // Free radio group members + if( hashmap_num_entries(&menu->radioGroupMap) > 0 ) { + if (0 != hashmap_iterate_pairs(&menu->radioGroupMap, freeHashmapItem, NULL)) { + ABORT("[DeleteMenu] Failed to release radioGroupMap entries!"); + } + } + + // Free radio groups hashmap + hashmap_destroy(&menu->radioGroupMap); + + free(menu); +} + + +void Create() { + +// +// // Allocate the hashmaps we need +// allocateMenuHashMaps(app); +// +// // Create a new menu bar +// id menubar = createMenu(str("")); +// +// // Parse the processed menu json +// app->processedMenu = json_decode(app->menuAsJSON); +// +// if( app->processedMenu == NULL ) { +// // Parse error! +// Fatal(app, "Unable to parse Menu JSON: %s", app->menuAsJSON); +// return; +// } +// +// +// // Pull out the Menu +// JsonNode *menuData = json_find_member(app->processedMenu, "Menu"); +// if( menuData == NULL ) { +// // Parse error! +// Fatal(app, "Unable to find Menu data: %s", app->processedMenu); +// return; +// } +// +// +// parseMenu(app, menubar, menuData, &menuItemMapForApplicationMenu, +// "checkboxMenuCallbackForApplicationMenu:", "radioMenuCallbackForApplicationMenu:", "menuCallbackForApplicationMenu:"); +// +// // Create the radiogroup cache +// JsonNode *radioGroups = json_find_member(app->processedMenu, "RadioGroups"); +// if( radioGroups == NULL ) { +// // Parse error! +// Fatal(app, "Unable to find RadioGroups data: %s", app->processedMenu); +// return; +// } +// +// // Iterate radio groups +// JsonNode *radioGroup; +// json_foreach(radioGroup, radioGroups) { +// // Get item label +// processRadioGroup(radioGroup, &menuItemMapForApplicationMenu, &radioGroupMapForApplicationMenu); +// } +// +// // Apply the menu bar +// msg(msg(c("NSApplication"), s("sharedApplication")), s("setMainMenu:"), menubar); + +} + +#endif //ASSETS_C_MENU_DARWIN_H