1

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
 ]
Kuba
  • 136,707
  • 13
  • 279
  • 740
  • 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. – Kuba Nov 26 '14 at 23:42
  • I think this is a workable code. Or it's possible to paste my running result in this webpage? – Chien-Ching Vincent Hsu Nov 26 '14 at 23:45
  • 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. – Kuba Nov 26 '14 at 23:54
  • no need to put DynamicModule inside Manipulate. Manipulate itself is DynamicModule. – Nasser Nov 26 '14 at 23:58
  • 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? – Nasser Nov 27 '14 at 00:14
  • When you move slider the position of cube should be changed. This code is an experiment to test combination of manipulate and eventhandler. There are two ways you can move cubes. One is move the cubes in eventhandler, and the PopupMenu and Sliders values should be changed, this part is the code can do now. Another one is to change the sliders and popupmenu to control the cubes. you can choose one number in popupmenu, click enter button to selete which one cube(the cube will be black), the same, it's work now.The problem now is I cannot change the position of cubes by moving the sliders. – Chien-Ching Vincent Hsu Nov 27 '14 at 00:41
  • Well, I move the sliders and nothing happens for me. Cube do not move at all. V 10.01 on windows 7. Changed item from 1 to 2, clicked enter, etc.. move slider, cube does not move. – Nasser Nov 27 '14 at 01:28
  • Yes, as I said how to make moving slider to control cubes is my problem. I think you could draw the cubes in the screen, and release the button of the mouse, you would notice the sliders be changed, that is what I did. And when you changed item from 1 to 2 than clicking enter button, doesn't the color be changed between the two cubes(because the cube you choose will be black color, now you change 1 to 2, therefore the two cubes colors should be changed with each other). – Chien-Ching Vincent Hsu Nov 27 '14 at 01:42

1 Answers1

3

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

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • Wow, it is exactly the result I want to acheive, thank you a lot – Chien-Ching Vincent Hsu Nov 28 '14 at 15:41
  • Hi @kuba. SetDelayed is treated as Set in the body of the DynamicModule so posInt:= is actually posInt= . – Mike Honeychurch Nov 28 '14 at 23:55
  • @MikeHoneychurch Unless it is DownValue what will be stored in DynamicModuleValues or something. That's why I use posInt[] := not posInt:= – Kuba Nov 29 '14 at 07:02
  • 1
    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 – Mike Honeychurch Nov 30 '14 at 07:22
  • @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. – Kuba Nov 30 '14 at 08:10
  • that wasn't the comment I was thinking of (was another comment he made another time) but nevertheless states the same thing in section B. ...in any case I always use Initialization so whether SetDelayed works in the body is not an issue but thought I would raise it because of Johns previous comments and you code in this answer. – Mike Honeychurch Nov 30 '14 at 08:41
  • @MikeHoneychurch His statements are correct but not precise enough, just like docs. Please compare the cell expressions of DynamicModule[{x}, x := RandomInteger[]; x] and DynamicModule[{x}, x[] := RandomInteger[]; x[]] – Kuba Nov 30 '14 at 08:47
  • good examples Kuba! – Mike Honeychurch Nov 30 '14 at 09:23