Re: Re: Re: How to find which variable caused the trigger in Manipulate[]
- To: mathgroup at smc.vnet.net
- Subject: [mg103919] Re: [mg103879] 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:39:02 -0400 (EDT)
- Reply-to: jfultz at wolfram.com
I was quite explicit about this in my previous email... >> * Use separate Dynamics, which display inside a Row[] as empty strings I.e., the Row is scoping two empty strings and the Text[]. Replacing Row with Column makes empty space because empty strings take up a full line height in a Column. The controls come from the surrounding Manipulate, and so nothing inside the Row is displaying as a column. Sincerely, John Fultz jfultz at wolfram.com User Interface Group Wolfram Research, Inc. On Sun, 11 Oct 2009 14:30:22 -0500, DrMajorBob wrote: > Why does that Row display as a column? (Even when I stretch the window > over two monitors.) > > Replacing Row with Column gives the same result, except that there's a lot > of excess space in the Text box... even when I specify 0 as the 3rd > argument, as in > > Manipulate[ > Column[{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"]]]}, Left, 0], {x, 0, 1}, {y, 0, 1}, {{xFlag, False}, > ControlType -> None}, {{yFlag, False}, ControlType -> None}] > > Why is that? > > Bobby > > On Sat, 10 Oct 2009 06:09:45 -0500, John Fultz <jfultz at wolfram.com> 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 >> jfultz at wolfram.com >> User Interface Group >> Wolfram Research, Inc. >> >> >> On Thu, 8 Oct 2009 07:49:43 -0400 (EDT), Nasser Abbasi wrote: >> >>> >>> "Nasser Abbasi" <nma at 12000.org> wrote in message >>> news:hafbgr$j4r$1 at smc.vnet.net... >>> >>>>> Again, I want something like this >>>>> >>>>> Manipulate[ >>>>> process[( pickTheCorrectControlVariableWhichChanged ], >>>>> {a, 0, 1}, {b, 0, 1}, Initialization :> >>>>> >>>>> (process[arg_] := Module[{}, Plot[Sin[arg*x], {x, -Pi, Pi}]]) >>>>> ] >>>>> >>> >>>> I made some progress and I think I have a solution. >>>> >>>> I save the old value of each control variable in a global variable, >>>> then >>>> in >>>> the Manipulate expression, I check, using an If statement which >>>> current >>>> value of the control variable is different from the old value. I >>>> got it >>>> to >>>> work ok finally. >>>> >>>> Here is an example: >>>> >>>> olda = 999; >>>> oldb = 999; >>>> >>>> Manipulate[ >>>> If[olda != a, {olda = a; Style[StringJoin["a=", ToString[a]]]}, >>>> >>>> If[oldb != b, {oldb = b; Style[StringJoin["b=", ToString[b]]]}, >>>> >>>> Text["this message should NOT show up!"]]], {a, 0, 1}, {b, 0, 1}, >>>> >>>> LocalizeVariables -> True, TrackedSymbols -> {a, b}] >>>> >>>> >>> It is me again, with the same problem. >>> >>> I found out that I can NOT use global variables in a demo, and I also >>> can't >>> wrap the whole Manipulate inside a module. Any one of the above method >>> will >>> have solved this problem, but rules are rules, so now I have to find >>> another >>> solution. So I am stuck again. >>> >>> Before I recode everything again, which I would hate to do, I thought= >> I'll >>> ask one more time, may be some expert can have a solution. But this >>> one= >> is >>> really hard. >>> >>> I'll explain again the problem to make sure we are all clear on it. >>> >>> I need to write a Manipulate where inside the Manipulate I need to >>> detect >>> which slider or in other words, which control variable was changed. >>> i.e. >>> which slider the user just changed to cause the Manipulate expression >>> to >>> be >>> generated. (I need to do this so I can do different processing based >>> on >>> the >>> slider that was selected) >>> >>> We all know that Manipulate generates a new version of its expression= >> when >>> one of the control variables changes value. I need to know which >>> control >>> variable changed. >>> >>> There is the general layout >>> >>> Manipulate[ >>> >>> (* expression that uses control variables *) >>> >>> , >>> >>> (* controls here which update the control variables values *) >>> ] >>> >>> But there are restriction on the solution, since this will be for a >>> demo. >>> Again, there can NOT be global variables used, (i.e. no variables in >>> the >>> Manipulate initialization section, since these are global), and there >>> can >>> NOT be a module around Manipulate[], i.e. no Module[{...}, >>> Manipulate[...]] >>> allowed. >>> >>> Here is a small code to show the problem >>> >>> Manipulate[ >>> Text[StringJoin["you moved the ", "x or y", " slider"]], >>> {x, 0, 1}, >>> {y, 0, 1} >>> ] >>> >>> Could someone modify the above, so that the code above will tell which >>> slider the user _just_ moved? >>> >>> It seems like an impossible problem for me to solve without the use of >>> global variables or a module around Manipulate. >>> >>> Here is what I tried so far, and this fail: >>> >>> Manipulate[ >>> Which[ >>> >>> x != oldx, >>> {oldx = x; Text[StringJoin["you moved the ", "x ", " slider"]]}, >>> >>> y != oldy, >>> {oldy = y; Text[StringJoin["you moved the ", "y ", " slider"]]}, >>> >>> True, Text["why Ami here??"] >>> ], >>> >>> {x, 0, 1}, >>> {y, 0, 1}, >>> {oldx, -999, ControlType -> None}, >>> {oldy, -999, ControlType -> None} >>> ] >>> >>> The reason it fail is because oldx and oldy are updated to the same >>> value >>> of >>> x and y whenever x or y changes before I get the chance to do the >>> comparison. I.e. when the new version of the expression is generated, >>> oldx=x >>> and oldy=y each time. This seems to consequences of Manipulate= >> generating >>> DynamicModule[] for the whole thing. You can see this by using the >>> SnapShot >>> option on the Manipulate output. This will generate the whole >>> expression >>> form. (Nice tool). >>> >>> If someone can make it so that the above will display the correct >>> message >>> each time, then I would declare that person to be the Mathematica Guru >>> of >>> the year. >>> >>> I think I have reached the limit of my current Mathematica >>> understanding >>> when it comes to internals of Manipulate and Dynamics to be to solve >>> this >>> one. But I'll keep on looking. >>> >>> Thank you, >>> --Nasser