Enable/Disable MenuItem - validateUserInterfaceItem?

Hi everyone,

first off: this forum is an amazing resource!
One thing I cant’t figure out though and did not find any explaination that help me in the forum:

I am working on a project which is a menulet (or Menubar app) - and I basicaly start/stop the actual script of the app with 2 (start & stop) menu items.
Now I do need to disable the one that has been pressed already, otherwise I can and up entering my mainloop more than once …
MenuItems as far as I understood have some auto-control in IB which makes it difficult to manually turn the setEnabled _().

How does the trick with validateUserInterfaceItem work? I can’t figure it out…

Thanks in advance!
Chris

Hi,

try this, set the tag value of the start item to 128 and the tag value of the stop item to 129
The handler assumes also a property isRunning which reflects the current state.

The delegate property of both menu items must be connected to the app delegate script


on validateUserInterfaceItem_(menuItem)
	set menuItemTag to menuItem's tag() as integer
	if menuItemTag = 128 then
		return isRunning = false
	else if menuItemTag = 129 then
		return isRunning = true
	else
		return true
	end if
end validateUserInterfaceItem_

Hi Sefan,

thanks for the fast reply.
Hmm… I seem to miss something here - sorry but I am pretty new to ASOBC.
It disables all my menuitems and if I bind the 2 (start/stop) ones to the appdelegate both of them are active but the others are disabled.

So you know what Im talking about - my Menulet has a Menu that drops down which has 5 menu items - 2 of them are the ones i want to control.
I changed the value for the start and stop item as you said and add your script + 2 propertys in my applescript like this…


property menuItem : missing value
property isRunning : missing value

on validateUserInterfaceItem_(menuItem)
   set menuItemTag to menuItem's tag() as integer
   if menuItemTag = 128 then
       return isRunning = false
   else if menuItemTag = 129 then
       return isRunning = true
   else
       return true
   end if
end validateUserInterfaceItem_

Then I get stuck with connecting the to items - I tried to bind the value to the appdelegate with the modelkeypath set to menuItem - end up only having star/stop enabled - if I don’t do that all items are disabled…

Sorry this is probably a stupid mistake but I am confused.

the property menuItem is not needed.

The handler validateUserInterfaceItem_ is called automatically when the menu is going to open

The property isRunning must be a boolean value (true or false) and is supposed to be set/reset in the IBAction when the start/stop menu items are selected.

Sorry, I did a mistake. The Menu delegate must be connected (in Interface Builder) to the app delegate script, not the delegate of the Menu Items

I can see that we are on the right track but I am not getting it the way it is supposed to work.

See this with my comments:


    property isRunning : boolean

    on clickStart_(sender)
        set isRunning to true
        -- here comes the main code (loop)
    end clickStart_
    
    on clickStop_(sender)
        set isRunning to false
        -- here comes the quit command for the loop
    end clickStop_
    
    on validateUserInterfaceItem_(menuItem)
            set menuItemTag to menuItem's tag() as integer
            if menuItemTag = 128 then
                return isRunning = false
            else if menuItemTag = 129 then
                return isRunning = false
            else
                return true -- i guess this was I typo and is supposed to be true / otherwise all items are disabled
            end if
    end validateUserInterfaceItem_

I have connected the clickStart/Stop parts to the MenuItems in IB and also the menu’s delegate to the app delegate.
If I run the code like above, both (start & stop) are disabled.

I tested it, it works if the IBAction methods clickstart_()/clickStop_() are connected to the menu items,
because the validateUserInterfaceItem method needs to retrieve their target.


.
else if menuItemTag = 129 then
return isRunning = true -- must be true
.

PS: set the value of the property isRunning to false, that’s probably the failure reason

Awesome! Thanks Stefan! It’s working now as you explained.
The true + removing some trash code that sneaked in while testing around did it.
Again: Thanks for you help!