summaryrefslogtreecommitdiffstats
path: root/src/VirtualInputDevice/WheelControls.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/VirtualInputDevice/WheelControls.java')
-rw-r--r--src/VirtualInputDevice/WheelControls.java399
1 files changed, 399 insertions, 0 deletions
diff --git a/src/VirtualInputDevice/WheelControls.java b/src/VirtualInputDevice/WheelControls.java
new file mode 100644
index 0000000..f4ac4d8
--- /dev/null
+++ b/src/VirtualInputDevice/WheelControls.java
@@ -0,0 +1,399 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.event.*;
+
+public class WheelControls extends Canvas implements RotationControls, MouseMotionListener, MouseListener {
+
+ private final static int NONE=0;
+ private final static int SLIDE_Y=1;
+ private final static int SLIDE_X=2;
+ private final static int SLIDE_Z=3;
+
+ private int mode = NONE;
+
+ private Dimension size;
+ private int thickness;
+ private int diameter;
+ private int space;
+ private int pipSize;
+ private int pipOffset; // Amount pip is below wheel
+ private int margin; // Margin between edge of Canvas and
+ // controls
+
+ private Polygon yPip;
+ private Rectangle yBackClip;
+
+ private Polygon xPip;
+ private Rectangle xBackClip;
+
+ private Polygon zPip;
+
+ private Rectangle yArea;
+ private Rectangle xArea;
+ private Rectangle zArea;
+
+ private Point oldMousePos = new Point();
+
+ float yAngle = 0.0f;
+ float xAngle = 0.0f;
+ float zAngle = 0.0f;
+
+ float yOrigAngle;
+ float xOrigAngle;
+ float zOrigAngle;
+
+ float angleStep = (float)Math.PI/30.0f;
+
+ public WheelControls() {
+ this(0.0f, 0.0f, 0.0f);
+ }
+
+ public WheelControls( float rotX, float rotY, float rotZ ) {
+ size = new Dimension( 200, 200 );
+
+ xAngle = constrainAngle(rotX);
+ yAngle = constrainAngle(rotY);
+ zAngle = constrainAngle(rotZ);
+
+ yOrigAngle = yAngle;
+ xOrigAngle = xAngle;
+ zOrigAngle = zAngle;
+
+ setSizes();
+
+ yPip = new Polygon();
+ yPip.addPoint( 0, 0 );
+ yPip.addPoint( -pipSize/2, pipSize );
+ yPip.addPoint( pipSize/2, pipSize );
+
+ xPip = new Polygon();
+ xPip.addPoint(0,0);
+ xPip.addPoint( pipSize, -pipSize/2 );
+ xPip.addPoint( pipSize, pipSize/2 );
+
+ zPip = new Polygon();
+ zPip.addPoint( diameter/2, pipOffset );
+ zPip.addPoint( diameter/2-pipSize/2, pipOffset-pipSize );
+ zPip.addPoint( diameter/2+pipSize/2, pipOffset-pipSize );
+
+ addMouseListener( this );
+ addMouseMotionListener( this );
+ }
+
+ private void setSizes() {
+ margin = 10;
+ int width = size.width - margin*2;
+ thickness = width * 7 / 100;
+ diameter = width * 70 / 100;
+ space = width * 10 / 100;
+ pipSize = width * 7 / 100;
+
+ pipOffset = thickness/2;
+
+ }
+
+ public void paint( Graphics g ) {
+ Graphics2D g2 = (Graphics2D)g;
+
+ g.drawOval( margin,margin, diameter, diameter );
+ zArea = new Rectangle( margin, margin, diameter, diameter );
+ drawZPip( g2, zAngle );
+
+ g.drawRect( margin, margin+diameter+space,
+ diameter, thickness ); // Y Wheel
+ yArea = new Rectangle( margin, margin+diameter+space, margin+diameter,
+ thickness+pipOffset );
+ yBackClip = new Rectangle( margin-thickness,
+ margin+diameter+space+thickness,
+ margin+diameter+thickness*2, thickness );
+ drawYPip( g2, yAngle );
+
+ g.drawRect( margin+diameter+space, margin,
+ thickness, diameter ); // X Wheel
+ xArea = new Rectangle( margin+diameter+space, margin,
+ thickness+pipOffset, margin+diameter );
+ xBackClip = new Rectangle( margin+diameter+space+thickness,
+ margin-thickness,
+ thickness, margin+diameter+thickness*2 );
+ drawXPip( g2, xAngle );
+
+
+ }
+
+ public float getXAngle() {
+ return xAngle;
+ }
+
+ public float getYAngle() {
+ return yAngle;
+ }
+
+ public float getZAngle() {
+ return zAngle;
+ }
+
+
+ public void reset() {
+ // Overwrite the old pip
+ drawYPip( (Graphics2D)(this.getGraphics()),
+ yAngle );
+ yAngle = yOrigAngle;
+ // Draw the new Pip
+ drawYPip( (Graphics2D)(this.getGraphics()),
+ yAngle );
+
+ // Overwrite the old pip
+ drawXPip( (Graphics2D)(this.getGraphics()),
+ xAngle );
+ xAngle = xOrigAngle;
+ // Draw the new Pip
+ drawXPip( (Graphics2D)(this.getGraphics()),
+ xAngle );
+
+ drawZPip( (Graphics2D)(this.getGraphics()),
+ zAngle );
+
+ zAngle = zOrigAngle;
+
+ drawZPip( (Graphics2D)(this.getGraphics()),
+ zAngle );
+ oldMousePos.setLocation(0,0);
+ }
+
+
+ private void drawXPip( Graphics2D g2, float angle ) {
+ AffineTransform trans = new AffineTransform();
+ int y;
+ int xOrig = margin+diameter+space;
+ int yOrig = margin;
+ Color origColor = g2.getColor();
+
+ if (angle <= Math.PI) {
+ y = yOrig + diameter - (int)((Math.abs( angle-Math.PI/2 )/(Math.PI/2)) * diameter/2);
+ } else
+ y = yOrig + (int)((Math.abs( (angle-Math.PI*1.5) )/(Math.PI/2)) * diameter/2);
+
+ if (angle<Math.PI/2 || angle > Math.PI*1.5)
+ g2.setColor( Color.red ); // Infront of wheel
+ else {
+ g2.setColor( Color.black ); // Behind Wheel
+ g2.setClip( xBackClip );
+ }
+
+ g2.setXORMode( getBackground() );
+ trans.setToTranslation( xOrig+pipOffset, y );
+ g2.setTransform( trans );
+ g2.fillPolygon( xPip );
+
+ // Reset graphics context
+ trans.setToIdentity();
+ g2.setTransform( trans );
+ g2.setColor(origColor);
+ g2.setPaintMode();
+ }
+
+ private void drawYPip( Graphics2D g2, float angle ) {
+ AffineTransform trans = new AffineTransform();
+ int x;
+ int xOrig = margin;
+ int yOrig = margin+diameter+space;
+ Color origColor = g2.getColor();
+
+ if (angle <= Math.PI) {
+ x = xOrig + diameter - (int)((Math.abs( angle-Math.PI/2 )/(Math.PI/2)) * diameter/2);
+ } else
+ x = xOrig + (int)((Math.abs( (angle-Math.PI*1.5) )/(Math.PI/2)) * diameter/2);
+
+ if (angle<Math.PI/2 || angle > Math.PI*1.5)
+ g2.setColor( Color.red ); // Infront on wheel
+ else {
+ g2.setColor( Color.black ); // Behind Wheel
+ g2.setClip( yBackClip );
+ }
+
+ g2.setXORMode( getBackground() );
+ trans.setToTranslation( x, yOrig+pipOffset );
+ g2.setTransform( trans );
+ g2.fillPolygon( yPip );
+
+ // Reset graphics context
+ trans.setToIdentity();
+ g2.setTransform( trans );
+ g2.setColor(origColor);
+ g2.setPaintMode();
+ }
+
+ private void drawZPip( Graphics2D g2, float zAngle ) {
+ AffineTransform trans = new AffineTransform();
+ Color origColor = g2.getColor();
+
+ trans.translate( margin, margin );
+ trans.rotate(zAngle, diameter/2, diameter/2 );
+
+ g2.setXORMode( getBackground() );
+ g2.setTransform(trans);
+ g2.setColor( Color.red );
+ g2.fillPolygon( zPip );
+
+ // Reset graphics context
+ trans.setToIdentity();
+ g2.setTransform( trans );
+ g2.setColor( origColor );
+ g2.setPaintMode();
+ }
+
+ public Dimension getPreferredSize() {
+ return size;
+ }
+
+ public void setSize( Dimension d ) {
+ // Set size to smallest dimension
+ if (d.width<d.height)
+ size.width = size.height = d.width;
+ else
+ size.width = size.height = d.height;
+ setSizes();
+ }
+
+ public void mouseClicked( MouseEvent e ) {
+ }
+
+ public void mouseEntered( MouseEvent e ) {
+ }
+
+ public void mouseExited( MouseEvent e ) {
+ }
+
+ public void mousePressed( MouseEvent e ) {
+ if ( yArea.contains( e.getPoint() )) {
+ mode = SLIDE_Y;
+ oldMousePos = e.getPoint();
+ } else if (xArea.contains( e.getPoint() )) {
+ mode = SLIDE_X;
+ oldMousePos = e.getPoint();
+ } else if (zArea.contains( e.getPoint() )) {
+ mode = SLIDE_Z;
+ oldMousePos = e.getPoint();
+ }
+ }
+
+ public void mouseReleased( MouseEvent e ) {
+ mode = NONE;
+ }
+
+ public void mouseDragged( MouseEvent e ) {
+ Point pos = e.getPoint();
+
+ int diffX = pos.x - oldMousePos.x;
+ int diffY = pos.y - oldMousePos.y;
+
+ switch(mode) {
+ case NONE:
+ break;
+ case SLIDE_Y:
+ // Overwrite the old pip
+ drawYPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ yAngle );
+ if (diffX<0)
+ yAngle -= angleStep;
+ else if (diffX>0)
+ yAngle += angleStep;
+
+ yAngle = constrainAngle(yAngle);
+
+ // Draw the new Pip
+ drawYPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ yAngle );
+ oldMousePos = pos;
+ break;
+ case SLIDE_X:
+ // Overwrite the old pip
+ drawXPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ xAngle );
+ if (diffY<0)
+ xAngle -= angleStep;
+ else if (diffY>0)
+ xAngle += angleStep;
+
+ xAngle = constrainAngle(xAngle);
+
+ // Draw the new Pip
+ drawXPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ xAngle );
+ oldMousePos = pos;
+ break;
+ case SLIDE_Z:
+ drawZPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ zAngle );
+
+ if (diffX<0)
+ zAngle -= angleStep;
+ else if (diffX>0)
+ zAngle += angleStep;
+
+ zAngle = constrainAngle( zAngle );
+ drawZPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ zAngle );
+ oldMousePos = pos;
+ break;
+ default:
+ throw( new RuntimeException("Internal Error"));
+ }
+ }
+
+ public void mouseMoved( MouseEvent e ) {
+ }
+
+ /**
+ * Constrain angle to be 0<angle<2PI
+ */
+ private float constrainAngle( float angle ) {
+ if ( angle > (float)Math.PI*2 ) return angle-(float)Math.PI*2;
+ if ( angle < 0.0f) return angle+(float)Math.PI*2;
+ return angle;
+ }
+}