package org.geogebra.desktop.geogebra3D.euclidianInput3D; import java.awt.AWTException; import java.awt.Dimension; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Robot; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import org.geogebra.common.awt.GPoint; import org.geogebra.common.euclidian.EuclidianConstants; import org.geogebra.common.euclidian.EuclidianControllerCompanion; import org.geogebra.common.euclidian.event.AbstractEvent; import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D; import org.geogebra.common.geogebra3D.input3D.EuclidianControllerInput3DCompanion; import org.geogebra.common.geogebra3D.input3D.Input3D; import org.geogebra.common.kernel.Kernel; import org.geogebra.desktop.geogebra3D.euclidian3D.EuclidianController3DD; import org.geogebra.desktop.geogebra3D.euclidian3D.EuclidianView3DD; /** * controller with specific methods from leonar3do input system * * @author mathieu * */ public class EuclidianControllerInput3D extends EuclidianController3DD { protected Input3D input3D; protected Robot robot; protected int robotX, robotY; /** * constructor * * @param kernel * kernel * @param input3d * input3d */ public EuclidianControllerInput3D(Kernel kernel, Input3D input3d) { super(kernel); this.input3D = input3d; ((EuclidianControllerInput3DCompanion) companion).setInput3D(input3d); // screen dimensions GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice(); input3D.setScreenHalfDimensions(gd.getDisplayMode().getWidth() / 2.0, gd.getDisplayMode().getHeight() / 2.0); // robot robot = null; if (input3d.useMouseRobot()) { try { robot = new Robot(); } catch (AWTException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override protected EuclidianControllerCompanion newCompanion() { return new EuclidianControllerInput3DCompanion(this); } private boolean isNotMovingObjectOrView() { return moveMode == MOVE_NONE && isNotMovingView; } @Override public void updateInput3D() { // update panel values Dimension panelDimension = ((EuclidianView3DD) view3D).getJPanel() .getSize(); Point panelPosition = ((EuclidianView3DD) view3D).getJPanel() .getLocationOnScreen(); input3D.setPanel(panelDimension.width, panelDimension.height, panelPosition.x, panelPosition.y); if (input3D.update()) { // //////////////////// // set values // eyes : set position only if we use glasses input3D.updateHeadTracking(); // update on screen position to check if we allow to use regular // mouse if (robot != null && (isNotMovingObjectOrView() || !input3D.hasMouseDirection())) { input3D.updateOnScreenPosition(); } // regular 2D mouse is used? then return if (input3D.currentlyUseMouse2D()) { return; } // 2D cursor pos if (robot != null) { if (isNotMovingObjectOrView() || !input3D.hasMouseDirection()) { // process mouse if (robotX != input3D.getOnScreenX() || robotY != input3D.getOnScreenY()) { // Log.debug(inputPosition[0]+","+inputPosition[1]+","+inputPosition[2]); // Log.debug(x+","+y); robotX = input3D.getOnScreenX(); robotY = input3D.getOnScreenY(); robot.mouseMove(robotX, robotY); } } } // mouse pos input3D.updateMousePosition(); // check if the 3D mouse is on 3D view if (input3D.hasMouse()) { if (!input3D.useInputDepthForHitting() || input3D.getMouse3DPosition().getZ() < view3D .getRenderer().getEyeToScreenDistance()) { input3D.updateMouse3DEvent(); input3D.handleButtons(); } } else if (robot != null) { // bird outside the view // process right press / release if (input3D.isRightPressed()) { if (input3D.wasRightReleased()) { robot.mousePress(InputEvent.BUTTON3_MASK); input3D.setWasRightReleased(false); } } else { if (!input3D.wasRightReleased()) { robot.mouseRelease(InputEvent.BUTTON3_MASK); input3D.setWasRightReleased(true); } } // process left press / release if (input3D.isLeftPressed()) { if (input3D.wasLeftReleased()) { robot.mousePress(InputEvent.BUTTON1_MASK); input3D.setWasLeftReleased(false); } } else { if (!input3D.wasLeftReleased()) { robot.mouseRelease(InputEvent.BUTTON1_MASK); input3D.setWasLeftReleased(true); } } } } } private boolean isNotMovingView = true; private void processRightRelease() { ((EuclidianView3D) getView()).setRotContinueAnimation( app.getMillisecondTime() - timeOld, animatedRotSpeed); } @Override public void mousePressed(MouseEvent e) { if (input3D.currentlyUseMouse2D()) { super.mousePressed(e); } else if (input3D.useHandGrabbing() && mode != MOVE_NONE) { releaseGrabbing(); super.mousePressed(e); } } @Override public void mouseReleased(MouseEvent e) { if (input3D.currentlyUseMouse2D()) { super.mouseReleased(e); } } @Override public void mouseMoved(MouseEvent e) { if (input3D.currentlyUseMouse2D()) { super.mouseMoved(e); } } @Override public void mouseDragged(MouseEvent e) { if (input3D.currentlyUseMouse2D()) { super.mouseDragged(e); } } @Override public boolean hasInput3D() { return true; } @Override public boolean cursor3DVisibleForCurrentMode(int cursorType) { if (mode == EuclidianConstants.MODE_MOVE && !input3D.hasMouseDirection() && !input3D.currentlyUseMouse2D()) { return false; } return super.cursor3DVisibleForCurrentMode(cursorType); } @Override public GPoint getMouseLoc() { if (input3D.currentlyUseMouse2D()) { return super.getMouseLoc(); } return input3D.getMouseLoc(); } @Override protected int getModeForShallMoveView(AbstractEvent event) { if (input3D.currentlyUseMouse2D()) { return super.getModeForShallMoveView(event); } return EuclidianConstants.MODE_MOVE; } @Override public void wrapMouseReleased(AbstractEvent e) { isNotMovingView = true; if (!input3D.wasRightReleased() && !input3D.useQuaternionsForRotate()) { processRightRelease(); return; } super.wrapMouseReleased(e); } /** * release hand grabbing */ protected void releaseGrabbing() { ((EuclidianViewInput3D) view3D).getCompanion().getStationaryCoords() .consumeLongDelay(); ((EuclidianControllerInput3DCompanion) getCompanion()) .releaseGrabbing(); } @Override public void exitInput3D() { input3D.exit(); } @Override public boolean isZSpace() { return input3D.isZSpace(); } }