Checkmarks on PopupMenu items

I’m attempting to add checkmarks to items in a PopupMenu, in order to represent states on a few items. Seeing that the current PopupMenu only has rows in it I can’t get at the underlying MenuItems to use checked. Any pointers would be helpful.

I’ve tried using Cocoa calls to get the menu item and set the state but I still don’t get check marks.

Const CocoaLib = "AppKit"

Declare Function itemAtIndex Lib CocoaLib selector "itemAtIndex:" ( id As ptr, idx As Integer ) As ptr
Declare Sub setState Lib CocoaLib selector "setState:" ( id As ptr, idx As Integer )
Declare Function menu Lib CocoaLib selector "menu" ( id As Integer ) As ptr

Dim ctrlHandle As Integer = Me.Handle
Dim mi As ptr = itemAtIndex( menu( ctrlHandle ), 0 )
setState( mi, 1 )

Spoke too soon. I’ve just noticed that I was working with itemAtIndex 0. Which for me is the wrong item.
The above code works I just needed to use

Dim mi As ptr = itemAtIndex( menu( ctrlHandle ), Me.SelectedItemIndex )

Here’s an extension method to use this in a nice controlled way:

Public Enum RowStates
Unchecked = 0
Checked = 1
Mixed = 2
End Enum

Public Function RowStateAt(extends Popup as PopupMenu, Index as Integer) as RowStates
  Declare Function itemAtIndex Lib CocoaLib selector "itemAtIndex:" ( id As ptr, idx As Integer ) As ptr
  Declare Function state Lib CocoaLib selector "state" ( id As ptr ) As Integer
  Declare Function menu Lib CocoaLib selector "menu" ( id As Integer ) As ptr
  
  Dim ctrlHandle As Integer = Popup.Handle
  If Index >= 0 And Index <= popup.LastRowIndex Then
    Dim mi As ptr = itemAtIndex( menu( ctrlHandle ), Index )
    Return CType( state( mi ), RowStates )
  Else
    Return CType( 0, RowStates )
  End If
  
End Function

Public Sub RowStateAt(Extends Popup as PopupMenu, Index as Integer, Assigns Value as RowStates)
  Declare Function itemAtIndex Lib CocoaLib selector "itemAtIndex:" ( id As ptr, idx As Integer ) As ptr
  Declare Sub setState Lib CocoaLib selector "setState:" ( id As ptr, idx As Integer )
  Declare Function menu Lib CocoaLib selector "menu" ( id As Integer ) As ptr
  
  Dim ctrlHandle As Integer = Popup.Handle
  If Index >= 0 And Index <= popup.LastRowIndex Then
    Dim mi As ptr = itemAtIndex( menu( ctrlHandle ), Index )
    setState( mi, Integer( Value ) )
  End If
  
End Sub

Put it in a module.

Set the state:

PopupMenu1.RowStateAt( Index ) = RowStates.Checked

or read the state:

if PopupMenu1.RowStateAt( Index ) = RowStates.Checked then
  // Do Something
end if
3 Likes

What’s wrong with using:

menuitemPtr.HasCheckMark = True

On a PopupMenu? You can’t get to the underlying MenuItem.

Who is creating the popup menu?

Xojo is. Dragged and dropped onto the Window.

Well you could create it at runtime. I do that for any menu (popup or otherwise) which is going to need to be modified during the life of the app.

He’s talking about a PopupMenu control, you’re talking about a MenuItem, methinks.

1 Like

If I’m creating a popup menu at runtime, I’m also adding menuitems to it.

I just tried that for one such popup menu. Added a check mark to one of the menu items and there it was.

Not exactly drag and drop on the window interface through. This allows you to build the interface as you normally would and then use checkmarks as you wish.

PopupMenu vs MenuItem

PopupMenu is a UI control.

Like this, at the top right corner

OK I guess you’re right. In fact mine is actually a ContextMenu. I do the same for a couple of menubar menus - create them empty and populate at runtime and rebuild them according to user actions.

Ah, you can’t do that with PopupMenus. All you can do is add or remove rows.

A thought:
I just whipped up this code and got myself a nice emoji based popup from a constructcontextual menu

Dim m As New menuitem

//U+2705  is the code of the tick I used here

m.Text =  "✅"+"I am ticked" 
base.AddMenu m

m = New menuitem
m.Text = "     I am not ticked " 
base.AddMenu m

Return True
1 Like

The problem with things like that is it is highly dependant upon the font you use and it will differ significantly by platform.

From the LR:
“Displays a list of items when clicked. The user can select one item from the list.“

Since you use the plural above, I am asking a simple question:

How the user can be able to choose more than one entry of a PopupMenu ?

Your software, your rules, but my point of view.

Interesting readings:

and maybe others…

Now, If I am wrong, care to explain, please ?

@Emile_Schwarz
If you look at this image you can see what I mean. You can choose only one item at a time but in doing so you are toggling an option on and off, for example Whole words or Match Case.

The interface is a copy of that found in Apple Numbers.

Thats not a popup menu.
Looks more like an Action Button, by the looks of it:

Forum for Xojo Programming Language and IDE. Copyright © 2021 Xojo, Inc.