/* * 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); } }; } }