Search code examples
wolfram-mathematicatogglebutton

Adjust TogglerBar button size in Mathematica


Is it possible to adjust the size/font of the TogglerBar, so that they are all equally large in case of different name size.

The example below is the solution proposed by Belisarius for : "Can TogglerBar be used as multiple CheckBox in Mathematica ?"

I would like each Button to be equally sized.

Manipulate[Graphics[
{
{White, Circle[{5, 5}, r]},(*For Mma 7 compatibility*)
If[MemberQ[whatToDisplay, "I am a Circle"],
{Red, Circle[{5, 5}, r]}],
If[MemberQ[whatToDisplay, "and I am a very nice Square"], {Blue,
Rectangle[{5, 5}, {r, r}]}],
If[MemberQ[whatToDisplay, "Other"], {Black,
 Line[Tuples[{3, 4}, 2]]}]
},
PlotRange -> {{0, 20}, {0, 10}}
],
{{r, 1, Style["Radius", Black, Bold, 12]}, 1, 5, 1,
ControlType -> Slider,
ControlPlacement -> Top},  
Control@{{whatToDisplay, True,
Style["What", Black, Bold, 12]}, {"I am a Circle",
"and I am a very nice Square", "Other"},
ControlType -> TogglerBar,
Appearance -> "Horizontal",
ControlPlacement -> Top}]

enter image description here

EDIT : It is trully ugly in the code (if we can still call that a code) but looks good on display.

enter image description here

enter image description here


Solution

  • Mathematica 8 introduced Overlay which allows multiple expressions to be easily overlaid atop each other. Coupled with Invisible (from v6), we have all the necessary ingredients to easily synchronize all of the button sizes without resorting to counting spaces or pixels. The following code illustrates their use, with the relevant parts emphasized:

    DynamicModule[{options, allLabels, size, pad}
    , options =
        { "I am a Circle" -> {Red, Circle[{5, 5}, size]}
        , "and I am a very nice Square" -> {Blue, Rectangle[{5, 5}, {size, size}]}
        , "Other" -> {Black, Line[Tuples[{3, 4}, 2]]}
        }
    ; allLabels = options[[All, 1]]
    ; pad[label_] :=
        Overlay[Append[Invisible /@ allLabels, label], Alignment -> Center]
    ; Manipulate[
        Graphics[what /. options /. size -> r, PlotRange -> {{0, 20}, {0, 10}}]
      , {{r, 1, "Radius"}, 1, 5, 1}
      , {{what, {}, "What"}, # -> pad[#] & /@ allLabels, TogglerBar}
      ]
    ]
    

    Manipulate result

    The definition:

    pad[label_] :=
      Overlay[Append[Invisible /@ allLabels, label], Alignment -> Center]
    

    defines a function that stacks all of the labels invisibly atop one another, and then puts the desired label visibly on top of that. The result is the desired label with enough whitespace on either side to accommodate any of the other labels.

    The Manipulate statement uses pad to create the labels for the TogglerBar:

    {{what, {}, "What"}, # -> pad[#] & /@ allLabels, TogglerBar}

    Note that the labels are specified in the form value -> label to allow the values to retain their original form without the Overlay and Invisible specifiers added by pad.