/* * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package com.sun.javafx.scene.input; import com.sun.javafx.scene.CameraHelper; import com.sun.javafx.scene.NodeHelper; import com.sun.javafx.scene.SceneHelper; import com.sun.javafx.scene.SceneUtils; import com.sun.javafx.scene.SubSceneHelper; import java.util.Arrays; import java.util.List; import java.util.Collections; import javafx.geometry.Point2D; import javafx.geometry.Point3D; import javafx.scene.Node; import javafx.scene.SubScene; import javafx.scene.input.PickResult; import javafx.scene.input.TransferMode; /** * Utility class for helper methods needed by input events. */ public class InputEventUtils { /** * Recomputes event coordinates for a different node. * @param coordinates Coordinates to recompute * @param oldSource Node in whose coordinate system the coordinates are * @param newSource Node to whose coordinate system to recompute * @return the recomputed coordinates */ public static Point3D recomputeCoordinates(PickResult result, Object newSource) { Point3D coordinates = result.getIntersectedPoint(); if (coordinates == null) { return new Point3D(Double.NaN, Double.NaN, Double.NaN); } final Node oldSourceNode = result.getIntersectedNode(); final Node newSourceNode = (newSource instanceof Node) ? (Node) newSource : null; final SubScene oldSubScene = (oldSourceNode == null ? null : NodeHelper.getSubScene(oldSourceNode)); final SubScene newSubScene = (newSourceNode == null ? null : NodeHelper.getSubScene(newSourceNode)); final boolean subScenesDiffer = (oldSubScene != newSubScene); if (oldSourceNode != null) { // transform to scene/nearest-subScene coordinates coordinates = oldSourceNode.localToScene(coordinates); if (subScenesDiffer && oldSubScene != null) { // transform to scene coordiantes coordinates = SceneUtils.subSceneToScene(oldSubScene, coordinates); } } if (newSourceNode != null) { if (subScenesDiffer && newSubScene != null) { // flatten the coords to flat mouse coordinates - project // by scene's camera Point2D planeCoords = CameraHelper.project( SceneHelper.getEffectiveCamera(newSourceNode.getScene()), coordinates); // convert the point to subScene coordinates planeCoords = SceneUtils.sceneToSubScenePlane(newSubScene, planeCoords); // compute inner intersection with the subScene's camera // projection plane if (planeCoords == null) { coordinates = null; } else { coordinates = CameraHelper.pickProjectPlane( SubSceneHelper.getEffectiveCamera(newSubScene), planeCoords.getX(), planeCoords.getY()); } } // transform the point to source's local coordinates if (coordinates != null) { coordinates = newSourceNode.sceneToLocal(coordinates); } if (coordinates == null) { coordinates = new Point3D(Double.NaN, Double.NaN, Double.NaN); } } return coordinates; } private static final List TM_ANY = Collections.unmodifiableList(Arrays.asList( TransferMode.COPY, TransferMode.MOVE, TransferMode.LINK )); private static final List TM_COPY_OR_MOVE = Collections.unmodifiableList(Arrays.asList( TransferMode.COPY, TransferMode.MOVE )); /** * Makes sure changes to the static arrays specified in TransferMode * don't have any effect on the transfer modes used. * @param modes Modes passed in by user * @return list containing the passed modes. If one of the static arrays * is passed, the expected modes are returned regardless of the * values in those arrays. */ public static List safeTransferModes(TransferMode[] modes) { if (modes == TransferMode.ANY) { return TM_ANY; } else if (modes == TransferMode.COPY_OR_MOVE) { return TM_COPY_OR_MOVE; } else { return Arrays.asList(modes); } } }