You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/04/27 17:21:55 UTC

svn commit: r769026 - in /incubator/pivot/trunk/wtk/src/pivot/wtk/media: ./ drawing/

Author: gbrown
Date: Mon Apr 27 15:21:53 2009
New Revision: 769026

URL: http://svn.apache.org/viewvc?rev=769026&view=rev
Log:
Updates to drawing API.

Added:
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Canvas.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/CanvasListener.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rotation.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Scale.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeListener.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeTransformListener.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Transform.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Translation.java
Modified:
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/Drawing.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/DrawingListener.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Arc.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Ellipse.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Line.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Path.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rectangle.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Shape.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Text.java

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/Drawing.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/Drawing.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/Drawing.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/Drawing.java Mon Apr 27 15:21:53 2009
@@ -20,9 +20,8 @@
 
 import pivot.util.ListenerList;
 import pivot.wtk.Bounds;
-import pivot.wtk.media.drawing.Group;
-import pivot.wtk.media.drawing.Shape;
-import pivot.wtk.media.drawing.ShapeListener;
+import pivot.wtk.media.drawing.Canvas;
+import pivot.wtk.media.drawing.CanvasListener;
 
 /**
  * Image representing a vector drawing.
@@ -32,20 +31,21 @@
 public class Drawing extends Image {
     private static class DrawingListenerList extends ListenerList<DrawingListener>
         implements DrawingListener {
-        public void rootChanged(Drawing drawing, Group previousRoot) {
+        public void canvasChanged(Drawing drawing, Canvas previousCanvas) {
             for (DrawingListener listener : this) {
-                listener.rootChanged(drawing, previousRoot);
+                listener.canvasChanged(drawing, previousCanvas);
             }
         }
     }
 
-    private Group root;
+    private Canvas canvas;
     private int width = 0;
     private int height = 0;
 
-    private ShapeListener rootListener = new ShapeListener.Adapter() {
-        @Override
-        public void regionInvalidated(Shape shape, int x, int y, int width, int height) {
+    private CanvasListener canvasListener = new CanvasListener() {
+        public void regionUpdated(Canvas canvas, int x, int y, int width, int height) {
+            // TODO Apply root transforms before propagating up
+
             Bounds bounds = new Bounds(0, 0, Drawing.this.width, Drawing.this.height);
             bounds = bounds.intersect(new Bounds(x, y, width, height));
             imageListeners.regionInvalidated(Drawing.this, x, y, width, height);
@@ -55,32 +55,32 @@
     private DrawingListenerList drawingListeners = new DrawingListenerList();
 
     public Drawing() {
-        this(new Group());
+        this(new Canvas());
     }
 
-    public Drawing(Group root) {
-        setRoot(root);
+    public Drawing(Canvas canvas) {
+        setCanvas(canvas);
     }
 
-    public Group getRoot() {
-        return root;
+    public Canvas getCanvas() {
+        return canvas;
     }
 
-    public void setRoot(Group root) {
-        Group previousRoot = this.root;
+    public void setCanvas(Canvas canvas) {
+        Canvas previousCanvas = this.canvas;
 
-        if (previousRoot != root) {
-            this.root = root;
+        if (previousCanvas != canvas) {
+            this.canvas = canvas;
 
-            if (previousRoot != null) {
-                previousRoot.getShapeListeners().remove(rootListener);
+            if (previousCanvas != null) {
+                previousCanvas.getCanvasListeners().remove(canvasListener);
             }
 
-            if (root != null) {
-                root.getShapeListeners().add(rootListener);
+            if (canvas != null) {
+                canvas.getCanvasListeners().add(canvasListener);
             }
 
-            drawingListeners.rootChanged(this, previousRoot);
+            drawingListeners.canvasChanged(this, previousCanvas);
 
             imageListeners.regionInvalidated(this, 0, 0, width, height);
         }
@@ -107,9 +107,9 @@
     public void paint(Graphics2D graphics) {
         graphics.clipRect(0, 0, width, height);
 
-        if (root != null) {
+        if (canvas != null) {
             // TODO Apply root transforms
-            root.draw(graphics);
+            canvas.draw(graphics);
         }
     }
 

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/DrawingListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/DrawingListener.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/DrawingListener.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/DrawingListener.java Mon Apr 27 15:21:53 2009
@@ -16,7 +16,7 @@
  */
 package pivot.wtk.media;
 
-import pivot.wtk.media.drawing.Group;
+import pivot.wtk.media.drawing.Canvas;
 
 /**
  * Drawing listener interface.
@@ -24,5 +24,5 @@
  * @author gbrown
  */
 public interface DrawingListener {
-    public void rootChanged(Drawing drawing, Group previousRoot);
+    public void canvasChanged(Drawing drawing, Canvas previousCanvas);
 }

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Arc.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Arc.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Arc.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Arc.java Mon Apr 27 15:21:53 2009
@@ -18,6 +18,8 @@
 
 import java.awt.Graphics2D;
 
