View Javadoc
1 /***************************************************************************** 2 * Virtual Mockup for Machine Vision 3 * Copyright (C) 2001-2003 Fabio R. de Miranda, João E. Kogler Jr., 4 * Carlos S. Santos. 5 * Virtual Mockup for Machine Vision Project funded by SENAC-SP 6 * 7 * Permission is granted to redistribute and/or modify this 8 * software under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This software is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License (http://www.gnu.org/copyleft/lesser.html) 16 * for more details. 17 * 18 *****************************************************************************/ 19 20 package camera3d.gui; 21 22 import camera3d.*; 23 import camera3d.event.SelectionChangedEvent; 24 import camera3d.manipulation.*; 25 import javax.swing.*; 26 import java.awt.event.*; 27 import java.util.*; 28 import java.util.ArrayList; 29 import javax.media.j3d.Canvas3D; 30 31 /*** 32 * 33 * @author Fábio Roberto de Miranda, Carlos da Silva dos Santos 34 * @version 1.0 35 */ 36 public class ViewportsEventHandler implements SelectionChangeListener { 37 38 /*** Indicates that the handler is in transforming state, when picking is disabled 39 * and the currently selected object can be manipulated. */ 40 public static final int TRANSFORMING = 0; 41 /*** Indicates that the handler is in idle state, when picking is enabled 42 * and no manipulation of objects can be performed. */ 43 public static final int IDLE = 1; 44 45 /*** Indicates whether a transformation is beeing performed. */ 46 private int state; 47 48 /*** Indicates the kind of transformation (translation, rotation, scaling or none) 49 * to be applied to the currently selected object. 50 */ 51 private TransformType type = TransformType.NONE; 52 //int type = ViewportContextMenu.NONE_TYPE; 53 54 /*** Indicates the mode (absolute or relative) of transformation to be applied to 55 * the currently selected object.*/ 56 private TransformMode mode = TransformMode.ABSOLUTE; 57 //int mode = VcObject.ABSOLUTE_MODE; 58 59 /*** Indicates the scope (axis, plane) on which a transformation will take effect. */ 60 private TransformScope scope = TransformScope.X; 61 //int axis = VcObject.X; 62 63 /*** Holds the initial X coordinate of a mouse drag event. */ 64 private int beginX; 65 /*** Holds the initial Y coordinate of a mouse drag event. */ 66 private int beginY; 67 68 /*** Manipulator used to perform a transformation on the currently selected 69 * object. */ 70 private TransformationManipulator currentManipulator; 71 private TranslationManipulator transManipulator; 72 private RotationManipulator rotManipulator; 73 private ScalingManipulator scaleManipulator; 74 75 private InternalListener internalListener = new InternalListener(); 76 private KeybListener keyboardListener = new KeybListener(); 77 78 // Introduced 08/04/2003 to eliminate dependency on ViewportContextMenu 79 // informing ViewportsEventHandler of which Viewport had been entered. 80 /*** List of Viewports which send their events to ViewportsEventHandler. Necessary 81 * for retrieving current Viewport from MouseEntered event.*/ 82 private List viewportList = new ArrayList(); 83 private Viewport lastViewport; 84 85 private GUIControl guiControl; 86 87 /*** Reference to the object currently selected */ 88 private VcObject selectedObject; 89 90 /*** Reference to the VcView object currently shown */ 91 private VcView currentView=null; 92 93 private static ViewportsEventHandler handler; 94 95 private ViewportWindowManager manager; 96 97 private static final Viewport UNLIKELY_VIEWPORT = new Viewport(); 98 99 /*** 100 * Desperate singleton 101 */ 102 public ViewportsEventHandler getViewportEventsHandler(GUIControl guiControl){ 103 handler = new ViewportsEventHandler(guiControl); 104 return handler; 105 } 106 107 public ViewportsEventHandler(GUIControl guiControl) { 108 this(); 109 this.guiControl = guiControl; 110 transManipulator = new TranslationManipulator(); 111 rotManipulator = new RotationManipulator(); 112 scaleManipulator = new ScalingManipulator(); 113 } 114 115 116 public ViewportsEventHandler(){ 117 this.state = ViewportsEventHandler.IDLE; 118 } 119 120 public void addViewportFrame(ViewportFrame vpFrame){ 121 vpFrame.getViewport().getCanvas3D().addMouseListener(internalListener); 122 vpFrame.getViewport().getCanvas3D().addMouseMotionListener((MouseMotionListener)internalListener); 123 vpFrame.getViewport().getCanvas3D().addKeyListener(keyboardListener); 124 viewportList.add(vpFrame.getViewport()); 125 } 126 127 128 /* Code pasted from Java's PopupDemo.java */ 129 class InternalListener extends MouseAdapter implements MouseMotionListener { 130 public void mousePressed(MouseEvent e) { 131 /* 132 Warning: there is a bug with the way translation manipulation works, 133 as we don't check whether the mouse click actually "hits" the object. 134 That allows the user to click on the void and initiate a translation, 135 causing a sudden movement of the object from its position to the mouse 136 position. 137 */ 138 // if the selectedObject is null or non-live we can't do 139 // anything with it 140 if(selectedObject==null|| !selectedObject.isLive()) return; 141 debugln("Mouse pressed"); 142 int mod = e.getModifiers(); 143 if ((mod&MouseEvent.BUTTON1_MASK)==MouseEvent.BUTTON1_MASK){ 144 beginX = e.getX(); 145 beginY = e.getY(); 146 switch (state) { 147 case TRANSFORMING: 148 currentManipulator.setBeginPoint(beginX, beginY); 149 ///DANGER 150 selectedObject.setOngoingTransformation(true); 151 break; 152 } 153 } 154 } 155 156 public void mouseReleased(MouseEvent e) { 157 if(selectedObject==null|| !selectedObject.isLive()) return; 158 debugln("Mouse released"); 159 switch (state) { 160 case TRANSFORMING: 161 //DANGER 162 selectedObject.setOngoingTransformation(false); 163 break; 164 } 165 } 166 167 public void mouseEntered(MouseEvent e){ 168 //debugln("Mouse entered"); 169 Canvas3D canvas = (Canvas3D)e.getSource(); 170 setEnteredViewport(getViewportFromCanvas(canvas)); 171 Object obj = canvas.getView().getViewPlatform().getUserData(); 172 if(obj instanceof VcView){ 173 currentView = (VcView) obj; 174 currentView.setNavigateEnable(true); 175 // does not allow manipulation of current view 176 if(currentView==selectedObject){ 177 cancelAction(); 178 } 179 debugln("___VPEHandler current view: " + currentView.getLabel()); 180 } 181 } 182 183 public void mouseExited(MouseEvent e){ 184 debugln("Mouse exited"); 185 if(currentView!=null){ 186 currentView.setNavigateEnable(false); 187 currentView = null; 188 } 189 } 190 191 // MouseMotionListener methods 192 public void mouseMoved(MouseEvent e){ 193 194 if(selectedObject==null|| !selectedObject.isLive()) return; 195 //debugln("Mouse moved to "+e.getX()+","+e.getY()); 196 int mod = e.getModifiers(); 197 if ((mod&MouseEvent.BUTTON1_MASK)==MouseEvent.BUTTON1_MASK){ 198 //debugln(" While Btn 1 pressed"); 199 switch (state) { 200 case TRANSFORMING: 201 currentManipulator.setCurrentPoint(e.getX(), e.getY()); 202 break; 203 } 204 205 } 206 } 207 208 public void mouseDragged(MouseEvent e){ 209 if(selectedObject==null|| !selectedObject.isLive()) return; 210 //debugln("Mouse Dragged to "+e.getX()+","+e.getY()); 211 int mod = e.getModifiers(); 212 if ((mod&MouseEvent.BUTTON1_MASK)==MouseEvent.BUTTON1_MASK){ 213 //debugln(" While Btn 1 pressed"); 214 switch (state) { 215 case TRANSFORMING: 216 if (currentManipulator!=null){ 217 currentManipulator.setCurrentPoint(e.getX(), e.getY()); 218 } 219 break; 220 } 221 } 222 223 } 224 225 } 226 227 class KeybListener extends KeyAdapter{ 228 public void keyPressed(KeyEvent k){ 229 debugln("Key Pressed: "+KeyEvent.getKeyText(k.getKeyCode())); 230 if (k.getKeyCode() == KeyEvent.VK_ESCAPE){ 231 cancelAction(); 232 } 233 if (k.getKeyCode() == KeyEvent.VK_X){ 234 setAxis(KeyEvent.VK_X); 235 } 236 if (k.getKeyCode() == KeyEvent.VK_Y){ 237 setAxis(KeyEvent.VK_Y); 238 } 239 if (k.getKeyCode() == KeyEvent.VK_Z){ 240 setAxis(KeyEvent.VK_Z); 241 } 242 243 244 } 245 246 public void keyReleased(KeyEvent k){ 247 debugln("Key Released: "+KeyEvent.getKeyText(k.getKeyCode())); 248 } 249 } 250 251 252 private void cancelAction(){ 253 state = ViewportsEventHandler.IDLE; 254 manager.setPickingInViewports(true); 255 256 if(selectedObject!=null)selectedObject.setOngoingTransformation(false); 257 if(currentManipulator!=null) currentManipulator.clearSelection(); 258 manager.setCursorInViewports(TransformType.NONE); 259 // Warn frames that no action is selected anymore 260 manager.setTransformationTypeInContextMenus(TransformType.NONE, mode, scope,false); 261 } 262 263 private void setEnteredViewport(Viewport viewport){ 264 this.lastViewport = viewport; 265 debugln("Entered view:"+viewport.getView().getLabel()); 266 if (state == ViewportsEventHandler.TRANSFORMING){ 267 //currentManipulator.setCurrentViewport(viewport); 268 currentManipulator.setCanvas3D(viewport.getCanvas3D()); 269 } 270 } 271 272 private Viewport getViewportFromCanvas(Canvas3D canvas){ 273 Viewport viewport = UNLIKELY_VIEWPORT; 274 275 for(Iterator iter = viewportList.iterator();iter.hasNext(); ){ 276 Viewport vp = (Viewport)iter.next(); 277 if(canvas==vp.getCanvas3D()){ 278 viewport = vp; 279 break; 280 } 281 } 282 return viewport; 283 } 284 285 public void setSelectedManipulationAction(TransformType type){ 286 /* If there is no object selected we will not allow setting action 287 type. It would be better to disable the corresponding option 288 in viewport context menu till one object gets selected. */ 289 if(selectedObject==null){ 290 cancelAction(); 291 return; 292 } 293 this.type = type; 294 manager.setCursorInViewports(type); 295 this.state = TRANSFORMING; 296 boolean viewSelected = false; 297 if(type==TransformType.TRANSLATION){ 298 currentManipulator = transManipulator; 299 transManipulator.setTranslatableObject((TranslatableObject)selectedObject); 300 }else if(type==TransformType.ROTATION){ 301 currentManipulator = rotManipulator; 302 rotManipulator.setRotatableObject((RotatableObject)selectedObject); 303 }else if(type==TransformType.SCALING){ 304 currentManipulator = scaleManipulator; 305 scaleManipulator.setScalableObject((ScalableObject)selectedObject); 306 // all scaling is performed relative to local axis 307 mode = TransformMode.RELATIVE; 308 if (selectedObject instanceof VcView){ 309 setSelectedManipulationScope(TransformScope.XYZ); 310 viewSelected = true; 311 } 312 } 313 currentManipulator.setCanvas3D(lastViewport.getCanvas3D()); 314 315 currentManipulator.setTransformationScope(scope); 316 currentManipulator.setTransformationMode(mode); 317 currentManipulator.setBeginPoint(beginX, beginY); 318 319 manager.setPickingInViewports(false); 320 manager.setTransformationTypeInContextMenus(type, mode, scope,viewSelected); 321 } 322 323 public void setSelectedManipulationScope(TransformScope scope){ 324 /* If there is no object selected we will not allow setting action 325 type. It would be better to disable the corresponding option 326 in viewport context menu till one object gets selected. */ 327 if(selectedObject==null){ 328 cancelAction(); 329 return; 330 } 331 332 debugln("VPEvtHandler select scope"); 333 this.scope = scope; 334 switch (state){ 335 case TRANSFORMING: 336 currentManipulator.setTransformationScope(scope); 337 debugln("VPEvtHandler: "+ scope.toString()); 338 break; 339 case IDLE: 340 break; 341 } 342 boolean viewSelected = (selectedObject instanceof VcView); 343 manager.setTransformationTypeInContextMenus(type, mode, scope, viewSelected); 344 } 345 346 public void setSelectedManipulationMode(TransformMode mode){ 347 /* If there is no object selected we will not allow setting action 348 mode. It would be better to disable the corresponding option 349 in viewport context menu till one object gets selected. */ 350 if(selectedObject==null){ 351 cancelAction(); 352 return; 353 } 354 355 debugln("VPEvtHandler mode "+ mode.toString()); 356 this.mode = mode; 357 358 switch (state){ 359 case TRANSFORMING: 360 if(selectedObject!=null){ 361 selectedObject.setOngoingTransformationMode(this.mode); 362 } 363 if (currentManipulator!=null){ 364 currentManipulator.setTransformationMode(this.mode); 365 //debugln("Manipulator was not null"); 366 } 367 break; 368 } 369 boolean viewSelected = (selectedObject instanceof VcView); 370 manager.setTransformationTypeInContextMenus(type, mode, scope,viewSelected); 371 } 372 373 /*** Needed to disable/enable picking of objects*/ 374 public void setViewportWindowManager(ViewportWindowManager manager){ 375 this.manager = manager; 376 } 377 378 void enablePicking(){ 379 manager.setPickingInViewports(true); 380 } 381 382 void disablePicking(){ 383 manager.setPickingInViewports(false); 384 } 385 386 387 void debugln(String s){ 388 if (GUIControl.debugflag) 389 System.out.println(s); 390 } 391 392 // Triggers proper transformation 393 void beginTransformation(){ 394 state = ViewportsEventHandler.TRANSFORMING; 395 } 396 397 /*** 398 * Informs this object of changes made to the list of selected objects. Necessary 399 * to inform transformation manipulators of the object currently selected. 400 */ 401 public void selectionChanged(SelectionChangedEvent event){ 402 List added = event.getAddedObjects(); 403 if(added.size() >= 1){ 404 this.selectedObject = (VcObject)added.get(0); 405 } else { 406 debugln("Zero objects selected: cancelling action"); 407 this.selectedObject = null; 408 cancelAction(); 409 selectedObject = null; 410 } 411 412 // if the selected object is the current view we will not allow 413 // any manipulation 414 if(selectedObject==currentView){ 415 cancelAction(); 416 return; 417 } 418 419 switch (state) { 420 case TRANSFORMING: 421 if (currentManipulator==rotManipulator){ 422 rotManipulator.setRotatableObject((RotatableObject)selectedObject); 423 } 424 if (currentManipulator==rotManipulator){ 425 transManipulator.setTranslatableObject((TranslatableObject)selectedObject); 426 } 427 if (currentManipulator==rotManipulator){ 428 scaleManipulator.setScalableObject((ScalableObject)selectedObject); 429 } 430 break; 431 } 432 if (selectedObject!=null){ 433 selectedObject.setOngoingTransformationMode(mode); 434 if (selectedObject instanceof VcView){ 435 if (type == TransformType.SCALING){ 436 // Do something to forbid the use of NU scaling of VcViews 437 if (scope!=TransformScope.XYZ){ 438 setSelectedManipulationScope(TransformScope.XYZ); 439 } 440 boolean viewSelected = (selectedObject instanceof VcView); 441 manager.setTransformationTypeInContextMenus(type, mode, scope,viewSelected); 442 } 443 } 444 } 445 446 } 447 448 void setAxis(int key){ 449 switch(key){ 450 case KeyEvent.VK_X: 451 setSelectedManipulationScope(TransformScope.X); 452 break; 453 case KeyEvent.VK_Y: 454 setSelectedManipulationScope(TransformScope.Y); 455 break; 456 case KeyEvent.VK_Z: 457 setSelectedManipulationScope(TransformScope.Z); 458 break; 459 } 460 /* 461 int ctx_type = type; 462 463 if ((type == VcObject.SCALING_TYPE)&&(selectedObject instanceof VcView)){ 464 ctx_type = ViewportContextMenu.VIEW_SCALE_TYPE; 465 } 466 */ 467 boolean viewSelected = (selectedObject instanceof VcView); 468 manager.setTransformationTypeInContextMenus(type, mode, scope,viewSelected); 469 } 470 471 }

This page was automatically generated by Maven