diff --git a/build.bat b/build.bat deleted file mode 100644 index 26f1cc3..0000000 --- a/build.bat +++ /dev/null @@ -1,27 +0,0 @@ -@echo off - -echo Piccolo Build System -echo ------------------- - -if "%JAVA_HOME%" == "" goto error - -set LOCALCLASSPATH=%JAVA_HOME%\lib\tools.jar;.\lib\ant.jar;.\lib\junit.jar;%CLASSPATH% -set ANT_HOME=./lib - -echo Building with classpath %LOCALCLASSPATH% - -echo Starting Ant... - -"%JAVA_HOME%\bin\java.exe" -Dant.home="%ANT_HOME%" -classpath "%LOCALCLASSPATH%" org.apache.tools.ant.Main %1 %2 %3 %4 %5 - -goto end - -:error - -echo "ERROR: JAVA_HOME not found in your environment." -echo "Please, set the JAVA_HOME variable in your environment to match the" -echo "location of the Java Virtual Machine you want to use." - -:end - -set LOCALCLASSPATH= \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100755 index 28bd31f..0000000 --- a/build.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -echo -echo "Piccolo Build System" -echo "-------------------" -echo - -if [ "$JAVA_HOME" = "" ] ; then - echo "ERROR: JAVA_HOME not found in your environment." - echo - echo "Please, set the JAVA_HOME variable in your environment to match the" - echo "location of the Java Virtual Machine you want to use." - exit 1 -fi - -LOCALCLASSPATH=$JAVA_HOME/lib/tools.jar:./lib/ant.jar:./lib/junit.jar -ANT_HOME=./lib - -echo Building with classpath $CLASSPATH:$LOCALCLASSPATH -echo - -echo Starting Ant... -echo - -"$JAVA_HOME/bin/java" -Dant.home=$ANT_HOME -classpath $LOCALCLASSPATH:$CLASSPATH org.apache.tools.ant.Main $* diff --git a/build.xml b/build.xml deleted file mode 100644 index b865de8..0000000 --- a/build.xml +++ /dev/null @@ -1,468 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/edu/umd/cs/piccolo/examples/ActivityExample.java b/examples/edu/umd/cs/piccolo/examples/ActivityExample.java deleted file mode 100644 index 6fcbbc2..0000000 --- a/examples/edu/umd/cs/piccolo/examples/ActivityExample.java +++ /dev/null @@ -1,84 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.activities.PActivity; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how create and schedule activities. - */ -public class ActivityExample extends PFrame { - - public ActivityExample() { - this(null); - } - - public ActivityExample(PCanvas aCanvas) { - super("ActivityExample", false, aCanvas); - } - - public void initialize() { - long currentTime = System.currentTimeMillis(); - - // Create a new node that we will apply different activities to, and - // place that node at location 200, 200. - final PNode aNode = PPath.createRectangle(0, 0, 100, 80); - PLayer layer = getCanvas().getLayer(); - layer.addChild(aNode); - aNode.setOffset(200, 200); - - // Create a new custom "flash" activity. This activity will start running in - // five seconds, and while it runs it will flash aNode's paint between - // red and green every half second. - PActivity flash = new PActivity(-1, 500, currentTime + 5000) { - boolean fRed = true; - - protected void activityStep(long elapsedTime) { - super.activityStep(elapsedTime); - - if (fRed) { - aNode.setPaint(Color.red); - } else { - aNode.setPaint(Color.green); - } - - fRed = !fRed; - } - }; - - // An activity will not run unless it is scheduled with the root. Once - // it has been scheduled it will be given a chance to run during the next - // PRoot.processInputs() call. - getCanvas().getRoot().addActivity(flash); - - // Use the PNode animate methods to create three activities that animate - // the node's position. Since our node already descends from the root node the - // animate methods will automatically schedule these activities for us. - PActivity a1 = aNode.animateToPositionScaleRotation(0, 0, 0.5, 0, 5000); - PActivity a2 = aNode.animateToPositionScaleRotation(100, 0, 1.5, Math.toRadians(110), 5000); - PActivity a3 = aNode.animateToPositionScaleRotation(200, 100, 1, 0, 5000); - PActivity a4 = aNode.animateToTransparency(0.25f, 3000); - - // the animate activities will start immediately (in the next call to PRoot.processInputs) - // by default. Here we set their start times (in PRoot global time) so that they start - // when the previous one has finished. - a1.setStartTime(currentTime); - - a2.startAfter(a1); - a3.startAfter(a2); - a4.startAfter(a3); - - // or the previous three lines could be replaced with these lines for the same effect. - //a2.setStartTime(currentTime + 5000); - //a3.setStartTime(currentTime + 10000); - //a4.setStartTime(currentTime + 15000); - } - - public static void main(String[] args) { - new ActivityExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/AngleNodeExample.java b/examples/edu/umd/cs/piccolo/examples/AngleNodeExample.java deleted file mode 100644 index 7524a94..0000000 --- a/examples/edu/umd/cs/piccolo/examples/AngleNodeExample.java +++ /dev/null @@ -1,120 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Stroke; -import java.awt.geom.GeneralPath; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PHandle; -import edu.umd.cs.piccolox.util.PLocator; - -/** - * This shows how to create a simple node that has two handles and can be used - * for specifying angles. The nodes UI desing isn't very exciting, but the - * example shows one way to create a custom node with custom handles. - */ -public class AngleNodeExample extends PFrame { - - public AngleNodeExample() { - this(null); - } - - public AngleNodeExample(PCanvas aCanvas) { - super("AngleNodeExample", false, aCanvas); - } - - public void initialize() { - PCanvas c = getCanvas(); - PLayer l = c.getLayer(); - l.addChild(new AngleNode()); - } - - public static void main(String[] args) { - new AngleNodeExample(); - } - - // the angle node class - public static class AngleNode extends PNode { - protected Point2D.Double pointOne; - protected Point2D.Double pointTwo; - protected Stroke stroke; - - public AngleNode() { - pointOne = new Point2D.Double(100, 0); - pointTwo = new Point2D.Double(0, 100); - stroke = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); - setPaint(Color.BLACK); - updateBounds(); - addHandles(); - } - - public void addHandles() { - // point one - PLocator l = new PLocator() { - public double locateX() { return pointOne.getX(); } - public double locateY() { return pointOne.getY(); } - }; - PHandle h = new PHandle(l) { - public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { - localToParent(aLocalDimension); - pointOne.setLocation(pointOne.getX() + aLocalDimension.getWidth(), - pointOne.getY() + aLocalDimension.getHeight()); - updateBounds(); - relocateHandle(); - } - }; - addChild(h); - - // point two - l = new PLocator() { - public double locateX() { return pointTwo.getX(); } - public double locateY() { return pointTwo.getY(); } - }; - h = new PHandle(l) { - public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { - localToParent(aLocalDimension); - pointTwo.setLocation(pointTwo.getX() + aLocalDimension.getWidth(), - pointTwo.getY() + aLocalDimension.getHeight()); - updateBounds(); - relocateHandle(); - } - }; - addChild(h); - } - - protected void paint(PPaintContext paintContext) { - Graphics2D g2 = paintContext.getGraphics(); - g2.setStroke(stroke); - g2.setPaint(getPaint()); - g2.draw(getAnglePath()); - } - - protected void updateBounds() { - GeneralPath p = getAnglePath(); - Rectangle2D b = stroke.createStrokedShape(p).getBounds2D(); - super.setBounds(b.getX(), b.getY(), b.getWidth(), b.getHeight()); - } - - public GeneralPath getAnglePath() { - GeneralPath p = new GeneralPath(); - p.moveTo((float)pointOne.getX(), (float)pointOne.getY()); - p.lineTo(0, 0); - p.lineTo((float)pointTwo.getX(), (float)pointTwo.getY()); - return p; - } - - public boolean setBounds(double x, double y, double width, double height) { - return false; // bounds can be set externally - } - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/BirdsEyeViewExample.java b/examples/edu/umd/cs/piccolo/examples/BirdsEyeViewExample.java deleted file mode 100644 index bc54c08..0000000 --- a/examples/edu/umd/cs/piccolo/examples/BirdsEyeViewExample.java +++ /dev/null @@ -1,432 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import javax.swing.JDialog; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PImage; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.nodes.PText; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.nodes.P3DRect; - -/** - * This example, contributed by Rowan Christmas, shows how to - * create a birds-eye view window. - */ -public class BirdsEyeViewExample extends PFrame { - - boolean fIsPressed = false; - - public BirdsEyeViewExample() { - this(null); - } - - public BirdsEyeViewExample(PCanvas aCanvas) { - super("BirdsEyeViewExample", false, aCanvas); - } - - public void initialize() { - - nodeDemo(); - createNodeUsingExistingClasses(); - subclassExistingClasses(); - composeOtherNodes(); - createCustomNode(); - - // Last of all lets remove the default pan event handler, and add a - // drag event handler instead. This way you will be able to drag the - // nodes around with the mouse. - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(new PDragEventHandler()); - - // this will create the actual BirdsEyeView and put it in a JDialog - BirdsEyeView bev = new BirdsEyeView(); - bev.connect(getCanvas(), new PLayer[]{getCanvas().getLayer()}); - JDialog bird = new JDialog(); - bird.getContentPane().add(bev); - bird.pack(); - bird.setSize(150, 150); - bird.setVisible(true); - - } - - // This method demonstrates the kinds of things that can be done with any - // node. - public void nodeDemo() { - PLayer layer = getCanvas().getLayer(); - PNode aNode = PPath.createRectangle(0, 0, 100, 80); - - // A node needs to be a descendent of the root to be displayed on the - // screen. - layer.addChild(aNode); - - // The default color for a node is blue, but you can change that with - // the setPaint method. - aNode.setPaint(Color.red); - - // A node can have children nodes added to it. - aNode.addChild(PPath.createRectangle(0, 0, 100, 80)); - - // The base bounds of a node is easy to change. Note that changing the - // base - // bounds of a node will not change it's children. - aNode.setBounds(-10, -10, 200, 110); - - // Each node has a transform that can be used to transform the node, and - // all its children on the screen. - aNode.translate(100, 100); - aNode.scale(1.5); - aNode.rotate(45); - - // The transparency of any node can be set, this transparency will be - // applied to any of the nodes children as well. - aNode.setTransparency(0.75f); - - // Its easy to copy nodes. - PNode aCopy = (PNode) aNode.clone(); - - // Make is so that the copies children are not pickable. For this - // example - // that means you will not be able to grab the child and remove it from - // its parent. - aNode.setChildrenPickable(false); - - // Change the look of the copy - aNode.setPaint(Color.GREEN); - aNode.setTransparency(1.0f); - - // Let's add the copy to the root, and translate it so that it does not - // cover the original node. - layer.addChild(aCopy); - aCopy.setOffset(0, 0); - aCopy.rotate(-45); - } - - // So far we have just been using PNode, but of course PNode has many - // subclasses that you can try out to. - public void createNodeUsingExistingClasses() { - PLayer layer = getCanvas().getLayer(); - layer.addChild(PPath.createEllipse(0, 0, 100, 100)); - layer.addChild(PPath.createRectangle(0, 100, 100, 100)); - layer.addChild(new PText("Hello World")); - - // Here we create an image node that displays a thumbnail - // image of the root node. Note that you can easily get a thumbnail - // of any node by using PNode.toImage(). - layer.addChild(new PImage(layer.toImage(300, 300, Color.YELLOW))); - } - - // Another way to create nodes is to customize other nodes that already - // exist. Here we create an ellipse, except when you press the mouse on - // this ellipse it turns into a square, when you release the mouse it - // goes back to being an ellipse. - public void subclassExistingClasses() { - final PNode n = new PPath(new Ellipse2D.Float(0, 0, 100, 80)) { - - public void paint(PPaintContext aPaintContext) { - if (fIsPressed) { - // if mouse is pressed draw self as a square. - Graphics2D g2 = aPaintContext.getGraphics(); - g2.setPaint(getPaint()); - g2.fill(getBoundsReference()); - } else { - // if mouse is not pressed draw self normally. - super.paint(aPaintContext); - } - } - }; - - n.addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent aEvent) { - super.mousePressed(aEvent); - fIsPressed = true; - n.invalidatePaint(); // this tells the framework that the node - // needs to be redisplayed. - } - - public void mouseReleased(PInputEvent aEvent) { - super.mousePressed(aEvent); - fIsPressed = false; - n.invalidatePaint(); // this tells the framework that the node - // needs to be redisplayed. - } - }); - - n.setPaint(Color.ORANGE); - getCanvas().getLayer().addChild(n); - } - - // Here a new "face" node is created. But instead of drawing the face - // directly - // using Graphics2D we compose the face from other nodes. - public void composeOtherNodes() { - PNode myCompositeFace = PPath.createRectangle(0, 0, 100, 80); - - // create parts for the face. - PNode eye1 = PPath.createEllipse(0, 0, 20, 20); - eye1.setPaint(Color.YELLOW); - PNode eye2 = (PNode) eye1.clone(); - PNode mouth = PPath.createRectangle(0, 0, 40, 20); - mouth.setPaint(Color.BLACK); - - // add the face parts - myCompositeFace.addChild(eye1); - myCompositeFace.addChild(eye2); - myCompositeFace.addChild(mouth); - - // don't want anyone grabbing out our eye's. - myCompositeFace.setChildrenPickable(false); - - // position the face parts. - eye2.translate(25, 0); - mouth.translate(0, 30); - - // set the face bounds so that it neatly contains the face parts. - PBounds b = myCompositeFace.getUnionOfChildrenBounds(null); - myCompositeFace.setBounds(b.inset(-5, -5)); - - // opps it to small, so scale it up. - myCompositeFace.scale(1.5); - - getCanvas().getLayer().addChild(myCompositeFace); - } - - // Here a completely new kind of node, a grid node" is created. We do - // all the drawing ourselves here instead of passing the work off to - // other parts of the framework. - public void createCustomNode() { - PNode n = new PNode() { - public void paint(PPaintContext aPaintContext) { - double bx = getX(); - double by = getY(); - double rightBorder = bx + getWidth(); - double bottomBorder = by + getHeight(); - - Line2D line = new Line2D.Double(); - Graphics2D g2 = aPaintContext.getGraphics(); - - g2.setStroke(new BasicStroke(0)); - g2.setPaint(getPaint()); - - // draw vertical lines - for (double x = bx; x < rightBorder; x += 5) { - line.setLine(x, by, x, bottomBorder); - g2.draw(line); - } - - for (double y = by; y < bottomBorder; y += 5) { - line.setLine(bx, y, rightBorder, y); - g2.draw(line); - } - } - }; - n.setBounds(0, 0, 100, 80); - n.setPaint(Color.black); - getCanvas().getLayer().addChild(n); - } - - public static void main(String[] args) { - new BirdsEyeViewExample(); - } - - /** - * The Birds Eye View Class - */ - public class BirdsEyeView extends PCanvas implements PropertyChangeListener { - - /** - * This is the node that shows the viewed area. - */ - PNode areaVisiblePNode; - - /** - * This is the canvas that is being viewed - */ - PCanvas viewedCanvas; - - /** - * The change listener to know when to update the birds eye view. - */ - PropertyChangeListener changeListener; - - int layerCount; - - /** - * Creates a new instance of a BirdsEyeView - */ - public BirdsEyeView() { - - // create the PropertyChangeListener for listening to the viewed - // canvas - changeListener = new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - updateFromViewed(); - } - }; - - // create the coverage node - areaVisiblePNode = new P3DRect(); - areaVisiblePNode.setPaint(new Color(128, 128, 255)); - areaVisiblePNode.setTransparency(.8f); - areaVisiblePNode.setBounds(0, 0, 100, 100); - getCamera().addChild(areaVisiblePNode); - - // add the drag event handler - getCamera().addInputEventListener(new PDragSequenceEventHandler() { - protected void startDrag(PInputEvent e) { - if (e.getPickedNode() == areaVisiblePNode) - super.startDrag(e); - } - - protected void drag(PInputEvent e) { - PDimension dim = e.getDelta(); - viewedCanvas.getCamera().translateView(0 - dim.getWidth(), - 0 - dim.getHeight()); - } - - }); - - // remove Pan and Zoom - removeInputEventListener(getPanEventHandler()); - removeInputEventListener(getZoomEventHandler()); - - setDefaultRenderQuality(PPaintContext.LOW_QUALITY_RENDERING); - - } - - public void connect(PCanvas canvas, PLayer[] viewed_layers) { - - this.viewedCanvas = canvas; - layerCount = 0; - - viewedCanvas.getCamera().addPropertyChangeListener(changeListener); - - for (layerCount = 0; layerCount < viewed_layers.length; ++layerCount) { - getCamera().addLayer(layerCount, viewed_layers[layerCount]); - } - - } - - /** - * Add a layer to list of viewed layers - */ - public void addLayer(PLayer new_layer) { - getCamera().addLayer(new_layer); - layerCount++; - } - - /** - * Remove the layer from the viewed layers - */ - public void removeLayer(PLayer old_layer) { - getCamera().removeLayer(old_layer); - layerCount--; - } - - /** - * Stop the birds eye view from receiving events from the viewed canvas - * and remove all layers - */ - public void disconnect() { - viewedCanvas.getCamera().removePropertyChangeListener( - changeListener); - - for (int i = 0; i < getCamera().getLayerCount(); ++i) { - getCamera().removeLayer(i); - } - - } - - /** - * This method will get called when the viewed canvas changes - */ - public void propertyChange(PropertyChangeEvent event) { - updateFromViewed(); - } - - /** - * This method gets the state of the viewed canvas and updates the - * BirdsEyeViewer This can be called from outside code - */ - public void updateFromViewed() { - - double viewedX; - double viewedY; - double viewedHeight; - double viewedWidth; - - double ul_camera_x = viewedCanvas.getCamera().getViewBounds() - .getX(); - double ul_camera_y = viewedCanvas.getCamera().getViewBounds() - .getY(); - double lr_camera_x = ul_camera_x - + viewedCanvas.getCamera().getViewBounds().getWidth(); - double lr_camera_y = ul_camera_y - + viewedCanvas.getCamera().getViewBounds().getHeight(); - - Rectangle2D drag_bounds = getCamera().getUnionOfLayerFullBounds(); - - double ul_layer_x = drag_bounds.getX(); - double ul_layer_y = drag_bounds.getY(); - double lr_layer_x = drag_bounds.getX() + drag_bounds.getWidth(); - double lr_layer_y = drag_bounds.getY() + drag_bounds.getHeight(); - - // find the upper left corner - - // set to the lesser value - if (ul_camera_x < ul_layer_x) - viewedX = ul_layer_x; - else - viewedX = ul_camera_x; - - // same for y - if (ul_camera_y < ul_layer_y) - viewedY = ul_layer_y; - else - viewedY = ul_camera_y; - - // find the lower right corner - - // set to the greater value - if (lr_camera_x < lr_layer_x) - viewedWidth = lr_camera_x - viewedX; - else - viewedWidth = lr_layer_x - viewedX; - - // same for height - if (lr_camera_y < lr_layer_y) - viewedHeight = lr_camera_y - viewedY; - else - viewedHeight = lr_layer_y - viewedY; - - Rectangle2D bounds = new Rectangle2D.Double(viewedX, viewedY, - viewedWidth, viewedHeight); - bounds = getCamera().viewToLocal(bounds); - areaVisiblePNode.setBounds(bounds); - - // keep the birds eye view centered - getCamera().animateViewToCenterBounds(drag_bounds, true, 0); - - } - - } // class BirdsEyeView - -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/CameraExample.java b/examples/edu/umd/cs/piccolo/examples/CameraExample.java deleted file mode 100644 index 8a7fb78..0000000 --- a/examples/edu/umd/cs/piccolo/examples/CameraExample.java +++ /dev/null @@ -1,47 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PBoundsHandle; - -/** - * This example shows how to create internal cameras - */ -public class CameraExample extends PFrame { - - public CameraExample() { - this(null); - } - - public CameraExample(PCanvas aCanvas) { - super("CameraExample", false, aCanvas); - } - - public void initialize() { - PLayer l = new PLayer(); - PPath n = PPath.createEllipse(0, 0, 100, 80); - n.setPaint(Color.red); - n.setStroke(null); - PBoundsHandle.addBoundsHandlesTo(n); - l.addChild(n); - n.translate(200, 200); - - PCamera c = new PCamera(); - c.setBounds(0, 0, 100, 80); - c.scaleView(0.1); - c.addLayer(l); - PBoundsHandle.addBoundsHandlesTo(c); - c.setPaint(Color.yellow); - - getCanvas().getLayer().addChild(l); - getCanvas().getLayer().addChild(c); - } - - public static void main(String[] args) { - new CameraExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/CenterExample.java b/examples/edu/umd/cs/piccolo/examples/CenterExample.java deleted file mode 100644 index 20aadd5..0000000 --- a/examples/edu/umd/cs/piccolo/examples/CenterExample.java +++ /dev/null @@ -1,36 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -public class CenterExample extends PFrame { - - public CenterExample() { - this(null); - } - - public CenterExample(PCanvas aCanvas) { - super("CenterExample", false, aCanvas); - } - - public void initialize() { - PCanvas c = getCanvas(); - PLayer l = c.getLayer(); - PCamera cam = c.getCamera(); - - cam.scaleView(2.0); - PPath path = PPath.createRectangle(0, 0, 100, 100); - - l.addChild(path); - path.translate(100, 10); - path.scale(0.2); - cam.animateViewToCenterBounds(path.getGlobalFullBounds(), true, 1000); - } - - public static void main(String[] args) { - new CenterExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/ChartLabelExample.java b/examples/edu/umd/cs/piccolo/examples/ChartLabelExample.java deleted file mode 100644 index 52a1e7c..0000000 --- a/examples/edu/umd/cs/piccolo/examples/ChartLabelExample.java +++ /dev/null @@ -1,95 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.Color; -import java.awt.geom.Point2D; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.nodes.PText; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how to create a vertical and a horizontal bar which can - * move with your graph and always stays on view. - * - * @author Tao - */ -public class ChartLabelExample extends PFrame { - final int nodeHeight = 15; - final int nodeWidth = 30; - - //Row Bar - PLayer rowBarLayer; - - //Colume Bar - PLayer colBarLayer; - - public ChartLabelExample() { - this(null); - } - - public ChartLabelExample(PCanvas aCanvas) { - super("ChartLabelExample", false, aCanvas); - } - - public void initialize() { - //create bar layers - rowBarLayer = new PLayer(); - colBarLayer = new PLayer(); - - //create bar nodes - for (int i = 0; i < 10; i++) { - //create row bar with node row1, row2,...row10 - PText p = new PText("Row " + i); - p.setX(0); - p.setY(nodeHeight * i + nodeHeight); - p.setPaint(Color.white); - colBarLayer.addChild(p); - - //create col bar with node col1, col2,...col10 - p = new PText("Col " + i); - p.setX(nodeWidth * i + nodeWidth); - p.setY(0); - p.setPaint(Color.white); - rowBarLayer.addChild(p); - } - - //add bar layers to camera - getCanvas().getCamera().addChild(rowBarLayer); - getCanvas().getCamera().addChild(colBarLayer); - - //create matrix nodes - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 10; j++) { - PPath path = PPath.createRectangle(nodeWidth * j + nodeWidth, - nodeHeight * i + nodeHeight, nodeWidth - 1, - nodeHeight - 1); - getCanvas().getLayer().addChild(path); - } - } - - //catch drag event and move bars corresponding - getCanvas().addInputEventListener(new PDragSequenceEventHandler() { - Point2D oldP, newP; - - public void mousePressed(PInputEvent aEvent) { - oldP = getCanvas().getCamera().getViewBounds().getCenter2D(); - } - - public void mouseReleased(PInputEvent aEvent) { - newP = getCanvas().getCamera().getViewBounds().getCenter2D(); - colBarLayer.translate(0, (oldP.getY() - newP.getY()) - / getCanvas().getLayer().getScale()); - rowBarLayer.translate((oldP.getX() - newP.getX()) - / getCanvas().getLayer().getScale(), 0); - } - }); - } - - public static void main(String[] args) { - new ChartLabelExample(); - } -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/ClipExample.java b/examples/edu/umd/cs/piccolo/examples/ClipExample.java deleted file mode 100644 index 950a3ab..0000000 --- a/examples/edu/umd/cs/piccolo/examples/ClipExample.java +++ /dev/null @@ -1,39 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.nodes.PClip; - -/** - * Quick example of how to use a clip. - */ -public class ClipExample extends PFrame { - - public ClipExample() { - this(null); - } - - public ClipExample(PCanvas aCanvas) { - super("ClipExample", false, aCanvas); - } - - public void initialize() { - PClip clip = new PClip(); - clip.setPathToEllipse(0, 0, 100, 100); - clip.setPaint(Color.red); - - clip.addChild(PPath.createRectangle(20, 20, 100, 50)); - getCanvas().getLayer().addChild(clip); - - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(new PDragEventHandler()); - } - - public static void main(String[] args) { - new ClipExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/CompositeExample.java b/examples/edu/umd/cs/piccolo/examples/CompositeExample.java deleted file mode 100644 index 368d9fa..0000000 --- a/examples/edu/umd/cs/piccolo/examples/CompositeExample.java +++ /dev/null @@ -1,53 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.nodes.PText; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.nodes.PComposite; - -/** - * This example shows how to create a composite node. A composite node is - * a group of nodes that behave as a single node when interacted with. - */ -public class CompositeExample extends PFrame { - - public CompositeExample() { - this(null); - } - - public CompositeExample(PCanvas aCanvas) { - super("CompositeExample", false, aCanvas); - } - - public void initialize() { - PComposite composite = new PComposite(); - - PNode circle = PPath.createEllipse(0, 0, 100, 100); - PNode rectangle = PPath.createRectangle(50, 50, 100, 100); - PNode text = new PText("Hello world!"); - - composite.addChild(circle); - composite.addChild(rectangle); - composite.addChild(text); - - rectangle.rotate(Math.toRadians(45)); - rectangle.setPaint(Color.RED); - - text.scale(2.0); - text.setPaint(Color.GREEN); - - getCanvas().getLayer().addChild(composite); - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(new PDragEventHandler()); - } - - public static void main(String[] args) { - new CompositeExample(); - } - -} diff --git a/examples/edu/umd/cs/piccolo/examples/DynamicExample.java b/examples/edu/umd/cs/piccolo/examples/DynamicExample.java deleted file mode 100644 index b7ea44e..0000000 --- a/examples/edu/umd/cs/piccolo/examples/DynamicExample.java +++ /dev/null @@ -1,70 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.BasicStroke; -import java.awt.Color; -import java.util.Iterator; -import java.util.Random; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.PRoot; -import edu.umd.cs.piccolo.activities.PActivity; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.util.PFixedWidthStroke; - -/** - * 1000 nodes rotated continuously. Note that if you zoom to a portion of the screen where - * you can't see any nodes the CPU usage goes down to 1%, even though all the objects are - * still getting rotated continuously (every 20 milliseconds). This shows that the cost - * of repainting and bounds caches is very cheap compared to the cost of drawing. - */ -public class DynamicExample extends PFrame { - - public DynamicExample() { - this(null); - } - - public DynamicExample(PCanvas aCanvas) { - super("DynamicExample", false, aCanvas); - } - - public void initialize() { - final PLayer layer = getCanvas().getLayer(); - PRoot root = getCanvas().getRoot(); - Random r = new Random(); - for (int i = 0; i < 1000; i++) { - final PNode n = PPath.createRectangle(0, 0, 100, 80); - n.translate(10000 * r.nextFloat(), 10000 * r.nextFloat()); - n.setPaint(new Color(r.nextFloat(), r.nextFloat(),r.nextFloat())); - layer.addChild(n); - } - getCanvas().getCamera().animateViewToCenterBounds(layer.getGlobalFullBounds(), true, 0); - PActivity a = new PActivity(-1, 20) { - public void activityStep(long currentTime) { - super.activityStep(currentTime); - rotateNodes(); - } - }; - root.addActivity(a); - - PPath p = new PPath(); - p.moveTo(0, 0); - p.lineTo(0, 1000); - PFixedWidthStroke stroke = new PFixedWidthStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, new float[] {5, 2}, 0); - p.setStroke(stroke); - layer.addChild(p); - } - - public void rotateNodes() { - Iterator i = getCanvas().getLayer().getChildrenReference().iterator(); - while (i.hasNext()) { - PNode each = (PNode) i.next(); - each.rotate(Math.toRadians(2)); - } - } - - public static void main(String[] args) { - new DynamicExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/EventHandlerExample.java b/examples/edu/umd/cs/piccolo/examples/EventHandlerExample.java deleted file mode 100644 index b0c3cd2..0000000 --- a/examples/edu/umd/cs/piccolo/examples/EventHandlerExample.java +++ /dev/null @@ -1,116 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.BasicStroke; -import java.awt.event.InputEvent; -import java.awt.geom.Point2D; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.event.PInputEventFilter; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PBounds; - -/** - * This example shows how to create and install a custom event listener that draws - * rectangles. - */ -public class EventHandlerExample extends PFrame { - - public EventHandlerExample() { - this(null); - } - - public EventHandlerExample(PCanvas aCanvas) { - super("EventHandlerExample", false, aCanvas); - } - - public void initialize() { - super.initialize(); - - // Create a new event handler the creates new rectangles on - // mouse pressed, dragged, release. - PBasicInputEventHandler rectEventHandler = createRectangleEventHandler(); - - // Make the event handler only work with BUTTON1 events, so that it does - // not conflict with the zoom event handler that is installed by default. - rectEventHandler.setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); - - // Remove the pan event handler that is installed by default so that it - // does not conflict with our new rectangle creation event handler. - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - - // Register our new event handler. - getCanvas().addInputEventListener(rectEventHandler); - } - - public PBasicInputEventHandler createRectangleEventHandler() { - - // Create a new subclass of PBasicEventHandler that creates new PPath nodes - // on mouse pressed, dragged, and released sequences. Not that subclassing - // PDragSequenceEventHandler would make this class easier to implement, but - // here you can see how to do it from scratch. - return new PBasicInputEventHandler() { - - // The rectangle that is currently getting created. - protected PPath rectangle; - - // The mouse press location for the current pressed, drag, release sequence. - protected Point2D pressPoint; - - // The current drag location. - protected Point2D dragPoint; - - public void mousePressed(PInputEvent e) { - super.mousePressed(e); - - PLayer layer = getCanvas().getLayer(); - - // Initialize the locations. - pressPoint = e.getPosition(); - dragPoint = pressPoint; - - // create a new rectangle and add it to the canvas layer so that - // we can see it. - rectangle = new PPath(); - rectangle.setStroke(new BasicStroke((float)(1/ e.getCamera().getViewScale()))); - layer.addChild(rectangle); - - // update the rectangle shape. - updateRectangle(); - } - - public void mouseDragged(PInputEvent e) { - super.mouseDragged(e); - // update the drag point location. - dragPoint = e.getPosition(); - - // update the rectangle shape. - updateRectangle(); - } - - public void mouseReleased(PInputEvent e) { - super.mouseReleased(e); - // update the rectangle shape. - updateRectangle(); - rectangle = null; - } - - public void updateRectangle() { - // create a new bounds that contains both the press and current - // drag point. - PBounds b = new PBounds(); - b.add(pressPoint); - b.add(dragPoint); - - // Set the rectangles bounds. - rectangle.setPathTo(b); - } - }; - } - - public static void main(String[] args) { - new EventHandlerExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/ExampleRunner.java b/examples/edu/umd/cs/piccolo/examples/ExampleRunner.java deleted file mode 100644 index ab75a88..0000000 --- a/examples/edu/umd/cs/piccolo/examples/ExampleRunner.java +++ /dev/null @@ -1,362 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.BorderLayout; -import java.awt.Container; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JPanel; - -import edu.umd.cs.piccolo.util.PDebug; -import edu.umd.cs.piccolox.PFrame; - -public class ExampleRunner extends JFrame { - - public ExampleRunner() { - setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); - setTitle("Piccolo Example Runner"); - setSize(426, 335); - getContentPane().setLayout(new BorderLayout()); - createExampleButtons(); - validate(); - pack(); - setVisible(true); - } - - public void createExampleButtons() { - Container c = getContentPane(); - Container p = new JPanel(); - - p = new JPanel(new GridLayout(0, 1)); - c.add(BorderLayout.NORTH, p); - - p.add(new JCheckBox(new AbstractAction("Print Frame Rates to Console") { - public void actionPerformed(ActionEvent e) { - PDebug.debugPrintFrameRate = !PDebug.debugPrintFrameRate; - } - })); - - p.add(new JCheckBox(new AbstractAction("Show Region Managment") { - public void actionPerformed(ActionEvent e) { - PDebug.debugRegionManagement = !PDebug.debugRegionManagement; - } - })); - - p.add(new JCheckBox(new AbstractAction("Show Full Bounds") { - public void actionPerformed(ActionEvent e) { - PDebug.debugFullBounds = !PDebug.debugFullBounds; - } - })); - - p = new JPanel(new GridLayout(0, 2)); - c.add(BorderLayout.CENTER, p); - - p.add(new JButton(new AbstractAction("ActivityExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new ActivityExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("AngleNodeExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new AngleNodeExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("BirdsEyeViewExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new BirdsEyeViewExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("CameraExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new CameraExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("CenterExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new CenterExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("ChartLabelExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new ChartLabelExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("ClipExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new ClipExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("CompositeExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new CompositeExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("DynamicExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new DynamicExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("EventHandlerExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new EventHandlerExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("FullScreenNodeExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new FullScreenNodeExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("GraphEditorExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new GraphEditorExample(); - example.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - p.add(new JButton(new AbstractAction("GridExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new GridExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("GroupExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new GroupExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("HandleExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new HandleExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("HierarchyZoomExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new HierarchyZoomExample(); - example.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("KeyEventFocusExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new KeyEventFocusExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("LayoutExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new LayoutExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("LensExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new LensExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("NavigationExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new NavigationExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("NodeCacheExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new NodeCacheExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("NodeEventExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new NodeEventExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("NodeExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new NodeExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("NodeLinkExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new NodeLinkExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("PanToExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new PanToExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("PathExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new PathExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("PositionExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new PositionExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("PositionPathActivityExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new PositionPathActivityExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("PulseExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new PulseExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("ScrollingExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new ScrollingExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("SelectionExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new SelectionExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("SquiggleExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new SquiggleExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("StickyExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new StickyExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("StickyHandleLayerExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new StickyHandleLayerExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("TextExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new TextExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("Tooltip Example") { - public void actionPerformed(ActionEvent e) { - PFrame example = new TooltipExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("TwoCanvasExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new TwoCanvasExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - - p.add(new JButton(new AbstractAction("WaitForActivitiesExample") { - public void actionPerformed(ActionEvent e) { - PFrame example = new WaitForActivitiesExample(); - example - .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - } - })); - } - - public static void main(String[] args) { - new ExampleRunner(); - } -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/FullScreenNodeExample.java b/examples/edu/umd/cs/piccolo/examples/FullScreenNodeExample.java deleted file mode 100644 index fcabba1..0000000 --- a/examples/edu/umd/cs/piccolo/examples/FullScreenNodeExample.java +++ /dev/null @@ -1,14 +0,0 @@ -package edu.umd.cs.piccolo.examples; - - -public class FullScreenNodeExample extends NodeExample { - - public void initialize() { - super.initialize(); - setFullScreenMode(true); - } - - public static void main(String[] args) { - new FullScreenNodeExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/GraphEditorExample.java b/examples/edu/umd/cs/piccolo/examples/GraphEditorExample.java deleted file mode 100644 index 115c94f..0000000 --- a/examples/edu/umd/cs/piccolo/examples/GraphEditorExample.java +++ /dev/null @@ -1,136 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; -import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.Random; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * Create a simple graph with some random nodes and connected edges. - * An event handler allows users to drag nodes around, keeping the edges connected. - * - * ported from .NET GraphEditorExample by Sun Hongmei. - */ -public class GraphEditorExample extends PFrame { - - public GraphEditorExample() { - this(null); - } - - public GraphEditorExample(PCanvas aCanvas) { - super("GraphEditorExample", false, aCanvas); - } - - public void initialize() { - int numNodes = 50; - int numEdges = 50; - - // Initialize, and create a layer for the edges (always underneath the nodes) - PLayer nodeLayer = getCanvas().getLayer(); - PLayer edgeLayer = new PLayer(); - getCanvas().getCamera().addLayer(0, edgeLayer); - Random rnd = new Random(); - ArrayList tmp; - for (int i = 0; i < numNodes; i++) { - float x = (float) (300. * rnd.nextDouble()); - float y = (float) (400. * rnd.nextDouble()); - PPath path = PPath.createEllipse(x, y, 20, 20); - tmp = new ArrayList(); - path.addAttribute("edges", tmp); - nodeLayer.addChild(path); - } - - // Create some random edges - // Each edge's Tag has an ArrayList used to store associated nodes - for (int i = 0; i < numEdges; i++) { - int n1 = rnd.nextInt(numNodes); - int n2 = rnd.nextInt(numNodes); - PNode node1 = nodeLayer.getChild(n1); - PNode node2 = nodeLayer.getChild(n2); - - Point2D.Double bound1 = (Point2D.Double) node1.getBounds().getCenter2D(); - Point2D.Double bound2 = (Point2D.Double) node2.getBounds().getCenter2D(); - - PPath edge = new PPath(); - edge.moveTo((float) bound1.getX(), (float) bound1.getY()); - edge.lineTo((float) bound2.getX(), (float) bound2.getY()); - - tmp = (ArrayList) node1.getAttribute("edges"); - tmp.add(edge); - tmp = (ArrayList) node2.getAttribute("edges"); - tmp.add(edge); - - tmp = new ArrayList(); - tmp.add(node1); - tmp.add(node2); - edge.addAttribute("nodes", tmp); - - edgeLayer.addChild(edge); - } - - // Create event handler to move nodes and update edges - nodeLayer.addInputEventListener(new NodeDragHandler()); - } - - public static void main(String[] args) { - new GraphEditorExample(); - } - - /// - /// Simple event handler which applies the following actions to every node it is called on: - /// * Turn node red when the mouse goes over the node - /// * Turn node white when the mouse exits the node - /// * Drag the node, and associated edges on mousedrag - /// It assumes that the node's Tag references an ArrayList with a list of associated - /// edges where each edge is a PPath which each have a Tag that references an ArrayList - /// with a list of associated nodes. - /// - class NodeDragHandler extends PDragSequenceEventHandler { - public NodeDragHandler() { - getEventFilter().setMarksAcceptedEventsAsHandled(true); - } - public void mouseEntered(PInputEvent e) { - if (e.getButton() == 0) { - e.getPickedNode().setPaint(Color.red); - } - } - - public void mouseExited(PInputEvent e) { - if (e.getButton() == 0) { - e.getPickedNode().setPaint(Color.white); - } - } - - public void drag(PInputEvent e) { - PNode node = e.getPickedNode(); - node.translate(e.getDelta().width, e.getDelta().height); - - ArrayList edges = (ArrayList) e.getPickedNode().getAttribute("edges"); - - int i; - for (i = 0; i < edges.size(); i++) { - PPath edge = (PPath) edges.get(i); - ArrayList nodes = (ArrayList) edge.getAttribute("nodes"); - PNode node1 = (PNode) nodes.get(0); - PNode node2 = (PNode) nodes.get(1); - - edge.reset(); - // Note that the node's "FullBounds" must be used (instead of just the "Bound") - // because the nodes have non-identity transforms which must be included when - // determining their position. - Point2D.Double bound1 = (Point2D.Double) node1.getFullBounds().getCenter2D(); - Point2D.Double bound2 = (Point2D.Double) node2.getFullBounds().getCenter2D(); - - edge.moveTo((float) bound1.getX(), (float) bound1.getY()); - edge.lineTo((float) bound2.getX(), (float) bound2.getY()); - } - } - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/GridExample.java b/examples/edu/umd/cs/piccolo/examples/GridExample.java deleted file mode 100644 index e19d9dc..0000000 --- a/examples/edu/umd/cs/piccolo/examples/GridExample.java +++ /dev/null @@ -1,145 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Stroke; -import java.awt.geom.Line2D; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.PRoot; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolox.PFrame; - -/** - * Example of drawing an infinite grid, and providing support for snap to grid. - */ -public class GridExample extends PFrame { - - static protected Line2D gridLine = new Line2D.Double(); - static protected Stroke gridStroke = new BasicStroke(1); - static protected Color gridPaint = Color.BLACK; - static protected double gridSpacing = 20; - - public GridExample() { - this(null); - } - - public GridExample(PCanvas aCanvas) { - super("GridExample", false, aCanvas); - } - - public void initialize() { - PRoot root = getCanvas().getRoot(); - final PCamera camera = getCanvas().getCamera(); - final PLayer gridLayer = new PLayer() { - protected void paint(PPaintContext paintContext) { - // make sure grid gets drawn on snap to grid boundaries. And - // expand a little to make sure that entire view is filled. - double bx = (getX() - (getX() % gridSpacing)) - gridSpacing; - double by = (getY() - (getY() % gridSpacing)) - gridSpacing; - double rightBorder = getX() + getWidth() + gridSpacing; - double bottomBorder = getY() + getHeight() + gridSpacing; - - Graphics2D g2 = paintContext.getGraphics(); - Rectangle2D clip = paintContext.getLocalClip(); - - g2.setStroke(gridStroke); - g2.setPaint(gridPaint); - - for (double x = bx; x < rightBorder; x += gridSpacing) { - gridLine.setLine(x, by, x, bottomBorder); - if (clip.intersectsLine(gridLine)) { - g2.draw(gridLine); - } - } - - for (double y = by; y < bottomBorder; y += gridSpacing) { - gridLine.setLine(bx, y, rightBorder, y); - if (clip.intersectsLine(gridLine)) { - g2.draw(gridLine); - } - } - } - }; - - // replace standar layer with grid layer. - root.removeChild(camera.getLayer(0)); - camera.removeLayer(0); - root.addChild(gridLayer); - camera.addLayer(gridLayer); - - // add constrains so that grid layers bounds always match cameras view bounds. This makes - // it look like an infinite grid. - camera.addPropertyChangeListener(PNode.PROPERTY_BOUNDS, new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - gridLayer.setBounds(camera.getViewBounds()); - } - }); - - camera.addPropertyChangeListener(PCamera.PROPERTY_VIEW_TRANSFORM, new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - gridLayer.setBounds(camera.getViewBounds()); - } - }); - - gridLayer.setBounds(camera.getViewBounds()); - - PNode n = new PNode(); - n.setPaint(Color.BLUE); - n.setBounds(0, 0, 100, 80); - - getCanvas().getLayer().addChild(n); - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - - // add a drag event handler that supports snap to grid. - getCanvas().addInputEventListener(new PDragSequenceEventHandler() { - - protected PNode draggedNode; - protected Point2D nodeStartPosition; - - protected boolean shouldStartDragInteraction(PInputEvent event) { - if (super.shouldStartDragInteraction(event)) { - return event.getPickedNode() != event.getTopCamera() && !(event.getPickedNode() instanceof PLayer); - } - return false; - } - - protected void startDrag(PInputEvent event) { - super.startDrag(event); - draggedNode = event.getPickedNode(); - draggedNode.moveToFront(); - nodeStartPosition = draggedNode.getOffset(); - } - - protected void drag(PInputEvent event) { - super.drag(event); - - Point2D start = getCanvas().getCamera().localToView((Point2D)getMousePressedCanvasPoint().clone()); - Point2D current = event.getPositionRelativeTo(getCanvas().getLayer()); - Point2D dest = new Point2D.Double(); - - dest.setLocation(nodeStartPosition.getX() + (current.getX() - start.getX()), - nodeStartPosition.getY() + (current.getY() - start.getY())); - - dest.setLocation(dest.getX() - (dest.getX() % gridSpacing), - dest.getY() - (dest.getY() % gridSpacing)); - - draggedNode.setOffset(dest.getX(), dest.getY()); - } - }); - } - - public static void main(String[] args) { - new GridExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/GroupExample.java b/examples/edu/umd/cs/piccolo/examples/GroupExample.java deleted file mode 100644 index 9ccc469..0000000 --- a/examples/edu/umd/cs/piccolo/examples/GroupExample.java +++ /dev/null @@ -1,192 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.util.ArrayList; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.event.PSelectionEventHandler; - -/** - * An example of how to implement decorator groups. Decorator groups are nodes that base their bounds and rendering on their children. - * This seems to be a common type of visual node that requires some potentially non-obvious subclassing to get right. - * - * Both a volatile and a non-volatile implementation are shown. The volatile implementation might be used in cases where you want to - * keep a scale-independent pen width border around a group of objects. The non-volatile implementation can be used in more standard - * cases where the decorator's bounds are stable during zooming. - * - * @author Lance Good - */ -public class GroupExample extends PFrame { - - public GroupExample() { - this(null); - } - - public GroupExample(PCanvas aCanvas) { - super("GroupExample", false, aCanvas); - } - - public void initialize() { - super.initialize(); - - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - - // Create a decorator group that is NOT volatile - DecoratorGroup dg = new DecoratorGroup(); - dg.setPaint(Color.magenta); - - // Put some nodes under the group for it to decorate - PPath p1 = PPath.createEllipse(25,25,75,75); - p1.setPaint(Color.red); - PPath p2 = PPath.createRectangle(125,75,50,50); - p2.setPaint(Color.blue); - - // Add everything to the Piccolo hierarchy - dg.addChild(p1); - dg.addChild(p2); - getCanvas().getLayer().addChild(dg); - - // Create a decorator group that IS volatile - VolatileDecoratorGroup vdg = new VolatileDecoratorGroup(getCanvas().getCamera()); - vdg.setPaint(Color.cyan); - - // Put some nodes under the group for it to decorate - PPath p3 = PPath.createEllipse(275,175,50,50); - p3.setPaint(Color.blue); - PPath p4 = PPath.createRectangle(175,175,75,75); - p4.setPaint(Color.green); - - // Add everything to the Piccolo hierarchy - vdg.addChild(p3); - vdg.addChild(p4); - getCanvas().getLayer().addChild(vdg); - - // Create a selection handler so we can see that the decorator actually works - ArrayList selectableParents = new ArrayList(); - selectableParents.add(dg); - selectableParents.add(vdg); - - PSelectionEventHandler ps = new PSelectionEventHandler(getCanvas().getLayer(),selectableParents); - getCanvas().addInputEventListener(ps); - } - - public static void main(String[] args) { - new GroupExample(); - } -} - -/** - * This is the non-volatile implementation of a decorator group that paints a background rectangle based - * on the bounds of its children. - */ -class DecoratorGroup extends PNode { - int INDENT = 10; - - PBounds cachedChildBounds = new PBounds(); - PBounds comparisonBounds = new PBounds(); - - public DecoratorGroup() { - super(); - } - - /** - * Change the default paint to fill an expanded bounding box based on its children's bounds - */ - public void paint(PPaintContext ppc) { - Paint paint = getPaint(); - if (paint != null) { - Graphics2D g2 = ppc.getGraphics(); - g2.setPaint(paint); - - PBounds bounds = getUnionOfChildrenBounds(null); - bounds.setRect(bounds.getX()-INDENT,bounds.getY()-INDENT,bounds.getWidth()+2*INDENT,bounds.getHeight()+2*INDENT); - g2.fill(bounds); - } - } - - /** - * Change the full bounds computation to take into account that we are expanding the children's bounds - * Do this instead of overriding getBoundsReference() since the node is not volatile - */ - public PBounds computeFullBounds(PBounds dstBounds) { - PBounds result = getUnionOfChildrenBounds(dstBounds); - - cachedChildBounds.setRect(result); - result.setRect(result.getX()-INDENT,result.getY()-INDENT,result.getWidth()+2*INDENT,result.getHeight()+2*INDENT); - localToParent(result); - return result; - } - - /** - * This is a crucial step. We have to override this method to invalidate the paint each time the bounds are changed so - * we repaint the correct region - */ - public boolean validateFullBounds() { - comparisonBounds = getUnionOfChildrenBounds(comparisonBounds); - - if (!cachedChildBounds.equals(comparisonBounds)) { - setPaintInvalid(true); - } - return super.validateFullBounds(); - } -} - -/** - * This is the volatile implementation of a decorator group that paints a background rectangle based - * on the bounds of its children. - */ -class VolatileDecoratorGroup extends PNode { - int INDENT = 10; - - PBounds cachedChildBounds = new PBounds(); - PBounds comparisonBounds = new PBounds(); - PCamera renderCamera; - - public VolatileDecoratorGroup(PCamera camera) { - super(); - renderCamera = camera; - } - - /** - * Indicate that the bounds are volatile for this group - */ - public boolean getBoundsVolatile() { - return true; - } - - /** - * Since our bounds are volatile, we can override this method to indicate that we are expanding our bounds beyond our children - */ - public PBounds getBoundsReference() { - PBounds bds = super.getBoundsReference(); - getUnionOfChildrenBounds(bds); - - cachedChildBounds.setRect(bds); - double scaledIndent = INDENT/renderCamera.getViewScale(); - bds.setRect(bds.getX()-scaledIndent,bds.getY()-scaledIndent,bds.getWidth()+2*scaledIndent,bds.getHeight()+2*scaledIndent); - - return bds; - } - - /** - * This is a crucial step. We have to override this method to invalidate the paint each time the bounds are changed so - * we repaint the correct region - */ - public boolean validateFullBounds() { - comparisonBounds = getUnionOfChildrenBounds(comparisonBounds); - - if (!cachedChildBounds.equals(comparisonBounds)) { - setPaintInvalid(true); - } - return super.validateFullBounds(); - } -} - - diff --git a/examples/edu/umd/cs/piccolo/examples/HandleExample.java b/examples/edu/umd/cs/piccolo/examples/HandleExample.java deleted file mode 100644 index 7430fec..0000000 --- a/examples/edu/umd/cs/piccolo/examples/HandleExample.java +++ /dev/null @@ -1,82 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.BasicStroke; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PBoundsHandle; -import edu.umd.cs.piccolox.handles.PHandle; -import edu.umd.cs.piccolox.util.PNodeLocator; - -/** - * This example show how to add the default handles to a node, and also how - * to create your own custom handles. - */ -public class HandleExample extends PFrame { - - public HandleExample() { - this(null); - } - - public HandleExample(PCanvas aCanvas) { - super("HandleExample", false, aCanvas); - } - - public void initialize() { - PPath n = PPath.createRectangle(0, 0, 100, 80); - - // add another node the the root as a reference point so that we can - // tell that our node is getting dragged, as opposed the the canvas - // view being panned. - getCanvas().getLayer().addChild(PPath.createRectangle(0, 0, 100, 80)); - - getCanvas().getLayer().addChild(n); - - // tell the node to show its default handles. - PBoundsHandle.addBoundsHandlesTo(n); - - // The default PBoundsHandle implementation doesn't work well with PPaths that have strokes. The reason - // for this is that the default PBoundsHandle modifies the bounds of an PNode, but when adding handles to - // a PPath we really want it to be modifying the underlying geometry of the PPath, the shape without the - // stroke. The solution is that we need to create handles specific to PPaths that locate themselves on the - // paths internal geometry, not the external bounds geometry... - - n.setStroke(new BasicStroke(10)); - n.setPaint(Color.green); - - // Here we create our own custom handle. This handle is located in the center of its parent - // node and you can use it to drag the parent around. This handle also updates its color when - // the is pressed/released in it. - final PHandle h = new PHandle(new PNodeLocator(n)) { // the default locator locates the center of a node. - public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { - localToParent(aLocalDimension); - getParent().translate(aLocalDimension.getWidth(), aLocalDimension.getHeight()); - } - }; - - h.addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent aEvent) { - h.setPaint(Color.YELLOW); - } - - public void mouseReleased(PInputEvent aEvent) { - h.setPaint(Color.RED); - } - }); - - // make this handle appear a bit different then the default handle appearance. - h.setPaint(Color.RED); - h.setBounds(-10, -10, 20, 20); - - // also add our new custom handle to the node. - n.addChild(h); - } - - public static void main(String[] args) { - new HandleExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/HelloWorldExample.java b/examples/edu/umd/cs/piccolo/examples/HelloWorldExample.java deleted file mode 100644 index 75967aa..0000000 --- a/examples/edu/umd/cs/piccolo/examples/HelloWorldExample.java +++ /dev/null @@ -1,25 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.nodes.PText; -import edu.umd.cs.piccolox.PFrame; - -public class HelloWorldExample extends PFrame { - - public HelloWorldExample() { - this(null); - } - - public HelloWorldExample(PCanvas aCanvas) { - super("HelloWorldExample", false, aCanvas); - } - - public void initialize() { - PText text = new PText("Hello World"); - getCanvas().getLayer().addChild(text); - } - - public static void main(String[] args) { - new HelloWorldExample(); - } -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/HierarchyZoomExample.java b/examples/edu/umd/cs/piccolo/examples/HierarchyZoomExample.java deleted file mode 100644 index d7ec773..0000000 --- a/examples/edu/umd/cs/piccolo/examples/HierarchyZoomExample.java +++ /dev/null @@ -1,50 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how to create and zoom over a node hierarchy. - */ -public class HierarchyZoomExample extends PFrame { - - public HierarchyZoomExample() { - this(null); - } - - public HierarchyZoomExample(PCanvas aCanvas) { - super("HierarchyZoomExample", false, aCanvas); - } - - public void initialize() { - PNode root = createHierarchy(10); - getCanvas().getLayer().addChild(root); - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent event) { - getCanvas().getCamera().animateViewToCenterBounds(event.getPickedNode().getGlobalBounds(), true, 500); - } - }); - } - - public PNode createHierarchy(int level) { - PPath result = PPath.createRectangle(0, 0, 100, 100); - - if (level > 0) { - PNode child = createHierarchy(level - 1); - child.scale(0.5); - result.addChild(child); - child.offset(25, 25); - } - - return result; - } - - public static void main(String[] args) { - new HierarchyZoomExample(); - } -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/KeyEventFocusExample.java b/examples/edu/umd/cs/piccolo/examples/KeyEventFocusExample.java deleted file mode 100644 index f2c6d0d..0000000 --- a/examples/edu/umd/cs/piccolo/examples/KeyEventFocusExample.java +++ /dev/null @@ -1,86 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how a node can get the keyboard focus. - */ -public class KeyEventFocusExample extends PFrame { - - public KeyEventFocusExample() { - this(null); - } - - public KeyEventFocusExample(PCanvas aCanvas) { - super("KeyEventFocusExample", false, aCanvas); - } - - public void initialize() { - // Create a green and red node and add them to canvas layer. - PCanvas canvas = getCanvas(); - PNode nodeGreen = PPath.createRectangle(0, 0, 100, 100); - PNode nodeRed = PPath.createRectangle(0, 0, 100, 100); - nodeRed.translate(200, 0); - nodeGreen.setPaint(Color.green); - nodeRed.setPaint(Color.red); - canvas.getLayer().addChild(nodeGreen); - canvas.getLayer().addChild(nodeRed); - - // Add an event handler to the green node the prints "green mousepressed" - // when the mouse is pressed on the green node, and "green keypressed" when - // the key is pressed and the event listener has keyboard focus. - nodeGreen.addInputEventListener(new PBasicInputEventHandler() { - public void keyPressed(PInputEvent event) { - System.out.println("green keypressed"); - } - - // Key board focus is managed by the PInputManager, accessible from - // the root object, or from an incoming PInputEvent. In this case when - // the mouse is pressed in the green node, then the event handler associated - // with it will set the keyfocus to itself. Now it will receive key events - // until someone else gets the focus. - public void mousePressed(PInputEvent event) { - event.getInputManager().setKeyboardFocus(event.getPath()); - System.out.println("green mousepressed"); - } - - public void keyboardFocusGained(PInputEvent event) { - System.out.println("green focus gained"); - } - - public void keyboardFocusLost(PInputEvent event) { - System.out.println("green focus lost"); - } - }); - - // do the same thing with the red node. - nodeRed.addInputEventListener(new PBasicInputEventHandler() { - public void keyPressed(PInputEvent event) { - System.out.println("red keypressed"); - } - - public void mousePressed(PInputEvent event) { - event.getInputManager().setKeyboardFocus(event.getPath()); - System.out.println("red mousepressed"); - } - - public void keyboardFocusGained(PInputEvent event) { - System.out.println("red focus gained"); - } - - public void keyboardFocusLost(PInputEvent event) { - System.out.println("red focus lost"); - } - }); - } - - public static void main(String[] args) { - new KeyEventFocusExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/LayoutExample.java b/examples/edu/umd/cs/piccolo/examples/LayoutExample.java deleted file mode 100644 index d5652ae..0000000 --- a/examples/edu/umd/cs/piccolo/examples/LayoutExample.java +++ /dev/null @@ -1,64 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; -import java.util.Iterator; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PBoundsHandle; - -/** - * This example shows how to create a node that will automatically - * layout its children. - */ -public class LayoutExample extends PFrame { - - public LayoutExample() { - this(null); - } - - public LayoutExample(PCanvas aCanvas) { - super("LayoutExample", false, aCanvas); - } - - public void initialize() { - // Create a new node and override its validateLayoutAfterChildren method so - // that it lays out its children in a row from left to - // right. - - final PNode layoutNode = new PNode() { - public void layoutChildren() { - double xOffset = 0; - double yOffset = 0; - - Iterator i = getChildrenIterator(); - while (i.hasNext()) { - PNode each = (PNode) i.next(); - each.setOffset(xOffset - each.getX(), yOffset); - xOffset += each.getWidth(); - } - } - }; - - layoutNode.setPaint(Color.red); - - // add some children to the layout node. - for (int i = 0; i < 1000; i++) { - // create child to add to the layout node. - PNode each = PPath.createRectangle(0, 0, 100, 80); - - // add the child to the layout node. - layoutNode.addChild(each); - } - - PBoundsHandle.addBoundsHandlesTo(layoutNode.getChild(0)); - - // add layoutNode to the root so it will be displayed. - getCanvas().getLayer().addChild(layoutNode); - } - - public static void main(String[] args) { - new LayoutExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/LensExample.java b/examples/edu/umd/cs/piccolo/examples/LensExample.java deleted file mode 100644 index 17374c2..0000000 --- a/examples/edu/umd/cs/piccolo/examples/LensExample.java +++ /dev/null @@ -1,131 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.Point2D; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.PRoot; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.nodes.PText; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PBoundsHandle; -import edu.umd.cs.piccolox.nodes.PLens; - -/** - * This example shows one way to create and use lens's in Piccolo. - */ -public class LensExample extends PFrame { - - public LensExample() { - this(null); - } - - public LensExample(PCanvas aCanvas) { - super("LensExample", false, aCanvas); - } - - public void initialize() { - PRoot root = getCanvas().getRoot(); - PCamera camera = getCanvas().getCamera(); - PLayer mainLayer = getCanvas().getLayer(); // viewed by the PCanvas camera, the lens is added to this layer. - PLayer sharedLayer = new PLayer(); // viewed by both the lens camera and the PCanvas camera - final PLayer lensOnlyLayer = new PLayer(); // viewed by only the lens camera - - root.addChild(lensOnlyLayer); - root.addChild(sharedLayer); - camera.addLayer(0, sharedLayer); - - final PLens lens = new PLens(); - lens.setBounds(10, 10, 100, 130); - lens.addLayer(0, lensOnlyLayer); - lens.addLayer(1, sharedLayer); - mainLayer.addChild(lens); - PBoundsHandle.addBoundsHandlesTo(lens); - - // Create an event handler that draws squiggles on the first layer of the bottom - // most camera. - PDragSequenceEventHandler squiggleEventHandler = new PDragSequenceEventHandler() { - protected PPath squiggle; - public void startDrag(PInputEvent e) { - super.startDrag(e); - Point2D p = e.getPosition(); - squiggle = new PPath(); - squiggle.moveTo((float)p.getX(), (float)p.getY()); - - // add squiggles to the first layer of the bottom camera. In the case of the - // lens these squiggles will be added to the layer that is only visible by the lens, - // In the case of the canvas camera the squiggles will be added to the shared layer - // viewed by both the canvas camera and the lens. - e.getCamera().getLayer(0).addChild(squiggle); - } - - public void drag(PInputEvent e) { - super.drag(e); - updateSquiggle(e); - } - - public void endDrag(PInputEvent e) { - super.endDrag(e); - updateSquiggle(e); - squiggle = null; - } - - public void updateSquiggle(PInputEvent aEvent) { - Point2D p = aEvent.getPosition(); - squiggle.lineTo((float)p.getX(), (float)p.getY()); - } - }; - - // add the squiggle event handler to both the lens and the - // canvas camera. - lens.getCamera().addInputEventListener(squiggleEventHandler); - camera.addInputEventListener(squiggleEventHandler); - - // make sure that the event handler consumes events so that it doesn't - // conflic with other event handlers or with itself (since its added to two - // event sources). - squiggleEventHandler.getEventFilter().setMarksAcceptedEventsAsHandled(true); - - // remove default event handlers, not really nessessary since the squiggleEventHandler - // consumes everything anyway, but still good to do. - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); - - // create a node that is viewed both by the main camera and by the - // lens. Note that in its paint method it checks to see which camera - // is painting it, and if its the lens uses a different color. - PNode sharedNode = new PNode() { - protected void paint(PPaintContext paintContext) { - if (paintContext.getCamera() == lens.getCamera()) { - Graphics2D g2 = paintContext.getGraphics(); - g2.setPaint(Color.RED); - g2.fill(getBoundsReference()); - } else { - super.paint(paintContext); - } - } - }; - sharedNode.setPaint(Color.GREEN); - sharedNode.setBounds(0, 0, 100, 200); - sharedNode.translate(200, 200); - sharedLayer.addChild(sharedNode); - - PText label = new PText("Move the lens \n (by dragging title bar) over the green rectangle, and it will appear red. press and drag the mouse on the canvas and it will draw squiggles. press and drag the mouse over the lens and drag squiggles that are only visible through the lens."); - label.setConstrainWidthToTextWidth(false); - label.setConstrainHeightToTextHeight(false); - label.setBounds(200, 100, 200, 200); - - sharedLayer.addChild(label); - } - - public static void main(String[] args) { - new LensExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/NavigationExample.java b/examples/edu/umd/cs/piccolo/examples/NavigationExample.java deleted file mode 100644 index cb7ef22..0000000 --- a/examples/edu/umd/cs/piccolo/examples/NavigationExample.java +++ /dev/null @@ -1,42 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.BasicStroke; -import java.awt.Color; -import java.util.Random; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.event.PNavigationEventHandler; - -public class NavigationExample extends PFrame { - - public NavigationExample() { - this(null); - } - - public NavigationExample(PCanvas aCanvas) { - super("NavigationExample", false, aCanvas); - } - - public void initialize() { - PLayer layer = getCanvas().getLayer(); - - Random random = new Random(); - for (int i = 0; i < 1000; i++) { - PPath each = PPath.createRectangle(0, 0, 100, 80); - each.scale(random.nextFloat() * 2); - each.offset(random.nextFloat() * 10000, random.nextFloat() * 10000); - each.setPaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); - each.setStroke(new BasicStroke(1 + (10 * random.nextFloat()))); - each.setStrokePaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); - layer.addChild(each); - } - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(new PNavigationEventHandler()); - } - - public static void main(String[] args) { - new NavigationExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/NodeCacheExample.java b/examples/edu/umd/cs/piccolo/examples/NodeCacheExample.java deleted file mode 100644 index 744fe06..0000000 --- a/examples/edu/umd/cs/piccolo/examples/NodeCacheExample.java +++ /dev/null @@ -1,47 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.BasicStroke; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.nodes.PNodeCache; - -public class NodeCacheExample extends PFrame { - - public NodeCacheExample() { - this(null); - } - - public NodeCacheExample(PCanvas aCanvas) { - super("NodeCacheExample", false, aCanvas); - } - - public void initialize() { - PCanvas canvas = getCanvas(); - - PPath circle = PPath.createEllipse(0, 0, 100, 100); - circle.setStroke(new BasicStroke(10)); - circle.setPaint(Color.YELLOW); - - PPath rectangle = PPath.createRectangle(-100, -50, 100, 100); - rectangle.setStroke(new BasicStroke(15)); - rectangle.setPaint(Color.ORANGE); - - PNodeCache cache = new PNodeCache(); - cache.addChild(circle); - cache.addChild(rectangle); - - cache.invalidateCache(); - - canvas.getLayer().addChild(cache); - canvas.removeInputEventListener(canvas.getPanEventHandler()); - canvas.addInputEventListener(new PDragEventHandler()); - } - - public static void main(String[] args) { - new NodeCacheExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/NodeEventExample.java b/examples/edu/umd/cs/piccolo/examples/NodeEventExample.java deleted file mode 100644 index 10369d1..0000000 --- a/examples/edu/umd/cs/piccolo/examples/NodeEventExample.java +++ /dev/null @@ -1,99 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; -import java.awt.geom.Dimension2D; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how to make a node handle events. - */ -public class NodeEventExample extends PFrame { - - public NodeEventExample() { - this(null); - } - - public NodeEventExample(PCanvas aCanvas) { - super("NodeEventExample", false, aCanvas); - } - - public void initialize() { - PLayer layer = getCanvas().getLayer(); - - // create a new node and override some of the event handling - // methods so that the node changes to orange when the mouse (Button 1) is - // pressed on the node, and changes back to green when the mouse - // is released. Also when the mouse is dragged the node updates its - // position so that the node is "dragged". Note that this only serves - // as a simple example, most of the time dragging nodes is best done - // with the PDragEventHandler, but this shows another way to do it. - // - // Note that each of these methods marks the event as handled. This is so that - // when the node is being dragged the zoom and pan event handles - // (that are installed by default) do not also operate, but they will - // still respond to events that are not handled by the node. (try to uncomment - // the aEvent.setHandled() calls and see what happens. - final PNode aNode = new PNode(); - aNode.addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent aEvent) { - aNode.setPaint(Color.orange); - printEventCoords(aEvent); - aEvent.setHandled(true); - } - - public void mouseDragged(PInputEvent aEvent) { - Dimension2D delta = aEvent.getDeltaRelativeTo(aNode); - aNode.translate(delta.getWidth(), delta.getHeight()); - printEventCoords(aEvent); - aEvent.setHandled(true); - } - - public void mouseReleased(PInputEvent aEvent) { - aNode.setPaint(Color.green); - printEventCoords(aEvent); - aEvent.setHandled(true); - } - - // Note this slows things down a lot, comment it out to see how the normal - // speed of things is. - // - // For fun the coords of each event that the node handles are printed out. - // This can help to understand how coordinate systems work. Notice that when - // the example first starts all the values for (canvas, global, and local) are - // equal. But once you drag the node then the local coordinates become different - // then the screen and global coordinates. When you pan or zoom then the screen - // coordinates become different from the global coordinates. - public void printEventCoords(PInputEvent aEvent) { - System.out.println("Canvas Location: " + aEvent.getCanvasPosition()); - //System.out.println("Global Location: " + aEvent.getGlobalLocation()); - System.out.println("Local Location: " + aEvent.getPositionRelativeTo(aNode)); - System.out.println("Canvas Delta: " + aEvent.getCanvasDelta()); - //System.out.println("Global Delta: " + aEvent.getGlobalDelta()); - System.out.println("Local Delta: " + aEvent.getDeltaRelativeTo(aNode)); - } - }); - aNode.setBounds(0, 0, 200, 200); - aNode.setPaint(Color.green); - - // By default the filter accepts all events, but here we constrain the kinds of - // events that aNode receives to button 1 events. Comment this line out and then - // you will be able to drag the node with any mouse button. - //aNode.setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); - - // add another node to the canvas that does not handle events as a reference - // point, so that we can make sure that our green node is getting dragged. - layer.addChild(PPath.createRectangle(0, 0, 100, 80)); - layer.addChild(aNode); - } - - public static void main(String[] args) { - new NodeEventExample(); - } -} - diff --git a/examples/edu/umd/cs/piccolo/examples/NodeExample.java b/examples/edu/umd/cs/piccolo/examples/NodeExample.java deleted file mode 100644 index 033467e..0000000 --- a/examples/edu/umd/cs/piccolo/examples/NodeExample.java +++ /dev/null @@ -1,222 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PImage; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.nodes.PText; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how to create and manipulate nodes. - */ -public class NodeExample extends PFrame { - - boolean fIsPressed = false; - - public NodeExample() { - this(null); - } - - public NodeExample(PCanvas aCanvas) { - super("NodeExample", false, aCanvas); - } - - public void initialize() { - nodeDemo(); - createNodeUsingExistingClasses(); - subclassExistingClasses(); - composeOtherNodes(); - createCustomNode(); - - // Last of all lets remove the default pan event handler, and add a - // drag event handler instead. This way you will be able to drag the - // nodes around with the mouse. - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(new PDragEventHandler()); - } - - // This method demonstrates the kinds of things that can be done with any node. - public void nodeDemo() { - PLayer layer = getCanvas().getLayer(); - PNode aNode = PPath.createRectangle(0, 0, 100, 80); - - // A node needs to be a descendent of the root to be displayed on the screen. - layer.addChild(aNode); - - // The default color for a node is blue, but you can change that with - // the setPaint method. - aNode.setPaint(Color.red); - - // A node can have children nodes added to it. - aNode.addChild(PPath.createRectangle(0, 0, 100, 80)); - - // The base bounds of a node is easy to change. Note that changing the base - // bounds of a node will not change it's children. - aNode.setBounds(-10, -10, 200, 110); - - // Each node has a transform that can be used to transform the node, and - // all its children on the screen. - aNode.translate(100, 100); - aNode.scale(1.5); - aNode.rotate(45); - - // The transparency of any node can be set, this transparency will be - // applied to any of the nodes children as well. - aNode.setTransparency(0.75f); - - // Its easy to copy nodes. - PNode aCopy = (PNode) aNode.clone(); - - // Make is so that the copies children are not pickable. For this example - // that means you will not be able to grab the child and remove it from - // its parent. - aNode.setChildrenPickable(false); - - // Change the look of the copy - aNode.setPaint(Color.GREEN); - aNode.setTransparency(1.0f); - - // Let's add the copy to the root, and translate it so that it does not - // cover the original node. - layer.addChild(aCopy); - aCopy.setOffset(0, 0); - aCopy.rotate(-45); - } - - // So far we have just been using PNode, but of course PNode has many - // subclasses that you can try out to. - public void createNodeUsingExistingClasses() { - PLayer layer = getCanvas().getLayer(); - layer.addChild(PPath.createEllipse(0, 0, 100, 100)); - layer.addChild(PPath.createRectangle(0, 100, 100, 100)); - layer.addChild(new PText("Hello World")); - - // Here we create an image node that displays a thumbnail - // image of the root node. Note that you can easily get a thumbnail - // of any node by using PNode.toImage(). - PImage image = new PImage(layer.toImage(300, 300, null)); - layer.addChild(image); - } - - // Another way to create nodes is to customize other nodes that already - // exist. Here we create an ellipse, except when you press the mouse on - // this ellipse it turns into a square, when you release the mouse it - // goes back to being an ellipse. - public void subclassExistingClasses() { - final PNode n = new PPath(new Ellipse2D.Float(0, 0, 100, 80)) { - - public void paint(PPaintContext aPaintContext) { - if (fIsPressed) { - // if mouse is pressed draw self as a square. - Graphics2D g2 = aPaintContext.getGraphics(); - g2.setPaint(getPaint()); - g2.fill(getBoundsReference()); - } else { - // if mouse is not pressed draw self normally. - super.paint(aPaintContext); - } - } - }; - - n.addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent aEvent) { - super.mousePressed(aEvent); - fIsPressed = true; - n.invalidatePaint(); // this tells the framework that the node needs to be redisplayed. - } - - public void mouseReleased(PInputEvent aEvent) { - super.mousePressed(aEvent); - fIsPressed = false; - n.invalidatePaint(); // this tells the framework that the node needs to be redisplayed. - } - }); - - n.setPaint(Color.ORANGE); - getCanvas().getLayer().addChild(n); - } - - // Here a new "face" node is created. But instead of drawing the face directly - // using Graphics2D we compose the face from other nodes. - public void composeOtherNodes() { - PNode myCompositeFace = PPath.createRectangle(0, 0, 100, 80); - - // create parts for the face. - PNode eye1 = PPath.createEllipse(0, 0, 20, 20); - eye1.setPaint(Color.YELLOW); - PNode eye2 = (PNode) eye1.clone(); - PNode mouth = PPath.createRectangle(0, 0, 40, 20); - mouth.setPaint(Color.BLACK); - - // add the face parts - myCompositeFace.addChild(eye1); - myCompositeFace.addChild(eye2); - myCompositeFace.addChild(mouth); - - // don't want anyone grabbing out our eye's. - myCompositeFace.setChildrenPickable(false); - - // position the face parts. - eye2.translate(25, 0); - mouth.translate(0, 30); - - // set the face bounds so that it neatly contains the face parts. - PBounds b = myCompositeFace.getUnionOfChildrenBounds(null); - myCompositeFace.setBounds(b.inset(-5, -5)); - - // opps it to small, so scale it up. - myCompositeFace.scale(1.5); - - getCanvas().getLayer().addChild(myCompositeFace); - } - - // Here a completely new kind of node, a grid node" is created. We do - // all the drawing ourselves here instead of passing the work off to - // other parts of the framework. - public void createCustomNode() { - PNode n = new PNode() { - public void paint(PPaintContext aPaintContext) { - double bx = getX(); - double by = getY(); - double rightBorder = bx + getWidth(); - double bottomBorder = by + getHeight(); - - Line2D line = new Line2D.Double(); - Graphics2D g2 = aPaintContext.getGraphics(); - - g2.setStroke(new BasicStroke(0)); - g2.setPaint(getPaint()); - - // draw vertical lines - for (double x = bx; x < rightBorder; x += 5) { - line.setLine(x, by, x, bottomBorder); - g2.draw(line); - } - - for (double y = by; y < bottomBorder; y += 5) { - line.setLine(bx, y, rightBorder, y); - g2.draw(line); - } - } - }; - n.setBounds(0, 0, 100, 80); - n.setPaint(Color.black); - getCanvas().getLayer().addChild(n); - } - - public static void main(String[] args) { - new NodeExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/NodeLinkExample.java b/examples/edu/umd/cs/piccolo/examples/NodeLinkExample.java deleted file mode 100644 index d22df55..0000000 --- a/examples/edu/umd/cs/piccolo/examples/NodeLinkExample.java +++ /dev/null @@ -1,74 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.geom.Line2D; -import java.awt.geom.Point2D; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * Simple example showing one way to create a link between two nodes. - * - * @author Jesse Grosjean - */ -public class NodeLinkExample extends PFrame { - - PNode node1; - PNode node2; - PPath link; - - public NodeLinkExample() { - this(null); - } - - public NodeLinkExample(PCanvas aCanvas) { - super("NodeLinkExample", false, aCanvas); - } - - public void initialize() { - PCanvas canvas = getCanvas(); - - canvas.removeInputEventListener(canvas.getPanEventHandler()); - canvas.addInputEventListener(new PDragEventHandler()); - - PNode layer = canvas.getLayer(); - - node1 = PPath.createEllipse(0, 0, 100, 100); - node2 = PPath.createEllipse(0, 0, 100, 100); - link = PPath.createLine(50, 50, 50, 50); - link.setPickable(false); - layer.addChild(node1); - layer.addChild(node2); - layer.addChild(link); - - node2.translate(200, 200); - - node1.addPropertyChangeListener(PNode.PROPERTY_FULL_BOUNDS, new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent arg0) { - updateLink(); - } - }); - - node2.addPropertyChangeListener(PNode.PROPERTY_FULL_BOUNDS, new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent arg0) { - updateLink(); - } - }); - } - - public void updateLink() { - Point2D p1 = node1.getFullBoundsReference().getCenter2D(); - Point2D p2 = node2.getFullBoundsReference().getCenter2D(); - Line2D line = new Line2D.Double(p1.getX(), p1.getY(), p2.getX(), p2.getY()); - link.setPathTo(line); - } - - public static void main(String[] args) { - new NodeLinkExample(); - } -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/PSwingExample.java b/examples/edu/umd/cs/piccolo/examples/PSwingExample.java deleted file mode 100644 index 8dd7ba7..0000000 --- a/examples/edu/umd/cs/piccolo/examples/PSwingExample.java +++ /dev/null @@ -1,48 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.pswing.PSwing; -import edu.umd.cs.piccolox.pswing.PSwingCanvas; - -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -/** - * Demonstrates the use of PSwing in a Piccolo application. - */ - -public class PSwingExample extends PFrame { - - public PSwingExample() { - this( new PSwingCanvas() ); - } - - public PSwingExample( PCanvas aCanvas ) { - super( "PSwingExample", false, aCanvas ); - } - - public void initialize() { - PSwingCanvas pswingCanvas = (PSwingCanvas)getCanvas(); - PLayer l = pswingCanvas.getLayer(); - - JSlider js = new JSlider( 0, 100 ); - js.addChangeListener( new ChangeListener() { - public void stateChanged( ChangeEvent e ) { - System.out.println( "e = " + e ); - } - } ); - js.setBorder( BorderFactory.createTitledBorder( "Test JSlider" ) ); - PSwing pSwing = new PSwing( js ); - pSwing.translate( 100, 100 ); - l.addChild( pSwing ); - - pswingCanvas.setPanEventHandler( null ); - } - - public static void main( String[] args ) { - new PSwingExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/PanToExample.java b/examples/edu/umd/cs/piccolo/examples/PanToExample.java deleted file mode 100644 index 24a738f..0000000 --- a/examples/edu/umd/cs/piccolo/examples/PanToExample.java +++ /dev/null @@ -1,73 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.util.Random; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * Click on a node and the camera will pan the minimum distance to bring that node fully into - * the cameras view. - */ -public class PanToExample extends PFrame { - - public PanToExample() { - this(null); - } - - public PanToExample(PCanvas aCanvas) { - super("PanToExample", false, aCanvas); - } - - public void initialize() { - - PPath eacha = PPath.createRectangle(50, 50, 300, 300); - eacha.setPaint(Color.red); - getCanvas().getLayer().addChild(eacha); - - eacha = PPath.createRectangle(-50, -50, 100, 100); - eacha.setPaint(Color.green); - getCanvas().getLayer().addChild(eacha); - - eacha = PPath.createRectangle(350, 350, 100, 100); - eacha.setPaint(Color.green); - getCanvas().getLayer().addChild(eacha); - - - getCanvas().getCamera().addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent event) { - if (!(event.getPickedNode() instanceof PCamera)) { - event.setHandled(true); - getCanvas().getCamera().animateViewToPanToBounds(event.getPickedNode().getGlobalFullBounds(), 500); - } - } - }); - - PLayer layer = getCanvas().getLayer(); - - Random random = new Random(); - for (int i = 0; i < 1000; i++) { - PPath each = PPath.createRectangle(0, 0, 100, 80); - each.scale(random.nextFloat() * 2); - each.offset(random.nextFloat() * 10000, random.nextFloat() * 10000); - each.setPaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); - each.setStroke(new BasicStroke(1 + (10 * random.nextFloat()))); - each.setStrokePaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); - layer.addChild(each); - } - - - getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); - } - - public static void main(String[] args) { - new PanToExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/PathExample.java b/examples/edu/umd/cs/piccolo/examples/PathExample.java deleted file mode 100644 index 14e5b95..0000000 --- a/examples/edu/umd/cs/piccolo/examples/PathExample.java +++ /dev/null @@ -1,54 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.BasicStroke; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PStickyHandleManager; -import edu.umd.cs.piccolox.util.PFixedWidthStroke; - -public class PathExample extends PFrame { - - public PathExample() { - this(null); - } - - public PathExample(PCanvas aCanvas) { - super("PathExample", false, aCanvas); - } - - public void initialize() { - PPath n1 = PPath.createRectangle(0, 0, 100, 80); - PPath n2 = PPath.createEllipse(100, 100, 200, 34); - PPath n3 = new PPath(); - n3.moveTo(0, 0); - n3.lineTo(20, 40); - n3.lineTo(10, 200); - n3.lineTo(155.444f, 33.232f); - n3.closePath(); - n3.setPaint(Color.yellow); - - n1.setStroke(new BasicStroke(5)); - n1.setStrokePaint(Color.red); - n2.setStroke(new PFixedWidthStroke()); - n3.setStroke(new PFixedWidthStroke()); -// n3.setStroke(null); - - getCanvas().getLayer().addChild(n1); - getCanvas().getLayer().addChild(n2); - getCanvas().getLayer().addChild(n3); - - // create a set of bounds handles for reshaping n3, and make them - // sticky relative to the getCanvas().getCamera(). - new PStickyHandleManager(getCanvas().getCamera(), n3); - - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(new PDragEventHandler()); - } - - public static void main(String[] args) { - new PathExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/PositionExample.java b/examples/edu/umd/cs/piccolo/examples/PositionExample.java deleted file mode 100644 index 94d698a..0000000 --- a/examples/edu/umd/cs/piccolo/examples/PositionExample.java +++ /dev/null @@ -1,40 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -public class PositionExample extends PFrame { - - public PositionExample() { - this(null); - } - - public PositionExample(PCanvas aCanvas) { - super("PositionExample", false, aCanvas); - } - - public void initialize() { - PNode n1 = PPath.createRectangle(0, 0, 100, 80); - PNode n2 = PPath.createRectangle(0, 0, 100, 80); - - getCanvas().getLayer().addChild(n1); - getCanvas().getLayer().addChild(n2); - - n2.scale(2.0); - n2.rotate(Math.toRadians(90)); - //n2.setScale(2.0); - //n2.setScale(1.0); - n2.scale(0.5); - n2.setPaint(Color.red); - - n1.offset(100, 0); - n2.offset(100, 0); - } - - public static void main(String[] args) { - new PositionExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/PositionPathActivityExample.java b/examples/edu/umd/cs/piccolo/examples/PositionPathActivityExample.java deleted file mode 100644 index 9f6dfdc..0000000 --- a/examples/edu/umd/cs/piccolo/examples/PositionPathActivityExample.java +++ /dev/null @@ -1,56 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.geom.Arc2D; -import java.awt.geom.GeneralPath; - -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.activities.PPositionPathActivity; - -/** - * This example shows how create a simple acitivty to animate a node along a - * general path. - */ -public class PositionPathActivityExample extends PFrame { - - public PositionPathActivityExample() { - super(); - } - - public void initialize() { - PLayer layer = getCanvas().getLayer(); - final PNode animatedNode = PPath.createRectangle(0, 0, 100, 80); - layer.addChild(animatedNode); - - // create animation path - GeneralPath path = new GeneralPath(); - path.moveTo(0, 0); - path.lineTo(300, 300); - path.lineTo(300, 0); - path.append(new Arc2D.Float(0, 0, 300, 300, 90, -90, Arc2D.OPEN), true); - path.closePath(); - - // create node to display animation path - PPath ppath = new PPath(path); - layer.addChild(ppath); - - // create activity to run animation. - PPositionPathActivity positionPathActivity = new PPositionPathActivity(5000, 0, new PPositionPathActivity.Target() { - public void setPosition(double x, double y) { - animatedNode.setOffset(x, y); - } - }); -// positionPathActivity.setSlowInSlowOut(false); - positionPathActivity.setPositions(path); - positionPathActivity.setLoopCount(Integer.MAX_VALUE); - - // add the activity. - animatedNode.addActivity(positionPathActivity); - } - - public static void main(String[] args) { - new PositionPathActivityExample(); - } -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/PulseExample.java b/examples/edu/umd/cs/piccolo/examples/PulseExample.java deleted file mode 100644 index 1b1fee4..0000000 --- a/examples/edu/umd/cs/piccolo/examples/PulseExample.java +++ /dev/null @@ -1,82 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.PRoot; -import edu.umd.cs.piccolo.activities.PActivityScheduler; -import edu.umd.cs.piccolo.activities.PColorActivity; -import edu.umd.cs.piccolo.activities.PInterpolatingActivity; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how to set up interpolating activities that repeat. For - * example it shows how to create a rectangle whos color pulses. - * - * @author jesse - */ -public class PulseExample extends PFrame { - - public PulseExample() { - this(null); - } - - public PulseExample(PCanvas aCanvas) { - super("PulseExample", false, aCanvas); - } - - public void initialize() { - PRoot root = getCanvas().getRoot(); - PLayer layer = getCanvas().getLayer(); - PActivityScheduler scheduler = root.getActivityScheduler(); - - final PNode singlePulse = PPath.createRectangle(0, 0, 100, 80); - final PPath repeatePulse = PPath.createRectangle(100, 80, 100, 80); - final PNode repeateReversePulse = PPath.createRectangle(200, 160, 100, 80); - - layer.addChild(singlePulse); - layer.addChild(repeatePulse); - layer.addChild(repeateReversePulse); - - // animate from source to destination color in one second, - PColorActivity singlePulseActivity = new PColorActivity(1000, 0, 1, PInterpolatingActivity.SOURCE_TO_DESTINATION, new PColorActivity.Target() { - public Color getColor() { - return (Color) singlePulse.getPaint(); - } - public void setColor(Color color) { - singlePulse.setPaint(color); - } - }, Color.ORANGE); - - // animate from source to destination color in one second, loop 5 times - PColorActivity repeatPulseActivity = new PColorActivity(1000, 0, 5, PInterpolatingActivity.SOURCE_TO_DESTINATION, new PColorActivity.Target() { - public Color getColor() { - return (Color) repeatePulse.getPaint(); - } - public void setColor(Color color) { - repeatePulse.setPaint(color); - } - }, Color.BLUE); - - // animate from source to destination to source color in one second, loop 10 times - PColorActivity repeatReversePulseActivity = new PColorActivity(500, 0, 10, PInterpolatingActivity.SOURCE_TO_DESTINATION_TO_SOURCE, new PColorActivity.Target() { - public Color getColor() { - return (Color) repeateReversePulse.getPaint(); - } - public void setColor(Color color) { - repeateReversePulse.setPaint(color); - } - }, Color.GREEN); - - scheduler.addActivity(singlePulseActivity); - scheduler.addActivity(repeatPulseActivity); - scheduler.addActivity(repeatReversePulseActivity); - } - - public static void main(String[] args) { - new PulseExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/ScrollingExample.java b/examples/edu/umd/cs/piccolo/examples/ScrollingExample.java deleted file mode 100644 index 1d3a0a5..0000000 --- a/examples/edu/umd/cs/piccolo/examples/ScrollingExample.java +++ /dev/null @@ -1,223 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Point; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.util.Iterator; - -import javax.swing.ButtonGroup; -import javax.swing.JToggleButton; -import javax.swing.JToolBar; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PAffineTransform; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.swing.PDefaultScrollDirector; -import edu.umd.cs.piccolox.swing.PScrollDirector; -import edu.umd.cs.piccolox.swing.PScrollPane; -import edu.umd.cs.piccolox.swing.PViewport; - -/** - * This creates a simple scene and allows switching between - * traditional scrolling where the scrollbars control the view - * and alternate scrolling where the scrollbars control the - * document. In laymans terms - in traditional window scrolling the stuff - * in the window moves in the opposite direction of the scroll bars and in - * document scrolling the stuff moves in the same direction as the scrollbars. - * - * Toggle buttons are provided to toggle between these two types - * of scrolling. - * - * @author Lance Good - * @author Ben Bederson - */ -public class ScrollingExample extends PFrame { - - public ScrollingExample() { - this(null); - } - - public ScrollingExample(PCanvas aCanvas) { - super("ScrollingExample", false, aCanvas); - } - - public void initialize() { - final PCanvas canvas = getCanvas(); - - final PScrollPane scrollPane = new PScrollPane(canvas); - getContentPane().add(scrollPane); - - final PViewport viewport = (PViewport) scrollPane.getViewport(); - final PScrollDirector windowSD = viewport.getScrollDirector(); - final PScrollDirector documentSD = new DocumentScrollDirector(); - - // Make some rectangles on the surface so we can see where we are - for (int x = 0; x < 20; x++) { - for (int y = 0; y < 20; y++) { - if (((x + y) % 2) == 0) { - PPath path = PPath.createRectangle(50 * x, 50 * y, 40, 40); - path.setPaint(Color.blue); - path.setStrokePaint(Color.black); - canvas.getLayer().addChild(path); - } - else if (((x + y) % 2) == 1) { - PPath path = PPath.createEllipse(50 * x, 50 * y, 40, 40); - path.setPaint(Color.blue); - path.setStrokePaint(Color.black); - canvas.getLayer().addChild(path); - } - } - } - - // Now, create the toolbar - JToolBar toolBar = new JToolBar(); - JToggleButton window = new JToggleButton("Window Scrolling"); - JToggleButton document = new JToggleButton("Document Scrolling"); - ButtonGroup bg = new ButtonGroup(); - bg.add(window); - bg.add(document); - toolBar.add(window); - toolBar.add(document); - toolBar.setFloatable(false); - window.setSelected(true); - window.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - viewport.setScrollDirector(windowSD); - viewport.fireStateChanged(); - scrollPane.revalidate(); - } - }); - document.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - viewport.setScrollDirector(documentSD); - viewport.fireStateChanged(); - scrollPane.revalidate(); - } - }); - getContentPane().add(toolBar, BorderLayout.NORTH); - - getContentPane().validate(); - } - - /** - * A modified scroll director that performs document based scroling - * rather than window based scrolling (ie. the scrollbars act in - * the inverse direction as normal) - */ - public class DocumentScrollDirector extends PDefaultScrollDirector { - - /** - * Get the View position given the specified camera bounds - modified - * such that: - * - * Rather than finding the distance from the upper left corner - * of the window to the upper left corner of the document - - * we instead find the distance from the lower right corner - * of the window to the upper left corner of the document - * THEN we subtract that value from total document width so - * that the position is inverted - * - * @param viewBounds The bounds for which the view position will be computed - * @return The view position - */ - public Point getViewPosition(Rectangle2D viewBounds) { - Point pos = new Point(); - if (camera != null) { - // First we compute the union of all the layers - PBounds layerBounds = new PBounds(); - java.util.List layers = camera.getLayersReference(); - for (Iterator i = layers.iterator(); i.hasNext();) { - PLayer layer = (PLayer) i.next(); - layerBounds.add(layer.getFullBoundsReference()); - } - - // Then we put the bounds into camera coordinates and - // union the camera bounds - camera.viewToLocal(layerBounds); - layerBounds.add(viewBounds); - - // Rather than finding the distance from the upper left corner - // of the window to the upper left corner of the document - - // we instead find the distance from the lower right corner - // of the window to the upper left corner of the document - // THEN we measure the offset from the lower right corner - // of the document - pos.setLocation( - (int) (layerBounds.getWidth() - (viewBounds.getX() + viewBounds.getWidth() - layerBounds.getX()) + 0.5), - (int) (layerBounds.getHeight() - (viewBounds.getY() + viewBounds.getHeight() - layerBounds.getY()) + 0.5)); - } - - return pos; - - } - - /** - * We do the same thing we did in getViewPosition above to flip the - * document-window position relationship - * - * @param x The new x position - * @param y The new y position - */ - public void setViewPosition(double x, double y) { - if (camera != null) { - // If a scroll is in progress - we ignore new scrolls - - // if we didn't, since the scrollbars depend on the camera location - // we can end up with an infinite loop - if (!scrollInProgress) { - scrollInProgress = true; - - // Get the union of all the layers' bounds - PBounds layerBounds = new PBounds(); - java.util.List layers = camera.getLayersReference(); - for (Iterator i = layers.iterator(); i.hasNext();) { - PLayer layer = (PLayer) i.next(); - layerBounds.add(layer.getFullBoundsReference()); - } - - PAffineTransform at = camera.getViewTransform(); - at.transform(layerBounds,layerBounds); - - // Union the camera view bounds - PBounds viewBounds = camera.getBoundsReference(); - layerBounds.add(viewBounds); - - // Now find the new view position in view coordinates - - // This is basically the distance from the lower right - // corner of the window to the upper left corner of the - // document - // We then measure the offset from the lower right corner - // of the document - Point2D newPoint = - new Point2D.Double( - layerBounds.getX() + layerBounds.getWidth() - (x + viewBounds.getWidth()), - layerBounds.getY() + layerBounds.getHeight() - (y + viewBounds.getHeight())); - - // Now transform the new view position into global coords - camera.localToView(newPoint); - - // Compute the new matrix values to put the camera at the - // correct location - double newX = - (at.getScaleX() * newPoint.getX() + at.getShearX() * newPoint.getY()); - double newY = - (at.getShearY() * newPoint.getX() + at.getScaleY() * newPoint.getY()); - - at.setTransform(at.getScaleX(), at.getShearY(), at.getShearX(), at.getScaleY(), newX, newY); - - // Now actually set the camera's transform - camera.setViewTransform(at); - scrollInProgress = false; - } - } - } - } - - public static void main(String[] args) { - new ScrollingExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/SelectionExample.java b/examples/edu/umd/cs/piccolo/examples/SelectionExample.java deleted file mode 100644 index 5e120eb..0000000 --- a/examples/edu/umd/cs/piccolo/examples/SelectionExample.java +++ /dev/null @@ -1,58 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.event.PNotification; -import edu.umd.cs.piccolox.event.PNotificationCenter; -import edu.umd.cs.piccolox.event.PSelectionEventHandler; - -/** - * This example shows how the selection event handler works. - * It creates a bunch of objects that can be selected. - */ -public class SelectionExample extends PFrame { - - public SelectionExample() { - this(null); - } - - public SelectionExample(PCanvas aCanvas) { - super("SelectionExample", false, aCanvas); - } - - public void initialize() { - for (int i=0; i<5; i++) { - for (int j=0; j<5; j++) { - PNode rect = PPath.createRectangle(i*60, j*60, 50, 50); - rect.setPaint(Color.blue); - getCanvas().getLayer().addChild(rect); - } - } - - // Turn off default navigation event handlers - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); - - // Create a selection event handler - PSelectionEventHandler selectionEventHandler = new PSelectionEventHandler(getCanvas().getLayer(), getCanvas().getLayer()); - getCanvas().addInputEventListener(selectionEventHandler); - getCanvas().getRoot().getDefaultInputManager().setKeyboardFocus(selectionEventHandler); - - PNotificationCenter.defaultCenter().addListener(this, - "selectionChanged", - PSelectionEventHandler.SELECTION_CHANGED_NOTIFICATION, - selectionEventHandler); - } - - public void selectionChanged(PNotification notfication) { - System.out.println("selection changed"); - } - - public static void main(String[] args) { - new SelectionExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/SliderExample.java b/examples/edu/umd/cs/piccolo/examples/SliderExample.java deleted file mode 100644 index fbfa5ed..0000000 --- a/examples/edu/umd/cs/piccolo/examples/SliderExample.java +++ /dev/null @@ -1,135 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import edu.umd.cs.piccolox.pswing.PSwing; -import edu.umd.cs.piccolox.pswing.PSwingCanvas; -import edu.umd.cs.piccolox.swing.PScrollPane; - -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - - -/** - * Tests a set of Sliders and Checkboxes in panels. - * - * @author Martin Clifford - */ -public class SliderExample extends JFrame { - private PSwingCanvas canvas; - private PScrollPane scrollPane; - private JTabbedPane tabbedPane; - private PSwing swing; - - public SliderExample() { - // Create main panel - JPanel mainPanel = new JPanel( false ); - // Create a tabbed pane - tabbedPane = new JTabbedPane(); - tabbedPane.setPreferredSize( new Dimension( 700, 700 ) ); - // Add tabbed pane to main panel - mainPanel.add( tabbedPane ); - // Set the frame contents - getContentPane().add( mainPanel ); - - // Create a canvas - canvas = new PSwingCanvas(); - canvas.setPreferredSize( new Dimension( 700, 700 ) ); - // Create a scroll pane for the canvas - scrollPane = new PScrollPane( canvas ); - // Create a new tab for the tabbed pane - tabbedPane.add( "Tab 1", scrollPane ); - - // Create the contents for "Tab 1" - JPanel tabPanel = new JPanel( false ); - tabPanel.setLayout( null ); - tabPanel.setPreferredSize( new Dimension( 700, 700 ) ); - // Populate the tab panel with four instances of nested panel. - JPanel panel; - panel = createNestedPanel(); - panel.setSize( new Dimension( 250, 250 ) ); - panel.setLocation( 0, 0 ); - tabPanel.add( panel ); - panel = createNestedPanel(); - panel.setSize( new Dimension( 250, 250 ) ); - panel.setLocation( 0, 350 ); - tabPanel.add( panel ); - panel = createNestedPanel(); - panel.setSize( new Dimension( 250, 250 ) ); - panel.setLocation( 350, 0 ); - tabPanel.add( panel ); - panel = createNestedPanel(); - panel.setSize( new Dimension( 250, 250 ) ); - panel.setLocation( 350, 350 ); - tabPanel.add( panel ); - // Add the default zoom button - JButton buttonPreset = new JButton( "Zoom = 100%" ); - buttonPreset.addActionListener( new ActionListener() { - public void actionPerformed( ActionEvent e ) { - canvas.getCamera().setViewScale( 1.0 ); - canvas.getCamera().setViewOffset( 0, 0 ); - } - } ); - buttonPreset.setSize( new Dimension( 120, 25 ) ); - buttonPreset.setLocation( 240, 285 ); - tabPanel.add( buttonPreset ); - // Create a pswing object for the tab panel - swing = new PSwing( tabPanel ); - swing.translate( 0, 0 ); - // Add the pswing object to the canvas - canvas.getLayer().addChild( swing ); - // Turn off default pan event handling - canvas.setPanEventHandler( null ); - - // Set up basic frame - setDefaultCloseOperation( javax.swing.WindowConstants.DISPOSE_ON_CLOSE ); - setTitle( "Slider Example" ); - setResizable( true ); - setBackground( null ); - pack(); - setVisible( true ); - } - - private JPanel createNestedPanel() { - // A panel MUST be created with double buffering off - JPanel panel; - JLabel label; - panel = new JPanel( false ); - panel.setLayout( new BorderLayout() ); - label = new JLabel( "A Panel within a panel" ); - label.setHorizontalAlignment( SwingConstants.CENTER ); - label.setForeground( Color.white ); - JLabel label2 = new JLabel( "A Panel within a panel" ); - label2.setHorizontalAlignment( SwingConstants.CENTER ); - JSlider slider = new JSlider(); - JCheckBox cbox1 = new JCheckBox( "Checkbox 1" ); - JCheckBox cbox2 = new JCheckBox( "Checkbox 2" ); - JPanel panel3 = new JPanel( false ); - panel3.setLayout( new BoxLayout( panel3, BoxLayout.PAGE_AXIS ) ); - panel3.setBorder( new EmptyBorder( 3, 3, 3, 3 ) ); - panel3.add( label2 ); - panel3.add( slider ); - panel3.add( cbox1 ); - panel3.add( cbox2 ); - JPanel panel2 = new JPanel( false ); - panel2.setBackground( Color.blue ); - panel.setBorder( new EmptyBorder( 1, 1, 1, 1 ) ); - panel2.add( label ); - panel2.add( panel3 ); - panel.setBackground( Color.red ); - panel.setSize( new Dimension( 250, 250 ) ); - panel.setBorder( new EmptyBorder( 5, 5, 5, 5 ) ); - panel.add( panel2, "Center" ); - panel.revalidate(); - return panel; - } - - public static void main( String[] args ) { - SwingUtilities.invokeLater( new Runnable() { - public void run() { - new SliderExample(); - } - } ); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/SquiggleExample.java b/examples/edu/umd/cs/piccolo/examples/SquiggleExample.java deleted file mode 100644 index bfc8b77..0000000 --- a/examples/edu/umd/cs/piccolo/examples/SquiggleExample.java +++ /dev/null @@ -1,75 +0,0 @@ - -package edu.umd.cs.piccolo.examples; -import java.awt.BasicStroke; -import java.awt.event.InputEvent; -import java.awt.geom.Point2D; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.event.PInputEventFilter; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -public class SquiggleExample extends PFrame { - - private PLayer layer; - - public SquiggleExample() { - this(null); - } - - public SquiggleExample(PCanvas aCanvas) { - super("SquiggleExample", false, aCanvas); - } - - public void initialize() { - super.initialize(); - PBasicInputEventHandler squiggleEventHandler = createSquiggleEventHandler(); - squiggleEventHandler.setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - getCanvas().addInputEventListener(squiggleEventHandler); - layer = getCanvas().getLayer(); - } - - public PBasicInputEventHandler createSquiggleEventHandler() { - return new PDragSequenceEventHandler() { - - protected PPath squiggle; - - public void startDrag(PInputEvent e) { - super.startDrag(e); - - Point2D p = e.getPosition(); - - squiggle = new PPath(); - squiggle.moveTo((float)p.getX(), (float)p.getY()); - squiggle.setStroke(new BasicStroke((float)(1/ e.getCamera().getViewScale()))); - layer.addChild(squiggle); - } - - public void drag(PInputEvent e) { - super.drag(e); - updateSquiggle(e); - } - - public void endDrag(PInputEvent e) { - super.endDrag(e); - updateSquiggle(e); - squiggle = null; - } - - public void updateSquiggle(PInputEvent aEvent) { - Point2D p = aEvent.getPosition(); - squiggle.lineTo((float)p.getX(), (float)p.getY()); - } - }; - } - - public static void main(String[] args) { - new SquiggleExample(); - } -} - diff --git a/examples/edu/umd/cs/piccolo/examples/StickyExample.java b/examples/edu/umd/cs/piccolo/examples/StickyExample.java deleted file mode 100644 index 4de65ff..0000000 --- a/examples/edu/umd/cs/piccolo/examples/StickyExample.java +++ /dev/null @@ -1,31 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PBoundsHandle; - -public class StickyExample extends PFrame { - - public StickyExample() { - this(null); - } - - public StickyExample(PCanvas aCanvas) { - super("StickyExample", false, aCanvas); - } - - public void initialize() { - PPath sticky = PPath.createRectangle(0, 0, 50, 50); - sticky.setPaint(Color.YELLOW); - sticky.setStroke(null); - PBoundsHandle.addBoundsHandlesTo(sticky); - getCanvas().getLayer().addChild(PPath.createRectangle(0, 0, 100, 80)); - getCanvas().getCamera().addChild(sticky); - } - - public static void main(String[] args) { - new StickyExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/StickyHandleLayerExample.java b/examples/edu/umd/cs/piccolo/examples/StickyHandleLayerExample.java deleted file mode 100644 index e22e606..0000000 --- a/examples/edu/umd/cs/piccolo/examples/StickyHandleLayerExample.java +++ /dev/null @@ -1,77 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.Color; -import java.util.Iterator; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.PRoot; -import edu.umd.cs.piccolo.activities.PActivity; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PBoundsHandle; -import edu.umd.cs.piccolox.handles.PHandle; -import edu.umd.cs.piccolox.util.PBoundsLocator; - -/** -* This example shows another way to create sticky handles. These handles are - * not added as children to the object that they manipulate. Instead they are - * added to the camera the views that objects. This means that they will not be - * affected by the cameras view transform, and so will stay the same size when - * the view is zoomed. They will also be drawn on top of all other objects, even - * if those objects overlap the object that they manipulate. For this setup we - * need to add and updateHandles activity that makes sure to relocate the handle - * after any change. Another way to do this would be to add change listeners to - * the camera and the node that they manipulate and only update them then. But - * this method is easier and should be plenty efficient for normal use. - * - * @author jesse - */ -public class StickyHandleLayerExample extends PFrame { - - public StickyHandleLayerExample() { - this(null); - } - - public StickyHandleLayerExample(PCanvas aCanvas) { - super("StickyHandleLayerExample", false, aCanvas); - } - - public void initialize() { - PCanvas c = getCanvas(); - - PActivity updateHandles = new PActivity(-1, 0) { - protected void activityStep(long elapsedTime) { - super.activityStep(elapsedTime); - - PRoot root = getActivityScheduler().getRoot(); - - if (root.getPaintInvalid() || root.getChildPaintInvalid()) { - Iterator i = getCanvas().getCamera().getChildrenIterator(); - while (i.hasNext()) { - PNode each = (PNode) i.next(); - if (each instanceof PHandle) { - PHandle handle = (PHandle) each; - handle.relocateHandle(); - } - } - } - } - }; - - PPath rect = PPath.createRectangle(0, 0, 100, 100); - rect.setPaint(Color.RED); - c.getLayer().addChild(rect); - - c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createNorthEastLocator(rect))); - c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createNorthWestLocator(rect))); - c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createSouthEastLocator(rect))); - c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createSouthWestLocator(rect))); - - c.getRoot().getActivityScheduler().addActivity(updateHandles, true); - } - - public static void main(String[] args) { - new StickyHandleLayerExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/TextExample.java b/examples/edu/umd/cs/piccolo/examples/TextExample.java deleted file mode 100644 index f78c650..0000000 --- a/examples/edu/umd/cs/piccolo/examples/TextExample.java +++ /dev/null @@ -1,29 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.event.PStyledTextEventHandler; - -/** - * @author Lance Good - */ -public class TextExample extends PFrame { - - public TextExample() { - this(null); - } - - public TextExample(PCanvas aCanvas) { - super("TextExample", false, aCanvas); - } - - public void initialize() { - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - PStyledTextEventHandler textHandler = new PStyledTextEventHandler(getCanvas()); - getCanvas().addInputEventListener(textHandler); - } - - public static void main(String[] args) { - new TextExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/TooltipExample.java b/examples/edu/umd/cs/piccolo/examples/TooltipExample.java deleted file mode 100644 index fad544b..0000000 --- a/examples/edu/umd/cs/piccolo/examples/TooltipExample.java +++ /dev/null @@ -1,70 +0,0 @@ -package edu.umd.cs.piccolo.examples; - -import java.awt.geom.Point2D; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.nodes.PText; -import edu.umd.cs.piccolox.PFrame; - -/** - * Simple example of one way to add tooltips - * - * @author jesse - */ -public class TooltipExample extends PFrame { - - public TooltipExample() { - this(null); - } - - public TooltipExample(PCanvas aCanvas) { - super("TooltipExample", false, aCanvas); - } - - public void initialize() { - PNode n1 = PPath.createEllipse(0, 0, 100, 100); - PNode n2 = PPath.createRectangle(300, 200, 100, 100); - - n1.addAttribute("tooltip", "node 1"); - n2.addAttribute("tooltip", "node 2"); - getCanvas().getLayer().addChild(n1); - getCanvas().getLayer().addChild(n2); - - final PCamera camera = getCanvas().getCamera(); - final PText tooltipNode = new PText(); - - tooltipNode.setPickable(false); - camera.addChild(tooltipNode); - - camera.addInputEventListener(new PBasicInputEventHandler() { - public void mouseMoved(PInputEvent event) { - updateToolTip(event); - } - - public void mouseDragged(PInputEvent event) { - updateToolTip(event); - } - - public void updateToolTip(PInputEvent event) { - PNode n = event.getInputManager().getMouseOver().getPickedNode(); - String tooltipString = (String) n.getAttribute("tooltip"); - Point2D p = event.getCanvasPosition(); - - event.getPath().canvasToLocal(p, camera); - - tooltipNode.setText(tooltipString); - tooltipNode.setOffset(p.getX() + 8, - p.getY() - 8); - } - }); - } - - public static void main(String[] argv) { - new TooltipExample(); - } -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/examples/TwoCanvasExample.java b/examples/edu/umd/cs/piccolo/examples/TwoCanvasExample.java deleted file mode 100644 index 9955356..0000000 --- a/examples/edu/umd/cs/piccolo/examples/TwoCanvasExample.java +++ /dev/null @@ -1,50 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import java.awt.Color; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.PRoot; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; -import edu.umd.cs.piccolox.handles.PBoundsHandle; - -public class TwoCanvasExample extends PFrame { - - public TwoCanvasExample() { - this(null); - } - - public TwoCanvasExample(PCanvas aCanvas) { - super("TwoCanvasExample", false, aCanvas); - } - - public void initialize() { - PRoot root = getCanvas().getRoot(); - PLayer layer = getCanvas().getLayer(); - - PNode n = PPath.createRectangle(0, 0, 100, 80); - PNode sticky = PPath.createRectangle(0, 0, 50, 50); - PBoundsHandle.addBoundsHandlesTo(n); - sticky.setPaint(Color.YELLOW); - PBoundsHandle.addBoundsHandlesTo(sticky); - - layer.addChild(n); - getCanvas().getCamera().addChild(sticky); - - PCamera otherCamera = new PCamera(); - otherCamera.addLayer(layer); - root.addChild(otherCamera); - - PCanvas other = new PCanvas(); - other.setCamera(otherCamera); - PFrame result = new PFrame("TwoCanvasExample", false, other); - result.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - result.setLocation(500, 100); - } - - public static void main(String[] args) { - new TwoCanvasExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/examples/WaitForActivitiesExample.java b/examples/edu/umd/cs/piccolo/examples/WaitForActivitiesExample.java deleted file mode 100644 index 5009e14..0000000 --- a/examples/edu/umd/cs/piccolo/examples/WaitForActivitiesExample.java +++ /dev/null @@ -1,41 +0,0 @@ -package edu.umd.cs.piccolo.examples; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.activities.PActivity; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolox.PFrame; - -/** - * This example shows how to use setTriggerTime to synchronize the start and end of - * two activities. - */ -public class WaitForActivitiesExample extends PFrame { - - public WaitForActivitiesExample() { - this(null); - } - - public WaitForActivitiesExample(PCanvas aCanvas) { - super("WaitForActivitiesExample", false, aCanvas); - } - - public void initialize() { - PLayer layer = getCanvas().getLayer(); - - PNode a = PPath.createRectangle(0, 0, 100, 80); - PNode b = PPath.createRectangle(0, 0, 100, 80); - - layer.addChild(a); - layer.addChild(b); - - PActivity a1 = a.animateToPositionScaleRotation(200, 200, 1, 0, 5000); - PActivity a2 = b.animateToPositionScaleRotation(200, 200, 1, 0, 5000); - - a2.startAfter(a1); - } - - public static void main(String[] args) { - new WaitForActivitiesExample(); - } -} diff --git a/examples/edu/umd/cs/piccolo/swtexamples/SWTBasicExample.java b/examples/edu/umd/cs/piccolo/swtexamples/SWTBasicExample.java deleted file mode 100644 index b2a9b40..0000000 --- a/examples/edu/umd/cs/piccolo/swtexamples/SWTBasicExample.java +++ /dev/null @@ -1,73 +0,0 @@ -package edu.umd.cs.piccolo.swtexamples; - -import java.awt.Color; - -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -import edu.umd.cs.piccolox.swt.PSWTCanvas; -import edu.umd.cs.piccolox.swt.PSWTPath; -import edu.umd.cs.piccolox.swt.PSWTText; - -/** - * @author good - * - * To change this generated comment edit the template variable "typecomment": - * Window>Preferences>Java>Templates. - * To enable and disable the creation of type comments go to - * Window>Preferences>Java>Code Generation. - */ -public class SWTBasicExample { - - /** - * Constructor for SWTBasicExample. - */ - public SWTBasicExample() { - super(); - } - - public static void main(String[] args) { - Display display = new Display (); - Shell shell = open (display); - while (!shell.isDisposed ()) { - if (!display.readAndDispatch ()) display.sleep (); - } - display.dispose (); - } - - public static Shell open(Display display) { - final Shell shell = new Shell (display); - shell.setLayout(new FillLayout()); - PSWTCanvas canvas = new PSWTCanvas(shell,0); - - PSWTPath rect = PSWTPath.createRectangle(25,25,50,50); - rect.setPaint(Color.red); - canvas.getLayer().addChild(rect); - - rect = PSWTPath.createRectangle(300,25,100,50); - rect.setPaint(Color.blue); - canvas.getLayer().addChild(rect); - - PSWTPath circle = PSWTPath.createEllipse(100,200,50,50); - circle.setPaint(Color.green); - canvas.getLayer().addChild(circle); - - circle = PSWTPath.createEllipse(400,400,75,150); - circle.setPaint(Color.yellow); - canvas.getLayer().addChild(circle); - - PSWTText text = new PSWTText("Hello World"); - text.translate(350,150); - text.setPenColor(Color.gray); - canvas.getLayer().addChild(text); - - text = new PSWTText("Goodbye World"); - text.translate(50,400); - text.setPenColor(Color.magenta); - canvas.getLayer().addChild(text); - - shell.open (); - return shell; - } -} diff --git a/examples/edu/umd/cs/piccolo/swtexamples/SWTBenchTest.java b/examples/edu/umd/cs/piccolo/swtexamples/SWTBenchTest.java deleted file mode 100644 index c9839ef..0000000 --- a/examples/edu/umd/cs/piccolo/swtexamples/SWTBenchTest.java +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright (C) 1998-2002 by University of Maryland, College Park, MD 20742, USA - * All rights reserved. - */ -package edu.umd.cs.piccolo.swtexamples; - -import java.util.Random; -import java.io.*; -import java.awt.*; -import java.awt.geom.*; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -import edu.umd.cs.piccolox.swt.SWTGraphics2D; - -/** - * Benchmarking test suite for SWT package - */ -public class SWTBenchTest extends Canvas { - - // Paths - GeneralPath testShape = new GeneralPath(); - - // Images - Image testImageOpaque, testImageBitmask, testImageTranslucent, testImageARGB; - - // Transforms - AffineTransform transform = new AffineTransform(); - static final AffineTransform IDENTITY = new AffineTransform(); - - // Geometry - double pts[] = new double[20]; - - // Colors - static final Color colors[] = { - Color.red, Color.green, Color.blue, Color.white, Color.yellow, - }; - - // Flags - boolean offscreen; - boolean antialiased; - - // Statistics - int results[][] = new int[NUM_CONTEXTS][NUM_TESTS]; - - - // Constants - - static final int CTX_NORMAL = 0; -// static final int CTX_CLIPPED = 1; - static final int CTX_TRANSFORMED = 1; -// static final int CTX_BLENDED = 3; - static final int NUM_CONTEXTS = 2; - -// static String contextNames[] = { -// "normal", -// "clip", -// "transform", -// "alpha", -// }; - - static String contextNames[] = { - "normal", - "transform" - }; - - - // - // TEST METHODS - // - - static final int DRAW_LINE = 0; - static final int DRAW_RECT = 1; - static final int FILL_RECT = 2; - static final int DRAW_OVAL = 3; - static final int FILL_OVAL = 4; - static final int DRAW_POLY = 5; - static final int FILL_POLY = 6; - static final int DRAW_TEXT = 7; - static final int DRAW_IMG1 = 8; - static final int DRAW_IMG2 = 9; - static final int DRAW_IMG3 = 10; - static final int DRAW_IMG4 = 11; - static final int DRAW_IMG5 = 12; - static final int NUM_TESTS = 13; - - static String testNames[] = { - "line", - "rect", - "fill rect", - "oval", - "fill oval", - "poly", - "fill poly", - "text", - "image", - "scaled image", - "mask image", - "alpha image", - "argb image", - }; - - void testDrawLine(SWTGraphics2D g, Random r) { - g.drawLine(rand(r), rand(r), rand(r), rand(r)); - } - - void testDrawRect(SWTGraphics2D g, Random r) { - g.drawRect(rand(r), rand(r), rand(r), rand(r)); - } - - void testFillRect(SWTGraphics2D g, Random r) { - g.fillRect(rand(r), rand(r), rand(r), rand(r)); - } - - void testDrawOval(SWTGraphics2D g, Random r) { - g.drawOval(rand(r), rand(r), rand(r), rand(r)); - } - - void testFillOval(SWTGraphics2D g, Random r) { - g.fillOval(rand(r), rand(r), rand(r), rand(r)); - } - - void genPoly(Random r) { - for (int i = 0; i < pts.length/2; i++) { - pts[2*i] = rand(r); - pts[2*i+1] = rand(r); - } - } - - void testDrawPoly(SWTGraphics2D g, Random r) { - genPoly(r); - g.drawPolyline(pts); - } - - void testFillPoly(SWTGraphics2D g, Random r) { - genPoly(r); - g.fillPolygon(pts); - } - - void testDrawText(SWTGraphics2D g, Random r) { - g.drawString("Abcdefghijklmnop", rand(r), rand(r)); - } - - // Basic image - void testDrawImg1(SWTGraphics2D g, Random r) { - g.drawImage(testImageOpaque, rand(r), rand(r)); - } - - // Scaled image - void testDrawImg2(SWTGraphics2D g, Random r) { - Rectangle rect = testImageOpaque.getBounds(); - g.drawImage(testImageOpaque, 0, 0, rect.width, rect.height, rand(r), rand(r), rand(r), rand(r)); - } - - // Bitmask image (unscaled) - void testDrawImg3(SWTGraphics2D g, Random r) { - g.drawImage(testImageBitmask, rand(r), rand(r)); - } - - // Translucent image (unscaled) - void testDrawImg4(SWTGraphics2D g, Random r) { - g.drawImage(testImageTranslucent, rand(r), rand(r)); - } - - // Buffered image (unscaled) - void testDrawImg5(SWTGraphics2D g, Random r) { - g.drawImage(testImageARGB, rand(r), rand(r)); - } - - Image loadImage(Display display, String name) { - try { - InputStream stream = SWTBenchTest.class.getResourceAsStream(name); - if (stream != null) { - ImageData imageData = new ImageData(stream); - return new Image(display,imageData); -// if (imageData != null) { -// ImageData mask = imageData.getTransparencyMask(); -// return new Image(display, imageData, mask); -// } - - } - } catch (Exception e) { - } - return null; - } - - SWTBenchTest(Composite parent, int style) { - super(parent,style); - - testImageOpaque = loadImage(getDisplay(),"opaque.jpg"); - testImageBitmask = loadImage(getDisplay(),"bitmask.gif"); - testImageTranslucent = loadImage(getDisplay(),"translucent.png"); - testImageARGB = new Image(getDisplay(),128, 128); - - GC tmpGC = new GC(testImageARGB); - tmpGC.drawImage(testImageTranslucent,0,0); - tmpGC.dispose(); - - addPaintListener(new PaintListener() { - public void paintControl(PaintEvent pe) { - runAll(new SWTGraphics2D(pe.gc,getDisplay())); - } - }); - } - - void setupTransform(Graphics2D g, Random r) { - transform.setToIdentity(); - - switch (abs(r.nextInt()) % 5) { - default: -// case 0: // UNIFORM SCALE - double s = r.nextDouble(); - transform.scale(5*s + 0.1, 5*s + 0.1); - break; -// case 1: // NON-UNIFORM SCALE -// transform.scale(5 * r.nextDouble() + 0.1, 5 * r.nextDouble() + 0.1); -// break; -// case 2: // ROTATION -// transform.rotate(r.nextDouble() * Math.PI * 2); -// break; -// case 3: // TRANSLATION -// transform.translate(r.nextDouble() * 500, r.nextDouble() * 500); -// break; -// case 4: // TRANSLATE + ROTATE + SCALE -// s = r.nextDouble(); -// transform.translate(r.nextDouble() * 500, r.nextDouble() * 500); -// transform.rotate(r.nextDouble() * Math.PI * 2); -// transform.scale(5*s + 0.1, 5*s + 0.1); -// break; - } - - g.setTransform(transform); - } - - void setupClip(Graphics2D g, Random r) { -// g.setClip(rand(r), rand(r), rand(r), rand(r)); - } - - void setupBlend(Graphics2D g, Random r) { - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, r.nextFloat())); - } - - void setup(int ctx, Graphics2D g, Random r) { - switch (ctx) { - case CTX_NORMAL: - break; - - case CTX_TRANSFORMED: - setupTransform(g, r); - break; - -// case CTX_CLIPPED: -// setupClip(g, r); -// break; -// -// case CTX_BLENDED: -// setupBlend(g, r); -// break; - } - } - - void test(int testNum, SWTGraphics2D g, Random r) { - - g.setColor(colors[abs(r.nextInt()) % colors.length]); - g.setBackground(colors[abs(r.nextInt()) % colors.length]); - - switch (testNum) { - case DRAW_LINE: testDrawLine(g, r); break; - case DRAW_RECT: testDrawRect(g, r); break; - case FILL_RECT: testFillRect(g, r); break; - case DRAW_OVAL: testDrawOval(g, r); break; - case FILL_OVAL: testFillOval(g, r); break; - case DRAW_POLY: testDrawPoly(g, r); break; - case FILL_POLY: testFillPoly(g, r); break; - case DRAW_TEXT: testDrawText(g, r); break; - case DRAW_IMG1: testDrawImg1(g, r); break; - case DRAW_IMG2: testDrawImg2(g, r); break; - case DRAW_IMG3: testDrawImg3(g, r); break; - case DRAW_IMG4: testDrawImg4(g, r); break; - case DRAW_IMG5: testDrawImg5(g, r); break; - } - } - - void runTest(SWTGraphics2D g, int ctx, int testNum) { - Random r1 = new Random(1); - Random r2 = new Random(1); - - System.out.println("Test: " + testNames[testNum]); - long t1 = System.currentTimeMillis(); - int i = 0; - while (true) { - if (i % 10 == 0) setup(ctx, g, r1); - test(testNum, g, r2); - i++; - long t2 = System.currentTimeMillis(); - if (t2 - t1 >= 5000) { - break; - } - } - results[ctx][testNum] += i / 5; - System.out.println("Shapes per second: " + (results[ctx][testNum])); - } - - void runAll(SWTGraphics2D g) { - System.out.println("BENCHMARKING: " + g); - - if (antialiased) { - System.out.println("ANTIALIASED"); - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - } - - for (int ctx = 0; ctx < NUM_CONTEXTS; ctx++) { - System.out.println("Context: " + contextNames[ctx]); - for (int i = 0; i < NUM_TESTS; i++) { - g.setClip(null); - g.setTransform(IDENTITY); - runTest(g, ctx, i); - } - } - - if (offscreen) { - g.dispose(); - } - - String fileName = g.getClass().getName().replace('.', '_'); - if (offscreen) fileName += "-offscreen"; - if (antialiased) fileName += "-antialiased"; - dumpResults(fileName + ".txt"); - System.exit(0); - } - - void dumpResults(String fileName) { - try { - FileOutputStream fout = new FileOutputStream(fileName); - PrintWriter out = new PrintWriter(fout); - out.print('\t'); - for (int i = 0; i < NUM_TESTS; i++) { - out.print(testNames[i]); - out.print('\t'); - } - out.println(""); - for (int ctx = 0; ctx < NUM_CONTEXTS; ctx++) { - out.print(contextNames[ctx]); - for (int i = 0; i < NUM_TESTS; i++) { - out.print('\t'); - out.print(results[ctx][i]); - } - out.println(""); - } - out.close(); - results = new int[NUM_CONTEXTS][NUM_TESTS]; - } catch (IOException e) { - e.printStackTrace(); - System.exit(1); - } - } - - public Point computeSize(int wHint, int hHint) { - return new Point(512,512); - } - - public Point computeSize(int wHint, int hHint, boolean changed) { - return computeSize(wHint,hHint); - } - - final static int abs(int x) { - return (x < 0 ? -x : x); - } - - final static double rand(Random r) { - return abs(r.nextInt()) % 500; - } - - public static void main(String args[]) { - // Create frame - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - - // Add bench test - SWTBenchTest m = new SWTBenchTest(shell,SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND); - m.setSize(512,512); - for (int i = 0; i < args.length; i++) { - if (args[i].intern() == "-offscreen") - m.offscreen = true; - else if (args[i].intern() == "-anti") - m.antialiased = true; - else { - System.out.println("Usage: java BenchTest [-anti] [-offscreen]"); - System.exit(1); - } - } - - shell.pack(); - shell.open(); - - while (!shell.isDisposed ()) { - if (!display.readAndDispatch ()) display.sleep (); - } - display.dispose (); - } - -} \ No newline at end of file diff --git a/examples/edu/umd/cs/piccolo/swtexamples/SWTHelloWorld.java b/examples/edu/umd/cs/piccolo/swtexamples/SWTHelloWorld.java deleted file mode 100644 index ca94965..0000000 --- a/examples/edu/umd/cs/piccolo/swtexamples/SWTHelloWorld.java +++ /dev/null @@ -1,47 +0,0 @@ -package edu.umd.cs.piccolo.swtexamples; - -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -import edu.umd.cs.piccolox.swt.PSWTCanvas; -import edu.umd.cs.piccolox.swt.PSWTText; - -/** - * @author good - * - * To change this generated comment edit the template variable "typecomment": - * Window>Preferences>Java>Templates. - * To enable and disable the creation of type comments go to - * Window>Preferences>Java>Code Generation. - */ -public class SWTHelloWorld { - - /** - * Constructor for SWTBasicExample. - */ - public SWTHelloWorld() { - super(); - } - - public static void main(String[] args) { - Display display = new Display (); - Shell shell = open (display); - while (!shell.isDisposed ()) { - if (!display.readAndDispatch ()) display.sleep (); - } - display.dispose (); - } - - public static Shell open(Display display) { - final Shell shell = new Shell (display); - shell.setLayout(new FillLayout()); - PSWTCanvas canvas = new PSWTCanvas(shell,0); - - PSWTText text = new PSWTText("Hello World"); - canvas.getLayer().addChild(text); - - shell.open (); - return shell; - } -} diff --git a/examples/edu/umd/cs/piccolo/swtexamples/bitmask.gif b/examples/edu/umd/cs/piccolo/swtexamples/bitmask.gif deleted file mode 100644 index 053a5da..0000000 --- a/examples/edu/umd/cs/piccolo/swtexamples/bitmask.gif +++ /dev/null Binary files differ diff --git a/examples/edu/umd/cs/piccolo/swtexamples/opaque.jpg b/examples/edu/umd/cs/piccolo/swtexamples/opaque.jpg deleted file mode 100644 index 2ff5ba6..0000000 --- a/examples/edu/umd/cs/piccolo/swtexamples/opaque.jpg +++ /dev/null Binary files differ diff --git a/examples/edu/umd/cs/piccolo/swtexamples/translucent.png b/examples/edu/umd/cs/piccolo/swtexamples/translucent.png deleted file mode 100644 index 07601a7..0000000 --- a/examples/edu/umd/cs/piccolo/swtexamples/translucent.png +++ /dev/null Binary files differ diff --git a/examples/edu/umd/cs/piccolo/tutorial/InterfaceFrame.java b/examples/edu/umd/cs/piccolo/tutorial/InterfaceFrame.java deleted file mode 100644 index a142264..0000000 --- a/examples/edu/umd/cs/piccolo/tutorial/InterfaceFrame.java +++ /dev/null @@ -1,134 +0,0 @@ -package edu.umd.cs.piccolo.tutorial; - -import java.awt.Color; -import java.awt.Graphics2D; - -import edu.umd.cs.piccolo.*; -import edu.umd.cs.piccolo.event.*; -import edu.umd.cs.piccolo.nodes.*; -import edu.umd.cs.piccolo.util.*; -import edu.umd.cs.piccolox.*; - -public class InterfaceFrame extends PFrame { - - public void initialize() { - // Remove the Default pan event handler and add a drag event handler - // so that we can drag the nodes around individually. - getCanvas().setPanEventHandler(null); - getCanvas().addInputEventListener(new PDragEventHandler()); - - // Add Some Default Nodes - - // Create a node. - PNode aNode = new PNode(); - - // A node will not be visible until its bounds and brush are set. - aNode.setBounds(0, 0, 100, 80); - aNode.setPaint(Color.RED); - - // A node needs to be a descendent of the root to be displayed. - PLayer layer = getCanvas().getLayer(); - layer.addChild(aNode); - - // A node can have child nodes added to it. - PNode anotherNode = new PNode(); - anotherNode.setBounds(0, 0, 100, 80); - anotherNode.setPaint(Color.YELLOW); - aNode.addChild(anotherNode); - - // The base bounds of a node are easy to change. Changing the bounds - // of a node will not affect it's children. - aNode.setBounds(-10, -10, 200, 110); - - // Each node has a transform that can be used to modify the position, - // scale or rotation of a node. Changing a node's transform, will - // transform all of its children as well. - aNode.translate(100, 100); - aNode.scale(1.5f); - aNode.rotate(45); - - // Add a couple of PPath nodes and a PText node. - layer.addChild(PPath.createEllipse(0, 0, 100, 100)); - layer.addChild(PPath.createRectangle(0, 100, 100, 100)); - layer.addChild(new PText("Hello World")); - - // Here we create a PImage node that displays a thumbnail image - // of the root node. Then we add the new PImage to the main layer. - PImage image = new PImage(layer.toImage(300, 300, null)); - layer.addChild(image); - - // Create a New Node using Composition - - PNode myCompositeFace = PPath.createRectangle(0, 0, 100, 80); - - // Create parts for the face. - PNode eye1 = PPath.createEllipse(0, 0, 20, 20); - eye1.setPaint(Color.YELLOW); - PNode eye2 = (PNode) eye1.clone(); - PNode mouth = PPath.createRectangle(0, 0, 40, 20); - mouth.setPaint(Color.BLACK); - - // Add the face parts. - myCompositeFace.addChild(eye1); - myCompositeFace.addChild(eye2); - myCompositeFace.addChild(mouth); - - // Don't want anyone grabbing out our eye's. - myCompositeFace.setChildrenPickable(false); - - // Position the face parts. - eye2.translate(25, 0); - mouth.translate(0, 30); - - // Set the face bounds so that it neatly contains the face parts. - PBounds b = myCompositeFace.getUnionOfChildrenBounds(null); - b.inset(-5, -5); - myCompositeFace.setBounds(b); - - // Opps its to small, so scale it up. - myCompositeFace.scale(1.5); - - layer.addChild(myCompositeFace); - - // Create a New Node using Inheritance. - ToggleShape ts = new ToggleShape(); - ts.setPaint(Color.ORANGE); - layer.addChild(ts); - } - - class ToggleShape extends PPath { - - private boolean fIsPressed = false; - - public ToggleShape() { - setPathToEllipse(0, 0, 100, 80); - - addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent event) { - super.mousePressed(event); - fIsPressed = true; - repaint(); - } - public void mouseReleased(PInputEvent event) { - super.mouseReleased(event); - fIsPressed = false; - repaint(); - } - }); - } - - protected void paint(PPaintContext paintContext) { - if (fIsPressed) { - Graphics2D g2 = paintContext.getGraphics(); - g2.setPaint(getPaint()); - g2.fill(getBoundsReference()); - } else { - super.paint(paintContext); - } - } - } - - public static void main(String[] args) { - new InterfaceFrame(); - } -} diff --git a/examples/edu/umd/cs/piccolo/tutorial/PiccoloPresentation.java b/examples/edu/umd/cs/piccolo/tutorial/PiccoloPresentation.java deleted file mode 100644 index 3fe86d6..0000000 --- a/examples/edu/umd/cs/piccolo/tutorial/PiccoloPresentation.java +++ /dev/null @@ -1,106 +0,0 @@ -package edu.umd.cs.piccolo.tutorial; - -import java.awt.Color; -import java.awt.event.KeyEvent; -import java.awt.geom.AffineTransform; -import java.io.File; -import java.util.ArrayList; - -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PImage; -import edu.umd.cs.piccolox.PFrame; - -public class PiccoloPresentation extends PFrame { - - protected PNode slideBar; - protected PNode currentSlide; - protected PBasicInputEventHandler eventHandler; - protected ArrayList slides = new ArrayList(); - - public PiccoloPresentation() { - super(); - } - - public void initialize() { - setFullScreenMode(true); - loadSlides(); - - eventHandler = new PBasicInputEventHandler() { - public void keyReleased(PInputEvent event) { - if (event.getKeyCode() == KeyEvent.VK_SPACE) { - int newIndex = slides.indexOf(currentSlide) + 1; - if (newIndex < slides.size()) { - goToSlide((PNode)slides.get(newIndex)); - } - } - } - - public void mouseReleased(PInputEvent event) { - PNode picked = event.getPickedNode(); - - if (picked.getParent() == slideBar) { - picked.moveToFront(); - if (picked.getScale() == 1) { - goToSlide(null); - } else { - goToSlide(picked); - } - } - } - }; - - getCanvas().requestFocus(); - getCanvas().addInputEventListener(eventHandler); - getCanvas().getRoot().getDefaultInputManager().setKeyboardFocus(eventHandler); - getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); - getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); - } - - public void goToSlide(PNode slide) { - if (currentSlide != null) { - currentSlide.animateToTransform((AffineTransform)currentSlide.getAttribute("small"), 1000); - } - - currentSlide = slide; - - if (currentSlide != null) { - currentSlide.moveToFront(); - currentSlide.animateToTransform((AffineTransform)currentSlide.getAttribute("large"), 1000); - } - } - - public void loadSlides() { - slideBar = new PNode(); - slideBar.setPaint(Color.DARK_GRAY); - slideBar.setBounds(0, 0, getCanvas().getWidth(), 100); - slideBar.setOffset(0, getCanvas().getHeight() - 100); - getCanvas().getLayer().addChild(slideBar); - - File[] slideFiles = new File("slides").listFiles(); - for (int i = 0; i < slideFiles.length; i++) { - PNode slide = new PImage(slideFiles[i].getPath()); - - if (slide.getHeight() != (getHeight() - 100)) { - slide = new PImage(slide.toImage(getWidth(), getHeight() - 100, null)); - } - slide.offset((getWidth() - slide.getWidth()) / 2, - (getHeight() - 100)); - slide.addAttribute("large", slide.getTransform()); - - slide.setTransform(new AffineTransform()); - slide.scale((100 - 20) / slide.getHeight()); - slide.offset(i * (slide.getFullBoundsReference().getWidth() + 10) + 10, 10); - slide.addAttribute("small", slide.getTransform()); - - slideBar.addChild(slide); - slides.add(slide); - } - - goToSlide((PNode)slides.get(0)); - } - - public static void main(String[] argv) { - new PiccoloPresentation(); - } -} diff --git a/examples/edu/umd/cs/piccolo/tutorial/SpecialEffects.java b/examples/edu/umd/cs/piccolo/tutorial/SpecialEffects.java deleted file mode 100644 index a49f2c0..0000000 --- a/examples/edu/umd/cs/piccolo/tutorial/SpecialEffects.java +++ /dev/null @@ -1,78 +0,0 @@ -package edu.umd.cs.piccolo.tutorial; - -import java.awt.Color; - -import edu.umd.cs.piccolo.*; -import edu.umd.cs.piccolo.activities.*; -import edu.umd.cs.piccolo.nodes.*; -import edu.umd.cs.piccolox.*; - -public class SpecialEffects extends PFrame { - public void initialize() { - // Create the Target for our Activities. - - // Create a new node that we will apply different activities to, and - // place that node at location 200, 200. - final PNode aNode = PPath.createRectangle(0, 0, 100, 80); - PLayer layer = getCanvas().getLayer(); - layer.addChild(aNode); - aNode.setOffset(200, 200); - - // Extend PActivity. - - // Store the current time in milliseconds for use below. - long currentTime = System.currentTimeMillis(); - - // Create a new custom "flash" activity. This activity will start running in - // five seconds, and while it runs it will flash aNode's paint between - // red and green every half second. - PActivity flash = new PActivity(-1, 500, currentTime + 5000) { - boolean fRed = true; - - protected void activityStep(long elapsedTime) { - super.activityStep(elapsedTime); - - // Toggle the target node's brush color between red and green - // each time the activity steps. - if (fRed) { - aNode.setPaint(Color.red); - } else { - aNode.setPaint(Color.green); - } - - fRed = !fRed; - } - }; - - // Schedule the activity. - getCanvas().getRoot().addActivity(flash); - - // Create three activities that animate the node's position. Since our node - // already descends from the root node the animate methods will automatically - // schedule these activities for us. - PActivity a1 = aNode.animateToPositionScaleRotation(0, 0, 0.5, 0, 5000); - PActivity a2 = aNode.animateToPositionScaleRotation(100, 0, 1.5, Math.toRadians(110), 5000); - PActivity a3 = aNode.animateToPositionScaleRotation(200, 100, 1, 0, 5000); - - // The animate activities will start immediately (in the next call to - // PRoot.processInputs) by default. Here we set their start times (in PRoot - // global time) so that they start when the previous one has finished. - a1.setStartTime(currentTime); - a2.startAfter(a1); - a3.startAfter(a2); - - a1.setDelegate(new PActivity.PActivityDelegate() { - public void activityStarted(PActivity activity) { - System.out.println("a1 started"); - } - public void activityStepped(PActivity activity) {} - public void activityFinished(PActivity activity) { - System.out.println("a1 finished"); - } - }); - } - - public static void main(String[] args) { - new SpecialEffects(); - } -} diff --git a/examples/edu/umd/cs/piccolo/tutorial/UserInteraction.java b/examples/edu/umd/cs/piccolo/tutorial/UserInteraction.java deleted file mode 100644 index 8233201..0000000 --- a/examples/edu/umd/cs/piccolo/tutorial/UserInteraction.java +++ /dev/null @@ -1,126 +0,0 @@ -package edu.umd.cs.piccolo.tutorial; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; -import java.awt.geom.Point2D; - -import edu.umd.cs.piccolo.*; -import edu.umd.cs.piccolo.event.*; -import edu.umd.cs.piccolo.nodes.*; -import edu.umd.cs.piccolo.util.*; -import edu.umd.cs.piccolox.*; - -public class UserInteraction extends PFrame { - - public UserInteraction() { - super(); - } - - public void initialize() { - // Create a Camera Event Listener. - - // Remove the pan event handler that is installed by default so that it - // does not conflict with our new squiggle handler. - getCanvas().setPanEventHandler(null); - - // Create a squiggle handler and register it with the Canvas. - PBasicInputEventHandler squiggleHandler = new SquiggleHandler(getCanvas()); - getCanvas().addInputEventListener(squiggleHandler); - - // Create a Node Event Listener. - - // Create a green rectangle node. - PNode nodeGreen = PPath.createRectangle(0, 0, 100, 100); - nodeGreen.setPaint(Color.GREEN); - getCanvas().getLayer().addChild(nodeGreen); - -// Attach event handler directly to the node. -nodeGreen.addInputEventListener(new PBasicInputEventHandler() { - public void mousePressed(PInputEvent event) { - event.getPickedNode().setPaint(Color.ORANGE); - event.getInputManager().setKeyboardFocus(event.getPath()); - event.setHandled(true); - } - public void mouseDragged(PInputEvent event) { - PNode aNode = event.getPickedNode(); - PDimension delta = event.getDeltaRelativeTo(aNode); - aNode.translate(delta.width, delta.height); - event.setHandled(true); - } - public void mouseReleased(PInputEvent event) { - event.getPickedNode().setPaint(Color.GREEN); - event.setHandled(true); - } - public void keyPressed(PInputEvent event) { - PNode node = event.getPickedNode(); - switch (event.getKeyCode()) { - case KeyEvent.VK_UP: - node.translate(0, -10f); - break; - case KeyEvent.VK_DOWN: - node.translate(0, 10f); - break; - case KeyEvent.VK_LEFT: - node.translate(-10f, 0); - break; - case KeyEvent.VK_RIGHT: - node.translate(10f, 0); - break; - } - } -}); - } - - public class SquiggleHandler extends PDragSequenceEventHandler { - protected PCanvas canvas; - - // The squiggle that is currently getting created. - protected PPath squiggle; - - public SquiggleHandler(PCanvas aCanvas) { - canvas = aCanvas; - setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); - } - - public void startDrag(PInputEvent e) { - super.startDrag(e); - - Point2D p = e.getPosition(); - - // Create a new squiggle and add it to the canvas. - squiggle = new PPath(); - squiggle.moveTo((float) p.getX(), (float) p.getY()); - squiggle.setStroke(new BasicStroke((float) (1 / e.getCamera().getViewScale()))); - canvas.getLayer().addChild(squiggle); - - // Reset the keydboard focus. - e.getInputManager().setKeyboardFocus(null); - } - - public void drag(PInputEvent e) { - super.drag(e); - // Update the squiggle while dragging. - updateSquiggle(e); - } - - public void endDrag(PInputEvent e) { - super.endDrag(e); - // Update the squiggle one last time. - updateSquiggle(e); - squiggle = null; - } - - public void updateSquiggle(PInputEvent aEvent) { - // Add a new segment to the squiggle from the last mouse position - // to the current mouse position. - Point2D p = aEvent.getPosition(); - squiggle.lineTo((float) p.getX(), (float) p.getY()); - } - } - - public static void main(String[] args) { - new UserInteraction(); - } -} diff --git a/examples/pom.xml b/examples/pom.xml new file mode 100644 index 0000000..364b719 --- /dev/null +++ b/examples/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + parent + edu.umd.cs.hcil + 1.3-SNAPSHOT + ../parent/pom.xml + + examples + 1.3-SNAPSHOT + Piccolo Examples + + A revolutionary way to create robust, full-featured graphical + applications in Java and C#, with striking visual effects such + as zooming, animation and multiple representations. + + + + edu.umd.cs.hcil + piccolox + 1.3-SNAPSHOT + + + junit + junit + 3.8.2 + test + + + + + + + maven-javadoc-plugin + + 1.2 + false + package + + + http://java.sun.com/j2se/1.3/docs/api/ + + + + + + + diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/ActivityExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/ActivityExample.java new file mode 100644 index 0000000..6fcbbc2 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/ActivityExample.java @@ -0,0 +1,84 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.activities.PActivity; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how create and schedule activities. + */ +public class ActivityExample extends PFrame { + + public ActivityExample() { + this(null); + } + + public ActivityExample(PCanvas aCanvas) { + super("ActivityExample", false, aCanvas); + } + + public void initialize() { + long currentTime = System.currentTimeMillis(); + + // Create a new node that we will apply different activities to, and + // place that node at location 200, 200. + final PNode aNode = PPath.createRectangle(0, 0, 100, 80); + PLayer layer = getCanvas().getLayer(); + layer.addChild(aNode); + aNode.setOffset(200, 200); + + // Create a new custom "flash" activity. This activity will start running in + // five seconds, and while it runs it will flash aNode's paint between + // red and green every half second. + PActivity flash = new PActivity(-1, 500, currentTime + 5000) { + boolean fRed = true; + + protected void activityStep(long elapsedTime) { + super.activityStep(elapsedTime); + + if (fRed) { + aNode.setPaint(Color.red); + } else { + aNode.setPaint(Color.green); + } + + fRed = !fRed; + } + }; + + // An activity will not run unless it is scheduled with the root. Once + // it has been scheduled it will be given a chance to run during the next + // PRoot.processInputs() call. + getCanvas().getRoot().addActivity(flash); + + // Use the PNode animate methods to create three activities that animate + // the node's position. Since our node already descends from the root node the + // animate methods will automatically schedule these activities for us. + PActivity a1 = aNode.animateToPositionScaleRotation(0, 0, 0.5, 0, 5000); + PActivity a2 = aNode.animateToPositionScaleRotation(100, 0, 1.5, Math.toRadians(110), 5000); + PActivity a3 = aNode.animateToPositionScaleRotation(200, 100, 1, 0, 5000); + PActivity a4 = aNode.animateToTransparency(0.25f, 3000); + + // the animate activities will start immediately (in the next call to PRoot.processInputs) + // by default. Here we set their start times (in PRoot global time) so that they start + // when the previous one has finished. + a1.setStartTime(currentTime); + + a2.startAfter(a1); + a3.startAfter(a2); + a4.startAfter(a3); + + // or the previous three lines could be replaced with these lines for the same effect. + //a2.setStartTime(currentTime + 5000); + //a3.setStartTime(currentTime + 10000); + //a4.setStartTime(currentTime + 15000); + } + + public static void main(String[] args) { + new ActivityExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/AngleNodeExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/AngleNodeExample.java new file mode 100644 index 0000000..7524a94 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/AngleNodeExample.java @@ -0,0 +1,120 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.util.PDimension; +import edu.umd.cs.piccolo.util.PPaintContext; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PHandle; +import edu.umd.cs.piccolox.util.PLocator; + +/** + * This shows how to create a simple node that has two handles and can be used + * for specifying angles. The nodes UI desing isn't very exciting, but the + * example shows one way to create a custom node with custom handles. + */ +public class AngleNodeExample extends PFrame { + + public AngleNodeExample() { + this(null); + } + + public AngleNodeExample(PCanvas aCanvas) { + super("AngleNodeExample", false, aCanvas); + } + + public void initialize() { + PCanvas c = getCanvas(); + PLayer l = c.getLayer(); + l.addChild(new AngleNode()); + } + + public static void main(String[] args) { + new AngleNodeExample(); + } + + // the angle node class + public static class AngleNode extends PNode { + protected Point2D.Double pointOne; + protected Point2D.Double pointTwo; + protected Stroke stroke; + + public AngleNode() { + pointOne = new Point2D.Double(100, 0); + pointTwo = new Point2D.Double(0, 100); + stroke = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); + setPaint(Color.BLACK); + updateBounds(); + addHandles(); + } + + public void addHandles() { + // point one + PLocator l = new PLocator() { + public double locateX() { return pointOne.getX(); } + public double locateY() { return pointOne.getY(); } + }; + PHandle h = new PHandle(l) { + public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { + localToParent(aLocalDimension); + pointOne.setLocation(pointOne.getX() + aLocalDimension.getWidth(), + pointOne.getY() + aLocalDimension.getHeight()); + updateBounds(); + relocateHandle(); + } + }; + addChild(h); + + // point two + l = new PLocator() { + public double locateX() { return pointTwo.getX(); } + public double locateY() { return pointTwo.getY(); } + }; + h = new PHandle(l) { + public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { + localToParent(aLocalDimension); + pointTwo.setLocation(pointTwo.getX() + aLocalDimension.getWidth(), + pointTwo.getY() + aLocalDimension.getHeight()); + updateBounds(); + relocateHandle(); + } + }; + addChild(h); + } + + protected void paint(PPaintContext paintContext) { + Graphics2D g2 = paintContext.getGraphics(); + g2.setStroke(stroke); + g2.setPaint(getPaint()); + g2.draw(getAnglePath()); + } + + protected void updateBounds() { + GeneralPath p = getAnglePath(); + Rectangle2D b = stroke.createStrokedShape(p).getBounds2D(); + super.setBounds(b.getX(), b.getY(), b.getWidth(), b.getHeight()); + } + + public GeneralPath getAnglePath() { + GeneralPath p = new GeneralPath(); + p.moveTo((float)pointOne.getX(), (float)pointOne.getY()); + p.lineTo(0, 0); + p.lineTo((float)pointTwo.getX(), (float)pointTwo.getY()); + return p; + } + + public boolean setBounds(double x, double y, double width, double height) { + return false; // bounds can be set externally + } + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/BirdsEyeViewExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/BirdsEyeViewExample.java new file mode 100644 index 0000000..bc54c08 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/BirdsEyeViewExample.java @@ -0,0 +1,432 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.JDialog; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PDragEventHandler; +import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PImage; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.nodes.PText; +import edu.umd.cs.piccolo.util.PBounds; +import edu.umd.cs.piccolo.util.PDimension; +import edu.umd.cs.piccolo.util.PPaintContext; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.nodes.P3DRect; + +/** + * This example, contributed by Rowan Christmas, shows how to + * create a birds-eye view window. + */ +public class BirdsEyeViewExample extends PFrame { + + boolean fIsPressed = false; + + public BirdsEyeViewExample() { + this(null); + } + + public BirdsEyeViewExample(PCanvas aCanvas) { + super("BirdsEyeViewExample", false, aCanvas); + } + + public void initialize() { + + nodeDemo(); + createNodeUsingExistingClasses(); + subclassExistingClasses(); + composeOtherNodes(); + createCustomNode(); + + // Last of all lets remove the default pan event handler, and add a + // drag event handler instead. This way you will be able to drag the + // nodes around with the mouse. + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(new PDragEventHandler()); + + // this will create the actual BirdsEyeView and put it in a JDialog + BirdsEyeView bev = new BirdsEyeView(); + bev.connect(getCanvas(), new PLayer[]{getCanvas().getLayer()}); + JDialog bird = new JDialog(); + bird.getContentPane().add(bev); + bird.pack(); + bird.setSize(150, 150); + bird.setVisible(true); + + } + + // This method demonstrates the kinds of things that can be done with any + // node. + public void nodeDemo() { + PLayer layer = getCanvas().getLayer(); + PNode aNode = PPath.createRectangle(0, 0, 100, 80); + + // A node needs to be a descendent of the root to be displayed on the + // screen. + layer.addChild(aNode); + + // The default color for a node is blue, but you can change that with + // the setPaint method. + aNode.setPaint(Color.red); + + // A node can have children nodes added to it. + aNode.addChild(PPath.createRectangle(0, 0, 100, 80)); + + // The base bounds of a node is easy to change. Note that changing the + // base + // bounds of a node will not change it's children. + aNode.setBounds(-10, -10, 200, 110); + + // Each node has a transform that can be used to transform the node, and + // all its children on the screen. + aNode.translate(100, 100); + aNode.scale(1.5); + aNode.rotate(45); + + // The transparency of any node can be set, this transparency will be + // applied to any of the nodes children as well. + aNode.setTransparency(0.75f); + + // Its easy to copy nodes. + PNode aCopy = (PNode) aNode.clone(); + + // Make is so that the copies children are not pickable. For this + // example + // that means you will not be able to grab the child and remove it from + // its parent. + aNode.setChildrenPickable(false); + + // Change the look of the copy + aNode.setPaint(Color.GREEN); + aNode.setTransparency(1.0f); + + // Let's add the copy to the root, and translate it so that it does not + // cover the original node. + layer.addChild(aCopy); + aCopy.setOffset(0, 0); + aCopy.rotate(-45); + } + + // So far we have just been using PNode, but of course PNode has many + // subclasses that you can try out to. + public void createNodeUsingExistingClasses() { + PLayer layer = getCanvas().getLayer(); + layer.addChild(PPath.createEllipse(0, 0, 100, 100)); + layer.addChild(PPath.createRectangle(0, 100, 100, 100)); + layer.addChild(new PText("Hello World")); + + // Here we create an image node that displays a thumbnail + // image of the root node. Note that you can easily get a thumbnail + // of any node by using PNode.toImage(). + layer.addChild(new PImage(layer.toImage(300, 300, Color.YELLOW))); + } + + // Another way to create nodes is to customize other nodes that already + // exist. Here we create an ellipse, except when you press the mouse on + // this ellipse it turns into a square, when you release the mouse it + // goes back to being an ellipse. + public void subclassExistingClasses() { + final PNode n = new PPath(new Ellipse2D.Float(0, 0, 100, 80)) { + + public void paint(PPaintContext aPaintContext) { + if (fIsPressed) { + // if mouse is pressed draw self as a square. + Graphics2D g2 = aPaintContext.getGraphics(); + g2.setPaint(getPaint()); + g2.fill(getBoundsReference()); + } else { + // if mouse is not pressed draw self normally. + super.paint(aPaintContext); + } + } + }; + + n.addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent aEvent) { + super.mousePressed(aEvent); + fIsPressed = true; + n.invalidatePaint(); // this tells the framework that the node + // needs to be redisplayed. + } + + public void mouseReleased(PInputEvent aEvent) { + super.mousePressed(aEvent); + fIsPressed = false; + n.invalidatePaint(); // this tells the framework that the node + // needs to be redisplayed. + } + }); + + n.setPaint(Color.ORANGE); + getCanvas().getLayer().addChild(n); + } + + // Here a new "face" node is created. But instead of drawing the face + // directly + // using Graphics2D we compose the face from other nodes. + public void composeOtherNodes() { + PNode myCompositeFace = PPath.createRectangle(0, 0, 100, 80); + + // create parts for the face. + PNode eye1 = PPath.createEllipse(0, 0, 20, 20); + eye1.setPaint(Color.YELLOW); + PNode eye2 = (PNode) eye1.clone(); + PNode mouth = PPath.createRectangle(0, 0, 40, 20); + mouth.setPaint(Color.BLACK); + + // add the face parts + myCompositeFace.addChild(eye1); + myCompositeFace.addChild(eye2); + myCompositeFace.addChild(mouth); + + // don't want anyone grabbing out our eye's. + myCompositeFace.setChildrenPickable(false); + + // position the face parts. + eye2.translate(25, 0); + mouth.translate(0, 30); + + // set the face bounds so that it neatly contains the face parts. + PBounds b = myCompositeFace.getUnionOfChildrenBounds(null); + myCompositeFace.setBounds(b.inset(-5, -5)); + + // opps it to small, so scale it up. + myCompositeFace.scale(1.5); + + getCanvas().getLayer().addChild(myCompositeFace); + } + + // Here a completely new kind of node, a grid node" is created. We do + // all the drawing ourselves here instead of passing the work off to + // other parts of the framework. + public void createCustomNode() { + PNode n = new PNode() { + public void paint(PPaintContext aPaintContext) { + double bx = getX(); + double by = getY(); + double rightBorder = bx + getWidth(); + double bottomBorder = by + getHeight(); + + Line2D line = new Line2D.Double(); + Graphics2D g2 = aPaintContext.getGraphics(); + + g2.setStroke(new BasicStroke(0)); + g2.setPaint(getPaint()); + + // draw vertical lines + for (double x = bx; x < rightBorder; x += 5) { + line.setLine(x, by, x, bottomBorder); + g2.draw(line); + } + + for (double y = by; y < bottomBorder; y += 5) { + line.setLine(bx, y, rightBorder, y); + g2.draw(line); + } + } + }; + n.setBounds(0, 0, 100, 80); + n.setPaint(Color.black); + getCanvas().getLayer().addChild(n); + } + + public static void main(String[] args) { + new BirdsEyeViewExample(); + } + + /** + * The Birds Eye View Class + */ + public class BirdsEyeView extends PCanvas implements PropertyChangeListener { + + /** + * This is the node that shows the viewed area. + */ + PNode areaVisiblePNode; + + /** + * This is the canvas that is being viewed + */ + PCanvas viewedCanvas; + + /** + * The change listener to know when to update the birds eye view. + */ + PropertyChangeListener changeListener; + + int layerCount; + + /** + * Creates a new instance of a BirdsEyeView + */ + public BirdsEyeView() { + + // create the PropertyChangeListener for listening to the viewed + // canvas + changeListener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + updateFromViewed(); + } + }; + + // create the coverage node + areaVisiblePNode = new P3DRect(); + areaVisiblePNode.setPaint(new Color(128, 128, 255)); + areaVisiblePNode.setTransparency(.8f); + areaVisiblePNode.setBounds(0, 0, 100, 100); + getCamera().addChild(areaVisiblePNode); + + // add the drag event handler + getCamera().addInputEventListener(new PDragSequenceEventHandler() { + protected void startDrag(PInputEvent e) { + if (e.getPickedNode() == areaVisiblePNode) + super.startDrag(e); + } + + protected void drag(PInputEvent e) { + PDimension dim = e.getDelta(); + viewedCanvas.getCamera().translateView(0 - dim.getWidth(), + 0 - dim.getHeight()); + } + + }); + + // remove Pan and Zoom + removeInputEventListener(getPanEventHandler()); + removeInputEventListener(getZoomEventHandler()); + + setDefaultRenderQuality(PPaintContext.LOW_QUALITY_RENDERING); + + } + + public void connect(PCanvas canvas, PLayer[] viewed_layers) { + + this.viewedCanvas = canvas; + layerCount = 0; + + viewedCanvas.getCamera().addPropertyChangeListener(changeListener); + + for (layerCount = 0; layerCount < viewed_layers.length; ++layerCount) { + getCamera().addLayer(layerCount, viewed_layers[layerCount]); + } + + } + + /** + * Add a layer to list of viewed layers + */ + public void addLayer(PLayer new_layer) { + getCamera().addLayer(new_layer); + layerCount++; + } + + /** + * Remove the layer from the viewed layers + */ + public void removeLayer(PLayer old_layer) { + getCamera().removeLayer(old_layer); + layerCount--; + } + + /** + * Stop the birds eye view from receiving events from the viewed canvas + * and remove all layers + */ + public void disconnect() { + viewedCanvas.getCamera().removePropertyChangeListener( + changeListener); + + for (int i = 0; i < getCamera().getLayerCount(); ++i) { + getCamera().removeLayer(i); + } + + } + + /** + * This method will get called when the viewed canvas changes + */ + public void propertyChange(PropertyChangeEvent event) { + updateFromViewed(); + } + + /** + * This method gets the state of the viewed canvas and updates the + * BirdsEyeViewer This can be called from outside code + */ + public void updateFromViewed() { + + double viewedX; + double viewedY; + double viewedHeight; + double viewedWidth; + + double ul_camera_x = viewedCanvas.getCamera().getViewBounds() + .getX(); + double ul_camera_y = viewedCanvas.getCamera().getViewBounds() + .getY(); + double lr_camera_x = ul_camera_x + + viewedCanvas.getCamera().getViewBounds().getWidth(); + double lr_camera_y = ul_camera_y + + viewedCanvas.getCamera().getViewBounds().getHeight(); + + Rectangle2D drag_bounds = getCamera().getUnionOfLayerFullBounds(); + + double ul_layer_x = drag_bounds.getX(); + double ul_layer_y = drag_bounds.getY(); + double lr_layer_x = drag_bounds.getX() + drag_bounds.getWidth(); + double lr_layer_y = drag_bounds.getY() + drag_bounds.getHeight(); + + // find the upper left corner + + // set to the lesser value + if (ul_camera_x < ul_layer_x) + viewedX = ul_layer_x; + else + viewedX = ul_camera_x; + + // same for y + if (ul_camera_y < ul_layer_y) + viewedY = ul_layer_y; + else + viewedY = ul_camera_y; + + // find the lower right corner + + // set to the greater value + if (lr_camera_x < lr_layer_x) + viewedWidth = lr_camera_x - viewedX; + else + viewedWidth = lr_layer_x - viewedX; + + // same for height + if (lr_camera_y < lr_layer_y) + viewedHeight = lr_camera_y - viewedY; + else + viewedHeight = lr_layer_y - viewedY; + + Rectangle2D bounds = new Rectangle2D.Double(viewedX, viewedY, + viewedWidth, viewedHeight); + bounds = getCamera().viewToLocal(bounds); + areaVisiblePNode.setBounds(bounds); + + // keep the birds eye view centered + getCamera().animateViewToCenterBounds(drag_bounds, true, 0); + + } + + } // class BirdsEyeView + +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/CameraExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/CameraExample.java new file mode 100644 index 0000000..8a7fb78 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/CameraExample.java @@ -0,0 +1,47 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PBoundsHandle; + +/** + * This example shows how to create internal cameras + */ +public class CameraExample extends PFrame { + + public CameraExample() { + this(null); + } + + public CameraExample(PCanvas aCanvas) { + super("CameraExample", false, aCanvas); + } + + public void initialize() { + PLayer l = new PLayer(); + PPath n = PPath.createEllipse(0, 0, 100, 80); + n.setPaint(Color.red); + n.setStroke(null); + PBoundsHandle.addBoundsHandlesTo(n); + l.addChild(n); + n.translate(200, 200); + + PCamera c = new PCamera(); + c.setBounds(0, 0, 100, 80); + c.scaleView(0.1); + c.addLayer(l); + PBoundsHandle.addBoundsHandlesTo(c); + c.setPaint(Color.yellow); + + getCanvas().getLayer().addChild(l); + getCanvas().getLayer().addChild(c); + } + + public static void main(String[] args) { + new CameraExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/CenterExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/CenterExample.java new file mode 100644 index 0000000..20aadd5 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/CenterExample.java @@ -0,0 +1,36 @@ +package edu.umd.cs.piccolo.examples; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +public class CenterExample extends PFrame { + + public CenterExample() { + this(null); + } + + public CenterExample(PCanvas aCanvas) { + super("CenterExample", false, aCanvas); + } + + public void initialize() { + PCanvas c = getCanvas(); + PLayer l = c.getLayer(); + PCamera cam = c.getCamera(); + + cam.scaleView(2.0); + PPath path = PPath.createRectangle(0, 0, 100, 100); + + l.addChild(path); + path.translate(100, 10); + path.scale(0.2); + cam.animateViewToCenterBounds(path.getGlobalFullBounds(), true, 1000); + } + + public static void main(String[] args) { + new CenterExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/ChartLabelExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/ChartLabelExample.java new file mode 100644 index 0000000..52a1e7c --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/ChartLabelExample.java @@ -0,0 +1,95 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.Color; +import java.awt.geom.Point2D; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.nodes.PText; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how to create a vertical and a horizontal bar which can + * move with your graph and always stays on view. + * + * @author Tao + */ +public class ChartLabelExample extends PFrame { + final int nodeHeight = 15; + final int nodeWidth = 30; + + //Row Bar + PLayer rowBarLayer; + + //Colume Bar + PLayer colBarLayer; + + public ChartLabelExample() { + this(null); + } + + public ChartLabelExample(PCanvas aCanvas) { + super("ChartLabelExample", false, aCanvas); + } + + public void initialize() { + //create bar layers + rowBarLayer = new PLayer(); + colBarLayer = new PLayer(); + + //create bar nodes + for (int i = 0; i < 10; i++) { + //create row bar with node row1, row2,...row10 + PText p = new PText("Row " + i); + p.setX(0); + p.setY(nodeHeight * i + nodeHeight); + p.setPaint(Color.white); + colBarLayer.addChild(p); + + //create col bar with node col1, col2,...col10 + p = new PText("Col " + i); + p.setX(nodeWidth * i + nodeWidth); + p.setY(0); + p.setPaint(Color.white); + rowBarLayer.addChild(p); + } + + //add bar layers to camera + getCanvas().getCamera().addChild(rowBarLayer); + getCanvas().getCamera().addChild(colBarLayer); + + //create matrix nodes + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + PPath path = PPath.createRectangle(nodeWidth * j + nodeWidth, + nodeHeight * i + nodeHeight, nodeWidth - 1, + nodeHeight - 1); + getCanvas().getLayer().addChild(path); + } + } + + //catch drag event and move bars corresponding + getCanvas().addInputEventListener(new PDragSequenceEventHandler() { + Point2D oldP, newP; + + public void mousePressed(PInputEvent aEvent) { + oldP = getCanvas().getCamera().getViewBounds().getCenter2D(); + } + + public void mouseReleased(PInputEvent aEvent) { + newP = getCanvas().getCamera().getViewBounds().getCenter2D(); + colBarLayer.translate(0, (oldP.getY() - newP.getY()) + / getCanvas().getLayer().getScale()); + rowBarLayer.translate((oldP.getX() - newP.getX()) + / getCanvas().getLayer().getScale(), 0); + } + }); + } + + public static void main(String[] args) { + new ChartLabelExample(); + } +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/ClipExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/ClipExample.java new file mode 100644 index 0000000..950a3ab --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/ClipExample.java @@ -0,0 +1,39 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.event.PDragEventHandler; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.nodes.PClip; + +/** + * Quick example of how to use a clip. + */ +public class ClipExample extends PFrame { + + public ClipExample() { + this(null); + } + + public ClipExample(PCanvas aCanvas) { + super("ClipExample", false, aCanvas); + } + + public void initialize() { + PClip clip = new PClip(); + clip.setPathToEllipse(0, 0, 100, 100); + clip.setPaint(Color.red); + + clip.addChild(PPath.createRectangle(20, 20, 100, 50)); + getCanvas().getLayer().addChild(clip); + + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(new PDragEventHandler()); + } + + public static void main(String[] args) { + new ClipExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/CompositeExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/CompositeExample.java new file mode 100644 index 0000000..368d9fa --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/CompositeExample.java @@ -0,0 +1,53 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PDragEventHandler; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.nodes.PText; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.nodes.PComposite; + +/** + * This example shows how to create a composite node. A composite node is + * a group of nodes that behave as a single node when interacted with. + */ +public class CompositeExample extends PFrame { + + public CompositeExample() { + this(null); + } + + public CompositeExample(PCanvas aCanvas) { + super("CompositeExample", false, aCanvas); + } + + public void initialize() { + PComposite composite = new PComposite(); + + PNode circle = PPath.createEllipse(0, 0, 100, 100); + PNode rectangle = PPath.createRectangle(50, 50, 100, 100); + PNode text = new PText("Hello world!"); + + composite.addChild(circle); + composite.addChild(rectangle); + composite.addChild(text); + + rectangle.rotate(Math.toRadians(45)); + rectangle.setPaint(Color.RED); + + text.scale(2.0); + text.setPaint(Color.GREEN); + + getCanvas().getLayer().addChild(composite); + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(new PDragEventHandler()); + } + + public static void main(String[] args) { + new CompositeExample(); + } + +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/DynamicExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/DynamicExample.java new file mode 100644 index 0000000..b7ea44e --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/DynamicExample.java @@ -0,0 +1,70 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.BasicStroke; +import java.awt.Color; +import java.util.Iterator; +import java.util.Random; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.PRoot; +import edu.umd.cs.piccolo.activities.PActivity; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.util.PFixedWidthStroke; + +/** + * 1000 nodes rotated continuously. Note that if you zoom to a portion of the screen where + * you can't see any nodes the CPU usage goes down to 1%, even though all the objects are + * still getting rotated continuously (every 20 milliseconds). This shows that the cost + * of repainting and bounds caches is very cheap compared to the cost of drawing. + */ +public class DynamicExample extends PFrame { + + public DynamicExample() { + this(null); + } + + public DynamicExample(PCanvas aCanvas) { + super("DynamicExample", false, aCanvas); + } + + public void initialize() { + final PLayer layer = getCanvas().getLayer(); + PRoot root = getCanvas().getRoot(); + Random r = new Random(); + for (int i = 0; i < 1000; i++) { + final PNode n = PPath.createRectangle(0, 0, 100, 80); + n.translate(10000 * r.nextFloat(), 10000 * r.nextFloat()); + n.setPaint(new Color(r.nextFloat(), r.nextFloat(),r.nextFloat())); + layer.addChild(n); + } + getCanvas().getCamera().animateViewToCenterBounds(layer.getGlobalFullBounds(), true, 0); + PActivity a = new PActivity(-1, 20) { + public void activityStep(long currentTime) { + super.activityStep(currentTime); + rotateNodes(); + } + }; + root.addActivity(a); + + PPath p = new PPath(); + p.moveTo(0, 0); + p.lineTo(0, 1000); + PFixedWidthStroke stroke = new PFixedWidthStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, new float[] {5, 2}, 0); + p.setStroke(stroke); + layer.addChild(p); + } + + public void rotateNodes() { + Iterator i = getCanvas().getLayer().getChildrenReference().iterator(); + while (i.hasNext()) { + PNode each = (PNode) i.next(); + each.rotate(Math.toRadians(2)); + } + } + + public static void main(String[] args) { + new DynamicExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/EventHandlerExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/EventHandlerExample.java new file mode 100644 index 0000000..b0c3cd2 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/EventHandlerExample.java @@ -0,0 +1,116 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.BasicStroke; +import java.awt.event.InputEvent; +import java.awt.geom.Point2D; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.event.PInputEventFilter; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.util.PBounds; + +/** + * This example shows how to create and install a custom event listener that draws + * rectangles. + */ +public class EventHandlerExample extends PFrame { + + public EventHandlerExample() { + this(null); + } + + public EventHandlerExample(PCanvas aCanvas) { + super("EventHandlerExample", false, aCanvas); + } + + public void initialize() { + super.initialize(); + + // Create a new event handler the creates new rectangles on + // mouse pressed, dragged, release. + PBasicInputEventHandler rectEventHandler = createRectangleEventHandler(); + + // Make the event handler only work with BUTTON1 events, so that it does + // not conflict with the zoom event handler that is installed by default. + rectEventHandler.setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); + + // Remove the pan event handler that is installed by default so that it + // does not conflict with our new rectangle creation event handler. + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + + // Register our new event handler. + getCanvas().addInputEventListener(rectEventHandler); + } + + public PBasicInputEventHandler createRectangleEventHandler() { + + // Create a new subclass of PBasicEventHandler that creates new PPath nodes + // on mouse pressed, dragged, and released sequences. Not that subclassing + // PDragSequenceEventHandler would make this class easier to implement, but + // here you can see how to do it from scratch. + return new PBasicInputEventHandler() { + + // The rectangle that is currently getting created. + protected PPath rectangle; + + // The mouse press location for the current pressed, drag, release sequence. + protected Point2D pressPoint; + + // The current drag location. + protected Point2D dragPoint; + + public void mousePressed(PInputEvent e) { + super.mousePressed(e); + + PLayer layer = getCanvas().getLayer(); + + // Initialize the locations. + pressPoint = e.getPosition(); + dragPoint = pressPoint; + + // create a new rectangle and add it to the canvas layer so that + // we can see it. + rectangle = new PPath(); + rectangle.setStroke(new BasicStroke((float)(1/ e.getCamera().getViewScale()))); + layer.addChild(rectangle); + + // update the rectangle shape. + updateRectangle(); + } + + public void mouseDragged(PInputEvent e) { + super.mouseDragged(e); + // update the drag point location. + dragPoint = e.getPosition(); + + // update the rectangle shape. + updateRectangle(); + } + + public void mouseReleased(PInputEvent e) { + super.mouseReleased(e); + // update the rectangle shape. + updateRectangle(); + rectangle = null; + } + + public void updateRectangle() { + // create a new bounds that contains both the press and current + // drag point. + PBounds b = new PBounds(); + b.add(pressPoint); + b.add(dragPoint); + + // Set the rectangles bounds. + rectangle.setPathTo(b); + } + }; + } + + public static void main(String[] args) { + new EventHandlerExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java new file mode 100644 index 0000000..ab75a88 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java @@ -0,0 +1,362 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JPanel; + +import edu.umd.cs.piccolo.util.PDebug; +import edu.umd.cs.piccolox.PFrame; + +public class ExampleRunner extends JFrame { + + public ExampleRunner() { + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("Piccolo Example Runner"); + setSize(426, 335); + getContentPane().setLayout(new BorderLayout()); + createExampleButtons(); + validate(); + pack(); + setVisible(true); + } + + public void createExampleButtons() { + Container c = getContentPane(); + Container p = new JPanel(); + + p = new JPanel(new GridLayout(0, 1)); + c.add(BorderLayout.NORTH, p); + + p.add(new JCheckBox(new AbstractAction("Print Frame Rates to Console") { + public void actionPerformed(ActionEvent e) { + PDebug.debugPrintFrameRate = !PDebug.debugPrintFrameRate; + } + })); + + p.add(new JCheckBox(new AbstractAction("Show Region Managment") { + public void actionPerformed(ActionEvent e) { + PDebug.debugRegionManagement = !PDebug.debugRegionManagement; + } + })); + + p.add(new JCheckBox(new AbstractAction("Show Full Bounds") { + public void actionPerformed(ActionEvent e) { + PDebug.debugFullBounds = !PDebug.debugFullBounds; + } + })); + + p = new JPanel(new GridLayout(0, 2)); + c.add(BorderLayout.CENTER, p); + + p.add(new JButton(new AbstractAction("ActivityExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new ActivityExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("AngleNodeExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new AngleNodeExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("BirdsEyeViewExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new BirdsEyeViewExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("CameraExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new CameraExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("CenterExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new CenterExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("ChartLabelExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new ChartLabelExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("ClipExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new ClipExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("CompositeExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new CompositeExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("DynamicExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new DynamicExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("EventHandlerExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new EventHandlerExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("FullScreenNodeExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new FullScreenNodeExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("GraphEditorExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new GraphEditorExample(); + example.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + p.add(new JButton(new AbstractAction("GridExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new GridExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("GroupExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new GroupExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("HandleExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new HandleExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("HierarchyZoomExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new HierarchyZoomExample(); + example.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("KeyEventFocusExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new KeyEventFocusExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("LayoutExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new LayoutExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("LensExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new LensExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("NavigationExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new NavigationExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("NodeCacheExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new NodeCacheExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("NodeEventExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new NodeEventExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("NodeExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new NodeExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("NodeLinkExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new NodeLinkExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("PanToExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new PanToExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("PathExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new PathExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("PositionExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new PositionExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("PositionPathActivityExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new PositionPathActivityExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("PulseExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new PulseExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("ScrollingExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new ScrollingExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("SelectionExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new SelectionExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("SquiggleExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new SquiggleExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("StickyExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new StickyExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("StickyHandleLayerExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new StickyHandleLayerExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("TextExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new TextExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("Tooltip Example") { + public void actionPerformed(ActionEvent e) { + PFrame example = new TooltipExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("TwoCanvasExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new TwoCanvasExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + + p.add(new JButton(new AbstractAction("WaitForActivitiesExample") { + public void actionPerformed(ActionEvent e) { + PFrame example = new WaitForActivitiesExample(); + example + .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + } + })); + } + + public static void main(String[] args) { + new ExampleRunner(); + } +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/FullScreenNodeExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/FullScreenNodeExample.java new file mode 100644 index 0000000..fcabba1 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/FullScreenNodeExample.java @@ -0,0 +1,14 @@ +package edu.umd.cs.piccolo.examples; + + +public class FullScreenNodeExample extends NodeExample { + + public void initialize() { + super.initialize(); + setFullScreenMode(true); + } + + public static void main(String[] args) { + new FullScreenNodeExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/GraphEditorExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/GraphEditorExample.java new file mode 100644 index 0000000..115c94f --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/GraphEditorExample.java @@ -0,0 +1,136 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Random; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * Create a simple graph with some random nodes and connected edges. + * An event handler allows users to drag nodes around, keeping the edges connected. + * + * ported from .NET GraphEditorExample by Sun Hongmei. + */ +public class GraphEditorExample extends PFrame { + + public GraphEditorExample() { + this(null); + } + + public GraphEditorExample(PCanvas aCanvas) { + super("GraphEditorExample", false, aCanvas); + } + + public void initialize() { + int numNodes = 50; + int numEdges = 50; + + // Initialize, and create a layer for the edges (always underneath the nodes) + PLayer nodeLayer = getCanvas().getLayer(); + PLayer edgeLayer = new PLayer(); + getCanvas().getCamera().addLayer(0, edgeLayer); + Random rnd = new Random(); + ArrayList tmp; + for (int i = 0; i < numNodes; i++) { + float x = (float) (300. * rnd.nextDouble()); + float y = (float) (400. * rnd.nextDouble()); + PPath path = PPath.createEllipse(x, y, 20, 20); + tmp = new ArrayList(); + path.addAttribute("edges", tmp); + nodeLayer.addChild(path); + } + + // Create some random edges + // Each edge's Tag has an ArrayList used to store associated nodes + for (int i = 0; i < numEdges; i++) { + int n1 = rnd.nextInt(numNodes); + int n2 = rnd.nextInt(numNodes); + PNode node1 = nodeLayer.getChild(n1); + PNode node2 = nodeLayer.getChild(n2); + + Point2D.Double bound1 = (Point2D.Double) node1.getBounds().getCenter2D(); + Point2D.Double bound2 = (Point2D.Double) node2.getBounds().getCenter2D(); + + PPath edge = new PPath(); + edge.moveTo((float) bound1.getX(), (float) bound1.getY()); + edge.lineTo((float) bound2.getX(), (float) bound2.getY()); + + tmp = (ArrayList) node1.getAttribute("edges"); + tmp.add(edge); + tmp = (ArrayList) node2.getAttribute("edges"); + tmp.add(edge); + + tmp = new ArrayList(); + tmp.add(node1); + tmp.add(node2); + edge.addAttribute("nodes", tmp); + + edgeLayer.addChild(edge); + } + + // Create event handler to move nodes and update edges + nodeLayer.addInputEventListener(new NodeDragHandler()); + } + + public static void main(String[] args) { + new GraphEditorExample(); + } + + /// + /// Simple event handler which applies the following actions to every node it is called on: + /// * Turn node red when the mouse goes over the node + /// * Turn node white when the mouse exits the node + /// * Drag the node, and associated edges on mousedrag + /// It assumes that the node's Tag references an ArrayList with a list of associated + /// edges where each edge is a PPath which each have a Tag that references an ArrayList + /// with a list of associated nodes. + /// + class NodeDragHandler extends PDragSequenceEventHandler { + public NodeDragHandler() { + getEventFilter().setMarksAcceptedEventsAsHandled(true); + } + public void mouseEntered(PInputEvent e) { + if (e.getButton() == 0) { + e.getPickedNode().setPaint(Color.red); + } + } + + public void mouseExited(PInputEvent e) { + if (e.getButton() == 0) { + e.getPickedNode().setPaint(Color.white); + } + } + + public void drag(PInputEvent e) { + PNode node = e.getPickedNode(); + node.translate(e.getDelta().width, e.getDelta().height); + + ArrayList edges = (ArrayList) e.getPickedNode().getAttribute("edges"); + + int i; + for (i = 0; i < edges.size(); i++) { + PPath edge = (PPath) edges.get(i); + ArrayList nodes = (ArrayList) edge.getAttribute("nodes"); + PNode node1 = (PNode) nodes.get(0); + PNode node2 = (PNode) nodes.get(1); + + edge.reset(); + // Note that the node's "FullBounds" must be used (instead of just the "Bound") + // because the nodes have non-identity transforms which must be included when + // determining their position. + Point2D.Double bound1 = (Point2D.Double) node1.getFullBounds().getCenter2D(); + Point2D.Double bound2 = (Point2D.Double) node2.getFullBounds().getCenter2D(); + + edge.moveTo((float) bound1.getX(), (float) bound1.getY()); + edge.lineTo((float) bound2.getX(), (float) bound2.getY()); + } + } + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/GridExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/GridExample.java new file mode 100644 index 0000000..e19d9dc --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/GridExample.java @@ -0,0 +1,145 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.PRoot; +import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.util.PPaintContext; +import edu.umd.cs.piccolox.PFrame; + +/** + * Example of drawing an infinite grid, and providing support for snap to grid. + */ +public class GridExample extends PFrame { + + static protected Line2D gridLine = new Line2D.Double(); + static protected Stroke gridStroke = new BasicStroke(1); + static protected Color gridPaint = Color.BLACK; + static protected double gridSpacing = 20; + + public GridExample() { + this(null); + } + + public GridExample(PCanvas aCanvas) { + super("GridExample", false, aCanvas); + } + + public void initialize() { + PRoot root = getCanvas().getRoot(); + final PCamera camera = getCanvas().getCamera(); + final PLayer gridLayer = new PLayer() { + protected void paint(PPaintContext paintContext) { + // make sure grid gets drawn on snap to grid boundaries. And + // expand a little to make sure that entire view is filled. + double bx = (getX() - (getX() % gridSpacing)) - gridSpacing; + double by = (getY() - (getY() % gridSpacing)) - gridSpacing; + double rightBorder = getX() + getWidth() + gridSpacing; + double bottomBorder = getY() + getHeight() + gridSpacing; + + Graphics2D g2 = paintContext.getGraphics(); + Rectangle2D clip = paintContext.getLocalClip(); + + g2.setStroke(gridStroke); + g2.setPaint(gridPaint); + + for (double x = bx; x < rightBorder; x += gridSpacing) { + gridLine.setLine(x, by, x, bottomBorder); + if (clip.intersectsLine(gridLine)) { + g2.draw(gridLine); + } + } + + for (double y = by; y < bottomBorder; y += gridSpacing) { + gridLine.setLine(bx, y, rightBorder, y); + if (clip.intersectsLine(gridLine)) { + g2.draw(gridLine); + } + } + } + }; + + // replace standar layer with grid layer. + root.removeChild(camera.getLayer(0)); + camera.removeLayer(0); + root.addChild(gridLayer); + camera.addLayer(gridLayer); + + // add constrains so that grid layers bounds always match cameras view bounds. This makes + // it look like an infinite grid. + camera.addPropertyChangeListener(PNode.PROPERTY_BOUNDS, new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + gridLayer.setBounds(camera.getViewBounds()); + } + }); + + camera.addPropertyChangeListener(PCamera.PROPERTY_VIEW_TRANSFORM, new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + gridLayer.setBounds(camera.getViewBounds()); + } + }); + + gridLayer.setBounds(camera.getViewBounds()); + + PNode n = new PNode(); + n.setPaint(Color.BLUE); + n.setBounds(0, 0, 100, 80); + + getCanvas().getLayer().addChild(n); + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + + // add a drag event handler that supports snap to grid. + getCanvas().addInputEventListener(new PDragSequenceEventHandler() { + + protected PNode draggedNode; + protected Point2D nodeStartPosition; + + protected boolean shouldStartDragInteraction(PInputEvent event) { + if (super.shouldStartDragInteraction(event)) { + return event.getPickedNode() != event.getTopCamera() && !(event.getPickedNode() instanceof PLayer); + } + return false; + } + + protected void startDrag(PInputEvent event) { + super.startDrag(event); + draggedNode = event.getPickedNode(); + draggedNode.moveToFront(); + nodeStartPosition = draggedNode.getOffset(); + } + + protected void drag(PInputEvent event) { + super.drag(event); + + Point2D start = getCanvas().getCamera().localToView((Point2D)getMousePressedCanvasPoint().clone()); + Point2D current = event.getPositionRelativeTo(getCanvas().getLayer()); + Point2D dest = new Point2D.Double(); + + dest.setLocation(nodeStartPosition.getX() + (current.getX() - start.getX()), + nodeStartPosition.getY() + (current.getY() - start.getY())); + + dest.setLocation(dest.getX() - (dest.getX() % gridSpacing), + dest.getY() - (dest.getY() % gridSpacing)); + + draggedNode.setOffset(dest.getX(), dest.getY()); + } + }); + } + + public static void main(String[] args) { + new GridExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/GroupExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/GroupExample.java new file mode 100644 index 0000000..9ccc469 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/GroupExample.java @@ -0,0 +1,192 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.util.ArrayList; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.util.PBounds; +import edu.umd.cs.piccolo.util.PPaintContext; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.event.PSelectionEventHandler; + +/** + * An example of how to implement decorator groups. Decorator groups are nodes that base their bounds and rendering on their children. + * This seems to be a common type of visual node that requires some potentially non-obvious subclassing to get right. + * + * Both a volatile and a non-volatile implementation are shown. The volatile implementation might be used in cases where you want to + * keep a scale-independent pen width border around a group of objects. The non-volatile implementation can be used in more standard + * cases where the decorator's bounds are stable during zooming. + * + * @author Lance Good + */ +public class GroupExample extends PFrame { + + public GroupExample() { + this(null); + } + + public GroupExample(PCanvas aCanvas) { + super("GroupExample", false, aCanvas); + } + + public void initialize() { + super.initialize(); + + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + + // Create a decorator group that is NOT volatile + DecoratorGroup dg = new DecoratorGroup(); + dg.setPaint(Color.magenta); + + // Put some nodes under the group for it to decorate + PPath p1 = PPath.createEllipse(25,25,75,75); + p1.setPaint(Color.red); + PPath p2 = PPath.createRectangle(125,75,50,50); + p2.setPaint(Color.blue); + + // Add everything to the Piccolo hierarchy + dg.addChild(p1); + dg.addChild(p2); + getCanvas().getLayer().addChild(dg); + + // Create a decorator group that IS volatile + VolatileDecoratorGroup vdg = new VolatileDecoratorGroup(getCanvas().getCamera()); + vdg.setPaint(Color.cyan); + + // Put some nodes under the group for it to decorate + PPath p3 = PPath.createEllipse(275,175,50,50); + p3.setPaint(Color.blue); + PPath p4 = PPath.createRectangle(175,175,75,75); + p4.setPaint(Color.green); + + // Add everything to the Piccolo hierarchy + vdg.addChild(p3); + vdg.addChild(p4); + getCanvas().getLayer().addChild(vdg); + + // Create a selection handler so we can see that the decorator actually works + ArrayList selectableParents = new ArrayList(); + selectableParents.add(dg); + selectableParents.add(vdg); + + PSelectionEventHandler ps = new PSelectionEventHandler(getCanvas().getLayer(),selectableParents); + getCanvas().addInputEventListener(ps); + } + + public static void main(String[] args) { + new GroupExample(); + } +} + +/** + * This is the non-volatile implementation of a decorator group that paints a background rectangle based + * on the bounds of its children. + */ +class DecoratorGroup extends PNode { + int INDENT = 10; + + PBounds cachedChildBounds = new PBounds(); + PBounds comparisonBounds = new PBounds(); + + public DecoratorGroup() { + super(); + } + + /** + * Change the default paint to fill an expanded bounding box based on its children's bounds + */ + public void paint(PPaintContext ppc) { + Paint paint = getPaint(); + if (paint != null) { + Graphics2D g2 = ppc.getGraphics(); + g2.setPaint(paint); + + PBounds bounds = getUnionOfChildrenBounds(null); + bounds.setRect(bounds.getX()-INDENT,bounds.getY()-INDENT,bounds.getWidth()+2*INDENT,bounds.getHeight()+2*INDENT); + g2.fill(bounds); + } + } + + /** + * Change the full bounds computation to take into account that we are expanding the children's bounds + * Do this instead of overriding getBoundsReference() since the node is not volatile + */ + public PBounds computeFullBounds(PBounds dstBounds) { + PBounds result = getUnionOfChildrenBounds(dstBounds); + + cachedChildBounds.setRect(result); + result.setRect(result.getX()-INDENT,result.getY()-INDENT,result.getWidth()+2*INDENT,result.getHeight()+2*INDENT); + localToParent(result); + return result; + } + + /** + * This is a crucial step. We have to override this method to invalidate the paint each time the bounds are changed so + * we repaint the correct region + */ + public boolean validateFullBounds() { + comparisonBounds = getUnionOfChildrenBounds(comparisonBounds); + + if (!cachedChildBounds.equals(comparisonBounds)) { + setPaintInvalid(true); + } + return super.validateFullBounds(); + } +} + +/** + * This is the volatile implementation of a decorator group that paints a background rectangle based + * on the bounds of its children. + */ +class VolatileDecoratorGroup extends PNode { + int INDENT = 10; + + PBounds cachedChildBounds = new PBounds(); + PBounds comparisonBounds = new PBounds(); + PCamera renderCamera; + + public VolatileDecoratorGroup(PCamera camera) { + super(); + renderCamera = camera; + } + + /** + * Indicate that the bounds are volatile for this group + */ + public boolean getBoundsVolatile() { + return true; + } + + /** + * Since our bounds are volatile, we can override this method to indicate that we are expanding our bounds beyond our children + */ + public PBounds getBoundsReference() { + PBounds bds = super.getBoundsReference(); + getUnionOfChildrenBounds(bds); + + cachedChildBounds.setRect(bds); + double scaledIndent = INDENT/renderCamera.getViewScale(); + bds.setRect(bds.getX()-scaledIndent,bds.getY()-scaledIndent,bds.getWidth()+2*scaledIndent,bds.getHeight()+2*scaledIndent); + + return bds; + } + + /** + * This is a crucial step. We have to override this method to invalidate the paint each time the bounds are changed so + * we repaint the correct region + */ + public boolean validateFullBounds() { + comparisonBounds = getUnionOfChildrenBounds(comparisonBounds); + + if (!cachedChildBounds.equals(comparisonBounds)) { + setPaintInvalid(true); + } + return super.validateFullBounds(); + } +} + + diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/HandleExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/HandleExample.java new file mode 100644 index 0000000..7430fec --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/HandleExample.java @@ -0,0 +1,82 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.BasicStroke; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.util.PDimension; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PBoundsHandle; +import edu.umd.cs.piccolox.handles.PHandle; +import edu.umd.cs.piccolox.util.PNodeLocator; + +/** + * This example show how to add the default handles to a node, and also how + * to create your own custom handles. + */ +public class HandleExample extends PFrame { + + public HandleExample() { + this(null); + } + + public HandleExample(PCanvas aCanvas) { + super("HandleExample", false, aCanvas); + } + + public void initialize() { + PPath n = PPath.createRectangle(0, 0, 100, 80); + + // add another node the the root as a reference point so that we can + // tell that our node is getting dragged, as opposed the the canvas + // view being panned. + getCanvas().getLayer().addChild(PPath.createRectangle(0, 0, 100, 80)); + + getCanvas().getLayer().addChild(n); + + // tell the node to show its default handles. + PBoundsHandle.addBoundsHandlesTo(n); + + // The default PBoundsHandle implementation doesn't work well with PPaths that have strokes. The reason + // for this is that the default PBoundsHandle modifies the bounds of an PNode, but when adding handles to + // a PPath we really want it to be modifying the underlying geometry of the PPath, the shape without the + // stroke. The solution is that we need to create handles specific to PPaths that locate themselves on the + // paths internal geometry, not the external bounds geometry... + + n.setStroke(new BasicStroke(10)); + n.setPaint(Color.green); + + // Here we create our own custom handle. This handle is located in the center of its parent + // node and you can use it to drag the parent around. This handle also updates its color when + // the is pressed/released in it. + final PHandle h = new PHandle(new PNodeLocator(n)) { // the default locator locates the center of a node. + public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { + localToParent(aLocalDimension); + getParent().translate(aLocalDimension.getWidth(), aLocalDimension.getHeight()); + } + }; + + h.addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent aEvent) { + h.setPaint(Color.YELLOW); + } + + public void mouseReleased(PInputEvent aEvent) { + h.setPaint(Color.RED); + } + }); + + // make this handle appear a bit different then the default handle appearance. + h.setPaint(Color.RED); + h.setBounds(-10, -10, 20, 20); + + // also add our new custom handle to the node. + n.addChild(h); + } + + public static void main(String[] args) { + new HandleExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/HelloWorldExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/HelloWorldExample.java new file mode 100644 index 0000000..75967aa --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/HelloWorldExample.java @@ -0,0 +1,25 @@ +package edu.umd.cs.piccolo.examples; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.nodes.PText; +import edu.umd.cs.piccolox.PFrame; + +public class HelloWorldExample extends PFrame { + + public HelloWorldExample() { + this(null); + } + + public HelloWorldExample(PCanvas aCanvas) { + super("HelloWorldExample", false, aCanvas); + } + + public void initialize() { + PText text = new PText("Hello World"); + getCanvas().getLayer().addChild(text); + } + + public static void main(String[] args) { + new HelloWorldExample(); + } +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/HierarchyZoomExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/HierarchyZoomExample.java new file mode 100644 index 0000000..d7ec773 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/HierarchyZoomExample.java @@ -0,0 +1,50 @@ +package edu.umd.cs.piccolo.examples; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how to create and zoom over a node hierarchy. + */ +public class HierarchyZoomExample extends PFrame { + + public HierarchyZoomExample() { + this(null); + } + + public HierarchyZoomExample(PCanvas aCanvas) { + super("HierarchyZoomExample", false, aCanvas); + } + + public void initialize() { + PNode root = createHierarchy(10); + getCanvas().getLayer().addChild(root); + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent event) { + getCanvas().getCamera().animateViewToCenterBounds(event.getPickedNode().getGlobalBounds(), true, 500); + } + }); + } + + public PNode createHierarchy(int level) { + PPath result = PPath.createRectangle(0, 0, 100, 100); + + if (level > 0) { + PNode child = createHierarchy(level - 1); + child.scale(0.5); + result.addChild(child); + child.offset(25, 25); + } + + return result; + } + + public static void main(String[] args) { + new HierarchyZoomExample(); + } +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/KeyEventFocusExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/KeyEventFocusExample.java new file mode 100644 index 0000000..f2c6d0d --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/KeyEventFocusExample.java @@ -0,0 +1,86 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how a node can get the keyboard focus. + */ +public class KeyEventFocusExample extends PFrame { + + public KeyEventFocusExample() { + this(null); + } + + public KeyEventFocusExample(PCanvas aCanvas) { + super("KeyEventFocusExample", false, aCanvas); + } + + public void initialize() { + // Create a green and red node and add them to canvas layer. + PCanvas canvas = getCanvas(); + PNode nodeGreen = PPath.createRectangle(0, 0, 100, 100); + PNode nodeRed = PPath.createRectangle(0, 0, 100, 100); + nodeRed.translate(200, 0); + nodeGreen.setPaint(Color.green); + nodeRed.setPaint(Color.red); + canvas.getLayer().addChild(nodeGreen); + canvas.getLayer().addChild(nodeRed); + + // Add an event handler to the green node the prints "green mousepressed" + // when the mouse is pressed on the green node, and "green keypressed" when + // the key is pressed and the event listener has keyboard focus. + nodeGreen.addInputEventListener(new PBasicInputEventHandler() { + public void keyPressed(PInputEvent event) { + System.out.println("green keypressed"); + } + + // Key board focus is managed by the PInputManager, accessible from + // the root object, or from an incoming PInputEvent. In this case when + // the mouse is pressed in the green node, then the event handler associated + // with it will set the keyfocus to itself. Now it will receive key events + // until someone else gets the focus. + public void mousePressed(PInputEvent event) { + event.getInputManager().setKeyboardFocus(event.getPath()); + System.out.println("green mousepressed"); + } + + public void keyboardFocusGained(PInputEvent event) { + System.out.println("green focus gained"); + } + + public void keyboardFocusLost(PInputEvent event) { + System.out.println("green focus lost"); + } + }); + + // do the same thing with the red node. + nodeRed.addInputEventListener(new PBasicInputEventHandler() { + public void keyPressed(PInputEvent event) { + System.out.println("red keypressed"); + } + + public void mousePressed(PInputEvent event) { + event.getInputManager().setKeyboardFocus(event.getPath()); + System.out.println("red mousepressed"); + } + + public void keyboardFocusGained(PInputEvent event) { + System.out.println("red focus gained"); + } + + public void keyboardFocusLost(PInputEvent event) { + System.out.println("red focus lost"); + } + }); + } + + public static void main(String[] args) { + new KeyEventFocusExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/LayoutExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/LayoutExample.java new file mode 100644 index 0000000..d5652ae --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/LayoutExample.java @@ -0,0 +1,64 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; +import java.util.Iterator; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PBoundsHandle; + +/** + * This example shows how to create a node that will automatically + * layout its children. + */ +public class LayoutExample extends PFrame { + + public LayoutExample() { + this(null); + } + + public LayoutExample(PCanvas aCanvas) { + super("LayoutExample", false, aCanvas); + } + + public void initialize() { + // Create a new node and override its validateLayoutAfterChildren method so + // that it lays out its children in a row from left to + // right. + + final PNode layoutNode = new PNode() { + public void layoutChildren() { + double xOffset = 0; + double yOffset = 0; + + Iterator i = getChildrenIterator(); + while (i.hasNext()) { + PNode each = (PNode) i.next(); + each.setOffset(xOffset - each.getX(), yOffset); + xOffset += each.getWidth(); + } + } + }; + + layoutNode.setPaint(Color.red); + + // add some children to the layout node. + for (int i = 0; i < 1000; i++) { + // create child to add to the layout node. + PNode each = PPath.createRectangle(0, 0, 100, 80); + + // add the child to the layout node. + layoutNode.addChild(each); + } + + PBoundsHandle.addBoundsHandlesTo(layoutNode.getChild(0)); + + // add layoutNode to the root so it will be displayed. + getCanvas().getLayer().addChild(layoutNode); + } + + public static void main(String[] args) { + new LayoutExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/LensExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/LensExample.java new file mode 100644 index 0000000..17374c2 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/LensExample.java @@ -0,0 +1,131 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Point2D; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.PRoot; +import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.nodes.PText; +import edu.umd.cs.piccolo.util.PPaintContext; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PBoundsHandle; +import edu.umd.cs.piccolox.nodes.PLens; + +/** + * This example shows one way to create and use lens's in Piccolo. + */ +public class LensExample extends PFrame { + + public LensExample() { + this(null); + } + + public LensExample(PCanvas aCanvas) { + super("LensExample", false, aCanvas); + } + + public void initialize() { + PRoot root = getCanvas().getRoot(); + PCamera camera = getCanvas().getCamera(); + PLayer mainLayer = getCanvas().getLayer(); // viewed by the PCanvas camera, the lens is added to this layer. + PLayer sharedLayer = new PLayer(); // viewed by both the lens camera and the PCanvas camera + final PLayer lensOnlyLayer = new PLayer(); // viewed by only the lens camera + + root.addChild(lensOnlyLayer); + root.addChild(sharedLayer); + camera.addLayer(0, sharedLayer); + + final PLens lens = new PLens(); + lens.setBounds(10, 10, 100, 130); + lens.addLayer(0, lensOnlyLayer); + lens.addLayer(1, sharedLayer); + mainLayer.addChild(lens); + PBoundsHandle.addBoundsHandlesTo(lens); + + // Create an event handler that draws squiggles on the first layer of the bottom + // most camera. + PDragSequenceEventHandler squiggleEventHandler = new PDragSequenceEventHandler() { + protected PPath squiggle; + public void startDrag(PInputEvent e) { + super.startDrag(e); + Point2D p = e.getPosition(); + squiggle = new PPath(); + squiggle.moveTo((float)p.getX(), (float)p.getY()); + + // add squiggles to the first layer of the bottom camera. In the case of the + // lens these squiggles will be added to the layer that is only visible by the lens, + // In the case of the canvas camera the squiggles will be added to the shared layer + // viewed by both the canvas camera and the lens. + e.getCamera().getLayer(0).addChild(squiggle); + } + + public void drag(PInputEvent e) { + super.drag(e); + updateSquiggle(e); + } + + public void endDrag(PInputEvent e) { + super.endDrag(e); + updateSquiggle(e); + squiggle = null; + } + + public void updateSquiggle(PInputEvent aEvent) { + Point2D p = aEvent.getPosition(); + squiggle.lineTo((float)p.getX(), (float)p.getY()); + } + }; + + // add the squiggle event handler to both the lens and the + // canvas camera. + lens.getCamera().addInputEventListener(squiggleEventHandler); + camera.addInputEventListener(squiggleEventHandler); + + // make sure that the event handler consumes events so that it doesn't + // conflic with other event handlers or with itself (since its added to two + // event sources). + squiggleEventHandler.getEventFilter().setMarksAcceptedEventsAsHandled(true); + + // remove default event handlers, not really nessessary since the squiggleEventHandler + // consumes everything anyway, but still good to do. + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); + + // create a node that is viewed both by the main camera and by the + // lens. Note that in its paint method it checks to see which camera + // is painting it, and if its the lens uses a different color. + PNode sharedNode = new PNode() { + protected void paint(PPaintContext paintContext) { + if (paintContext.getCamera() == lens.getCamera()) { + Graphics2D g2 = paintContext.getGraphics(); + g2.setPaint(Color.RED); + g2.fill(getBoundsReference()); + } else { + super.paint(paintContext); + } + } + }; + sharedNode.setPaint(Color.GREEN); + sharedNode.setBounds(0, 0, 100, 200); + sharedNode.translate(200, 200); + sharedLayer.addChild(sharedNode); + + PText label = new PText("Move the lens \n (by dragging title bar) over the green rectangle, and it will appear red. press and drag the mouse on the canvas and it will draw squiggles. press and drag the mouse over the lens and drag squiggles that are only visible through the lens."); + label.setConstrainWidthToTextWidth(false); + label.setConstrainHeightToTextHeight(false); + label.setBounds(200, 100, 200, 200); + + sharedLayer.addChild(label); + } + + public static void main(String[] args) { + new LensExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/NavigationExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/NavigationExample.java new file mode 100644 index 0000000..cb7ef22 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/NavigationExample.java @@ -0,0 +1,42 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.BasicStroke; +import java.awt.Color; +import java.util.Random; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.event.PNavigationEventHandler; + +public class NavigationExample extends PFrame { + + public NavigationExample() { + this(null); + } + + public NavigationExample(PCanvas aCanvas) { + super("NavigationExample", false, aCanvas); + } + + public void initialize() { + PLayer layer = getCanvas().getLayer(); + + Random random = new Random(); + for (int i = 0; i < 1000; i++) { + PPath each = PPath.createRectangle(0, 0, 100, 80); + each.scale(random.nextFloat() * 2); + each.offset(random.nextFloat() * 10000, random.nextFloat() * 10000); + each.setPaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); + each.setStroke(new BasicStroke(1 + (10 * random.nextFloat()))); + each.setStrokePaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); + layer.addChild(each); + } + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(new PNavigationEventHandler()); + } + + public static void main(String[] args) { + new NavigationExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeCacheExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeCacheExample.java new file mode 100644 index 0000000..744fe06 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeCacheExample.java @@ -0,0 +1,47 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.BasicStroke; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.event.PDragEventHandler; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.nodes.PNodeCache; + +public class NodeCacheExample extends PFrame { + + public NodeCacheExample() { + this(null); + } + + public NodeCacheExample(PCanvas aCanvas) { + super("NodeCacheExample", false, aCanvas); + } + + public void initialize() { + PCanvas canvas = getCanvas(); + + PPath circle = PPath.createEllipse(0, 0, 100, 100); + circle.setStroke(new BasicStroke(10)); + circle.setPaint(Color.YELLOW); + + PPath rectangle = PPath.createRectangle(-100, -50, 100, 100); + rectangle.setStroke(new BasicStroke(15)); + rectangle.setPaint(Color.ORANGE); + + PNodeCache cache = new PNodeCache(); + cache.addChild(circle); + cache.addChild(rectangle); + + cache.invalidateCache(); + + canvas.getLayer().addChild(cache); + canvas.removeInputEventListener(canvas.getPanEventHandler()); + canvas.addInputEventListener(new PDragEventHandler()); + } + + public static void main(String[] args) { + new NodeCacheExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeEventExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeEventExample.java new file mode 100644 index 0000000..10369d1 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeEventExample.java @@ -0,0 +1,99 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how to make a node handle events. + */ +public class NodeEventExample extends PFrame { + + public NodeEventExample() { + this(null); + } + + public NodeEventExample(PCanvas aCanvas) { + super("NodeEventExample", false, aCanvas); + } + + public void initialize() { + PLayer layer = getCanvas().getLayer(); + + // create a new node and override some of the event handling + // methods so that the node changes to orange when the mouse (Button 1) is + // pressed on the node, and changes back to green when the mouse + // is released. Also when the mouse is dragged the node updates its + // position so that the node is "dragged". Note that this only serves + // as a simple example, most of the time dragging nodes is best done + // with the PDragEventHandler, but this shows another way to do it. + // + // Note that each of these methods marks the event as handled. This is so that + // when the node is being dragged the zoom and pan event handles + // (that are installed by default) do not also operate, but they will + // still respond to events that are not handled by the node. (try to uncomment + // the aEvent.setHandled() calls and see what happens. + final PNode aNode = new PNode(); + aNode.addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent aEvent) { + aNode.setPaint(Color.orange); + printEventCoords(aEvent); + aEvent.setHandled(true); + } + + public void mouseDragged(PInputEvent aEvent) { + Dimension2D delta = aEvent.getDeltaRelativeTo(aNode); + aNode.translate(delta.getWidth(), delta.getHeight()); + printEventCoords(aEvent); + aEvent.setHandled(true); + } + + public void mouseReleased(PInputEvent aEvent) { + aNode.setPaint(Color.green); + printEventCoords(aEvent); + aEvent.setHandled(true); + } + + // Note this slows things down a lot, comment it out to see how the normal + // speed of things is. + // + // For fun the coords of each event that the node handles are printed out. + // This can help to understand how coordinate systems work. Notice that when + // the example first starts all the values for (canvas, global, and local) are + // equal. But once you drag the node then the local coordinates become different + // then the screen and global coordinates. When you pan or zoom then the screen + // coordinates become different from the global coordinates. + public void printEventCoords(PInputEvent aEvent) { + System.out.println("Canvas Location: " + aEvent.getCanvasPosition()); + //System.out.println("Global Location: " + aEvent.getGlobalLocation()); + System.out.println("Local Location: " + aEvent.getPositionRelativeTo(aNode)); + System.out.println("Canvas Delta: " + aEvent.getCanvasDelta()); + //System.out.println("Global Delta: " + aEvent.getGlobalDelta()); + System.out.println("Local Delta: " + aEvent.getDeltaRelativeTo(aNode)); + } + }); + aNode.setBounds(0, 0, 200, 200); + aNode.setPaint(Color.green); + + // By default the filter accepts all events, but here we constrain the kinds of + // events that aNode receives to button 1 events. Comment this line out and then + // you will be able to drag the node with any mouse button. + //aNode.setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); + + // add another node to the canvas that does not handle events as a reference + // point, so that we can make sure that our green node is getting dragged. + layer.addChild(PPath.createRectangle(0, 0, 100, 80)); + layer.addChild(aNode); + } + + public static void main(String[] args) { + new NodeEventExample(); + } +} + diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeExample.java new file mode 100644 index 0000000..033467e --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeExample.java @@ -0,0 +1,222 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PDragEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PImage; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.nodes.PText; +import edu.umd.cs.piccolo.util.PBounds; +import edu.umd.cs.piccolo.util.PPaintContext; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how to create and manipulate nodes. + */ +public class NodeExample extends PFrame { + + boolean fIsPressed = false; + + public NodeExample() { + this(null); + } + + public NodeExample(PCanvas aCanvas) { + super("NodeExample", false, aCanvas); + } + + public void initialize() { + nodeDemo(); + createNodeUsingExistingClasses(); + subclassExistingClasses(); + composeOtherNodes(); + createCustomNode(); + + // Last of all lets remove the default pan event handler, and add a + // drag event handler instead. This way you will be able to drag the + // nodes around with the mouse. + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(new PDragEventHandler()); + } + + // This method demonstrates the kinds of things that can be done with any node. + public void nodeDemo() { + PLayer layer = getCanvas().getLayer(); + PNode aNode = PPath.createRectangle(0, 0, 100, 80); + + // A node needs to be a descendent of the root to be displayed on the screen. + layer.addChild(aNode); + + // The default color for a node is blue, but you can change that with + // the setPaint method. + aNode.setPaint(Color.red); + + // A node can have children nodes added to it. + aNode.addChild(PPath.createRectangle(0, 0, 100, 80)); + + // The base bounds of a node is easy to change. Note that changing the base + // bounds of a node will not change it's children. + aNode.setBounds(-10, -10, 200, 110); + + // Each node has a transform that can be used to transform the node, and + // all its children on the screen. + aNode.translate(100, 100); + aNode.scale(1.5); + aNode.rotate(45); + + // The transparency of any node can be set, this transparency will be + // applied to any of the nodes children as well. + aNode.setTransparency(0.75f); + + // Its easy to copy nodes. + PNode aCopy = (PNode) aNode.clone(); + + // Make is so that the copies children are not pickable. For this example + // that means you will not be able to grab the child and remove it from + // its parent. + aNode.setChildrenPickable(false); + + // Change the look of the copy + aNode.setPaint(Color.GREEN); + aNode.setTransparency(1.0f); + + // Let's add the copy to the root, and translate it so that it does not + // cover the original node. + layer.addChild(aCopy); + aCopy.setOffset(0, 0); + aCopy.rotate(-45); + } + + // So far we have just been using PNode, but of course PNode has many + // subclasses that you can try out to. + public void createNodeUsingExistingClasses() { + PLayer layer = getCanvas().getLayer(); + layer.addChild(PPath.createEllipse(0, 0, 100, 100)); + layer.addChild(PPath.createRectangle(0, 100, 100, 100)); + layer.addChild(new PText("Hello World")); + + // Here we create an image node that displays a thumbnail + // image of the root node. Note that you can easily get a thumbnail + // of any node by using PNode.toImage(). + PImage image = new PImage(layer.toImage(300, 300, null)); + layer.addChild(image); + } + + // Another way to create nodes is to customize other nodes that already + // exist. Here we create an ellipse, except when you press the mouse on + // this ellipse it turns into a square, when you release the mouse it + // goes back to being an ellipse. + public void subclassExistingClasses() { + final PNode n = new PPath(new Ellipse2D.Float(0, 0, 100, 80)) { + + public void paint(PPaintContext aPaintContext) { + if (fIsPressed) { + // if mouse is pressed draw self as a square. + Graphics2D g2 = aPaintContext.getGraphics(); + g2.setPaint(getPaint()); + g2.fill(getBoundsReference()); + } else { + // if mouse is not pressed draw self normally. + super.paint(aPaintContext); + } + } + }; + + n.addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent aEvent) { + super.mousePressed(aEvent); + fIsPressed = true; + n.invalidatePaint(); // this tells the framework that the node needs to be redisplayed. + } + + public void mouseReleased(PInputEvent aEvent) { + super.mousePressed(aEvent); + fIsPressed = false; + n.invalidatePaint(); // this tells the framework that the node needs to be redisplayed. + } + }); + + n.setPaint(Color.ORANGE); + getCanvas().getLayer().addChild(n); + } + + // Here a new "face" node is created. But instead of drawing the face directly + // using Graphics2D we compose the face from other nodes. + public void composeOtherNodes() { + PNode myCompositeFace = PPath.createRectangle(0, 0, 100, 80); + + // create parts for the face. + PNode eye1 = PPath.createEllipse(0, 0, 20, 20); + eye1.setPaint(Color.YELLOW); + PNode eye2 = (PNode) eye1.clone(); + PNode mouth = PPath.createRectangle(0, 0, 40, 20); + mouth.setPaint(Color.BLACK); + + // add the face parts + myCompositeFace.addChild(eye1); + myCompositeFace.addChild(eye2); + myCompositeFace.addChild(mouth); + + // don't want anyone grabbing out our eye's. + myCompositeFace.setChildrenPickable(false); + + // position the face parts. + eye2.translate(25, 0); + mouth.translate(0, 30); + + // set the face bounds so that it neatly contains the face parts. + PBounds b = myCompositeFace.getUnionOfChildrenBounds(null); + myCompositeFace.setBounds(b.inset(-5, -5)); + + // opps it to small, so scale it up. + myCompositeFace.scale(1.5); + + getCanvas().getLayer().addChild(myCompositeFace); + } + + // Here a completely new kind of node, a grid node" is created. We do + // all the drawing ourselves here instead of passing the work off to + // other parts of the framework. + public void createCustomNode() { + PNode n = new PNode() { + public void paint(PPaintContext aPaintContext) { + double bx = getX(); + double by = getY(); + double rightBorder = bx + getWidth(); + double bottomBorder = by + getHeight(); + + Line2D line = new Line2D.Double(); + Graphics2D g2 = aPaintContext.getGraphics(); + + g2.setStroke(new BasicStroke(0)); + g2.setPaint(getPaint()); + + // draw vertical lines + for (double x = bx; x < rightBorder; x += 5) { + line.setLine(x, by, x, bottomBorder); + g2.draw(line); + } + + for (double y = by; y < bottomBorder; y += 5) { + line.setLine(bx, y, rightBorder, y); + g2.draw(line); + } + } + }; + n.setBounds(0, 0, 100, 80); + n.setPaint(Color.black); + getCanvas().getLayer().addChild(n); + } + + public static void main(String[] args) { + new NodeExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeLinkExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeLinkExample.java new file mode 100644 index 0000000..d22df55 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/NodeLinkExample.java @@ -0,0 +1,74 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PDragEventHandler; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * Simple example showing one way to create a link between two nodes. + * + * @author Jesse Grosjean + */ +public class NodeLinkExample extends PFrame { + + PNode node1; + PNode node2; + PPath link; + + public NodeLinkExample() { + this(null); + } + + public NodeLinkExample(PCanvas aCanvas) { + super("NodeLinkExample", false, aCanvas); + } + + public void initialize() { + PCanvas canvas = getCanvas(); + + canvas.removeInputEventListener(canvas.getPanEventHandler()); + canvas.addInputEventListener(new PDragEventHandler()); + + PNode layer = canvas.getLayer(); + + node1 = PPath.createEllipse(0, 0, 100, 100); + node2 = PPath.createEllipse(0, 0, 100, 100); + link = PPath.createLine(50, 50, 50, 50); + link.setPickable(false); + layer.addChild(node1); + layer.addChild(node2); + layer.addChild(link); + + node2.translate(200, 200); + + node1.addPropertyChangeListener(PNode.PROPERTY_FULL_BOUNDS, new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent arg0) { + updateLink(); + } + }); + + node2.addPropertyChangeListener(PNode.PROPERTY_FULL_BOUNDS, new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent arg0) { + updateLink(); + } + }); + } + + public void updateLink() { + Point2D p1 = node1.getFullBoundsReference().getCenter2D(); + Point2D p2 = node2.getFullBoundsReference().getCenter2D(); + Line2D line = new Line2D.Double(p1.getX(), p1.getY(), p2.getX(), p2.getY()); + link.setPathTo(line); + } + + public static void main(String[] args) { + new NodeLinkExample(); + } +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/PSwingExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/PSwingExample.java new file mode 100644 index 0000000..8dd7ba7 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/PSwingExample.java @@ -0,0 +1,48 @@ +package edu.umd.cs.piccolo.examples; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.pswing.PSwing; +import edu.umd.cs.piccolox.pswing.PSwingCanvas; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +/** + * Demonstrates the use of PSwing in a Piccolo application. + */ + +public class PSwingExample extends PFrame { + + public PSwingExample() { + this( new PSwingCanvas() ); + } + + public PSwingExample( PCanvas aCanvas ) { + super( "PSwingExample", false, aCanvas ); + } + + public void initialize() { + PSwingCanvas pswingCanvas = (PSwingCanvas)getCanvas(); + PLayer l = pswingCanvas.getLayer(); + + JSlider js = new JSlider( 0, 100 ); + js.addChangeListener( new ChangeListener() { + public void stateChanged( ChangeEvent e ) { + System.out.println( "e = " + e ); + } + } ); + js.setBorder( BorderFactory.createTitledBorder( "Test JSlider" ) ); + PSwing pSwing = new PSwing( js ); + pSwing.translate( 100, 100 ); + l.addChild( pSwing ); + + pswingCanvas.setPanEventHandler( null ); + } + + public static void main( String[] args ) { + new PSwingExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/PanToExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/PanToExample.java new file mode 100644 index 0000000..24a738f --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/PanToExample.java @@ -0,0 +1,73 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.util.Random; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * Click on a node and the camera will pan the minimum distance to bring that node fully into + * the cameras view. + */ +public class PanToExample extends PFrame { + + public PanToExample() { + this(null); + } + + public PanToExample(PCanvas aCanvas) { + super("PanToExample", false, aCanvas); + } + + public void initialize() { + + PPath eacha = PPath.createRectangle(50, 50, 300, 300); + eacha.setPaint(Color.red); + getCanvas().getLayer().addChild(eacha); + + eacha = PPath.createRectangle(-50, -50, 100, 100); + eacha.setPaint(Color.green); + getCanvas().getLayer().addChild(eacha); + + eacha = PPath.createRectangle(350, 350, 100, 100); + eacha.setPaint(Color.green); + getCanvas().getLayer().addChild(eacha); + + + getCanvas().getCamera().addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent event) { + if (!(event.getPickedNode() instanceof PCamera)) { + event.setHandled(true); + getCanvas().getCamera().animateViewToPanToBounds(event.getPickedNode().getGlobalFullBounds(), 500); + } + } + }); + + PLayer layer = getCanvas().getLayer(); + + Random random = new Random(); + for (int i = 0; i < 1000; i++) { + PPath each = PPath.createRectangle(0, 0, 100, 80); + each.scale(random.nextFloat() * 2); + each.offset(random.nextFloat() * 10000, random.nextFloat() * 10000); + each.setPaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); + each.setStroke(new BasicStroke(1 + (10 * random.nextFloat()))); + each.setStrokePaint(new Color(random.nextFloat(),random.nextFloat(),random.nextFloat())); + layer.addChild(each); + } + + + getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); + } + + public static void main(String[] args) { + new PanToExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/PathExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/PathExample.java new file mode 100644 index 0000000..14e5b95 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/PathExample.java @@ -0,0 +1,54 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.BasicStroke; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.event.PDragEventHandler; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PStickyHandleManager; +import edu.umd.cs.piccolox.util.PFixedWidthStroke; + +public class PathExample extends PFrame { + + public PathExample() { + this(null); + } + + public PathExample(PCanvas aCanvas) { + super("PathExample", false, aCanvas); + } + + public void initialize() { + PPath n1 = PPath.createRectangle(0, 0, 100, 80); + PPath n2 = PPath.createEllipse(100, 100, 200, 34); + PPath n3 = new PPath(); + n3.moveTo(0, 0); + n3.lineTo(20, 40); + n3.lineTo(10, 200); + n3.lineTo(155.444f, 33.232f); + n3.closePath(); + n3.setPaint(Color.yellow); + + n1.setStroke(new BasicStroke(5)); + n1.setStrokePaint(Color.red); + n2.setStroke(new PFixedWidthStroke()); + n3.setStroke(new PFixedWidthStroke()); +// n3.setStroke(null); + + getCanvas().getLayer().addChild(n1); + getCanvas().getLayer().addChild(n2); + getCanvas().getLayer().addChild(n3); + + // create a set of bounds handles for reshaping n3, and make them + // sticky relative to the getCanvas().getCamera(). + new PStickyHandleManager(getCanvas().getCamera(), n3); + + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(new PDragEventHandler()); + } + + public static void main(String[] args) { + new PathExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/PositionExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/PositionExample.java new file mode 100644 index 0000000..94d698a --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/PositionExample.java @@ -0,0 +1,40 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +public class PositionExample extends PFrame { + + public PositionExample() { + this(null); + } + + public PositionExample(PCanvas aCanvas) { + super("PositionExample", false, aCanvas); + } + + public void initialize() { + PNode n1 = PPath.createRectangle(0, 0, 100, 80); + PNode n2 = PPath.createRectangle(0, 0, 100, 80); + + getCanvas().getLayer().addChild(n1); + getCanvas().getLayer().addChild(n2); + + n2.scale(2.0); + n2.rotate(Math.toRadians(90)); + //n2.setScale(2.0); + //n2.setScale(1.0); + n2.scale(0.5); + n2.setPaint(Color.red); + + n1.offset(100, 0); + n2.offset(100, 0); + } + + public static void main(String[] args) { + new PositionExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/PositionPathActivityExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/PositionPathActivityExample.java new file mode 100644 index 0000000..9f6dfdc --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/PositionPathActivityExample.java @@ -0,0 +1,56 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.geom.Arc2D; +import java.awt.geom.GeneralPath; + +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.activities.PPositionPathActivity; + +/** + * This example shows how create a simple acitivty to animate a node along a + * general path. + */ +public class PositionPathActivityExample extends PFrame { + + public PositionPathActivityExample() { + super(); + } + + public void initialize() { + PLayer layer = getCanvas().getLayer(); + final PNode animatedNode = PPath.createRectangle(0, 0, 100, 80); + layer.addChild(animatedNode); + + // create animation path + GeneralPath path = new GeneralPath(); + path.moveTo(0, 0); + path.lineTo(300, 300); + path.lineTo(300, 0); + path.append(new Arc2D.Float(0, 0, 300, 300, 90, -90, Arc2D.OPEN), true); + path.closePath(); + + // create node to display animation path + PPath ppath = new PPath(path); + layer.addChild(ppath); + + // create activity to run animation. + PPositionPathActivity positionPathActivity = new PPositionPathActivity(5000, 0, new PPositionPathActivity.Target() { + public void setPosition(double x, double y) { + animatedNode.setOffset(x, y); + } + }); +// positionPathActivity.setSlowInSlowOut(false); + positionPathActivity.setPositions(path); + positionPathActivity.setLoopCount(Integer.MAX_VALUE); + + // add the activity. + animatedNode.addActivity(positionPathActivity); + } + + public static void main(String[] args) { + new PositionPathActivityExample(); + } +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/PulseExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/PulseExample.java new file mode 100644 index 0000000..1b1fee4 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/PulseExample.java @@ -0,0 +1,82 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.PRoot; +import edu.umd.cs.piccolo.activities.PActivityScheduler; +import edu.umd.cs.piccolo.activities.PColorActivity; +import edu.umd.cs.piccolo.activities.PInterpolatingActivity; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how to set up interpolating activities that repeat. For + * example it shows how to create a rectangle whos color pulses. + * + * @author jesse + */ +public class PulseExample extends PFrame { + + public PulseExample() { + this(null); + } + + public PulseExample(PCanvas aCanvas) { + super("PulseExample", false, aCanvas); + } + + public void initialize() { + PRoot root = getCanvas().getRoot(); + PLayer layer = getCanvas().getLayer(); + PActivityScheduler scheduler = root.getActivityScheduler(); + + final PNode singlePulse = PPath.createRectangle(0, 0, 100, 80); + final PPath repeatePulse = PPath.createRectangle(100, 80, 100, 80); + final PNode repeateReversePulse = PPath.createRectangle(200, 160, 100, 80); + + layer.addChild(singlePulse); + layer.addChild(repeatePulse); + layer.addChild(repeateReversePulse); + + // animate from source to destination color in one second, + PColorActivity singlePulseActivity = new PColorActivity(1000, 0, 1, PInterpolatingActivity.SOURCE_TO_DESTINATION, new PColorActivity.Target() { + public Color getColor() { + return (Color) singlePulse.getPaint(); + } + public void setColor(Color color) { + singlePulse.setPaint(color); + } + }, Color.ORANGE); + + // animate from source to destination color in one second, loop 5 times + PColorActivity repeatPulseActivity = new PColorActivity(1000, 0, 5, PInterpolatingActivity.SOURCE_TO_DESTINATION, new PColorActivity.Target() { + public Color getColor() { + return (Color) repeatePulse.getPaint(); + } + public void setColor(Color color) { + repeatePulse.setPaint(color); + } + }, Color.BLUE); + + // animate from source to destination to source color in one second, loop 10 times + PColorActivity repeatReversePulseActivity = new PColorActivity(500, 0, 10, PInterpolatingActivity.SOURCE_TO_DESTINATION_TO_SOURCE, new PColorActivity.Target() { + public Color getColor() { + return (Color) repeateReversePulse.getPaint(); + } + public void setColor(Color color) { + repeateReversePulse.setPaint(color); + } + }, Color.GREEN); + + scheduler.addActivity(singlePulseActivity); + scheduler.addActivity(repeatPulseActivity); + scheduler.addActivity(repeatReversePulseActivity); + } + + public static void main(String[] args) { + new PulseExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/ScrollingExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/ScrollingExample.java new file mode 100644 index 0000000..1d3a0a5 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/ScrollingExample.java @@ -0,0 +1,223 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.Iterator; + +import javax.swing.ButtonGroup; +import javax.swing.JToggleButton; +import javax.swing.JToolBar; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.util.PAffineTransform; +import edu.umd.cs.piccolo.util.PBounds; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.swing.PDefaultScrollDirector; +import edu.umd.cs.piccolox.swing.PScrollDirector; +import edu.umd.cs.piccolox.swing.PScrollPane; +import edu.umd.cs.piccolox.swing.PViewport; + +/** + * This creates a simple scene and allows switching between + * traditional scrolling where the scrollbars control the view + * and alternate scrolling where the scrollbars control the + * document. In laymans terms - in traditional window scrolling the stuff + * in the window moves in the opposite direction of the scroll bars and in + * document scrolling the stuff moves in the same direction as the scrollbars. + * + * Toggle buttons are provided to toggle between these two types + * of scrolling. + * + * @author Lance Good + * @author Ben Bederson + */ +public class ScrollingExample extends PFrame { + + public ScrollingExample() { + this(null); + } + + public ScrollingExample(PCanvas aCanvas) { + super("ScrollingExample", false, aCanvas); + } + + public void initialize() { + final PCanvas canvas = getCanvas(); + + final PScrollPane scrollPane = new PScrollPane(canvas); + getContentPane().add(scrollPane); + + final PViewport viewport = (PViewport) scrollPane.getViewport(); + final PScrollDirector windowSD = viewport.getScrollDirector(); + final PScrollDirector documentSD = new DocumentScrollDirector(); + + // Make some rectangles on the surface so we can see where we are + for (int x = 0; x < 20; x++) { + for (int y = 0; y < 20; y++) { + if (((x + y) % 2) == 0) { + PPath path = PPath.createRectangle(50 * x, 50 * y, 40, 40); + path.setPaint(Color.blue); + path.setStrokePaint(Color.black); + canvas.getLayer().addChild(path); + } + else if (((x + y) % 2) == 1) { + PPath path = PPath.createEllipse(50 * x, 50 * y, 40, 40); + path.setPaint(Color.blue); + path.setStrokePaint(Color.black); + canvas.getLayer().addChild(path); + } + } + } + + // Now, create the toolbar + JToolBar toolBar = new JToolBar(); + JToggleButton window = new JToggleButton("Window Scrolling"); + JToggleButton document = new JToggleButton("Document Scrolling"); + ButtonGroup bg = new ButtonGroup(); + bg.add(window); + bg.add(document); + toolBar.add(window); + toolBar.add(document); + toolBar.setFloatable(false); + window.setSelected(true); + window.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + viewport.setScrollDirector(windowSD); + viewport.fireStateChanged(); + scrollPane.revalidate(); + } + }); + document.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + viewport.setScrollDirector(documentSD); + viewport.fireStateChanged(); + scrollPane.revalidate(); + } + }); + getContentPane().add(toolBar, BorderLayout.NORTH); + + getContentPane().validate(); + } + + /** + * A modified scroll director that performs document based scroling + * rather than window based scrolling (ie. the scrollbars act in + * the inverse direction as normal) + */ + public class DocumentScrollDirector extends PDefaultScrollDirector { + + /** + * Get the View position given the specified camera bounds - modified + * such that: + * + * Rather than finding the distance from the upper left corner + * of the window to the upper left corner of the document - + * we instead find the distance from the lower right corner + * of the window to the upper left corner of the document + * THEN we subtract that value from total document width so + * that the position is inverted + * + * @param viewBounds The bounds for which the view position will be computed + * @return The view position + */ + public Point getViewPosition(Rectangle2D viewBounds) { + Point pos = new Point(); + if (camera != null) { + // First we compute the union of all the layers + PBounds layerBounds = new PBounds(); + java.util.List layers = camera.getLayersReference(); + for (Iterator i = layers.iterator(); i.hasNext();) { + PLayer layer = (PLayer) i.next(); + layerBounds.add(layer.getFullBoundsReference()); + } + + // Then we put the bounds into camera coordinates and + // union the camera bounds + camera.viewToLocal(layerBounds); + layerBounds.add(viewBounds); + + // Rather than finding the distance from the upper left corner + // of the window to the upper left corner of the document - + // we instead find the distance from the lower right corner + // of the window to the upper left corner of the document + // THEN we measure the offset from the lower right corner + // of the document + pos.setLocation( + (int) (layerBounds.getWidth() - (viewBounds.getX() + viewBounds.getWidth() - layerBounds.getX()) + 0.5), + (int) (layerBounds.getHeight() - (viewBounds.getY() + viewBounds.getHeight() - layerBounds.getY()) + 0.5)); + } + + return pos; + + } + + /** + * We do the same thing we did in getViewPosition above to flip the + * document-window position relationship + * + * @param x The new x position + * @param y The new y position + */ + public void setViewPosition(double x, double y) { + if (camera != null) { + // If a scroll is in progress - we ignore new scrolls - + // if we didn't, since the scrollbars depend on the camera location + // we can end up with an infinite loop + if (!scrollInProgress) { + scrollInProgress = true; + + // Get the union of all the layers' bounds + PBounds layerBounds = new PBounds(); + java.util.List layers = camera.getLayersReference(); + for (Iterator i = layers.iterator(); i.hasNext();) { + PLayer layer = (PLayer) i.next(); + layerBounds.add(layer.getFullBoundsReference()); + } + + PAffineTransform at = camera.getViewTransform(); + at.transform(layerBounds,layerBounds); + + // Union the camera view bounds + PBounds viewBounds = camera.getBoundsReference(); + layerBounds.add(viewBounds); + + // Now find the new view position in view coordinates - + // This is basically the distance from the lower right + // corner of the window to the upper left corner of the + // document + // We then measure the offset from the lower right corner + // of the document + Point2D newPoint = + new Point2D.Double( + layerBounds.getX() + layerBounds.getWidth() - (x + viewBounds.getWidth()), + layerBounds.getY() + layerBounds.getHeight() - (y + viewBounds.getHeight())); + + // Now transform the new view position into global coords + camera.localToView(newPoint); + + // Compute the new matrix values to put the camera at the + // correct location + double newX = - (at.getScaleX() * newPoint.getX() + at.getShearX() * newPoint.getY()); + double newY = - (at.getShearY() * newPoint.getX() + at.getScaleY() * newPoint.getY()); + + at.setTransform(at.getScaleX(), at.getShearY(), at.getShearX(), at.getScaleY(), newX, newY); + + // Now actually set the camera's transform + camera.setViewTransform(at); + scrollInProgress = false; + } + } + } + } + + public static void main(String[] args) { + new ScrollingExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/SelectionExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/SelectionExample.java new file mode 100644 index 0000000..5e120eb --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/SelectionExample.java @@ -0,0 +1,58 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.event.PNotification; +import edu.umd.cs.piccolox.event.PNotificationCenter; +import edu.umd.cs.piccolox.event.PSelectionEventHandler; + +/** + * This example shows how the selection event handler works. + * It creates a bunch of objects that can be selected. + */ +public class SelectionExample extends PFrame { + + public SelectionExample() { + this(null); + } + + public SelectionExample(PCanvas aCanvas) { + super("SelectionExample", false, aCanvas); + } + + public void initialize() { + for (int i=0; i<5; i++) { + for (int j=0; j<5; j++) { + PNode rect = PPath.createRectangle(i*60, j*60, 50, 50); + rect.setPaint(Color.blue); + getCanvas().getLayer().addChild(rect); + } + } + + // Turn off default navigation event handlers + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); + + // Create a selection event handler + PSelectionEventHandler selectionEventHandler = new PSelectionEventHandler(getCanvas().getLayer(), getCanvas().getLayer()); + getCanvas().addInputEventListener(selectionEventHandler); + getCanvas().getRoot().getDefaultInputManager().setKeyboardFocus(selectionEventHandler); + + PNotificationCenter.defaultCenter().addListener(this, + "selectionChanged", + PSelectionEventHandler.SELECTION_CHANGED_NOTIFICATION, + selectionEventHandler); + } + + public void selectionChanged(PNotification notfication) { + System.out.println("selection changed"); + } + + public static void main(String[] args) { + new SelectionExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/SliderExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/SliderExample.java new file mode 100644 index 0000000..fbfa5ed --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/SliderExample.java @@ -0,0 +1,135 @@ +package edu.umd.cs.piccolo.examples; + +import edu.umd.cs.piccolox.pswing.PSwing; +import edu.umd.cs.piccolox.pswing.PSwingCanvas; +import edu.umd.cs.piccolox.swing.PScrollPane; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + + +/** + * Tests a set of Sliders and Checkboxes in panels. + * + * @author Martin Clifford + */ +public class SliderExample extends JFrame { + private PSwingCanvas canvas; + private PScrollPane scrollPane; + private JTabbedPane tabbedPane; + private PSwing swing; + + public SliderExample() { + // Create main panel + JPanel mainPanel = new JPanel( false ); + // Create a tabbed pane + tabbedPane = new JTabbedPane(); + tabbedPane.setPreferredSize( new Dimension( 700, 700 ) ); + // Add tabbed pane to main panel + mainPanel.add( tabbedPane ); + // Set the frame contents + getContentPane().add( mainPanel ); + + // Create a canvas + canvas = new PSwingCanvas(); + canvas.setPreferredSize( new Dimension( 700, 700 ) ); + // Create a scroll pane for the canvas + scrollPane = new PScrollPane( canvas ); + // Create a new tab for the tabbed pane + tabbedPane.add( "Tab 1", scrollPane ); + + // Create the contents for "Tab 1" + JPanel tabPanel = new JPanel( false ); + tabPanel.setLayout( null ); + tabPanel.setPreferredSize( new Dimension( 700, 700 ) ); + // Populate the tab panel with four instances of nested panel. + JPanel panel; + panel = createNestedPanel(); + panel.setSize( new Dimension( 250, 250 ) ); + panel.setLocation( 0, 0 ); + tabPanel.add( panel ); + panel = createNestedPanel(); + panel.setSize( new Dimension( 250, 250 ) ); + panel.setLocation( 0, 350 ); + tabPanel.add( panel ); + panel = createNestedPanel(); + panel.setSize( new Dimension( 250, 250 ) ); + panel.setLocation( 350, 0 ); + tabPanel.add( panel ); + panel = createNestedPanel(); + panel.setSize( new Dimension( 250, 250 ) ); + panel.setLocation( 350, 350 ); + tabPanel.add( panel ); + // Add the default zoom button + JButton buttonPreset = new JButton( "Zoom = 100%" ); + buttonPreset.addActionListener( new ActionListener() { + public void actionPerformed( ActionEvent e ) { + canvas.getCamera().setViewScale( 1.0 ); + canvas.getCamera().setViewOffset( 0, 0 ); + } + } ); + buttonPreset.setSize( new Dimension( 120, 25 ) ); + buttonPreset.setLocation( 240, 285 ); + tabPanel.add( buttonPreset ); + // Create a pswing object for the tab panel + swing = new PSwing( tabPanel ); + swing.translate( 0, 0 ); + // Add the pswing object to the canvas + canvas.getLayer().addChild( swing ); + // Turn off default pan event handling + canvas.setPanEventHandler( null ); + + // Set up basic frame + setDefaultCloseOperation( javax.swing.WindowConstants.DISPOSE_ON_CLOSE ); + setTitle( "Slider Example" ); + setResizable( true ); + setBackground( null ); + pack(); + setVisible( true ); + } + + private JPanel createNestedPanel() { + // A panel MUST be created with double buffering off + JPanel panel; + JLabel label; + panel = new JPanel( false ); + panel.setLayout( new BorderLayout() ); + label = new JLabel( "A Panel within a panel" ); + label.setHorizontalAlignment( SwingConstants.CENTER ); + label.setForeground( Color.white ); + JLabel label2 = new JLabel( "A Panel within a panel" ); + label2.setHorizontalAlignment( SwingConstants.CENTER ); + JSlider slider = new JSlider(); + JCheckBox cbox1 = new JCheckBox( "Checkbox 1" ); + JCheckBox cbox2 = new JCheckBox( "Checkbox 2" ); + JPanel panel3 = new JPanel( false ); + panel3.setLayout( new BoxLayout( panel3, BoxLayout.PAGE_AXIS ) ); + panel3.setBorder( new EmptyBorder( 3, 3, 3, 3 ) ); + panel3.add( label2 ); + panel3.add( slider ); + panel3.add( cbox1 ); + panel3.add( cbox2 ); + JPanel panel2 = new JPanel( false ); + panel2.setBackground( Color.blue ); + panel.setBorder( new EmptyBorder( 1, 1, 1, 1 ) ); + panel2.add( label ); + panel2.add( panel3 ); + panel.setBackground( Color.red ); + panel.setSize( new Dimension( 250, 250 ) ); + panel.setBorder( new EmptyBorder( 5, 5, 5, 5 ) ); + panel.add( panel2, "Center" ); + panel.revalidate(); + return panel; + } + + public static void main( String[] args ) { + SwingUtilities.invokeLater( new Runnable() { + public void run() { + new SliderExample(); + } + } ); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/SquiggleExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/SquiggleExample.java new file mode 100644 index 0000000..bfc8b77 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/SquiggleExample.java @@ -0,0 +1,75 @@ + +package edu.umd.cs.piccolo.examples; +import java.awt.BasicStroke; +import java.awt.event.InputEvent; +import java.awt.geom.Point2D; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.event.PInputEventFilter; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +public class SquiggleExample extends PFrame { + + private PLayer layer; + + public SquiggleExample() { + this(null); + } + + public SquiggleExample(PCanvas aCanvas) { + super("SquiggleExample", false, aCanvas); + } + + public void initialize() { + super.initialize(); + PBasicInputEventHandler squiggleEventHandler = createSquiggleEventHandler(); + squiggleEventHandler.setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + getCanvas().addInputEventListener(squiggleEventHandler); + layer = getCanvas().getLayer(); + } + + public PBasicInputEventHandler createSquiggleEventHandler() { + return new PDragSequenceEventHandler() { + + protected PPath squiggle; + + public void startDrag(PInputEvent e) { + super.startDrag(e); + + Point2D p = e.getPosition(); + + squiggle = new PPath(); + squiggle.moveTo((float)p.getX(), (float)p.getY()); + squiggle.setStroke(new BasicStroke((float)(1/ e.getCamera().getViewScale()))); + layer.addChild(squiggle); + } + + public void drag(PInputEvent e) { + super.drag(e); + updateSquiggle(e); + } + + public void endDrag(PInputEvent e) { + super.endDrag(e); + updateSquiggle(e); + squiggle = null; + } + + public void updateSquiggle(PInputEvent aEvent) { + Point2D p = aEvent.getPosition(); + squiggle.lineTo((float)p.getX(), (float)p.getY()); + } + }; + } + + public static void main(String[] args) { + new SquiggleExample(); + } +} + diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/StickyExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/StickyExample.java new file mode 100644 index 0000000..4de65ff --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/StickyExample.java @@ -0,0 +1,31 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PBoundsHandle; + +public class StickyExample extends PFrame { + + public StickyExample() { + this(null); + } + + public StickyExample(PCanvas aCanvas) { + super("StickyExample", false, aCanvas); + } + + public void initialize() { + PPath sticky = PPath.createRectangle(0, 0, 50, 50); + sticky.setPaint(Color.YELLOW); + sticky.setStroke(null); + PBoundsHandle.addBoundsHandlesTo(sticky); + getCanvas().getLayer().addChild(PPath.createRectangle(0, 0, 100, 80)); + getCanvas().getCamera().addChild(sticky); + } + + public static void main(String[] args) { + new StickyExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/StickyHandleLayerExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/StickyHandleLayerExample.java new file mode 100644 index 0000000..e22e606 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/StickyHandleLayerExample.java @@ -0,0 +1,77 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.Color; +import java.util.Iterator; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.PRoot; +import edu.umd.cs.piccolo.activities.PActivity; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PBoundsHandle; +import edu.umd.cs.piccolox.handles.PHandle; +import edu.umd.cs.piccolox.util.PBoundsLocator; + +/** +* This example shows another way to create sticky handles. These handles are + * not added as children to the object that they manipulate. Instead they are + * added to the camera the views that objects. This means that they will not be + * affected by the cameras view transform, and so will stay the same size when + * the view is zoomed. They will also be drawn on top of all other objects, even + * if those objects overlap the object that they manipulate. For this setup we + * need to add and updateHandles activity that makes sure to relocate the handle + * after any change. Another way to do this would be to add change listeners to + * the camera and the node that they manipulate and only update them then. But + * this method is easier and should be plenty efficient for normal use. + * + * @author jesse + */ +public class StickyHandleLayerExample extends PFrame { + + public StickyHandleLayerExample() { + this(null); + } + + public StickyHandleLayerExample(PCanvas aCanvas) { + super("StickyHandleLayerExample", false, aCanvas); + } + + public void initialize() { + PCanvas c = getCanvas(); + + PActivity updateHandles = new PActivity(-1, 0) { + protected void activityStep(long elapsedTime) { + super.activityStep(elapsedTime); + + PRoot root = getActivityScheduler().getRoot(); + + if (root.getPaintInvalid() || root.getChildPaintInvalid()) { + Iterator i = getCanvas().getCamera().getChildrenIterator(); + while (i.hasNext()) { + PNode each = (PNode) i.next(); + if (each instanceof PHandle) { + PHandle handle = (PHandle) each; + handle.relocateHandle(); + } + } + } + } + }; + + PPath rect = PPath.createRectangle(0, 0, 100, 100); + rect.setPaint(Color.RED); + c.getLayer().addChild(rect); + + c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createNorthEastLocator(rect))); + c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createNorthWestLocator(rect))); + c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createSouthEastLocator(rect))); + c.getCamera().addChild(new PBoundsHandle(PBoundsLocator.createSouthWestLocator(rect))); + + c.getRoot().getActivityScheduler().addActivity(updateHandles, true); + } + + public static void main(String[] args) { + new StickyHandleLayerExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/TextExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/TextExample.java new file mode 100644 index 0000000..f78c650 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/TextExample.java @@ -0,0 +1,29 @@ +package edu.umd.cs.piccolo.examples; + +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.event.PStyledTextEventHandler; + +/** + * @author Lance Good + */ +public class TextExample extends PFrame { + + public TextExample() { + this(null); + } + + public TextExample(PCanvas aCanvas) { + super("TextExample", false, aCanvas); + } + + public void initialize() { + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + PStyledTextEventHandler textHandler = new PStyledTextEventHandler(getCanvas()); + getCanvas().addInputEventListener(textHandler); + } + + public static void main(String[] args) { + new TextExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/TooltipExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/TooltipExample.java new file mode 100644 index 0000000..fad544b --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/TooltipExample.java @@ -0,0 +1,70 @@ +package edu.umd.cs.piccolo.examples; + +import java.awt.geom.Point2D; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolo.nodes.PText; +import edu.umd.cs.piccolox.PFrame; + +/** + * Simple example of one way to add tooltips + * + * @author jesse + */ +public class TooltipExample extends PFrame { + + public TooltipExample() { + this(null); + } + + public TooltipExample(PCanvas aCanvas) { + super("TooltipExample", false, aCanvas); + } + + public void initialize() { + PNode n1 = PPath.createEllipse(0, 0, 100, 100); + PNode n2 = PPath.createRectangle(300, 200, 100, 100); + + n1.addAttribute("tooltip", "node 1"); + n2.addAttribute("tooltip", "node 2"); + getCanvas().getLayer().addChild(n1); + getCanvas().getLayer().addChild(n2); + + final PCamera camera = getCanvas().getCamera(); + final PText tooltipNode = new PText(); + + tooltipNode.setPickable(false); + camera.addChild(tooltipNode); + + camera.addInputEventListener(new PBasicInputEventHandler() { + public void mouseMoved(PInputEvent event) { + updateToolTip(event); + } + + public void mouseDragged(PInputEvent event) { + updateToolTip(event); + } + + public void updateToolTip(PInputEvent event) { + PNode n = event.getInputManager().getMouseOver().getPickedNode(); + String tooltipString = (String) n.getAttribute("tooltip"); + Point2D p = event.getCanvasPosition(); + + event.getPath().canvasToLocal(p, camera); + + tooltipNode.setText(tooltipString); + tooltipNode.setOffset(p.getX() + 8, + p.getY() - 8); + } + }); + } + + public static void main(String[] argv) { + new TooltipExample(); + } +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/TwoCanvasExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/TwoCanvasExample.java new file mode 100644 index 0000000..9955356 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/TwoCanvasExample.java @@ -0,0 +1,50 @@ +package edu.umd.cs.piccolo.examples; +import java.awt.Color; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.PRoot; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; +import edu.umd.cs.piccolox.handles.PBoundsHandle; + +public class TwoCanvasExample extends PFrame { + + public TwoCanvasExample() { + this(null); + } + + public TwoCanvasExample(PCanvas aCanvas) { + super("TwoCanvasExample", false, aCanvas); + } + + public void initialize() { + PRoot root = getCanvas().getRoot(); + PLayer layer = getCanvas().getLayer(); + + PNode n = PPath.createRectangle(0, 0, 100, 80); + PNode sticky = PPath.createRectangle(0, 0, 50, 50); + PBoundsHandle.addBoundsHandlesTo(n); + sticky.setPaint(Color.YELLOW); + PBoundsHandle.addBoundsHandlesTo(sticky); + + layer.addChild(n); + getCanvas().getCamera().addChild(sticky); + + PCamera otherCamera = new PCamera(); + otherCamera.addLayer(layer); + root.addChild(otherCamera); + + PCanvas other = new PCanvas(); + other.setCamera(otherCamera); + PFrame result = new PFrame("TwoCanvasExample", false, other); + result.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + result.setLocation(500, 100); + } + + public static void main(String[] args) { + new TwoCanvasExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/WaitForActivitiesExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/WaitForActivitiesExample.java new file mode 100644 index 0000000..5009e14 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/WaitForActivitiesExample.java @@ -0,0 +1,41 @@ +package edu.umd.cs.piccolo.examples; +import edu.umd.cs.piccolo.PCanvas; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.activities.PActivity; +import edu.umd.cs.piccolo.nodes.PPath; +import edu.umd.cs.piccolox.PFrame; + +/** + * This example shows how to use setTriggerTime to synchronize the start and end of + * two activities. + */ +public class WaitForActivitiesExample extends PFrame { + + public WaitForActivitiesExample() { + this(null); + } + + public WaitForActivitiesExample(PCanvas aCanvas) { + super("WaitForActivitiesExample", false, aCanvas); + } + + public void initialize() { + PLayer layer = getCanvas().getLayer(); + + PNode a = PPath.createRectangle(0, 0, 100, 80); + PNode b = PPath.createRectangle(0, 0, 100, 80); + + layer.addChild(a); + layer.addChild(b); + + PActivity a1 = a.animateToPositionScaleRotation(200, 200, 1, 0, 5000); + PActivity a2 = b.animateToPositionScaleRotation(200, 200, 1, 0, 5000); + + a2.startAfter(a1); + } + + public static void main(String[] args) { + new WaitForActivitiesExample(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTBasicExample.java b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTBasicExample.java new file mode 100644 index 0000000..b2a9b40 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTBasicExample.java @@ -0,0 +1,73 @@ +package edu.umd.cs.piccolo.swtexamples; + +import java.awt.Color; + +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import edu.umd.cs.piccolox.swt.PSWTCanvas; +import edu.umd.cs.piccolox.swt.PSWTPath; +import edu.umd.cs.piccolox.swt.PSWTText; + +/** + * @author good + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class SWTBasicExample { + + /** + * Constructor for SWTBasicExample. + */ + public SWTBasicExample() { + super(); + } + + public static void main(String[] args) { + Display display = new Display (); + Shell shell = open (display); + while (!shell.isDisposed ()) { + if (!display.readAndDispatch ()) display.sleep (); + } + display.dispose (); + } + + public static Shell open(Display display) { + final Shell shell = new Shell (display); + shell.setLayout(new FillLayout()); + PSWTCanvas canvas = new PSWTCanvas(shell,0); + + PSWTPath rect = PSWTPath.createRectangle(25,25,50,50); + rect.setPaint(Color.red); + canvas.getLayer().addChild(rect); + + rect = PSWTPath.createRectangle(300,25,100,50); + rect.setPaint(Color.blue); + canvas.getLayer().addChild(rect); + + PSWTPath circle = PSWTPath.createEllipse(100,200,50,50); + circle.setPaint(Color.green); + canvas.getLayer().addChild(circle); + + circle = PSWTPath.createEllipse(400,400,75,150); + circle.setPaint(Color.yellow); + canvas.getLayer().addChild(circle); + + PSWTText text = new PSWTText("Hello World"); + text.translate(350,150); + text.setPenColor(Color.gray); + canvas.getLayer().addChild(text); + + text = new PSWTText("Goodbye World"); + text.translate(50,400); + text.setPenColor(Color.magenta); + canvas.getLayer().addChild(text); + + shell.open (); + return shell; + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTBenchTest.java b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTBenchTest.java new file mode 100644 index 0000000..c9839ef --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTBenchTest.java @@ -0,0 +1,418 @@ +/* + * Copyright (C) 1998-2002 by University of Maryland, College Park, MD 20742, USA + * All rights reserved. + */ +package edu.umd.cs.piccolo.swtexamples; + +import java.util.Random; +import java.io.*; +import java.awt.*; +import java.awt.geom.*; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import edu.umd.cs.piccolox.swt.SWTGraphics2D; + +/** + * Benchmarking test suite for SWT package + */ +public class SWTBenchTest extends Canvas { + + // Paths + GeneralPath testShape = new GeneralPath(); + + // Images + Image testImageOpaque, testImageBitmask, testImageTranslucent, testImageARGB; + + // Transforms + AffineTransform transform = new AffineTransform(); + static final AffineTransform IDENTITY = new AffineTransform(); + + // Geometry + double pts[] = new double[20]; + + // Colors + static final Color colors[] = { + Color.red, Color.green, Color.blue, Color.white, Color.yellow, + }; + + // Flags + boolean offscreen; + boolean antialiased; + + // Statistics + int results[][] = new int[NUM_CONTEXTS][NUM_TESTS]; + + + // Constants + + static final int CTX_NORMAL = 0; +// static final int CTX_CLIPPED = 1; + static final int CTX_TRANSFORMED = 1; +// static final int CTX_BLENDED = 3; + static final int NUM_CONTEXTS = 2; + +// static String contextNames[] = { +// "normal", +// "clip", +// "transform", +// "alpha", +// }; + + static String contextNames[] = { + "normal", + "transform" + }; + + + // + // TEST METHODS + // + + static final int DRAW_LINE = 0; + static final int DRAW_RECT = 1; + static final int FILL_RECT = 2; + static final int DRAW_OVAL = 3; + static final int FILL_OVAL = 4; + static final int DRAW_POLY = 5; + static final int FILL_POLY = 6; + static final int DRAW_TEXT = 7; + static final int DRAW_IMG1 = 8; + static final int DRAW_IMG2 = 9; + static final int DRAW_IMG3 = 10; + static final int DRAW_IMG4 = 11; + static final int DRAW_IMG5 = 12; + static final int NUM_TESTS = 13; + + static String testNames[] = { + "line", + "rect", + "fill rect", + "oval", + "fill oval", + "poly", + "fill poly", + "text", + "image", + "scaled image", + "mask image", + "alpha image", + "argb image", + }; + + void testDrawLine(SWTGraphics2D g, Random r) { + g.drawLine(rand(r), rand(r), rand(r), rand(r)); + } + + void testDrawRect(SWTGraphics2D g, Random r) { + g.drawRect(rand(r), rand(r), rand(r), rand(r)); + } + + void testFillRect(SWTGraphics2D g, Random r) { + g.fillRect(rand(r), rand(r), rand(r), rand(r)); + } + + void testDrawOval(SWTGraphics2D g, Random r) { + g.drawOval(rand(r), rand(r), rand(r), rand(r)); + } + + void testFillOval(SWTGraphics2D g, Random r) { + g.fillOval(rand(r), rand(r), rand(r), rand(r)); + } + + void genPoly(Random r) { + for (int i = 0; i < pts.length/2; i++) { + pts[2*i] = rand(r); + pts[2*i+1] = rand(r); + } + } + + void testDrawPoly(SWTGraphics2D g, Random r) { + genPoly(r); + g.drawPolyline(pts); + } + + void testFillPoly(SWTGraphics2D g, Random r) { + genPoly(r); + g.fillPolygon(pts); + } + + void testDrawText(SWTGraphics2D g, Random r) { + g.drawString("Abcdefghijklmnop", rand(r), rand(r)); + } + + // Basic image + void testDrawImg1(SWTGraphics2D g, Random r) { + g.drawImage(testImageOpaque, rand(r), rand(r)); + } + + // Scaled image + void testDrawImg2(SWTGraphics2D g, Random r) { + Rectangle rect = testImageOpaque.getBounds(); + g.drawImage(testImageOpaque, 0, 0, rect.width, rect.height, rand(r), rand(r), rand(r), rand(r)); + } + + // Bitmask image (unscaled) + void testDrawImg3(SWTGraphics2D g, Random r) { + g.drawImage(testImageBitmask, rand(r), rand(r)); + } + + // Translucent image (unscaled) + void testDrawImg4(SWTGraphics2D g, Random r) { + g.drawImage(testImageTranslucent, rand(r), rand(r)); + } + + // Buffered image (unscaled) + void testDrawImg5(SWTGraphics2D g, Random r) { + g.drawImage(testImageARGB, rand(r), rand(r)); + } + + Image loadImage(Display display, String name) { + try { + InputStream stream = SWTBenchTest.class.getResourceAsStream(name); + if (stream != null) { + ImageData imageData = new ImageData(stream); + return new Image(display,imageData); +// if (imageData != null) { +// ImageData mask = imageData.getTransparencyMask(); +// return new Image(display, imageData, mask); +// } + + } + } catch (Exception e) { + } + return null; + } + + SWTBenchTest(Composite parent, int style) { + super(parent,style); + + testImageOpaque = loadImage(getDisplay(),"opaque.jpg"); + testImageBitmask = loadImage(getDisplay(),"bitmask.gif"); + testImageTranslucent = loadImage(getDisplay(),"translucent.png"); + testImageARGB = new Image(getDisplay(),128, 128); + + GC tmpGC = new GC(testImageARGB); + tmpGC.drawImage(testImageTranslucent,0,0); + tmpGC.dispose(); + + addPaintListener(new PaintListener() { + public void paintControl(PaintEvent pe) { + runAll(new SWTGraphics2D(pe.gc,getDisplay())); + } + }); + } + + void setupTransform(Graphics2D g, Random r) { + transform.setToIdentity(); + + switch (abs(r.nextInt()) % 5) { + default: +// case 0: // UNIFORM SCALE + double s = r.nextDouble(); + transform.scale(5*s + 0.1, 5*s + 0.1); + break; +// case 1: // NON-UNIFORM SCALE +// transform.scale(5 * r.nextDouble() + 0.1, 5 * r.nextDouble() + 0.1); +// break; +// case 2: // ROTATION +// transform.rotate(r.nextDouble() * Math.PI * 2); +// break; +// case 3: // TRANSLATION +// transform.translate(r.nextDouble() * 500, r.nextDouble() * 500); +// break; +// case 4: // TRANSLATE + ROTATE + SCALE +// s = r.nextDouble(); +// transform.translate(r.nextDouble() * 500, r.nextDouble() * 500); +// transform.rotate(r.nextDouble() * Math.PI * 2); +// transform.scale(5*s + 0.1, 5*s + 0.1); +// break; + } + + g.setTransform(transform); + } + + void setupClip(Graphics2D g, Random r) { +// g.setClip(rand(r), rand(r), rand(r), rand(r)); + } + + void setupBlend(Graphics2D g, Random r) { + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, r.nextFloat())); + } + + void setup(int ctx, Graphics2D g, Random r) { + switch (ctx) { + case CTX_NORMAL: + break; + + case CTX_TRANSFORMED: + setupTransform(g, r); + break; + +// case CTX_CLIPPED: +// setupClip(g, r); +// break; +// +// case CTX_BLENDED: +// setupBlend(g, r); +// break; + } + } + + void test(int testNum, SWTGraphics2D g, Random r) { + + g.setColor(colors[abs(r.nextInt()) % colors.length]); + g.setBackground(colors[abs(r.nextInt()) % colors.length]); + + switch (testNum) { + case DRAW_LINE: testDrawLine(g, r); break; + case DRAW_RECT: testDrawRect(g, r); break; + case FILL_RECT: testFillRect(g, r); break; + case DRAW_OVAL: testDrawOval(g, r); break; + case FILL_OVAL: testFillOval(g, r); break; + case DRAW_POLY: testDrawPoly(g, r); break; + case FILL_POLY: testFillPoly(g, r); break; + case DRAW_TEXT: testDrawText(g, r); break; + case DRAW_IMG1: testDrawImg1(g, r); break; + case DRAW_IMG2: testDrawImg2(g, r); break; + case DRAW_IMG3: testDrawImg3(g, r); break; + case DRAW_IMG4: testDrawImg4(g, r); break; + case DRAW_IMG5: testDrawImg5(g, r); break; + } + } + + void runTest(SWTGraphics2D g, int ctx, int testNum) { + Random r1 = new Random(1); + Random r2 = new Random(1); + + System.out.println("Test: " + testNames[testNum]); + long t1 = System.currentTimeMillis(); + int i = 0; + while (true) { + if (i % 10 == 0) setup(ctx, g, r1); + test(testNum, g, r2); + i++; + long t2 = System.currentTimeMillis(); + if (t2 - t1 >= 5000) { + break; + } + } + results[ctx][testNum] += i / 5; + System.out.println("Shapes per second: " + (results[ctx][testNum])); + } + + void runAll(SWTGraphics2D g) { + System.out.println("BENCHMARKING: " + g); + + if (antialiased) { + System.out.println("ANTIALIASED"); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } + + for (int ctx = 0; ctx < NUM_CONTEXTS; ctx++) { + System.out.println("Context: " + contextNames[ctx]); + for (int i = 0; i < NUM_TESTS; i++) { + g.setClip(null); + g.setTransform(IDENTITY); + runTest(g, ctx, i); + } + } + + if (offscreen) { + g.dispose(); + } + + String fileName = g.getClass().getName().replace('.', '_'); + if (offscreen) fileName += "-offscreen"; + if (antialiased) fileName += "-antialiased"; + dumpResults(fileName + ".txt"); + System.exit(0); + } + + void dumpResults(String fileName) { + try { + FileOutputStream fout = new FileOutputStream(fileName); + PrintWriter out = new PrintWriter(fout); + out.print('\t'); + for (int i = 0; i < NUM_TESTS; i++) { + out.print(testNames[i]); + out.print('\t'); + } + out.println(""); + for (int ctx = 0; ctx < NUM_CONTEXTS; ctx++) { + out.print(contextNames[ctx]); + for (int i = 0; i < NUM_TESTS; i++) { + out.print('\t'); + out.print(results[ctx][i]); + } + out.println(""); + } + out.close(); + results = new int[NUM_CONTEXTS][NUM_TESTS]; + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + + public Point computeSize(int wHint, int hHint) { + return new Point(512,512); + } + + public Point computeSize(int wHint, int hHint, boolean changed) { + return computeSize(wHint,hHint); + } + + final static int abs(int x) { + return (x < 0 ? -x : x); + } + + final static double rand(Random r) { + return abs(r.nextInt()) % 500; + } + + public static void main(String args[]) { + // Create frame + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + + // Add bench test + SWTBenchTest m = new SWTBenchTest(shell,SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND); + m.setSize(512,512); + for (int i = 0; i < args.length; i++) { + if (args[i].intern() == "-offscreen") + m.offscreen = true; + else if (args[i].intern() == "-anti") + m.antialiased = true; + else { + System.out.println("Usage: java BenchTest [-anti] [-offscreen]"); + System.exit(1); + } + } + + shell.pack(); + shell.open(); + + while (!shell.isDisposed ()) { + if (!display.readAndDispatch ()) display.sleep (); + } + display.dispose (); + } + +} \ No newline at end of file diff --git a/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTHelloWorld.java b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTHelloWorld.java new file mode 100644 index 0000000..ca94965 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/SWTHelloWorld.java @@ -0,0 +1,47 @@ +package edu.umd.cs.piccolo.swtexamples; + +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import edu.umd.cs.piccolox.swt.PSWTCanvas; +import edu.umd.cs.piccolox.swt.PSWTText; + +/** + * @author good + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class SWTHelloWorld { + + /** + * Constructor for SWTBasicExample. + */ + public SWTHelloWorld() { + super(); + } + + public static void main(String[] args) { + Display display = new Display (); + Shell shell = open (display); + while (!shell.isDisposed ()) { + if (!display.readAndDispatch ()) display.sleep (); + } + display.dispose (); + } + + public static Shell open(Display display) { + final Shell shell = new Shell (display); + shell.setLayout(new FillLayout()); + PSWTCanvas canvas = new PSWTCanvas(shell,0); + + PSWTText text = new PSWTText("Hello World"); + canvas.getLayer().addChild(text); + + shell.open (); + return shell; + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/bitmask.gif b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/bitmask.gif new file mode 100644 index 0000000..053a5da --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/bitmask.gif Binary files differ diff --git a/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/opaque.jpg b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/opaque.jpg new file mode 100644 index 0000000..2ff5ba6 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/opaque.jpg Binary files differ diff --git a/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/translucent.png b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/translucent.png new file mode 100644 index 0000000..07601a7 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/swtexamples/translucent.png Binary files differ diff --git a/examples/src/main/java/edu/umd/cs/piccolo/tutorial/InterfaceFrame.java b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/InterfaceFrame.java new file mode 100644 index 0000000..a142264 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/InterfaceFrame.java @@ -0,0 +1,134 @@ +package edu.umd.cs.piccolo.tutorial; + +import java.awt.Color; +import java.awt.Graphics2D; + +import edu.umd.cs.piccolo.*; +import edu.umd.cs.piccolo.event.*; +import edu.umd.cs.piccolo.nodes.*; +import edu.umd.cs.piccolo.util.*; +import edu.umd.cs.piccolox.*; + +public class InterfaceFrame extends PFrame { + + public void initialize() { + // Remove the Default pan event handler and add a drag event handler + // so that we can drag the nodes around individually. + getCanvas().setPanEventHandler(null); + getCanvas().addInputEventListener(new PDragEventHandler()); + + // Add Some Default Nodes + + // Create a node. + PNode aNode = new PNode(); + + // A node will not be visible until its bounds and brush are set. + aNode.setBounds(0, 0, 100, 80); + aNode.setPaint(Color.RED); + + // A node needs to be a descendent of the root to be displayed. + PLayer layer = getCanvas().getLayer(); + layer.addChild(aNode); + + // A node can have child nodes added to it. + PNode anotherNode = new PNode(); + anotherNode.setBounds(0, 0, 100, 80); + anotherNode.setPaint(Color.YELLOW); + aNode.addChild(anotherNode); + + // The base bounds of a node are easy to change. Changing the bounds + // of a node will not affect it's children. + aNode.setBounds(-10, -10, 200, 110); + + // Each node has a transform that can be used to modify the position, + // scale or rotation of a node. Changing a node's transform, will + // transform all of its children as well. + aNode.translate(100, 100); + aNode.scale(1.5f); + aNode.rotate(45); + + // Add a couple of PPath nodes and a PText node. + layer.addChild(PPath.createEllipse(0, 0, 100, 100)); + layer.addChild(PPath.createRectangle(0, 100, 100, 100)); + layer.addChild(new PText("Hello World")); + + // Here we create a PImage node that displays a thumbnail image + // of the root node. Then we add the new PImage to the main layer. + PImage image = new PImage(layer.toImage(300, 300, null)); + layer.addChild(image); + + // Create a New Node using Composition + + PNode myCompositeFace = PPath.createRectangle(0, 0, 100, 80); + + // Create parts for the face. + PNode eye1 = PPath.createEllipse(0, 0, 20, 20); + eye1.setPaint(Color.YELLOW); + PNode eye2 = (PNode) eye1.clone(); + PNode mouth = PPath.createRectangle(0, 0, 40, 20); + mouth.setPaint(Color.BLACK); + + // Add the face parts. + myCompositeFace.addChild(eye1); + myCompositeFace.addChild(eye2); + myCompositeFace.addChild(mouth); + + // Don't want anyone grabbing out our eye's. + myCompositeFace.setChildrenPickable(false); + + // Position the face parts. + eye2.translate(25, 0); + mouth.translate(0, 30); + + // Set the face bounds so that it neatly contains the face parts. + PBounds b = myCompositeFace.getUnionOfChildrenBounds(null); + b.inset(-5, -5); + myCompositeFace.setBounds(b); + + // Opps its to small, so scale it up. + myCompositeFace.scale(1.5); + + layer.addChild(myCompositeFace); + + // Create a New Node using Inheritance. + ToggleShape ts = new ToggleShape(); + ts.setPaint(Color.ORANGE); + layer.addChild(ts); + } + + class ToggleShape extends PPath { + + private boolean fIsPressed = false; + + public ToggleShape() { + setPathToEllipse(0, 0, 100, 80); + + addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent event) { + super.mousePressed(event); + fIsPressed = true; + repaint(); + } + public void mouseReleased(PInputEvent event) { + super.mouseReleased(event); + fIsPressed = false; + repaint(); + } + }); + } + + protected void paint(PPaintContext paintContext) { + if (fIsPressed) { + Graphics2D g2 = paintContext.getGraphics(); + g2.setPaint(getPaint()); + g2.fill(getBoundsReference()); + } else { + super.paint(paintContext); + } + } + } + + public static void main(String[] args) { + new InterfaceFrame(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/tutorial/PiccoloPresentation.java b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/PiccoloPresentation.java new file mode 100644 index 0000000..3fe86d6 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/PiccoloPresentation.java @@ -0,0 +1,106 @@ +package edu.umd.cs.piccolo.tutorial; + +import java.awt.Color; +import java.awt.event.KeyEvent; +import java.awt.geom.AffineTransform; +import java.io.File; +import java.util.ArrayList; + +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.event.PBasicInputEventHandler; +import edu.umd.cs.piccolo.event.PInputEvent; +import edu.umd.cs.piccolo.nodes.PImage; +import edu.umd.cs.piccolox.PFrame; + +public class PiccoloPresentation extends PFrame { + + protected PNode slideBar; + protected PNode currentSlide; + protected PBasicInputEventHandler eventHandler; + protected ArrayList slides = new ArrayList(); + + public PiccoloPresentation() { + super(); + } + + public void initialize() { + setFullScreenMode(true); + loadSlides(); + + eventHandler = new PBasicInputEventHandler() { + public void keyReleased(PInputEvent event) { + if (event.getKeyCode() == KeyEvent.VK_SPACE) { + int newIndex = slides.indexOf(currentSlide) + 1; + if (newIndex < slides.size()) { + goToSlide((PNode)slides.get(newIndex)); + } + } + } + + public void mouseReleased(PInputEvent event) { + PNode picked = event.getPickedNode(); + + if (picked.getParent() == slideBar) { + picked.moveToFront(); + if (picked.getScale() == 1) { + goToSlide(null); + } else { + goToSlide(picked); + } + } + } + }; + + getCanvas().requestFocus(); + getCanvas().addInputEventListener(eventHandler); + getCanvas().getRoot().getDefaultInputManager().setKeyboardFocus(eventHandler); + getCanvas().removeInputEventListener(getCanvas().getZoomEventHandler()); + getCanvas().removeInputEventListener(getCanvas().getPanEventHandler()); + } + + public void goToSlide(PNode slide) { + if (currentSlide != null) { + currentSlide.animateToTransform((AffineTransform)currentSlide.getAttribute("small"), 1000); + } + + currentSlide = slide; + + if (currentSlide != null) { + currentSlide.moveToFront(); + currentSlide.animateToTransform((AffineTransform)currentSlide.getAttribute("large"), 1000); + } + } + + public void loadSlides() { + slideBar = new PNode(); + slideBar.setPaint(Color.DARK_GRAY); + slideBar.setBounds(0, 0, getCanvas().getWidth(), 100); + slideBar.setOffset(0, getCanvas().getHeight() - 100); + getCanvas().getLayer().addChild(slideBar); + + File[] slideFiles = new File("slides").listFiles(); + for (int i = 0; i < slideFiles.length; i++) { + PNode slide = new PImage(slideFiles[i].getPath()); + + if (slide.getHeight() != (getHeight() - 100)) { + slide = new PImage(slide.toImage(getWidth(), getHeight() - 100, null)); + } + slide.offset((getWidth() - slide.getWidth()) / 2, - (getHeight() - 100)); + slide.addAttribute("large", slide.getTransform()); + + slide.setTransform(new AffineTransform()); + slide.scale((100 - 20) / slide.getHeight()); + slide.offset(i * (slide.getFullBoundsReference().getWidth() + 10) + 10, 10); + slide.addAttribute("small", slide.getTransform()); + + slideBar.addChild(slide); + slides.add(slide); + } + + goToSlide((PNode)slides.get(0)); + } + + public static void main(String[] argv) { + new PiccoloPresentation(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/tutorial/SpecialEffects.java b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/SpecialEffects.java new file mode 100644 index 0000000..a49f2c0 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/SpecialEffects.java @@ -0,0 +1,78 @@ +package edu.umd.cs.piccolo.tutorial; + +import java.awt.Color; + +import edu.umd.cs.piccolo.*; +import edu.umd.cs.piccolo.activities.*; +import edu.umd.cs.piccolo.nodes.*; +import edu.umd.cs.piccolox.*; + +public class SpecialEffects extends PFrame { + public void initialize() { + // Create the Target for our Activities. + + // Create a new node that we will apply different activities to, and + // place that node at location 200, 200. + final PNode aNode = PPath.createRectangle(0, 0, 100, 80); + PLayer layer = getCanvas().getLayer(); + layer.addChild(aNode); + aNode.setOffset(200, 200); + + // Extend PActivity. + + // Store the current time in milliseconds for use below. + long currentTime = System.currentTimeMillis(); + + // Create a new custom "flash" activity. This activity will start running in + // five seconds, and while it runs it will flash aNode's paint between + // red and green every half second. + PActivity flash = new PActivity(-1, 500, currentTime + 5000) { + boolean fRed = true; + + protected void activityStep(long elapsedTime) { + super.activityStep(elapsedTime); + + // Toggle the target node's brush color between red and green + // each time the activity steps. + if (fRed) { + aNode.setPaint(Color.red); + } else { + aNode.setPaint(Color.green); + } + + fRed = !fRed; + } + }; + + // Schedule the activity. + getCanvas().getRoot().addActivity(flash); + + // Create three activities that animate the node's position. Since our node + // already descends from the root node the animate methods will automatically + // schedule these activities for us. + PActivity a1 = aNode.animateToPositionScaleRotation(0, 0, 0.5, 0, 5000); + PActivity a2 = aNode.animateToPositionScaleRotation(100, 0, 1.5, Math.toRadians(110), 5000); + PActivity a3 = aNode.animateToPositionScaleRotation(200, 100, 1, 0, 5000); + + // The animate activities will start immediately (in the next call to + // PRoot.processInputs) by default. Here we set their start times (in PRoot + // global time) so that they start when the previous one has finished. + a1.setStartTime(currentTime); + a2.startAfter(a1); + a3.startAfter(a2); + + a1.setDelegate(new PActivity.PActivityDelegate() { + public void activityStarted(PActivity activity) { + System.out.println("a1 started"); + } + public void activityStepped(PActivity activity) {} + public void activityFinished(PActivity activity) { + System.out.println("a1 finished"); + } + }); + } + + public static void main(String[] args) { + new SpecialEffects(); + } +} diff --git a/examples/src/main/java/edu/umd/cs/piccolo/tutorial/UserInteraction.java b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/UserInteraction.java new file mode 100644 index 0000000..8233201 --- /dev/null +++ b/examples/src/main/java/edu/umd/cs/piccolo/tutorial/UserInteraction.java @@ -0,0 +1,126 @@ +package edu.umd.cs.piccolo.tutorial; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.geom.Point2D; + +import edu.umd.cs.piccolo.*; +import edu.umd.cs.piccolo.event.*; +import edu.umd.cs.piccolo.nodes.*; +import edu.umd.cs.piccolo.util.*; +import edu.umd.cs.piccolox.*; + +public class UserInteraction extends PFrame { + + public UserInteraction() { + super(); + } + + public void initialize() { + // Create a Camera Event Listener. + + // Remove the pan event handler that is installed by default so that it + // does not conflict with our new squiggle handler. + getCanvas().setPanEventHandler(null); + + // Create a squiggle handler and register it with the Canvas. + PBasicInputEventHandler squiggleHandler = new SquiggleHandler(getCanvas()); + getCanvas().addInputEventListener(squiggleHandler); + + // Create a Node Event Listener. + + // Create a green rectangle node. + PNode nodeGreen = PPath.createRectangle(0, 0, 100, 100); + nodeGreen.setPaint(Color.GREEN); + getCanvas().getLayer().addChild(nodeGreen); + +// Attach event handler directly to the node. +nodeGreen.addInputEventListener(new PBasicInputEventHandler() { + public void mousePressed(PInputEvent event) { + event.getPickedNode().setPaint(Color.ORANGE); + event.getInputManager().setKeyboardFocus(event.getPath()); + event.setHandled(true); + } + public void mouseDragged(PInputEvent event) { + PNode aNode = event.getPickedNode(); + PDimension delta = event.getDeltaRelativeTo(aNode); + aNode.translate(delta.width, delta.height); + event.setHandled(true); + } + public void mouseReleased(PInputEvent event) { + event.getPickedNode().setPaint(Color.GREEN); + event.setHandled(true); + } + public void keyPressed(PInputEvent event) { + PNode node = event.getPickedNode(); + switch (event.getKeyCode()) { + case KeyEvent.VK_UP: + node.translate(0, -10f); + break; + case KeyEvent.VK_DOWN: + node.translate(0, 10f); + break; + case KeyEvent.VK_LEFT: + node.translate(-10f, 0); + break; + case KeyEvent.VK_RIGHT: + node.translate(10f, 0); + break; + } + } +}); + } + + public class SquiggleHandler extends PDragSequenceEventHandler { + protected PCanvas canvas; + + // The squiggle that is currently getting created. + protected PPath squiggle; + + public SquiggleHandler(PCanvas aCanvas) { + canvas = aCanvas; + setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); + } + + public void startDrag(PInputEvent e) { + super.startDrag(e); + + Point2D p = e.getPosition(); + + // Create a new squiggle and add it to the canvas. + squiggle = new PPath(); + squiggle.moveTo((float) p.getX(), (float) p.getY()); + squiggle.setStroke(new BasicStroke((float) (1 / e.getCamera().getViewScale()))); + canvas.getLayer().addChild(squiggle); + + // Reset the keydboard focus. + e.getInputManager().setKeyboardFocus(null); + } + + public void drag(PInputEvent e) { + super.drag(e); + // Update the squiggle while dragging. + updateSquiggle(e); + } + + public void endDrag(PInputEvent e) { + super.endDrag(e); + // Update the squiggle one last time. + updateSquiggle(e); + squiggle = null; + } + + public void updateSquiggle(PInputEvent aEvent) { + // Add a new segment to the squiggle from the last mouse position + // to the current mouse position. + Point2D p = aEvent.getPosition(); + squiggle.lineTo((float) p.getX(), (float) p.getY()); + } + } + + public static void main(String[] args) { + new UserInteraction(); + } +} diff --git a/extras/edu/umd/cs/piccolox/PApplet.java b/extras/edu/umd/cs/piccolox/PApplet.java deleted file mode 100644 index 2233740..0000000 --- a/extras/edu/umd/cs/piccolox/PApplet.java +++ /dev/null @@ -1,69 +0,0 @@ -package edu.umd.cs.piccolox; - -import javax.swing.JApplet; -import javax.swing.SwingUtilities; - -import edu.umd.cs.piccolo.PCanvas; - -/** - * PApplet is meant to be subclassed by applications that just need a PCanvas - * embedded in a web page. - * - * @version 1.0 - * @author Jesse Grosjean - */ -public class PApplet extends JApplet { - - private PCanvas canvas; - - public void init() { - setBackground(null); - - canvas = createCanvas(); - getContentPane().add(canvas); - validate(); - canvas.requestFocus(); - beforeInitialize(); - - // Manipulation of Piccolo's scene graph should be done from Swings - // event dispatch thread since Piccolo is not thread safe. This code calls - // initialize() from that thread once the PFrame is initialized, so you are - // safe to start working with Piccolo in the initialize() method. - SwingUtilities.invokeLater(new Runnable() { - public void run() { - PApplet.this.initialize(); - repaint(); - } - }); - } - - public PCanvas getCanvas() { - return canvas; - } - - public PCanvas createCanvas() { - return new PCanvas(); - } - - //**************************************************************** - // Initialize - //**************************************************************** - - /** - * This method will be called before the initialize() method and will be - * called on the thread that is constructing this object. - */ - public void beforeInitialize() { - } - - /** - * Subclasses should override this method and add their - * Piccolo initialization code there. This method will be called on the - * swing event dispatch thread. Note that the constructors of PFrame - * subclasses may not be complete when this method is called. If you need to - * initailize some things in your class before this method is called place - * that code in beforeInitialize(); - */ - public void initialize() { - } -} \ No newline at end of file diff --git a/extras/edu/umd/cs/piccolox/PFrame.java b/extras/edu/umd/cs/piccolox/PFrame.java deleted file mode 100644 index 77ef011..0000000 --- a/extras/edu/umd/cs/piccolox/PFrame.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox; - -import java.awt.DisplayMode; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.Rectangle; -import java.awt.event.ComponentAdapter; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.util.ArrayList; -import java.util.Collection; -import java.util.EventListener; -import java.util.Iterator; - -import javax.swing.JFrame; -import javax.swing.SwingUtilities; - -import edu.umd.cs.piccolo.PCanvas; - -/** - * PFrame is meant to be subclassed by applications that just need a PCanvas in a JFrame. - * It also includes full screen mode functionality when run in JDK 1.4. These - * subclasses should override the initialize method and start adding their own - * code there. Look in the examples package to see lots of uses of PFrame. - * - * @version 1.0 - * @author Jesse Grosjean - */ -public class PFrame extends JFrame { - - private PCanvas canvas; - private GraphicsDevice graphicsDevice; - private EventListener escapeFullScreenModeListener; - - public PFrame() { - this("", false, null); - } - - public PFrame(String title, boolean fullScreenMode, PCanvas aCanvas) { - this(title, GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(), fullScreenMode, aCanvas); - } - - public PFrame(String title, GraphicsDevice aDevice, final boolean fullScreenMode, final PCanvas aCanvas) { - super(title, aDevice.getDefaultConfiguration()); - - graphicsDevice = aDevice; - - setBackground(null); - setBounds(getDefaultFrameBounds()); - - try { - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - } catch (SecurityException e) {} // expected from applets - - if (aCanvas == null) { - canvas = new PCanvas(); - } else { - canvas = aCanvas; - } - - setContentPane(canvas); - validate(); - setFullScreenMode(fullScreenMode); - canvas.requestFocus(); - beforeInitialize(); - - // Manipulation of Piccolo's scene graph should be done from Swings - // event dispatch thread since Piccolo is not thread safe. This code calls - // initialize() from that thread once the PFrame is initialized, so you are - // safe to start working with Piccolo in the initialize() method. - SwingUtilities.invokeLater(new Runnable() { - public void run() { - PFrame.this.initialize(); - repaint(); - } - }); - } - - public PCanvas getCanvas() { - return canvas; - } - - public Rectangle getDefaultFrameBounds() { - return new Rectangle(100, 100, 400, 400); - } - - //**************************************************************** - // Full Screen Display Mode - //**************************************************************** - - public boolean isFullScreenMode() { - return graphicsDevice.getFullScreenWindow() != null; - } - - public void setFullScreenMode(boolean fullScreenMode) { - if (fullScreenMode) { - addEscapeFullScreenModeListener(); - - if (isDisplayable()) { - dispose(); - } - - setUndecorated(true); - setResizable(false); - graphicsDevice.setFullScreenWindow(this); - - if (graphicsDevice.isDisplayChangeSupported()) { - chooseBestDisplayMode(graphicsDevice); - } - validate(); - } else { - removeEscapeFullScreenModeListener(); - - if (isDisplayable()) { - dispose(); - } - - setUndecorated(false); - setResizable(true); - graphicsDevice.setFullScreenWindow(null); - validate(); - setVisible(true); - } - } - - protected void chooseBestDisplayMode(GraphicsDevice device) { - DisplayMode best = getBestDisplayMode(device); - if (best != null) { - device.setDisplayMode(best); - } - } - - protected DisplayMode getBestDisplayMode(GraphicsDevice device) { - Iterator itr = getPreferredDisplayModes(device).iterator(); - while (itr.hasNext()) { - DisplayMode each = (DisplayMode) itr.next(); - DisplayMode[] modes = device.getDisplayModes(); - for (int i = 0; i < modes.length; i++) { - if (modes[i].getWidth() == each.getWidth() && - modes[i].getHeight() == each.getHeight() && - modes[i].getBitDepth() == each.getBitDepth()) { - return each; - } - } - } - - return null; - } - - /** - * By default return the current display mode. Subclasses may override this method - * to return other modes in the collection. - */ - protected Collection getPreferredDisplayModes(GraphicsDevice device) { - ArrayList result = new ArrayList(); - - result.add(device.getDisplayMode()); - /*result.add(new DisplayMode(640, 480, 32, 0)); - result.add(new DisplayMode(640, 480, 16, 0)); - result.add(new DisplayMode(640, 480, 8, 0));*/ - - return result; - } - - /** - * This method adds a key listener that will take this PFrame out of full - * screen mode when the escape key is pressed. This is called for you - * automatically when the frame enters full screen mode. - */ - public void addEscapeFullScreenModeListener() { - removeEscapeFullScreenModeListener(); - escapeFullScreenModeListener = new KeyAdapter() { - public void keyPressed(KeyEvent aEvent) { - if (aEvent.getKeyCode() == KeyEvent.VK_ESCAPE) { - setFullScreenMode(false); - } - } - }; - canvas.addKeyListener((KeyListener)escapeFullScreenModeListener); - } - - /** - * This method removes the escape full screen mode key listener. It will be - * called for you automatically when full screen mode exits, but the method - * has been made public for applications that wish to use other methods for - * exiting full screen mode. - */ - public void removeEscapeFullScreenModeListener() { - if (escapeFullScreenModeListener != null) { - canvas.removeKeyListener((KeyListener)escapeFullScreenModeListener); - escapeFullScreenModeListener = null; - } - } - - //**************************************************************** - // Initialize - //**************************************************************** - - /** - * This method will be called before the initialize() method and will be - * called on the thread that is constructing this object. - */ - public void beforeInitialize() { - } - - /** - * Subclasses should override this method and add their - * Piccolo initialization code there. This method will be called on the - * swing event dispatch thread. Note that the constructors of PFrame - * subclasses may not be complete when this method is called. If you need to - * initailize some things in your class before this method is called place - * that code in beforeInitialize(); - */ - public void initialize() { - } - - public static void main(String[] argv) { - new PFrame(); - } -} diff --git a/extras/edu/umd/cs/piccolox/activities/PPathActivity.java b/extras/edu/umd/cs/piccolox/activities/PPathActivity.java deleted file mode 100644 index e38a6df..0000000 --- a/extras/edu/umd/cs/piccolox/activities/PPathActivity.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.activities; - -import edu.umd.cs.piccolo.activities.PInterpolatingActivity; - -/** - * PPathActivity is the abstract base class for all path - * activity interpolators. Path activities interpolate between multiple states - * over the duration of the activity. - *

- * Knots are used to determine when in time the activity should move from state - * to state. Knot values should be increasing in value from 0 to 1 inclusive. - * This class is based on the Java 3D PathInterpolator object, see that class - * documentation for more information on the basic concepts used in this classes - * design. - *

- * See PPositionPathActivity for a concrete path activity that will animate - * through a list of points. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public abstract class PPathActivity extends PInterpolatingActivity { - - protected float[] knots; - - public PPathActivity(long duration, long stepRate, float[] knots) { - this(duration, stepRate, 0, PInterpolatingActivity.SOURCE_TO_DESTINATION, knots); - } - - public PPathActivity(long duration, long stepRate, int loopCount, int mode, float[] knots) { - super(duration, stepRate, loopCount, mode); - setKnots(knots); - } - - public int getKnotsLength() { - return knots.length; - } - - public void setKnots(float[] knots) { - this.knots = knots; - } - - public float[] getKnots() { - return knots; - } - - public void setKnot(int index, float knot) { - knots[index] = knot; - } - - public float getKnot(int index) { - return knots[index]; - } - - public void setRelativeTargetValue(float zeroToOne) { - int currentKnotIndex = 0; - - while (zeroToOne > knots[currentKnotIndex]) { - currentKnotIndex++; - } - - int startKnot = currentKnotIndex - 1; - int endKnot = currentKnotIndex; - - if (startKnot < 0) startKnot = 0; - if (endKnot > getKnotsLength() - 1) endKnot = getKnotsLength() - 1; - - float currentRange = knots[endKnot] - knots[startKnot]; - float currentPointOnRange = zeroToOne - knots[startKnot]; - float normalizedPointOnRange = currentPointOnRange; - - if (currentRange != 0) { - normalizedPointOnRange = currentPointOnRange / currentRange; - } - - setRelativeTargetValue(normalizedPointOnRange, startKnot, endKnot); - } - - public abstract void setRelativeTargetValue(float zeroToOne, int startKnot, int endKnot); -} diff --git a/extras/edu/umd/cs/piccolox/activities/PPositionPathActivity.java b/extras/edu/umd/cs/piccolox/activities/PPositionPathActivity.java deleted file mode 100644 index f476913..0000000 --- a/extras/edu/umd/cs/piccolox/activities/PPositionPathActivity.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.activities; - -import java.awt.geom.GeneralPath; -import java.awt.geom.PathIterator; -import java.awt.geom.Point2D; -import java.util.ArrayList; - -import edu.umd.cs.piccolo.activities.PInterpolatingActivity; - -/** - * PPositionPathActivity animates through a sequence of points. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PPositionPathActivity extends PPathActivity { - - protected Point2D[] positions; - protected Target target; - - public interface Target { - public void setPosition(double x, double y); - } - - public PPositionPathActivity(long duration, long stepRate, Target aTarget) { - this(duration, stepRate, aTarget, null, null); - } - - public PPositionPathActivity(long duration, long stepRate, Target aTarget, float[] knots, Point2D[] positions) { - this(duration, stepRate, 1, PInterpolatingActivity.SOURCE_TO_DESTINATION, aTarget, knots, positions); - } - - public PPositionPathActivity(long duration, long stepRate, int loopCount, int mode, Target aTarget, float[] knots, Point2D[] positions) { - super(duration, stepRate, loopCount, mode, knots); - target = aTarget; - this.positions = positions; - } - - protected boolean isAnimation() { - return true; - } - - public Point2D[] getPositions() { - return positions; - } - - public Point2D getPosition(int index) { - return positions[index]; - } - - public void setPositions(Point2D[] positions) { - this.positions = positions; - } - - public void setPosition(int index, Point2D position) { - positions[index] = position; - } - - public void setPositions(GeneralPath path) { - PathIterator pi = path.getPathIterator(null, 1); - ArrayList points = new ArrayList(); - float point[] = new float[6]; - float distanceSum = 0; - float lastMoveToX = 0; - float lastMoveToY = 0; - - while (!pi.isDone()) { - int type = pi.currentSegment(point); - - switch (type) { - case PathIterator.SEG_MOVETO: - points.add(new Point2D.Float(point[0], point[1])); - lastMoveToX = point[0]; - lastMoveToY = point[1]; - break; - - case PathIterator.SEG_LINETO: - points.add(new Point2D.Float(point[0], point[1])); - break; - - case PathIterator.SEG_CLOSE: - points.add(new Point2D.Float(lastMoveToX, lastMoveToY)); - break; - - case PathIterator.SEG_QUADTO: - case PathIterator.SEG_CUBICTO: - throw new RuntimeException(); - } - - if (points.size() > 1) { - Point2D last = (Point2D) points.get(points.size() - 2); - Point2D current = (Point2D) points.get(points.size() - 1); - distanceSum += last.distance(current); - } - - pi.next(); - } - - int size = points.size(); - Point2D newPositions[] = new Point2D[size]; - float newKnots[] = new float[size]; - - for (int i = 0; i < size; i++) { - newPositions[i] = (Point2D) points.get(i); - if (i > 0) { - float dist = (float) newPositions[i - 1].distance(newPositions[i]); - newKnots[i] = newKnots[i - 1] + (dist / distanceSum); - } - } - - setPositions(newPositions); - setKnots(newKnots); - } - - public void setRelativeTargetValue(float zeroToOne, int startKnot, int endKnot) { - Point2D start = getPosition(startKnot); - Point2D end = getPosition(endKnot); - target.setPosition(start.getX() + (zeroToOne * (end.getX() - start.getX())), - start.getY() + (zeroToOne * (end.getY() - start.getY()))); - } -} diff --git a/extras/edu/umd/cs/piccolox/activities/package.html b/extras/edu/umd/cs/piccolox/activities/package.html deleted file mode 100644 index ad0df74..0000000 --- a/extras/edu/umd/cs/piccolox/activities/package.html +++ /dev/null @@ -1,34 +0,0 @@ - - - -

This package provides additional support for Piccolo activities.

- - diff --git a/extras/edu/umd/cs/piccolox/event/PNavigationEventHandler.java b/extras/edu/umd/cs/piccolox/event/PNavigationEventHandler.java deleted file mode 100644 index 38ed096..0000000 --- a/extras/edu/umd/cs/piccolox/event/PNavigationEventHandler.java +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.event; - -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.activities.PActivity; -import edu.umd.cs.piccolo.activities.PTransformActivity; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.event.PInputEventFilter; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PDimension; - -/** - * PNavigationEventHandler implements simple focus based navigation. Uses - * mouse button one or the arrow keys to set a new focus. Animates the canvas - * view to keep the focus node on the screen and at 100 percent scale with minimal - * view movement. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PNavigationEventHandler extends PBasicInputEventHandler { - - public static final int NORTH = 0; - public static final int SOUTH = 1; - public static final int EAST = 2; - public static final int WEST = 3; - public static final int IN = 4; - public static final int OUT = 5; - - private static Hashtable NODE_TO_GLOBAL_NODE_CENTER_MAPPING = new Hashtable(); - - private PNode focusNode; - private PActivity navigationActivity; - - public PNavigationEventHandler() { - super(); - setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); - } - - //**************************************************************** - // Focus Change Events. - //**************************************************************** - - public void keyPressed(PInputEvent e) { - PNode oldLocation = focusNode; - - switch (e.getKeyCode()) { - case KeyEvent.VK_LEFT: - moveFocusLeft(e); - break; - - case KeyEvent.VK_RIGHT: - moveFocusRight(e); - break; - - case KeyEvent.VK_UP: - case KeyEvent.VK_PAGE_UP: - if (e.isAltDown()) { - moveFocusOut(e); - } else { - moveFocusUp(e); - } - break; - - case KeyEvent.VK_DOWN: - case KeyEvent.VK_PAGE_DOWN: - if (e.isAltDown()) { - moveFocusIn(e); - } else { - moveFocusDown(e); - } - break; - } - - if (focusNode != null && oldLocation != focusNode) { - directCameraViewToFocus(e.getCamera(), focusNode, 500); - } - } - - public void mousePressed(PInputEvent aEvent) { - moveFocusToMouseOver(aEvent); - - if (focusNode != null) { - directCameraViewToFocus(aEvent.getCamera(), focusNode, 500); - aEvent.getInputManager().setKeyboardFocus(aEvent.getPath()); - } - } - - //**************************************************************** - // Focus Movement - Moves the focus the specified direction. Left, - // right, up, down mean move the focus to the closest sibling of the - // current focus node that exists in that direction. Move in means - // move the focus to a child of the current focus, move out means - // move the focus to the parent of the current focus. - //**************************************************************** - - public void moveFocusDown(PInputEvent e) { - PNode n = getNeighborInDirection(SOUTH); - - if (n != null) { - focusNode = n; - } - } - - public void moveFocusIn(PInputEvent e) { - PNode n = getNeighborInDirection(IN); - - if (n != null) { - focusNode = n; - } - } - - public void moveFocusLeft(PInputEvent e) { - PNode n = getNeighborInDirection(WEST); - - if (n != null) { - focusNode = n; - } - } - - public void moveFocusOut(PInputEvent e) { - PNode n = getNeighborInDirection(OUT); - - if (n != null) { - focusNode = n; - } - } - - public void moveFocusRight(PInputEvent e) { - PNode n = getNeighborInDirection(EAST); - - if (n != null) { - focusNode = n; - } - } - - public void moveFocusUp(PInputEvent e) { - PNode n = getNeighborInDirection(NORTH); - - if (n != null) { - focusNode = n; - } - } - - public void moveFocusToMouseOver(PInputEvent e) { - PNode focus = e.getPickedNode(); - if (!(focus instanceof PCamera)) { - focusNode = focus; - } - } - - public PNode getNeighborInDirection(int aDirection) { - if (focusNode == null) return null; - - NODE_TO_GLOBAL_NODE_CENTER_MAPPING.clear(); - - Point2D highlightCenter = focusNode.getGlobalFullBounds().getCenter2D(); - NODE_TO_GLOBAL_NODE_CENTER_MAPPING.put(focusNode, highlightCenter); - - List l = getNeighbors(); - sortNodesByDistanceFromPoint(l, highlightCenter); - - Iterator i = l.iterator(); - while (i.hasNext()) { - PNode each = (PNode) i.next(); - if (nodeIsNeighborInDirection(each, aDirection)) { - return each; - } - } - - return null; - } - - public List getNeighbors() { - ArrayList result = new ArrayList(); - - if (focusNode == null) return result; - if (focusNode.getParent() == null) return result; - - PNode focusParent = focusNode.getParent(); - - Iterator i = focusParent.getChildrenIterator(); - - while (i.hasNext()) { - PNode each = (PNode) i.next(); - if (each != focusNode && each.getPickable()) { - result.add(each); - } - } - - result.add(focusParent); - - i = focusNode.getChildrenIterator(); - while (i.hasNext()) { - result.add(i.next()); - } - - return result; - } - - public boolean nodeIsNeighborInDirection(PNode aNode, int aDirection) { - switch (aDirection) { - case IN: { - return aNode.isDescendentOf(focusNode); - } - - case OUT: { - return aNode.isAncestorOf(focusNode); - } - - default: { - if (aNode.isAncestorOf(focusNode) || aNode.isDescendentOf(focusNode)) { - return false; - } - } - } - - Point2D highlightCenter = (Point2D) NODE_TO_GLOBAL_NODE_CENTER_MAPPING.get(focusNode); - Point2D nodeCenter = (Point2D) NODE_TO_GLOBAL_NODE_CENTER_MAPPING.get(aNode); - - double ytest1 = nodeCenter.getX() - highlightCenter.getX() + highlightCenter.getY(); - double ytest2 = -nodeCenter.getX() + highlightCenter.getX() + highlightCenter.getY(); - - switch (aDirection) { - case NORTH: { - if (nodeCenter.getY() < highlightCenter.getY()) { - if (nodeCenter.getY() < ytest1 && nodeCenter.getY() < ytest2) { - return true; - } - } - break; - } - - case EAST: { - if (nodeCenter.getX() > highlightCenter.getX()) { - if (nodeCenter.getY() < ytest1 && nodeCenter.getY() > ytest2) { - return true; - } - } - break; - } - - case SOUTH: { - if (nodeCenter.getY() > highlightCenter.getY()) { - if (nodeCenter.getY() > ytest1 && nodeCenter.getY() > ytest2) { - return true; - } - } - break; - } - case WEST: { - if (nodeCenter.getX() < highlightCenter.getX()) { - if (nodeCenter.getY() > ytest1 && nodeCenter.getY() < ytest2) { - return true; - } - } - break; - } - } - return false; - } - - public void sortNodesByDistanceFromPoint(List aNodesList, final Point2D aPoint) { - Collections.sort(aNodesList, new Comparator() { - public int compare(Object o1, Object o2) { - PNode each1 = (PNode) o1; - PNode each2 = (PNode) o2; - Point2D each1Center = each1.getGlobalFullBounds().getCenter2D(); - Point2D each2Center = each2.getGlobalFullBounds().getCenter2D(); - - NODE_TO_GLOBAL_NODE_CENTER_MAPPING.put(each1, each1Center); - NODE_TO_GLOBAL_NODE_CENTER_MAPPING.put(each2, each2Center); - - double distance1 = aPoint.distance(each1Center); - double distance2 = aPoint.distance(each2Center); - - if (distance1 < distance2) { - return -1; - } else if (distance1 == distance2) { - return 0; - } else { - return 1; - } - } - }); - } - - //**************************************************************** - // Canvas Movement - The canvas view is updated so that the current - // focus remains visible on the screen at 100 percent scale. - //**************************************************************** - - protected PActivity animateCameraViewTransformTo(final PCamera aCamera, AffineTransform aTransform, int duration) { - boolean wasOldAnimation = false; - - // first stop any old animations. - if (navigationActivity != null) { - navigationActivity.terminate(); - wasOldAnimation = true; - } - - if (duration == 0) { - aCamera.setViewTransform(aTransform); - return null; - } - - AffineTransform source = aCamera.getViewTransformReference(); - - if (!source.equals(aTransform)) { - navigationActivity = aCamera.animateViewToTransform(aTransform, duration); - ((PTransformActivity)navigationActivity).setSlowInSlowOut(!wasOldAnimation); - return navigationActivity; - } - - return null; - } - - public PActivity directCameraViewToFocus(PCamera aCamera, PNode aFocusNode, int duration) { - focusNode = aFocusNode; - AffineTransform originalViewTransform = aCamera.getViewTransform(); - - // Scale the canvas to include - PDimension d = new PDimension(1, 0); - focusNode.globalToLocal(d); - - double scaleFactor = d.getWidth() / aCamera.getViewScale(); - Point2D scalePoint = focusNode.getGlobalFullBounds().getCenter2D(); - if (scaleFactor != 1) { - aCamera.scaleViewAboutPoint(scaleFactor, scalePoint.getX(), scalePoint.getY()); - } - - // Pan the canvas to include the view bounds with minimal canvas - // movement. - aCamera.animateViewToPanToBounds(focusNode.getGlobalFullBounds(), 0); - - // Get rid of any white space. The canvas may be panned and - // zoomed in to do this. But make sure not stay constrained by max - // magnification. - //fillViewWhiteSpace(aCamera); - - AffineTransform resultingTransform = aCamera.getViewTransform(); - aCamera.setViewTransform(originalViewTransform); - - // Animate the canvas so that it ends up with the given - // view transform. - return animateCameraViewTransformTo(aCamera, resultingTransform, duration); - } - - protected void fillViewWhiteSpace(PCamera aCamera) { - PBounds rootBounds = aCamera.getRoot().getFullBoundsReference(); - PBounds viewBounds = aCamera.getViewBounds(); - - if (!rootBounds.contains(aCamera.getViewBounds())) { - aCamera.animateViewToPanToBounds(rootBounds, 0); - aCamera.animateViewToPanToBounds(focusNode.getGlobalFullBounds(), 0); - - // center content. - double dx = 0; - double dy = 0; - viewBounds = aCamera.getViewBounds(); - - if (viewBounds.getWidth() > rootBounds.getWidth()) { // then center along x axis. - double boundsCenterX = rootBounds.getMinX() + (rootBounds.getWidth() / 2); - double viewBoundsCenterX = viewBounds.getMinX() + (viewBounds.getWidth() / 2); - dx = viewBoundsCenterX - boundsCenterX; - } - - if (viewBounds.getHeight() > rootBounds.getHeight()) { // then center along y axis. - double boundsCenterY = rootBounds.getMinY() + (rootBounds.getHeight() / 2); - double viewBoundsCenterY = viewBounds.getMinY() + (viewBounds.getHeight() / 2); - dy = viewBoundsCenterY - boundsCenterY; - } - aCamera.translateView(dx, dy); - } - } -} diff --git a/extras/edu/umd/cs/piccolox/event/PNotification.java b/extras/edu/umd/cs/piccolox/event/PNotification.java deleted file mode 100644 index 0fa8e4e..0000000 --- a/extras/edu/umd/cs/piccolox/event/PNotification.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - * - * This class PNotification center is derived from the class - * NSNotification from: - * - * Wotonomy: OpenStep design patterns for pure Java - * applications. Copyright (C) 2000 Blacksmith, Inc. - */ -package edu.umd.cs.piccolox.event; - -import java.util.Map; - -/** - * PNotification objects encapsulate information so that it can be - * broadcast to other objects by a PNotificationCenter. A PNotification contains a - * name, an object, and an optional properties map. The name is a tag - * identifying the notification. The object is any object that the poster of the - * notification wants to send to observers of that notification (typically, it - * is the object that posted the notification). The properties map stores other - * related objects, if any. - *

- * You don't usually create your own notifications directly. The - * PNotificationCenter method postNotification() allow you to conveniently post a - * notification without creating it first. - *

- * @author Jesse Grosjean - */ -public class PNotification { - - protected String name; - protected Object source; - protected Map properties; - - public PNotification(String name, Object source, Map properties) { - this.name = name; - this.source = source; - this.properties = properties; - } - - /** - * Return the name of the notification. This is the same as the name used to - * register with the notfication center. - */ - public String getName() { - return name; - } - - /** - * Return the object associated with this notification. This is most often - * the same object that posted the notfication. It may be null. - */ - public Object getObject() { - return source; - } - - /** - * Return a property associated with the notfication. - */ - public Object getProperty(Object key) { - if (properties != null) { - return properties.get(key); - } - return null; - } -} diff --git a/extras/edu/umd/cs/piccolox/event/PNotificationCenter.java b/extras/edu/umd/cs/piccolox/event/PNotificationCenter.java deleted file mode 100644 index f9a6325..0000000 --- a/extras/edu/umd/cs/piccolox/event/PNotificationCenter.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - * - * This class PNotificationCenter center is derived from the class - * NSNotificationCenter from: - * - * Wotonomy: OpenStep design patterns for pure Java - * applications. Copyright (C) 2000 Blacksmith, Inc. - */ -package edu.umd.cs.piccolox.event; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * PNotificationCenter provides a way for objects that don't know about - * each other to communicate. It receives PNotification objects and broadcasts - * them to all interested listeners. Unlike standard Java events, the event - * listeners don't need to know about the event source, and the event source - * doesn't need to maintain the list of listeners. - *

- * Listeners of the notfications center are held by weak references. So the - * notfication center will not create garbage collection problems as standard - * java event listeners do. - *

- * @author Jesse Grosjean - */ -public class PNotificationCenter { - - public static final Object NULL_MARKER = new Object(); - - protected static PNotificationCenter DEFAULT_CENTER; - - protected HashMap listenersMap; - protected ReferenceQueue keyQueue; - - public static PNotificationCenter defaultCenter() { - if (DEFAULT_CENTER == null) { - DEFAULT_CENTER = new PNotificationCenter(); - } - return DEFAULT_CENTER; - } - - private PNotificationCenter() { - listenersMap = new HashMap(); - keyQueue = new ReferenceQueue(); - } - - //**************************************************************** - // Add Listener Methods - //**************************************************************** - - /** - * Registers the 'listener' to receive notifications with the name - * 'notificationName' and/or containing 'object'. When a matching - * notification is posted the callBackMethodName message will be sent to the - * listener with a single PNotification argument. If notificationName is null - * then the listener will receive all notifications with an object matching - * 'object'. If 'object' is null the listener will receive all notifications - * with the name 'notificationName'. - */ - public void addListener(Object listener, String callbackMethodName, String notificationName, Object object) { - processKeyQueue(); - - Object name = notificationName; - Method method = null; - - try { - method = listener.getClass().getMethod(callbackMethodName, new Class[] { PNotification.class }); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - return; - } - - if (name == null) name = NULL_MARKER; - if (object == null) object = NULL_MARKER; - - Object key = new CompoundKey(name, object); - Object value = new CompoundValue(listener, method); - - List list = (List) listenersMap.get(key); - if (list == null) { - list = new ArrayList(); - listenersMap.put(new CompoundKey(name, object, keyQueue), list); - } - - if (!list.contains(value)) { - list.add(value); - } - } - - //**************************************************************** - // Remove Listener Methods - //**************************************************************** - - /** - * Removes the listener so that it no longer recives notfications from this - * notfication center. - */ - public void removeListener(Object listener) { - processKeyQueue(); - - Iterator i = new LinkedList(listenersMap.keySet()).iterator(); - while (i.hasNext()) { - removeListener(listener, i.next()); - } - } - - /** - * Removes the listeners as the listener of notifications matching - * notificationName and object. If listener is null all listeners matching - * notificationName and object are removed. If notificationName is null the - * listener will be removed from all notifications containing the object. If - * the object is null then the listener will be removed from all - * notifications matching notficationName. - */ - public void removeListener(Object listener, String notificationName, Object object) { - processKeyQueue(); - - List keys = matchingKeys(notificationName, object); - Iterator it = keys.iterator(); - while (it.hasNext()) { - removeListener(listener, it.next()); - } - } - - //**************************************************************** - // Post PNotification Methods - //**************************************************************** - - /** - * Post a new notfication with notificationName and object. The object is - * typically the object posting the notification. The object may be null. - */ - public void postNotification(String notificationName, Object object) { - postNotification(notificationName, object, null); - } - - /** - * Creates a notification with the name notificationName, associates it with - * the object, and posts it to this notification center. The object is - * typically the object posting the notification. It may be nil. - */ - public void postNotification(String notificationName, Object object, Map userInfo) { - postNotification(new PNotification(notificationName, object, userInfo)); - } - - /** - * Post the notification to this notification center. Most often clients will - * instead use one of this classes convenience postNotifcations methods. - */ - public void postNotification(PNotification aNotification) { - List mergedListeners = new LinkedList(); - List listenersList; - - Object name = aNotification.getName(); - Object object = aNotification.getObject(); - - if (name != null) { - if (object != null) { // both are specified - listenersList = (List) listenersMap.get(new CompoundKey(name, object)); - if (listenersList != null) { - mergedListeners.addAll(listenersList); - } - listenersList = (List) listenersMap.get(new CompoundKey(name, NULL_MARKER)); - if (listenersList != null) { - mergedListeners.addAll(listenersList); - } - listenersList = (List) listenersMap.get(new CompoundKey(NULL_MARKER, object)); - if (listenersList != null) { - mergedListeners.addAll(listenersList); - } - } else { // object is null - listenersList = (List) listenersMap.get(new CompoundKey(name, NULL_MARKER)); - if (listenersList != null) { - mergedListeners.addAll(listenersList); - } - } - } else if (object != null) { // name is null - listenersList = (List) listenersMap.get(new CompoundKey(NULL_MARKER, object)); - if (listenersList != null) { - mergedListeners.addAll(listenersList); - } - } - - Object key = new CompoundKey(NULL_MARKER, NULL_MARKER); - listenersList = (List) listenersMap.get(key); - if (listenersList != null) { - mergedListeners.addAll(listenersList); - } - - CompoundValue value; - Iterator it = mergedListeners.iterator(); - - while (it.hasNext()) { - value = (CompoundValue) it.next(); - if (value.get() == null) { - it.remove(); - } else { - try { - value.getMethod().invoke(value.get(), new Object[] { aNotification }); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - } - } - - //**************************************************************** - // Implementation classes and methods - //**************************************************************** - - protected List matchingKeys(String name, Object object) { - List result = new LinkedList(); - - Iterator it = listenersMap.keySet().iterator(); - while (it.hasNext()) { - CompoundKey key = (CompoundKey) it.next(); - if ((name == null) || (name == key.name())) { - if ((object == null) || (object == key.get())) { - result.add(key); - } - } - } - - return result; - } - - protected void removeListener(Object listener, Object key) { - if (listener == null) { - listenersMap.remove(key); - return; - } - - List list = (List) listenersMap.get(key); - if (list == null) - return; - - Iterator it = list.iterator(); - while (it.hasNext()) { - Object observer = ((CompoundValue) it.next()).get(); - if ((observer == null) || (listener == observer)) { - it.remove(); - } - } - - if (list.size() == 0) { - listenersMap.remove(key); - } - } - - protected void processKeyQueue() { - CompoundKey key; - while ((key = (CompoundKey) keyQueue.poll()) != null) { - listenersMap.remove(key); - } - } - - protected static class CompoundKey extends WeakReference { - - private Object name; - private int hashCode; - - public CompoundKey(Object aName, Object anObject) { - super(anObject); - name = aName; - hashCode = aName.hashCode() + anObject.hashCode(); - } - - public CompoundKey(Object aName, Object anObject, ReferenceQueue aQueue) { - super(anObject, aQueue); - name = aName; - hashCode = aName.hashCode() + anObject.hashCode(); - } - - public Object name() { - return name; - } - - public int hashCode() { - return hashCode; - } - - public boolean equals(Object anObject) { - if (this == anObject) return true; - CompoundKey key = (CompoundKey) anObject; - if (name == key.name || (name != null && name.equals(key.name))) { - Object object = get(); - if (object != null) { - if ( object == (key.get())) { - return true; - } - } - } - return false; - } - - public String toString() { - return "[CompoundKey:" + name() + ":" + get() + "]"; - } - } - - protected static class CompoundValue extends WeakReference { - - protected int hashCode; - protected Method method; - - public CompoundValue(Object object, Method method) { - super(object); - hashCode = object.hashCode(); - this.method = method; - } - - public Method getMethod() { - return method; - } - - public int hashCode() { - return hashCode; - } - - public boolean equals(Object object) { - if (this == object) return true; - CompoundValue value = (CompoundValue) object; - if (method == value.method || (method != null && method.equals(value.method))) { - Object o = get(); - if (o != null) { - if (o == value.get()) { - return true; - } - } - } - return false; - } - - public String toString() { - return "[CompoundValue:" + get() + ":" + getMethod().getName() + "]"; - } - } -} diff --git a/extras/edu/umd/cs/piccolox/event/PSelectionEventHandler.java b/extras/edu/umd/cs/piccolox/event/PSelectionEventHandler.java deleted file mode 100644 index 8383eb6..0000000 --- a/extras/edu/umd/cs/piccolox/event/PSelectionEventHandler.java +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.event; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Paint; -import java.awt.Stroke; -import java.awt.event.KeyEvent; -import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolo.util.PNodeFilter; -import edu.umd.cs.piccolox.handles.PBoundsHandle; - -/** - * PSelectionEventHandler provides standard interaction for selection. Clicking - * selects the object under the cursor. Shift-clicking allows multiple objects to be - * selected. Dragging offers marquee selection. Pressing the delete key deletes - * the selection by default. - * @version 1.0 - * @author Ben Bederson - */ -public class PSelectionEventHandler extends PDragSequenceEventHandler { - - public static final String SELECTION_CHANGED_NOTIFICATION = "SELECTION_CHANGED_NOTIFICATION"; - - final static int DASH_WIDTH = 5; - final static int NUM_STROKES = 10; - - private HashMap selection = null; // The current selection - private List selectableParents = null; // List of nodes whose children can be selected - private PPath marquee = null; - private PNode marqueeParent = null; // Node that marquee is added to as a child - private Point2D presspt = null; - private Point2D canvasPressPt = null; - private float strokeNum = 0; - private Stroke[] strokes = null; - private HashMap allItems = null; // Used within drag handler temporarily - private ArrayList unselectList = null; // Used within drag handler temporarily - private HashMap marqueeMap = null; - private PNode pressNode = null; // Node pressed on (or null if none) - private boolean deleteKeyActive = true; // True if DELETE key should delete selection - private Paint marqueePaint; - private float marqueePaintTransparency = 1.0f; - - /** - * Creates a selection event handler. - * @param marqueeParent The node to which the event handler dynamically adds a marquee - * (temporarily) to represent the area being selected. - * @param selectableParent The node whose children will be selected - * by this event handler. - */ - public PSelectionEventHandler(PNode marqueeParent, PNode selectableParent) { - this.marqueeParent = marqueeParent; - this.selectableParents = new ArrayList(); - this.selectableParents.add(selectableParent); - init(); - } - - /** - * Creates a selection event handler. - * @param marqueeParent The node to which the event handler dynamically adds a marquee - * (temporarily) to represent the area being selected. - * @param selectableParents A list of nodes whose children will be selected - * by this event handler. - */ - public PSelectionEventHandler(PNode marqueeParent, List selectableParents) { - this.marqueeParent = marqueeParent; - this.selectableParents = selectableParents; - init(); - } - - protected void init() { - float[] dash = { DASH_WIDTH, DASH_WIDTH }; - strokes = new Stroke[NUM_STROKES]; - for (int i = 0; i < NUM_STROKES; i++) { - strokes[i] = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, dash, i); - } - - selection = new HashMap(); - allItems = new HashMap(); - unselectList = new ArrayList(); - marqueeMap = new HashMap(); - } - - /////////////////////////////////////////////////////// - // Public static methods for manipulating the selection - /////////////////////////////////////////////////////// - - public void select(Collection items) { - boolean changes = false; - Iterator itemIt = items.iterator(); - while (itemIt.hasNext()) { - PNode node = (PNode)itemIt.next(); - changes |= internalSelect(node); - } - if (changes) { - postSelectionChanged(); - } - } - - public void select(Map items) { - select( items.keySet() ); - } - - private boolean internalSelect( PNode node ) { - if (isSelected(node)) { - return false; - } - - selection.put(node, Boolean.TRUE); - decorateSelectedNode(node); - return true; - } - - private void postSelectionChanged() - { - PNotificationCenter.defaultCenter().postNotification(SELECTION_CHANGED_NOTIFICATION, this); - } - - public void select(PNode node) { - if (internalSelect(node)) { - postSelectionChanged(); - } - } - - public void decorateSelectedNode(PNode node) { - PBoundsHandle.addBoundsHandlesTo(node); - } - - public void unselect(Collection items) { - boolean changes = false; - Iterator itemIt = items.iterator(); - while (itemIt.hasNext()) { - PNode node = (PNode)itemIt.next(); - changes |= internalUnselect(node); - } - if (changes) { - postSelectionChanged(); - } - } - - private boolean internalUnselect( PNode node ) { - if (!isSelected(node)) { - return false; - } - - undecorateSelectedNode(node); - selection.remove(node); - return true; - } - - public void unselect(PNode node) { - if( internalUnselect(node) ) { - postSelectionChanged(); - } - } - - public void undecorateSelectedNode(PNode node) { - PBoundsHandle.removeBoundsHandlesFrom(node); - } - - public void unselectAll() { - // Because unselect() removes from selection, we need to - // take a copy of it first so it isn't changed while we're iterating - ArrayList sel = new ArrayList(selection.keySet()); - unselect( sel ); - } - - public boolean isSelected(PNode node) { - if ((node != null) && (selection.containsKey(node))) { - return true; - } else { - return false; - } - } - - /** - * Returns a copy of the currently selected nodes. - */ - public Collection getSelection() { - ArrayList sel = new ArrayList(selection.keySet()); - return sel; - } - - /** - * Gets a reference to the currently selected nodes. You should not modify or store - * this collection. - */ - public Collection getSelectionReference() - { - return Collections.unmodifiableCollection( selection.keySet() ); - } - - /** - * Determine if the specified node is selectable (i.e., if it is a child - * of the one the list of selectable parents. - */ - protected boolean isSelectable(PNode node) { - boolean selectable = false; - - Iterator parentsIt = selectableParents.iterator(); - while (parentsIt.hasNext()) { - PNode parent = (PNode)parentsIt.next(); - if (parent.getChildrenReference().contains(node)) { - selectable = true; - break; - } - else if (parent instanceof PCamera) { - for(int i=0; i<((PCamera)parent).getLayerCount(); i++) { - PLayer layer = ((PCamera)parent).getLayer(i); - if (layer.getChildrenReference().contains(node)) { - selectable = true; - break; - } - } - } - } - - return selectable; - } - - ////////////////////////////////////////////////////// - // Methods for modifying the set of selectable parents - ////////////////////////////////////////////////////// - - public void addSelectableParent(PNode node) { - selectableParents.add(node); - } - - public void removeSelectableParent(PNode node) { - selectableParents.remove(node); - } - - public void setSelectableParent(PNode node) { - selectableParents.clear(); - selectableParents.add(node); - } - - public void setSelectableParents(Collection c) { - selectableParents.clear(); - selectableParents.addAll(c); - } - - public Collection getSelectableParents() { - return new ArrayList(selectableParents); - } - - //////////////////////////////////////////////////////// - // The overridden methods from PDragSequenceEventHandler - //////////////////////////////////////////////////////// - - protected void startDrag(PInputEvent e) { - super.startDrag(e); - - initializeSelection(e); - - if (isMarqueeSelection(e)) { - initializeMarquee(e); - - if (!isOptionSelection(e)) { - startMarqueeSelection(e); - } - else { - startOptionMarqueeSelection(e); - } - } - else { - if (!isOptionSelection(e)) { - startStandardSelection(e); - } else { - startStandardOptionSelection(e); - } - } - } - - protected void drag(PInputEvent e) { - super.drag(e); - - if (isMarqueeSelection(e)) { - updateMarquee(e); - - if (!isOptionSelection(e)) { - computeMarqueeSelection(e); - } - else { - computeOptionMarqueeSelection(e); - } - } else { - dragStandardSelection(e); - } - } - - protected void endDrag(PInputEvent e) { - super.endDrag(e); - - if (isMarqueeSelection(e)) { - endMarqueeSelection(e); - } - else { - endStandardSelection(e); - } - } - - //////////////////////////// - // Additional methods - //////////////////////////// - - public boolean isOptionSelection(PInputEvent pie) { - return pie.isShiftDown(); - } - - protected boolean isMarqueeSelection(PInputEvent pie) { - return (pressNode == null); - } - - protected void initializeSelection(PInputEvent pie) { - canvasPressPt = pie.getCanvasPosition(); - presspt = pie.getPosition(); - pressNode = pie.getPath().getPickedNode(); - if (pressNode instanceof PCamera) { - pressNode = null; - } - } - - protected void initializeMarquee(PInputEvent e) { - marquee = PPath.createRectangle((float)presspt.getX(), (float)presspt.getY(), 0, 0); - marquee.setPaint(marqueePaint); - marquee.setTransparency(marqueePaintTransparency); - marquee.setStrokePaint(Color.black); - marquee.setStroke(strokes[0]); - marqueeParent.addChild(marquee); - - marqueeMap.clear(); - } - - protected void startOptionMarqueeSelection(PInputEvent e) { - } - - protected void startMarqueeSelection(PInputEvent e) { - unselectAll(); - } - - protected void startStandardSelection(PInputEvent pie) { - // Option indicator not down - clear selection, and start fresh - if (!isSelected(pressNode)) { - unselectAll(); - - if (isSelectable(pressNode)) { - select(pressNode); - } - } - } - - protected void startStandardOptionSelection(PInputEvent pie) { - // Option indicator is down, toggle selection - if (isSelectable(pressNode)) { - if (isSelected(pressNode)) { - unselect(pressNode); - } else { - select(pressNode); - } - } - } - - protected void updateMarquee(PInputEvent pie) { - PBounds b = new PBounds(); - - if (marqueeParent instanceof PCamera) { - b.add(canvasPressPt); - b.add(pie.getCanvasPosition()); - } - else { - b.add(presspt); - b.add(pie.getPosition()); - } - - marquee.globalToLocal(b); - marquee.setPathToRectangle((float) b.x, (float) b.y, (float) b.width, (float) b.height); - b.reset(); - b.add(presspt); - b.add(pie.getPosition()); - - allItems.clear(); - PNodeFilter filter = createNodeFilter(b); - Iterator parentsIt = selectableParents.iterator(); - while (parentsIt.hasNext()) { - PNode parent = (PNode) parentsIt.next(); - - Collection items; - if (parent instanceof PCamera) { - items = new ArrayList(); - for(int i=0; i<((PCamera)parent).getLayerCount(); i++) { - ((PCamera)parent).getLayer(i).getAllNodes(filter,items); - } - } - else { - items = parent.getAllNodes(filter, null); - } - - Iterator itemsIt = items.iterator(); - while (itemsIt.hasNext()) { - allItems.put(itemsIt.next(), Boolean.TRUE); - } - } - } - - protected void computeMarqueeSelection(PInputEvent pie) { - unselectList.clear(); - // Make just the items in the list selected - // Do this efficiently by first unselecting things not in the list - Iterator selectionEn = selection.keySet().iterator(); - while (selectionEn.hasNext()) { - PNode node = (PNode) selectionEn.next(); - if (!allItems.containsKey(node)) { - unselectList.add(node); - } - } - unselect(unselectList); - - // Then select the rest - selectionEn = allItems.keySet().iterator(); - while (selectionEn.hasNext()) { - PNode node = (PNode) selectionEn.next(); - if (!selection.containsKey(node) && !marqueeMap.containsKey(node) && isSelectable(node)) { - marqueeMap.put(node,Boolean.TRUE); - } - else if (!isSelectable(node)) { - selectionEn.remove(); - } - } - - select(allItems); - } - - protected void computeOptionMarqueeSelection(PInputEvent pie) { - unselectList.clear(); - Iterator selectionEn = selection.keySet().iterator(); - while (selectionEn.hasNext()) { - PNode node = (PNode) selectionEn.next(); - if (!allItems.containsKey(node) && marqueeMap.containsKey(node)) { - marqueeMap.remove(node); - unselectList.add(node); - } - } - unselect(unselectList); - - - // Then select the rest - selectionEn = allItems.keySet().iterator(); - while (selectionEn.hasNext()) { - PNode node = (PNode) selectionEn.next(); - if (!selection.containsKey(node) && !marqueeMap.containsKey(node) && isSelectable(node)) { - marqueeMap.put(node,Boolean.TRUE); - } - else if (!isSelectable(node)) { - selectionEn.remove(); - } - } - - select(allItems); - } - - protected PNodeFilter createNodeFilter(PBounds bounds) { - return new BoundsFilter(bounds); - } - - protected PBounds getMarqueeBounds() { - if (marquee != null) { - return marquee.getBounds(); - } - return new PBounds(); - } - - protected void dragStandardSelection(PInputEvent e) { - // There was a press node, so drag selection - PDimension d = e.getCanvasDelta(); - e.getTopCamera().localToView(d); - - PDimension gDist = new PDimension(); - Iterator selectionEn = getSelection().iterator(); - while (selectionEn.hasNext()) { - PNode node = (PNode) selectionEn.next(); - - gDist.setSize(d); - node.getParent().globalToLocal(gDist); - node.offset(gDist.getWidth(), gDist.getHeight()); - } - } - - protected void endMarqueeSelection(PInputEvent e) { - // Remove marquee - allItems.clear(); - marqueeMap.clear(); - marquee.removeFromParent(); - marquee = null; - } - - protected void endStandardSelection(PInputEvent e) { - pressNode = null; - } - - /** - * This gets called continuously during the drag, and is used to animate the marquee - */ - protected void dragActivityStep(PInputEvent aEvent) { - if (marquee != null) { - float origStrokeNum = strokeNum; - strokeNum = (strokeNum + 0.5f) % NUM_STROKES; // Increment by partial steps to slow down animation - if ((int)strokeNum != (int)origStrokeNum) { - marquee.setStroke(strokes[(int)strokeNum]); - } - } - } - - /** - * Delete selection when delete key is pressed (if enabled) - */ - public void keyPressed(PInputEvent e) { - switch (e.getKeyCode()) { - case KeyEvent.VK_DELETE: - if (deleteKeyActive) { - Iterator selectionEn = selection.keySet().iterator(); - while (selectionEn.hasNext()) { - PNode node = (PNode) selectionEn.next(); - node.removeFromParent(); - } - selection.clear(); - } - } - } - - public boolean getSupportDeleteKey() { - return deleteKeyActive; - } - - public boolean isDeleteKeyActive() { - return deleteKeyActive; - } - - /** - * Specifies if the DELETE key should delete the selection - */ - public void setDeleteKeyActive(boolean deleteKeyActive) { - this.deleteKeyActive = deleteKeyActive; - } - - ////////////////////// - // Inner classes - ////////////////////// - - protected class BoundsFilter implements PNodeFilter { - PBounds localBounds = new PBounds(); - PBounds bounds; - - protected BoundsFilter(PBounds bounds) { - this.bounds = bounds; - } - - public boolean accept(PNode node) { - localBounds.setRect(bounds); - node.globalToLocal(localBounds); - - boolean boundsIntersects = node.intersects(localBounds); - boolean isMarquee = (node == marquee); - return (node.getPickable() && boundsIntersects && !isMarquee && !selectableParents.contains(node) && !isCameraLayer(node)); - } - - public boolean acceptChildrenOf(PNode node) { - return selectableParents.contains(node) || isCameraLayer(node); - } - - public boolean isCameraLayer(PNode node) { - if (node instanceof PLayer) { - for(Iterator i=selectableParents.iterator(); i.hasNext();) { - PNode parent = (PNode)i.next(); - if (parent instanceof PCamera) { - if (((PCamera)parent).indexOfLayer((PLayer)node) != -1) { - return true; - } - } - } - } - return false; - } - } - - /** - * Indicates the color used to paint the marquee. - * @return the paint for interior of the marquee - */ - public Paint getMarqueePaint() { - return marqueePaint; - } - - /** - * Sets the color used to paint the marquee. - * @param paint the paint color - */ - public void setMarqueePaint(Paint paint) { - this.marqueePaint = paint; - } - - /** - * Indicates the transparency level for the interior of the marquee. - * @return Returns the marquee paint transparency, zero to one - */ - public float getMarqueePaintTransparency() { - return marqueePaintTransparency; - } - - /** - * Sets the transparency level for the interior of the marquee. - * @param marqueePaintTransparency The marquee paint transparency to set. - */ - public void setMarqueePaintTransparency(float marqueePaintTransparency) { - this.marqueePaintTransparency = marqueePaintTransparency; - } -} \ No newline at end of file diff --git a/extras/edu/umd/cs/piccolox/event/PStyledTextEventHandler.java b/extras/edu/umd/cs/piccolox/event/PStyledTextEventHandler.java deleted file mode 100644 index 64af73c..0000000 --- a/extras/edu/umd/cs/piccolox/event/PStyledTextEventHandler.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ - package edu.umd.cs.piccolox.event; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.RenderingHints; -import java.awt.event.InputEvent; -import java.awt.event.MouseEvent; -import java.awt.geom.Point2D; - -import javax.swing.JTextPane; -import javax.swing.SwingUtilities; -import javax.swing.border.CompoundBorder; -import javax.swing.border.EmptyBorder; -import javax.swing.border.LineBorder; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.text.Document; -import javax.swing.text.JTextComponent; -import javax.swing.text.SimpleAttributeSet; -import javax.swing.text.StyleConstants; -import javax.swing.text.StyledDocument; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PCanvas; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolox.nodes.PStyledText; - -/** - * @author Lance Good - */ -public class PStyledTextEventHandler extends PBasicInputEventHandler { - - protected PCanvas canvas; - - protected JTextComponent editor; - - protected DocumentListener docListener; - - protected PStyledText editedText; - - /** - * Basic constructor for PStyledTextEventHandler - */ - public PStyledTextEventHandler(PCanvas canvas) { - super(); - - this.canvas = canvas; - initEditor(createDefaultEditor()); - } - - /** - * Constructor for PStyledTextEventHandler that allows an editor to be specified - */ - public PStyledTextEventHandler(PCanvas canvas, JTextComponent editor) { - super(); - - this.canvas = canvas; - initEditor(editor); - } - - protected void initEditor(JTextComponent newEditor) { - editor = newEditor; - - canvas.setLayout(null); - canvas.add(editor); - editor.setVisible(false); - - docListener = createDocumentListener(); - } - - protected JTextComponent createDefaultEditor() { - JTextPane tComp = new JTextPane() { - - /** - * Set some rendering hints - if we don't then the rendering can be inconsistent. Also, - * Swing doesn't work correctly with fractional metrics. - */ - public void paint(Graphics g) { - Graphics2D g2 = (Graphics2D)g; - - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF); - - super.paint(g); - } - }; - tComp.setBorder(new CompoundBorder(new LineBorder(Color.black),new EmptyBorder(3,3,3,3))); - return tComp; - } - - protected DocumentListener createDocumentListener() { - return new DocumentListener() { - public void removeUpdate(DocumentEvent e) { - reshapeEditorLater(); - } - - public void insertUpdate(DocumentEvent e) { - reshapeEditorLater(); - } - - public void changedUpdate(DocumentEvent e) { - reshapeEditorLater(); - } - }; - } - - public PStyledText createText() { - PStyledText newText = new PStyledText(); - - Document doc = editor.getUI().getEditorKit(editor).createDefaultDocument(); - if (doc instanceof StyledDocument) { - if (!doc.getDefaultRootElement().getAttributes().isDefined(StyleConstants.FontFamily) - || !doc.getDefaultRootElement().getAttributes().isDefined(StyleConstants.FontSize)) { - - Font eFont = editor.getFont(); - SimpleAttributeSet sas = new SimpleAttributeSet(); - sas.addAttribute(StyleConstants.FontFamily, eFont.getFamily()); - sas.addAttribute(StyleConstants.FontSize, new Integer(eFont.getSize())); - - ((StyledDocument) doc).setParagraphAttributes(0, doc.getLength(), sas, false); - } - } - newText.setDocument(doc); - - return newText; - } - - public void mousePressed(PInputEvent inputEvent) { - PNode pickedNode = inputEvent.getPickedNode(); - - stopEditing(); - - if (pickedNode instanceof PStyledText) { - startEditing(inputEvent,(PStyledText)pickedNode); - } - else if (pickedNode instanceof PCamera) { - PStyledText newText = createText(); - Insets pInsets = newText.getInsets(); - canvas.getLayer().addChild(newText); - newText.translate(inputEvent.getPosition().getX()-pInsets.left,inputEvent.getPosition().getY()-pInsets.top); - startEditing(inputEvent, newText); - } - } - - public void startEditing(PInputEvent event, PStyledText text) { - // Get the node's top right hand corner - Insets pInsets = text.getInsets(); - Point2D nodePt = new Point2D.Double(text.getX()+pInsets.left,text.getY()+pInsets.top); - text.localToGlobal(nodePt); - event.getTopCamera().viewToLocal(nodePt); - - // Update the editor to edit the specified node - editor.setDocument(text.getDocument()); - editor.setVisible(true); - - Insets bInsets = editor.getBorder().getBorderInsets(editor); - editor.setLocation((int)nodePt.getX()-bInsets.left,(int)nodePt.getY()-bInsets.top); - reshapeEditorLater(); - - dispatchEventToEditor(event); - canvas.repaint(); - - text.setEditing(true); - text.getDocument().addDocumentListener(docListener); - editedText = text; - } - - public void stopEditing() { - if (editedText != null) { - editedText.getDocument().removeDocumentListener(docListener); - editedText.setEditing(false); - - if (editedText.getDocument().getLength() == 0) { - editedText.removeFromParent(); - } - else { - editedText.syncWithDocument(); - } - - editor.setVisible(false); - canvas.repaint(); - - editedText = null; - } - } - - public void dispatchEventToEditor(final PInputEvent e) { - // We have to nest the mouse press in two invoke laters so that it is - // fired so that the component has been completely validated at the new size - // and the mouse event has the correct offset - SwingUtilities.invokeLater(new Runnable() { - public void run() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - MouseEvent me = - new MouseEvent( - editor, - MouseEvent.MOUSE_PRESSED, - e.getWhen(), - e.getModifiers() | InputEvent.BUTTON1_MASK, - (int) (e.getCanvasPosition().getX() - editor.getX()), - (int) (e.getCanvasPosition().getY() - editor.getY()), - 1, - false); - editor.dispatchEvent(me); - } - }); - } - }); - } - - - public void reshapeEditor() { - if (editedText != null) { - // Update the size to fit the new document - note that it is a 2 stage process - Dimension prefSize = editor.getPreferredSize(); - - Insets pInsets = editedText.getInsets(); - Insets jInsets = editor.getInsets(); - - int width = (editedText.getConstrainWidthToTextWidth()) ? (int)prefSize.getWidth() : (int)(editedText.getWidth()-pInsets.left-pInsets.right+jInsets.left+jInsets.right+3.0); - prefSize.setSize(width,prefSize.getHeight()); - editor.setSize(prefSize); - - prefSize = editor.getPreferredSize(); - int height = (editedText.getConstrainHeightToTextHeight()) ? (int)prefSize.getHeight() : (int)(editedText.getHeight()-pInsets.top-pInsets.bottom+jInsets.top+jInsets.bottom+3.0); - prefSize.setSize(width,height); - editor.setSize(prefSize); - } - } - - /** - * Sometimes we need to invoke this later because the document events seem to get fired - * before the text is actually incorporated into the document - */ - protected void reshapeEditorLater() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - reshapeEditor(); - } - }); - } - -} diff --git a/extras/edu/umd/cs/piccolox/event/PZoomToEventHandler.java b/extras/edu/umd/cs/piccolox/event/PZoomToEventHandler.java deleted file mode 100644 index 9a07a14..0000000 --- a/extras/edu/umd/cs/piccolox/event/PZoomToEventHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.event; - -import java.awt.event.InputEvent; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.event.PInputEventFilter; -import edu.umd.cs.piccolo.util.PBounds; - -/** - * PZoomToEventHandler is used to zoom the camera view to the node - * clicked on with button one. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PZoomToEventHandler extends PBasicInputEventHandler { - - public PZoomToEventHandler() { - setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); - } - - public void mousePressed(PInputEvent aEvent) { - zoomTo(aEvent); - } - - protected void zoomTo(final PInputEvent aEvent) { - PBounds zoomToBounds; - PNode picked = aEvent.getPickedNode(); - - if (picked instanceof PCamera) { - PCamera c = (PCamera) picked; - zoomToBounds = c.getUnionOfLayerFullBounds(); - } else { - zoomToBounds = picked.getGlobalFullBounds(); - } - - aEvent.getCamera().animateViewToCenterBounds(zoomToBounds, true, 500); - } -} diff --git a/extras/edu/umd/cs/piccolox/event/package.html b/extras/edu/umd/cs/piccolox/event/package.html deleted file mode 100644 index 5c3cf9c..0000000 --- a/extras/edu/umd/cs/piccolox/event/package.html +++ /dev/null @@ -1,34 +0,0 @@ - - - -

This package provides additional Piccolo event handlers.

- - diff --git a/extras/edu/umd/cs/piccolox/handles/PBoundsHandle.java b/extras/edu/umd/cs/piccolox/handles/PBoundsHandle.java deleted file mode 100644 index 14d536f..0000000 --- a/extras/edu/umd/cs/piccolox/handles/PBoundsHandle.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.handles; - -import java.awt.Cursor; -import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.Iterator; - -import javax.swing.SwingConstants; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PBasicInputEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolo.util.PPickPath; -import edu.umd.cs.piccolox.util.PBoundsLocator; - -/** - * PBoundsHandle a handle for resizing the bounds of another node. If a - * bounds handle is dragged such that the other node's width or height becomes - * negative then the each drag handle's locator assciated with that - * other node is "flipped" so that they are attached to and dragging a different - * corner of the nodes bounds. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PBoundsHandle extends PHandle { - - private transient PBasicInputEventHandler handleCursorHandler; - - public static void addBoundsHandlesTo(PNode aNode) { - aNode.addChild(new PBoundsHandle(PBoundsLocator.createEastLocator(aNode))); - aNode.addChild(new PBoundsHandle(PBoundsLocator.createWestLocator(aNode))); - aNode.addChild(new PBoundsHandle(PBoundsLocator.createNorthLocator(aNode))); - aNode.addChild(new PBoundsHandle(PBoundsLocator.createSouthLocator(aNode))); - aNode.addChild(new PBoundsHandle(PBoundsLocator.createNorthEastLocator(aNode))); - aNode.addChild(new PBoundsHandle(PBoundsLocator.createNorthWestLocator(aNode))); - aNode.addChild(new PBoundsHandle(PBoundsLocator.createSouthEastLocator(aNode))); - aNode.addChild(new PBoundsHandle(PBoundsLocator.createSouthWestLocator(aNode))); - } - - public static void addStickyBoundsHandlesTo(PNode aNode, PCamera camera) { - camera.addChild(new PBoundsHandle(PBoundsLocator.createEastLocator(aNode))); - camera.addChild(new PBoundsHandle(PBoundsLocator.createWestLocator(aNode))); - camera.addChild(new PBoundsHandle(PBoundsLocator.createNorthLocator(aNode))); - camera.addChild(new PBoundsHandle(PBoundsLocator.createSouthLocator(aNode))); - camera.addChild(new PBoundsHandle(PBoundsLocator.createNorthEastLocator(aNode))); - camera.addChild(new PBoundsHandle(PBoundsLocator.createNorthWestLocator(aNode))); - camera.addChild(new PBoundsHandle(PBoundsLocator.createSouthEastLocator(aNode))); - camera.addChild(new PBoundsHandle(PBoundsLocator.createSouthWestLocator(aNode))); - } - - public static void removeBoundsHandlesFrom(PNode aNode) { - ArrayList handles = new ArrayList(); - - Iterator i = aNode.getChildrenIterator(); - while (i.hasNext()) { - PNode each = (PNode) i.next(); - if (each instanceof PBoundsHandle) { - handles.add(each); - } - } - aNode.removeChildren(handles); - } - - public PBoundsHandle(PBoundsLocator aLocator) { - super(aLocator); - } - - protected void installHandleEventHandlers() { - super.installHandleEventHandlers(); - handleCursorHandler = new PBasicInputEventHandler() { - boolean cursorPushed = false; - public void mouseEntered(PInputEvent aEvent) { - if (!cursorPushed) { - aEvent.pushCursor(getCursorFor(((PBoundsLocator)getLocator()).getSide())); - cursorPushed = true; - } - } - public void mouseExited(PInputEvent aEvent) { - PPickPath focus = aEvent.getInputManager().getMouseFocus(); - if (cursorPushed) { - if (focus == null || focus.getPickedNode() != PBoundsHandle.this) { - aEvent.popCursor(); - cursorPushed = false; - } - } - } - public void mouseReleased(PInputEvent event) { - if (cursorPushed) { - event.popCursor(); - cursorPushed = false; - } - } - }; - addInputEventListener(handleCursorHandler); - } - - /** - * Return the event handler that is responsible for setting the mouse - * cursor when it enters/exits this handle. - */ - public PBasicInputEventHandler getHandleCursorEventHandler() { - return handleCursorHandler; - } - - public void startHandleDrag(Point2D aLocalPoint, PInputEvent aEvent) { - PBoundsLocator l = (PBoundsLocator) getLocator(); - l.getNode().startResizeBounds(); - } - - public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { - PBoundsLocator l = (PBoundsLocator) getLocator(); - - PNode n = l.getNode(); - PBounds b = n.getBounds(); - - PNode parent = getParent(); - if (parent != n && parent instanceof PCamera) { - ((PCamera)parent).localToView(aLocalDimension); - } - - localToGlobal(aLocalDimension); - n.globalToLocal(aLocalDimension); - - double dx = aLocalDimension.getWidth(); - double dy = aLocalDimension.getHeight(); - - switch (l.getSide()) { - case SwingConstants.NORTH: - b.setRect(b.x, b.y + dy, b.width, b.height - dy); - break; - - case SwingConstants.SOUTH: - b.setRect(b.x, b.y, b.width, b.height + dy); - break; - - case SwingConstants.EAST: - b.setRect(b.x, b.y, b.width + dx, b.height); - break; - - case SwingConstants.WEST: - b.setRect(b.x + dx, b.y, b.width - dx, b.height); - break; - - case SwingConstants.NORTH_WEST: - b.setRect(b.x + dx, b.y + dy, b.width - dx, b.height - dy); - break; - - case SwingConstants.SOUTH_WEST: - b.setRect(b.x + dx, b.y, b.width - dx, b.height + dy); - break; - - case SwingConstants.NORTH_EAST: - b.setRect(b.x, b.y + dy, b.width + dx, b.height - dy); - break; - - case SwingConstants.SOUTH_EAST: - b.setRect(b.x, b.y, b.width + dx, b.height + dy); - break; - } - - boolean flipX = false; - boolean flipY = false; - - if (b.width < 0) { - flipX = true; - b.width = -b.width; - b.x -= b.width; - } - - if (b.height < 0) { - flipY = true; - b.height = -b.height; - b.y -= b.height; - } - - if (flipX || flipY) { - flipSiblingBoundsHandles(flipX, flipY); - } - - n.setBounds(b); - } - - public void endHandleDrag(Point2D aLocalPoint, PInputEvent aEvent) { - PBoundsLocator l = (PBoundsLocator) getLocator(); - l.getNode().endResizeBounds(); - } - - public void flipSiblingBoundsHandles(boolean flipX, boolean flipY) { - Iterator i = getParent().getChildrenIterator(); - while (i.hasNext()) { - Object each = i.next(); - if (each instanceof PBoundsHandle) { - ((PBoundsHandle)each).flipHandleIfNeeded(flipX, flipY); - } - } - } - - public void flipHandleIfNeeded(boolean flipX, boolean flipY) { - PBoundsLocator l = (PBoundsLocator) getLocator(); - - if (flipX || flipY) { - switch (l.getSide()) { - case SwingConstants.NORTH: { - if (flipY) { - l.setSide(SwingConstants.SOUTH); - } - break; - } - - case SwingConstants.SOUTH: { - if (flipY) { - l.setSide(SwingConstants.NORTH); - } - break; - } - - case SwingConstants.EAST: { - if (flipX) { - l.setSide(SwingConstants.WEST); - } - break; - } - - case SwingConstants.WEST: { - if (flipX) { - l.setSide(SwingConstants.EAST); - } - break; - } - - case SwingConstants.NORTH_WEST: { - if (flipX && flipY) { - l.setSide(SwingConstants.SOUTH_EAST); - } else if (flipX) { - l.setSide(SwingConstants.NORTH_EAST); - } else if (flipY) { - l.setSide(SwingConstants.SOUTH_WEST); - } - - break; - } - - case SwingConstants.SOUTH_WEST: { - if (flipX && flipY) { - l.setSide(SwingConstants.NORTH_EAST); - } else if (flipX) { - l.setSide(SwingConstants.SOUTH_EAST); - } else if (flipY) { - l.setSide(SwingConstants.NORTH_WEST); - } - break; - } - - case SwingConstants.NORTH_EAST: { - if (flipX && flipY) { - l.setSide(SwingConstants.SOUTH_WEST); - } else if (flipX) { - l.setSide(SwingConstants.NORTH_WEST); - } else if (flipY) { - l.setSide(SwingConstants.SOUTH_EAST); - } - break; - } - - case SwingConstants.SOUTH_EAST: { - if (flipX && flipY) { - l.setSide(SwingConstants.NORTH_WEST); - } else if (flipX) { - l.setSide(SwingConstants.SOUTH_WEST); - } else if (flipY) { - l.setSide(SwingConstants.NORTH_EAST); - } - break; - } - } - } - - // reset locator to update layout - setLocator(l); - } - - public Cursor getCursorFor(int side) { - switch (side) { - case SwingConstants.NORTH: - return new Cursor(Cursor.N_RESIZE_CURSOR); - - case SwingConstants.SOUTH: - return new Cursor(Cursor.S_RESIZE_CURSOR); - - case SwingConstants.EAST: - return new Cursor(Cursor.E_RESIZE_CURSOR); - - case SwingConstants.WEST: - return new Cursor(Cursor.W_RESIZE_CURSOR); - - case SwingConstants.NORTH_WEST: - return new Cursor(Cursor.NW_RESIZE_CURSOR); - - case SwingConstants.SOUTH_WEST: - return new Cursor(Cursor.SW_RESIZE_CURSOR); - - case SwingConstants.NORTH_EAST: - return new Cursor(Cursor.NE_RESIZE_CURSOR); - - case SwingConstants.SOUTH_EAST: - return new Cursor(Cursor.SE_RESIZE_CURSOR); - } - return null; - } -} diff --git a/extras/edu/umd/cs/piccolox/handles/PHandle.java b/extras/edu/umd/cs/piccolox/handles/PHandle.java deleted file mode 100644 index 8f2a2c7..0000000 --- a/extras/edu/umd/cs/piccolox/handles/PHandle.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.handles; - -import java.awt.Color; -import java.awt.Shape; -import java.awt.event.InputEvent; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Point2D; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.IOException; -import java.io.ObjectInputStream; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PDragSequenceEventHandler; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.event.PInputEventFilter; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolox.util.PLocator; -import edu.umd.cs.piccolox.util.PNodeLocator; - -/** - * PHandle is used to modify some aspect of Piccolo when it - * is dragged. Each handle has a PLocator that it uses to automatically position - * itself. See PBoundsHandle for an example of a handle that resizes the bounds - * of another node. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PHandle extends PPath { - - public static float DEFAULT_HANDLE_SIZE = 8; - public static Shape DEFAULT_HANDLE_SHAPE = new Ellipse2D.Float(0f, 0f, DEFAULT_HANDLE_SIZE, DEFAULT_HANDLE_SIZE); - public static Color DEFAULT_COLOR = Color.white; - - private PLocator locator; - private transient PDragSequenceEventHandler handleDragger; - - /** - * Construct a new handle that will use the given locator - * to locate itself on its parent node. - */ - public PHandle(PLocator aLocator) { - super(DEFAULT_HANDLE_SHAPE); - locator = aLocator; - setPaint(DEFAULT_COLOR); - installHandleEventHandlers(); - } - - protected void installHandleEventHandlers() { - handleDragger = new PDragSequenceEventHandler() { - protected void startDrag(PInputEvent event) { - super.startDrag(event); - startHandleDrag(event.getPositionRelativeTo(PHandle.this), event); - } - protected void drag(PInputEvent event) { - super.drag(event); - PDimension aDelta = event.getDeltaRelativeTo(PHandle.this); - if (aDelta.getWidth() != 0 || aDelta.getHeight() != 0) { - dragHandle(aDelta, event); - } - } - protected void endDrag(PInputEvent event) { - super.endDrag(event); - endHandleDrag(event.getPositionRelativeTo(PHandle.this), event); - } - }; - - addPropertyChangeListener(PNode.PROPERTY_TRANSFORM, new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - relocateHandle(); - } - }); - - handleDragger.setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK)); - handleDragger.getEventFilter().setMarksAcceptedEventsAsHandled(true); - handleDragger.getEventFilter().setAcceptsMouseEntered(false); - handleDragger.getEventFilter().setAcceptsMouseExited(false); - handleDragger.getEventFilter().setAcceptsMouseMoved(false); // no need for moved events for handle interaction, - // so reject them so we don't consume them - addInputEventListener(handleDragger); - } - - /** - * Return the event handler that is responsible for the drag handle - * interaction. - */ - public PDragSequenceEventHandler getHandleDraggerHandler() { - return handleDragger; - } - - /** - * Get the locator that this handle uses to position itself on its - * parent node. - */ - public PLocator getLocator() { - return locator; - } - - /** - * Set the locator that this handle uses to position itself on its - * parent node. - */ - public void setLocator(PLocator aLocator) { - locator = aLocator; - invalidatePaint(); - relocateHandle(); - } - - //**************************************************************** - // Handle Dragging - These are the methods the subclasses should - // normally override to give a handle unique behavior. - //**************************************************************** - - /** - * Override this method to get notified when the handle starts to get dragged. - */ - public void startHandleDrag(Point2D aLocalPoint, PInputEvent aEvent) { - } - - /** - * Override this method to get notified as the handle is dragged. - */ - public void dragHandle(PDimension aLocalDimension, PInputEvent aEvent) { - } - - /** - * Override this method to get notified when the handle stops getting dragged. - */ - public void endHandleDrag(Point2D aLocalPoint, PInputEvent aEvent) { - } - - //**************************************************************** - // Layout - When a handle's parent's layout changes the handle - // invalidates its own layout and then repositions itself on its - // parents bounds using its locator to determine that new - // position. - //**************************************************************** - - public void setParent(PNode newParent) { - super.setParent(newParent); - relocateHandle(); - } - - public void parentBoundsChanged() { - relocateHandle(); - } - - /** - * Force this handle to relocate itself using its locator. - */ - public void relocateHandle() { - if (locator != null) { - PBounds b = getBoundsReference(); - Point2D aPoint = locator.locatePoint(null); - - if (locator instanceof PNodeLocator) { - PNode located = ((PNodeLocator)locator).getNode(); - PNode parent = getParent(); - - located.localToGlobal(aPoint); - globalToLocal(aPoint); - - if (parent != located && parent instanceof PCamera) { - ((PCamera)parent).viewToLocal(aPoint); - } - } - - double newCenterX = aPoint.getX(); - double newCenterY = aPoint.getY(); - - if (newCenterX != b.getCenterX() || - newCenterY != b.getCenterY()) { - - centerBoundsOnPoint(newCenterX, newCenterY); - } - } - } - - //**************************************************************** - // Serialization - //**************************************************************** - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - installHandleEventHandlers(); - } -} \ No newline at end of file diff --git a/extras/edu/umd/cs/piccolox/handles/PStickyHandleManager.java b/extras/edu/umd/cs/piccolox/handles/PStickyHandleManager.java deleted file mode 100644 index a74c6be..0000000 --- a/extras/edu/umd/cs/piccolox/handles/PStickyHandleManager.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.handles; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PPickPath; - -public class PStickyHandleManager extends PNode { - - private PNode target; - private PCamera camera; - - public PStickyHandleManager(PCamera newCamera, PNode newTarget) { - setCameraTarget(newCamera, newTarget); - PBoundsHandle.addBoundsHandlesTo(this); - } - - public void setCameraTarget(PCamera newCamera, PNode newTarget) { - camera = newCamera; - camera.addChild(this); - target = newTarget; - } - - public boolean setBounds(double x, double y, double width, double height) { - PBounds b = new PBounds(x, y, width, height); - camera.localToGlobal(b); - camera.localToView(b); - target.globalToLocal(b); - target.setBounds(b); - return super.setBounds(x, y, width, height); - } - - protected boolean getBoundsVolatile() { - return true; - } - - public PBounds getBoundsReference() { - PBounds targetBounds = target.getFullBounds(); - camera.viewToLocal(targetBounds); - camera.globalToLocal(targetBounds); - PBounds bounds = super.getBoundsReference(); - bounds.setRect(targetBounds); - return super.getBoundsReference(); - } - - public void startResizeBounds() { - super.startResizeBounds(); - target.startResizeBounds(); - } - - public void endResizeBounds() { - super.endResizeBounds(); - target.endResizeBounds(); - } - - public boolean pickAfterChildren(PPickPath pickPath) { - return false; - } -} diff --git a/extras/edu/umd/cs/piccolox/handles/package.html b/extras/edu/umd/cs/piccolox/handles/package.html deleted file mode 100644 index e610ac8..0000000 --- a/extras/edu/umd/cs/piccolox/handles/package.html +++ /dev/null @@ -1,34 +0,0 @@ - - - -

This package contains handle nodes.

- - diff --git a/extras/edu/umd/cs/piccolox/nodes/P3DRect.java b/extras/edu/umd/cs/piccolox/nodes/P3DRect.java deleted file mode 100644 index b810656..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/P3DRect.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.nodes; - -import java.awt.*; -import java.awt.geom.*; -import edu.umd.cs.piccolo.*; -import edu.umd.cs.piccolo.util.*; -import edu.umd.cs.piccolox.*; - -/** - * This is a simple node that draws a "3D" rectangle within the bounds of the node. - * Drawing a 3D rectangle in a zooming environment is a little tricky because - * if you just use the regular (Java2D) 3D rectangle, the 3D borders get scaled, - * and that is ugly. This version always draws the 3D border at fixed 2 pixel width. - * - * @author Ben Bederson - */ -public class P3DRect extends PNode { - - private Color topLeftOuterColor; - private Color topLeftInnerColor; - private Color bottomRightInnerColor; - private Color bottomRightOuterColor; - private GeneralPath path; - private Stroke stroke; - private boolean raised; - - public P3DRect() { - raised = true; - stroke = new BasicStroke(0); - path = new GeneralPath(); - } - - public P3DRect(Rectangle2D bounds) { - this(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight()); - } - - public P3DRect(double x, double y, double width, double height) { - this(); - setBounds(x, y, width, height); - } - - public void setRaised(boolean raised) { - this.raised = raised; - setPaint(getPaint()); - } - - public boolean getRaised() { - return raised; - } - - protected void paint(PPaintContext paintContext) { - Graphics2D g2 = paintContext.getGraphics(); - - double x = getX(); - double y = getY(); - double width = getWidth(); - double height = getHeight(); - double magX = g2.getTransform().getScaleX(); - double magY = g2.getTransform().getScaleY(); - double dx = (float)(1.0 / magX); - double dy = (float)(1.0 / magY); - PBounds bounds = getBounds(); - - g2.setPaint(getPaint()); - g2.fill(bounds); - g2.setStroke(stroke); - - path.reset(); - path.moveTo((float)(x+width), (float)y); - path.lineTo((float)x, (float)y); - path.lineTo((float)x, (float)(y+height)); - g2.setPaint(topLeftOuterColor); - g2.draw(path); - - path.reset(); - path.moveTo((float)(x+width), (float)(y+dy)); - path.lineTo((float)(x+dx), (float)(y+dy)); - path.lineTo((float)(x+dx), (float)(y+height)); - g2.setPaint(topLeftInnerColor); - g2.draw(path); - - path.reset(); - path.moveTo((float)(x+width), (float)(y)); - path.lineTo((float)(x+width), (float)(y+height)); - path.lineTo((float)(x), (float)(y+height)); - g2.setPaint(bottomRightOuterColor); - g2.draw(path); - - path.reset(); - path.moveTo((float)(x+width-dx), (float)(y+dy)); - path.lineTo((float)(x+width-dx), (float)(y+height-dy)); - path.lineTo((float)(x), (float)(y+height-dy)); - g2.setPaint(bottomRightInnerColor); - g2.draw(path); - } - - public void setPaint(Paint newPaint) { - super.setPaint(newPaint); - - if (newPaint instanceof Color) { - Color color = (Color)newPaint; - - if (raised) { - topLeftOuterColor = color.brighter(); - topLeftInnerColor = topLeftOuterColor.brighter(); - bottomRightInnerColor = color.darker(); - bottomRightOuterColor = bottomRightInnerColor.darker(); - } else { - topLeftOuterColor = color.darker(); - topLeftInnerColor = topLeftOuterColor.darker(); - bottomRightInnerColor = color.brighter(); - bottomRightOuterColor = bottomRightInnerColor.brighter(); - } - } else { - topLeftOuterColor = null; - topLeftInnerColor = null; - bottomRightInnerColor = null; - bottomRightOuterColor = null; - } - } - - public static void main(String[] args) { - new PFrame() { - public void initialize() { - getCanvas().setDefaultRenderQuality(PPaintContext.LOW_QUALITY_RENDERING); - - P3DRect rect1 = new P3DRect(50, 50, 100, 100); - rect1.setPaint(new Color(239, 235, 222)); - - P3DRect rect2 = new P3DRect(50, 50, 100, 100); - rect2.setPaint(new Color(239, 235, 222)); - rect2.translate(110, 0); - rect2.setRaised(false); - - getCanvas().getLayer().addChild(rect1); - getCanvas().getLayer().addChild(rect2); - } - }; - } -} diff --git a/extras/edu/umd/cs/piccolox/nodes/PCacheCamera.java b/extras/edu/umd/cs/piccolox/nodes/PCacheCamera.java deleted file mode 100644 index 5697cb7..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/PCacheCamera.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Created on Mar 4, 2005 - */ -package edu.umd.cs.piccolox.nodes; - -import java.awt.Color; -import java.awt.GraphicsEnvironment; -import java.awt.Paint; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PRoot; -import edu.umd.cs.piccolo.activities.PTransformActivity; -import edu.umd.cs.piccolo.util.PAffineTransform; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolo.util.PUtil; - -/** - * An extension to PCamera that provides a fast image based animationToCenterBounds method - * - * @author Lance Good - */ -public class PCacheCamera extends PCamera { - - private BufferedImage paintBuffer; - private boolean imageAnimate; - private PBounds imageAnimateBounds; - - /** - * Get the buffer used to provide fast image based animation - */ - protected BufferedImage getPaintBuffer() { - PBounds fRef = getFullBoundsReference(); - if (paintBuffer == null || paintBuffer.getWidth() < fRef.getWidth() || paintBuffer.getHeight() < fRef.getHeight()) { - paintBuffer = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage((int)Math.ceil(fRef.getWidth()),(int)Math.ceil(fRef.getHeight())); - } - return paintBuffer; - } - - /** - * Caches the information necessary to animate from the current view bounds to the - * specified centerBounds - */ - private AffineTransform cacheViewBounds(Rectangle2D centerBounds, boolean scaleToFit) { - PBounds viewBounds = getViewBounds(); - - // Initialize the image to the union of the current and destination bounds - PBounds imageBounds = new PBounds(viewBounds); - imageBounds.add(centerBounds); - - animateViewToCenterBounds(imageBounds,scaleToFit,0); - - imageAnimateBounds = getViewBounds(); - - // Now create the actual cache image that we will use to animate fast - - BufferedImage buffer = getPaintBuffer(); - Paint fPaint = Color.white; - if (getPaint() != null) { - fPaint = getPaint(); - } - toImage(buffer,fPaint); - - // Do this after the painting above! - imageAnimate = true; - - // Return the bounds to the previous viewbounds - animateViewToCenterBounds(viewBounds,scaleToFit,0); - - // The code below is just copied from animateViewToCenterBounds to create the - // correct transform to center the specified bounds - - PDimension delta = viewBounds.deltaRequiredToCenter(centerBounds); - PAffineTransform newTransform = getViewTransform(); - newTransform.translate(delta.width, delta.height); - - if (scaleToFit) { - double s = Math.min(viewBounds.getWidth() / centerBounds.getWidth(), viewBounds.getHeight() / centerBounds.getHeight()); - newTransform.scaleAboutPoint(s, centerBounds.getCenterX(), centerBounds.getCenterY()); - } - - return newTransform; - } - - /** - * Turns off the fast image animation and does any other applicable cleanup - */ - private void clearViewCache() { - imageAnimate = false; - imageAnimateBounds = null; - } - - /** - * Mimics the standard animateViewToCenterBounds but uses a cached image for performance - * rather than re-rendering the scene at each step - */ - public PTransformActivity animateStaticViewToCenterBoundsFast(Rectangle2D centerBounds, boolean shouldScaleToFit, long duration) { - if (duration == 0) { - return animateViewToCenterBounds(centerBounds,shouldScaleToFit,duration); - } - - AffineTransform newViewTransform = cacheViewBounds(centerBounds,shouldScaleToFit); - - return animateStaticViewToTransformFast(newViewTransform, duration); - } - - /** - * This copies the behavior of the standard animateViewToTransform but clears the cache - * when it is done - */ - protected PTransformActivity animateStaticViewToTransformFast(AffineTransform destination, long duration) { - if (duration == 0) { - setViewTransform(destination); - return null; - } - - PTransformActivity.Target t = new PTransformActivity.Target() { - public void setTransform(AffineTransform aTransform) { - PCacheCamera.this.setViewTransform(aTransform); - } - public void getSourceMatrix(double[] aSource) { - getViewTransformReference().getMatrix(aSource); - } - }; - - PTransformActivity ta = new PTransformActivity(duration, PUtil.DEFAULT_ACTIVITY_STEP_RATE, t, destination) { - protected void activityFinished() { - clearViewCache(); - repaint(); - super.activityFinished(); - } - }; - - PRoot r = getRoot(); - if (r != null) { - r.getActivityScheduler().addActivity(ta); - } - - return ta; - } - - /** - * Overrides the camera's full paint method to do the fast rendering when possible - */ - public void fullPaint(PPaintContext paintContext) { - if (imageAnimate) { - PBounds fRef = getFullBoundsReference(); - PBounds viewBounds = getViewBounds(); - double scale = getFullBoundsReference().getWidth()/imageAnimateBounds.getWidth(); - double xOffset = (viewBounds.getX()-imageAnimateBounds.getX())*scale; - double yOffset = (viewBounds.getY()-imageAnimateBounds.getY())*scale; - double scaleW = viewBounds.getWidth()*scale; - double scaleH = viewBounds.getHeight()*scale; - paintContext.getGraphics().drawImage(paintBuffer,0,0,(int)Math.ceil(fRef.getWidth()),(int)Math.ceil(fRef.getHeight()), - (int)Math.floor(xOffset),(int)Math.floor(yOffset),(int)Math.ceil(xOffset+scaleW),(int)Math.ceil(yOffset+scaleH),null); - } - else { - super.fullPaint(paintContext); - } - } -} diff --git a/extras/edu/umd/cs/piccolox/nodes/PClip.java b/extras/edu/umd/cs/piccolox/nodes/PClip.java deleted file mode 100644 index 37300a3..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/PClip.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.nodes; - -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.geom.Rectangle2D; - -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolo.util.PPickPath; - -/** - * PClip is a simple node that applies a clip before rendering or picking its - * children. PClip is a subclass of PPath, the clip applies is the GeneralPath wrapped - * by its super class. See piccolo/examples ClipExample. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PClip extends PPath { - - public PBounds computeFullBounds(PBounds dstBounds) { - if (dstBounds == null) dstBounds = new PBounds(); - dstBounds.reset(); - dstBounds.add(getBoundsReference()); - localToParent(dstBounds); - return dstBounds; - } - - public void repaintFrom(PBounds localBounds, PNode childOrThis) { - if (childOrThis != this) { - Rectangle2D.intersect(getBoundsReference(), localBounds, localBounds); - super.repaintFrom(localBounds, childOrThis); - } else { - super.repaintFrom(localBounds, childOrThis); - } - } - - protected void paint(PPaintContext paintContext) { - Paint p = getPaint(); - if (p != null) { - Graphics2D g2 = paintContext.getGraphics(); - g2.setPaint(p); - g2.fill(getPathReference()); - } - paintContext.pushClip(getPathReference()); - } - - protected void paintAfterChildren(PPaintContext paintContext) { - paintContext.popClip(getPathReference()); - if (getStroke() != null && getStrokePaint() != null) { - Graphics2D g2 = paintContext.getGraphics(); - g2.setPaint(getStrokePaint()); - g2.setStroke(getStroke()); - g2.draw(getPathReference()); - } - } - - public boolean fullPick(PPickPath pickPath) { - if (getPickable() && fullIntersects(pickPath.getPickBounds())) { - pickPath.pushNode(this); - pickPath.pushTransform(getTransformReference(false)); - - if (pick(pickPath)) { - return true; - } - - if (getChildrenPickable() && getPathReference().intersects(pickPath.getPickBounds())) { - int count = getChildrenCount(); - for (int i = count - 1; i >= 0; i--) { - PNode each = getChild(i); - if (each.fullPick(pickPath)) - return true; - } - } - - if (pickAfterChildren(pickPath)) { - return true; - } - - pickPath.popTransform(getTransformReference(false)); - pickPath.popNode(this); - } - - return false; - } -} diff --git a/extras/edu/umd/cs/piccolox/nodes/PComposite.java b/extras/edu/umd/cs/piccolox/nodes/PComposite.java deleted file mode 100644 index 6079c2e..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/PComposite.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.nodes; - -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.util.PPickPath; - -/** - * PComposite is a simple node that makes a group of nodes appear to - * be a single node when picking and interacting. There is also partial - * (commented out) support for resizing the child node to fit when this - * nodes bounds are set. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PComposite extends PNode { - - /* - public boolean setBounds(double x, double y, double width, double height) { - PBounds childBounds = getUnionOfChildrenBounds(null); - - double dx = x - childBounds.x; - double dy = y - childBounds.y; - double sx = width / childBounds.width; - double sy = height / childBounds.height; - double scale = sx > sy ? sx : sy; - - Iterator i = getChildrenIterator(); - while (i.hasNext()) { - PNode each = (PNode) i.next(); - each.offset(dx, dy); - each.scaleAboutPoint(scale, each.getBoundsReference().x, each.getBoundsReference().y); - } - - return super.setBounds(x, y, width, height); - } - - protected void layoutChildren() { - getBoundsReference().setRect(getUnionOfChildrenBounds(null)); - } - */ - - /** - * Return true if this node or any pickable descendends are picked. If - * a pick occurs the pickPath is modified so that this node is always returned - * as the picked node, event if it was a decendent node that initialy reported the - * pick. - */ - public boolean fullPick(PPickPath pickPath) { - if (super.fullPick(pickPath)) { - PNode picked = pickPath.getPickedNode(); - - // this code won't work with internal cameras, because it doesn't pop - // the cameras view transform. - while (picked != this) { - pickPath.popTransform(picked.getTransformReference(false)); - pickPath.popNode(picked); - picked = pickPath.getPickedNode(); - } - - return true; - } - return false; - } -} diff --git a/extras/edu/umd/cs/piccolox/nodes/PLens.java b/extras/edu/umd/cs/piccolox/nodes/PLens.java deleted file mode 100644 index 249d7ea..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/PLens.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.nodes; - -import java.awt.Color; -import java.awt.Paint; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PDragEventHandler; -import edu.umd.cs.piccolo.nodes.PPath; - -/** - * PLens is a simple default lens implementation for Piccolo. See piccolo/examples - * LensExample for one possible use of this lens. Lens's are often application - * specific, it may be easiest to study this code, and then implement your own custom - * lens using the general principles illustrated here. - *

- * The basic design here is to add a PCamera as the child of a Pnode (the lens node). The camera is - * the viewing part of the lens, and the node is the title bar that can be used to - * move the lens around. Users of this lens will probably want to set up some lens - * specific event handler and attach it to the camera. - *

- * A lens also needs a layer that it will look at (it should not be the same as the layer - * that it's added to because then it will draw itself in a recursive loop. Last of all - * the PLens will need to be added to the PCanvas layer (so that it can be seen - * by the main camera). - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PLens extends PNode { - - public static double LENS_DRAGBAR_HEIGHT = 20; - public static Paint DEFAULT_DRAGBAR_PAINT = Color.DARK_GRAY; - public static Paint DEFAULT_LENS_PAINT = Color.LIGHT_GRAY; - - private PPath dragBar; - private PCamera camera; - private PDragEventHandler lensDragger; - - public PLens() { - dragBar = PPath.createRectangle(0, 0, 100, 100); // Drag bar gets resized to fit the available space, so any rectangle will do here - dragBar.setPaint(DEFAULT_DRAGBAR_PAINT); - dragBar.setPickable(false); // This forces drag events to percolate up to PLens object - addChild(dragBar); - - camera = new PCamera(); - camera.setPaint(DEFAULT_LENS_PAINT); - addChild(camera); - - // create an event handler to drag the lens around. Note that this event - // handler consumes events in case another conflicting event handler has been - // installed higher up in the heirarchy. - lensDragger = new PDragEventHandler(); - lensDragger.getEventFilter().setMarksAcceptedEventsAsHandled(true); - addInputEventListener(lensDragger); - - // When this PLens is dragged around adjust the cameras view transform. - addPropertyChangeListener(PNode.PROPERTY_TRANSFORM, new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - camera.setViewTransform(getInverseTransform()); - } - }); - } - - public PLens(PLayer layer) { - this(); - addLayer(0, layer); - } - - public PCamera getCamera() { - return camera; - } - - public PPath getDragBar() { - return dragBar; - } - - public PDragEventHandler getLensDraggerHandler() { - return lensDragger; - } - - public void addLayer(int index, PLayer layer) { - camera.addLayer(index, layer); - } - - public void removeLayer(PLayer layer) { - camera.removeLayer(layer); - } - - // when the lens is resized this method gives us a chance to layout the lenses - // camera child appropriately. - protected void layoutChildren() { - dragBar.setPathToRectangle((float)getX(), (float)getY(), (float)getWidth(), (float)LENS_DRAGBAR_HEIGHT); - camera.setBounds(getX(), getY() + LENS_DRAGBAR_HEIGHT, getWidth(), getHeight() - LENS_DRAGBAR_HEIGHT); - } -} diff --git a/extras/edu/umd/cs/piccolox/nodes/PLine.java b/extras/edu/umd/cs/piccolox/nodes/PLine.java deleted file mode 100644 index 8e682c3..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/PLine.java +++ /dev/null @@ -1,204 +0,0 @@ -package edu.umd.cs.piccolox.nodes; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.Stroke; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.nodes.PPath; -import edu.umd.cs.piccolo.util.PAffineTransform; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolo.util.PUtil; -import edu.umd.cs.piccolox.util.LineShape; - -/** - * PLine a class for drawing multisegment lines. - * Submitted by Hallvard Traetteberg. - */ -public class PLine extends PNode { - - private static final PAffineTransform TEMP_TRANSFORM = new PAffineTransform(); - private static final BasicStroke DEFAULT_STROKE = new BasicStroke(1.0f); - private static final Color DEFAULT_STROKE_PAINT = Color.black; - - private transient LineShape line; - private transient Stroke stroke; - private Paint strokePaint; - - public PLine(LineShape line) { - strokePaint = DEFAULT_STROKE_PAINT; - stroke = DEFAULT_STROKE; - if (line == null) { - line = new LineShape(null); - } - this.line = line; - } - - public PLine() { - this(null); - } - - public PLine(LineShape line, Stroke aStroke) { - this(line); - stroke = aStroke; - } - - //**************************************************************** - // Stroke - //**************************************************************** - - public Paint getStrokePaint() { - return strokePaint; - } - - public void setStrokePaint(Paint aPaint) { - Paint old = strokePaint; - strokePaint = aPaint; - invalidatePaint(); - firePropertyChange(PPath.PROPERTY_CODE_STROKE_PAINT, PPath.PROPERTY_STROKE_PAINT, old, strokePaint); - } - - public Stroke getStroke() { - return stroke; - } - - public void setStroke(Stroke aStroke) { - Stroke old = stroke; - stroke = aStroke; - updateBoundsFromLine(); - invalidatePaint(); - firePropertyChange(PPath.PROPERTY_CODE_STROKE, PPath.PROPERTY_STROKE, old, stroke); - } - - //**************************************************************** - // Bounds - //**************************************************************** - - public boolean setBounds(double x, double y, double width, double height) { - if (line == null || !super.setBounds(x, y, width, height)) { - return false; - } - - Rectangle2D lineBounds = line.getBounds2D(); - Rectangle2D lineStrokeBounds = getLineBoundsWithStroke(); - double strokeOutset = Math.max(lineStrokeBounds.getWidth() - lineBounds.getWidth(), - lineStrokeBounds.getHeight() - lineBounds.getHeight()); - - x += strokeOutset / 2; - y += strokeOutset / 2; - width -= strokeOutset; - height -= strokeOutset; - - TEMP_TRANSFORM.setToIdentity(); - TEMP_TRANSFORM.translate(x, y); - TEMP_TRANSFORM.scale(width / lineBounds.getWidth(), height / lineBounds.getHeight()); - TEMP_TRANSFORM.translate(-lineBounds.getX(), -lineBounds.getY()); - line.transformPoints(TEMP_TRANSFORM); - - return true; - } - - public boolean intersects(Rectangle2D aBounds) { - if (super.intersects(aBounds)) { - if (line.intersects(aBounds)) { - return true; - } else if (stroke != null && strokePaint != null) { - return stroke.createStrokedShape(line).intersects(aBounds); - } - } - return false; - } - - public Rectangle2D getLineBoundsWithStroke() { - if (stroke != null) { - return stroke.createStrokedShape(line).getBounds2D(); - } else { - return line.getBounds2D(); - } - } - - public void updateBoundsFromLine() { - if (line.getPointCount() == 0) { - resetBounds(); - } else { - Rectangle2D b = getLineBoundsWithStroke(); - super.setBounds(b.getX(), b.getY(), b.getWidth(), b.getHeight()); - } - } - - //**************************************************************** - // Painting - //**************************************************************** - - protected void paint(PPaintContext paintContext) { - Graphics2D g2 = paintContext.getGraphics(); - - if (stroke != null && strokePaint != null) { - g2.setPaint(strokePaint); - g2.setStroke(stroke); - g2.draw(line); - } - } - - public LineShape getLineReference() { - return line; - } - - public int getPointCount() { - return line.getPointCount(); - } - - public Point2D getPoint(int i, Point2D dst) { - if (dst == null) { - dst = new Point2D.Double(); - } - return line.getPoint(i, dst); - } - - protected void lineChanged() { - firePropertyChange(PPath.PROPERTY_CODE_PATH, PPath.PROPERTY_PATH, null, line); - updateBoundsFromLine(); - invalidatePaint(); - } - - public void setPoint(int i, double x, double y) { - line.setPoint(i, x, y); - lineChanged(); - } - - public void addPoint(int i, double x, double y) { - line.addPoint(i, x, y); - lineChanged(); - } - - public void removePoints(int i, int n) { - line.removePoints(i, n); - lineChanged(); - } - - public void removeAllPoints() { - line.removePoints(0, line.getPointCount()); - lineChanged(); - } - - //**************************************************************** - // Serialization - //**************************************************************** - - private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - PUtil.writeStroke(stroke, out); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - stroke = PUtil.readStroke(in); - } -} diff --git a/extras/edu/umd/cs/piccolox/nodes/PNodeCache.java b/extras/edu/umd/cs/piccolox/nodes/PNodeCache.java deleted file mode 100644 index 8304aba..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/PNodeCache.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.nodes; - -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.geom.Dimension2D; - -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PDimension; -import edu.umd.cs.piccolo.util.PPaintContext; -import edu.umd.cs.piccolo.util.PPickPath; - -/** - * PNodeCache caches a visual representation of it's children - * into an image and uses this cached image for painting instead of - * painting it's children directly. This is intended to be used in - * two ways. - *

- * First it can be used as a simple optimization technique. If a node - * has many descendents it may be faster to paint the cached image - * representation instead of painting each node. - *

- * Second PNodeCache provides a place where "image" effects such as - * blurring and drop shadows can be added to the Piccolo scene graph. - * This can be done by overriding the method createImageCache and - * returing an image with the desired effect applied. - *

- * @version 1.0 - * @author Jesse Grosjean - */ -public class PNodeCache extends PNode { - - private transient Image imageCache; - private boolean validatingCache; - - /** - * Override this method to customize the image cache creation process. For - * example if you want to create a shadow effect you would do that here. Fill - * in the cacheOffsetRef if needed to make your image cache line up with the - * nodes children. - */ - public Image createImageCache(Dimension2D cacheOffsetRef) { - return toImage(); - } - - public Image getImageCache() { - if (imageCache == null) { - PDimension cacheOffsetRef = new PDimension(); - validatingCache = true; - resetBounds(); - imageCache = createImageCache(cacheOffsetRef); - PBounds b = getFullBoundsReference(); - setBounds(b.getX() + cacheOffsetRef.getWidth(), - b.getY() + cacheOffsetRef.getHeight(), - imageCache.getWidth(null), - imageCache.getHeight(null)); - validatingCache = false; - } - return imageCache; - } - - public void invalidateCache() { - imageCache = null; - } - - public void invalidatePaint() { - if (!validatingCache) { - super.invalidatePaint(); - } - } - - public void repaintFrom(PBounds localBounds, PNode childOrThis) { - if (!validatingCache) { - super.repaintFrom(localBounds, childOrThis); - invalidateCache(); - } - } - - public void fullPaint(PPaintContext paintContext) { - if (validatingCache) { - super.fullPaint(paintContext); - } else { - Graphics2D g2 = paintContext.getGraphics(); - g2.drawImage(getImageCache(), (int) getX(), (int) getY(), null); - } - } - - protected boolean pickAfterChildren(PPickPath pickPath) { - return false; - } -} diff --git a/extras/edu/umd/cs/piccolox/nodes/PStyledText.java b/extras/edu/umd/cs/piccolox/nodes/PStyledText.java deleted file mode 100644 index b222041..0000000 --- a/extras/edu/umd/cs/piccolox/nodes/PStyledText.java +++ /dev/null @@ -1,680 +0,0 @@ -/* - * Copyright (c) 2002-@year@, University of Maryland - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions - * and the following disclaimer. - * - * Redistributions 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 the University of Maryland nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Piccolo was written at the Human-Computer Interaction Laboratory www.cs.umd.edu/hcil by Jesse Grosjean - * under the supervision of Ben Bederson. The Piccolo website is www.cs.umd.edu/hcil/piccolo. - */ -package edu.umd.cs.piccolox.nodes; - -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.font.FontRenderContext; -import java.awt.font.LineBreakMeasurer; -import java.awt.font.TextAttribute; -import java.awt.font.TextLayout; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.text.AttributedCharacterIterator; -import java.text.AttributedString; -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - -import javax.swing.text.AttributeSet; -import javax.swing.text.DefaultStyledDocument; -import javax.swing.text.Document; -import javax.swing.text.Element; -import javax.swing.text.StyleConstants; -import javax.swing.text.StyleContext; - -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.util.PPaintContext; - -/** - * @author Lance Good - */ -public class PStyledText extends PNode { - - protected static FontRenderContext SWING_FRC = new FontRenderContext(null,true,false); - protected static Line2D paintLine = new Line2D.Double(); - - protected Document document; - protected transient ArrayList stringContents; - protected transient LineInfo[] lines; - - protected boolean editing; - protected Insets insets = new Insets(0,0,0,0); - protected boolean constrainHeightToTextHeight = true; - protected boolean constrainWidthToTextWidth = true; - - /** - * Constructor for PStyledText. - */ - public PStyledText() { - super(); - } - - /** - * Controls whether this node changes its width to fit the width - * of its text. If flag is true it does; if flag is false it doesn't - */ - public void setConstrainWidthToTextWidth(boolean constrainWidthToTextWidth) { - this.constrainWidthToTextWidth = constrainWidthToTextWidth; - recomputeLayout(); - } - - /** - * Controls whether this node changes its height to fit the height - * of its text. If flag is true it does; if flag is false it doesn't - */ - public void setConstrainHeightToTextHeight(boolean constrainHeightToTextHeight) { - this.constrainHeightToTextHeight = constrainHeightToTextHeight; - recomputeLayout(); - } - - /** - * Controls whether this node changes its width to fit the width - * of its text. If flag is true it does; if flag is false it doesn't - */ - public boolean getConstrainWidthToTextWidth() { - return constrainWidthToTextWidth; - } - - /** - * Controls whether this node changes its height to fit the height - * of its text. If flag is true it does; if flag is false it doesn't - */ - public boolean getConstrainHeightToTextHeight() { - return constrainHeightToTextHeight; - } - - /** - * Get the document for this PStyledText - */ - public Document getDocument() { - return document; - } - - /** - * Set the document on this PStyledText - */ - public void setDocument(Document document) { - // Save the document - this.document = document; - - syncWithDocument(); - } - - - public void syncWithDocument() { - // The paragraph start and end indices - ArrayList pEnds = null; - - // The current position in the specified range - int pos = 0; - - // First get the actual text and stick it in an Attributed String - try { - - stringContents = new ArrayList(); - pEnds = new ArrayList(); - - String s = document.getText(0,document.getLength()); - StringTokenizer tokenizer = new StringTokenizer(s,"\n",true); - - // lastNewLine is used to detect the case when two newlines follow in direct succession - // & lastNewLine should be true to start in case the first character is a newline - boolean lastNewLine = true; - for(int i=0; tokenizer.hasMoreTokens(); i++) { - String token = tokenizer.nextToken(); - - // If the token - if (token.equals("\n")) { - if (lastNewLine) { - stringContents.add(new AttributedString(" ")); - pEnds.add(new RunInfo(pos,pos+1)); - - pos = pos + 1; - - lastNewLine = true; - } - else { - pos = pos + 1; - - lastNewLine = true; - } - } - // If the token is empty - create an attributed string with a single space - // since LineBreakMeasurers don't work with an empty string - // - note that this case should only arise if the document is empty - else if (token.equals("")) { - stringContents.add(new AttributedString(" ")); - pEnds.add(new RunInfo(pos,pos)); - - lastNewLine = false; - } - // This is the normal case - where we have some text - else { - stringContents.add(new AttributedString(token)); - pEnds.add(new RunInfo(pos,pos+token.length())); - - // Increment the position - pos = pos+token.length(); - - lastNewLine = false; - } - } - - // Add one more newline if the last character was a newline - if (lastNewLine) { - stringContents.add(new AttributedString(" ")); - pEnds.add(new RunInfo(pos,pos+1)); - - lastNewLine = false; - } - } - catch (Exception e) { - e.printStackTrace(); - } - - // The default style context - which will be reused - StyleContext style = StyleContext.getDefaultStyleContext(); - - RunInfo pEnd = null; - for (int i = 0; i < stringContents.size(); i++) { - pEnd = (RunInfo)pEnds.get(i); - pos = pEnd.runStart; - - // The current element will be used as a temp variable while searching - // for the leaf element at the current position - Element curElement = null; - - // Small assumption here that there is one root element - can fix - // for more general support later - Element rootElement = document.getDefaultRootElement(); - - // If the string is length 0 then we just need to add the attributes once - if (pEnd.runStart != pEnd.runLimit) { - // OK, now we loop until we find all the leaf elements in the range - while (pos < pEnd.runLimit) { - - // Before each pass, start at the root - curElement = rootElement; - - // Now we descend the hierarchy until we get to a leaf - while (!curElement.isLeaf()) { - curElement = - curElement.getElement(curElement.getElementIndex(pos)); - } - - // These are the mandatory attributes - - AttributeSet attributes = curElement.getAttributes(); - Color foreground = style.getForeground(attributes); - - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.FOREGROUND, - foreground, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - - Font font = (attributes.isDefined(StyleConstants.FontSize) || attributes.isDefined(StyleConstants.FontFamily)) ? style.getFont(attributes) : null; - if (font == null) { - if (document instanceof DefaultStyledDocument) { - font = style.getFont(((DefaultStyledDocument)document).getCharacterElement(pos).getAttributes()); - if (font == null) { - font = style.getFont(((DefaultStyledDocument)document).getParagraphElement(pos).getAttributes()); - } - if (font == null) { - font = style.getFont(rootElement.getAttributes()); - } - } - else { - font = style.getFont(rootElement.getAttributes()); - } - } - if (font != null) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.FONT, - font, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - - // These are the optional attributes - - Color background = (attributes.isDefined(StyleConstants.Background)) ? style.getBackground(attributes) : null; - if (background != null) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.BACKGROUND, - background, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - - boolean underline = StyleConstants.isUnderline(attributes); - if (underline) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.UNDERLINE, - Boolean.TRUE, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - - boolean strikethrough = StyleConstants.isStrikeThrough(attributes); - if (strikethrough) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.STRIKETHROUGH, - Boolean.TRUE, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - - // And set the position to the end of the given attribute - pos = curElement.getEndOffset(); - } - } - else { - // Before each pass, start at the root - curElement = rootElement; - - // Now we descend the hierarchy until we get to a leaf - while (!curElement.isLeaf()) { - curElement = - curElement.getElement(curElement.getElementIndex(pos)); - } - - // These are the mandatory attributes - - AttributeSet attributes = curElement.getAttributes(); - Color foreground = style.getForeground(attributes); - - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.FOREGROUND, - foreground, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - - // These are the optional attributes - - Font font = (attributes.isDefined(StyleConstants.FontSize) || attributes.isDefined(StyleConstants.FontFamily)) ? style.getFont(attributes) : null; - if (font == null) { - if (document instanceof DefaultStyledDocument) { - font = style.getFont(((DefaultStyledDocument)document).getCharacterElement(pos).getAttributes()); - if (font == null) { - font = style.getFont(((DefaultStyledDocument)document).getParagraphElement(pos).getAttributes()); - } - if (font == null) { - font = style.getFont(rootElement.getAttributes()); - } - } - else { - font = style.getFont(rootElement.getAttributes()); - } - } - if (font != null) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.FONT, - font, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - - Color background = (attributes.isDefined(StyleConstants.Background)) ? style.getBackground(attributes) : null; - if (background != null) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.BACKGROUND, - background, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - - boolean underline = StyleConstants.isUnderline(attributes); - if (underline) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.UNDERLINE, - Boolean.TRUE, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - - boolean strikethrough = StyleConstants.isStrikeThrough(attributes); - if (strikethrough) { - ((AttributedString)stringContents.get(i)).addAttribute( - TextAttribute.STRIKETHROUGH, - Boolean.TRUE, - (int)Math.max(0,curElement.getStartOffset()-pEnd.runStart), - (int)Math.min(pEnd.runLimit-pEnd.runStart,curElement.getEndOffset()-pEnd.runStart)); - } - } - } - - recomputeLayout(); - } - - /** - * Compute the bounds of the text wrapped by this node. The text layout - * is wrapped based on the bounds of this node. If the shrinkBoundsToFit parameter - * is true then after the text has been laid out the bounds of this node are shrunk - * to fit around those text bounds. - */ - public void recomputeLayout() { - if (stringContents == null) return; - - ArrayList linesList = new ArrayList(); - - double textWidth = 0; - double textHeight = 0; - - for(int i=0; i - - -

This package contains additional nodes that may be useful for Piccolo applications.

- - diff --git a/extras/edu/umd/cs/piccolox/package.html b/extras/edu/umd/cs/piccolox/package.html deleted file mode 100644 index 05d102e..0000000 --- a/extras/edu/umd/cs/piccolox/package.html +++ /dev/null @@ -1,34 +0,0 @@ - - - -

Piccolo extras (piccolox) provides additional features not found in the core Piccolo library.

- - diff --git a/extras/edu/umd/cs/piccolox/pswing/PComboBox.java b/extras/edu/umd/cs/piccolox/pswing/PComboBox.java deleted file mode 100644 index 29d9f86..0000000 --- a/extras/edu/umd/cs/piccolox/pswing/PComboBox.java +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Copyright (C) 1998-2000 by University of Maryland, College Park, MD 20742, USA - * All rights reserved. - */ -package edu.umd.cs.piccolox.pswing; - -import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; -import java.io.Serializable; -import java.util.Vector; - -import javax.swing.ComboBoxModel; -import javax.swing.JComboBox; -import javax.swing.plaf.basic.BasicComboBoxUI; -import javax.swing.plaf.basic.BasicComboPopup; -import javax.swing.plaf.basic.ComboPopup; - -/** - * The PComboBox is used instead of a JComboBox in a Piccolo scene graph. - * This PComboBox won't work properly if it is located in an abnormal hierarchy of Cameras. - * Support is provided for only one (or zero) view transforms. - *

- * A ComboBox for use in Piccolo. This still has an associated JPopupMenu - * (which is always potentially heavyweight depending on component location - * relative to containing window borders.) However, this ComboBox places - * the PopupMenu component of the ComboBox in the appropriate position - * relative to the permanent part of the ComboBox. The PopupMenu is never - * transformed. - *

- * This class was not designed for subclassing. If different behavior - * is required, it seems more appropriate to subclass JComboBox directly - * using this class as a model. - *

- * NOTE: There is currently a known bug, namely, if the ComboBox receives - * focus through 'tab' focus traversal and the keyboard is used to interact - * with the ComboBox, there may be unexpected results. - *

- *

- * Warning: Serialized objects of this class will not be - * compatible with future Piccolo releases. The current serialization support is - * appropriate for short term storage or RMI between applications running the - * same version of Piccolo. A future release of Piccolo will provide support for long - * term persistence. - * - * @author Lance Good - */ -public class PComboBox extends JComboBox implements Serializable { - - private PSwing pSwing; - private PSwingCanvas canvas; - - /** - * Creates a PComboBox that takes its items from an existing ComboBoxModel. - * - * @param model The ComboBoxModel from which the list will be created - */ - public PComboBox( ComboBoxModel model ) { - super( model ); - init(); - } - - /** - * Creates a PComboBox that contains the elements in the specified array. - * - * @param items The items to populate the PComboBox list - */ - public PComboBox( final Object items[] ) { - super( items ); - init(); - } - - /** - * Creates a PComboBox that contains the elements in the specified Vector. - * - * @param items The items to populate the PComboBox list - */ - public PComboBox( Vector items ) { - super( items ); - init(); - } - - /** - * Create an empty PComboBox - */ - public PComboBox() { - super(); - init(); - } - - /** - * Substitue our UI for the default - */ - private void init() { - setUI( new PBasicComboBoxUI() ); - } - - /** - * Clients must set the PSwing and PSwingCanvas environment for this PComboBox to work properly. - * - * @param pSwing - * @param canvas - */ - public void setEnvironment( PSwing pSwing, PSwingCanvas canvas ) { - this.pSwing = pSwing; - this.canvas = canvas; - } - - /** - * The substitute look and feel - used to capture the mouse - * events on the arrowButton and the component itself and - * to create our PopupMenu rather than the default - */ - protected class PBasicComboBoxUI extends BasicComboBoxUI { - - /** - * Create our Popup instead of theirs - */ - protected ComboPopup createPopup() { - PBasicComboPopup popup = new PBasicComboPopup( comboBox ); - popup.getAccessibleContext().setAccessibleParent( comboBox ); - return popup; - } - } - - /** - * The substitute ComboPopupMenu that places itself correctly - * in Piccolo. - */ - protected class PBasicComboPopup extends BasicComboPopup { - - /** - * @param combo The parent ComboBox - */ - public PBasicComboPopup( JComboBox combo ) { - super( combo ); - } - - - /** - * Computes the bounds for the Popup in Piccolo if a - * PMouseEvent has been received. Otherwise, it uses the - * default algorithm for placing the popup. - * - * @param px corresponds to the x coordinate of the popup - * @param py corresponds to the y coordinate of the popup - * @param pw corresponds to the width of the popup - * @param ph corresponds to the height of the popup - * @return The bounds for the PopupMenu - */ - protected Rectangle computePopupBounds( int px, int py, int pw, int ph ) { - Rectangle2D r = getNodeBoundsInCanvas(); - Rectangle sup = super.computePopupBounds( px, py, pw, ph ); - return new Rectangle( (int)r.getX(), (int)r.getMaxY(), (int)sup.getWidth(), (int)sup.getHeight() ); - } - } - - private Rectangle2D getNodeBoundsInCanvas() { - if( pSwing == null || canvas == null ) { - throw new RuntimeException( "PComboBox.setEnvironment( swing, pCanvas );//has to be done manually at present" ); - } - Rectangle2D r1c = pSwing.getBounds(); - pSwing.localToGlobal( r1c ); - canvas.getCamera().globalToLocal( r1c ); - r1c = canvas.getCamera().getViewTransform().createTransformedShape( r1c ).getBounds2D(); - return r1c; - } - -} - - - - - - - - - - - - - diff --git a/extras/edu/umd/cs/piccolox/pswing/PSwing.java b/extras/edu/umd/cs/piccolox/pswing/PSwing.java deleted file mode 100644 index 3bd2e74..0000000 --- a/extras/edu/umd/cs/piccolox/pswing/PSwing.java +++ /dev/null @@ -1,546 +0,0 @@ -/** - * Copyright (C) 1998-2000 by University of Maryland, College Park, MD 20742, USA - * All rights reserved. - */ -package edu.umd.cs.piccolox.pswing; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PPaintContext; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; - -/* - This message was sent to Sun on August 27, 1999 - - ----------------------------------------------- - - We are currently developing Piccolo, a "scenegraph" for use in 2D graphics. - One of our ultimate goals is to support Swing lightweight components - within Piccolo, whose graphical space supports arbitray affine transforms. - The challenge in this pursuit is getting the components to respond and - render properly though not actually displayed in a standard Java component - hierarchy. - - - The first issues involved making the Swing components focusable and - showing. This was accomplished by adding the Swing components to a 0x0 - JComponent which was in turn added to our main Piccolo application component. - To our good fortune, a Java component is showing merely if it and its - ancestors are showing and not based on whether it is ACTUALLY visible. - Likewise, focus in a JComponent depends merely on the component's - containing window having focus. - - - The second issue involved capturing the repaint calls on a Swing - component. Normally, for a repaint and the consequent call to - paintImmediately, a Swing component obtains the Graphics object necessary - to render itself through the Java component heirarchy. However, for Piccolo - we would like the component to render using a Graphics object that Piccolo - may have arbitrarily transformed in some way. By capturing in the - RepaintManager the repaint calls made on our special Swing components, we - are able to redirect the repaint requests through the Piccolo architecture to - put the Graphics in its proper context. Unfortunately, this means that - if the Swing component contains other Swing components, then any repaint - requests made by one of these nested components must go through - the Piccolo architecture then through the top level Swing component - down to the nested Swing component. This normally doesn't cause a - problem. However, if calling paint on one of these nested - children causes a call to repaint then an infinite loop ensues. This does - in fact happen in the Swing components that use cell renderers. Before - the cell renderer is painted, it is invalidated and consequently - repainted. We solved this problem by putting a lock on repaint calls for - a component while that component is painting. (A similar problem faced - the Swing team over this same issue. They solved it by inserting a - CellRendererPane to capture the renderer's invalidate calls.) - - - Another issue arose over the forwarding of mouse events to the Swing - components. Since our Swing components are not actually displayed on - screen in the standard manner, we must manually dispatch any MouseEvents - we want the component to receive. Hence, we needed to find the deepest - visible component at a particular location that accepts MouseEvents. - Finding the deepest visible component at a point was achieved with the - "findComponentAt" method in java.awt.Container. With the - "getListeners(Class listenerType)" method added in JDK1.3 Beta we are able - to determine if the component has any Mouse Listeners. However, we haven't - yet found a way to determine if MouseEvents have been specifically enabled - for a component. The package private method "eventEnabled" in - java.awt.Component does exactly what we want but is, of course, - inaccessible. In order to dispatch events correctly we would need a - public accessor to the method "boolean eventEnabled(AWTEvent)" in - java.awt.Component. - - - Still another issue involves the management of cursors when the mouse is - over a Swing component in our application. To the Java mechanisms, the - mouse never appears to enter the bounds of the Swing components since they - are contained by a 0x0 JComponent. Hence, we must manually change the - cursor when the mouse enters one of the Swing components in our - application. This generally works but becomes a problem if the Swing - component's cursor changes while we are over that Swing component (for - instance, if you resize a Table Column). In order to manage cursors - properly, we would need setCursor to fire property change events. - - - With the above fixes, most Swing components work. The only Swing - components that are definitely broken are ToolTips and those that rely on - JPopupMenu. In order to implement ToolTips properly, we would need to have - a method in ToolTipManager that allows us to set the current manager, as - is possible with RepaintManager. In order to implement JPopupMenu, we - will likely need to reimplement JPopupMenu to function in Piccolo with - a transformed Graphics and to insert itself in the proper place in the - Piccolo scenegraph. - -*/ - - -/** - * PSwing is used to add Swing Components to a Piccolo canvas. - *

- * Example: adding a swing JButton to a PCanvas: - *

- *     PSwingCanvas canvas = new PSwingCanvas();
- *     JButton button = new JButton("Button");
- *     swing = new PSwing(canvas, button);
- *     canvas.getLayer().addChild(swing);
- * 
- * 

- * NOTE: PSwing has the current limitation that it does not listen for - * Container events. This is only an issue if you create a PSwing - * and later add Swing components to the PSwing's component hierarchy - * that do not have double buffering turned off or have a smaller font - * size than the minimum font size of the original PSwing's component - * hierarchy. - *

- * For instance, the following bit of code will give unexpected - * results: - *

- *            JPanel panel = new JPanel();
- *            PSwing swing = new PSwing(panel);
- *            JPanel newChild = new JPanel();
- *            newChild.setDoubleBuffered(true);
- *            panel.add(newChild);
- *       
- *

- * NOTE: PSwing cannot be correctly interacted with through multiple cameras. - * There is no support for it yet. - *

- * NOTE: PSwing is java.io.Serializable. - *

- * Warning: Serialized objects of this class will not be - * compatible with future Piccolo releases. The current serialization support is - * appropriate for short term storage or RMI between applications running the - * same version of Piccolo. A future release of Piccolo will provide support for long - * term persistence. - * - * @author Sam R. Reid - * @author Benjamin B. Bederson - * @author Lance E. Good - * - * 3-23-2007 edited to automatically detect PCamera/PSwingCanvas to allow single-arg constructor usage - */ -public class PSwing extends PNode implements Serializable, PropertyChangeListener { - - - /** - * Used as a hashtable key for this object in the Swing component's - * client properties. - */ - public static final String PSWING_PROPERTY = "PSwing"; - private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform(); - private static PBounds TEMP_REPAINT_BOUNDS2 = new PBounds(); - - /** - * The cutoff at which the Swing component is rendered greek - */ - private double renderCutoff = 0.3; - private JComponent component = null; - private double minFontSize = Double.MAX_VALUE; - private Stroke defaultStroke = new BasicStroke(); - private Font defaultFont = new Font( "Serif", Font.PLAIN, 12 ); - private BufferedImage buffer; - private static final Color BUFFER_BACKGROUND_COLOR = new Color( 0, 0, 0, 0 ); - private PSwingCanvas canvas; - - //////////////////////////////////////////////////////////// - ///////Following fields are for automatic canvas/camera detection - //////////////////////////////////////////////////////////// - /*/keep track of which nodes we've attached listeners to since no built in support in PNode*/ - private ArrayList listeningTo = new ArrayList(); - - /*The parent listener for camera/canvas changes*/ - private PropertyChangeListener parentListener = new PropertyChangeListener() { - public void propertyChange( PropertyChangeEvent evt ) { - PNode source = (PNode)evt.getSource(); - PNode parent = source.getParent(); - if( parent != null ) { - listenForCanvas( parent ); - } - - } - }; - - /** - * Constructs a new visual component wrapper for the Swing component. - * - * @param component The swing component to be wrapped - */ - public PSwing(JComponent component) { - this.component = component; - component.putClientProperty( PSWING_PROPERTY, this ); - init( component ); - component.revalidate(); - component.addPropertyChangeListener( new PropertyChangeListener() { - public void propertyChange( PropertyChangeEvent evt ) { - reshape(); - } - } ); - reshape(); - listenForCanvas( this ); - } - - /** - * Deprecated constructor for application code still depending on this signature. - * @param pSwingCanvas - * @param component - * @deprecated - */ - public PSwing(PSwingCanvas pSwingCanvas, JComponent component) { - this(component); - } - - /** - * Ensures the bounds of the underlying component are accurate, and sets the bounds of this PNode. - */ - void reshape() { - component.setBounds( 0, 0, component.getPreferredSize().width, component.getPreferredSize().height ); - setBounds( 0, 0, component.getPreferredSize().width, component.getPreferredSize().height ); - } - - /** - * Determines if the Swing component should be rendered normally or - * as a filled rectangle. - *

- * The transform, clip, and composite will be set appropriately when this object - * is rendered. It is up to this object to restore the transform, clip, and composite of - * the Graphics2D if this node changes any of them. However, the color, font, and stroke are - * unspecified by Piccolo. This object should set those things if they are used, but - * they do not need to be restored. - * - * @param renderContext Contains information about current render. - */ - public void paint( PPaintContext renderContext ) { - Graphics2D g2 = renderContext.getGraphics(); - - if( defaultStroke == null ) { - defaultStroke = new BasicStroke(); - } - g2.setStroke( defaultStroke ); - - if( defaultFont == null ) { - defaultFont = new Font( "Serif", Font.PLAIN, 12 ); - } - - g2.setFont( defaultFont ); - - if( component.getParent() == null ) { -// pSwingCanvas.getSwingWrapper().add( component ); - component.revalidate(); - } - - if( shouldRenderGreek( renderContext ) ) { - paintAsGreek( g2 ); - } - else { - paint( g2 ); - } - - } - - protected boolean shouldRenderGreek( PPaintContext renderContext ) { - return ( renderContext.getScale() < renderCutoff -// && pSwingCanvas.getInteracting() - ) || - minFontSize * renderContext.getScale() < 0.5; - } - - /** - * Paints the Swing component as greek. - * - * @param g2 The graphics used to render the filled rectangle - */ - public void paintAsGreek( Graphics2D g2 ) { - Color background = component.getBackground(); - Color foreground = component.getForeground(); - Rectangle2D rect = getBounds(); - - if( background != null ) { - g2.setColor( background ); - } - g2.fill( rect ); - - if( foreground != null ) { - g2.setColor( foreground ); - } - g2.draw( rect ); - } - - /** - * Remove from the SwingWrapper; throws an exception if no canvas is associated with this PSwing. - */ - public void removeFromSwingWrapper() { - if( canvas != null && Arrays.asList( this.canvas.getSwingWrapper().getComponents() ).contains( component ) ) { - this.canvas.getSwingWrapper().remove( component ); - } - } - - /** - * Renders to a buffered image, then draws that image to the - * drawing surface associated with g2 (usually the screen). - * - * @param g2 graphics context for rendering the JComponent - */ - public void paint( Graphics2D g2 ) { - if( component.getBounds().isEmpty() ) { - // The component has not been initialized yet. - return; - } - - PSwingRepaintManager manager = (PSwingRepaintManager)RepaintManager.currentManager( component ); - manager.lockRepaint( component ); - - Graphics2D bufferedGraphics = null; - if( !isBufferValid() ) { - // Get the graphics context associated with a new buffered image. - // Use TYPE_INT_ARGB_PRE so that transparent components look good on Windows. - buffer = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE ); - bufferedGraphics = buffer.createGraphics(); - } - else { - // Use the graphics context associated with the existing buffered image - bufferedGraphics = buffer.createGraphics(); - // Clear the buffered image to prevent artifacts on Macintosh - bufferedGraphics.setBackground( BUFFER_BACKGROUND_COLOR ); - bufferedGraphics.clearRect( 0, 0, component.getWidth(), component.getHeight() ); - } - - // Start with the rendering hints from the provided graphics context - bufferedGraphics.setRenderingHints( g2.getRenderingHints() ); - - //PSwing sometimes causes JComponent text to render with "..." when fractional font metrics are enabled. These are now always disabled for the offscreen buffer. - bufferedGraphics.setRenderingHint( RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF ); - - // Draw the component to the buffer - component.paint( bufferedGraphics ); - - // Draw the buffer to g2's associated drawing surface - g2.drawRenderedImage( buffer, IDENTITY_TRANSFORM ); - - manager.unlockRepaint( component ); - } - - /** - * Tells whether the buffer for the image of the Swing components - * is currently valid. - * - * @return true if the buffer is currently valid - */ - private boolean isBufferValid() { - return !( buffer == null || buffer.getWidth() != component.getWidth() || buffer.getHeight() != component.getHeight() ); - } - - /** - * Repaints the specified portion of this visual component - * Note that the input parameter may be modified as a result of this call. - * - * @param repaintBounds - */ - public void repaint( PBounds repaintBounds ) { - Shape sh = getTransform().createTransformedShape( repaintBounds ); - TEMP_REPAINT_BOUNDS2.setRect( sh.getBounds2D() ); - repaintFrom( TEMP_REPAINT_BOUNDS2, this ); - } - - /** - * Sets the Swing component's bounds to its preferred bounds - * unless it already is set to its preferred size. Also - * updates the visual components copy of these bounds - */ - public void computeBounds() { - reshape(); -// if( !component.getBounds().isEmpty() ) { -// Dimension d = component.getPreferredSize(); -// getBoundsReference().setRect( 0, 0, d.getWidth(), d.getHeight() ); -// if( !component.getSize().equals( d ) ) { -// component.setBounds( 0, 0, (int)d.getWidth(), (int)d.getHeight() ); -// } -// } - } - - /** - * Returns the Swing component that this visual component wraps - * - * @return The Swing component that this visual component wraps - */ - public JComponent getComponent() { - return component; - } - - /** - * We need to turn off double buffering of Swing components within - * Piccolo since all components contained within a native container - * use the same buffer for double buffering. With normal Swing - * widgets this is fine, but for Swing components within Piccolo this - * causes problems. This function recurses the component tree - * rooted at c, and turns off any double buffering in use. It also - * updates the minimum font size based on the font size of c and adds - * a property change listener to listen for changes to the font. - * - * @param c The Component to be recursively unDoubleBuffered - */ - void init( Component c ) { - Component[] children = null; - if( c instanceof Container ) { - children = ( (Container)c ).getComponents(); - } - - if( c.getFont() != null ) { - minFontSize = Math.min( minFontSize, c.getFont().getSize() ); - } - - if( children != null ) { - for( int j = 0; j < children.length; j++ ) { - init( children[j] ); - } - } - - if( c instanceof JComponent ) { - ( (JComponent)c ).setDoubleBuffered( false ); - c.addPropertyChangeListener( "font", this ); - c.addComponentListener( new ComponentAdapter() { - public void componentResized( ComponentEvent e ) { - computeBounds(); - } - - public void componentShown( ComponentEvent e ) { - computeBounds(); - } - } ); - } - } - - /** - * Listens for changes in font on components rooted at this PSwing - */ - public void propertyChange( PropertyChangeEvent evt ) { - if( component.isAncestorOf( (Component)evt.getSource() ) && - ( (Component)evt.getSource() ).getFont() != null ) { - minFontSize = Math.min( minFontSize, ( (Component)evt.getSource() ).getFont().getSize() ); - } - } - - private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - init( component ); - } - - //////////////////////////////////////////////////////////// - ///////Start methods for automatic canvas detection - //////////////////////////////////////////////////////////// - /** - * Attaches a listener to the specified node and all its parents to listen - * for a change in the PSwingCanvas. Only PROPERTY_PARENT listeners are added - * so this code wouldn't handle if a PLayer were viewed by a different PCamera - * since that constitutes a child change. - * @param node The child node at which to begin a parent-based traversal for adding listeners. - */ - private void listenForCanvas( PNode node ) { - //need to get the full tree for this node - PNode p = node; - while( p != null ) { - listenToNode( p ); - - PNode parent = p; -// System.out.println( "parent = " + parent.getClass() ); - if( parent instanceof PLayer ) { - PLayer player = (PLayer)parent; -// System.out.println( "Found player: with " + player.getCameraCount() + " cameras" ); - for( int i = 0; i < player.getCameraCount(); i++ ) { - PCamera cam = player.getCamera( i ); - if( cam.getComponent() instanceof PSwingCanvas ) { - updateCanvas( (PSwingCanvas)cam.getComponent() ); - break; - } - } - } - p = p.getParent(); - } - } - - /** - * Attach a listener to the specified node, if one has not already been attached. - * @param node the node to listen to for parent/pcamera/pcanvas changes - */ - private void listenToNode( PNode node ) { -// System.out.println( "listeningTo.size() = " + listeningTo.size() ); - if( !listeningTo( node ) ) { - listeningTo.add( node ); - node.addPropertyChangeListener( PNode.PROPERTY_PARENT, parentListener ); - } - } - - /** - * Determine whether this PSwing is already listening to the specified node for camera/canvas changes. - * @param node the node to check - * @return true if this PSwing is already listening to the specified node for camera/canvas changes - */ - private boolean listeningTo( PNode node ) { - for( int i = 0; i < listeningTo.size(); i++ ) { - PNode pNode = (PNode)listeningTo.get( i ); - if( pNode == node ) { - return true; - } - } - return false; - } - - /** - * Removes this PSwing from previous PSwingCanvas (if any), and ensure that this PSwing is attached to the new PSwingCanvas. - * @param newCanvas the new PSwingCanvas (may be null) - */ - private void updateCanvas( PSwingCanvas newCanvas ) { - if( newCanvas != canvas ) { - if( canvas != null ) { - canvas.removePSwing( this ); - } - if( newCanvas != null ) { - canvas = newCanvas; - canvas.addPSwing( this ); - reshape(); - repaint(); - canvas.invalidate(); - canvas.revalidate(); - canvas.repaint(); - } - } - } - //////////////////////////////////////////////////////////// - ///////End methods for automatic canvas detection - //////////////////////////////////////////////////////////// -} diff --git a/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java b/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java deleted file mode 100644 index d7263f8..0000000 --- a/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright 2003-2005, University of Colorado */ - -/* - * CVS Info - - * Filename : $Source$ - * Branch : $Name$ - * Modified by : $Author: samreid $ - * Revision : $Revision: 13998 $ - * Date modified : $Date: 2007-03-22 17:51:34 -0600 (Thu, 22 Mar 2007) $ - */ -package edu.umd.cs.piccolox.pswing; - -import edu.umd.cs.piccolo.PCanvas; - -import javax.swing.*; -import java.awt.*; - -/** - * The PSwingCanvas is a PCanvas that can display Swing components with the PSwing adapter. - * - * @author Benjamin B. Bederson - * @author Sam R. Reid - * @author Lance E. Good - */ - -public class PSwingCanvas extends PCanvas { - public static final String SWING_WRAPPER_KEY = "Swing Wrapper"; - private static PSwingRepaintManager pSwingRepaintManager = new PSwingRepaintManager(); - - private SwingWrapper swingWrapper; - private PSwingEventHandler swingEventHandler; - - /** - * Construct a new PSwingCanvas. - */ - public PSwingCanvas() { - swingWrapper = new SwingWrapper( this ); - add( swingWrapper ); - RepaintManager.setCurrentManager( pSwingRepaintManager ); - pSwingRepaintManager.addPSwingCanvas( this ); - - swingEventHandler = new PSwingEventHandler( this, getCamera() );//todo or maybe getCameraLayer() or getRoot()? - swingEventHandler.setActive( true ); - } - - JComponent getSwingWrapper() { - return swingWrapper; - } - - public void addPSwing( PSwing pSwing ) { - swingWrapper.add( pSwing.getComponent() ); - } - - public void removePSwing( PSwing pSwing ) { - swingWrapper.remove( pSwing.getComponent() ); - } - - private static class SwingWrapper extends JComponent { - private PSwingCanvas pSwingCanvas; - - public SwingWrapper( PSwingCanvas pSwingCanvas ) { - this.pSwingCanvas = pSwingCanvas; - setSize( new Dimension( 0, 0 ) ); - setPreferredSize( new Dimension( 0, 0 ) ); - putClientProperty( SWING_WRAPPER_KEY, SWING_WRAPPER_KEY ); - } - - public PSwingCanvas getpSwingCanvas() { - return pSwingCanvas; - } - } - -} \ No newline at end of file diff --git a/extras/edu/umd/cs/piccolox/pswing/PSwingEventHandler.java b/extras/edu/umd/cs/piccolox/pswing/PSwingEventHandler.java deleted file mode 100644 index ee777c9..0000000 --- a/extras/edu/umd/cs/piccolox/pswing/PSwingEventHandler.java +++ /dev/null @@ -1,460 +0,0 @@ -/** - * Copyright (C) 1998-2000 by University of Maryland, College Park, MD 20742, USA - * All rights reserved. - */ -package edu.umd.cs.piccolox.pswing; - -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.event.PInputEventListener; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.InputEvent; -import java.awt.event.MouseEvent; -import java.awt.geom.AffineTransform; -import java.awt.geom.NoninvertibleTransformException; -import java.awt.geom.Point2D; - -/** - * Event handler to send MousePressed, MouseReleased, MouseMoved, - * MouseClicked, and MouseDragged events on Swing components within - * a PCanvas. - * - * @author Ben Bederson - * @author Lance Good - * @author Sam Reid - */ -public class PSwingEventHandler implements PInputEventListener { - - private PNode listenNode = null; //used to listen to for events - private boolean active = false; //True when event handlers are set active. - - // The previous component - used to generate mouseEntered and - // mouseExited events - private Component prevComponent = null; - - // Previous points used in generating mouseEntered and mouseExited events - private Point2D prevPoint = null; - private Point2D prevOff = null; - - private boolean recursing = false;//to avoid accidental recursive handling - - private ButtonData leftButtonData = new ButtonData(); - private ButtonData rightButtonData = new ButtonData(); - private ButtonData middleButtonData = new ButtonData(); - - private PSwingCanvas canvas; - - /** - * Constructs a new PSwingEventHandler for the given canvas, - * and a node that will recieve the mouse events. - * - * @param canvas the canvas associated with this PSwingEventHandler. - * @param node the node the mouse listeners will be attached to. - */ - public PSwingEventHandler( PSwingCanvas canvas, PNode node ) { - this.canvas = canvas; - listenNode = node; - } - - /** - * Constructs a new PSwingEventHandler for the given canvas. - */ - public PSwingEventHandler( PSwingCanvas canvas ) { - this.canvas = canvas; - } - - /** - * Sets whether this event handler can fire events. - * - * @param active - */ - void setActive( boolean active ) { - if( this.active && !active ) { - if( listenNode != null ) { - this.active = false; - listenNode.removeInputEventListener( this ); - } - } - else if( !this.active && active ) { - if( listenNode != null ) { - this.active = true; - listenNode.addInputEventListener( this ); - } - } - } - - /** - * Determines if this event handler is active. - * - * @return True if active - */ - public boolean isActive() { - return active; - } - - /** - * Finds the component at the specified location (must be showing). - * - * @param c - * @param x - * @param y - * @return the component at the specified location. - */ - private Component findShowingComponentAt( Component c, int x, int y ) { - if( !c.contains( x, y ) ) { - return null; - } - - if( c instanceof Container ) { - Container contain = ( (Container)c ); - int ncomponents = contain.getComponentCount(); - Component component[] = contain.getComponents(); - - for( int i = 0; i < ncomponents; i++ ) { - Component comp = component[i]; - if( comp != null ) { - Point p = comp.getLocation(); - if( comp instanceof Container ) { - comp = findShowingComponentAt( comp, x - (int)p.getX(), y - (int)p.getY() ); - } - else { - comp = comp.getComponentAt( x - (int)p.getX(), y - (int)p.getY() ); - } - if( comp != null && comp.isShowing() ) { - return comp; - } - } - } - } - return c; - } - - /** - * Determines if any Swing components in Piccolo - * should receive the given MouseEvent and - * forwards the event to that component. - * However, mouseEntered and mouseExited are independent of the buttons. - * Also, notice the notes on mouseEntered and mouseExited. - * - * @param pSwingMouseEvent - * @param aEvent - */ - void dispatchEvent( PSwingMouseEvent pSwingMouseEvent, PInputEvent aEvent ) { - Component comp = null; - Point2D pt = null; - PNode pickedNode = pSwingMouseEvent.getPath().getPickedNode(); - - // The offsets to put the event in the correct context - int offX = 0; - int offY = 0; - - PNode currentNode = pSwingMouseEvent.getCurrentNode(); - - if( currentNode instanceof PSwing ) { - - PSwing swing = (PSwing)currentNode; - PNode grabNode = pickedNode; - - if( grabNode.isDescendentOf( canvas.getRoot() ) ) { - pt = new Point2D.Double( pSwingMouseEvent.getX(), pSwingMouseEvent.getY() ); - cameraToLocal( pSwingMouseEvent.getPath().getTopCamera(), pt, grabNode ); - prevPoint = new Point2D.Double( pt.getX(), pt.getY() ); - - // This is only partially fixed to find the deepest - // component at pt. It needs to do something like - // package private method: - // Container.getMouseEventTarget(int,int,boolean) - comp = findShowingComponentAt( swing.getComponent(), (int)pt.getX(), (int)pt.getY() ); - - // We found the right component - but we need to - // get the offset to put the event in the component's - // coordinates - if( comp != null && comp != swing.getComponent() ) { - for( Component c = comp; c != swing.getComponent(); c = c.getParent() ) { - offX += c.getLocation().getX(); - offY += c.getLocation().getY(); - } - } - - // Mouse Pressed gives focus - effects Mouse Drags and - // Mouse Releases - if( comp != null && pSwingMouseEvent.getID() == MouseEvent.MOUSE_PRESSED ) { - if( SwingUtilities.isLeftMouseButton( pSwingMouseEvent ) ) { - leftButtonData.setState( swing, pickedNode, comp, offX, offY ); - } - else if( SwingUtilities.isMiddleMouseButton( pSwingMouseEvent ) ) { - middleButtonData.setState( swing, pickedNode, comp, offX, offY ); - } - else if( SwingUtilities.isRightMouseButton( pSwingMouseEvent ) ) { - rightButtonData.setState( swing, pickedNode, comp, offX, offY ); - } - } - } - } - - // This first case we don't want to give events to just - // any Swing component - but to the one that got the - // original mousePressed - if( pSwingMouseEvent.getID() == MouseEvent.MOUSE_DRAGGED || - pSwingMouseEvent.getID() == MouseEvent.MOUSE_RELEASED ) { - - // LEFT MOUSE BUTTON - if( SwingUtilities.isLeftMouseButton( pSwingMouseEvent ) && leftButtonData.getFocusedComponent() != null ) { - handleButton( pSwingMouseEvent, aEvent, leftButtonData ); - } - - // MIDDLE MOUSE BUTTON - if( SwingUtilities.isMiddleMouseButton( pSwingMouseEvent ) && middleButtonData.getFocusedComponent() != null ) - { - handleButton( pSwingMouseEvent, aEvent, middleButtonData ); - } - - // RIGHT MOUSE BUTTON - if( SwingUtilities.isRightMouseButton( pSwingMouseEvent ) && rightButtonData.getFocusedComponent() != null ) - { - handleButton( pSwingMouseEvent, aEvent, rightButtonData ); - } - } - // This case covers the cases mousePressed, mouseClicked, - // and mouseMoved events - else if( ( pSwingMouseEvent.getID() == MouseEvent.MOUSE_PRESSED || - pSwingMouseEvent.getID() == MouseEvent.MOUSE_CLICKED || - pSwingMouseEvent.getID() == MouseEvent.MOUSE_MOVED ) && - ( comp != null ) ) { - - MouseEvent e_temp = new MouseEvent( comp, - pSwingMouseEvent.getID(), - pSwingMouseEvent.getWhen(), - pSwingMouseEvent.getModifiers(), - (int)pt.getX() - offX, - (int)pt.getY() - offY, - pSwingMouseEvent.getClickCount(), - pSwingMouseEvent.isPopupTrigger() ); - - PSwingMouseEvent e2 = PSwingMouseEvent.createMouseEvent( e_temp.getID(), e_temp, aEvent ); - dispatchEvent( comp, e2 ); - pSwingMouseEvent.consume(); - } - - // Now we need to check if an exit or enter event needs to - // be dispatched - this code is independent of the mouseButtons. - // I tested in normal Swing to see the correct behavior. - if( prevComponent != null ) { - // This means mouseExited - - // This shouldn't happen - since we're only getting node events - if( comp == null || pSwingMouseEvent.getID() == MouseEvent.MOUSE_EXITED ) { - MouseEvent e_temp = createExitEvent( pSwingMouseEvent ); - - PSwingMouseEvent e2 = PSwingMouseEvent.createMouseEvent( e_temp.getID(), e_temp, aEvent ); - - dispatchEvent( prevComponent, e2 ); - prevComponent = null; - - if( pSwingMouseEvent.getID() == MouseEvent.MOUSE_EXITED ) { - pSwingMouseEvent.consume(); - } - } - - // This means mouseExited prevComponent and mouseEntered comp - else if( prevComponent != comp ) { - MouseEvent e_temp = createExitEvent( pSwingMouseEvent ); - PSwingMouseEvent e2 = PSwingMouseEvent.createMouseEvent( e_temp.getID(), e_temp, aEvent ); - dispatchEvent( prevComponent, e2 ); - - e_temp = createEnterEvent( comp, pSwingMouseEvent, offX, offY ); - e2 = PSwingMouseEvent.createMouseEvent( e_temp.getID(), e_temp, aEvent ); - comp.dispatchEvent( e2 ); - } - } - else { - // This means mouseEntered - if( comp != null ) { - MouseEvent e_temp = createEnterEvent( comp, pSwingMouseEvent, offX, offY ); - PSwingMouseEvent e2 = PSwingMouseEvent.createMouseEvent( e_temp.getID(), e_temp, aEvent ); - dispatchEvent( comp, e2 ); - } - } - - //todo add cursors -// // We have to manager our own Cursors since this is normally -// // done on the native side -// if( comp != cursorComponent && -// focusNodeLeft == null && -// focusNodeMiddle == null && -// focusNodeRight == null ) { -// if( comp != null ) { -// cursorComponent = comp; -// canvas.setCursor( comp.getCursor(), false ); -// } -// else { -// cursorComponent = null; -// canvas.resetCursor(); -// } -// } - - // Set the previous variables for next time - prevComponent = comp; - - if( comp != null ) { - prevOff = new Point2D.Double( offX, offY ); - } - } - - private MouseEvent createEnterEvent( Component comp, PSwingMouseEvent e1, int offX, int offY ) { - return new MouseEvent( comp, MouseEvent.MOUSE_ENTERED, - e1.getWhen(), 0, - (int)prevPoint.getX() - offX, (int)prevPoint.getY() - offY, - e1.getClickCount(), e1.isPopupTrigger() ); - } - - private MouseEvent createExitEvent( PSwingMouseEvent e1 ) { - return new MouseEvent( prevComponent, MouseEvent.MOUSE_EXITED, - e1.getWhen(), 0, - (int)prevPoint.getX() - (int)prevOff.getX(), (int)prevPoint.getY() - (int)prevOff.getY(), - e1.getClickCount(), e1.isPopupTrigger() ); - } - - private void handleButton( PSwingMouseEvent e1, PInputEvent aEvent, ButtonData buttonData ) { - Point2D pt; - if( buttonData.getPNode().isDescendentOf( canvas.getRoot() ) ) { - pt = new Point2D.Double( e1.getX(), e1.getY() ); - cameraToLocal( e1.getPath().getTopCamera(), pt, buttonData.getPNode() ); - //todo this probably won't handle viewing through multiple cameras. - MouseEvent e_temp = new MouseEvent( buttonData.getFocusedComponent(), - e1.getID(), e1.getWhen(), e1.getModifiers(), - (int)pt.getX() - buttonData.getOffsetX(), - (int)pt.getY() - buttonData.getOffsetY(), - e1.getClickCount(), e1.isPopupTrigger() ); - - PSwingMouseEvent e2 = PSwingMouseEvent.createMouseEvent( e_temp.getID(), e_temp, aEvent ); - dispatchEvent( buttonData.getFocusedComponent(), e2 ); - } - else { - dispatchEvent( buttonData.getFocusedComponent(), e1 ); - } - //buttonData.getPSwing().repaint(); //Experiment with SliderExample (from Martin) suggests this line is unnecessary, and a serious problem in performance. - e1.consume(); - if( e1.getID() == MouseEvent.MOUSE_RELEASED ) { - buttonData.mouseReleased(); - } - } - - private void dispatchEvent( final Component target, final PSwingMouseEvent event ) { - SwingUtilities.invokeLater( new Runnable() { - public void run() { - target.dispatchEvent( event ); - } - } ); - } - - private void cameraToLocal( PCamera topCamera, Point2D pt, PNode node ) { - AffineTransform inverse = null; - try { - inverse = topCamera.getViewTransform().createInverse(); - } - catch( NoninvertibleTransformException e ) { - e.printStackTrace(); - } - - /* Only apply the camera's view transform when this node is a descendant of PLayer */ - PNode searchNode = node; - do { - searchNode = searchNode.getParent(); - if (searchNode instanceof PLayer) { - inverse.transform( pt, pt ); - break; - } - } while(searchNode != null); - - if( node != null ) { - node.globalToLocal( pt ); - } - return; - } - - /** - * Process a piccolo event and (if active) dispatch the corresponding Swing event. - * - * @param aEvent - * @param type - */ - public void processEvent( PInputEvent aEvent, int type ) { - if(aEvent.isMouseEvent()) { - InputEvent sourceSwingEvent = aEvent.getSourceSwingEvent(); - if (sourceSwingEvent instanceof MouseEvent) { - MouseEvent swingMouseEvent = (MouseEvent) sourceSwingEvent; - PSwingMouseEvent pSwingMouseEvent = PSwingMouseEvent.createMouseEvent( swingMouseEvent.getID(), swingMouseEvent, aEvent ); - if( !recursing ) { - recursing = true; - dispatchEvent( pSwingMouseEvent, aEvent ); - recursing = false; - } - } else { - new Exception("PInputEvent.getSourceSwingEvent was not a MouseEvent. Actual event: " + sourceSwingEvent + ", class=" + sourceSwingEvent.getClass().getName() ).printStackTrace(); - } - } - -/* if( !( EventQueue.getCurrentEvent() instanceof MouseEvent ) ) { - new Exception( "EventQueue.getCurrentEvent was not a MouseEvent, consider making PInputEvent.getSourceSwingEvent public. Actual event: " + EventQueue.getCurrentEvent() + ", class=" + EventQueue.getCurrentEvent().getClass().getName() ).printStackTrace(); - } - if( aEvent.isMouseEvent() && EventQueue.getCurrentEvent() instanceof MouseEvent ) { - MouseEvent sourceSwingEvent = (MouseEvent)EventQueue.getCurrentEvent(); - PSwingMouseEvent pSwingMouseEvent = PSwingMouseEvent.createMouseEvent( sourceSwingEvent.getID(), sourceSwingEvent, aEvent ); - if( !recursing ) { - recursing = true; - dispatchEvent( pSwingMouseEvent, aEvent ); - recursing = false; - } - } -*/ - } - - /** - * Internal Utility class for handling button interactivity. - */ - private static class ButtonData { - private PSwing focusPSwing = null; - private PNode focusNode = null; - private Component focusComponent = null; - private int focusOffX = 0; - private int focusOffY = 0; - - public void setState( PSwing swing, PNode visualNode, Component comp, int offX, int offY ) { - focusPSwing = swing; - focusComponent = comp; - focusNode = visualNode; - focusOffX = offX; - focusOffY = offY; - } - - public Component getFocusedComponent() { - return focusComponent; - } - - public PNode getPNode() { - return focusNode; - } - - public int getOffsetX() { - return focusOffX; - } - - public int getOffsetY() { - return focusOffY; - } - - public PSwing getPSwing() { - return focusPSwing; - } - - public void mouseReleased() { - focusComponent = null; - focusNode = null; - } - } -} diff --git a/extras/edu/umd/cs/piccolox/pswing/PSwingMouseEvent.java b/extras/edu/umd/cs/piccolox/pswing/PSwingMouseEvent.java deleted file mode 100644 index e9a49fc..0000000 --- a/extras/edu/umd/cs/piccolox/pswing/PSwingMouseEvent.java +++ /dev/null @@ -1,243 +0,0 @@ -/** - * Copyright (C) 1998-2000 by University of Maryland, College Park, MD 20742, USA - * All rights reserved. - */ -package edu.umd.cs.piccolox.pswing; - -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.event.PInputEvent; -import edu.umd.cs.piccolo.util.PPickPath; - -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.geom.Point2D; -import java.io.Serializable; - -/** - * PMouseEvent is an event which indicates that a mouse action occurred in a node. - *

- * This low-level event is generated by a node object for: - *