Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

This follows up on another question about the sensitivity of Locators in a a LocatorPane.

I would like to be able to enable/disable individual locators in a LocatorPane. In the simplified version of the applet, pictured below, I would like to be able to disable the locators that set the slope of the red line, while allowing the locators that set the slope of the blue line to remain enabled.

locators

Using individual Locators, rather than a LocatorPane, is not an option. (There are some subtle issues that arise with individual locators. Essentially, multiple Locators can behave in a "flaky" fashion in complex applets, in ways that LocatorPane does not.)

Code below:

Manipulate[m = 15;
 LocatorPane[Dynamic[pts],
  Dynamic[ Module[{x = pts[[1, 1]], y = pts[[2, 2]], x2 = pts[[3, 1]], y2 = pts[[4, 2]]},
  Graphics[{
  {Blue, Line[{-m*{x2, y2}, m*{x2, y2}}]},
  Line[{{x2, 0}, {x2, y2}}], Line[{{x2, y2}, {0, y2}}],
  {Red, Line[{-m*{x, y}, m*{x, y}}]},
  Line[{{x, 0}, {x, y}}], Line[{{x, y}, {0, y}}]},
  PlotRange -> m, Axes -> True, ImageSize -> {300, 300}]]],
  {{{-m, 0}, {m, 0}, {1, 0}}, 
   {{0, -m}, {0, m}, {0, 1}}, 
   {{-m, 0}, {m, 0}, {1, 0}}, 
   {{0, -m}, {0, m}, {0, 1}}},
 Appearance -> {Automatic, Automatic, Automatic, Automatic}], 
 {{pts, {{6, 0}, {0, 9}, {3, 0}, {0, 7}}}, ControlType -> None}]

The visibility of the locators can be individually controlled by toggling the respective locator's Appearance between None and Automatic. But even when the locator is invisible (i.e. Appearance -> None) it continues enabled. For example, the red sliders will continue to set the slope of the red line.

A possible solution would be to obtain the Appearance setting of the red sliders and make the assignment of x and y contingent on the Appearance setting.

share|improve this question
2  
Could you describe briefly or link to a description of this unwanted "flaky" behavior of individual locators? –  jVincent Aug 6 '12 at 9:36
    
Ever time I tried to use individual locators (with out a LocatorPane I would run into a situation in which they would cease to be responsive after moving once. I take this to mean that some routines needed to be wrapped in Dynamic, but I could never figure out a solution, no matter how much I tried. So the flakiness may have been inherent to the Locators or a reflection of my inability to fully understand the use of Dynamic wrappers. –  David Carraher Aug 6 '12 at 13:12
1  
Sounds like an interesting problem, if you have code that exhibits this problem I think you should add it to your question or add a new question for it. –  jVincent Aug 6 '12 at 13:22
    
The problem rears its head in the context of a couple pages of code. Generally I avoid inflicting large amounts of code on others. –  David Carraher Aug 6 '12 at 14:36
    
"Generally I avoid inflicting large amounts of code on others." -- Something I think we all appreciate. Nevertheless it might make in interesting question, and you certainly haven't made a pest of yourself with wall-of-code questions. –  Mr.Wizard Aug 6 '12 at 19:50

2 Answers 2

up vote 6 down vote accepted

A simple way to do this is to change the Dynamic so that it updates only the points you want to be editable. Here is a very simple demonstration

 pts = {{6, 0}, {0, 9}, {3, 0}, {0, 7}};
 updatable = Range@Length@pts;
 Button["Fixate point 3", (updatable = {1, 2, 4})]
 LocatorPane[Dynamic[pts, (pts[[updatable]] = #[[updatable]]) &], 
 Dynamic@Graphics[Point /@ pts, PlotRange -> {{-10, 10}, {-10, 10}}]]
share|improve this answer
    
Interesting. I'll need some time before I can fully examine it, but it looks promising. –  David Carraher Aug 6 '12 at 13:14
1  
+1 It works like a charm. Very clever suggestion. –  David Carraher Aug 6 '12 at 14:51

I like @jVincent's approach.

Here is a different approach Overlaying LocatorPanes inside Manipulate :

locPane[Dynamic[pts_], shape_, color_] := 
 LocatorPane[Dynamic[pts], 
 Dynamic@Module[{x = pts[[1, 1]], y = pts[[2, 2]]}, 
 Graphics[{{color, Line[{-m*{x, y}, m*{x, y}}]}, 
  Line[{{x, 0}, {x, y}}], Line[{{x, y}, {0, y}}]}, PlotRange -> m,
  Axes -> True, ImageSize -> {300, 300}]],
 {{{-m, 0}, {m, 0}, {1, 0}}, {{0, -m}, {0, m}, {0, 1}}},
 Appearance -> {shape, shape}];
(* locator apperance graphics *)
redCircle = Graphics[{Red, Table[Circle[{0, 0}, i], {i, 2}]}, ImageSize -> 10];
blueCircle = Graphics[{Blue, Table[Circle[{0, 0}, i], {i, 2}]}, ImageSize -> 10];
grayDisk =  Graphics[{Lighter@Lighter@Gray, Disk[{0, 0}, 2], 
 Gray, Circle[{0, 0}, 3]},  ImageSize -> 10];

Method 1: Overlay two instances of locPane inside a Manipulate

Manipulate[m = 15; 
 Overlay[{
  locPane[Dynamic[pts], Dynamic@If[layer == 1, redCircle, grayDisk], Red], 
  locPane[Dynamic[pts2], Dynamic@If[layer == 2, blueCircle, grayDisk], Blue]},
  All, Dynamic[layer]], 
{{pts, {{6, 0}, {0, 9}}}, ControlType -> None}, 
{{pts2, {{7, 0}, {0, 7}}}, ControlType -> None}, 
{{layer, 1, "layer"}, {1, 2}}]

to get

enter image description here

Method 2: Overlay two instances of locPane inside an EventHandler and Manipulate:

Right-mouse-click toggles between two locator panes:

DynamicModule[{layer = 1}, EventHandler[Manipulate[m = 15;
 Overlay[
{locPane[Dynamic[pts], Dynamic@If[layer == 1, redCircle, grayDisk], Red], 
 locPane[Dynamic[pts2], Dynamic@If[layer == 2, blueCircle, grayDisk], Blue]},
 All, Dynamic[layer]],
{{pts, {{6, 0}, {0, 9}}}, ControlType -> None},
{{pts2, {{7, 0}, {0, 7}}}, ControlType -> None}],
{{"MouseClicked", 2} :> ((layer = layer /. {1 -> 2, 2 -> 1}))}, 
PassEventsDown -> True]]

enter image description here

share|improve this answer
    
When I run your solution after EDIT, each locator stops and freezes after moving one unit. (This is precisely the sort of trouble I run into when I attempt to use Locator instead of LocatorPane.) I suspect that some variable needs to be wrapped in Dynamic. –  David Carraher Aug 6 '12 at 15:40
    
@DavidCarraher, I think the version you are using is not the last one - I added Dynamic before Module in both versions to fix that same issue. –  kguler Aug 6 '12 at 15:54
    
+1 You are correct. It works fine. –  David Carraher Aug 6 '12 at 15:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.