Usage Examples for DynamicWrapper
Suppose we have a Graphics
object which depends on some parameters and a controller with which we want to control these parameters. This could be done easily enough using the second argument of Dynamic
, for example
gr[pts_, col_, radius_] := Graphics[{col, Disk[#, radius] & /@ pts},
PlotRange -> {{0, 3}, {0, 3}}, ImageSize -> 200];
contrl = {1, radius};
col = Blue; radius = .1;
pts = RandomReal[3, {10, 2}];
Grid[{{Dynamic[Framed[gr[pts, col, radius]]],
Slider2D[Dynamic[cntrl,
(cntrl = #; col = Blend[{Red, Blue}, cntrl[[1]]]; radius = cntrl[[2]])&]]
}}]
However, suppose that we also want a switch which switches the coupling between the controller and the plot on and off. With DynamicWrapper
this can be done by doing something like this
Grid[{{Dynamic[Framed[gr[pts, col, radius]]],
Slider2D[Dynamic[cntrl]],
Toggler["Off", {DynamicWrapper["On",
col = Blend[{Red, Blue}, cntrl[[1]]]; radius = cntrl[[2]]],
"Off"}]
}}]
By clicking on the label of the slider you can then toggle between coupling or no coupling. The same effect can be achieved without using DynamicWrapper
for example
DynamicModule[{state = "Off"},
Grid[{{Dynamic[Framed[gr[pts, col, radius]]],
Labeled[Slider2D[Dynamic[cntrl,(cntrl = #;
If[state === "On", col = Blend[{Red, Blue}, cntrl[[1]]];
radius = cntrl[[2]]]) &]],
Toggler[Dynamic[state], {"On", "Off"}], Top]
}}]
]
but imho the DynamicWrapper
solution is more elegant in this case.
How about a 'Next page' button that becomes active only if the user has seen or at least scrolled to a particular part of a page, a disclaimer for instance?
EDIT
As requested: this was what I had in mind
texts = ExampleData["Text"];
i = 1;
imax = texts // Length;
bottomSeen = False;
Panel[
Column[
{
Button["Next page", If[i <= imax, i++, i = 1]; bottomSeen = False;,
Enabled -> Dynamic[bottomSeen]],
Dynamic[
Pane[
Column[
{
ExampleData[texts[[i]]],
,
DynamicWrapper["SEEN THIS", bottomSeen = True]
}],
ImageSize -> {500, 150}, Scrollbars -> True,
ScrollPosition -> {1, 1}
]
]
}
]
]
There's one problem I didn't anticipate: a DynamicWrapper
placed in a Pane
is activated as soon as the Pane is visible even when the DynamicWrapper
content is scrolled outside the visible window of the Pane. I haven't solved that yet.
It seems to me that it is not so much that something would be hard to implement without DynamicWrapper
but that using that function offers an alternative and perhaps cosmetically/aesthetically better option.
My typical usage would be where I need to have an expression or compound expression dynamically evaluate (things that come to mind are evaluations that determine the list for a popup menu). Dynamic
needs to display so you could just stick a spacer at the end of Dynamic
:
DynamicModule[{a, b},
Column[{
Style["Heading", "Section"],
Dynamic[b = 2 a + 1; Spacer[0]],
Slider[Dynamic[a]],
Dynamic[{a, b}]
}]
]
or do something like this:
DynamicModule[{a, b},
Column[{
DynamicWrapper[Style["Heading", "Section"], b = 2 a + 1],
Slider[Dynamic[a]],
Dynamic[{a, b}]
}]
]
but as per documentation this is the same as writing
DynamicModule[{a, b},
Column[{
Dynamic[b = 2 a + 1; Refresh[Style["Heading", "Section"], None]],
Slider[Dynamic[a]],
Dynamic[{a, b}]
}]
]
So using DynamicWrapper
is just a personal preference (IMO).