4
$\begingroup$

How do I make ActionMenu's menu appear with one mouseclick of the button and disappear with a second consecutive click on the same button? I would like to be able to click on an ActionMenu in order to inspect the action labels and then click on the ActionMenu button again to close the menu. I believe this behavior is likely seen in many operating systems. This functionality doesn't appear to be obviously supported within Mathematica's control objects, but I hope I'm wrong.

As my first attempt to get this working, I tried the following hoping that the EventHandler would re-evaluate the ActionMenu and set it to the initial view with the menu not visible but this "hacky" attempt didn't yield anything. Here's the code:

EventHandler[ActionMenu["Print Factorials", {"4!" :> Print[4!], "7!" :> Print[7!], 
"10!" :> Print[10!]}], {"MouseClicked" :> ActionMenu[
"Print Factorials", {"4!" :> Print[4!], "7!" :> Print[7!], 
 "10!" :> Print[10!]}]}, PassEventsDown -> True]

I've also tried using Mouseover to achieve this idiomatic functionality without any luck. Again, here's the code in case this helps:

Mouseover[ActionMenu[
Style["Print Factorials", FontFamily -> "Arial", 
FontSize -> 12], {"4!" :> Print[4!], "7!" :> Print[7!], 
"10!" :> Print[10!]}, Appearance -> None, Enabled -> False], 
ActionMenu[
Style["Print Factorials", FontFamily -> "Arial", 
FontSize -> 12], {"4!" :> Print[4!], "7!" :> Print[7!], 
"10!" :> Print[10!]}, Appearance -> None]]
$\endgroup$
9
  • $\begingroup$ The default behaviour of ActionMenu seems to be exactly as you want it to... if you click on any menu item or outside of the menu, it disappears. $\endgroup$
    – Gerli
    Dec 4, 2015 at 11:36
  • 1
    $\begingroup$ @Gerli, create an ActionMenu and click the button to display the menu and then click the button again only to see that the menu remains displayed. I never allowed for clicking outside of the button in my question but yes, I realize that this does cause the menu to disappear. Now just try clicking the start menu in windows or a menu button on Linux and click once again on the same button to see the menu disappear. I really don't see how this could be any more clearly asked in the subject. $\endgroup$
    – rfrasier
    Dec 5, 2015 at 10:50
  • $\begingroup$ I voted to reopen, but you may want to add why you don't use a PopupMenu instead of an ActionMenu. $\endgroup$
    – Karsten7
    Dec 5, 2015 at 11:45
  • $\begingroup$ Using PopupView is another alternative. $\endgroup$
    – Karsten7
    Dec 5, 2015 at 11:58
  • 1
    $\begingroup$ @Karsten 7., thanks for reopening. The functionality of PopupMenu and PopupView satisfy my question regarding clicking to reveal and hide the menu, but my use-case constraint is to have an evaluation triggered by the selection of a menu item. For example, I'd like to have a new notebook opened with some operations done. This evaluation functionality didn't seem obvious to me in PopupMenu. $\endgroup$
    – rfrasier
    Dec 5, 2015 at 13:24

2 Answers 2

4
$\begingroup$

Since a PopupMenu exhibits a behavior you are after, let's adjust it to act like an ActionMenu:

myActionMenu[lbl_, actions_, opts___] := DynamicModule[{x = Unique[x]},
  PopupMenu[Dynamic[x, (# /. actions) &], First /@ actions, lbl, opts]
]


myActionMenu[
   "Print Factorials", 
   {"4!" :> Print[4!], "7!" :> Print[7!], "10!" :> Print[10!]}
]
$\endgroup$
3
$\begingroup$

A modified version of the solution provided by Kuba, that behaves like an ActionMenu with the option setting Method -> "Queued"

popupActionMenu[lbl_, actions_] := 
 DynamicModule[{x, trigger}, 
  Row[{PopupMenu[Dynamic[Refresh[x, TrackedSymbols :> {}], (trigger =.; trigger = #) &], 
     First /@ actions, lbl, BaseStyle -> "ActionMenu", Appearance -> "ActionMenu"], 
    DynamicWrapper["", Refresh[trigger /. actions, TrackedSymbols :> {trigger}], 
     SynchronousUpdating -> False]}]]


popupActionMenu["Print Factorials", 
  {"4!" :> Print[4!], "7!" :> (Pause[6]; Print[7!]), "10!" :> Print[10!]}]

The DynamicWrapper could be replaced with

Dynamic[trigger /. actions; "", TrackedSymbols :> {trigger}, SynchronousUpdating -> False]

A version based on PopupView

popupActionMenu[lbl_, actions_] := DynamicModule[{n = 1},
  PopupView[actions[[All, 1]], Dynamic[n, (actions[[#, 2]]) &], ActionMenu[lbl, {}]]]


popupActionMenu["Print Factorials", 
  {"4!" :> Print[4!], "7!" :> Print[7!], "10!" :> Print[10!]}]
$\endgroup$
1
  • $\begingroup$ It seems that initial assignment fixes first action problem. $\endgroup$
    – Kuba
    Dec 6, 2015 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.