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.

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?

share|improve this question
    
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. :-) –  ndroock1 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
add comment

1 Answer 1

up vote 9 down vote accepted

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]]]]
share|improve this answer
    
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! ) –  ndroock1 Apr 13 '12 at 20:24
add comment

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.