+import pivot.wtk.Bounds;
+
 /**
  * Shape representing an arc.
  *
@@ -25,6 +27,12 @@
  */
 public class Arc extends Shape {
     @Override
+    public Bounds getBounds() {
+        // TODO
+        return null;
+    }
+
+    @Override
     public boolean contains(int x, int y) {
         // TODO Auto-generated method stub
         return false;

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Canvas.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Canvas.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Canvas.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Canvas.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+import pivot.util.ListenerList;
+
+/**
+ * Shape representing the root of a shape hierarchy.
+ *
+ * @author gbrown
+ */
+public class Canvas extends Group {
+    private class CanvasListenerList extends ListenerList<CanvasListener>
+        implements CanvasListener {
+        public void regionUpdated(Canvas canvas, int x, int y, int width, int height) {
+            for (CanvasListener listener : this) {
+                listener.regionUpdated(canvas, x, y, width, height);
+            }
+        }
+    }
+
+    @Override
+    protected void invalidate() {
+        super.invalidate();
+
+        // TODO Queue validate callback
+    }
+
+    @Override
+    protected void update(int x, int y, int width, int height) {
+        super.update(x, y, width, height);
+        canvasListeners.regionUpdated(this, x, y, width, height);
+    }
+
+    private CanvasListenerList canvasListeners = new CanvasListenerList();
+
+    public ListenerList<CanvasListener> getCanvasListeners() {
+        return canvasListeners;
+    }
+}

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/CanvasListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/CanvasListener.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/CanvasListener.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/CanvasListener.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+/**
+ * Canvas listener interface.
+ *
+ * @author gbrown
+ */
+public interface CanvasListener {
+    /**
+     * Called when a region within a canvas needs to be repainted.
+     *
+     * @param canvas
+     * @param x
+     * @param y
+     * @param width
+     * @param height
+     */
+    public void regionUpdated(Canvas canvas, int x, int y, int width, int height);
+}

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Ellipse.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Ellipse.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Ellipse.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Ellipse.java Mon Apr 27 15:21:53 2009
@@ -18,6 +18,8 @@
 
 import java.awt.Graphics2D;
 
+import pivot.wtk.Bounds;
+
 /**
  * Shape representing an ellipse.
  *
@@ -25,6 +27,12 @@
  */
 public class Ellipse extends Shape {
     @Override
+    public Bounds getBounds() {
+        // TODO
+        return null;
+    }
+
+    @Override
     public boolean contains(int x, int y) {
         // TODO Auto-generated method stub
         return false;

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java Mon Apr 27 15:21:53 2009
@@ -33,9 +33,9 @@
 
     @Override
     public Bounds getBounds() {
-        // TODO If invalid, recalcuate the bounds and call setBounds()
+        // TODO If invalid, recalcuate (and cache) the bounds
 
-        return super.getBounds();
+        return null;
     }
 
     public void draw(Graphics2D graphics) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Line.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Line.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Line.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Line.java Mon Apr 27 15:21:53 2009
@@ -19,6 +19,8 @@
 import java.awt.Graphics2D;
 import java.awt.Paint;
 
+import pivot.wtk.Bounds;
+
 /**
  * Shape representing a line.
  *
@@ -26,6 +28,12 @@
  */
 public class Line extends Shape {
     @Override
+    public Bounds getBounds() {
+        // TODO
+        return null;
+    }
+
+    @Override
     public boolean contains(int x, int y) {
         // TODO Auto-generated method stub
         return false;
@@ -33,11 +41,13 @@
 
     @Override
     public Paint getFill() {
+        // Lines don't have a fill
         return null;
     }
 
     @Override
     public void setFill(Paint fill) {
+        // Lines can't have a fill
         throw new UnsupportedOperationException();
     }
 

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Path.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Path.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Path.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Path.java Mon Apr 27 15:21:53 2009
@@ -18,6 +18,8 @@
 
 import java.awt.Graphics2D;
 
+import pivot.wtk.Bounds;
+
 /**
  * Shape representing an arbitrary geometric path.
  * <p>
@@ -28,6 +30,12 @@
  */
 public class Path extends Shape {
     @Override
+    public Bounds getBounds() {
+        // TODO
+        return null;
+    }
+
+    @Override
     public boolean contains(int x, int y) {
         // TODO Auto-generated method stub
         return false;

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rectangle.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rectangle.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rectangle.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rectangle.java Mon Apr 27 15:21:53 2009
@@ -18,6 +18,8 @@
 
 import java.awt.Graphics2D;
 
+import pivot.wtk.Bounds;
+
 /**
  * Shape representing a rectangle.
  *
@@ -25,6 +27,12 @@
  */
 public class Rectangle extends Shape {
     @Override
+    public Bounds getBounds() {
+        // TODO
+        return null;
+    }
+
+    @Override
     public boolean contains(int x, int y) {
         // TODO
         return false;

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rotation.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rotation.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rotation.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Rotation.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * Represents a rotation transformation.
+ *
+ * @author gbrown
+ */
+public class Rotation implements Transform {
+    public AffineTransform getAffineTransform() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Scale.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Scale.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Scale.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Scale.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * Reprensents a scale transformation.
+ *
+ * @author gbrown
+ */
+public class Scale implements Transform {
+    public AffineTransform getAffineTransform() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Shape.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Shape.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Shape.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Shape.java Mon Apr 27 15:21:53 2009
@@ -19,7 +19,11 @@
 import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.util.Iterator;
 
+import pivot.collections.ArrayList;
+import pivot.collections.Sequence;
 import pivot.util.ListenerList;
 import pivot.wtk.Bounds;
 import pivot.wtk.Point;
@@ -30,7 +34,65 @@
  * @author gbrown
  */
 public abstract class Shape {
-    // TODO Define a transform sequence; also add ShapeTransformListener
+    /**
+     * Represents a sequence of affine transformations applied to this shape.
+     * <p>
+     * TODO These operations invalidate the shape.
+     * <p>
+     * TODO Fire ShapeTransform events as appropriate.
+     *
+     * @author gbrown
+     */
+    public class TransformSequence
+        implements Transform, Sequence<Transform>, Iterable<Transform> {
+        public int add(Transform transform) {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public Transform update(int index, Transform transform) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void insert(Transform transform, int index) {
+            // TODO Auto-generated method stub
+
+        }
+
+        public int remove(Transform transform) {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public Sequence<Transform> remove(int index, int count) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        public Transform get(int index) {
+            return transforms.get(index);
+        }
+
+        public int indexOf(Transform transform) {
+            return transforms.indexOf(transform);
+        }
+
+        public int getLength() {
+            return transforms.getLength();
+        }
+
+        public AffineTransform getAffineTransform() {
+            // TODO Invalidate this when the list is modified and lazily
+            // recalculate here when requested
+
+            return null;
+        }
+
+        public Iterator<Transform> iterator() {
+            // TODO
+            return null;
+        }
+    }
 
     private class ShapeListenerList extends ListenerList<ShapeListener>
         implements ShapeListener {
@@ -57,12 +119,6 @@
                 listener.fillChanged(shape, previousFill);
             }
         }
-
-        public void regionInvalidated(Shape shape, int x, int y, int width, int height) {
-            for (ShapeListener listener : this) {
-                listener.regionInvalidated(shape, x, y, width, height);
-            }
-        }
     }
 
     private Group parent = null;
@@ -75,6 +131,9 @@
     private Paint stroke = Color.BLACK;
     private int strokeThickness = 1;
 
+    private ArrayList<Transform> transforms = new ArrayList<Transform>();
+    private TransformSequence transformSequence = new TransformSequence();
+
     private ShapeListenerList shapeListeners = new ShapeListenerList();
 
     public Group getParent() {
@@ -107,13 +166,13 @@
 
     public void setOrigin(int x, int y) {
         // Repaint the region formerly occupied by this shape
-        invalidateRegion();
+        update();
 
         this.x = x;
         this.y = y;
 
         // Repaint the region currently occupied by this shape
-        invalidateRegion();
+        update();
     }
 
     public void setOrigin(Point origin) {
@@ -124,10 +183,14 @@
         setOrigin(origin.x, origin.y);
     }
 
-    public Bounds getBounds() {
-        // TODO Make this public abstract
-        return bounds;
-    }
+    /**
+     * Returns the bounds of the component, including the stroke thickness.
+     *
+     * @return
+     * The component's bounding area. The x and y coordinates are relative to
+     * the parent group's origin.
+     */
+    public abstract Bounds getBounds();
 
     public Bounds getTransformedBounds() {
         // TODO Apply transform to bounds and return
@@ -165,7 +228,7 @@
 
     public void setFill(Paint fill) {
         this.fill = fill;
-        invalidateRegion();
+        update();
     }
 
     public void setFill(String fill) {
@@ -191,7 +254,7 @@
 
     public void setStroke(Paint stroke) {
         this.stroke = stroke;
-        invalidateRegion();
+        update();
     }
 
     public void setStroke(String stroke) {
@@ -222,34 +285,40 @@
 
         this.strokeThickness = strokeThickness;
 
-        invalidateRegion();
+        invalidate();
     }
 
     public abstract void draw(Graphics2D graphics);
 
-    protected void invalidateRegion() {
-        invalidateRegion(bounds);
+    public TransformSequence getTransforms() {
+        return transformSequence;
     }
 
-    protected void invalidateRegion(Bounds bounds) {
-        invalidateRegion(bounds.x, bounds.y, bounds.width, bounds.height);
+    protected void invalidate() {
+        // TODO Clear transformedBounds; recalculate in getTransformedBounds()
+        // TODO If parent is non-null, propagate upwards
+    }
+
+    protected void validate() {
+        // TODO Recalculate transformed bounds
     }
 
-    protected void invalidateRegion(int x, int y, int width, int height) {
-        shapeListeners.regionInvalidated(this, x, y, width, height);
+    protected final void update() {
+        update(bounds);
+    }
 
+    protected final void update(Bounds bounds) {
+        update(bounds.x, bounds.y, bounds.width, bounds.height);
+    }
+
+    protected void update(int x, int y, int width, int height) {
         // TODO Transform region bounds
 
         if (parent != null) {
-            parent.invalidateRegion(this.x + x, this.y + y, width, height);
+            parent.update(this.x + x, this.y + y, width, height);
         }
     }
 
-    protected void invalidateBounds() {
-        // TODO Clear transformedBounds; recalculate in getTransformedBounds()
-        // TODO If parent is non-null, propagate upwards
-    }
-
     public ListenerList<ShapeListener> getShapeListeners() {
         return shapeListeners;
     }

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeListener.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeListener.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeListener.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+import java.awt.Paint;
+
+/**
+ * Shape listener interface.
+ *
+ * @author gbrown
+ */
+public interface ShapeListener {
+    /**
+     * Shape listener adapter.
+     *
+     * @author gbrown
+     */
+    public static class Adapter implements ShapeListener {
+        public void originChanged(Shape shape, int previousX, int previousY) {
+        }
+
+        public void strokeChanged(Shape shape, Paint previousStroke) {
+        }
+
+        public void strokeThicknessChanged(Shape shape, int previousStrokeThickness) {
+        }
+
+        public void fillChanged(Shape shape, Paint previousFill) {
+        }
+    }
+
+    /**
+     * Called when a shape's origin has changed.
+     *
+     * @param shape
+     * @param previousX
+     * @param previousY
+     */
+    public void originChanged(Shape shape, int previousX, int previousY);
+
+    /**
+     * Called when a shape's stroke has changed.
+     *
+     * @param shape
+     * @param previousStroke
+     */
+    public void strokeChanged(Shape shape, Paint previousStroke);
+
+    /**
+     * Called when a shape's stroke thickness has changed.
+     *
+     * @param shape
+     * @param previousStrokeThickness
+     */
+    public void strokeThicknessChanged(Shape shape, int previousStrokeThickness);
+
+    /**
+     * Called when a shape's fill has changed.
+     *
+     * @param shape
+     * @param previousFill
+     */
+    public void fillChanged(Shape shape, Paint previousFill);
+}

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeTransformListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeTransformListener.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeTransformListener.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/ShapeTransformListener.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+/**
+ * Shape transform listener interface.
+ *
+ * @author gbrown
+ */
+public interface ShapeTransformListener {
+    /**
+     * Called when a transform has been inserted into a shape's transform
+     * sequence.
+     *
+     * @param shape
+     * @param index
+     */
+    public void transformInserted(Shape shape, int index);
+
+    /**
+     * Called when a transform has been removed from a shape's transform
+     * sequence.
+     *
+     * @param shape
+     * @param index
+     * @param count
+     */
+    public void transformsRemoved(Shape shape, int index, int count);
+}

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Text.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Text.java?rev=769026&r1=769025&r2=769026&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Text.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Text.java Mon Apr 27 15:21:53 2009
@@ -19,6 +19,8 @@
 import java.awt.Font;
 import java.awt.Graphics2D;
 
+import pivot.wtk.Bounds;
+
 /**
  * Shape representing a block of text.
  *
@@ -29,12 +31,19 @@
     private Font font = null; // TODO Need to specify a default
     private int wrapWidth = -1;
 
+    @Override
+    public Bounds getBounds() {
+        // TODO Recalculate width, height in validate()
+        return null;
+    }
+
     public String getText() {
         return text;
     }
 
     public void setText(String text) {
         this.text = text;
+        invalidate();
     }
 
     public Font getFont() {

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Transform.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Transform.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Transform.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Transform.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * Interface encapsulating an affine transformation.
+ *
+ * @author gbrown
+ */
+public interface Transform {
+    public AffineTransform getAffineTransform();
+}

Added: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Translation.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Translation.java?rev=769026&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Translation.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Translation.java Mon Apr 27 15:21:53 2009
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.media.drawing;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * Represents a translation transformation.
+ *
+ * @author gbrown
+ */
+public class Translation implements Transform {
+    public AffineTransform getAffineTransform() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}