3
$\begingroup$

Question

What is the shortest method to make a PopupMenu with custom appearance, e.g. something like:

wrapper = Framed[#, FrameMargins -> 25] &;
spec = {1 -> "label", 2 -> "label2"};

wrapper @ PopupMenu[Dynamic[test], spec, Appearance -> None]

enter image description here

But the problem here is that only the inner content of the wrapper triggers menu. wrapper needs to be the menu.

Problems I've faced

  • This won't work as the head of the first argument needs to be Dynamic.

    PopupMenu[ wrapper @ Dynamic[test], spec]
    
  • This should work but it does not, it seems that unless the first arg of Dynamic exactly matches a value it won't be shown.

    PopupMenu[
      Dynamic[wrapper@test, (test = #) &]
    , spec
    , Appearance -> None
    ]
    
  • I was about to create something from scratch with DynamicModule and a temporary variable etc, but then I realized I'd have to handle all possible specifications of the second argument of Dynamic, Automatic 1-2-3 functions etc. (see stress test)

Requirements

So I'm asking question in hope that I've missed something basic.

The goal is to create MyCustomPopup which has custom wrapper as an appearance but it also should be ready to replace every PopupMenu in my codebase.

Here's a stress test:

PopupMenu[Dynamic[test, {Automatic, Print[test]&} ], {1 -> "label"}]

PopupMenu[Dynamic[test, {None, Automatic, Print[test]&} ], {1}]
$\endgroup$
4
  • $\begingroup$ p.s. AttachedCell won't do because notebook's frame clips it, while native menus can live outside. $\endgroup$
    – Kuba
    Oct 19, 2017 at 17:24
  • 1
    $\begingroup$ PopupMenu can take a fourth argument which does just this. Most custom PopupMenus I've seen use a button with an Option based Appearance in the fourth argument and set Appearance->None $\endgroup$
    – b3m2a1
    Oct 19, 2017 at 17:29
  • $\begingroup$ @b3m2a1 I bet I knew that, well, what are you waiting for? $\endgroup$
    – Kuba
    Oct 19, 2017 at 18:20
  • $\begingroup$ No time to write up a good answer now. I'll get to it soon, if no one else does so first. $\endgroup$
    – b3m2a1
    Oct 19, 2017 at 19:24

1 Answer 1

5
$\begingroup$

This is what the 4th argument to PopupMenu is for. Here's a quick example:

PopupMenu[Dynamic[a],
 {1, 2, 3},
 "asd",
 Button[Dynamic[a],
  Appearance -> 
   FrontEndResource["MUnitExpressions", "ButtonAppearances"],
  ImageSize -> {100, 35}
  ],
 Appearance -> None
 ]

example

Using Button for this seems to be the standard thing used internally, based on what I've seen in interface notebooks.

Here's what it looks like clicked:

click

Note for ActionMenu this is often used, too, but the interface element is simply the first argument. I use this all the time. For example here's a screenshot from my basic dev helper palette:

ex2

Except for that toggle bar, all of this is done using that type of trick, and using Button with the Options type Appearance.

$\endgroup$

Your Answer

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

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