# How to add several Locators to a Graphic with a mouse click?

Background: Suppose I have something like this:

 DynamicModule[{pt1 = {0, 0}, pt2 = {0, 1}, pt3 = {1, 0}},
Graphics[Polygon[{pt1, pt2, pt3}], PlotRange -> 1]]


which I would like to change into this via a mouse click on the Polygon into this:

 DynamicModule[
{pt1 = {0, 0}, pt2 = {0, 1}, pt3 = {1, 0}},
Manipulate[
Graphics[Polygon[{pt1, pt2, pt3}], PlotRange -> 1],
{{pt1, {0, 0}}, Locator}, {{pt2, {0, 1}}, Locator}, {{pt3, {1, 0}},
Locator}]]


Question: What code should I add to one of the snippets above to achieve this?

-
You could see this question and its answers: mathematica.stackexchange.com/questions/4179/… – FJRA Apr 13 '12 at 13:25
FJRA, I know, I asked the question myself. I am still learning Dynamic, it is hard but I am getting there with your help. :-) – nilo de roock Apr 13 '12 at 13:34
Sorry, I didn't noticed it's you :P. Anyway it's good to have the link as reference for anyone who lands in this related question. – FJRA Apr 13 '12 at 13:36

Here are two possible solutions. In both cases, one click brings locators up, another click will make them disappear.

# Solution 1

Using multiple dynamic locators. The Map (or /@) is needed, since Dynamic inside Locator should have evaluated part number for pts.

DynamicModule[{pts = {{0, 0}, {0, 1}, {1, 0}}, locs = {}},
Graphics[{EventHandler[
Polygon[Dynamic[
pts]], {"MouseClicked" :> (locs =
If[locs === {},
Locator[Dynamic[pts[[#]]]] & /@ Range[Length[pts]], {}])}],
Dynamic[locs]}, PlotRange -> 1, PlotRangePadding -> Scaled[.05]]]


A slightly weird behavior of locators (washed out color when it appears first)... which I don't know why.

# Solution 2

Using LocatorPane. Simpler, but Dynamic needs to refresh both locPts and pts when locs is assigned (Dynamic[expr, f] syntax).

DynamicModule[{pts = {{0, 0}, {0, 1}, {1, 0}}, locPts = {}},
LocatorPane[Dynamic[locPts, (If[locPts =!= {}, pts = locPts = #]) &],
Graphics[{EventHandler[
Polygon[Dynamic[
pts]], {"MouseClicked" :> (locPts = If[locPts === {}, pts, {}])}]},
PlotRange -> 1, PlotRangePadding -> Scaled[.05]]]]

-
Sorry, I upped your answer, but I forgot to accept. Thanks again for your excellent answer. ( The fog that hang over DynamicModule is -finally- beginning to fade! ) – nilo de roock Apr 13 '12 at 20:24