<commit_before>/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2003-2011 Ausenco Engineering Canada Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
package com.sandwell.JavaSimulation3D;

import com.sandwell.JavaSimulation.Entity;
import com.sandwell.JavaSimulation.Vector;
import com.sun.j3d.utils.behaviors.vp.ViewPlatformAWTBehavior;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;

import com.sandwell.JavaSimulation3D.util.Rectangle;
import com.sandwell.JavaSimulation3D.util.Shape;

import javax.media.j3d.Transform3D;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

/**
 * Provides mouse events processing of moving the viewer within a J3D environment.<br>
 * Provides this functionality by providing the viewer location, the point to look at and the up vector.<br>
 * Provides changes of the viewer of: zoom, pan, translate, orbit and field of view angle<br>
 * Provides the position of the locator in model units
 */
public class OrbitBehavior extends ViewPlatformAWTBehavior {
	public static final double DEFAULT_FOV = Math.PI / 3.15789d; // default if 57 degrees (about human FOV)
	public static final double DEFAULT_RADIUS = 2.41d;
	static final double MIN_RADIUS = 0.0000001d;
	static final double MAX_RADIUS = Double.POSITIVE_INFINITY;

	private static final double ORBIT_ANGLE_FACTOR = -0.01d;

	// Temporary place where all the entityTooltip state will be shared
	static MouseEvent tootipEvent = null;
	static OrbitBehavior tooltipBehavior = null;
	static boolean showtooltip = true;
	static EntityToolTip entityToolTip = null;

	// The enumerated mouse behavior modes
	static final int CHANGE_PAN = 2;
	static final int CHANGE_ROTATION = 4;
	static final int CHANGE_TRANSLATION = 8;
	static final int CHANGE_ZOOM_BOX = 64;
	static final int CHANGE_NODE = 128;

	static enum Plane { XY_PLANE, XZ_PLANE, YZ_PLANE };

	private final Sim3DWindow window;
	private final ModelView modelView;

	private final Vector3d orbitCenter;
	private final Vector3d orbitAngles;
	private double orbitRadius;
	private double fov;

	// used for calculations (only create once)
	private Vector3d universeDatumPoint = new Vector3d();

	// Zoom box parameters
	private int mouseX = 0;
	private int mouseY = 0;
	private Rectangle rectangle;

	// Do/undo parameters
	private Vector undoSteps = new Vector( 10, 1 ); // contains zoom steps
	private int undoStep = 0;                       // The position of the current zoom step in undoSteps
	private boolean windowMovedAndResized = false;  // true => window both resized and moved

	private static int mouseMode = OrbitBehavior.CHANGE_TRANSLATION;

	private static boolean positionMode = true;

	private static String currentCreationClass;

	private Vector3d dragEntityStartPosition = new Vector3d();

	// resize
	protected static DisplayEntity selectedEntity = null;
	private final Vector3d selectedStart = new Vector3d();

	// moving in z direction
	private int mouseXForZDragging; // x location needs to be fixed while moving in z direction
	private boolean zDragging = false;

	private static boolean resizeBounds = false;

	public static final int CORNER_BOTTOMLEFT = 1;
	public static final int CORNER_BOTTOMCENTER = 2;
	public static final int CORNER_BOTTOMRIGHT = 3;
	public static final int CORNER_MIDDLERIGHT = 4;
	public static final int CORNER_TOPRIGHT = 5;
	public static final int CORNER_TOPCENTER = 6;
	public static final int CORNER_TOPLEFT = 7;
	public static final int CORNER_MIDDLELEFT = 8;
	public static final int CORNER_ROTATE = 9;
	private Cursor rotation;

	public static int resizeType = 0;

	/**
	 * Creates a new OrbitBehavior
	 *
	 * @param c The Canvas3D to add the behavior to
	 * @param flags The option flags
	 */
	public OrbitBehavior(ModelView v, Sim3DWindow window) {
		super(v.getCanvas3D(), MOUSE_LISTENER | MOUSE_MOTION_LISTENER);
		modelView = v;
		this.window = window;
		setEnable( true );

		orbitCenter = new Vector3d();
		orbitAngles = new Vector3d();
		orbitRadius = DEFAULT_RADIUS;
		fov = DEFAULT_FOV;
		integrateTransforms();

		Toolkit tk = Toolkit.getDefaultToolkit();

		// The middle of the image is the hot spot for rotating cursor
		Dimension dim = tk.getBestCursorSize(32, 32);
		dim.height /= 2;
		dim.width /= 2;

		// Create rotating cursor from image
		Image cursorImage = tk.getImage(
				GUIFrame.class.getResource("/resources/images/rotating.png"));
		try {
			rotation = tk.createCustomCursor(
				cursorImage, new Point(dim.width,dim.height), "Rotating");
		}

		// use the default cursor, do not throw an exception
		catch(Exception exc){
			rotation = null;
		}
	}

