Context Menu

I am creating a contextual menu with the menu items based on certain conditions. The mAllowCloseAreas and mAllowCloseOtherAreas are booleans set by checkboxes. If my checkboxes are unchecked, the menu is not showing. If I check one or the other or both checkboxes I get one or the other or both menus as shown below. But… When I uncheck the checkboxes, for some reason on a right click I am still getting a context menu with the last item unchecked being displayed. What am I missing.

[code] ContextAreaClicked = CheckMouseOverArea(x,y)

if ContextAreaClicked <> -1 then
// Add some items
if mAllowCloseAreas = True then
base.Append(New MenuItem(“Close Area”))
end if

if mAllowCloseOtherAreas = True AND UBound(AreaItems) > 0 then
  base.Append(New MenuItem("Close Other Areas"))
end if
Return True

end if[/code]

I think you might need to remove existing menu items before constructing your new menu

Add

While base.count > 0
base.remove(0)
Wend

After If Contextarea…

Sounds like (Xojo: Account Login)>]this Cocoa zombie menu bug

To workaround it, you have to keep a reference to the menu each time it is shown, so that next time around you can depopulate the old menu if you need it not to show…. depopulating the current base item doesn’t seem to work.

Thanks Jim it does sound like this. I’ll try it out. Your link does not seem to work

If you create your ContextualMenu in Control.ConstructContextualMenu, you do not have to deal with remove anything since the ContextualMenu is built each time you ask it using keyboard, ctrl-click or right-click.

What is in CheckMouseOverArea ?

What happens if you add an Else statement ?
(what are your boolean values, etc.)

This seems to be the bug though, it is not recreated every time. In my code above if I set either mAllowCloseAreas or mAllowCloseOtherAreas to true the relevant menu item is added to the context menu. If I then set them both to false, one menu item (i.e. the last one set to false) is always displayed on right click which makes me think base is persistent.

CheckMouseOverArea simply checks that the user is right clicking in the relevant area of my control. I only want the menu to appear if they click a certain area in the control. If they don’t click the relevant area CheckMouseOverArea returns -1

“base” is indeed recreated each time - if not, menu items would appear doubled, then tripled, etc.

Some remarks:

Make sure that base is really empty (Count = 0) when returning

And please note this line from the docs: [quote]If the event was fired because of a non-mouse event, then x and y are both set to -1[/quote]
So be sure to have this considered in your CheckMouseOverArea function.

And also from the docs: [quote]If you return False, the event is passed up the parent hierarchy[/quote]If for example you code above is in a ContainerControl returning False will trigger the ConstructContextualMenu of the window (should it be implemented) and more menu items will be added there.

Thanks Eli. There is a definite bug here and i’m pretty sure it is (Xojo: Account Login)"%20rel=“nofollow%20external”>Feedback%20Case%20#31366]this one that Jim Mckay pointed out. Ive been over and over this and Jim’s bug seems to be the issue.

If anyone has time to have a look, take a look at my example project here

The code in my example project is:

[code]Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) As Boolean
If chkDontAddMenu.Value = True Then
return False
else
base.Append(New MenuItem(“Test menu item”))
End If

return true
End Function
[/code]

So if the checkbox chkDontAddMenu.Value = true you would expect the context menu not to be created. Well it is. have a play with the linked project and see. i.e. base can’t be created every time or am I missing something obvious?

There is - in my opinion - no bug here. The error is coming from two things:

  • don’t use the Checkbox.Value property, use the State property instead
  • return True, not False

If chkDontAddMenu.State = Checkbox.CheckedStates.Checked Then Return True ...

In my opinion one shouldn’t use the Value property on Checkboxes anymore - it doesn’t work reliably, despite the remarks in the docs. I think Xojo should deprecate the Value property and remove it entirely at some point in the future.

About returning True in ConstructContextualMenu: as far as I know, returning True means: you have handled the construction of the menu. The text in the docs is a bit misleading: [quote]If you return True, the contextual menu is displayed.[/quote] I always understood it in the same way as with other events in the framework - like the MouseDown event for example:

[quote]Return True if you are going to handle the MouseDown. […]
If you return False, the system handles the MouseDown […].[/quote]
So I understand the ConstructContextualMenu event as follows:

[quote]Return True if you are going to handle the construction of the menu. […]
If you return False, the system handles the the construction of the menu (which might be the last called one).[…].[/quote]

Mike,

I created a ContextualMenu that display a list of files that appears in a Folder.

After removing a bug of my own, I can remove or add any file I want between two right-click (ctrl-click, etc.) and see the immediate difference: the Menu is re build between two ‘clicks’ (two times you right-click).
Now, if I remove a file between two right-click (etc.) I can really see the new Menu WITHOUT the removed file. Same if I add one (or many) files.

Things are not easy, but you certainly have a bad logic somewhere (no pun intended; I went there and I suffer from it until I realized that was MY logic who went wrong in the context). Sometimes you have to rethink the logic to get the results you want.