menuclass not as dynamic as suggested

This forum is for general developer support questions.

menuclass not as dynamic as suggested

Postby chris » Sun Jan 15, 2017 10:14 pm

The wiki says:
A BOOPSI menu tree built with menuclass allows for dynamic addition and removal of menus and items at any time. As with other modifications, there's no need to detach the menu tree from the window in order to perform these operations; it's menuclass that takes care of synchronizing each change with Intuition and doing any necessary relayout afterwards.


This appears to not be the case. I've removed a bunch of items (T_ITEM) under a menu (T_MENU) using both OM_REMMEMBER and MA_RemChild, and in neither case does the menu physically update. It does something, because all the strings I've freed end up showing as random garbage, but the menu items themselves persist.

I've re-added the same items and the same garbage stays in the menu, despite my new items being created pointing at valid strings.

So, menuclass isn't doing what it is supposed to.

I can't figure out how to force the menu to refresh to workaround this bug. Re-applying WINDOW_MenuStrip doesn't help. Anyone?
chris
 
Posts: 548
Joined: Sat Jun 18, 2011 12:05 pm

Re: menuclass not as dynamic as suggested

Postby mritter0 » Sun Jan 15, 2017 11:01 pm

This is how I do it, no extra refresh needed:

Code: Select all
BOOL
SAK_AddMenuItem(Object *MenuObj,uint32 Parent,Object *AddItem)
{
   Object                     *item;

   if ((item=(Object *)IIntuition->IDoMethod(MenuObj,MM_FINDID,0,Parent)))
   {
      IIntuition->SetAttrs(item,
         MA_AddChild,                  AddItem,
      TAG_END);

      return(TRUE);
   }

   return(FALSE);
}


VOID
SAK_RemoveMenuItem(Object *MenuObj,uint32 ID)
{
   Object                     *item;

   if ((item=(Object *)IIntuition->IDoMethod(MenuObj,MM_FINDID,0,ID)))
   {
      IIntuition->SetAttrs(MenuObj,
         MA_RemoveChild,                  item,
      TAG_END);
      IIntuition->DisposeObject(item);
   }
}


      SAK_RemoveMenuItem(MenuStripObj,LocalDevicesNode->GoMenuID);

Workbench Explorer - A better way to browse drawers
User avatar
mritter0
 
Posts: 184
Joined: Mon Aug 25, 2014 10:41 pm
Location: Bettendorf, IA, USA

Re: menuclass not as dynamic as suggested

Postby broadblues » Mon Jan 16, 2017 8:18 pm

chris wrote:The wiki says:
A BOOPSI menu tree built with menuclass allows for dynamic addition and removal of menus and items at any time. As with other modifications, there's no need to detach the menu tree from the window in order to perform these operations; it's menuclass that takes care of synchronizing each change with Intuition and doing any necessary relayout afterwards.


This appears to not be the case. I've removed a bunch of items (T_ITEM) under a menu (T_MENU) using both OM_REMMEMBER and MA_RemChild, and in neither case does the menu physically update. It does something, because all the strings I've freed end up showing as random garbage, but the menu items themselves persist.

I've re-added the same items and the same garbage stays in the menu, despite my new items being created pointing at valid strings.

So, menuclass isn't doing what it is supposed to.

I can't figure out how to force the menu to refresh to workaround this bug. Re-applying WINDOW_MenuStrip doesn't help. Anyone?


Post a code snippet, if you can, as this definetly works in general, so you either have a mistake in your code, or an edge case where it broken...
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
 
Posts: 478
Joined: Sat Jun 18, 2011 3:40 am
Location: Portsmouth, UK

Re: menuclass not as dynamic as suggested

Postby chris » Tue Jan 17, 2017 12:16 am

Hmm, odd, I must be doing something wrong then.

This is the function which deletes and re-adds the items:

Code: Select all
void ami_menu_refresh(struct Menu *menu, struct ami_menu_data **md, int menu_item, int max,
   nserror (*cb)(struct ami_menu_data **md))
{
#ifdef __amigaos4__
   Object *restrict obj;
   Object *restrict menu_item_obj;
   int i;

   if(menu == NULL) return;

   if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
      /* find the address of the menu */
      menu_item_obj = (Object *)IDoMethod((Object *)menu, MM_FINDID, 0, menu_item);

      /* remove all children */
      while((obj = (Object *)IDoMethod(menu_item_obj, MM_NEXTCHILD, 0, NULL)) != NULL) {
         IDoMethod(menu_item_obj, OM_REMMEMBER, obj);
         DisposeObject(obj);
      }

      /* free associated data */
      for(i = (menu_item + 1); i <= max; i++) {
         if(md[i] == NULL) continue;
         ami_menu_free_lab_item(md, i);
      }

      /* get current data */
      cb(md);

      /* re-add items to menu */
      ami_menu_layout_mc_recursive(menu_item_obj, md, NM_ITEM, (menu_item + 1), max);
   }
#endif
}


I know for a fact that the callback and the addition code works, and I get the corrupted menu even without those two lines, so I think the problem is above them.

I'm calling this function with something like:
ami_menu_refresh(root menuclass obj, menu-data array, ID of a menu (T_MENU/NM_TITLE), max ID to process, callback which re-populates the menu-data array)

I suspect it's something stupid!
chris
 
Posts: 548
Joined: Sat Jun 18, 2011 12:05 pm

Re: menuclass not as dynamic as suggested

Postby chris » Tue Jan 17, 2017 12:28 am

Ah, fixed it. I'd taken out the MA_ID of my T_MENU items at one point to try to solve another problem, so it wasn't finding the ID in the menu and hence not removing the items.

Thanks anyway. :oops:
chris
 
Posts: 548
Joined: Sat Jun 18, 2011 12:05 pm


Return to General Developer Support

Who is online

Users browsing this forum: No registered users and 2 guests