Dynamic sub-menus

[quote=105973:@Dan Paymar]No matter how that’s done, the problem is still putting in the submenu items. My current code is:

      m = new MenuItem
      m.text = Gname  ' This will be the actual game name from the game file
      m.name = "Games" + Gnames( y, 0 )  ' This will the menuitem name, e.g. "GamesJB"
      m.append( new MenuItem( Gname ) )

Everything seems great up to the append statement, but I end up with just the original menu, all disabled, with no submenus.

Can this be made to work?[/quote]
Sure
The code I posted works
All you need is to add in the retrieval of the list of games
oh and you’ll probably need to set all the “enabled” properties of those items but it really does put them all in the right spot
just the way I wrote it
Oh yes and get rid of the menu array - they really aren’t needed at all for this (or ever in my experience but …)

I guess that means that the code I’ve written can NOT be made to work.
OK, I’ll try to incorporate your code into my program.

If I understand it right, it’s necessary to build the entire menu dynamically instead of creating the basic structure in the IDE and adding only the submenu items at run time. Right?

Do I have to accumulate all of the submenu items before creating their menuitem?

But what do you mean by getting rid of the menu array? What is that? Are you referring to the Gnames string array?

[quote=106029:@Dan Paymar]I guess that means that the code I’ve written can NOT be made to work.
OK, I’ll try to incorporate your code into my program.
[/quote]
Of course it can be made to work.

[quote]If I understand it right, it’s necessary to build the entire menu dynamically instead of creating the basic structure in the IDE and adding only the submenu items at run time. Right?
[/quote]
Wrong. Just get rid of the “menu array”.

[quote]Do I have to accumulate all of the submenu items before creating their menuitem?
[/quote]
It can be done in either order.

Both Norman and I are referring to the Index property in the inspector of the IDE. If you fill that in, you are creating a menu array/control set. Don’t do that. Leave them blank or -1.

Blank and -1 don’t seem to work. Use the default big negative number.

To be pedantic, setting the Index property to something other than the default value makes the menuitem into a control array / control set / menu array / whatever you want to call it. That allows you to have multiple items with the same name, all of which share the same menu handler code. It also allows you to create new instances in code. However, the new instances appear as siblings of the original, not as children. For that reason, using the Index property doesn’t work for what you want to do.

Another note, if I set the Index in the above image to 0, then I can no longer write

GamesBJ.Append m

I have to use the index:

GamesBJ(0).Append m

So even with your index values set the way they are, you can still Append sub-items to them, as long as you use the index value.

Tim, the IDE won’t accept a negative number for the Index,
but if I set the Index to 0 and write
GamesJB(0).append m
it works to create the submenus, but they are disabled.
What is the specific code to enable them?

Right after

dim subitem as new MenuItem( gamenames(i) )

add

subitem.enabled = true

should do
Although the problem with this set up is you have no menu handler and no easy way to attach one to each of the dynamic items we added
This is a perfect case where a subclass might work better

However thats hard to be sure of because I’m sure you want to do more than just get the name of the menu item (thats trivial) that was selected
You want to “DO something” but I don’t know what
Open the file with that game or ???
In that case the subclass would probably work quite well.

My original code works when the Index is included in the Append:
m = new MenuItem m.text = Gname m.name = "Games" + Gnames( y, 0 ) m.enabled = true GamesJB(0).append m
I get the proper submenus, but all the submenu items are disabled. I tried inserting an “enabled=true” as shown above, and tried it after the append, but it doesn’t work.

How do I enable the submenu items?

Seems the MenuItem will remain disabled if there is no Handler code assigned to its “Action” event. Please see the previous sample for adding a handler code of “Action” event for dynamically added MenuItem.

Oh, of course. Apparently I need separate menu handlers for GamesJB, GamesAA, etc.
Thanks

Same handler function could be used as well for all sub-menu MenuItems and “Select Case” may be used in that handler to take necessary action based on the actual MenuItem that is passed to that handler.

Maybe not the handler for “GamesJB, GamesAA and others”, these seem to be on the main menu bar as these are active/enabled anyway. Instead the handler for actual sub-menu MenuItems for each of these MenuItems “GamesJB, GamesAA and others” that are on the main menu bar. However the details of the menu system used in this case are not provided above so this is just a guess.

I created a menu handler “GamesJB” (the name of the submenu). The items in that submenu are enabled, but when I select one the menu handler receives Index=-2147483648. I tried a menu handler called simply Games (the name of the menu in the menu bar), and it doesn’t get an index at all. What am I missing?

Syed, you say a single menu handler could take care of all submenus. How do I get all submenu selections to go to the same handler, and what do I get as an Index?

Not sure about the index problem.

This code complies and executes without any error. The code below was added to the “Open” event of Window1 in a new Desktop project in Xojo 2013r2. Note that the same handler “mnuFontsSubMenus” is used to handle the “Action” event of two separate MenuItems under the “Fonts” menu on the main menu bar.

  dim m,mNew as MenuItem
  m=self.menubar
  mNew=New MenuItem
  
  mNew.text="Fonts"
  mNew.name="Fonts"
  
  mNew.Append(new menuitem("TestOne"))
  mNew.Append(new menuitem("Testtwo"))
  mNew.Append(new menuitem("Testthree"))
  mNew.Append( new MenuItem( "-" ) )
  
  dim submenu as New Menuitem("MySub")
  
  submenu.Append(new menuitem("submenu One"))
  submenu.Append(new menuitem("submenu Two"))
  submenu.Append(new menuitem("submenu three"))
  
  m.Append mnew
  mNew.Append submenu
  
  //
  // Assign handler to "Fonts - TestOne" "Action" event
  // 
  Dim subMenuItem As MenuItem
  subMenuItem = mNew.Child("TestOne")
  If subMenuItem <> Nil Then
    AddHandler subMenuItem.Action, AddressOf mnuFontsSubMenus
    subMenuItem.Enabled = True
  End If
  
  //
  // Assign the same handler to "Fonts - Testtwo" "Action" event
  //
  subMenuItem = mNew.Child("Testtwo")
  If subMenuItem <> Nil Then
    AddHandler subMenuItem.Action, AddressOf mnuFontsSubMenus
    subMenuItem.Enabled = True
  End If

  //
  // Add a Method to Window1 with following code to handle the "Fonts - TestOne" "Action" event
  // and any other MenuItem Action events as required.
  //
  Function mnuFontsSubMenus( mnuMI As MenuItem) As Boolean
       
  Select Case mnuMI.Text
  Case "TestOne"
    MsgBox("Fonts - TestOne")
  Case "Testtwo"
    MsgBox("Fonts - Testtwo")
  End Select

  End Function

Ahha, I figured it out. When building the menus, I set the index for each game with
m.index = x
where x is the position of the game name in the original gamename list.

Thanks to all who replied to my query.

In the previous sample above, reference to the “Fonts” MenuItem on the main menu bar can be obtained without the need of index as shown below.

  //
  // Add after second "If subMenuItem <> Nil Then ... End If" in previous sample above.
  //
  subMenuItem = m.Child("Fonts")
  If subMenuItem <> Nil Then
    MsgBox("Main Menu - Fonts")
  End If

Once reference to “Fonts” MenuItem on the main menu bar is available then the MenuItems of the “Fornts” menu can be accessed as already shown in previous sample above.

In my case I need the Index because it points back into the original list of all game names.

I now have the menus and menu handlers working properly. Now I need to work on how to delete the correct submenu item.

Just bypassed the problem of how to remove a specific submenu item. Simply delete the game file and rebuild the Games menu!