1

Typically when adding locators I would use a button i.e. something along the lines

DynamicModule[{pt={{0,0}}},
    Column[{LocatorPane[Dynamic[pt],
        Dynamic[
            Graphics[{Red,Point[pt]},PlotRange->{{-2,2},{-2,2}}]
            ]
        ],
    Button["Add locator",AppendTo[pt,{0,0}]]}]
]

However, say I wanted to do the same, but within a manipulate and with a SetterBar[] (or Slider[] or PopupMenu[]). I have tried several approaches, but the best I have come up with is at best sketchy. The following code works, but you have to move a locator before a new one shows up (or goes away).

Clear[update]

update[list_, i_] :=If[Length[list] < i, Append[list, {0, 0}], Take[list, i]]<

Manipulate[
    DynamicModule[
        {pt={{0,0}}},
        LocatorPane[Dynamic[pt,(pt=update[#,nrPts])&],
            Dynamic[
                Graphics[{Red,Point[pt]},PlotRange->{{-2,2},{-2,2}}]
            ]
        ]
    ],
    {nrPts,{1,2,3,4},SetterBar}
]

I have tried to place Dynamic[] in various places, but to no avail. Is there some way to use SetterBar[] and get as smooth results as with Button[]?

E.O.
  • 1,213
  • 1
  • 12
  • 16
  • Any reason for using a button instead of the option LocatorAutoCreate->True to add locators ? – kglr Dec 17 '12 at 13:15
  • In case you don't know, there is a LocatorAutoCreate option for LocatorPane that adds/removes points when alt-clicking. – jVincent Dec 17 '12 at 13:15
  • @kguler Originally the button adds a locator at the position which is the average of all the other locators, but I removed it since it wasn't relevant to the question. So no, there isn't really a reason :-) – E.O. Dec 17 '12 at 13:22
  • 1
    Please see this code http://mathematica.stackexchange.com/a/14149/193 – Dr. belisarius Dec 17 '12 at 13:27

1 Answers1

2

As noted in comments, you can normally have the functionality of being able to add and remove points just by calling LocatorPane with LocatorAutoCreate->True and alt-clicking.

 pts = {{0, 0}};
 LocatorPane[Dynamic[pts], 
     Dynamic@Graphics[{Red, Point[pts]}, 
     PlotRange -> {{-2, 2}, {-2, 2}}],
 LocatorAutoCreate -> True]

In case this is not enought or more control is wanted, you can use a DynamicWrapper to change pts without having to reload the LocatorPane

Manipulate[DynamicModule[{pt = {{0, 0}}},

DynamicWrapper[
      LocatorPane[Dynamic[pt[[1 ;; nrPts]], (pt[[1 ;; nrPts]] = #) &], 
         Dynamic[Graphics[{Red, Point[pt]}, PlotRange -> {{-2, 2}, {-2, 2}}]]
      ]
, If[Length@pt < nrPts, pt = PadRight[pt, nrPts, {{0, 0}}]]]
], {nrPts, {1, 2, 3, 4}, SetterBar}]

In the above, you could hide points currenlty inactive by only showing Point[pt[[1;;nrPts]] in graphcis, but I left them visible just to show that they stay even when not being manipulated.

jVincent
  • 14,766
  • 1
  • 42
  • 74