1
$\begingroup$

I combine manipulate and eventhandler, now I can change the controller when working on eventhandler, but how to change the value in eventhandler when I control the manipulate controller?

Chosen = 1;
Location = {{0, 0, 0}, {0, 0, 0}};
Manipulate[
 DynamicModule[{pos10 = {{}, {}}, pos11 = {{0, 0, 0}, {0, 0, 0}}, 
   pos12 = {{0, 0, 0}, {0, 0, 0}}, pos20, 
   pos21 = {{0, 0, 0}, {0, 0, 0}}, pos22 = {{0, 0, 0}, {0, 0, 0}}, 
   posInt}, posInt[] := MousePosition["Graphics3DBoxIntercepts"];

  Graphics3D[{Table[With[{i = i}, EventHandler[Dynamic[
        If[i == Chosen,
         Translate[{Black, Cuboid[]}, pos11[[i]]],
         Translate[Cuboid[], {pos11[[i]]}]]
        ], {"MouseDown" :> {pos10[[i]] = Mean@posInt[], 
          ChosenItem = Chosen = i,}, 
        "MouseDragged" :> (pos11[[i]] = 
           pos12[[i]] + Mean@posInt[] - pos10[[i]]), 
        "MouseUp" :> {(pos12[[i]] = pos11[[i]]), 
          x = pos12[[Chosen, 1]], y = pos12[[Chosen, 2]], 
          z = pos12[[Chosen, 3]], Location[[Chosen]] = pos12[[Chosen]]}
        }]], {i, 2}]}, PlotRange -> 3]]
 ,
 {{ChosenItem, 1, "Item:"}, {1, 2}, PopupMenu},
 Button["Enter", {Chosen = ChosenItem, x = Location[[Chosen, 1]], 
   y = Location[[Chosen, 2]], z = Location[[Chosen, 3]]}],
 {{x, 0, "X"}, -3, 3},
 {{y, 0, "Y"}, -3, 3},
 {{z, 0, "Z"}, -3, 3},
 SaveDefinitions -> True
 ]
$\endgroup$
  • $\begingroup$ Please provide a minimal working example of your problem. Also, I'm encouraging you to stick only with DynamicModule + Sliders and friends if you are working on more complex GUI. $\endgroup$ – Kuba Nov 26 '14 at 23:42
  • $\begingroup$ I think this is a workable code. Or it's possible to paste my running result in this webpage? $\endgroup$ – Chien-Ching Vincent Hsu Nov 26 '14 at 23:45
  • $\begingroup$ I know it works but it may be shorter. p.s. you can use something like Row[List@Slider[ Dynamic[z, (z = #; pos11[[Chosen, 3]] = z) &], {-3, 3}]] but you have to swap Manipulate with DynamicModule. And since you'd have to change x, y, z controllers to explicitly stated Sliders, there is no need to keep Manipulate. $\endgroup$ – Kuba Nov 26 '14 at 23:54
  • $\begingroup$ no need to put DynamicModule inside Manipulate. Manipulate itself is DynamicModule. $\endgroup$ – Nasser Nov 26 '14 at 23:58
  • $\begingroup$ Is something supposed to happen when the sliders are moved? It will help to explain a little bit what this is supposed to do? V10, and nothing changes for me when I moved the slides or click Enter button? $\endgroup$ – Nasser Nov 27 '14 at 0:14
3
$\begingroup$

Here's your code with fixes I've suggested in comments:

DynamicModule[
 {Location = {{0, 0, 0}, {0, 0, 0}},
  pos10 = {{}, {}},
  pos11 = {{0, 0, 0}, {0, 0, 0}},
  pos12 = {{0, 0, 0}, {0, 0, 0}},
  pos20,
  pos21 = {{0, 0, 0}, {0, 0, 0}},
  pos22 = {{0, 0, 0}, {0, 0, 0}},
  posInt, x, y, z, Chosen = 1},

 posInt[] := MousePosition["Graphics3DBoxIntercepts"];

 Deploy@Panel@Column[{
     PopupMenu[Dynamic@Chosen, {1, 2}],
     Slider[Dynamic[x, (x = #; pos11[[Chosen, 1]] = x) &], {-3, 3}],
     Slider[Dynamic[y, (y = #; pos11[[Chosen, 2]] = y) &], {-3, 3}],
     Slider[Dynamic[z, (z = #; pos11[[Chosen, 3]] = z) &], {-3, 3}],

     Panel@
      Graphics3D[{Table[
         With[{i = i}, 
          EventHandler[
           Dynamic[
            If[i == Chosen, Translate[{Black, Cuboid[]}, pos11[[i]]], 
             Translate[
              Cuboid[], {pos11[[i]]}]]], {
           "MouseDown" :> {pos10[[i]] =Mean@posInt[], Chosen = i}, 
           "MouseDragged" :> (pos11[[i]] = pos12[[i]] + Mean@posInt[] - pos10[[i]]), 
           "MouseUp" :> {(pos12[[i]] = pos11[[i]]), 
                          x = pos12[[Chosen, 1]], y = pos12[[Chosen, 2]], 
                          z = pos12[[Chosen, 3]], 
                          Location[[Chosen]] = pos12[[Chosen]]}}]], {i, 2}]}, 
       PlotRange -> 3, ImageSize -> 500]

     }]
 ]

enter image description here

$\endgroup$
  • $\begingroup$ Wow, it is exactly the result I want to acheive, thank you a lot $\endgroup$ – Chien-Ching Vincent Hsu Nov 28 '14 at 15:41
  • $\begingroup$ Hi @kuba. SetDelayed is treated as Set in the body of the DynamicModule so posInt:= is actually posInt= . $\endgroup$ – Mike Honeychurch Nov 28 '14 at 23:55
  • $\begingroup$ @MikeHoneychurch Unless it is DownValue what will be stored in DynamicModuleValues or something. That's why I use posInt[] := not posInt:= $\endgroup$ – Kuba Nov 29 '14 at 7:02
  • 1
    $\begingroup$ I am pretty sure John Fultz has already explained that SetDelayed is treated as Set in the body. AFAIK you need to use Initialization is you want SetDelayed faithfully/reliably $\endgroup$ – Mike Honeychurch Nov 30 '14 at 7:22
  • $\begingroup$ @MikeHoneychurch WRI is to blame that we even have to talk about that and be confused. Quick check is to run the code, it would not work if it wasn't delayed. I think you meant this answer but it is not well stated. I like him but quality of docs about Dynamics is poor. So yes, you are right in case of OwnValues but don't worry about DownValues, they are transvered to DynamicModuleValues with full respect to the user :P. $\endgroup$ – Kuba Nov 30 '14 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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