Manipulate with explicit updates
While your solution works, I personally find it a bit off, since you are actually trying to have dynamic controls for a variable, who's state you immediately change away from the dynamic value just to use it to trigger an event. In short, you want to have one of two actions associated with the button presses, and could code this explicitly using a custom control, rather then indirectly implementing it in the guise of a dynamic controller with an added added event trigger somewhere else. Here is an example of a custom control implementing the events directly:
Manipulate[
val,
{x, {1, 2, 3}, Setter},
{{val, 0, "operator"},
Row[{ Button["Call f", val = f[x]],
Button["Call g", val = g[x]]}] &}
]
Here I added a new scoped variable since the spec for Manipulate
needs to associate a variable with the custom control, even though it's not actually controlling any variable. If you wanted access to the operator that performed the last call, you could associate that variable with it.
Three variations using SetterBar
, ButtonBar
and Setter
s:
SetterBar
:
Manipulate[op, {x, {1, 2, 3}, SetterBar},
{{op, f[1], "op"}, {"f", "g"},SetterBar[Dynamic@op, {(f[x]) ->"f", (g[x]) ->"g"}] &},
TrackedSymbols -> {op}]
ButtonBar
:
Manipulate[op, {x, {1, 2, 3}, SetterBar},
{{op, f[1], "op"}, {"f", "g"}, ButtonBar[{"f" :> (op = f[x]), "g" :>(op = g[x])}] &},
TrackedSymbols -> {op}]
Two Setter
s:
Manipulate[op, {x, {1, 2, 3}, SetterBar},
Row[{Control[{{op, f[1], "op"}, {}, Setter[Dynamic[op], f[x], "f"] &}],
Control[{{op, g[1], ""}, {}, Setter[Dynamic[op], g[x], "g"] &}]}],
TrackedSymbols -> {op}]
@Mohsen. Here is a cleaned up version of your original Manipulate
. The Module
wrapper is eliminated by introducing val
as an invisible control. This is a common and useful way to introduce addition dynamic variables into a Manipulate
expression.
Manipulate[
If[op != "",
val = Switch[op,
"f", f[x],
"g", g[x]];
op = ""];
val,
{val, ControlType -> None},
{x, {1, 2, 3}, Setter},
{op, {"f", "g"}, Setter},
TrackedSymbols -> {op},
Initialization :> (op = ""; val = "";)]
It is also good to initialize op
and val
so that nothing is displayed until the first click is made on the "op" setter. With these minor changes your original approach is really quite valid.