/* * LiveCursor * * Copyright (c) 2001 * University of Maryland * All Rights Reserved. * * Benjamin B. Bederson * May 2001 * * This code creates a cursor that points in the direction of motion * instead of always pointing in the same direction. This has the * advantage of bringing a little life to the screen while at the same * time providing some potential interaction benefits: * - The user has control over the direction of the cursor which * can be useful when showing something to someone else and you * want to be clear about what you are pointing to. * - The cursor generally won't cover the thing you are getting close * to since the tail of the cursor is away from the thing you are * moving towards. * - This works with left and right-handed users equally well. Traditional * cursors are designed for right-handed users. * * LiveCursor uses the Jazz library * http://www.cs.umd.edu/hcil/jazz */ /* The LiveCursor software is subject to the Mozilla Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/. Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is LiveCursor v1.0 The Initial Developer of the Original Code is Ben Bederson. All of the code is Copyright (C) 2001 University of Maryland. All Rights Reserved. INTELLECTUAL PROPERTY NOTES In this directory tree, we are releasing Jazz to the interested development community as Open Source code. LiveCursor is copyrighted by the University of Maryland, and is available for all users, in accordance with the Open Source model. It is available as free software for license according to the Mozilla Public License. If you re-distribute this code, with or without modifications, then one of the provisions of the Mozilla Public License, under which you are using it, is to include the following statement: ----------------------------------------------------------------------------- "The contents of this directory tree are subject to the Mozilla Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/. Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is LiveCursor v1.0 The Initial Developer of the Original Code is Benjamin B. Bederson. All of the code is Copyright (C) 2001 University of Maryland. All Rights Reserved. -------------------------------------------------------------------------------- */ import java.net.*; import java.awt.*; import java.awt.geom.*; import java.awt.event.*; import javax.swing.*; import edu.umd.cs.jazz.*; import edu.umd.cs.jazz.util.*; import edu.umd.cs.jazz.event.*; import edu.umd.cs.jazz.component.*; public class LiveCursor implements MouseMotionListener { ZPolygon cursor = null; ZVisualLeaf cursorLeaf = null; Point2D p1 = new Point2D.Double(0, 0); double prevTheta = 0; ZCanvas canvas; public LiveCursor(ZCanvas canvas) { this.canvas = canvas; createCursor(); canvas.getPanEventHandler().setActive(false); ZEventHandler selectionHandler; selectionHandler = new ZCompositeSelectionHandler(canvas.getCameraNode(), canvas, canvas.getLayer()); selectionHandler.setActive(true); canvas.addMouseMotionListener(this); } void createCursor() { double[] xp = {0, 6, 1, 1, -1, -1, -6, 0}; double[] yp = {0, 14, 12, 20, 20, 12, 14, 0}; cursor = new ZPolygon(xp, yp); cursor.setPenPaint(Color.black); cursor.setFillPaint(Color.white); cursorLeaf = new ZVisualLeaf(cursor); cursorLeaf.setPickable(false); cursorLeaf.setFindable(false); ZLayerGroup layer = new ZLayerGroup(); canvas.getRoot().addChild(layer); layer.addChild(cursorLeaf); canvas.getCamera().addLayer(layer); // Turn off cursor Point hotspot = new Point(0, 0); ClassLoader classLoader = this.getClass().getClassLoader(); URL resource = classLoader.getResource("empty-cursor.gif"); ImageIcon imageIcon = new ImageIcon(resource); java.awt.Image cursorImage = imageIcon.getImage(); Cursor cursor = canvas.getToolkit().createCustomCursor(cursorImage, hotspot, "none"); canvas.setCursor(cursor); } public void mouseDragged(MouseEvent e) { mouseMoved(e); } public void mouseMoved(MouseEvent e) { ZTransformGroup tg = cursorLeaf.editor().getTransformGroup(); AffineTransform at = new AffineTransform(); Point2D p2 = new Point2D.Double(e.getX(), e.getY()); canvas.screenToGlobal(p2); double dx = p2.getX() - p1.getX(); double dy = p2.getY() - p1.getY(); double t = Math.atan2(dy, dx) + (3.1415 / 2); if (t < 0) { t += 2 * 3.1415; } if (Math.abs(t - prevTheta) > 3.1415) { if (t > 3.1415) { t -= 2*3.1415; } else { t += 2*3.1415; } } double theta; theta = prevTheta + 0.1 * (t - prevTheta); if (theta < 0) { theta += 2*3.1415; } if (theta > 2*3.1415) { theta -= 2*3.1415; } // theta = -20 * 3.1415 / 180; at.translate(p2.getX(), p2.getY()); at.rotate(theta); tg.setTransform(at); p1 = p2; prevTheta = theta; } static public void LiveCursorTest() { ZCanvas canvas; int width = 800; int height = 800; JFrame frame; frame = new JFrame("LiveCursor Test"); frame.setBounds(600, 100, width, height); // Give this window some dimensions canvas = new ZCanvas(); frame.getContentPane().add(canvas); frame.setVisible(true); // Make this window visible // Watch for the user closing the window so we can exit gracefully frame.addWindowListener (new WindowAdapter () { public void windowClosing (WindowEvent e) { System.exit(0); } }); new LiveCursor(canvas); // Create some stuff to see int numRects = 10; ZRectangle rect; ZVisualLeaf leaf; Color color; double x1, y1, x2, y2; for (int i=0; i