diff --git a/v2/internal/ffenestri/ffenestri_darwin.c b/v2/internal/ffenestri/ffenestri_darwin.c index dd5890e6e..56c63fcb7 100644 --- a/v2/internal/ffenestri/ffenestri_darwin.c +++ b/v2/internal/ffenestri/ffenestri_darwin.c @@ -1372,211 +1372,6 @@ void parseMenuRole(struct Application *app, id parentMenu, JsonNode *item) { } -id parseTextMenuItem(struct Application *app, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers, const char *menuCallback) { - id item = ALLOC("NSMenuItem"); - id wrappedId = ((id(*)(id, SEL, const char*))objc_msgSend)(c("NSValue"), s("valueWithPointer:"), menuid); - msg_id(item, s("setRepresentedObject:"), wrappedId); - - id key = processAcceleratorKey(acceleratorkey); - ((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), - s(menuCallback), key); - - msg_bool(item, s("setEnabled:"), !disabled); - msg_reg(item, s("autorelease")); - - // Process modifiers - if( modifiers != NULL ) { - unsigned long modifierFlags = parseModifiers(modifiers); - msg_int(item, s("setKeyEquivalentModifierMask:"), modifierFlags); - } - msg_id(parentMenu, s("addItem:"), item); - - return item; -} - -id parseCheckboxMenuItem(struct Application *app, id parentmenu, const char -*title, const char *menuid, bool disabled, bool checked, const char *key, -struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction) { - id item = ALLOC("NSMenuItem"); - - // Store the item in the menu item map - hashmap_put(menuItemMap, (char*)menuid, strlen(menuid), item); - - id wrappedId = msg_id(c("NSValue"), s("valueWithPointer:"), (id)menuid); - msg_id(item, s("setRepresentedObject:"), wrappedId); - ((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), s(checkboxCallbackFunction), str(key)); - msg_bool(item, s("setEnabled:"), !disabled); - msg_reg(item, s("autorelease")); - msg_int(item, s("setState:"), (checked ? NSControlStateValueOn : NSControlStateValueOff)); - msg_id(parentmenu, s("addItem:"), item); - return item; -} - -id parseRadioMenuItem(struct Application *app, id parentmenu, const char *title, - const char *menuid, bool disabled, bool checked, const char *acceleratorkey, - struct hashmap_s *menuItemMap, const char *radioCallbackFunction) { - id item = ALLOC("NSMenuItem"); - - // Store the item in the menu item map - hashmap_put(menuItemMap, (char*)menuid, strlen(menuid), item); - - id wrappedId = msg_id(c("NSValue"), s("valueWithPointer:"), (id)menuid); - msg_id(item, s("setRepresentedObject:"), wrappedId); - - id key = processAcceleratorKey(acceleratorkey); - - ((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), s(radioCallbackFunction), key); - - msg_bool(item, s("setEnabled:"), !disabled); - msg_reg(item, s("autorelease")); - msg_int(item, s("setState:"), (checked ? NSControlStateValueOn : NSControlStateValueOff)); - - msg_id(parentmenu, s("addItem:"), item); - return item; - -} - -void parseMenuItem(struct Application *app, id parentMenu, JsonNode *item, -struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char -*radioCallbackFunction, const char *menuCallbackFunction) { - - // Check if this item is hidden and if so, exit early! - bool hidden = false; - getJSONBool(item, "Hidden", &hidden); - if( hidden ) { - return; - } - - // Get the role - JsonNode *role = json_find_member(item, "Role"); - if( role != NULL ) { - parseMenuRole(app, parentMenu, role); - return; - } - - // Check if this is a submenu - JsonNode *submenu = json_find_member(item, "SubMenu"); - if( submenu != NULL ) { - // Get the label - JsonNode *menuNameNode = json_find_member(item, "Label"); - const char *name = ""; - if ( menuNameNode != NULL) { - name = menuNameNode->string_; - } - - id thisMenuItem = createMenuItemNoAutorelease(str(name), NULL, ""); - id thisMenu = createMenu(str(name)); - - msg_id(thisMenuItem, s("setSubmenu:"), thisMenu); - msg_id(parentMenu, s("addItem:"), thisMenuItem); - - // Loop over submenu items - JsonNode *item; - json_foreach(item, submenu) { - // Get item label - parseMenuItem(app, thisMenu, item, menuItemMap, checkboxCallbackFunction, radioCallbackFunction, menuCallbackFunction); - } - - return; - } - - // This is a user menu. Get the common data - // Get the label - const char *label = getJSONString(item, "Label"); - if ( label == NULL) { - label = "(empty)"; - } - - const char *menuid = getJSONString(item, "ID"); - if ( menuid == NULL) { - menuid = ""; - } - - bool disabled = false; - getJSONBool(item, "Disabled", &disabled); - - // Get the Accelerator - JsonNode *accelerator = json_find_member(item, "Accelerator"); - const char *acceleratorkey = NULL; - const char **modifiers = NULL; - - // If we have an accelerator - if( accelerator != NULL ) { - // Get the key - acceleratorkey = getJSONString(accelerator, "Key"); - // Check if there are modifiers - JsonNode *modifiersList = json_find_member(accelerator, "Modifiers"); - if ( modifiersList != NULL ) { - // Allocate an array of strings - int noOfModifiers = json_array_length(modifiersList); - - // Do we have any? - if (noOfModifiers > 0) { - modifiers = malloc(sizeof(const char *) * (noOfModifiers + 1)); - JsonNode *modifier; - int count = 0; - // Iterate the modifiers and save a reference to them in our new array - json_foreach(modifier, modifiersList) { - // Get modifier name - modifiers[count] = modifier->string_; - count++; - } - // Null terminate the modifier list - modifiers[count] = NULL; - } - } - } - - - // Get the Type - JsonNode *type = json_find_member(item, "Type"); - if( type != NULL ) { - - if( STREQ(type->string_, "Text")) { - parseTextMenuItem(app, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, menuCallbackFunction); - } - else if ( STREQ(type->string_, "Separator")) { - addSeparator(parentMenu); - } - else if ( STREQ(type->string_, "Checkbox")) { - // Get checked state - bool checked = false; - getJSONBool(item, "Checked", &checked); - - parseCheckboxMenuItem(app, parentMenu, label, menuid, disabled, checked, "", menuItemMap, checkboxCallbackFunction); - } - else if ( STREQ(type->string_, "Radio")) { - // Get checked state - bool checked = false; - getJSONBool(item, "Checked", &checked); - - parseRadioMenuItem(app, parentMenu, label, menuid, disabled, checked, "", menuItemMap, radioCallbackFunction); - } - - if ( modifiers != NULL ) { - free(modifiers); - } - - return; - } -} - -void parseMenu(struct Application *app, id parentMenu, JsonNode *menu, struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char *radioCallbackFunction, const char *menuCallbackFunction) { - JsonNode *items = json_find_member(menu, "Items"); - if( items == NULL ) { - // Parse error! - Fatal(app, "Unable to find Items in Menu"); - return; - } - - // Iterate items - JsonNode *item; - json_foreach(item, items) { - // Get item label - parseMenuItem(app, parentMenu, item, menuItemMap, checkboxCallbackFunction, radioCallbackFunction, menuCallbackFunction); - } -} - void dumpMemberList(const char *name, id *memberList) { void *member = memberList[0]; int count = 0; @@ -1589,43 +1384,6 @@ void dumpMemberList(const char *name, id *memberList) { printf("]\n"); } -void processRadioGroup(JsonNode *radioGroup, struct hashmap_s *menuItemMap, -struct hashmap_s *radioGroupMap) { - - int groupLength; - getJSONInt(radioGroup, "Length", &groupLength); - JsonNode *members = json_find_member(radioGroup, "Members"); - JsonNode *member; - - // Allocate array - size_t arrayLength = sizeof(id)*(groupLength+1); - id memberList[arrayLength]; - - // Build the radio group items - int count=0; - json_foreach(member, members) { - // Get menu by id - id menuItem = (id)hashmap_get(menuItemMap, (char*)member->string_, strlen(member->string_)); - // Save Member - memberList[count] = menuItem; - count = count + 1; - } - // Null terminate array - memberList[groupLength] = 0; - - // dumpMemberList("memberList", memberList); - - // Store the members - json_foreach(member, members) { - // Copy the memberList - char *newMemberList = (char *)malloc(arrayLength); - memcpy(newMemberList, memberList, arrayLength); - // add group to each member of group - hashmap_put(radioGroupMap, member->string_, strlen(member->string_), newMemberList); - } - -} - // updateMenu replaces the current menu with the given one void updateMenu(struct Application *app, const char *menuAsJSON) { Debug(app, "Menu is now: %s", menuAsJSON); diff --git a/v2/internal/ffenestri/menu_darwin.c b/v2/internal/ffenestri/menu_darwin.c index f7f90d464..da994dd71 100644 --- a/v2/internal/ffenestri/menu_darwin.c +++ b/v2/internal/ffenestri/menu_darwin.c @@ -695,38 +695,6 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) { return; } - // Check if this is a submenu - JsonNode *submenu = json_find_member(item, "SubMenu"); - if( submenu != NULL ) { - // Get the label - JsonNode *menuNameNode = json_find_member(item, "Label"); - const char *name = ""; - if ( menuNameNode != NULL) { - name = menuNameNode->string_; - } - - id thisMenuItem = createMenuItemNoAutorelease(str(name), NULL, ""); - id thisMenu = createMenu(str(name)); - - msg_id(thisMenuItem, s("setSubmenu:"), thisMenu); - msg_id(parentMenu, s("addItem:"), thisMenuItem); - - JsonNode *submenuItems = json_find_member(submenu, "Items"); - // If we have no items, just return - if ( submenuItems == NULL ) { - return; - } - - // Loop over submenu items - JsonNode *item; - json_foreach(item, submenuItems) { - // Get item label - processMenuItem(menu, thisMenu, item); - } - - return; - } - // This is a user menu. Get the common data // Get the label const char *label = getJSONString(item, "Label"); @@ -792,9 +760,36 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) { // Get the Type JsonNode *type = json_find_member(item, "Type"); if( type != NULL ) { + if( STREQ(type->string_, "Text") || STREQ(type->string_, "Submenu")) { + id thisMenuItem = processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, tooltip, image, fontName, fontSize, RGBA, templateImage, alternate); - if( STREQ(type->string_, "Text")) { - processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, tooltip, image, fontName, fontSize, RGBA, templateImage, alternate); + // Check if this node has a submenu + JsonNode *submenu = json_find_member(item, "SubMenu"); + if( submenu != NULL ) { + // Get the label + JsonNode *menuNameNode = json_find_member(item, "Label"); + const char *name = ""; + if ( menuNameNode != NULL) { + name = menuNameNode->string_; + } + + id thisMenu = createMenu(str(name)); + + msg_id(thisMenuItem, s("setSubmenu:"), thisMenu); + + JsonNode *submenuItems = json_find_member(submenu, "Items"); + // If we have no items, just return + if ( submenuItems == NULL ) { + return; + } + + // Loop over submenu items + JsonNode *item; + json_foreach(item, submenuItems) { + // Get item label + processMenuItem(menu, thisMenu, item); + } + } } else if ( STREQ(type->string_, "Separator")) { addSeparator(parentMenu); @@ -813,7 +808,6 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) { processRadioMenuItem(menu, parentMenu, label, menuid, disabled, checked, ""); } - } if ( modifiers != NULL ) {