Re: Re: How to find which variable caused the trigger in Manipulate[]
- To: mathgroup at smc.vnet.net
- Subject: [mg103895] Re: [mg103821] Re: How to find which variable caused the trigger in Manipulate[]
- From: "Nasser Abbasi" <nma at 12000.org>
- Date: Sun, 11 Oct 2009 08:05:54 -0400 (EDT)
- References: <200910916541.056199@jfultz2winlap>
- Reply-to: "Nasser Abbasi" <nma at 12000.org>
"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