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.

On a graphic (in this example a simple plot), I need two points to move when I drag with the mouse, and these points must move to location {1,1} when I click on them.

This is how I got it to work, but I don't think it's a good way.

 DynamicModule[{pt = {{1, 2}, {2, 3}}},
  EventHandler[  LocatorPane[Dynamic[pt], Plot[t, {t, -3, 3}], 
  Appearance -> Graphics[Circle[], ImageSize -> 10]], 
 "MouseClicked" :> (pt = 
 ReplacePart[pt, 
  First@Flatten@
     Sort[MapIndexed[{#2, Norm[MousePosition["Graphics"] - #]} &, 
       pt], #1[[2]] < #2[[2]] &] -> {-1, -1}]), 
 "MouseDragged" :> (pt = 
 ReplacePart[pt, 
  First@Flatten@
     Sort[MapIndexed[{#2, Norm[MousePosition["Graphics"] - #]} &, 
       pt], #1[[2]] < #2[[2]] &] -> MousePosition["Graphics"]])]]

Any suggestions for improvement?

share|improve this question
    
your code is fine. Perhaps, you could replace the second argument of ReplacePart by somewhat shorter Nearest[pt -> {1, 2}, MousePosition["Graphics"], 1] –  kguler Jan 31 '13 at 22:35
add comment

1 Answer

Each of the following codes is different that yours in this thing that it is not sorting/managing points. Events are restricted to the objects, not the Graphics. So this sould be better for overall performance.

1 quick approach

If you don't need LocatorPane ability to create new Locators, and you don't, this code will do the same but shorter way.

DynamicModule[{pt1 = {1, 2}, pt2 = {2, 3}, eh},
 Dynamic[
  Graphics[{eh@pt1, eh@pt2}, ImageSize -> 500, PlotRange -> 3, Axes -> True]
  , None] ,
 Initialization :> (
   SetAttributes[eh, HoldAll];
   eh[val_] := EventHandler[{Disk[Dynamic@val, .2]},
     {"MouseClicked" :> (val = {1, 1}),
      "MouseDragged" :> (val = MousePosition["Graphics"])
      }]; ) ]

Notice Dynamic[... , None] around the body, it's purpose is to force definitions from Initialization to be read. None is to do not repeat this.

2 working with LocatorAutoCreate

This code will allow you to make whatever you want:

DynamicModule[{pts = {{.5, .5}, {1, 1}}, eh, val},
 Dynamic[
  LocatorPane[Dynamic@pts,
              Graphics[{eh@pts}, Axes -> True], 
              LocatorAutoCreate -> True, Appearance -> None]
  , None]     
 ,
 Initialization :> (
   SetAttributes[eh, HoldAll];
   eh[list_] := MapIndexed[
      With[{i = #2[[1]]}, EventHandler[Dynamic@Disk[list[[i]], .1],
                          {"MouseClicked" :> (list[[i]] = {1, 1}),
                           "MouseDragged" :> (list[[i]] = MousePosition["Graphics"])}]
        ] &, list];
   )]
share|improve this answer
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.