Re: Re: How to find which variable caused the trigger in Manipulate[]

*To*: mathgroup at smc.vnet.net*Subject*: [mg103918] Re: [mg103821] Re: How to find which variable caused the trigger in Manipulate[]*From*: John Fultz <jfultz at wolfram.com>*Date*: Mon, 12 Oct 2009 06:38:50 -0400 (EDT)*Reply-to*: jfultz at wolfram.com

This looks to me like a bug, but one that is very simple to work around. Use Rule instead of RuleDelayed for the Refresh. I.e., Manipulate[ Row[{Dynamic[Refresh[r = process["x "]; "", TrackedSymbols -> {x}]], Dynamic[Refresh[r = process["y "]; "", TrackedSymbols -> {y}]], Dynamic[Refresh[Text[r], TrackedSymbols -> {x, y}]]}], {x, 0, 1}, {y, 0, 1}, {r, "", "", ControlType -> None}, Initialization :> (process[s_String] := Module[{}, Text[StringJoin[s, DateString[]]]])] After a bit of experimentation, my advice is to completely avoid RuleDelayed with the TrackedSymbols option. Sincerely, John Fultz jfultz at wolfram.com User Interface Group Wolfram Research, Inc. On Sat, 10 Oct 2009 12:20:44 -0500, Nasser Abbasi wrote: > > > "This is a very simple version of what you asked for that doesn't solve > some > of > the fundamental problems you'll probably come across, but it shows you the > techniques to solving them. Principally... > > * Contain all evaluation inside of scoped Dynamics to prevent the entire > Manipulate from refreshing. > * Add flag variables (and perhaps you'll want other variables, too) as > control > variables, but with ControlType->None so they don't appear. > * Use separate Dynamics, which display inside a Row[] as empty strings > (this > is > important...remember that if a Dynamic doesn't display onscreen, then > there's > nothing available to update...see my previous posts on Dynamic if you're > at > all > confused about this), to track the individual variables. > + These separate Dynamics each scope a single variable only. > + The scoped variable is determined by using Refresh with TrackedSymbols > > One of the problems my version doesn't solve is sensibly setting a start > condition, so the evaluation assumes that the initial state has changed > the > y > parameter (as a result of the initial creation of the flag-tracking > dynamics). > That's a problem I'll let you figure out. > > > Manipulate[Row[{ > Dynamic[ > Refresh[xFlag = True; yFlag = False; "", TrackedSymbols -> {x}]], > Dynamic[ > Refresh[xFlag = False; yFlag = True; "", TrackedSymbols -> {y}]], > Dynamic[ > Text[StringJoin["you moved the ", Which[xFlag, "x", yFlag, "y"], > " slider"]]] > }], > {x, 0, 1}, {y, 0, 1}, > {{xFlag, False}, ControlType -> None}, > {{yFlag, False}, ControlType -> None}] > > > Sincerely, > > John Fultz" > > > Fantastic John. > > The Dynamic[Refresh[....., TrackedSymbols->{...}]] is the construct I was > looking for. This tells me which controls have changed. I've looked at > Refresh[] sometime ago, but must have looked at only its interval option > and > overlooked its other option which is TrackedSymbols. > > I have implemented the solution as I showed before using lots of flags > which > I was checking for inside Manipulate. > > But with the above method you showed is much better, and I have recoded > the > whole demo using this method, cutting the code size by 50% and making the > logic much simpler. > > There is one thing still not clear to me. If you look at the following > example I just wrote: > > Manipulate[ > > Row[{ > Dynamic[Refresh[r = process["x "]; "", TrackedSymbols -> {x}]], > Dynamic[Refresh[r = process["y "]; "", TrackedSymbols -> {y}]], > Dynamic[Refresh[Text[r], TrackedSymbols :> {x, y, r}]]} > ], > > {x, 0, 1}, > {y, 0, 1}, > {r, "", "", ControlType -> None}, > > Initialization :> > (process[s_String] := Module[{},Text[StringJoin[s, > DateString[]]]]) > ] > > The above works as I wanted. When the x or the y slider is moved, the= code > detects which one and shows the corresponding message. > > However, what I do not understand is why I had to write > > Dynamic[Refresh[Text[r], TrackedSymbols :> {x, y, r}]]} > > instead of just > > Dynamic[Refresh[Text[r], TrackedSymbols :> {x, y}]]} > > For it to work? i.e. why do I have to add "r" to the list of symbols to > track? Since it must be that either 'x' or 'y' must have changed by the > time > the code reaches this line, and so it should have been enough to just > check > for ANY of these 2 control variables to have changed. But I find that I > have > to also check for "r" being changed for the message to appear, i.e. for > Text[r] to be executed. > > Is TrackedSymbols :> {x, y} in the context of Dynamic[Refresh[expr,...]], > supposed to mean that if ANY one of these control variables changed then > evaluate expr ? > > Thank you again, your help was very valuable. > > --Nasser