PopupMenu - detect pre-selection "hover"/show MenuItem tooltip?

  1. 2 months ago

    Joshua H

    Mar 11 Pre-Release Testers, Xojo Pro USA
    Edited 2 months ago

    Is there an event or other technique to detect when a user is "hovering" on a row in a PopupMenu (before the .Change() event is fired)? What I'd like to do is show an item-sensitive Help Tag while the user is hovering. I don't see an obvious way to do this. This is a Desktop app (Mac OS X and Windows targets)

    Not sure about Windows, but it can be done in macOS pretty simply...

    Create a new class and set the super to PopupMenu. Then add a new method:

    Public Sub addrow(Text As String, ToolTip as String)
      super.AddRow(Text)
      
      #if TargetMacOS
        declare function menu lib "AppKit" selector "menu" (obj as ptr) as ptr
        declare function itemAtIndex lib "AppKit" selector "itemAtIndex:" (obj as ptr, index as integer) as ptr
        declare sub setToolTip lib "AppKit" selector "setToolTip:" (obj as ptr,tip as CFStringRef)
        
        setToolTip(itemAtIndex(menu(ptr(me.Handle)),me.ListCount-1),tooltip)
      #Endif
    End Sub
  2. Norman P

    Mar 11 Pre-Release Testers, Xojo Pro Alberta Canada

    What kind of app are we talking about ?
    Desktop ? Web ? iOS ?

  3. Joshua H

    Mar 11 Pre-Release Testers, Xojo Pro USA

    (updated)

  4. Norman P

    Mar 11 Pre-Release Testers, Xojo Pro Alberta Canada

    ah you mean over each element of the popup as a person hovers through them once the popup is open ?

  5. Joshua H

    Mar 11 Pre-Release Testers, Xojo Pro USA

    Yes, basically. Similar to the way HelpTags are displayed on other controls: after a brief pause on the item (row), I want to show a little blurb of text relevant to that row, for individual items of a PopupMenu (or MenuItem that is. Popup()'ed, if that makes it any easier to work with). For Desktop apps, it seems like there's no event corresponding to that (closest option I can see is MouseMove but that only provides X/Y position, not row index).

  6. Norman P

    Mar 11 Pre-Release Testers, Xojo Pro Alberta Canada

    i'm not even sure that at a very low level you'd have an easy time of this as on macOS the underlying PopUpButton doest have any tracking for this built in that I can see

    You'd almost need a "OverRow" event of some kind with the row index so you could craft the right help tag

  7. jim m

    Mar 11 Pre-Release Testers, Xojo Pro Answer piDog.com

    Not sure about Windows, but it can be done in macOS pretty simply...

    Create a new class and set the super to PopupMenu. Then add a new method:

    Public Sub addrow(Text As String, ToolTip as String)
      super.AddRow(Text)
      
      #if TargetMacOS
        declare function menu lib "AppKit" selector "menu" (obj as ptr) as ptr
        declare function itemAtIndex lib "AppKit" selector "itemAtIndex:" (obj as ptr, index as integer) as ptr
        declare sub setToolTip lib "AppKit" selector "setToolTip:" (obj as ptr,tip as CFStringRef)
        
        setToolTip(itemAtIndex(menu(ptr(me.Handle)),me.ListCount-1),tooltip)
      #Endif
    End Sub
  8. Joshua H

    Mar 11 Pre-Release Testers, Xojo Pro USA

    Oh, cool! That's great, I'll give it a try! I have a back-up plan for Windows (and fewer users there anyway) so this might do the trick for now. Thanks!!

  9. Norman P

    Mar 11 Pre-Release Testers, Xojo Pro Alberta Canada

    ah clever to set it when adding rows instead of trying to track it and do this at mouse move time

    that will mean every menu that wants a tip has to be created at runtime and not statically set up in the IDE but not sure thats a huge hit

  10. Joshua H

    Mar 11 Pre-Release Testers, Xojo Pro USA
    Edited 2 months ago

    The menu is already being built at runtime. I haven't noticed (nor received reports) of a lag, so what's a few more milliseconds :-)

  11. Norman P

    Mar 11 Pre-Release Testers, Xojo Pro Alberta Canada
    Edited 2 months ago

    none if this works
    so far I'm not seeing any tooltips here on 10.12 or 10.14

  12. Joshua H

    Mar 15 Pre-Release Testers, Xojo Pro USA

    Following up on this: I got @jim ms method working, although in a slightly modified form, as I ended up switching from PopupMenu to MenuItem (with .popup()) for other reasons. So I just made a new subclass of MenuItem with an override of MenuItem.Constructor(Text As String, Tag As Variant = Nil), as:

    Public Sub Constructor(Text as String, tag as Variant = Nil, hovertext as string = "")
      // Constructor(Text As String, Tag As Variant = Nil) -- From MenuItem
      Super.Constructor(Text, tag)
      
      #if TargetMacOS
        declare sub setToolTip lib "AppKit" selector "setToolTip:" (obj as ptr, tip as CFStringRef)
        
        setToolTip(ptr(self.Handle(HandleType.CocoaNSMenuItem)), hovertext)
        
      #Endif
      
    End Sub

    Works like a charm. I see the tool tip when I hover on the Menu Item, just like I wanted. Thanks a bunch for this idea, Jim!

or Sign Up to reply!