Live menuitem update

Hi everyone,

is it possible to update a menuitem text in real time ?
in the finder, if you press - depress option in some menus the text changes, as in many apps (save changes to “save as” for example

in xojo, I change the text in the enablemenuitem event of a control or a window, but if I check for option key it is changed but not
in real time, you have to re-clic the menu to get the new text

is there a way to achieve this in xojo, and bonus if it is multi platform.
thanks.

Have you tried to set the name in the EnableMenuitems event?

On macOS you would need to use create two menu items and set one of them to be the alternate and the system will swap them in and out, as required… On Windows I was able to do something similar just using a timer to poll the keyboard… I think the Windows method should work on Linux as well, but I never tested it…

I’ll go grab the code I used (will have to check it against 64-bit first, so give me a few)

yes. (as stated in my first post)

I just noticed that the entire xojo IDE ( in mac at least) does not use at all these live menuitems…

I do not think this can be a Clue at all. Xojo IDE have things we do not have, so … I think the reverse can be too.

[code]Public Sub SetAlternate(Extends aMenuItem As MenuItem, Assigns value As Boolean)
#if TargetCocoa
Declare Sub setAlternate_ Lib “Cocoa” Selector “setAlternate:” (aNSMenuItem As Integer, value As Boolean)
setAlternate_ aMenuItem.Handle(MenuItem.HandleType.CocoaNSMenuItem), value
#endif

#Pragma Unused aMenuItem
#Pragma Unused value
End Sub
[/code]

For macOS, slap this in a module and then call it from somewhere (I was doing it in App.Open)

MyAlternateMenuItem.SetAlternate = TRUE

Make sure that the two menu items are in your menu stacked on top of each other and they need the same key for their shortcut…

Okay, this code also works on macOS, but feels a little hacky, so I’d stick with the extend method posted above… This code is from a long time ago (before the new framework and 64-bit) but should be easy enough to update to use the new Timer.CallLater

In my application, and test demo, all this code was part of the App class, but the EnableMenuItems event handler can be at any level…

Sub Open() Handles Open me.InitMenuModifierTimer End Sub

[code]Private Sub InitMenuModifierTimer()
me.mMenuModifierTimer = NEW Timer
me.mMenuModifierTimer.Period = 100 // still responsive and low CPU usage
me.mMenuModifierTimer.Mode = Timer.ModeMultiple
me.mMenuModifierTimer.Enabled = TRUE

AddHandler me.mMenuModifierTimer.Action, WeakAddressOf MenuModifierAction
End Sub
[/code]

[code]Private Sub MenuModifierAction(menuModifierTimer As Timer)
#pragma Unused menuModifierTimer

EnableMenuItems
End Sub
[/code]

My test code was using the Shift Key for the modifier, but just check for whatever modifier you require and set the menu items as required…

Sub EnableMenuItems() Handles EnableMenuItems UntitledOink.Visible = NOT Keyboard.AsyncShiftKey UntitledOinkModified.Visible = Keyboard.AsyncShiftKey End Sub

In my project file UntitledOinkModified had Visible set to FALSE so it wasn’t showing in the menu when the menu is first opened…

Any questions, feel free to ask…

The problem is that Xojo loves to rebuild the menu, so your changes are going to get ignored.
Of course you may catch an event and do make changes after Xojo build the menu and before displaying it, but that could be difficult.

shouldn’t this line Sub EnableMenuItems() Handles EnableMenuItems
be instead Sub EnableMenuItems() // Handles EnableMenuItems
?

in fact everything relies in :

[quote]EnableMenuItems (Method)
Forces an update of the menu bar and executes the EnableMenuItems event handler.[/quote]

and a timer to fire it at regular interval.

well after some tests, it doesn’t update really live, you have to choose another menu, but it does not require you to clic twice at least to get the other text of the menu.

The other way you can do it on the macOS (although’ recommend using the preferred method “alternate” as ? Sean says, anyway the other method which is really hacky, would be to inject an actual control into the menuitem and change the text on that control or label.

I’m just heading home, when I get back to work tonight, I’ll post a sample project with the timer method…

[quote=369885:@Jean-Yves Pochez]shouldn’t this line Sub EnableMenuItems() Handles EnableMenuItems
be instead Sub EnableMenuItems() // Handles EnableMenuItems
?[/quote]
Possibly, I just copied the event handler out of the IDE, so I’ll check it tonight and file a bug report if it happens again…

[quote=369885:@Jean-Yves Pochez]shouldn’t this line Sub EnableMenuItems() Handles EnableMenuItems
be instead Sub EnableMenuItems() // Handles EnableMenuItems
?[/quote]
No. It should be an actual event handler.

https://securedhosting.tk/files/xojo/MenuItemAsyncSwapUsingTimer.zip