diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java index 50b6d5cfe..00d15bb2f 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java @@ -11,6 +11,7 @@ import com.jme3.gde.core.scene.controller.SceneToolController; import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.gde.scenecomposer.tools.shortcuts.ShortcutManager; import com.jme3.input.event.KeyInputEvent; import com.jme3.light.Light; import com.jme3.light.PointLight; @@ -31,6 +32,7 @@ import com.jme3.scene.control.Control; import com.jme3.scene.shape.Quad; import com.jme3.texture.Texture; import java.util.concurrent.Callable; +import org.openide.util.Lookup; /** * @@ -184,7 +186,12 @@ public class SceneComposerToolController extends SceneToolController { * @param camera */ public void doEditToolActivatedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); + scm.getActiveShortcut().actionPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.actionPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } @@ -198,36 +205,66 @@ public class SceneComposerToolController extends SceneToolController { * @param camera */ public void doEditToolActivatedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); + scm.getActiveShortcut().actionSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.actionSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } } public void doEditToolMoved(Vector2f mouseLoc, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); + scm.getActiveShortcut().mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject(), selectedSpatial); + } else if (editTool != null) { editTool.setCamera(camera); editTool.mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject(), selectedSpatial); } } public void doEditToolDraggedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); + scm.getActiveShortcut().draggedPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.draggedPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } } public void doEditToolDraggedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().setCamera(null); + scm.getActiveShortcut().draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } } - void doKeyPressed(KeyInputEvent kie) { - if (editTool != null) { - editTool.keyPressed(kie); + public void doKeyPressed(KeyInputEvent kie) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.doKeyPressed(kie); + } else { + if (scm.activateShortcut(kie)) { + scm.getActiveShortcut().activate(manager, toolsNode, onTopToolsNode, selected, this); + } else { + if (editTool != null) { + editTool.keyPressed(kie); + } + } } } diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java deleted file mode 100644 index d7b92db91..000000000 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package com.jme3.gde.scenecomposer.tools; - -import com.jme3.bullet.control.CharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; -import com.jme3.gde.scenecomposer.SceneEditTool; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; -import org.openide.util.lookup.ServiceProvider; - -/** - * - * @author Nehon - */ -@ServiceProvider(service = MoveManager.class) -public class MoveManager { - - private Vector3f startLoc; - private Vector3f startWorldLoc; - private Vector3f lastLoc; - private Vector3f offset; - private Node alternativePickTarget = null; - private Node plane; - private Spatial spatial; - protected static final Quaternion XY = new Quaternion().fromAngleAxis(0, new Vector3f(1, 0, 0)); - protected static final Quaternion YZ = new Quaternion().fromAngleAxis(-FastMath.PI / 2, new Vector3f(0, 1, 0)); - protected static final Quaternion XZ = new Quaternion().fromAngleAxis(FastMath.PI / 2, new Vector3f(1, 0, 0)); - //temp vars - private Quaternion rot = new Quaternion(); - private Vector3f newPos = new Vector3f(); - - public MoveManager() { - float size = 1000; - Geometry g = new Geometry("plane", new Quad(size, size)); - g.setLocalTranslation(-size / 2, -size / 2, 0); - plane = new Node(); - plane.attachChild(g); - } - - public Vector3f getOffset() { - return offset; - } - - public void reset() { - offset = null; - startLoc = null; - startWorldLoc = null; - lastLoc = null; - spatial = null; - alternativePickTarget = null; - } - - public void initiateMove(Spatial selectedSpatial, Quaternion planeRotation, boolean local) { - spatial = selectedSpatial; - startLoc = selectedSpatial.getLocalTranslation().clone(); - startWorldLoc = selectedSpatial.getWorldTranslation().clone(); - if (local) { - rot.set(selectedSpatial.getWorldRotation()); - plane.setLocalRotation(rot.multLocal(planeRotation)); - } else { - rot.set(planeRotation); - } - - plane.setLocalRotation(rot); - plane.setLocalTranslation(startWorldLoc); - - } - - public void updatePlaneRotation(Quaternion planeRotation) { - plane.setLocalRotation(rot); - } - - public boolean move(Camera camera, Vector2f screenCoord) { - return move(camera, screenCoord, Vector3f.UNIT_XYZ, false); - } - - public boolean move(Camera camera, Vector2f screenCoord, Vector3f constraintAxis, boolean gridSnap) { - Node toPick = alternativePickTarget == null ? plane : alternativePickTarget; - - Vector3f planeHit = SceneEditTool.pickWorldLocation(camera, screenCoord, toPick, alternativePickTarget == null ? null : spatial); - if (planeHit == null) { - return false; - } - - Spatial parent = spatial.getParent(); - //we are moving the root node, there is a slight chance that something went wrong. - if (parent == null) { - return false; - } - - //offset in world space - if (offset == null) { - offset = planeHit.subtract(spatial.getWorldTranslation()); // get the offset when we start so it doesn't jump - } - - newPos.set(planeHit).subtractLocal(offset); - - //constraining the translation with the contraintAxis. - Vector3f tmp = startWorldLoc.mult(Vector3f.UNIT_XYZ.subtract(constraintAxis)); - newPos.multLocal(constraintAxis).addLocal(tmp); - worldToLocalMove(gridSnap); - return true; - } - - private void worldToLocalMove(boolean gridSnap) { - //snap to grid (grid is assumed 1 WU per cell) - if (gridSnap) { - newPos.set(Math.round(newPos.x), Math.round(newPos.y), Math.round(newPos.z)); - } - - //computing the inverse world transform to get the new localtranslation - newPos.subtractLocal(spatial.getParent().getWorldTranslation()); - newPos = spatial.getParent().getWorldRotation().inverse().normalizeLocal().multLocal(newPos); - newPos.divideLocal(spatial.getParent().getWorldScale()); - - lastLoc = newPos; - spatial.setLocalTranslation(newPos); - - RigidBodyControl control = spatial.getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(spatial.getWorldTranslation()); - } - CharacterControl character = spatial.getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(spatial.getWorldTranslation()); - } - } - - public boolean moveAcross(Vector3f constraintAxis, float value, boolean gridSnap) { - newPos.set(startWorldLoc).addLocal(constraintAxis.mult(value)); - Spatial parent = spatial.getParent(); - //we are moving the root node, there is a slight chance that something went wrong. - if (parent == null) { - return false; - } - worldToLocalMove(gridSnap); - return true; - } - - public MoveUndo makeUndo() { - return new MoveUndo(spatial, startLoc, lastLoc); - } - - public void setAlternativePickTarget(Node alternativePickTarget) { - this.alternativePickTarget = alternativePickTarget; - } - - protected class MoveUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Vector3f before = new Vector3f(), after = new Vector3f(); - - MoveUndo(Spatial spatial, Vector3f before, Vector3f after) { - this.spatial = spatial; - this.before.set(before); - if (after != null) { - this.after.set(after); - } - } - - @Override - public void sceneUndo() { - spatial.setLocalTranslation(before); - RigidBodyControl control = spatial.getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(spatial.getWorldTranslation()); - } - CharacterControl character = spatial.getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(spatial.getWorldTranslation()); - } - // toolController.selectedSpatialTransformed(); - } - - @Override - public void sceneRedo() { - spatial.setLocalTranslation(after); - RigidBodyControl control = spatial.getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(spatial.getWorldTranslation()); - } - CharacterControl character = spatial.getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(spatial.getWorldTranslation()); - } - //toolController.selectedSpatialTransformed(); - } - - public void setAfter(Vector3f after) { - this.after.set(after); - } - } -} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java index 22fa8478a..af4f11fe5 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java @@ -33,9 +33,9 @@ public class PickManager { private Spatial spatial; private SceneComposerToolController.TransformationType transformationType; - protected static final Quaternion PLANE_XY = new Quaternion().fromAngleAxis(0, new Vector3f(1, 0, 0)); - protected static final Quaternion PLANE_YZ = new Quaternion().fromAngleAxis(-FastMath.PI / 2, new Vector3f(0, 1, 0));//YAW090 - protected static final Quaternion PLANE_XZ = new Quaternion().fromAngleAxis(FastMath.PI / 2, new Vector3f(1, 0, 0)); //PITCH090 + public static final Quaternion PLANE_XY = new Quaternion().fromAngleAxis(0, new Vector3f(1, 0, 0)); + public static final Quaternion PLANE_YZ = new Quaternion().fromAngleAxis(-FastMath.PI / 2, new Vector3f(0, 1, 0));//YAW090 + public static final Quaternion PLANE_XZ = new Quaternion().fromAngleAxis(FastMath.PI / 2, new Vector3f(1, 0, 0)); //PITCH090 public PickManager() { @@ -75,7 +75,7 @@ public class PickManager { origineRotation = new Quaternion(Quaternion.IDENTITY); } else if (transformationType == SceneComposerToolController.TransformationType.camera) { rot.set(camera.getRotation()); - origineRotation = camera.getRotation().clone(); + origineRotation = camera.getRotation(); } plane.setLocalRotation(rot); } @@ -87,10 +87,6 @@ public class PickManager { * @return true if the the new picked location is set, else return false. */ public boolean updatePick(Camera camera, Vector2f screenCoord) { - if(transformationType == SceneComposerToolController.TransformationType.camera){ - origineRotation = camera.getRotation(); - plane.setLocalRotation(camera.getRotation()); - } finalPickLoc = SceneEditTool.pickWorldLocation(camera, screenCoord, plane, null); return finalPickLoc != null; } diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java index 21e9a56d8..e5a125771 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java @@ -25,7 +25,6 @@ import org.openide.util.Lookup; public class RotateTool extends SceneEditTool { private Vector3f pickedMarker; - private Vector2f lastScreenCoord; private Quaternion startRotate; private Quaternion lastRotate; private boolean wasDragging = false; @@ -48,9 +47,8 @@ public class RotateTool extends SceneEditTool { if (!pressed) { setDefaultAxisMarkerColors(); pickedMarker = null; // mouse released, reset selection - lastScreenCoord = null; if (wasDragging) { - actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); + actionPerformed(new RotateUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); wasDragging = false; } pickManager.reset(); @@ -100,10 +98,9 @@ public class RotateTool extends SceneEditTool { if (!pressed) { setDefaultAxisMarkerColors(); pickedMarker = null; // mouse released, reset selection - lastScreenCoord = null; if (wasDragging) { - actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); + actionPerformed(new RotateUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); wasDragging = false; } pickManager.reset(); @@ -138,12 +135,12 @@ public class RotateTool extends SceneEditTool { } } - private class ScaleUndo extends AbstractUndoableSceneEdit { + private class RotateUndo extends AbstractUndoableSceneEdit { private Spatial spatial; private Quaternion before, after; - ScaleUndo(Spatial spatial, Quaternion before, Quaternion after) { + RotateUndo(Spatial spatial, Quaternion before, Quaternion after) { this.spatial = spatial; this.before = before; this.after = after; diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java index 43d3cba3a..87f3c283f 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java @@ -8,425 +8,51 @@ import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; -import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; import com.jme3.gde.scenecomposer.SceneEditTool; -import com.jme3.input.KeyInput; -import com.jme3.input.event.KeyInputEvent; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.terrain.Terrain; import org.openide.loaders.DataObject; -import org.openide.util.Lookup; /** - * This duplicates the Blender manipulate tool. - * It supports quick access to Grab, Rotate, and Scale operations - * by typing one of the following keys: 'g', 'r', or 's' - * Those keys can be followed by an axis key to specify what axis - * to perform the transformation: x, y, z - * Then, after the operation and axis are selected, you can type in a - * number and then hit 'enter' to complete the transformation. - * - * Ctrl+Shift+D will duplicate an object - * X will delete an object - * - * ITEMS TO FINISH: - * 1) fixed scale and rotation values by holding Ctrl and dragging mouse - * BUGS: - * 1) window always needs focus from primary click when it should focus from secondary and middle mouse - * + * This duplicates the Blender manipulate tool. It supports quick access to + * Grab, Rotate, and Scale operations by typing one of the following keys: 'g', + * 'r', or 's' Those keys can be followed by an axis key to specify what axis to + * perform the transformation: x, y, z Then, after the operation and axis are + * selected, you can type in a number and then hit 'enter' to complete the + * transformation. + * + * Ctrl+Shift+D will duplicate an object X will delete an object + * + * ITEMS TO FINISH: 1) fixed scale and rotation values by holding Ctrl and + * dragging mouse BUGS: 1) window always needs focus from primary click when it + * should focus from secondary and middle mouse + * * @author Brent Owens */ public class SelectTool extends SceneEditTool { - private enum State { - - translate, rotate, scale - }; - private State currentState = null; - private Vector3f currentAxis = Vector3f.UNIT_XYZ; - private StringBuilder numberBuilder = new StringBuilder(); // gets appended with numbers - private Quaternion startRot; - private Vector3f startTrans; - private Vector3f startScale; - private boolean wasDraggingL = false; private boolean wasDraggingR = false; private boolean wasDownR = false; - private boolean ctrlDown = false; - private boolean shiftDown = false; - private boolean altDown = false; - private MoveManager.MoveUndo moving; - private ScaleUndo scaling; - private RotateUndo rotating; - private Vector2f startMouseCoord; // for scaling and rotation - private Vector2f startSelectedCoord; // for scaling and rotation - private float lastRotAngle; // used for rotation /** - * This is stateful: - * First it checks for a command (rotate, translate, delete, etc..) - * Then it checks for an axis (x,y,z) - * Then it checks for a number (user typed a number - * Then, finally, it checks if Enter was hit. - * + * This is stateful: First it checks for a command (rotate, translate, + * delete, etc..) Then it checks for an axis (x,y,z) Then it checks for a + * number (user typed a number Then, finally, it checks if Enter was hit. + * * If either of the commands was actioned, the preceeding states/axis/amount - * will be reset. For example if the user types: G Y 2 R - * Then it will: - * 1) Set state as 'Translate' for the G (grab) - * 2) Set the axis as 'Y'; it will translate along the Y axis - * 3) Distance will be 2, when the 2 key is hit - * 4) Distance, Axis, and state are then reset because a new state was set: Rotate - * it won't actually translate because 'Enter' was not hit and 'R' reset the state. - * + * will be reset. For example if the user types: G Y 2 R Then it will: 1) + * Set state as 'Translate' for the G (grab) 2) Set the axis as 'Y'; it will + * translate along the Y axis 3) Distance will be 2, when the 2 key is hit + * 4) Distance, Axis, and state are then reset because a new state was set: + * Rotate it won't actually translate because 'Enter' was not hit and 'R' + * reset the state. + * */ - @Override - public void keyPressed(KeyInputEvent kie) { - - checkModificatorKeys(kie); // alt,shift,ctrl - Spatial selected = toolController.getSelectedSpatial(); - - if (selected == null) { - return; // only do anything if a spatial is selected - } - // key released - if (kie.isPressed()) { - boolean commandUsed = checkCommandKey(kie); - boolean stateChange = checkStateKey(kie); - boolean axisChange = checkAxisKey(kie); - boolean numberChange = checkNumberKey(kie); - boolean enterHit = checkEnterHit(kie); - boolean escHit = checkEscHit(kie); - - if (commandUsed) { - return; // commands take priority - } - if (stateChange) { - currentAxis = Vector3f.UNIT_XYZ; - numberBuilder = new StringBuilder(); - recordInitialState(selected); - } else if (axisChange) { - } else if (numberChange) { - } else if (enterHit) { - if (currentState != null && numberBuilder.length() > 0) { - applyKeyedChangeState(selected); - clearState(false); - } - } - - - // ----------------------- - // reset conditions below: - - if (escHit) { - if (moving != null) { - moving.sceneUndo(); - } - - moving = null; - clearState(); - } - - if (!stateChange && !axisChange && !numberChange && !enterHit && !escHit) { - // nothing valid was hit, reset the state - //clearState(); // this will be - } - } - } - - /** - * Abort any manipulations - */ - private void clearState() { - clearState(true); - } - - private void clearState(boolean resetSelected) { - Spatial selected = toolController.getSelectedSpatial(); - if (resetSelected && selected != null) { - // reset the transforms - if (startRot != null) { - selected.setLocalRotation(startRot); - } - if (startTrans != null) { - selected.setLocalTranslation(startTrans); - } - if (startScale != null) { - selected.setLocalScale(startScale); - } - } - currentState = null; - currentAxis = Vector3f.UNIT_XYZ; - numberBuilder = new StringBuilder(); - startRot = null; - startTrans = null; - startScale = null; - startMouseCoord = null; - startSelectedCoord = null; - lastRotAngle = 0; - } - - private void recordInitialState(Spatial selected) { - startRot = selected.getLocalRotation().clone(); - startTrans = selected.getLocalTranslation().clone(); - startScale = selected.getLocalScale().clone(); - } - - /** - * Applies the changes entered by a number, not by mouse. - * Translate: adds the value to the current local translation - * Rotate: rotates by X degrees - * Scale: scale the current scale by X amount - */ - private void applyKeyedChangeState(Spatial selected) { - Float value = null; - try { - value = new Float(numberBuilder.toString()); - } catch (NumberFormatException e) { - return; - } - - if (currentState == State.translate) { - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - moveManager.moveAcross(currentAxis, value, toolController.isSnapToGrid()); - moving.setAfter(selected.getLocalTranslation()); - actionPerformed(moving); - moving = null; - } else if (currentState == State.scale) { - float x = 1, y = 1, z = 1; - if (currentAxis == Vector3f.UNIT_X) { - x = value; - } else if (currentAxis == Vector3f.UNIT_Y) { - y = value; - } else if (currentAxis == Vector3f.UNIT_Z) { - z = value; - } else if (currentAxis == Vector3f.UNIT_XYZ) { - x = value; - y = value; - z = value; - } - Vector3f before = selected.getLocalScale().clone(); - Vector3f after = selected.getLocalScale().multLocal(x, y, z); - selected.setLocalScale(after); - actionPerformed(new ScaleUndo(selected, before, after)); - } else if (currentState == State.rotate) { - float x = 0, y = 0, z = 0; - if (currentAxis == Vector3f.UNIT_X) { - x = 1; - } else if (currentAxis == Vector3f.UNIT_Y) { - y = 1; - } else if (currentAxis == Vector3f.UNIT_Z) { - z = 1; - } - Vector3f axis = new Vector3f(x, y, z); - Quaternion initialRot = selected.getLocalRotation().clone(); - Quaternion rot = new Quaternion(); - rot = rot.fromAngleAxis(value * FastMath.DEG_TO_RAD, axis); - selected.setLocalRotation(selected.getLocalRotation().mult(rot)); - RotateUndo undo = new RotateUndo(selected, initialRot, rot); - actionPerformed(undo); - toolController.updateSelection(null);// force a re-draw of the bbox shape - toolController.updateSelection(selected); - - } - clearState(false); - } - - private void checkModificatorKeys(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_LCONTROL || kie.getKeyCode() == KeyInput.KEY_RCONTROL) { - ctrlDown = kie.isPressed(); - } - - if (kie.getKeyCode() == KeyInput.KEY_LSHIFT || kie.getKeyCode() == KeyInput.KEY_RSHIFT) { - shiftDown = kie.isPressed(); - } - - if (kie.getKeyCode() == KeyInput.KEY_LMENU || kie.getKeyCode() == KeyInput.KEY_RMENU) { - altDown = kie.isPressed(); - } - } - - private boolean checkCommandKey(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_D) { - if (shiftDown) { - duplicateSelected(); - return true; - } - } - // X will only delete if the user isn't already transforming - if (currentState == null && kie.getKeyCode() == KeyInput.KEY_X) { - if (!ctrlDown && !shiftDown) { - deleteSelected(); - return true; - } - } - return false; - } - - private boolean checkStateKey(KeyInputEvent kie) { - Spatial selected = toolController.getSelectedSpatial(); - if (kie.getKeyCode() == KeyInput.KEY_G && !ctrlDown) { - currentState = State.translate; - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - moveManager.reset(); - Quaternion rot = camera.getRotation().mult(new Quaternion().fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y)); - moveManager.initiateMove(selected, rot, false); - moving = moveManager.makeUndo(); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_R && !ctrlDown) { - currentState = State.rotate; - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_S && !ctrlDown) { - currentState = State.scale; - return true; - } - return false; - } - - private boolean checkAxisKey(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_X) { - currentAxis = Vector3f.UNIT_X; - checkMovePlane(MoveManager.XY, MoveManager.XZ); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_Y) { - currentAxis = Vector3f.UNIT_Y; - checkMovePlane(MoveManager.XY, MoveManager.YZ); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_Z) { - currentAxis = Vector3f.UNIT_Z; - checkMovePlane(MoveManager.XZ, MoveManager.YZ); - return true; - } - return false; - } - - private void checkMovePlane(Quaternion rot1, Quaternion rot2) { - if (currentState == State.translate) { - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - Quaternion rot = camera.getRotation().mult(new Quaternion().fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y)); - Quaternion planRot = null; - if (rot.dot(rot1) < rot.dot(rot2)) { - planRot = rot1; - } else { - planRot = rot2; - } - moveManager.updatePlaneRotation(planRot); - } - } - - private boolean checkNumberKey(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_MINUS) { - if (numberBuilder.length() > 0) { - if (numberBuilder.charAt(0) == '-') { - numberBuilder.replace(0, 1, ""); - } else { - numberBuilder.insert(0, '-'); - } - } else { - numberBuilder.append('-'); - } - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_0 || kie.getKeyCode() == KeyInput.KEY_NUMPAD0) { - numberBuilder.append('0'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_1 || kie.getKeyCode() == KeyInput.KEY_NUMPAD1) { - numberBuilder.append('1'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_2 || kie.getKeyCode() == KeyInput.KEY_NUMPAD2) { - numberBuilder.append('2'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_3 || kie.getKeyCode() == KeyInput.KEY_NUMPAD3) { - numberBuilder.append('3'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_4 || kie.getKeyCode() == KeyInput.KEY_NUMPAD4) { - numberBuilder.append('4'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_5 || kie.getKeyCode() == KeyInput.KEY_NUMPAD5) { - numberBuilder.append('5'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_6 || kie.getKeyCode() == KeyInput.KEY_NUMPAD6) { - numberBuilder.append('6'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_7 || kie.getKeyCode() == KeyInput.KEY_NUMPAD7) { - numberBuilder.append('7'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_8 || kie.getKeyCode() == KeyInput.KEY_NUMPAD8) { - numberBuilder.append('8'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_9 || kie.getKeyCode() == KeyInput.KEY_NUMPAD9) { - numberBuilder.append('9'); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_PERIOD) { - if (numberBuilder.indexOf(".") == -1) { // if it doesn't exist yet - if (numberBuilder.length() == 0 - || (numberBuilder.length() == 1 && numberBuilder.charAt(0) == '-')) { - numberBuilder.append("0."); - } else { - numberBuilder.append("."); - } - } - return true; - } - - return false; - } - - private boolean checkEnterHit(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_RETURN) { - return true; - } - return false; - } - - private boolean checkEscHit(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_ESCAPE) { - return true; - } - return false; - } - @Override public void actionPrimary(Vector2f screenCoord, boolean pressed, final JmeNode rootNode, DataObject dataObject) { - if (!pressed) { - Spatial selected = toolController.getSelectedSpatial(); - // left mouse released - if (!wasDraggingL) { - // left mouse pressed - if (currentState != null) { - // finish manipulating the spatial - if (moving != null) { - moving.setAfter(selected.getLocalTranslation()); - actionPerformed(moving); - moving = null; - clearState(false); - } else if (scaling != null) { - scaling.after = selected.getLocalScale().clone(); - actionPerformed(scaling); - scaling = null; - clearState(false); - toolController.rebuildSelectionBox(); - } else if (rotating != null) { - rotating.after = selected.getLocalRotation().clone(); - actionPerformed(rotating); - rotating = null; - clearState(false); - } - } else { - // mouse released and wasn't dragging, place cursor - final Vector3f result = pickWorldLocation(getCamera(), screenCoord, rootNode); - if (result != null) { - if (toolController.isSnapToGrid()) { - result.set(Math.round(result.x), result.y, Math.round(result.z)); - } - toolController.setCursorLocation(result); - } - } - } - wasDraggingL = false; - } + } @Override @@ -435,19 +61,7 @@ public class SelectTool extends SceneEditTool { Spatial selected = toolController.getSelectedSpatial(); // mouse down - if (moving != null) { - moving.sceneUndo(); - moving = null; - clearState(); - } else if (scaling != null) { - scaling.sceneUndo(); - scaling = null; - clearState(); - } else if (rotating != null) { - rotating.sceneUndo(); - rotating = null; - clearState(); - } else if (!wasDraggingR && !wasDownR) { // wasn't dragging and was not down already + if (!wasDraggingR && !wasDownR) { // wasn't dragging and was not down already // pick on the spot Spatial s = pickWorldSpatial(camera, screenCoord, rootNode); if (!toolController.selectTerrain() && isTerrain(s)) { @@ -498,8 +112,8 @@ public class SelectTool extends SceneEditTool { } /** - * Climb up the spatial until we find the first node parent. - * TODO: use userData to determine the actual model's parent. + * Climb up the spatial until we find the first node parent. TODO: use + * userData to determine the actual model's parent. */ private Spatial findModelNodeParent(Spatial child) { if (child == null) { @@ -519,14 +133,10 @@ public class SelectTool extends SceneEditTool { @Override public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject currentDataObject, JmeSpatial selectedSpatial) { - if (currentState != null) { - handleMouseManipulate(screenCoord, currentState, currentAxis, rootNode, currentDataObject, selectedSpatial); - } } @Override public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { - wasDraggingL = pressed; } @Override @@ -535,252 +145,8 @@ public class SelectTool extends SceneEditTool { } /** - * Manipulate the spatial - */ - private void handleMouseManipulate(Vector2f screenCoord, - State state, - Vector3f axis, - JmeNode rootNode, - DataObject currentDataObject, - JmeSpatial selectedSpatial) { - if (state == State.translate) { - doMouseTranslate(axis, screenCoord, rootNode, selectedSpatial); - } else if (state == State.scale) { - doMouseScale(axis, screenCoord, rootNode, selectedSpatial); - } else if (state == State.rotate) { - doMouseRotate(axis, screenCoord, rootNode, selectedSpatial); - } - - } - - private void doMouseTranslate(Vector3f axis, Vector2f screenCoord, JmeNode rootNode, JmeSpatial selectedSpatial) { - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - if (toolController.isSnapToScene()) { - moveManager.setAlternativePickTarget(rootNode.getLookup().lookup(Node.class)); - } - // free form translation - moveManager.move(camera, screenCoord, axis, toolController.isSnapToGrid()); - } - - private void doMouseScale(Vector3f axis, Vector2f screenCoord, JmeNode rootNode, JmeSpatial selectedSpatial) { - Spatial selected = toolController.getSelectedSpatial(); - // scale based on the original mouse position and original model-to-screen position - // and compare that to the distance from the new mouse position and the original distance - if (startMouseCoord == null) { - startMouseCoord = screenCoord.clone(); - } - if (startSelectedCoord == null) { - Vector3f screen = getCamera().getScreenCoordinates(selected.getWorldTranslation()); - startSelectedCoord = new Vector2f(screen.x, screen.y); - } - - if (scaling == null) { - scaling = new ScaleUndo(selected, selected.getLocalScale().clone(), null); - } - - float origDist = startMouseCoord.distanceSquared(startSelectedCoord); - float newDist = screenCoord.distanceSquared(startSelectedCoord); - if (origDist == 0) { - origDist = 1; - } - float ratio = newDist / origDist; - Vector3f prev = selected.getLocalScale(); - if (axis == Vector3f.UNIT_X) { - selected.setLocalScale(ratio, prev.y, prev.z); - } else if (axis == Vector3f.UNIT_Y) { - selected.setLocalScale(prev.x, ratio, prev.z); - } else if (axis == Vector3f.UNIT_Z) { - selected.setLocalScale(prev.x, prev.y, ratio); - } else { - selected.setLocalScale(ratio, ratio, ratio); - } - } - - private void doMouseRotate(Vector3f axis, Vector2f screenCoord, JmeNode rootNode, JmeSpatial selectedSpatial) { - Spatial selected = toolController.getSelectedSpatial(); - if (startMouseCoord == null) { - startMouseCoord = screenCoord.clone(); - } - if (startSelectedCoord == null) { - Vector3f screen = getCamera().getScreenCoordinates(selected.getWorldTranslation()); - startSelectedCoord = new Vector2f(screen.x, screen.y); - } - - if (rotating == null) { - rotating = new RotateUndo(selected, selected.getLocalRotation().clone(), null); - } - - Vector2f origRot = startMouseCoord.subtract(startSelectedCoord); - Vector2f newRot = screenCoord.subtract(startSelectedCoord); - float newRotAngle = origRot.angleBetween(newRot); - float temp = newRotAngle; - - if (lastRotAngle != 0) { - newRotAngle -= lastRotAngle; - } - - lastRotAngle = temp; - - Quaternion rotate = new Quaternion(); - if (axis != Vector3f.UNIT_XYZ) { - rotate = rotate.fromAngleAxis(newRotAngle, selected.getWorldRotation().inverse().mult(axis)); - } else { - rotate = rotate.fromAngleAxis(newRotAngle, selected.getWorldRotation().inverse().mult(getCamera().getDirection().mult(-1).normalizeLocal())); - } - selected.setLocalRotation(selected.getLocalRotation().mult(rotate)); - - - } - - private void duplicateSelected() { - Spatial selected = toolController.getSelectedSpatial(); - if (selected == null) { - return; - } - Spatial clone = selected.clone(); - clone.move(1, 0, 1); - - selected.getParent().attachChild(clone); - actionPerformed(new DuplicateUndo(clone, selected.getParent())); - selected = clone; - final Spatial cloned = clone; - final JmeNode rootNode = toolController.getRootNode(); - refreshSelected(rootNode, selected.getParent()); - - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - if (cloned != null) { - SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{rootNode.getChild(cloned)}); - SceneExplorerTopComponent.findInstance().setSelectedNode(rootNode.getChild(cloned)); - } - } - }); - - // set to automatically 'grab'/'translate' the new cloned model - toolController.updateSelection(selected); - currentState = State.translate; - currentAxis = Vector3f.UNIT_XYZ; - } - - private void deleteSelected() { - Spatial selected = toolController.getSelectedSpatial(); - if (selected == null) { - return; - } - Node parent = selected.getParent(); - selected.removeFromParent(); - actionPerformed(new DeleteUndo(selected, parent)); - - selected = null; - toolController.updateSelection(selected); - - final JmeNode rootNode = toolController.getRootNode(); - refreshSelected(rootNode, parent); - } - - private void refreshSelected(final JmeNode jmeRootNode, final Node parent) { - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - jmeRootNode.getChild(parent).refresh(false); - } - }); - } - - private class ScaleUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Vector3f before, after; - - ScaleUndo(Spatial spatial, Vector3f before, Vector3f after) { - this.spatial = spatial; - this.before = before; - this.after = after; - } - - @Override - public void sceneUndo() { - spatial.setLocalScale(before); - } - - @Override - public void sceneRedo() { - spatial.setLocalScale(after); - } - } - - private class RotateUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Quaternion before, after; - - RotateUndo(Spatial spatial, Quaternion before, Quaternion after) { - this.spatial = spatial; - this.before = before; - this.after = after; - } - - @Override - public void sceneUndo() { - spatial.setLocalRotation(before); - } - - @Override - public void sceneRedo() { - spatial.setLocalRotation(after); - } - } - - private class DeleteUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Node parent; - - DeleteUndo(Spatial spatial, Node parent) { - this.spatial = spatial; - this.parent = parent; - } - - @Override - public void sceneUndo() { - parent.attachChild(spatial); - } - - @Override - public void sceneRedo() { - spatial.removeFromParent(); - } - } - - private class DuplicateUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Node parent; - - DuplicateUndo(Spatial spatial, Node parent) { - this.spatial = spatial; - this.parent = parent; - } - - @Override - public void sceneUndo() { - spatial.removeFromParent(); - } - - @Override - public void sceneRedo() { - parent.attachChild(spatial); - } - } - - /** - * Check if the selected item is a Terrain - * It will climb up the parent tree to see if - * a parent is terrain too. - * Recursive call. + * Check if the selected item is a Terrain It will climb up the parent tree + * to see if a parent is terrain too. Recursive call. */ protected boolean isTerrain(Spatial s) { if (s == null) { diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java new file mode 100644 index 000000000..cc13ece1d --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java @@ -0,0 +1,123 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector2f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class DeleteShortcut extends ShortcutTool { + + @Override + public boolean isActivableBy(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_X && kie.isPressed()) { + if (Lookup.getDefault().lookup(ShortcutManager.class).isShiftDown()) { + return true; + } + } + return false; + } + + @Override + public void cancel() { + terminate(); + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + if (selectedSpatial != null) { + delete(); + } + terminate(); + } + + private void delete() { + Spatial selected = toolController.getSelectedSpatial(); + + Node parent = selected.getParent(); + selected.removeFromParent(); + actionPerformed(new DeleteUndo(selected, parent)); + + selected = null; + toolController.updateSelection(selected); + + final JmeNode rootNode = toolController.getRootNode(); + refreshSelected(rootNode, parent); + } + + private void refreshSelected(final JmeNode jmeRootNode, final Node parent) { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + jmeRootNode.getChild(parent).refresh(false); + } + }); + } + + @Override + public void keyPressed(KeyInputEvent kie) { + + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + private class DeleteUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Node parent; + + DeleteUndo(Spatial spatial, Node parent) { + this.spatial = spatial; + this.parent = parent; + } + + @Override + public void sceneUndo() { + parent.attachChild(spatial); + } + + @Override + public void sceneRedo() { + spatial.removeFromParent(); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java new file mode 100644 index 000000000..d98eb6ee9 --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java @@ -0,0 +1,141 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector2f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class DuplicateShortcut extends ShortcutTool { + + @Override + public boolean isActivableBy(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_D && kie.isPressed()) { + if (Lookup.getDefault().lookup(ShortcutManager.class).isShiftDown()) { + return true; + } + } + return false; + } + + @Override + public void cancel() { + terminate(); + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + if (selectedSpatial != null) { + duplicate(); + terminate(); + + //then enable move shortcut + toolController.doKeyPressed(new KeyInputEvent(KeyInput.KEY_G, 'g', true, false)); + } else { + terminate(); + } + } + + private void duplicate() { + Spatial selected = toolController.getSelectedSpatial(); + + Spatial clone = selected.clone(); + clone.move(1, 0, 1); + + selected.getParent().attachChild(clone); + actionPerformed(new DuplicateUndo(clone, selected.getParent())); + selected = clone; + final Spatial cloned = clone; + final JmeNode rootNode = toolController.getRootNode(); + refreshSelected(rootNode, selected.getParent()); + + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + if (cloned != null) { + SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{rootNode.getChild(cloned)}); + SceneExplorerTopComponent.findInstance().setSelectedNode(rootNode.getChild(cloned)); + } + } + }); + + toolController.updateSelection(selected); + } + + private void refreshSelected(final JmeNode jmeRootNode, final Node parent) { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + jmeRootNode.getChild(parent).refresh(false); + } + }); + } + + @Override + public void keyPressed(KeyInputEvent kie) { + + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + private class DuplicateUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Node parent; + + DuplicateUndo(Spatial spatial, Node parent) { + this.spatial = spatial; + this.parent = parent; + } + + @Override + public void sceneUndo() { + spatial.removeFromParent(); + } + + @Override + public void sceneRedo() { + parent.attachChild(spatial); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java new file mode 100644 index 000000000..6291ab932 --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java @@ -0,0 +1,227 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.bullet.control.CharacterControl; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class MoveShortcut extends ShortcutTool { + + private Vector3f currentAxis; + private StringBuilder numberBuilder; + private Spatial spatial; + private PickManager pickManager; + private boolean pickEnabled; + private Vector3f startPosition; + private Vector3f finalPosition; + + @Override + + public boolean isActivableBy(KeyInputEvent kie) { + return kie.getKeyCode() == KeyInput.KEY_G; + } + + @Override + public void cancel() { + spatial.setLocalTranslation(startPosition); + terminate(); + } + + private void apply() { + actionPerformed(new MoveUndo(toolController.getSelectedSpatial(), startPosition, finalPosition)); + terminate(); + } + + private void init(Spatial selectedSpatial) { + spatial = selectedSpatial; + startPosition = spatial.getLocalTranslation().clone(); + currentAxis = Vector3f.UNIT_XYZ; + pickManager = Lookup.getDefault().lookup(PickManager.class); + pickEnabled = false; + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + numberBuilder = new StringBuilder(); + if (selectedSpatial == null) { + terminate(); + } else { + init(selectedSpatial); + } + } + + @Override + public void keyPressed(KeyInputEvent kie) { + if (kie.isPressed()) { + Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); + + Vector3f axis = new Vector3f(); + boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis); + if (axisChanged) { + currentAxis = axis; + } + boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); + boolean enterHit = ShortcutManager.checkEnterHit(kie); + boolean escHit = ShortcutManager.checkEscHit(kie); + + if (escHit) { + cancel(); + } else if (enterHit) { + apply(); + } else if (axisChanged && pickEnabled) { + //update pick manager + + if (currentAxis.equals(Vector3f.UNIT_X)) { + pickManager.setTransformation(PickManager.PLANE_XY, getTransformType(), camera); + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + pickManager.setTransformation(PickManager.PLANE_YZ, getTransformType(), camera); + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + pickManager.setTransformation(PickManager.PLANE_XZ, getTransformType(), camera); + } + } else if (axisChanged || numberChanged) { + //update transformation + float number = ShortcutManager.getNumberKey(numberBuilder); + Vector3f translation = currentAxis.mult(number); + finalPosition = startPosition.add(translation); + spatial.setLocalTranslation(finalPosition); + + } + + } + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + cancel(); + } + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + + if (!pickEnabled) { + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), camera.getRotation(), SceneComposerToolController.TransformationType.camera, camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_X)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XY, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else { + return; + } + } + + if (pickManager.updatePick(camera, screenCoord)) { + //pick update success + Vector3f diff; + + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + diff = pickManager.getTranslation(); + } else { + diff = pickManager.getTranslation(currentAxis); + } + Vector3f position = startPosition.add(diff); + finalPosition = position; + toolController.getSelectedSpatial().setLocalTranslation(position); + updateToolsTransformation(); + } + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + cancel(); + } + } + + private class MoveUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Vector3f before = new Vector3f(), after = new Vector3f(); + + MoveUndo(Spatial spatial, Vector3f before, Vector3f after) { + this.spatial = spatial; + this.before.set(before); + if (after != null) { + this.after.set(after); + } + } + + @Override + public void sceneUndo() { + spatial.setLocalTranslation(before); + RigidBodyControl control = spatial.getControl(RigidBodyControl.class); + if (control != null) { + control.setPhysicsLocation(spatial.getWorldTranslation()); + } + CharacterControl character = spatial.getControl(CharacterControl.class); + if (character != null) { + character.setPhysicsLocation(spatial.getWorldTranslation()); + } + // toolController.selectedSpatialTransformed(); + } + + @Override + public void sceneRedo() { + spatial.setLocalTranslation(after); + RigidBodyControl control = spatial.getControl(RigidBodyControl.class); + if (control != null) { + control.setPhysicsLocation(spatial.getWorldTranslation()); + } + CharacterControl character = spatial.getControl(CharacterControl.class); + if (character != null) { + character.setPhysicsLocation(spatial.getWorldTranslation()); + } + //toolController.selectedSpatialTransformed(); + } + + public void setAfter(Vector3f after) { + this.after.set(after); + } + } + +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java new file mode 100644 index 000000000..8b9ffe404 --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java @@ -0,0 +1,189 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class RotateShortcut extends ShortcutTool { + + private Vector3f currentAxis; + private StringBuilder numberBuilder; + private Spatial spatial; + private PickManager pickManager; + private boolean pickEnabled; + private Quaternion startRotation; + private Quaternion finalRotation; + + @Override + + public boolean isActivableBy(KeyInputEvent kie) { + return kie.getKeyCode() == KeyInput.KEY_R; + } + + @Override + public void cancel() { + spatial.setLocalRotation(startRotation); + terminate(); + } + + private void apply() { + actionPerformed(new RotateUndo(toolController.getSelectedSpatial(), startRotation, finalRotation)); + terminate(); + } + + private void init(Spatial selectedSpatial) { + spatial = selectedSpatial; + startRotation = spatial.getLocalRotation().clone(); + currentAxis = Vector3f.UNIT_XYZ; + pickManager = Lookup.getDefault().lookup(PickManager.class); + pickEnabled = false; + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + numberBuilder = new StringBuilder(); + if (selectedSpatial == null) { + terminate(); + } else { + init(selectedSpatial); + } + } + + @Override + public void keyPressed(KeyInputEvent kie) { + if (kie.isPressed()) { + Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); + + Vector3f axis = new Vector3f(); + boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis); + if (axisChanged) { + currentAxis = axis; + } + boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); + boolean enterHit = ShortcutManager.checkEnterHit(kie); + boolean escHit = ShortcutManager.checkEscHit(kie); + + if (escHit) { + cancel(); + } else if (enterHit) { + apply(); + } else if (axisChanged && pickEnabled) { + pickEnabled = false; + spatial.setLocalRotation(startRotation.clone()); + } else if (axisChanged || numberChanged) { + //update transformation + /* float number = ShortcutManager.getNumberKey(numberBuilder); + Vector3f translation = currentAxis.mult(number); + finalPosition = startPosition.add(translation); + spatial.setLocalTranslation(finalPosition); + */ + } + + } + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + cancel(); + } + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + + if (!pickEnabled) { + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), camera.getRotation(), SceneComposerToolController.TransformationType.camera, camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_X)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XY, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else { + return; + } + } + + if (pickManager.updatePick(camera, screenCoord)) { + + Quaternion rotation = startRotation.mult(pickManager.getRotation(startRotation.inverse())); + toolController.getSelectedSpatial().setLocalRotation(rotation); + finalRotation = rotation; + updateToolsTransformation(); + } + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + cancel(); + } + } + + private class RotateUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Quaternion before, after; + + RotateUndo(Spatial spatial, Quaternion before, Quaternion after) { + this.spatial = spatial; + this.before = before; + this.after = after; + } + + @Override + public void sceneUndo() { + spatial.setLocalRotation(before); + toolController.selectedSpatialTransformed(); + } + + @Override + public void sceneRedo() { + spatial.setLocalRotation(after); + toolController.selectedSpatialTransformed(); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java new file mode 100644 index 000000000..8fa18858f --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java @@ -0,0 +1,199 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class ScaleShortcut extends ShortcutTool { + + private Vector3f currentAxis; + private StringBuilder numberBuilder; + private Spatial spatial; + private PickManager pickManager; + private boolean pickEnabled; + private Vector3f startScale; + private Vector3f finalScale; + + @Override + + public boolean isActivableBy(KeyInputEvent kie) { + return kie.getKeyCode() == KeyInput.KEY_S; + } + + @Override + public void cancel() { + spatial.setLocalScale(startScale); + terminate(); + } + + private void apply() { + actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startScale, finalScale)); + terminate(); + } + + private void init(Spatial selectedSpatial) { + spatial = selectedSpatial; + startScale = spatial.getLocalScale().clone(); + currentAxis = Vector3f.UNIT_XYZ; + pickManager = Lookup.getDefault().lookup(PickManager.class); + pickEnabled = false; + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + numberBuilder = new StringBuilder(); + if (selectedSpatial == null) { + terminate(); + } else { + init(selectedSpatial); + } + } + + @Override + public void keyPressed(KeyInputEvent kie) { + if (kie.isPressed()) { + Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); + + Vector3f axis = new Vector3f(); + boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis); + if (axisChanged) { + currentAxis = axis; + } + boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); + boolean enterHit = ShortcutManager.checkEnterHit(kie); + boolean escHit = ShortcutManager.checkEscHit(kie); + + if (escHit) { + cancel(); + } else if (enterHit) { + apply(); + } else if (axisChanged && pickEnabled) { + pickEnabled = false; + } else if (axisChanged || numberChanged) { + //update transformation + /* float number = ShortcutManager.getNumberKey(numberBuilder); + Vector3f translation = currentAxis.mult(number); + finalPosition = startPosition.add(translation); + spatial.setLocalTranslation(finalPosition); + */ + } + + } + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + cancel(); + } + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + + if (!pickEnabled) { + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), camera.getRotation(), SceneComposerToolController.TransformationType.camera, camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_X)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XY, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else { + return; + } + } + + if (pickManager.updatePick(camera, screenCoord)) { + Vector3f scale = startScale; + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + Vector3f constraintAxis = pickManager.getStartOffset().normalize(); + float diff = pickManager.getTranslation(constraintAxis).dot(constraintAxis); + diff *= 0.5f; + scale = startScale.add(new Vector3f(diff, diff, diff)); + } else { + // Get the translation in the spatial Space + Quaternion worldToSpatial = toolController.getSelectedSpatial().getWorldRotation().inverse(); + Vector3f diff = pickManager.getTranslation(worldToSpatial.mult(currentAxis)); + diff.multLocal(0.5f); + scale = startScale.add(diff); + } + finalScale = scale; + toolController.getSelectedSpatial().setLocalScale(scale); + updateToolsTransformation(); + } + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + cancel(); + } + } + + private class ScaleUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Vector3f before, after; + + ScaleUndo(Spatial spatial, Vector3f before, Vector3f after) { + this.spatial = spatial; + this.before = before; + this.after = after; + } + + @Override + public void sceneUndo() { + spatial.setLocalScale(before); + toolController.selectedSpatialTransformed(); + } + + @Override + public void sceneRedo() { + spatial.setLocalScale(after); + toolController.selectedSpatialTransformed(); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java new file mode 100644 index 000000000..187293e92 --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java @@ -0,0 +1,335 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.gde.scenecomposer.SceneEditTool; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector3f; +import java.util.ArrayList; +import org.openide.util.Lookup; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author dokthar + */ +@ServiceProvider(service = ShortcutManager.class) +public class ShortcutManager { + + private ShortcutTool currentShortcut; + private ArrayList shortcutList; + private boolean ctrlDown = false; + private boolean shiftDown = false; + private boolean altDown = false; + + public ShortcutManager() { + shortcutList = new ArrayList(); + shortcutList.add(new MoveShortcut()); + shortcutList.add(new RotateShortcut()); + shortcutList.add(new ScaleShortcut()); + shortcutList.add(new DuplicateShortcut()); + shortcutList.add(new DeleteShortcut()); + } + + /* + Methodes + */ + /** + * This MUST be called by the shortcut tool once the modifications are done. + */ + public void terminate() { + currentShortcut = null; + } + + /** + * + * @return true if a shortCutTool is active, else return false. + */ + public boolean isActive() { + return currentShortcut != null; + } + + /** + * @return the ctrlDown + */ + public boolean isCtrlDown() { + return ctrlDown; + } + + /** + * @return the shiftDown + */ + public boolean isShiftDown() { + return shiftDown; + } + + /** + * @return the altDown + */ + public boolean isAltDown() { + return altDown; + } + + /** + * Set the current shortcut to shortcut. cancel the current + * shortcut if it was still active + * + * @param shortcut the ShortCutTool to set + */ + public void setShortCut(ShortcutTool shortcut) { + if (isActive()) { + currentShortcut.cancel(); + } + currentShortcut = shortcut; + } + + /** + * Get the shortcut that can be enable with the given kei, the current + * shortcut cannot be enable twice. This also check for command key used to + * provide isCtrlDown(), isShiftDown() and isAltDown(). + * + * @param kie the KeyInputEvent + * @return the activable shortcut else return null + */ + public ShortcutTool getActivableShortcut(KeyInputEvent kie) { + if (checkCommandeKey(kie)) { + return null; + } + for (ShortcutTool s : shortcutList) { + if (s != currentShortcut) { + if (s.isActivableBy(kie)) { + return s; + } + } + } + return null; + } + + /** + * + * @return the current active shortcut + */ + public ShortcutTool getActiveShortcut() { + return currentShortcut; + } + + /** + * + * @param kie the KeyInputEvent + * @return true if the given Kei can enable a sortcut, else false + */ + public boolean canActivateShortcut(KeyInputEvent kie) { + return getActivableShortcut(kie) != null; + } + + /** + * Set the current shortcut with the shortcut one that can be enable with + * the given key + * + * @param kie the KeyInputEvent + * @return true is the shortcut changed, else false + */ + public boolean activateShortcut(KeyInputEvent kie) { + ShortcutTool newShortcut = getActivableShortcut(kie); + if (newShortcut != null) { + currentShortcut = newShortcut; + } + return newShortcut != null; + } + + /** + * This should be called to trigger the currentShortcut.keyPressed() method. + * This also check for command key used to provide isCtrlDown(), + * isShiftDown() and isAltDown(). + * + * @param kie + */ + public void doKeyPressed(KeyInputEvent kie) { + if (checkCommandeKey(kie)) { + //return; + } else if (isActive()) { + currentShortcut.keyPressed(kie); + } + } + + private boolean checkCommandeKey(KeyInputEvent kie) { + if (checkCtrlHit(kie)) { + ctrlDown = kie.isPressed(); + return true; + } else if (checkAltHit(kie)) { + altDown = kie.isPressed(); + return true; + } else if (checkShiftHit(kie)) { + shiftDown = kie.isPressed(); + return true; + } + return false; + } + + /* + STATIC + */ + /** + * + * @param kie + * @return true if the given kie is KEY_RETURN + */ + public static boolean checkEnterHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_RETURN) { + return true; + } + return false; + } + + /** + * + * @param kie + * @return true if the given kie is KEY_ESCAPE + */ + public static boolean checkEscHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_ESCAPE) { + return true; + } + return false; + } + + /** + * + * @param kie + * @return true if the given kie is KEY_LCONTROL || KEY_RCONTROL + */ + public static boolean checkCtrlHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_LCONTROL || kie.getKeyCode() == KeyInput.KEY_RCONTROL) { + return true; + } + return false; + } + + /** + * + * @param kie + * @return true if the given kie is KEY_LSHIFT || KEY_RSHIFT + */ + public static boolean checkShiftHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_LSHIFT || kie.getKeyCode() == KeyInput.KEY_RSHIFT) { + return true; + } + return false; + } + + /** + * + * @param kie + * @return true if the given kie is KEY_LMENU || KEY_RMENU + */ + public static boolean checkAltHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_LMENU || kie.getKeyCode() == KeyInput.KEY_RMENU) { + return true; + } + return false; + } + + /** + * store the number kie into the numberBuilder + * + * @param kie + * @param numberBuilder + * @return true if the given kie is handled as a number key event + */ + public static boolean checkNumberKey(KeyInputEvent kie, StringBuilder numberBuilder) { + if (kie.getKeyCode() == KeyInput.KEY_MINUS) { + if (numberBuilder.length() > 0) { + if (numberBuilder.charAt(0) == '-') { + numberBuilder.replace(0, 1, ""); + } else { + numberBuilder.insert(0, '-'); + } + } else { + numberBuilder.append('-'); + } + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_0 || kie.getKeyCode() == KeyInput.KEY_NUMPAD0) { + numberBuilder.append('0'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_1 || kie.getKeyCode() == KeyInput.KEY_NUMPAD1) { + numberBuilder.append('1'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_2 || kie.getKeyCode() == KeyInput.KEY_NUMPAD2) { + numberBuilder.append('2'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_3 || kie.getKeyCode() == KeyInput.KEY_NUMPAD3) { + numberBuilder.append('3'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_4 || kie.getKeyCode() == KeyInput.KEY_NUMPAD4) { + numberBuilder.append('4'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_5 || kie.getKeyCode() == KeyInput.KEY_NUMPAD5) { + numberBuilder.append('5'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_6 || kie.getKeyCode() == KeyInput.KEY_NUMPAD6) { + numberBuilder.append('6'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_7 || kie.getKeyCode() == KeyInput.KEY_NUMPAD7) { + numberBuilder.append('7'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_8 || kie.getKeyCode() == KeyInput.KEY_NUMPAD8) { + numberBuilder.append('8'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_9 || kie.getKeyCode() == KeyInput.KEY_NUMPAD9) { + numberBuilder.append('9'); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_PERIOD) { + if (numberBuilder.indexOf(".") == -1) { // if it doesn't exist yet + if (numberBuilder.length() == 0 + || (numberBuilder.length() == 1 && numberBuilder.charAt(0) == '-')) { + numberBuilder.append("0."); + } else { + numberBuilder.append("."); + } + } + return true; + } + + return false; + } + + /** + * + * @param numberBuilder the StringBuilder storing the float number + * @return the float value created from the given StringBuilder + */ + public static float getNumberKey(StringBuilder numberBuilder) { + if (numberBuilder.length() == 0) { + return 0; + } else { + return new Float(numberBuilder.toString()); + } + } + + /** + * Check for axis input for key X,Y,Z and store the corresponding UNIT_ into + * the axisStore + * + * @param kie + * @param axisStore + * @return true if the given kie is handled as a Axis input + */ + public static boolean checkAxisKey(KeyInputEvent kie, Vector3f axisStore) { + if (kie.getKeyCode() == KeyInput.KEY_X) { + axisStore.set(Vector3f.UNIT_X); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_Y) { + axisStore.set(Vector3f.UNIT_Y); + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_Z) { + axisStore.set(Vector3f.UNIT_Z); + return true; + } + return false; + } + +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutTool.java new file mode 100644 index 000000000..9b094fc1d --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutTool.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.gde.scenecomposer.SceneEditTool; +import com.jme3.input.event.KeyInputEvent; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public abstract class ShortcutTool extends SceneEditTool { + + public abstract boolean isActivableBy(KeyInputEvent kie); + + public abstract void cancel(); + + protected final void terminate() { + Lookup.getDefault().lookup(ShortcutManager.class).terminate(); + } + + @Override + public abstract void keyPressed(KeyInputEvent kie); + +}