	protected synchronized void processAWTEvents( final java.awt.AWTEvent[] events ) {
		motion = false;
		for( int i = 0; i < events.length; i++ ) {
			if( events[i] instanceof MouseEvent ) {
				MouseEvent evt = (MouseEvent)events[i];
				// Check if the next event is the same as this event to suppress
				// a large class of duplicates (dragging/moving)
				if (i + 1 < events.length && events[i + 1] instanceof MouseEvent) {
					MouseEvent nextevt = (MouseEvent)events[i + 1];
					// events have the same ID
					if (evt.getID() == nextevt.getID()) {
						if (evt.getID() == MouseEvent.MOUSE_DRAGGED)
							continue;
						if (evt.getID() == MouseEvent.MOUSE_MOVED)
							continue;
					}
				}

				processMouseEvent(evt);
			}
		}
		GraphicsUpdateBehavior.forceUpdate = true;
	}

	public void destroy() {
		canvases = null;
	}

	static void enableTooltip(boolean enable) {
		if (!enable)
			OrbitBehavior.killToolTip();

		OrbitBehavior.showtooltip = enable;
	}

	static void killToolTip() {
		if( entityToolTip != null ) {
			entityToolTip.abort();
			entityToolTip = null;
		}
	}

	public static void selectEntity(Entity ent) {
		if(ent == selectedEntity)
			return;

		// Unselect previous entity
		resizeObjectDeselected();

		if (ent instanceof DisplayEntity) {
			selectedEntity = (DisplayEntity)ent;
			resizeBounds = true;
			selectedEntity.setResizeBounds( true );
		}
		GraphicsUpdateBehavior.forceUpdate = true;
	}

