Enable MenuItem when Window is minimized

Hi everyone !

This is my very first question here!!

I’ve been using Xojo for a couple of weeks know and purchased my license. I’ve managed to create a quite simple yet functional app and I got a lot of help reading the docs and searching in the forums. Everything looks good so far, but I’m stuck with the menu bar. I have a menu bar with two options (for the moment haha):

File with a menu item Close (woks fine)
Window with these menu items:

  [b]  Minimize[/b] [i]works fine minimizing the window[/i] 
  [b]Separator[/b]
  [b]My app name[/b]  [i] A menu item (MyMenuItem) with the name of the app[/i]

The window have an EventHandler, there I use MyMenuItem.Checked = True so there’s a checkmark simulating the active window.

The problem comes when resizing the window, all of the options of the menu bar become “disabled” (I suppose that’s normal behavior) but what I want to achieve is the My app name item (MyMenuItem) to be “active” so the user can click it to restore the window (restore/maximize) and have a “bullet” instead of the checkmark (until the window is maximized) but I don’t know how and can’t find the exact answer on the forums (I swear I tried!!!)

Here’s the behavior I want to achieve (from another app):

I’ve tried enabling MyMenuItem in the EventHandler, but it doesn’t work. I don’t know if the “bullet” is an icon I have to assign.

Thank you very much for your help!

Greetings,

Paolo

All of this should be done in the EnableMenuItems event…

Put the menu handler for restoring the window into App, so it will be active all the time.

@Dave, @Michel,

Thanks for the prompt response! That did the trick. The “WindowMenu” in the example projects also helped me understand some other things.

The only doubt I have is the “bullet” instead of the check mark in the MenuItem when the window is minimized. I know this is too much, given I already have the menu item enabled but I’m curious, how can I achieve this? is this a custom icon?

Greetins,

Paolo

Well, this is available in MacOSLib, but that is kind of overkill. You may be able to strip it out and use it directly but I don’t know for sure. Look in the Additional Modules Folder -> Cocoa MenuItems module and you should see the relevant class. I think it’s called MenuItemWindowMenu.

[quote=142847:@Paul Garza]@Dave, @Michel,

Thanks for the prompt response! That did the trick. The “WindowMenu” in the example projects also helped me understand some other things.

The only doubt I have is the “bullet” instead of the check mark in the MenuItem when the window is minimized. I know this is too much, given I already have the menu item enabled but I’m curious, how can I achieve this? is this a custom icon?

Greetins,

Paolo[/quote]

Diamond is &u2666 ?

but you don’t have “control” of changing text in that area.
.CHECKED=true gives a checkmark
or adding an ICON (picture of a diamond)

[quote=142884:@Dave S]but you don’t have “control” of changing text in that area.
.CHECKED=true gives a checkmark
or adding an ICON (picture of a diamond)[/quote]

Diamond is just a character he can copy/paste from this post and place in the Text property of his menuitem just like any other character.

I just tried it fine.

But that Diamond did not appear in the same position that the checkmark would appear, did it?

Indeed.

I created a menuitem subclass which you can set to have a diamond, a checkmark, or nothing. It is independent of MacOSLib but depends on a BasicNSImage class to provide some of the system images, as well as a module for reading string constants to be used in the BasicNSImage class. Add the two classes and module to your project and set the super of your window menu items to DiamondMenuItem and you should be all set. Enjoy!
Link to project

I’m learning stuff looking at your code Jason, thanks for sharing. It gave me the idea to change just the MixedState image to the diamond and then the Checked and Unchecked states can still be controlled with normal Xojo methods.

Implemented as extension methods there’s only 2 needed…

MenuItem.addDiamondAsMixedStateImage() sets the image for mixedstate
MenuItem.setToMixedState() switches to mixedstate

Also, _NSGetThemeImage is a private function. Probably fine (except for App Store inclusion) but I copied the image out to file diamond.png and use that instead. Maybe this is not so good, missing a retina version or something and a better picture can be saved out.

Another odd wrinkle is that the docs for setOnStateImage, setOffStateImage and setMixedStateImage all say “Changing state images is currently unsupported in OS X.” yet they all seem to work.

http://home.comcast.net/~trochoid/diamond.zip

and here’s the pic

//file diamond.png is in Resources folder that's next to project file
//(will also need CopyFiles build step to copy file into built app)

//Menubar has item named FileMainWindow


Class App inherits Application

   Sub Open()
      FileMainWindow.addDiamondAsMixedStateImage  //load diamond when app opens
   End Sub

   Function FileMainWindow() As Boolean //MenuHandler
      Window1.Show
      Return True
   End Function

End Class


Window MainWindow

   Sub Open()
      FileMainWindow.Checked = true //show checked on initial opening  
   End Sub

   Sub Close()
      FileMainWindow.Checked = false //clear when closed
   End Sub

   Sub Minimize()
      FileMainWindow.setToMixedState  //switch to diamond
   End Sub

   Sub Restore()
      FileMainWindow.Checked = true //return to check
   End Sub

End Window


Module DiamondizeMenu

   Sub addDiamondAsMixedStateImage(extends theMenuItem As MenuItem)
      //set MixedState image to be a diamond
      
      const Cocoa = "Cocoa"
      declare function NSClassFromString     lib Cocoa (className as CFStringRef) as ptr
      declare function alloc                 lib Cocoa selector "alloc" (classRef as ptr) as ptr
      declare function URLWithString         lib Cocoa selector "URLWithString:" _
         (id as Ptr, URLString as CFStringRef) as Ptr
      declare function initWithContentsOfURL lib Cocoa selector "initWithContentsOfURL:" _
         (id as Ptr, url as Ptr) as Ptr
      declare sub      setMixedStateImage    lib Cocoa selector "setMixedStateImage:" _
         (id as integer, image as Ptr)
      
      dim NSURLclass As Ptr = NSClassFromString("NSURL")
      dim NSImageclass As Ptr = NSClassFromString("NSImage")
      
      dim f As FolderItem = getDiamondFile //get file of diamond image
      dim url As Ptr = URLWithString(NSURLclass, f.URLPath) //get NSURL of file
      dim img As Ptr = initWithContentsOfURL(alloc(NSImageclass), url) //open as NSImage
      
      dim menuHandle As integer = theMenuItem.Handle(MenuItem.HandleType.CocoaNSMenuItem)
      
      setMixedStateImage(menuHandle, img) //set the image for mixedstate
      
   End Sub

   Sub setToMixedState(extends theMenuItem As MenuItem)
      //set state to mixedstate option
      
      declare sub setState lib "Cocoa" selector "setState:" (id as integer, newState as integer)
      
      dim menuHandle As integer = theMenuItem.Handle(MenuItem.HandleType.CocoaNSMenuItem)
      
      setState(menuHandle, -1) //-1=MixedState, 0=empty, 1=on/checked
      
   End Sub

   Private Function getDiamondFile() As FolderItem
      #if DebugBuild then
         return GetFolderItem("").Child("Resources").Child("diamond.png")
      #else
         return App.ExecutableFile.Parent.Parent.Child("Resources").Child("diamond.png")
      #endif
   End Function

End Module