I am looking for practical uses of the function DynamicWrapper
. I read documentation and know whatever it says. I would appreciate a clear example of a useful dynamic interface (an app) that would be hard to implement without DynamicWrapper
.
-
1$\begingroup$ There's some good examples here and here. $\endgroup$– Greg HurstCommented Jan 22, 2019 at 20:22
-
$\begingroup$ @ChipHurst thank you, very nice ! $\endgroup$– Vitaliy KaurovCommented Jan 22, 2019 at 20:23
3 Answers
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.
-
$\begingroup$ BTW, the only reason I did not vote for this is that I do not have
DynamicWrapper
to test it with. Looks nice though. $\endgroup$ Commented Jan 25, 2012 at 14:05
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.
-
$\begingroup$ Is it possible to sketch up some code example? $\endgroup$ Commented Jan 25, 2012 at 17:39
-
$\begingroup$ @vitaly see update. I'm not there yet. $\endgroup$ Commented Jan 25, 2012 at 23:18
-
$\begingroup$ I think the fact that the cell (rather than the containers like
Pane
orPanel
) displaying theDynamicWrapper
object is visible is causing the unwanted update. To see this, you modify the first example in theBasic Examples
section of theDynamicWrapper
page in the doc center as{DynamicWrapper["xxx", b = 2 a + 1], "\n\n\n\n\n\n\n\n\n\n"}
and scroll up/down as you play with the Slider in the following input cell. $\endgroup$– kglrCommented Jan 26, 2012 at 5:23
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).