I've created a function test[], which could also be a symbol test, if need be, and I'm trying to implement it in a manipulate. test[] looks like this:
test[]:=Button["Label",Functionality[]];
This will return an error if used directly in a Manipulate[], but works if it is wrapped in a Dynamic or an Evaluate.
Manipulate[content,test[]];
Manipulate::vsform: Manipulate argument test[] does not have the correct form for a variable specification.
Manipulate[content,Dynamic[test[]]]
This one works
Manipulate[content,Evaluate[test]]
Note that while this works, test is not a function
Manipulate[content,Evaluate[test[]]]
This works on my mac, but not my PC at work...
I think the issue is something to do with Manipulate being HoldAll, but don't understand why Dynamic[] should fix this. Also, Evaluate[] will only work some of the time.
So, why is the Dynamic[] or Evaluate[] necessary? Looking under the custom controllers section of the advanced manipulate tutorial, I see no references to this issue, and could not find any elsewhere.
You can inline the Button
instead of using a separate test[]
function. Otherwise you last example, Manipulate[content,Evaluate[test[]]]
, does show the button on my machine in Mathematica 8. There should be no difference between platforms (Windows or Mac).
If you're doing something sufficiently different from what Manipulate
provides by default, you may find it more convenient to build it from scratch using Dynamic
(this is what I usually do).
Here's an example of how to include some buttons as controllers.
First, set up something to show inside the Manipulate
:
rotate90[{x_, y_}] := {-y, x}
koch[p1_, p2_, n_] := {koch[p1, p1 + (p2 - p1)/3, n - 1],
koch[p1 + (p2 - p1)/3, (p1 + p2)/2 + Sqrt[3]/6 rotate90[p2 - p1],
n - 1], koch[(p1 + p2)/2 + Sqrt[3]/6 rotate90[p2 - p1],
p2 - (p2 - p1)/3, n - 1], koch[p2 - (p2 - p1)/3, p2, n - 1]}
koch[p1_, p2_, 0] := Line[{p1, p2}]
snowflake[n_] :=
Graphics[{koch[{0, 0}, {1, 0}, n],
koch[{1, 0}, {1/2, -Sqrt[3]/2}, n],
koch[{1/2, -Sqrt[3]/2}, {0, 0}, n]}]
Then set up the Manipulate
itself:
Manipulate[snowflake[n], {{n, 2}, ControlType -> None},
Style["A Koch snowflake", Bold], Delimiter,
Row[{Button["+", n++], Button["-", n = Max[n - 1, 0]]}]]
Here's an example showing that this works even if the Button
is defined in a separate function:
SetAttributes[paletteButton, HoldRest]
paletteButton[name_, func_] :=
Button[name, func, Appearance -> "Palette"]
Manipulate[snowflake[n], {{n, 2}, ControlType -> None},
Style["A Koch snowflake", Bold], Delimiter,
Evaluate@paletteButton["+", n++]]
As you mentioned in your question, here it is necessary to wrap the function in Evaluate
to obtain an inlined Button
. Otherwise Manipulate
will not be able to notice that what we have here is a control and not a variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With