	protected void processMouseEvent( final MouseEvent evt ) {
		if (evt.getID() == MouseEvent.MOUSE_WHEEL) {
			orbitRadius *= Math.pow(0.9d, -((MouseWheelEvent)evt).getWheelRotation());
			// Cap the radius to a minimum value
			orbitRadius = Math.max(orbitRadius, MIN_RADIUS);
<commit_msg>JS3D: switch mouse pointer back to arrow for the right-click menu<commit_after>/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2003-2011 Ausenco Engineering Canada Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
package com.sandwell.JavaSimulation3D;

import com.sandwell.JavaSimulation.Entity;
import com.sandwell.JavaSimulation.Vector;
import com.sun.j3d.utils.behaviors.vp.ViewPlatformAWTBehavior;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;

import com.sandwell.JavaSimulation3D.util.Rectangle;
import com.sandwell.JavaSimulation3D.util.Shape;

import javax.media.j3d.Transform3D;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

/**
 * Provides mouse events processing of moving the viewer within a J3D environment.<br>
 * Provides this functionality by providing the viewer location, the point to look at and the up vector.<br>
 * Provides changes of the viewer of: zoom, pan, translate, orbit and field of view angle<br>
 * Provides the position of the locator in model units
 */
public class OrbitBehavior extends ViewPlatformAWTBehavior {
	public static final double DEFAULT_FOV = Math.PI / 3.15789d; // default if 57 degrees (about human FOV)
	public static final double DEFAULT_RADIUS = 2.41d;
	static final double MIN_RADIUS = 0.0000001d;
	static final double MAX_RADIUS = Double.POSITIVE_INFINITY;

	private static final double ORBIT_ANGLE_FACTOR = -0.01d;

	// Temporary place where all the entityTooltip state will be shared
	static MouseEvent tootipEvent = null;
	static OrbitBehavior tooltipBehavior = null;
	static boolean showtooltip = true;
	static EntityToolTip entityToolTip = null;

	// The enumerated mouse behavior modes
	static final int CHANGE_PAN = 2;
	static final int CHANGE_ROTATION = 4;
	static final int CHANGE_TRANSLATION = 8;
	static final int CHANGE_ZOOM_BOX = 64;
	static final int CHANGE_NODE = 128;

	static enum Plane { XY_PLANE, XZ_PLANE, YZ_PLANE };

	private final Sim3DWindow window;
	private final ModelView modelView;

	private final Vector3d orbitCenter;
	private final Vector3d orbitAngles;
	private double orbitRadius;
	private double fov;

	// used for calculations (only create once)
	private Vector3d universeDatumPoint = new Vector3d();

	// Zoom box parameters
	private int mouseX = 0;
	private int mouseY = 0;
	private Rectangle rectangle;

	// Do/undo parameters
	private Vector undoSteps = new Vector( 10, 1 ); // contains zoom steps
	private int undoStep = 0;                       // The position of the current zoom step in undoSteps
	private boolean windowMovedAndResized = false;  // true => window both resized and moved

	private static int mouseMode = OrbitBehavior.CHANGE_TRANSLATION;

	private static boolean positionMode = true;

	private static String currentCreationClass;

	private Vector3d dragEntityStartPosition = new Vector3d();

	// resize
	protected static DisplayEntity selectedEntity = null;
	private final Vector3d selectedStart = new Vector3d();

	// moving in z direction
	private int mouseXForZDragging; // x location needs to be fixed while moving in z direction
	private boolean zDragging = false;

	private static boolean resizeBounds = false;

	public static final int CORNER_BOTTOMLEFT = 1;
	public static final int CORNER_BOTTOMCENTER = 2;
	public static final int CORNER_BOTTOMRIGHT = 3;
	public static final int CORNER_MIDDLERIGHT = 4;
	public static final int CORNER_TOPRIGHT = 5;
	public static final int CORNER_TOPCENTER = 6;
	public static final int CORNER_TOPLEFT = 7;
	public static final int CORNER_MIDDLELEFT = 8;
	public static final int CORNER_ROTATE = 9;
	private Cursor rotation;

	public static int resizeType = 0;

	/**
	 * Creates a new OrbitBehavior
	 *
	 * @param c The Canvas3D to add the behavior to
	 * @param flags The option flags
	 */
	public OrbitBehavior(ModelView v, Sim3DWindow window) {
		super(v.getCanvas3D(), MOUSE_LISTENER | MOUSE_MOTION_LISTENER);
		modelView = v;
		this.window = window;
		setEnable( true );

		orbitCenter = new Vector3d();
		orbitAngles = new Vector3d();
		orbitRadius = DEFAULT_RADIUS;
		fov = DEFAULT_FOV;
		integrateTransforms();

		Toolkit tk = Toolkit.getDefaultToolkit();

		// The middle of the image is the hot spot for rotating cursor
		Dimension dim = tk.getBestCursorSize(32, 32);
		dim.height /= 2;
		dim.width /= 2;

		// Create rotating cursor from image
		Image cursorImage = tk.getImage(
				GUIFrame.class.getResource("/resources/images/rotating.png"));
		try {
			rotation = tk.createCustomCursor(
				cursorImage, new Point(dim.width,dim.height), "Rotating");
		}

		// use the default cursor, do not throw an exception
		catch(Exception exc){
			rotation = null;
		}
	}

	protected synchronized void processAWTEvents( final java.awt.AWTEvent[] events ) {
		motion = false;
		for( int i = 0; i < events.length; i++ ) {
			if( events[i] instanceof MouseEvent ) {
				MouseEvent evt = (MouseEvent)events[i];
				// Check if the next event is the same as this event to suppress
				// a large class of duplicates (dragging/moving)
				if (i + 1 < events.length && events[i + 1] instanceof MouseEvent) {
					MouseEvent nextevt = (MouseEvent)events[i + 1];
					// events have the same ID
					if (evt.getID() == nextevt.getID()) {
						if (evt.getID() == MouseEvent.MOUSE_DRAGGED)
							continue;
						if (evt.getID() == MouseEvent.MOUSE_MOVED)
							continue;
					}
				}

				processMouseEvent(evt);
			}
		}
		GraphicsUpdateBehavior.forceUpdate = true;
	}

	public void destroy() {
		canvases = null;
	}

	static void enableTooltip(boolean enable) {
		if (!enable)
			OrbitBehavior.killToolTip();

		OrbitBehavior.showtooltip = enable;
	}

	static void killToolTip() {
		if( entityToolTip != null ) {
			entityToolTip.abort();
			entityToolTip = null;
		}
	}

	public static void selectEntity(Entity ent) {
		if(ent == selectedEntity)
			return;

		// Unselect previous entity
		resizeObjectDeselected();

		if (ent instanceof DisplayEntity) {
			selectedEntity = (DisplayEntity)ent;
			resizeBounds = true;
			selectedEntity.setResizeBounds( true );
		}
		GraphicsUpdateBehavior.forceUpdate = true;
	}

	protected void processMouseEvent( final MouseEvent evt ) {

		// no processing if the right click menu is visible
		if(window.getPicker().getMenu().isVisible()) {

			// Back to default mouse icon
			edgeSelected(null, null, 0.0d);
			return;
		}

		if (evt.getID() == MouseEvent.MOUSE_WHEEL) {
			orbitRadius *= Math.pow(0.9d, -((MouseWheelEvent)evt).getWheelRotation());
			// Cap the radius to a minimum value
			orbitRadius = Math.max(orbitRadius, MIN_RADIUS);

{'fraction_non_alphanumeric': 0.08205200878622547, 'fraction_numerical': 0.012966768227875009, 'mean_word_length': 3.981997882103777, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7313335', 'n_tokens_mistral': 4772, 'n_tokens_neox': 4244, 'n_words': 1465}