2
votes

I made a progressIndicator that works just fine inside Manipulate. I click on a button, which calls a function foo[] which does work, and as it is working, the progressIndicator dynamically shows the progress the function is making.

But when I make a copy of the Manipulate display itself to create a copy of it in another cell, now clicking on the first display stops working, and the progressIndicator in the copy is the one which updates instead.

I have no global symbols. The variables used in the progressIndicator is inside the Manipulate.

Would any one knows how to resolve this? This is a problem, since in making a demo, one must make a copy of the Manipulate itself in the notebook in few places (make few snapshots), and hence no global variables are allowed to be used, else problems can show up.

I made small example to show the problem:

Manipulate[
 x,
 Grid[{
   {Control[{{x, 0, "x="}, 0, 1, .1}], SpanFromLeft},

   {Button[Text[Style["run", 11]], {y = 0; foo[]}, ImageSize -> 100, 
     Method -> "Queued"],
    Button[Text[Style["clear", 11]], y = 0, ImageSize -> 100]},

   {Dynamic[ProgressIndicator[y, {0, 1}, ImageSize -> 100]]},
   {Dynamic[Text@Row[{ Style[ y*100 , 11], Style["%", 11]}]]}
   }, Spacings -> {0, .3}],

 {{y, 0}, None},

 TrackedSymbols :> {x}, (*does nothing, just for testing *)

 SynchronousUpdating -> False,
 SynchronousInitialization -> False,
 Initialization :>
  (
   foo[] := Module[{i},
     Do[Pause[.15]; y = i, {i, 0, 1, .1}] (*Pause[] to slow it down*)
     ]
   )
 ]

After you run the above, if you copy the Manipulate display itself to a new empty cell, and hit the clear button to reset the counter, and then hit the run the button again on the first Manipulate, you will see that the progress indicator of the second copy is now updating, not the first one.

I must have some shared symbols there, but I do not see where that is.

enter image description here

Thanks for any help.

Update 1

Ok, I added DynamicModule[{symbolsNamesHere}, Manipulate[...]]

This resolved the problem with the 'sharing' between snapshots, so now the ProgresssIndicator works ok in all copies.

But demo CDF is not processed. Here is screen shot

enter image description here

ps. send email to WRI, as I do not understand this error. Never used DownValues.

2

2 Answers

3
votes

Maybe you could try something like

Manipulate[x, 
 Grid[{
    {Control[{{x, 0, "x="}, 0, 1, .1}], SpanFromLeft}, 

    {Button[Text[Style["run", 11]], {y = 0; foo[Unevaluated[y]]}, 
      ImageSize -> 100, Method -> "Queued"],
     Button[Text[Style["clear", 11]], y = 0, 
      ImageSize -> 100]}, 

    {Dynamic[ProgressIndicator[y, {0, 1}, ImageSize -> 100]]}, 

    {Dynamic[Text@Row[{Style[y*100, 11], Style["%", 11]}]]}}, 
  Spacings -> {0, .3}],

 {{y, 0}, None}, 

 TrackedSymbols :> {x, y},(*does nothing,just for testing*)
 SynchronousUpdating -> False, SynchronousInitialization -> False, 
 Initialization :> (foo[a_] := 
    Module[{i}, 
      Do[Pause[.15]; a = i, {i, 0, 1, .1}] (*Pause[] to slow it down*)])
]

The only difference is that in this code, foo is defined as a function of a parameter instead of using y directly which should solve the scoping problems you were having. To update y in the Manipulate you would then use foo[Unevaluated[y]].

3
votes

foo is the shared symbol. You can localize it using DynamicModule[{foo}, Manipulate[...]].

Update

Apparently, Wolfram Demonstrations will not accept the construct as presented. As a work-around, perhaps this will work instead:

Manipulate[
    (* ... *)
    {{y, 0}, None},
    {foo, None}, (* <-- added an empty manipulator for foo *)
    (* ... *)
    Initialization :>
    (
      foo =.; (* <-- unbind foo before defining it *)
      foo[] := Module[{i},
        Do[Pause[.15]; y = i, {i, 0, 1, .1}] (*Pause[] to slow it down*)
      ]
    )