MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

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

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.

    Refresh[xFlag = True; yFlag = False; "", TrackedSymbols -> {x}]],
    Refresh[xFlag = False; yFlag = True; "", TrackedSymbols -> {y}]],
    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}]

John Fultz
jfultz at
User Interface Group
Wolfram Research, Inc.

On Thu, 8 Oct 2009 07:49:43 -0400 (EDT), Nasser Abbasi wrote:
> "Nasser Abbasi" <nma at> wrote in message
> news:hafbgr$j4r$1 at
>>> 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=
> ask one more time, may be some expert can have a solution. But this one=
> 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=
> 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=
> 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

  • Prev by Date: Re: Re: undocumented feature: TableView
  • Next by Date: Re: Re: generating submultisets with repeated elements
  • Previous by thread: Re: Re: How to find which variable caused the trigger in Manipulate[]
  • Next by thread: Re: Re: Re: How to find which variable caused