Message Boards Message Boards

Find which Locator is active in a Manipulate or LocatorPane?

Posted 7 years ago

I am working on something where I need to know which locator out of many is currently being changed.

(* edit, I cross posted here: https://mathematica.stackexchange.com/questions/156022/ subsequent edit, there are two nice answers posted at this URL. *)

Here is some working code that uses the second argument to Dynamic to identify which locator is active for a limited set of Locators. I'd like to extend this to many Locators. In this code, the Locators are hard-coded. I'd like to extend this programmatically so I can slot in the Locators and the Manipulator controls. I've tried various combinations of Hold* without really knowing what I am doing.

Does anyone know how I can achieve my goal of finding which is the active locator?

See some additional comments below the working code about an attempt to do this with LocatorPane.

DynamicModule[
 {active = 0, p},
 Manipulate[
  Column[
   {active,
     Deploy@Graphics[
      {
       {
        Locator@
         Dynamic[p[1, 1, 
           1], {((p[1, 1, 1] = {-1, Last[#]}; 
              active = {1, 1, 1}) &), ((active = 0) &)}],
        Locator@
         Dynamic[p[1, 1, 
           2], {((p[1, 1, 2] = #; 
              active = {1, 1, 2}) &), ((active = 0) &)}],
        Locator@
         Dynamic[p[1, 1, 
           3], {((p[1, 1, 3] = {1, Last[#]}; 
              active = {1, 1, 3}) &), (active = 0) &}]
        },
       Line[{p[1, 1, 1], p[1, 1, 2], p[1, 1, 3]}] 
       },
      PlotRange -> 2
      ]
    }
   ],
  {{p[1, 1, 1], {-1, -1}}, ControlType -> None},
  {{p[1, 1, 2], {0, 0}}, ControlType -> None},
  {{p[1, 1, 3], {1, 1}}, ControlType -> None}
  ]
 ]

Trying to do the same thing with a LocatorPane and Nearest. It is not clear to me that the 2 argument form of Dynamic is working here:

DynamicModule[{active = False, pt1 = {1, 1}/2, pt2 = {-1, 1}/2, 
  pt3 = {1, -1}/2},
 Row[
  {active,
   LocatorPane[
    {
     Dynamic[
      pt1, {((active = Nearest[pt1, #, 1][[1]]); 
         pt1 = {0, 1} #) &, ((active = 0) &)}],
     Dynamic[
      pt2, {((active = Nearest[pt2, #, 1][[1]]); 
         pt2 = #) &, ((active = 0) &)}]
     },
    Graphics[{Yellow, Disk[{0, 0}, 2]},
     PlotRange -> 2
     ]
    ]
   }
  ]
 ]
POSTED BY: W. Craig Carter
2 Replies

In LocatorPane, you can use CurrentValue["CurrentLocatorPaneThumb"] to get the index of the currently active thumb.

DynamicModule[{active = False, pts = {{1, 1}/2, {-1, 1}/2}},
 Row[
  {active,
   LocatorPane[
    Dynamic[pts,
     With[{t=CurrentValue["CurrentLocatorPaneThumb"]},
      If[t===1, pts[[1]]={0,1}*#[[1]], pts[[t]]=#[[t]]]
      ]&
     ],
    Graphics[{Yellow, Disk[{0, 0}, 2]},
     PlotRange -> 2
     ]
    ]
   }
  ]
 ]

There is an example of this in the documentation for TrackingFunction, which is the way Dynamic's second argument is exposed to users of Manipulate, but I'll look into adding it to the LocatorPane reference page too.

POSTED BY: Lou D'Andria

Thank you Lou, TrackingFunction is very useful. For other readers, there is a small problem with Lou's code, but it was enough to get me started--so double thanks Lou. Here is some code adapted from the doc page on TrackingFunction

Manipulate[
 Row@{
     Dynamic@CurrentValue["CurrentLocatorPaneThumb"], 
        Graphics[Line[pts], PlotRange -> 2]
 },
{{pts, {{-1, -1}, {1, 1}}}, Locator, TrackingFunction -> 
   (If[ CurrentValue["CurrentLocatorPaneThumb"] === 1, 
        pts[[1]] = {#[[1, 1]],  pts[[1, 2]]},
        pts[[2]] = {pts[[2, 1]], #[[2, 2]]}] &)
 }

]

POSTED BY: W. Craig Carter
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract