You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/03/26 00:12:17 UTC
svn commit: r758461 [29/47] - in /incubator/pivot/branches: ./ 1.1/
1.1/charts-test/ 1.1/charts-test/src/ 1.1/charts-test/src/pivot/
1.1/charts-test/src/pivot/charts/ 1.1/charts-test/src/pivot/charts/test/
1.1/charts/ 1.1/charts/lib/ 1.1/charts/src/ 1....
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/BlurDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/BlurDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/BlurDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/BlurDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+
+import pivot.wtk.Component;
+import pivot.wtk.Bounds;
+
+/**
+ * Decorator that applies a blur to a component.
+ * <p>
+ * Blurs are given an integer magnitude, which represents the intensity of
+ * the blur. This value translates to a grid of pixels (<tt>blurMagnitude^2</tt>),
+ * where each pixel value is calculated by consulting its neighboring pixels
+ * according to the grid. Because of this, note that you will get "prettier"
+ * blurring if you choose odd values for the blur magnitude; this allows the
+ * pixel in question to reside at the center of the grid, thus preventing any
+ * arbitrary shifting of pixels. Also note that the greater the intensity of
+ * the blur, the greater the intensity of the calculations necessary to
+ * accomplish the blur (and the longer it will take to perform the blur).
+ * <p>
+ * TODO Increase size of buffered image to account for edge conditions of the
+ * blur.
+ * <p>
+ * TODO Use unequal values in the blur kernel to make pixels that are farther
+ * away count less towards the blur.
+ *
+ * @author tvolkert
+ */
+public class BlurDecorator implements Decorator {
+ private int blurMagnitude;
+
+ private Graphics2D graphics = null;
+
+ private BufferedImage bufferedImage = null;
+ private Graphics2D bufferedImageGraphics = null;
+
+ /**
+ * Creates a <tt>BlurDecorator</tt> with the default blur magnitude.
+ *
+ * @see #BlurDecorator(int)
+ */
+ public BlurDecorator() {
+ this(9);
+ }
+
+ /**
+ * Creates a <tt>BlurDecorator</tt> with the specified blur magnitude.
+ *
+ * @param blurMagnitude
+ * The intensity of the blur.
+ */
+ public BlurDecorator(int blurMagnitude) {
+ this.blurMagnitude = blurMagnitude;
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ this.graphics = graphics;
+
+ int width = component.getWidth();
+ int height = component.getHeight();
+
+ if (bufferedImage == null
+ || bufferedImage.getWidth() != width
+ || bufferedImage.getHeight() != height) {
+ bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ }
+
+ bufferedImageGraphics = bufferedImage.createGraphics();
+ bufferedImageGraphics.setClip(graphics.getClip());
+
+ return bufferedImageGraphics;
+ }
+
+ public void update() {
+ bufferedImageGraphics.dispose();
+ bufferedImage.flush();
+
+ float[] kernel = new float[blurMagnitude * blurMagnitude];
+ for (int i = 0, n = kernel.length; i < n; i++) {
+ kernel[i] = 1f / n;
+ }
+
+ ConvolveOp blur = new ConvolveOp(new Kernel(blurMagnitude, blurMagnitude,
+ kernel), ConvolveOp.EDGE_NO_OP, null);
+ bufferedImage = blur.filter(bufferedImage, null);
+
+ this.graphics.drawImage(bufferedImage, 0, 0, null);
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(0, 0, component.getWidth(), component.getHeight());
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ClipDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ClipDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ClipDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ClipDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+
+import pivot.wtk.Bounds;
+import pivot.wtk.Component;
+
+/**
+ * Decorator that adds a rectangular region to the current clip.
+ *
+ * @author gbrown
+ */
+public class ClipDecorator implements Decorator {
+ private int x = 0;
+ private int y = 0;
+ private int width = 0;
+ private int height = 0;
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ graphics.clipRect(x, y, width, height);
+ return graphics;
+ }
+
+ public void update() {
+ // No-op
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(x, y, width, height);
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Decorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Decorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Decorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Decorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+
+import pivot.wtk.Bounds;
+import pivot.wtk.Component;
+
+/**
+ * Interface defining a component "decorator". Decorators allow a caller to
+ * attach additional visual effects to a component.
+ *
+ * @author gbrown
+ */
+public interface Decorator {
+ /**
+ * Prepares the graphics context into which the component or prior
+ * decorator will paint. This method is called immediately prior to
+ * {@link Component#paint(Graphics2D)}; decorators are called in
+ * descending order.
+ *
+ * @param component
+ * @param graphics
+ *
+ * @return
+ * The graphics context that should be used by the component or prior
+ * decorators.
+ */
+ public Graphics2D prepare(Component component, Graphics2D graphics);
+
+ /**
+ * Updates the graphics context into which the component or prior
+ * decorator was painted. This method is called immediately after
+ * {@link Component#paint(Graphics2D)}; decorators are called in
+ * ascending order.
+ */
+ public void update();
+
+ /**
+ * Returns the bounding area of the decorator.
+ *
+ * @param component
+ *
+ * @return
+ * The decorator's bounds, relative to the component's origin.
+ */
+ public Bounds getBounds(Component component);
+
+ /**
+ * Returns the transformation the decorator applies to the component's
+ * coordinate space.
+ *
+ * @return
+ * The decorator's transform.
+ */
+ public AffineTransform getTransform(Component component);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/DropShadowDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/DropShadowDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/DropShadowDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/DropShadowDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Contains code and concepts from ShadowRenderer.java v1.6,
+ * copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
+ * Santa Clara, California 95054, U.S.A. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import pivot.wtk.Component;
+import pivot.wtk.Bounds;
+
+/**
+ * Decorator that adds a drop shadows to a component.
+ *
+ * @author gbrown
+ * @author tvolkert
+ * @author eryzhikov
+ * @author Romain Guy
+ * @author Sebastien Petrucci
+ */
+public class DropShadowDecorator implements Decorator {
+ private int blurRadius;
+ private int xOffset;
+ private int yOffset;
+
+ private Color shadowColor = Color.BLACK;
+ private float shadowOpacity = 0.33f;
+
+ private Graphics2D graphics = null;
+ private BufferedImage componentImage = null;
+ private Graphics2D componentImageGraphics = null;
+
+ public DropShadowDecorator() {
+ this(5, 5, 5);
+ }
+
+ public DropShadowDecorator(int blurRadius, int xOffset, int yOffset) {
+ this.blurRadius = blurRadius;
+ this.xOffset = xOffset;
+ this.yOffset = yOffset;
+ }
+
+ /**
+ * Returns the color used to draw the shadow.
+ *
+ * @return
+ * The color used to draw the shadow.
+ */
+ public Color getShadowColor() {
+ return shadowColor;
+ }
+
+ /**
+ * Sets the color used to draw the shadow.
+ *
+ * @param shadowColor
+ * The color used to draw the shadow.
+ */
+ public void setShadowColor(Color shadowColor) {
+ this.shadowColor = shadowColor;
+ }
+
+ /**
+ * Sets the color used to draw the shadow.
+ *
+ * @param shadowColor
+ * The color used to draw the shadow.
+ */
+ public final void setShadowColor(String shadowColor) {
+ if (shadowColor == null) {
+ throw new IllegalArgumentException("shadowColor is null.");
+ }
+
+ setShadowColor(Color.decode(shadowColor));
+ }
+
+ /**
+ * Returns the opacity used to draw the shadow.
+ *
+ * @return
+ * The color used to draw the shadow.
+ */
+ public float getShadowOpacity() {
+ return shadowOpacity;
+ }
+
+ /**
+ * Sets the opacity used to draw the shadow.
+ *
+ * @param shadowOpacity
+ * The opacity used to draw the shadow.
+ */
+ public void setShadowOpacity(float shadowOpacity) {
+ this.shadowOpacity = shadowOpacity;
+ }
+
+ /**
+ * Returns the blur radius used to draw the shadow.
+ *
+ * @return
+ * The blur radius used to draw the shadow.
+ */
+ public int getBlurRadius() {
+ return blurRadius;
+ }
+
+ /**
+ * Sets the blur radius used to draw the shadow.
+ *
+ * @param blurRadius
+ * The blur radius used to draw the shadow.
+ */
+ public void setBlurRadius(int blurRadius) {
+ this.blurRadius = blurRadius;
+ }
+
+ /**
+ * Returns the amount that the drop shadow will be offset along the x axis.
+ *
+ * @return
+ * The x offset used to draw the shadow
+ */
+ public int getXOffset() {
+ return xOffset;
+ }
+
+ /**
+ * Sets the amount that the drop shadow will be offset along the x axis.
+ *
+ * @param xOffset
+ * The x offset used to draw the shadow
+ */
+ public void setXOffset(int xOffset) {
+ this.xOffset = xOffset;
+ }
+
+ /**
+ * Returns the amount that the drop shadow will be offset along the y axis.
+ *
+ * @return
+ * The y offset used to draw the shadow
+ */
+ public int getYOffset() {
+ return yOffset;
+ }
+
+ /**
+ * Sets the amount that the drop shadow will be offset along the y axis.
+ *
+ * @param yOffset
+ * The y offset used to draw the shadow
+ */
+ public void setYOffset(int yOffset) {
+ this.yOffset = yOffset;
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ this.graphics = graphics;
+
+ int width = component.getWidth();
+ int height = component.getHeight();
+
+ if (width > 0
+ && height > 0) {
+ if (componentImage == null
+ || componentImage.getWidth() != width
+ || componentImage.getHeight() != height) {
+ componentImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ }
+
+ componentImageGraphics = componentImage.createGraphics();
+ componentImageGraphics.setClip(graphics.getClip());
+
+ componentImageGraphics.setComposite(AlphaComposite.Clear);
+ componentImageGraphics.fillRect(0, 0, componentImage.getWidth(), componentImage.getHeight());
+
+ componentImageGraphics.setComposite(AlphaComposite.SrcOver);
+
+ graphics = componentImageGraphics;
+ }
+
+ return graphics;
+ }
+
+ public void update() {
+ if (componentImage != null) {
+ componentImageGraphics.dispose();
+
+ BufferedImage shadowImage = createShadow(componentImage);
+
+ graphics.drawImage(shadowImage, xOffset - blurRadius, yOffset - blurRadius, null);
+ graphics.drawImage(componentImage, 0, 0, null);
+ }
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(xOffset - blurRadius, yOffset - blurRadius,
+ component.getWidth() + blurRadius * 2,
+ component.getHeight() + blurRadius * 2);
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+
+ /**
+ * Generates the shadow for a given picture and the current properties of
+ * the decorator. The generated image dimensions are computed as follows:
+ *
+ * <pre>
+ * width = imageWidth + 2 * blurRadius
+ * height = imageHeight + 2 * blurRadius
+ * </pre>
+ *
+ * @param image
+ * The image from which the shadow will be cast.
+ *
+ * @return
+ * An image containing the generated shadow.
+ */
+ private BufferedImage createShadow(BufferedImage src) {
+ int shadowSize = blurRadius * 2;
+
+ int srcWidth = src.getWidth();
+ int srcHeight = src.getHeight();
+
+ int dstWidth = srcWidth + shadowSize;
+ int dstHeight = srcHeight + shadowSize;
+
+ int left = blurRadius;
+ int right = shadowSize - left;
+
+ int yStop = dstHeight - right;
+
+ int shadowRgb = shadowColor.getRGB() & 0x00FFFFFF;
+ int[] aHistory = new int[shadowSize];
+ int historyIdx;
+
+ int aSum;
+
+ BufferedImage dst = new BufferedImage(dstWidth, dstHeight,
+ BufferedImage.TYPE_INT_ARGB);
+
+ int[] dstBuffer = new int[dstWidth * dstHeight];
+ int[] srcBuffer = new int[srcWidth * srcHeight];
+
+ Raster srcRaster = src.getRaster();
+ srcRaster.getDataElements(0, 0, srcWidth, srcHeight, srcBuffer);
+
+ int lastPixelOffset = right * dstWidth;
+ float hSumDivider = 1.0f / shadowSize;
+ float vSumDivider = shadowOpacity / shadowSize;
+
+ int[] hSumLookup = new int[256 * shadowSize];
+ for (int i = 0; i < hSumLookup.length; i++) {
+ hSumLookup[i] = (int) (i * hSumDivider);
+ }
+
+ int[] vSumLookup = new int[256 * shadowSize];
+ for (int i = 0; i < vSumLookup.length; i++) {
+ vSumLookup[i] = (int) (i * vSumDivider);
+ }
+
+ int srcOffset;
+
+ // Horizontal pass: extract the alpha mask from the source picture and
+ // blur it into the destination picture
+ for (int srcY = 0, dstOffset = left * dstWidth; srcY < srcHeight; srcY++) {
+ // First pixels are empty
+ for (historyIdx = 0; historyIdx < shadowSize;) {
+ aHistory[historyIdx++] = 0;
+ }
+
+ aSum = 0;
+ historyIdx = 0;
+ srcOffset = srcY * srcWidth;
+
+ // Compute the blur average with pixels from the source image
+ for (int srcX = 0; srcX < srcWidth; srcX++) {
+ int a = hSumLookup[aSum];
+ // Store the alpha value only; the shadow color will be added
+ // in the next pass
+ dstBuffer[dstOffset++] = a << 24;
+
+ // Substract the oldest pixel from the sum
+ aSum -= aHistory[historyIdx];
+
+ // Extract the new pixel and store its value into history...
+ a = srcBuffer[srcOffset + srcX] >>> 24;
+ aHistory[historyIdx] = a;
+
+ // ...and add its value to the sum
+ aSum += a;
+
+ if (++historyIdx >= shadowSize) {
+ historyIdx -= shadowSize;
+ }
+ }
+
+ // Blur the end of the row - no new pixels to grab
+ for (int i = 0; i < shadowSize; i++) {
+ int a = hSumLookup[aSum];
+ dstBuffer[dstOffset++] = a << 24;
+
+ // Substract the oldest pixel from the sum...and nothing new
+ // to add!
+ aSum -= aHistory[historyIdx];
+
+ if (++historyIdx >= shadowSize) {
+ historyIdx -= shadowSize;
+ }
+ }
+ }
+
+ // Vertical pass
+ for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
+ aSum = 0;
+
+ // First pixels are empty...
+ for (historyIdx = 0; historyIdx < left;) {
+ aHistory[historyIdx++] = 0;
+ }
+
+ // ...and then they come from the dstBuffer
+ for (int y = 0; y < right; y++, bufferOffset += dstWidth) {
+ // Extract alpha and store into history...
+ int a = dstBuffer[bufferOffset] >>> 24;
+ aHistory[historyIdx++] = a;
+
+ // ...and add to sum
+ aSum += a;
+ }
+
+ bufferOffset = x;
+ historyIdx = 0;
+
+ // Compute the blur avera`ge with pixels from the previous pass
+ for (int y = 0; y < yStop; y++, bufferOffset += dstWidth) {
+ // Store alpha value + shadow color
+ int a = vSumLookup[aSum];
+ dstBuffer[bufferOffset] = a << 24 | shadowRgb;
+
+ // Substract the oldest pixel from the sum
+ aSum -= aHistory[historyIdx];
+
+ // Extract the new pixel and store its value into history...
+ a = dstBuffer[bufferOffset + lastPixelOffset] >>> 24;
+ aHistory[historyIdx] = a;
+
+ // ... and add its value to the sum
+ aSum += a;
+
+ if (++historyIdx >= shadowSize) {
+ historyIdx -= shadowSize;
+ }
+ }
+
+ // Blur the end of the column - no pixels to grab anymore
+ for (int y = yStop; y < dstHeight; y++, bufferOffset += dstWidth) {
+ int a = vSumLookup[aSum];
+ dstBuffer[bufferOffset] = a << 24 | shadowRgb;
+
+ // Substract the oldest pixel from the sum
+ aSum -= aHistory[historyIdx];
+
+ if (++historyIdx >= shadowSize) {
+ historyIdx -= shadowSize;
+ }
+ }
+ }
+
+ WritableRaster dstRaster = dst.getRaster();
+ dstRaster.setDataElements(0, 0, dstWidth, dstHeight, dstBuffer);
+
+ return dst;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/FadeDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/FadeDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/FadeDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/FadeDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,55 @@
+package pivot.wtk.effects;
+
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+
+import pivot.wtk.Component;
+import pivot.wtk.Bounds;
+
+/**
+ * Decorator that applies an opacity to a component.
+ *
+ * @author gbrown
+ */
+public class FadeDecorator implements Decorator {
+ private float opacity;
+
+ public FadeDecorator() {
+ this(0.5f);
+ }
+
+ public FadeDecorator(float opacity) {
+ this.opacity = opacity;
+ }
+
+ public float getOpacity() {
+ return opacity;
+ }
+
+ public void setOpacity(float opacity) {
+ if (opacity < 0f
+ || opacity > 1f) {
+ throw new IllegalArgumentException("opacity must be a value between 0 and 1, inclusive.");
+ }
+
+ this.opacity = opacity;
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
+ return graphics;
+ }
+
+ public void update() {
+ // No-op
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(0, 0, component.getWidth(), component.getHeight());
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/GrayscaleDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/GrayscaleDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/GrayscaleDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/GrayscaleDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
+import pivot.wtk.Component;
+import pivot.wtk.Bounds;
+
+/**
+ * Decorator that applies a grayscale conversion to a component.
+ *
+ * @author tvolkert
+ * @author gbrown
+ */
+public class GrayscaleDecorator implements Decorator {
+ private Graphics2D graphics = null;
+
+ private BufferedImage bufferedImage = null;
+ private Graphics2D bufferedImageGraphics = null;
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ this.graphics = graphics;
+
+ int width = component.getWidth();
+ int height = component.getHeight();
+
+ if (bufferedImage == null
+ || bufferedImage.getWidth() < width
+ || bufferedImage.getHeight() < height) {
+ bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
+ }
+
+ bufferedImageGraphics = bufferedImage.createGraphics();
+ bufferedImageGraphics.setClip(graphics.getClip());
+
+ return bufferedImageGraphics;
+ }
+
+ public void update() {
+ bufferedImageGraphics.dispose();
+ bufferedImage.flush();
+
+ graphics.drawImage(bufferedImage, 0, 0, null);
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(0, 0, component.getWidth(), component.getHeight());
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ReflectionDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ReflectionDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ReflectionDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ReflectionDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,81 @@
+package pivot.wtk.effects;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
+import pivot.wtk.Component;
+import pivot.wtk.Bounds;
+
+/**
+ * Decorator that paints a reflection of a component.
+ * <p>
+ * TODO Make gradient properties configurable.
+ * <p>
+ * TODO Add a shear value.
+ *
+ * @author gbrown
+ */
+public class ReflectionDecorator implements Decorator {
+ private Graphics2D graphics = null;
+ private Component component = null;
+
+ private BufferedImage componentImage = null;
+ private Graphics2D componentImageGraphics = null;
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ this.graphics = graphics;
+ this.component = component;
+
+ int width = component.getWidth();
+ int height = component.getHeight();
+
+ componentImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ componentImageGraphics = componentImage.createGraphics();
+
+ // Clear the image background
+ componentImageGraphics.setComposite(AlphaComposite.Clear);
+ componentImageGraphics.fillRect(0, 0, componentImage.getWidth(), componentImage.getHeight());
+
+ componentImageGraphics.setComposite(AlphaComposite.SrcOver);
+
+ return componentImageGraphics;
+ }
+
+ public void update() {
+ // Draw the component
+ graphics.drawImage(componentImage, 0, 0, null);
+
+ // Draw the reflection
+ int width = componentImage.getWidth();
+ int height = componentImage.getHeight();
+
+ GradientPaint mask = new GradientPaint(0, height / 4, new Color(1.0f, 1.0f, 1.0f, 0.0f),
+ 0, height, new Color(1.0f, 1.0f, 1.0f, 0.5f));
+ componentImageGraphics.setPaint(mask);
+
+ componentImageGraphics.setComposite(AlphaComposite.DstIn);
+ componentImageGraphics.fillRect(0, 0, width, height);
+
+ componentImageGraphics.dispose();
+ componentImage.flush();
+
+ graphics.transform(getTransform(component));
+
+ graphics.drawImage(componentImage, 0, 0, null);
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(0, 0, component.getWidth(), component.getHeight() * 2);
+ }
+
+ public AffineTransform getTransform(Component component) {
+ AffineTransform transform = AffineTransform.getScaleInstance(1.0, -1.0);
+ transform.translate(0, -(component.getHeight() * 2));
+
+ return transform;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/SaturationDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/SaturationDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/SaturationDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/SaturationDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Contains code and concepts from ShadowRenderer.java v1.6,
+ * copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
+ * Santa Clara, California 95054, U.S.A. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import pivot.wtk.Component;
+import pivot.wtk.Bounds;
+
+/**
+ * Decorator that modifies the color saturation of a component.
+ *
+ * @author tvolkert
+ */
+public class SaturationDecorator implements Decorator {
+ private float multiplier;
+
+ private Graphics2D graphics = null;
+
+ private BufferedImage componentImage = null;
+ private Graphics2D componentGraphics = null;
+
+ public SaturationDecorator() {
+ this(1.0f);
+ }
+
+ public SaturationDecorator(float multiplier) {
+ this.multiplier = multiplier;
+ }
+
+ public float getMultiplier() {
+ return multiplier;
+ }
+
+ public void setMultiplier(float multiplier) {
+ this.multiplier = multiplier;
+ }
+
+ public void setMultiplier(Number multiplier) {
+ if (multiplier == null) {
+ throw new IllegalArgumentException("Multiplier is null.");
+ }
+
+ setMultiplier(multiplier.floatValue());
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ int x = 0;
+ int y = 0;
+ int width = component.getWidth();
+ int height = component.getHeight();
+
+ java.awt.Rectangle clipBounds = graphics.getClipBounds();
+ if (clipBounds != null) {
+ x = clipBounds.x;
+ y = clipBounds.y;
+ width = clipBounds.width;
+ height = clipBounds.height;
+ }
+
+ componentImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+
+ this.graphics = graphics;
+
+ componentGraphics = componentImage.createGraphics();
+ componentGraphics.translate(-x, -y);
+ componentGraphics.setClip(graphics.getClip());
+
+ return componentGraphics;
+ }
+
+ /**
+ * Adjusts the saturation of the component image and draws the resulting
+ * image using the component's graphics.
+ */
+ public void update() {
+ int width = componentImage.getWidth();
+ int height = componentImage.getHeight();
+
+ int[] buffer = new int[width * height];
+
+ WritableRaster raster = componentImage.getRaster();
+ raster.getDataElements(0, 0, width, height, buffer);
+
+ float[] hsb = new float[3];
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ int srcRGB = buffer[i * width + j];
+
+ // Adjust color saturation
+ Color.RGBtoHSB((srcRGB >> 16) & 0xff,
+ (srcRGB >> 8) & 0xff, srcRGB & 0xff, hsb);
+ int dstRGB = Color.HSBtoRGB(hsb[0],
+ Math.min(Math.max(hsb[1] * multiplier, 0f), 1f), hsb[2]);
+
+ // Preserve the source alpha channel
+ dstRGB = (srcRGB & 0xff000000) | (dstRGB & 0xffffff);
+
+ buffer[i * width + j] = dstRGB;
+ }
+ }
+
+ raster.setDataElements(0, 0, width, height, buffer);
+
+ int x = 0;
+ int y = 0;
+
+ java.awt.Rectangle clipBounds = componentGraphics.getClipBounds();
+ if (clipBounds != null) {
+ x = clipBounds.x;
+ y = clipBounds.y;
+ }
+
+ componentGraphics.dispose();
+ graphics.drawImage(componentImage, x, y, null);
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(0, 0, component.getWidth(), component.getHeight());
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ScaleDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ScaleDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ScaleDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ScaleDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+
+import pivot.wtk.Bounds;
+import pivot.wtk.Component;
+import pivot.wtk.Container;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.Platform;
+import pivot.wtk.VerticalAlignment;
+
+/**
+ * Decorator that scales the painting of a component along the X and/or Y axes.
+ *
+ * @author tvolkert
+ */
+public class ScaleDecorator implements Decorator {
+ private float scaleX;
+ private float scaleY;
+ private HorizontalAlignment horizontalAlignment = HorizontalAlignment.CENTER;
+ private VerticalAlignment verticalAlignment = VerticalAlignment.CENTER;
+
+ /**
+ * Creates a new <tt>ScaleDecorator</tt> with the default <tt>scaleX</tt>
+ * <tt>scaleY</tt> values of <tt>1</tt>.
+ */
+ public ScaleDecorator() {
+ this(1f, 1f);
+ }
+
+ /**
+ * Creates a new <tt>ScaleDecorator</tt> with the specified <tt>scaleX</tt>
+ * and <tt>scaleY</tt> values.
+ *
+ * @param scaleX
+ * The amount to scale the component's x-axis
+ *
+ * @param scaleY
+ * The amount to scale the component's y-axis
+ */
+ public ScaleDecorator(float scaleX, float scaleY) {
+ if (scaleX <= 0
+ || scaleY <= 0) {
+ throw new IllegalArgumentException("Scale values must be positive.");
+ }
+
+ this.scaleX = scaleX;
+ this.scaleY = scaleY;
+ }
+
+ /**
+ * Gets the amount by which drawing operations will be scaled along the
+ * x-axis.
+ *
+ * @return
+ * The amount to scale the component's x-axis
+ */
+ public float getScaleX() {
+ return scaleX;
+ }
+
+ /**
+ * Sets the amount by which drawing operations will be scaled along the
+ * x-axis.
+ *
+ * @param scaleX
+ * The amount to scale the component's x-axis
+ */
+ public void setScaleX(float scaleX) {
+ if (scaleX <= 0) {
+ throw new IllegalArgumentException("scaleX must be positive.");
+ }
+
+ this.scaleX = scaleX;
+ }
+
+ /**
+ * Sets the amount by which drawing operations will be scaled along the
+ * x-axis.
+ *
+ * @param scaleX
+ * The amount to scale the component's x-axis
+ */
+ public void setScaleX(Number scaleX) {
+ if (scaleX == null) {
+ throw new IllegalArgumentException("scaleX is null.");
+ }
+
+ setScaleX(scaleX.floatValue());
+ }
+
+ /**
+ * Gets the amount by which drawing operations will be scaled along the
+ * y-axis.
+ *
+ * @return
+ * The amount to scale the component's y-axis
+ */
+ public float getScaleY() {
+ return scaleY;
+ }
+
+ /**
+ * Sets the amount by which drawing operations will be scaled along the
+ * y-axis.
+ *
+ * @param scaleY
+ * The amount to scale the component's y-axis
+ */
+ public void setScaleY(float scaleY) {
+ if (scaleY <= 0) {
+ throw new IllegalArgumentException("scaleY must be positive.");
+ }
+
+ this.scaleY = scaleY;
+ }
+
+ /**
+ * Sets the amount by which drawing operations will be scaled along the
+ * y-axis.
+ *
+ * @param scaleY
+ * The amount to scale the component's y-axis
+ */
+ public void setScaleY(Number scaleY) {
+ if (scaleY == null) {
+ throw new IllegalArgumentException("scaleY is null.");
+ }
+
+ setScaleY(scaleY.floatValue());
+ }
+
+ /**
+ * Gets the horizontal alignment of the decorator. A left alignment will
+ * paint the component's left edge at the component's x-coordinate. A right
+ * alignment will paint the component's right edge along the right side
+ * of the component's bounding box. A center or justified alignment will
+ * paint the scaled component centered with respect to the component's
+ * bounding box.
+ *
+ * @return
+ * The horizontal alignment
+ */
+ public HorizontalAlignment getHorizontalAlignment() {
+ return horizontalAlignment;
+ }
+
+ /**
+ * Sets the horizontal alignment of the decorator. A left alignment will
+ * paint the component's left edge at the component's x-coordinate. A right
+ * alignment will paint the component's right edge along the right side
+ * of the component's bounding box. A center or justified alignment will
+ * paint the scaled component centered with respect to the component's
+ * bounding box.
+ *
+ * @param horizontalAlignment
+ * The horizontal alignment
+ */
+ public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) {
+ if (horizontalAlignment == null) {
+ throw new IllegalArgumentException("horizontalAlignment is null.");
+ }
+
+ this.horizontalAlignment = horizontalAlignment;
+ }
+
+ /**
+ * Sets the horizontal alignment of the decorator. A left alignment will
+ * paint the component's left edge at the component's x-coordinate. A right
+ * alignment will paint the component's right edge along the right side
+ * of the component's bounding box. A center or justified alignment will
+ * paint the scaled component centered with respect to the component's
+ * bounding box.
+ *
+ * @param horizontalAlignment
+ * The horizontal alignment
+ */
+ public final void setHorizontalAlignment(String horizontalAlignment) {
+ if (horizontalAlignment == null) {
+ throw new IllegalArgumentException("horizontalAlignment is null.");
+ }
+
+ setHorizontalAlignment(HorizontalAlignment.decode(horizontalAlignment));
+ }
+
+ /**
+ * Gets the vertical alignment of the decorator. A top alignment will
+ * paint the component's top edge at the component's y-coordinate. A bottom
+ * alignment will paint the component's bottom edge along the bottom side
+ * of the component's bounding box. A center or justified alignment will
+ * paint the scaled component centered with respect to the component's
+ * bounding box.
+ *
+ * @return
+ * The vertical alignment
+ */
+ public VerticalAlignment getVerticalAlignment() {
+ return verticalAlignment;
+ }
+
+ /**
+ * Sets the vertical alignment of the decorator. A top alignment will
+ * paint the component's top edge at the component's y-coordinate. A bottom
+ * alignment will paint the component's bottom edge along the bottom side
+ * of the component's bounding box. A center or justified alignment will
+ * paint the scaled component centered with respect to the component's
+ * bounding box.
+ *
+ * @param verticalAlignment
+ * The vertical alignment
+ */
+ public void setVerticalAlignment(VerticalAlignment verticalAlignment) {
+ if (verticalAlignment == null) {
+ throw new IllegalArgumentException("verticalAlignment is null.");
+ }
+
+ this.verticalAlignment = verticalAlignment;
+ }
+
+ /**
+ * Sets the vertical alignment of the decorator. A top alignment will
+ * paint the component's top edge at the component's y-coordinate. A bottom
+ * alignment will paint the component's bottom edge along the bottom side
+ * of the component's bounding box. A center or justified alignment will
+ * paint the scaled component centered with respect to the component's
+ * bounding box.
+ *
+ * @param verticalAlignment
+ * The vertical alignment
+ */
+ public final void setVerticalAlignment(String verticalAlignment) {
+ if (verticalAlignment == null) {
+ throw new IllegalArgumentException("verticalAlignment is null.");
+ }
+
+ setVerticalAlignment(VerticalAlignment.decode(verticalAlignment));
+ }
+
+ /**
+ * Gets the x translation that will be applied with respect to the
+ * specified component, given this decorator's <tt>scaleX</tt> and
+ * <tt>horizontalAlignment</tt> properties.
+ *
+ * @param component
+ * The component being decorated
+ *
+ * @return
+ * The amount to translate x-coordinate actions when decorating this
+ * component
+ */
+ private int getTranslatedX(Component component) {
+ int width = component.getWidth();
+ int translatedWidth = (int)Math.ceil(width * scaleX);
+
+ int tx;
+
+ switch (horizontalAlignment) {
+ case LEFT:
+ tx = 0;
+ break;
+ case RIGHT:
+ tx = width - translatedWidth;
+ break;
+ default:
+ tx = (width - translatedWidth) / 2;
+ break;
+ }
+
+ return tx;
+ }
+
+ /**
+ * Gets the y translation that will be applied with respect to the
+ * specified component, given this decorator's <tt>scaleY</tt> and
+ * <tt>verticalAlignment</tt> properties.
+ *
+ * @param component
+ * The component being decorated
+ *
+ * @return
+ * The amount to translate y-coordinate actions when decorating this
+ * component
+ */
+ private int getTranslatedY(Component component) {
+ int height = component.getHeight();
+ int translatedHeight = (int)Math.ceil(height * scaleY);
+
+ int ty;
+
+ switch (verticalAlignment) {
+ case TOP:
+ ty = 0;
+ break;
+ case BOTTOM:
+ ty = height - translatedHeight;
+ break;
+ default:
+ ty = (height - translatedHeight) / 2;
+ break;
+ }
+
+ return ty;
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ Platform.getTextAntialiasingHint());
+
+ int tx = getTranslatedX(component);
+ int ty = getTranslatedY(component);
+
+ if (tx != 0 || ty != 0) {
+ graphics.translate(tx, ty);
+ }
+
+ graphics.scale(scaleX, scaleY);
+
+ return graphics;
+ }
+
+ public void update() {
+ // No-op
+ }
+
+ public void repaint(Component component, int x, int y, int width, int height) {
+ Container parent = component.getParent();
+
+ if (parent != null) {
+ int tx = getTranslatedX(component);
+ int ty = getTranslatedY(component);
+
+ x = (int)((x * scaleX) + component.getX() + tx);
+ y = (int)((y * scaleY) + component.getY() + ty);
+ width = (int)Math.ceil(width * scaleX);
+ height = (int)Math.ceil(height * scaleY);
+
+ parent.repaint(x, y, width, height);
+ }
+ }
+
+ public Bounds getBounds(Component component) {
+ int width = (int)Math.ceil(component.getWidth() * scaleX);
+ int height = (int)Math.ceil(component.getHeight() * scaleY);
+
+ int tx = getTranslatedX(component);
+ int ty = getTranslatedY(component);
+
+ return new Bounds(tx, ty, width, height);
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return AffineTransform.getScaleInstance(scaleX, scaleY);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ShadeDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ShadeDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ShadeDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/ShadeDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+
+import pivot.wtk.Component;
+import pivot.wtk.Bounds;
+
+/**
+ * Decorator that applies a "shade" to a component. The shade is a rectangle
+ * of the same size as the component that is painted over the component using a
+ * given color and opacity value.
+ *
+ * @author tvolkert
+ */
+public class ShadeDecorator implements Decorator {
+ private float opacity;
+ private Color color;
+
+ private Graphics2D graphics;
+ private Component component;
+
+ /**
+ * Creates a new <tt>ShadeDecorator</tt> with the default opacity and
+ * shade color.
+ */
+ public ShadeDecorator() {
+ this(0.33f, Color.BLACK);
+ }
+
+ /**
+ * Creates a new <tt>ShadeDecorator</tt> with the specified opacity and
+ * shade color.
+ *
+ * @param opacity
+ * The opacity of the shade, between 0 and 1, exclusive.
+ *
+ * @param color
+ * The color of the shade.
+ */
+ public ShadeDecorator(float opacity, Color color) {
+ if (opacity <= 0 || opacity >= 1) {
+ throw new IllegalArgumentException("opacity must be between 0 and 1, exclusive.");
+ }
+
+ if (color == null) {
+ throw new IllegalArgumentException("color is null.");
+ }
+
+ this.opacity = opacity;
+ this.color = color;
+ }
+
+ public float getOpacity() {
+ return opacity;
+ }
+
+ public void setOpacity(float opacity) {
+ this.opacity = opacity;
+ }
+
+ public void setOpacity(Number opacity) {
+ if (opacity == null) {
+ throw new IllegalArgumentException("opacity is null.");
+ }
+
+ setOpacity(opacity.floatValue());
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public void setColor(Color color) {
+ if (color == null) {
+ throw new IllegalArgumentException("color is null.");
+ }
+
+ this.color = color;
+ }
+
+ /**
+ *
+ */
+ public final void setColor(String color) {
+ if (color == null) {
+ throw new IllegalArgumentException("color is null.");
+ }
+
+ setColor(Color.decode(color));
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ this.graphics = graphics;
+ this.component = component;
+
+ return graphics;
+ }
+
+ public void update() {
+ graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
+ graphics.setColor(color);
+ graphics.fillRect(0, 0, component.getWidth(), component.getHeight());
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(0, 0, component.getWidth(), component.getHeight());
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TagDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TagDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TagDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TagDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+
+import pivot.wtk.Bounds;
+import pivot.wtk.Component;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.Visual;
+
+/**
+ * Decorator that allows a caller to attach a "tag" visual to a component.
+ *
+ * @author gbrown
+ */
+public class TagDecorator implements Decorator {
+ private Visual tag;
+ private HorizontalAlignment horizontalAlignment;
+ private VerticalAlignment verticalAlignment;
+ private int xOffset;
+ private int yOffset;
+
+ private Graphics2D graphics = null;
+ private Bounds bounds = null;
+
+ public TagDecorator() {
+ this(null);
+ }
+
+ public TagDecorator(Visual tag) {
+ this(tag, HorizontalAlignment.RIGHT, VerticalAlignment.TOP, 0, 0);
+ }
+
+ public TagDecorator(Visual tag,
+ HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment,
+ int xOffset, int yOffset) {
+ this.tag = tag;
+ this.horizontalAlignment = horizontalAlignment;
+ this.verticalAlignment = verticalAlignment;
+ this.xOffset = xOffset;
+ this.yOffset = yOffset;
+ }
+
+ public Visual getTag() {
+ return tag;
+ }
+
+ public void setTag(Visual tag) {
+ this.tag = tag;
+ }
+
+ public HorizontalAlignment getHorizontalAlignment() {
+ return horizontalAlignment;
+ }
+
+ public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) {
+ if (horizontalAlignment == null) {
+ throw new IllegalArgumentException("horizontalAlignment is null.");
+ }
+
+ this.horizontalAlignment = horizontalAlignment;
+ }
+
+ public VerticalAlignment getVerticalAlignment() {
+ return verticalAlignment;
+ }
+
+ public void setVerticalAlignment(VerticalAlignment verticalAlignment) {
+ if (verticalAlignment == null) {
+ throw new IllegalArgumentException("verticalAlignment is null.");
+ }
+
+ this.verticalAlignment = verticalAlignment;
+ }
+
+ public int getXOffset() {
+ return xOffset;
+ }
+
+ public void setXOffset(int xOffset) {
+ this.xOffset = xOffset;
+ }
+
+ public int getYOffset() {
+ return yOffset;
+ }
+
+ public void setYOffset(int yOffset) {
+ this.yOffset = yOffset;
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ if (tag != null) {
+ bounds = getBounds(component);
+ this.graphics = graphics;
+ }
+
+ return graphics;
+ }
+
+ public void update() {
+ if (tag != null) {
+ graphics.translate(bounds.x, bounds.y);
+ tag.paint(graphics);
+ }
+ }
+
+ public Bounds getBounds(Component component) {
+ Bounds bounds;
+
+ if (tag == null) {
+ bounds = null;
+ } else {
+ bounds = new Bounds();
+
+ switch (horizontalAlignment) {
+ case LEFT: {
+ bounds.x = xOffset;
+ break;
+ }
+
+ case RIGHT: {
+ bounds.x = component.getWidth() - tag.getWidth() + xOffset;
+ break;
+ }
+
+ case CENTER: {
+ bounds.x = (component.getWidth() - tag.getWidth()) / 2 + xOffset;
+ break;
+ }
+ }
+
+ switch (verticalAlignment) {
+ case TOP: {
+ bounds.y = yOffset;
+ break;
+ }
+
+ case BOTTOM: {
+ bounds.y = component.getHeight() - tag.getHeight() + yOffset;
+ break;
+ }
+
+ case CENTER: {
+ bounds.y = (component.getHeight() - tag.getHeight()) / 2 + yOffset;
+ break;
+ }
+ }
+
+ bounds.width = tag.getWidth();
+ bounds.height = tag.getHeight();
+ }
+
+ return bounds;
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Transition.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Transition.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Transition.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/Transition.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import pivot.wtk.ApplicationContext;
+
+/**
+ * Abstract base class for "transitions", which are animated application
+ * effects.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public abstract class Transition {
+ private int duration;
+ private int rate;
+ private boolean repeat;
+
+ private TransitionListener transitionListener;
+
+ private long startTime = 0;
+ private long currentTime = 0;
+ private ApplicationContext.ScheduledCallback transitionCallback = null;
+
+ public static final int DEFAULT_DURATION = 0;
+ public static final int DEFAULT_RATE = 15;
+
+ private final Runnable updateCallback = new Runnable() {
+ public void run() {
+ currentTime = System.currentTimeMillis();
+
+ long endTime = startTime + duration;
+ if (currentTime >= endTime) {
+ if (repeat) {
+ startTime = endTime;
+ } else {
+ currentTime = endTime;
+ stop();
+
+ if (transitionListener != null) {
+ transitionListener.transitionCompleted(Transition.this);
+ }
+ }
+ }
+
+ update();
+ }
+ };
+
+ /**
+ * Creates a new, non-repeating transition with the default duration
+ * and rate.
+ */
+ public Transition() {
+ this(DEFAULT_DURATION, DEFAULT_RATE, false);
+ }
+
+ /**
+ * Creates a new transition with the given duration, rate, and repeat.
+ *
+ * @param duration
+ * Transition duration, in milliseconds.
+ *
+ * @param rate
+ * Transition rate, in frames per second.
+ */
+ public Transition(int duration, int rate, boolean repeat) {
+ if (duration <= 0) {
+ throw new IllegalArgumentException("duration must be positive.");
+ }
+
+ this.duration = duration;
+ this.rate = rate;
+ this.repeat = repeat;
+ }
+
+ /**
+ * Returns the transition duration.
+ *
+ * @return
+ * The duration of the transition, in milliseconds.
+ *
+ * @see #setDuration(int)
+ */
+ public int getDuration() {
+ return duration;
+ }
+
+ /**
+ * Sets the transition duration, the length of time the transition is
+ * scheduled to run.
+ *
+ * @param duration
+ * The duration of the transition, in milliseconds.
+ */
+ public void setDuration(int duration) {
+ if (duration < 0) {
+ throw new IllegalArgumentException("duration is negative.");
+ }
+
+ if (transitionCallback != null) {
+ throw new IllegalStateException("Transition is currently running.");
+ }
+
+ this.duration = duration;
+ }
+
+ /**
+ * Returns the transition rate.
+ *
+ * @return
+ * The rate of the transition, in frames per second.
+ *
+ * @see #setRate(int)
+ */
+ public int getRate() {
+ return rate;
+ }
+
+ /**
+ * Sets the transition rate, the number of times the transition will be
+ * updated within the span of one second.
+ *
+ * @param rate
+ * The transition rate, in frames per second.
+ */
+ public void setRate(int rate) {
+ if (rate < 0) {
+ throw new IllegalArgumentException("rate is negative.");
+ }
+
+ if (transitionCallback != null) {
+ throw new IllegalStateException("Transition is currently running.");
+ }
+
+ this.rate = rate;
+ }
+
+ /**
+ * Returns the transition interval, the number of milliseconds between
+ * updates.
+ *
+ * @return
+ * The transition interval, in milliseconds.
+ */
+ public int getInterval() {
+ return (int)((1f / (float)rate) * 1000);
+ }
+
+ /**
+ * Returns the time at which the transition was started.
+ *
+ * @return
+ * The transition's start time.
+ */
+ public long getStartTime() {
+ return startTime;
+ }
+
+ /**
+ * Returns the last time the transition was updated.
+ *
+ * @return
+ * The most recent update time.
+ */
+ public long getCurrentTime() {
+ return currentTime;
+ }
+
+ /**
+ * Returns the elapsed time since the transition started.
+ *
+ * @return
+ * Returns the amount of time that has passed since the transition
+ * was started.
+ */
+ public int getElapsedTime() {
+ return (int)(currentTime - startTime);
+ }
+
+ /**
+ * Returns the percentage of the transition that has completed.
+ *
+ * @return
+ * A value between 0 and 1, inclusive, representing the transition's
+ * percent complete.
+ */
+ public float getPercentComplete() {
+ return (float)(currentTime - startTime) / (float)(duration);
+ }
+
+ /**
+ * Tells whether or not the transition is currently running.
+ *
+ * @return
+ * <tt>true</tt> if the transition is currently running; <tt>false</tt> if
+ * it is not
+ */
+ public boolean isRunning() {
+ return (transitionCallback != null);
+ }
+
+ /**
+ * Starts the transition. Calls {@link #update()} to establish the
+ * initial state and starts a timer that will repeatedly call
+ * {@link #update()} at the current rate.
+ */
+ public final void start() {
+ start(null);
+ }
+
+ /**
+ * Starts the transition. Calls {@link #update()} to establish the
+ * initial state and starts a timer that will repeatedly call
+ * {@link #update()} at the current rate. The specified
+ * <tt>TransitionListener</tt> will be notified when the transition
+ * completes.
+ *
+ * @param transitionListener
+ * The listener to get notified when the transition completes, or
+ * <tt>null</tt> if no notification is necessary
+ */
+ public void start(TransitionListener transitionListener) {
+ if (transitionCallback != null) {
+ throw new IllegalStateException("Transition is currently running.");
+ }
+
+ this.transitionListener = transitionListener;
+
+ startTime = System.currentTimeMillis();
+ currentTime = startTime;
+
+ transitionCallback = ApplicationContext.scheduleRecurringCallback(updateCallback,
+ getInterval());
+
+ update();
+ }
+
+ /**
+ * Stops the transition. Does not fire a
+ * {@link TransitionListener#transitionCompleted(Transition)} event.
+ */
+ public void stop() {
+ if (transitionCallback != null) {
+ transitionCallback.cancel();
+ }
+
+ transitionCallback = null;
+ }
+
+ /**
+ * "Fast-forwards" to the end of the transition and fires a
+ * {@link TransitionListener#transitionCompleted(Transition)} event.
+ */
+ public void end() {
+ if (transitionCallback != null) {
+ currentTime = startTime + duration;
+ stop();
+ update();
+ transitionListener.transitionCompleted(this);
+ }
+ }
+
+ /**
+ * Called repeatedly while the transition is running to update the
+ * transition's state.
+ */
+ protected abstract void update();
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TransitionListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TransitionListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TransitionListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TransitionListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+/**
+ * Transition listener interface.
+ *
+ * @author tvolkert
+ */
+public interface TransitionListener {
+ /**
+ * Called when a transition has completed.
+ *
+ * @param transition
+ */
+ public void transitionCompleted(Transition transition);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TranslationDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TranslationDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TranslationDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/TranslationDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+
+import pivot.wtk.Bounds;
+import pivot.wtk.Component;
+import pivot.wtk.Point;
+
+/**
+ * Decorator that translates the paint origin of its component.
+ *
+ * @author gbrown
+ */
+public class TranslationDecorator implements Decorator {
+ private int x = 0;
+ private int y = 0;
+ private boolean clip = false;
+
+ public TranslationDecorator() {
+ }
+
+ public TranslationDecorator(boolean clip) {
+ setClip(clip);
+ }
+
+ public TranslationDecorator(int x, int y, boolean clip) {
+ setOffset(x, y);
+ setClip(clip);
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public Point getOffset() {
+ return new Point(x, y);
+ }
+
+ public void setOffset(Point offset) {
+ if (offset == null) {
+ throw new IllegalArgumentException("offset is null.");
+ }
+
+ setOffset(offset.x, offset.y);
+ }
+
+ public void setOffset(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public boolean getClip() {
+ return clip;
+ }
+
+ public void setClip(boolean clip) {
+ this.clip = clip;
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ graphics.translate(x, y);
+ return graphics;
+ }
+
+ public void update() {
+ // No-op
+ }
+
+ public Bounds getBounds(Component component) {
+ Bounds bounds = new Bounds(x, y, component.getWidth(), component.getHeight());
+
+ if (clip) {
+ bounds.intersect(component.getBounds());
+ }
+
+ return bounds;
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return AffineTransform.getTranslateInstance(x, y);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/WatermarkDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/WatermarkDecorator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/WatermarkDecorator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/WatermarkDecorator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects;
+
+import java.awt.AlphaComposite;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.net.URL;
+
+import pivot.wtk.Component;
+import pivot.wtk.FlowPane;
+import pivot.wtk.ImageView;
+import pivot.wtk.Label;
+import pivot.wtk.Orientation;
+import pivot.wtk.Bounds;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.media.Image;
+
+/**
+ * Decorator that paints a watermark effect over a component.
+ *
+ * @author tvolkert
+ */
+public class WatermarkDecorator implements Decorator {
+ private float opacity = 0.075f;
+ private double theta = Math.PI / 4;
+
+ private FlowPane flowPane = new FlowPane(Orientation.HORIZONTAL);
+ private ImageView imageView = new ImageView();
+ private Label label = new Label();
+
+ private Component component = null;
+ private Graphics2D graphics = null;
+
+ /**
+ * Cretes a new <tt>WatermarkDecorator</tt> with no text or image.
+ */
+ public WatermarkDecorator() {
+ this(null, null);
+ }
+
+ /**
+ * Cretes a new <tt>WatermarkDecorator</tt> with the specified string as
+ * its text and no image.
+ *
+ * @param text
+ * The text to paint over the decorated component
+ */
+ public WatermarkDecorator(String text) {
+ this(text, null);
+ }
+
+ /**
+ * Cretes a new <tt>WatermarkDecorator</tt> with no text and the specified
+ * image.
+ *
+ * @param image
+ * The image to paint over the decorated component
+ */
+ public WatermarkDecorator(Image image) {
+ this(null, image);
+ }
+
+ /**
+ * Cretes a new <tt>WatermarkDecorator</tt> with the specified text and
+ * image.
+ *
+ * @param text
+ * The text to paint over the decorated component
+ *
+ * @param image
+ * The image to paint over the decorated component
+ */
+ public WatermarkDecorator(String text, Image image) {
+ flowPane.add(imageView);
+ flowPane.add(label);
+
+ flowPane.getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
+ imageView.getStyles().put("opacity", opacity);
+
+ Font font = (Font)label.getStyles().get("font");
+ label.getStyles().put("font", font.deriveFont(Font.BOLD, 60));
+
+ label.setText(text);
+ imageView.setImage(image);
+
+ validate();
+ }
+
+ /**
+ * Gets the text that will be painted over this decorator's component.
+ *
+ * @return
+ * This decorator's text
+ */
+ public String getText() {
+ return label.getText();
+ }
+
+ /**
+ * Sets the text that will be painted over this decorator's component.
+ *
+ * @param text
+ * This decorator's text
+ */
+ public void setText(String text) {
+ label.setText(text);
+ validate();
+ }
+
+ /**
+ * Gets the font that will be used when painting this decorator's text.
+ *
+ * @return
+ * This decorator's font
+ */
+ public Font getFont() {
+ return (Font)label.getStyles().get("font");
+ }
+
+ /**
+ * Sets the font that will be used when painting this decorator's text.
+ *
+ * @param font
+ * This decorator's font
+ */
+ public void setFont(Font font) {
+ label.getStyles().put("font", font);
+ validate();
+ }
+
+ /**
+ * Sets the font that will be used when painting this decorator's text.
+ *
+ * @param font
+ * This decorator's font
+ */
+ public final void setFont(String font) {
+ setFont(Font.decode(font));
+ }
+
+ /**
+ * Gets the image that will be painted over this decorator's component.
+ *
+ * @return
+ * This decorator's image
+ */
+ public Image getImage() {
+ return imageView.getImage();
+ }
+
+ /**
+ * Sets the image that will be painted over this decorator's component.
+ *
+ * @param image
+ * This decorator's image
+ */
+ public void setImage(Image image) {
+ imageView.setImage(image);
+ validate();
+ }
+
+ /**
+ * Sets the image that will be painted over this decorator's component.
+ *
+ * @param image
+ * This decorator's image
+ */
+ public void setImage(URL image) {
+ if (image == null) {
+ throw new IllegalArgumentException("image is null.");
+ }
+
+ setImage(Image.load(image));
+ }
+
+ /**
+ * Sets the image that will be painted over this decorator's component.
+ *
+ * @param image
+ * This decorator's image
+ */
+ public void setImage(String image) {
+ if (image == null) {
+ throw new IllegalArgumentException("image is null.");
+ }
+
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ setImage(classLoader.getResource(image));
+ }
+
+ /**
+ * Gets the opacity of the watermark.
+ *
+ * @return
+ * This decorator's opacity
+ */
+ public float getOpacity() {
+ return opacity;
+ }
+
+ /**
+ * Sets the opacity of the watermark.
+ *
+ * @param opacity
+ * This decorator's opacity
+ */
+ public void setOpacity(float opacity) {
+ this.opacity = opacity;
+ imageView.getStyles().put("opacity", opacity);
+ }
+
+ /**
+ * Gets the angle at the watermark will be painted, in radians.
+ *
+ * @return
+ * This decorator's watermark angle
+ */
+ public double getTheta() {
+ return theta;
+ }
+
+ /**
+ * Sets the angle at the watermark will be painted, in radians. This value
+ * must lie between <tt>0</tt> and <tt>PI / 2</tt> (inclusive).
+ *
+ * @param theta
+ * This decorator's watermark angle
+ */
+ public void setTheta(double theta) {
+ if (theta < 0
+ || theta > Math.PI / 2) {
+ throw new IllegalArgumentException("Theta must be between 0 nd PI / 2.");
+ }
+
+ this.theta = theta;
+ }
+
+ /**
+ * Sets this decorator's flow pane to its preferred size and validates it.
+ */
+ private void validate() {
+ flowPane.setSize(flowPane.getPreferredSize());
+ flowPane.validate();
+ }
+
+ public Graphics2D prepare(Component component, Graphics2D graphics) {
+ this.component = component;
+ this.graphics = graphics;
+
+ return graphics;
+ }
+
+ public void update() {
+ int width = component.getWidth();
+ int height = component.getHeight();
+
+ double sinTheta = Math.sin(theta);
+ double cosTheta = Math.cos(theta);
+
+ Graphics2D watermarkGraphics = (Graphics2D)graphics.create();
+ watermarkGraphics.setComposite(AlphaComposite.getInstance
+ (AlphaComposite.SRC_OVER, opacity));
+ watermarkGraphics.rotate(theta);
+
+ // Calculate the separation in between each repetition of the watermark
+ int dX = (int)(1.5 * flowPane.getWidth());
+ int dY = 2 * flowPane.getHeight();
+
+ // Prepare the origin of our graphics context
+ int x = 0;
+ int y = (int)(-width * sinTheta);
+ watermarkGraphics.translate(x, y);
+
+ for (int yStop = (int)(height * cosTheta), p = 0; y < yStop; y += dY, p = 1 - p) {
+ for (int xStop = (int)(height * sinTheta + width * cosTheta); x < xStop; x += dX) {
+ flowPane.paint(watermarkGraphics);
+ watermarkGraphics.translate(dX, 0);
+ }
+
+ // Move X origin back to its starting position & Y origin down
+ watermarkGraphics.translate(-x, dY);
+ x = 0;
+
+ // Shift the x back and forth to add randomness feel to pattern
+ watermarkGraphics.translate((int)((0.5f - p) * flowPane.getWidth()), 0);
+ }
+
+ watermarkGraphics.dispose();
+ }
+
+ public Bounds getBounds(Component component) {
+ return new Bounds(0, 0, component.getWidth(), component.getHeight());
+ }
+
+ public AffineTransform getTransform(Component component) {
+ return new AffineTransform();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Circular.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Circular.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Circular.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Circular.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2003 Robert Penner, all rights reserved.
+ *
+ * This work is subject to the terms in
+ * http://www.robertpenner.com/easing_terms_of_use.html.
+ *
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects.easing;
+
+/**
+ * Circular easing operation.
+ *
+ * @author Robert Penner
+ * @author gbrown
+ */
+public class Circular implements Easing {
+ public float easeIn(float time, float begin, float change, float duration) {
+ return -change * ((float)Math.sqrt(1f - (time /= duration) * time) - 1f) + begin;
+ }
+
+ public float easeOut(float time, float begin, float change, float duration) {
+ return change * (float)Math.sqrt(1f - (time = time / duration - 1f) * time) + begin;
+ }
+
+ public float easeInOut(float time, float begin, float change, float duration) {
+ if ((time /= duration / 2f) < 1f) {
+ return -change / 2f * ((float)Math.sqrt(1f - time * time) - 1f) + begin;
+ } else {
+ return change / 2f * ((float)Math.sqrt(1f - (time -= 2f) * time) + 1f) + begin;
+ }
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Cubic.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Cubic.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Cubic.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Cubic.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2003 Robert Penner, all rights reserved.
+ *
+ * This work is subject to the terms in
+ * http://www.robertpenner.com/easing_terms_of_use.html.
+ *
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects.easing;
+
+/**
+ * Cubic easing operation.
+ *
+ * @author Robert Penner
+ * @author gbrown
+ */
+public class Cubic implements Easing {
+ public float easeIn(float time, float begin, float change, float duration) {
+ return change * (time /= duration) * time * time + begin;
+ }
+
+ public float easeOut(float time, float begin, float change, float duration) {
+ return change * ((time = time / duration - 1f) * time * time + 1f) + begin;
+ }
+
+ public float easeInOut(float time, float begin, float change, float duration) {
+ if ((time /= duration / 2f) < 1f) {
+ return change / 2f * time * time * time + begin;
+ } else {
+ return change / 2f * ((time -= 2f) * time * time + 2f) + begin;
+ }
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Easing.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Easing.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Easing.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Easing.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2003 Robert Penner, all rights reserved.
+ *
+ * This work is subject to the terms in
+ * http://www.robertpenner.com/easing_terms_of_use.html.
+ *
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects.easing;
+
+/**
+ * Base interface for easing operations.
+ *
+ * @author Robert Penner
+ * @author gbrown
+ */
+public interface Easing {
+ public float easeIn(float time, float begin, float change, float duration);
+ public float easeOut(float time, float begin, float change, float duration);
+ public float easeInOut(float time, float begin, float change, float duration);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Exponential.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Exponential.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Exponential.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Exponential.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003 Robert Penner, all rights reserved.
+ *
+ * This work is subject to the terms in
+ * http://www.robertpenner.com/easing_terms_of_use.html.
+ *
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects.easing;
+
+/**
+ * Exponential easing operation.
+ *
+ * @author Robert Penner
+ * @author gbrown
+ */
+public class Exponential implements Easing {
+ public float easeIn(float time, float begin, float change, float duration) {
+ return (time == 0) ? begin
+ : change * (float)Math.pow(2, 10 * (time / duration - 1f)) + begin;
+ }
+
+ public float easeOut(float time, float begin, float change, float duration) {
+ return (time == duration) ? begin + change
+ : change * ((float)-Math.pow(2, -10 * time / duration) + 1f) + begin;
+ }
+
+ public float easeInOut(float time, float begin, float change, float duration) {
+ if (time == 0) {
+ return begin;
+ }
+
+ if (time == duration) {
+ return begin + change;
+ }
+
+ if ((time /= duration / 2f) < 1) {
+ return change / 2f * (float)Math.pow(2, 10 * (time - 1)) + begin;
+ }
+
+ return change / 2f * ((float)-Math.pow(2, -10 * --time) + 2) + begin;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Linear.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Linear.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Linear.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/effects/easing/Linear.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2003 Robert Penner, all rights reserved.
+ *
+ * This work is subject to the terms in
+ * http://www.robertpenner.com/easing_terms_of_use.html.
+ *
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtk.effects.easing;
+
+/**
+ * Linear easing operation.
+ *
+ * @author Robert Penner
+ * @author gbrown
+ */
+public class Linear implements Easing {
+ public float easeIn(float time, float begin, float change, float duration) {
+ return change * time / duration + begin;
+ }
+
+ public float easeOut(float time, float begin, float change, float duration) {
+ return change * time / duration + begin;
+ }
+
+ public float easeInOut(float time, float begin, float change, float duration) {
+ return change * time / duration + begin;
+ }
+}