[skycastle-commits] SF.net SVN: skycastle: [485] trunk/skycastle/modules/ui/src/main/java/org/ skycastle

  • From: zzorn@xxxxxxxxxxxxxxxxxxxxx
  • To: skycastle-commits@xxxxxxxxxxxxx
  • Date: Sat, 26 Apr 2008 17:02:05 -0700

Revision: 485
          http://skycastle.svn.sourceforge.net/skycastle/?rev=485&view=rev
Author:   zzorn
Date:     2008-04-26 17:02:04 -0700 (Sat, 26 Apr 2008)

Log Message:
-----------
Working on adding input support.

Modified Paths:
--------------
    trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java

Added Paths:
-----------
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java
    trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java

Removed Paths:
-------------
    trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java
    
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java

Modified: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java
===================================================================
--- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java 
2008-04-26 20:42:11 UTC (rev 484)
+++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java 
2008-04-27 00:02:04 UTC (rev 485)
@@ -1,12 +1,14 @@
 package org.skycastle.opengl;
 
 import com.jme.renderer.Camera;
+import com.jme.renderer.ColorRGBA;
 import com.jme.renderer.Renderer;
 import com.jme.scene.Spatial;
 import com.jme.scene.state.CullState;
 import com.jme.system.DisplaySystem;
 import com.jmex.awt.JMECanvas;
 import com.jmex.awt.SimpleCanvasImpl;
+import jpen.PenManager;
 import org.skycastle.opengl.navigationgestures.*;
 import org.skycastle.util.ParameterChecker;
 import org.skycastle.util.cursor.CursorChangerImpl;
@@ -14,6 +16,7 @@
 
 import javax.swing.*;
 import java.awt.Canvas;
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.event.ComponentAdapter;
@@ -24,7 +27,8 @@
 /**
  * A 3D Canvas, showing a 3D object in an AWT Canvas component.
  * <p/>
- * Allows registering Gestures, that can be used to navigate the 3D view 
(already has default gestures registered).
+ * Allows registering Gestures, that can be used to navigate the 3D view 
(already has default gestures
+ * registered).
  * <p/>
  * Also allows adding FrameListeners, that are called after each rendering 
frame in the swing thread.
  *
@@ -37,6 +41,7 @@
     //======================================================================
     // Private Fields
 
+    private final ColorRGBA myBackgroundColor = new ColorRGBA();
     private final Set<NavigationGesture> myNavigationGestures = new 
HashSet<NavigationGesture>();
     private final CursorChangerImpl myCursorChanger = new CursorChangerImpl();
     private final FpsCounter myFpsCounter = new FpsCounter();
@@ -113,7 +118,8 @@
     /**
      * TODO: CHECK: Are the units meters?
      *
-     * @return distance in screen units to the far clipping plane - 3D 
geometry beyond this distance is not shown.
+     * @return distance in screen units to the far clipping plane - 3D 
geometry beyond this distance is not
+     *         shown.
      */
     public float getViewDistance()
     {
@@ -124,7 +130,8 @@
     /**
      * TODO: CHECK: Are the units meters?
      *
-     * @param viewDistance distance in screen units to the far clipping plane 
- 3D geometry beyond this distance is not shown.
+     * @param viewDistance distance in screen units to the far clipping plane 
- 3D geometry beyond this
+     *                     distance is not shown.
      */
     public void setViewDistance( final float viewDistance )
     {
@@ -160,7 +167,8 @@
 
 
     /**
-     * Adds the specified FrameListener.  The listener is called after each 
frame is rendered in the swing thread.
+     * Adds the specified FrameListener.  The listener is called after each 
frame is rendered in the swing
+     * thread.
      *
      * @param addedFrameListener should not be null or already added.
      */
@@ -191,8 +199,8 @@
 
 
     /**
-     * @return the number of frames rendered per second,
-     *         or a negative value if the canvas has not yet been rendered.
+     * @return the number of frames rendered per second, or a negative value 
if the canvas has not yet been
+     *         rendered.
      */
     public double getFramesPerSecond()
     {
@@ -201,8 +209,8 @@
 
 
     /**
-     * @return number of seconds between the previous frame and the frame 
before that,
-     *         or a negative value if the canvas has not yet been rendered.
+     * @return number of seconds between the previous frame and the frame 
before that, or a negative value if
+     *         the canvas has not yet been rendered.
      */
     public double getSecondsBetweenFrames()
     {
@@ -253,6 +261,7 @@
         registerNavigationGestureListener( addedNavigationGesture );
     }
 
+    private PenManager myPenManager;
 
     /**
      * @param removedNavigationGesture gesture to remove.
@@ -283,6 +292,20 @@
         }
     }
 
+
+    /**
+     * Should be called before the canvas is initiated for it to take effect.
+     *
+     * @param color the background color to use for the {@link Canvas3D}.
+     */
+    public void setBackgroundColor( final Color color )
+    {
+        myBackgroundColor.set( color.getRed() / 255.0f,
+                               color.getGreen() / 255.0f,
+                               color.getBlue() / 255.0f,
+                               color.getAlpha() / 255.0f );
+    }
+
     //======================================================================
     // Private Methods
 
@@ -291,6 +314,7 @@
         if ( myCanvas != null )
         {
             navigationGesture.init( myCanvas, myCursorChanger, 
myCameraAccessor );
+            myPenManager.pen.addListener( navigationGesture );
         }
     }
 
@@ -319,8 +343,11 @@
         myCanvasRenderer = new MyCanvasRenderer( width, height, my3DNode, 
myCanvas );
         jmeCanvas.setImplementor( myCanvasRenderer );
 
+        // Listen to tablet pen movement over the canvas
+        myPenManager = new PenManager( myCanvas );
+
         // Add navigation gesture listeners to the created 3D canvas
-        for ( NavigationGesture navigationGesture : myNavigationGestures )
+        for ( final NavigationGesture navigationGesture : myNavigationGestures 
)
         {
             registerNavigationGestureListener( navigationGesture );
         }
@@ -427,8 +454,8 @@
          *
          * @param width          initial size of the canvas.  Should be larger 
than 0.
          * @param height         initial size of the canvas.  Should be larger 
than 0.
-         * @param canvasRootNode the 3D object to render.
-         *                       May be null, in which case nothing is 
rendered (black area)
+         * @param canvasRootNode the 3D object to render. May be null, in 
which case nothing is rendered
+         *                       (black area)
          * @param canvas         the canvas we are rendering to.  Needed for 
listening to resize events.
          */
         public MyCanvasRenderer( final int width,
@@ -462,8 +489,8 @@
         // Other Public Methods
 
         /**
-         * @return the number of frames rendered per second,
-         *         or a negative value if the canvas has not yet been rendered.
+         * @return the number of frames rendered per second, or a negative 
value if the canvas has not yet
+         *         been rendered.
          */
         public double getFramesPerSecond()
         {
@@ -472,8 +499,8 @@
 
 
         /**
-         * @return number of seconds between the previous frame and the frame 
before that,
-         *         or a negative value if the canvas has not yet been rendered.
+         * @return number of seconds between the previous frame and the frame 
before that, or a negative value
+         *         if the canvas has not yet been rendered.
          */
         public double getSecondsBetweenFrames()
         {
@@ -482,8 +509,8 @@
 
 
         /**
-         * @param canvasRootNode the spatial to render with this 
CanvasRenderer.
-         *                       May be null, in which case nothing is 
rendered (black area)
+         * @param canvasRootNode the spatial to render with this 
CanvasRenderer. May be null, in which case
+         *                       nothing is rendered (black area)
          */
         public void setCanvasRootNode( final Spatial canvasRootNode )
         {
@@ -517,6 +544,9 @@
             }
 
             getCamera().setFrustumFar( myViewDistance );
+
+            // Set the background color
+            getRenderer().setBackgroundColor( myBackgroundColor );
         }
 
 

Modified: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java
     2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java
     2008-04-27 00:02:04 UTC (rev 485)
@@ -2,6 +2,10 @@
 
 import com.jme.math.Vector3f;
 import com.jme.renderer.Camera;
+import jpen.PButtonEvent;
+import jpen.PKindEvent;
+import jpen.PLevelEvent;
+import jpen.PScrollEvent;
 import org.skycastle.util.cursor.CursorChanger;
 
 import javax.swing.event.MouseInputAdapter;
@@ -65,6 +69,34 @@
     }
 
     //----------------------------------------------------------------------
+    // PenListener Implementation
+
+
+    public void penKindEvent( final PKindEvent ev )
+    {
+    }
+
+
+    public void penLevelEvent( final PLevelEvent ev )
+    {
+    }
+
+
+    public void penButtonEvent( final PButtonEvent ev )
+    {
+    }
+
+
+    public void penScrollEvent( final PScrollEvent ev )
+    {
+    }
+
+
+    public void penTock( final long availableMillis )
+    {
+    }
+
+    //----------------------------------------------------------------------
     // Other Public Methods
 
     /**
@@ -95,6 +127,7 @@
         mySensitivity = sensitivity;
     }
 
+
     /**
      * Moves the mouse position to the specified canvas coordinates
      */
@@ -106,7 +139,8 @@
 
 
     /**
-     * @return an interface that can be used to change the mouse cursor on the 
3D canvas we are rendering to (or hide it).
+     * @return an interface that can be used to change the mouse cursor on the 
3D canvas we are rendering to
+     *         (or hide it).
      */
     protected final CursorChanger getCursorChanger()
     {
@@ -126,7 +160,8 @@
 
 
     /**
-     * @return the camera that has been assigned to this navigation gesture 
listener, or null if no camera has yet been assigned.
+     * @return the camera that has been assigned to this navigation gesture 
listener, or null if no camera has
+     *         yet been assigned.
      */
     protected final Camera getCamera()
     {
@@ -142,7 +177,8 @@
 
 
     /**
-     * @return a multiplication factor calculated from the altitude, used to 
adjust the move and pan operations.
+     * @return a multiplication factor calculated from the altitude, used to 
adjust the move and pan
+     *         operations.
      */
     protected final float getAltitudeFactor()
     {
@@ -174,8 +210,9 @@
      *
      * @param location A location to calculate the altitude of.
      *
-     * @return the altitude of the specified location above the ground.  The 
accuracy can be calculated relative to the altitude,
-     *         if the location is closer to the ground, higher accuracy is 
used than if it is further from the ground.
+     * @return the altitude of the specified location above the ground.  The 
accuracy can be calculated
+     *         relative to the altitude, if the location is closer to the 
ground, higher accuracy is used than
+     *         if it is further from the ground.
      */
     private float getAltitudeAt( final Vector3f location )
     {
@@ -187,8 +224,9 @@
      * REFACTOR: Move to some terrain or map class and make public.
      *
      * @param location some location in the world.  Usually only the x and y 
values are used, z is ignored.
-     *                 The z value can be used to determine the accuracy to 
calculate the terrain height at.  If the location is far above (or below) the 
ground,
-     *                 less accuracy is needed, while if it is close to the 
ground, greater accuracy is needed.
+     *                 The z value can be used to determine the accuracy to 
calculate the terrain height at.
+     *                 If the location is far above (or below) the ground, 
less accuracy is needed, while if
+     *                 it is close to the ground, greater accuracy is needed.
      *
      * @return the terrain height at the specified location.
      */

Modified: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java
     2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java
     2008-04-27 00:02:04 UTC (rev 485)
@@ -1,6 +1,7 @@
 package org.skycastle.opengl.navigationgestures;
 
 
+import jpen.event.PenListener;
 import org.skycastle.util.cursor.CursorChanger;
 
 import javax.swing.event.MouseInputListener;
@@ -13,24 +14,27 @@
  * @author Hans H�ggstr�m
  */
 public interface NavigationGesture
-        extends MouseInputListener, MouseWheelListener
+        extends MouseInputListener, MouseWheelListener, PenListener
 {
 
     /**
      * Initializes the navigation gesture.
      *
-     * @param component      the component that the gesture should listen to.  
Can be asked e.g. the size and position.
-     *                       Might also be used to add rubber band graphics or 
similar on top of the component
-     * @param cursorChanger  an interface that can be used to change the mouse 
cursor on the 3D canvas rendered to.
-     * @param cameraAccessor Can be asked for the camera that the navigation 
gesture listener should modify when gestures happen.
+     * @param component      the component that the gesture should listen to.  
Can be asked e.g. the size and
+     *                       position. Might also be used to add rubber band 
graphics or similar on top of the
+     *                       component
+     * @param cursorChanger  an interface that can be used to change the mouse 
cursor on the 3D canvas
+     *                       rendered to.
+     * @param cameraAccessor Can be asked for the camera that the navigation 
gesture listener should modify
+     *                       when gestures happen.
      */
     void init( Component component,
                CursorChanger cursorChanger,
                CameraAccessor cameraAccessor );
 
     /**
-     * De-initializes the navigation gesture.  The navigation gesture should 
stop listening to the component, and should
-     * remove its cursor settings.
+     * De-initializes the navigation gesture.  The navigation gesture should 
stop listening to the component,
+     * and should remove its cursor settings.
      */
     void deInit();
 

Deleted: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java
===================================================================
--- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java 
2008-04-26 20:42:11 UTC (rev 484)
+++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java 
2008-04-27 00:02:04 UTC (rev 485)
@@ -1,75 +0,0 @@
-package org.skycastle.sketch;
-
-import jpen.*;
-import jpen.event.PenListener;
-
-import javax.swing.*;
-
-/**
- * @author Hans Haggstrom
- */
-public class PenInput
-        implements PenListener
-{
-
-    //----------------------------------------------------------------------
-    // Main Method
-
-    public static void main( String... args )
-    {
-        new PenInput();
-    }
-
-    //----------------------------------------------------------------------
-    // Constructors
-
-    PenInput()
-    {
-        JLabel l = new JLabel( "Move the pen or mouse over me!" );
-        PenManager pm = new PenManager( l );
-        pm.pen.addListener( this );
-
-        JFrame f = new JFrame( "JPen Example" );
-        f.getContentPane().add( l );
-        f.setSize( 300, 300 );
-        f.setVisible( true );
-    }
-
-    //----------------------------------------------------------------------
-    // PenListener Implementation
-
-    @Override
-    public void penKindEvent( PKindEvent
-            ev )
-    {
-        System.out.println( ev );
-    }
-
-    @Override
-    public void penLevelEvent( PLevelEvent
-            ev )
-    {
-        System.out.println( ev );
-    }
-
-    @Override
-    public void penButtonEvent( PButtonEvent
-            ev )
-    {
-        System.out.println( ev );
-    }
-
-    @Override
-    public void penScrollEvent( PScrollEvent
-            ev )
-    {
-        System.out.println( ev );
-    }
-
-    @Override
-    public void penTock( long availableMillis )
-    {
-        System.out.println( "TOCK - available period fraction: " + 
availableMillis );
-    }
-
-}

Deleted: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java   
    2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java   
    2008-04-27 00:02:04 UTC (rev 485)
@@ -1,279 +0,0 @@
-package org.skycastle.sketch;
-
-import com.jme.app.SimpleGame;
-import com.jme.bounding.BoundingBox;
-import com.jme.image.Texture;
-import com.jme.input.*;
-import com.jme.math.Vector3f;
-import com.jme.renderer.ColorRGBA;
-import com.jme.renderer.Renderer;
-import com.jme.scene.Controller;
-import com.jme.scene.Node;
-import com.jme.scene.SceneElement;
-import com.jme.scene.shape.Box;
-import com.jme.scene.state.LightState;
-import com.jme.scene.state.TextureState;
-import com.jme.util.TextureManager;
-import com.jmex.awt.swingui.JMEDesktop;
-
-import javax.swing.*;
-import javax.swing.plaf.basic.BasicInternalFrameUI;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Container;
-import java.beans.PropertyVetoException;
-import java.util.logging.Logger;
-
-/**
- * OpenGL main loop for the sketch program.
- *
- * @author Hans Haggstrom
- */
-@SuppressWarnings( { "MagicNumber" } )
-public class Sketch3DUI
-        extends SimpleGame
-{
-
-    //======================================================================
-    // Private Fields
-
-    /**
-     * Keyboard look input handler.
-     */
-    private KeyboardLookHandler lookHandler = null;
-
-    /**
-     * Scene node for the GUI.
-     */
-    private Node guiNode = null;
-
-    /**
-     * JME desktop on which the GUI will be shown.
-     */
-    private JMEDesktop desktop = null;
-
-    //======================================================================
-    // Non-Private Fields
-
-    /**
-     * The color to be used as background color for the desktop. This is 
completely transparent right now.
-     */
-    protected static final Color DESKTOP_BACKGROUND_COLOR = new Color( 0.5f, 
0.5f, 0.5f, 0.0f );
-
-    //======================================================================
-    // Private Constants
-
-    private static final Logger LOGGER = Logger.getLogger( 
Sketch3DUI.class.getName() );
-
-    //======================================================================
-    // Public Methods
-
-    //----------------------------------------------------------------------
-    // Other Public Methods
-
-    /**
-     * Set up key bindings.
-     */
-    public void initKeyBindings()
-    {
-        /* Remove some keybindings established by BaseSimpleGame, since they
-           are needed for chatting.
-           TODO: Find a more elegant solution. Maybe bind/rebind depending on
-                 focus, or handling these during update.
-                 Eventually, we may also need to implement our own base game
-                 class.
-         */
-        KeyBindingManager.getKeyBindingManager().remove( "toggle_pause" );
-        KeyBindingManager.getKeyBindingManager().remove( "step" );
-        KeyBindingManager.getKeyBindingManager().remove( "toggle_wire" );
-        KeyBindingManager.getKeyBindingManager().remove( "toggle_lights" );
-        KeyBindingManager.getKeyBindingManager().remove( "toggle_bounds" );
-        KeyBindingManager.getKeyBindingManager().remove( "toggle_normals" );
-        KeyBindingManager.getKeyBindingManager().remove( "camera_out" );
-        KeyBindingManager.getKeyBindingManager().remove( "mem_report" );
-
-        // Bind the BaseSimpleGame functions to other keys.
-        KeyBindingManager.getKeyBindingManager().set( "toggle_pause", 
KeyInput.KEY_F4 );
-        KeyBindingManager.getKeyBindingManager().set( "step", KeyInput.KEY_F5 
);
-        KeyBindingManager.getKeyBindingManager().set( "toggle_wire", 
KeyInput.KEY_F6 );
-        KeyBindingManager.getKeyBindingManager().set( "toggle_lights", 
KeyInput.KEY_F7 );
-        KeyBindingManager.getKeyBindingManager().set( "toggle_bounds", 
KeyInput.KEY_F8 );
-        KeyBindingManager.getKeyBindingManager().set( "toggle_normals", 
KeyInput.KEY_F9 );
-        KeyBindingManager.getKeyBindingManager().set( "camera_out", 
KeyInput.KEY_F10 );
-        KeyBindingManager.getKeyBindingManager().set( "mem_report", 
KeyInput.KEY_F11 );
-    }
-
-    //======================================================================
-    // Protected Methods
-
-    /**
-     * Create the UI. Create the elements of the Swing UI.
-     */
-    protected void initUI()
-    {
-        /// JME part of the GUI creation.
-        guiNode = new Node( "gui" );
-        guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO );
-
-        desktop = new JMEDesktop(
-                "desktop",
-                display.getWidth(),
-                display.getHeight(),
-                input
-        );
-        guiNode.attachChild( desktop );
-        desktop.getLocalTranslation().set(
-                display.getWidth() / 2.0f,
-                display.getHeight() / 2.0f, 0
-        );
-
-        // AWT/Swing part of the GUI creation.
-        desktop.getJDesktop().setBackground( DESKTOP_BACKGROUND_COLOR );
-
-
-        JInternalFrame toolFrame = new JInternalFrame();
-//        toolFrame.setLocation( 10, 10 );
-//        toolFrame.setResizable( true );
-
-        toolFrame.setOpaque( false );
-        Container contentPane = toolFrame.getContentPane();
-        contentPane.setLayout( new BorderLayout() );
-        contentPane.setBackground( new Color( 0, 0, 0, 0 ) );
-
-        contentPane.add( new JLabel( "foo" ), BorderLayout.EAST );
-        contentPane.add( createNorthPanel(), BorderLayout.NORTH );
-
-        toolFrame.setBorder( BorderFactory.createEmptyBorder() );
-        toolFrame.setTitle( null );
-
-        toolFrame.setVisible( true );
-        toolFrame.pack();
-
-        final BasicInternalFrameUI basicInternalFrameUI = 
(BasicInternalFrameUI) toolFrame.getUI();
-        basicInternalFrameUI.setNorthPane( null );
-
-        desktop.getJDesktop().add( toolFrame );
-
-/*
-        toolFrame.putClientProperty(  );
-
-        a) internalFrame.putClientProperty("JInternalFrame.isPalette", 
Boolean.TRUE);
-*/
-
-/*
-        final JLabel jLabel = new JLabel( "fooo" );
-
-        jLabel.setForeground( Color.WHITE );
-        jDesktopPane.setLayout( new BorderLayout() );
-        jDesktopPane.add( jLabel, BorderLayout.CENTER );
-*/
-        try
-        {
-            toolFrame.setMaximum( true );
-        }
-        catch ( PropertyVetoException e )
-        {
-            e.printStackTrace();
-        }
-    }
-
-    private JComponent createNorthPanel()
-    {
-        SketchToolbarFactory sketchFactory = new SketchToolbarFactory();
-        return sketchFactory.createToolbar();
-    }
-
-
-    /**
-     * Create the 3D scene. In this case, this is just the rotating box.
-     */
-    protected void create3DScene()
-    {
-        final Vector3f axis = new Vector3f( 1, 1, 0.5f ).normalizeLocal();
-        final Box box = new Box( "Box",
-                                 new Vector3f( -5, -5, -5 ),
-                                 new Vector3f( 5, 5, 5 ) );
-
-        box.setModelBound( new BoundingBox() );
-        box.updateModelBound();
-        box.setLocalTranslation( new Vector3f( 0, 0, -10 ) );
-        box.setLightCombineMode( LightState.OFF );
-
-        TextureState ts = display.getRenderer().createTextureState();
-        ts.setEnabled( true );
-        ts.setTexture( TextureManager.loadTexture(
-                Sketch3DUI.class.getClassLoader().getResource(
-                        "org/skycastle/client/data/skycastle.png" ),
-                Texture.MM_LINEAR,
-                Texture.FM_LINEAR )
-        );
-        box.setRenderState( ts );
-        box.addController(
-                // Controller which rotates the box.
-                new Controller()
-                {
-
-                    private static final long serialVersionUID = 1L;
-
-                    @Override
-                    public void update( float time )
-                    {
-                        box.getLocalRotation().fromAngleNormalAxis(
-                                timer.getTimeInSeconds(), axis );
-                    }
-
-                }
-        );
-
-        rootNode.attachChild( box );
-    }
-
-
-    /**
-     * Initialize game. Overridden from SimpleGame.
-     */
-    @Override
-    protected void simpleInitGame()
-    {
-        display.setTitle( "Skycastle 3D Client" );
-        display.getRenderer().setBackgroundColor( ColorRGBA.black );
-
-        // Set up the keyboard look handler.
-        input = new InputHandler();
-        lookHandler = new KeyboardLookHandler( cam, 50, 1 );
-        input.addToAttachedHandlers( lookHandler );
-        // Some changes to the BaseSimpleGame keyboard bindings.
-        initKeyBindings();
-
-        // Set up GUI, static 3D scene and chat client.
-        initUI();
-        create3DScene();
-
-        // Always show the the GUI.
-        guiNode.setCullMode( SceneElement.CULL_NEVER );
-        guiNode.setLightCombineMode( LightState.OFF );
-        guiNode.updateRenderState();
-        guiNode.updateGeometricState( 0, true );
-        MouseInput.get().setCursorVisible( true );
-    }
-
-
-    /**
-     * Update hook. Overridden from SimpleGame.
-     */
-    @Override
-    protected void simpleUpdate()
-    {
-    }
-
-
-    /**
-     * Render hook. Overridden from SimpleGame.
-     */
-    @Override
-    protected void simpleRender()
-    {
-        display.getRenderer().draw( guiNode );
-    }
-
-}

Modified: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java
 2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java
 2008-04-27 00:02:04 UTC (rev 485)
@@ -15,8 +15,8 @@
 /**
  * @author Hans Häggström
  */
-@SuppressWarnings( { "serial" } )
-public class SketchController
+@SuppressWarnings( { "serial", "NonSerializableFieldInSerializableClass" } )
+public final class SketchController
 {
 
     //======================================================================
@@ -56,49 +56,60 @@
 
     };
 
-    private SketchView mySketchView;
+/*
+    private final CommandAction myAddTestStrokeAction = new CommandAction( 
myCommandStack,
+                                                                           
"Test Stroke",
+                                                                           
"Add Test Stroke" )
+    {
 
-    private Sketch mySketch;
+        private final Group myGroup = mySketch.getRootGroup();
 
-    //======================================================================
-    // Private Constants
+        {
+            ParameterChecker.checkNotNull( mySketch.getRootGroup(), "group" );
+        }
 
-    private static final String APP_NAME = "Sketch Room";
-    private final CommandAction myAddTestStrokeAction = new CommandAction( 
myCommandStack,
-                                                                           
"Test Stroke",
-                                                                           
"Adds a random test stroke to the Sketch" )
-    {
         @Override
         protected Command createCommand()
         {
-            final Stroke testStroke = createTestStroke();
+            final Stroke stroke = createTestStroke();
 
-            return new AbstractCommand( "Test Stroke", true )
+            return new AbstractCommand( "Stroke", true )
             {
 
                 public void doCommand()
                 {
-                    mySketch.getRootGroup().add( testStroke );
+                    myGroup.add( stroke );
                 }
 
+
                 @Override
                 public void undoCommand()
                 {
-                    mySketch.getRootGroup().remove( testStroke );
+                    myGroup.remove( stroke );
                 }
+
             };
         }
+
     };
+*/
 
+    private SketchView mySketchView;
+
+    private Sketch mySketch;
+
     //======================================================================
+    // Private Constants
+
+    private static final String APP_NAME = "Sketch Room";
+    private static final Logger LOGGER = Logger.getLogger( 
SketchController.class.getName() );
+
+    //======================================================================
     // Public Methods
 
     //----------------------------------------------------------------------
     // Constructors
 
-    private static final Logger LOGGER = Logger.getLogger( 
SketchController.class.getName() );
-
-
     /**
      * Creates a new {@link org.skycastle.sketch.SketchController}.
      */
@@ -125,32 +136,51 @@
         mySketchView.addMenuAction( "File", myExitAction );
         mySketchView.addMenuAction( "Edit", myCommandStack.getUndoAction() );
         mySketchView.addMenuAction( "Edit", myCommandStack.getRedoAction() );
+/*
         mySketchView.addMenuAction( "Debug", myAddTestStrokeAction );
 
         mySketchView.addToolbarAction( myAddTestStrokeAction );
+*/
         mySketchView.addToolbarAction( myCommandStack.getUndoAction() );
         mySketchView.addToolbarAction( myCommandStack.getRedoAction() );
 
+        mySketchView.addNavigationGesture( new StrokeTool( 
mySketch.getRootGroup(), myCommandStack ) );
+
         mySketchView.setSketch( mySketch );
     }
 
+    //======================================================================
+    // Private Methods
 
     private Stroke createTestStroke()
     {
         final StrokeImpl stroke = new StrokeImpl();
 
         final Random random = new Random();
-        float x = (float) ( random.nextGaussian() * 100 );
-        float y = (float) ( random.nextGaussian() * 100 );
+        float x = (float) ( random.nextGaussian() * 10 );
+        float y = (float) ( random.nextGaussian() * 10 );
+        float w = (float) ( 1 );
 
-        for ( int i = 0; i < 100; i++ )
+        float xv = 0;
+        float yv = 0;
+        float wv = 0;
+
+        for ( int i = 0; i < 1000; i++ )
         {
-            x += random.nextGaussian() * 10;
-            y += random.nextGaussian() * 10;
+            xv += random.nextGaussian() * 0.1;
+            yv += random.nextGaussian() * 0.1;
+            wv += random.nextGaussian() * 0.01;
 
-            stroke.addPoint( new StrokePointImpl( x, y ) );
+            x += xv;
+            y += yv;
+            w += wv;
+
+            final StrokePointImpl strokePoint = new StrokePointImpl( x, y );
+            strokePoint.setProperty( "width", w );
+            stroke.addPoint( strokePoint );
         }
 
         return stroke;
     }
+
 }

Deleted: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java
   2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java
   2008-04-27 00:02:04 UTC (rev 485)
@@ -1,21 +0,0 @@
-package org.skycastle.sketch;
-
-import org.skycastle.sketch.model.Sketch;
-
-/**
- * Helps with rendering a {@link Sketch}.
- *
- * @author Hans Häggström
- */
-public class SketchRenderer
-{
-
-    /**
-     * Creates a new {@link org.skycastle.sketch.SketchRenderer}.
-     */
-    public SketchRenderer()
-    {
-    }
-
-
-}

Deleted: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java
     2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java
     2008-04-27 00:02:04 UTC (rev 485)
@@ -1,60 +0,0 @@
-package org.skycastle.sketch;
-
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-
-/**
- * @author Hans Haggstrom
- */
-public class SketchToolbarFactory
-{
-
-    public JToolBar createToolbar()
-    {
-        final JToolBar toolBar = new JToolBar();
-        toolBar.add( new JButton( new AbstractAction( "Quit" )
-        {
-
-            public void actionPerformed( final ActionEvent e )
-            {
-                System.exit( 0 );
-            }
-
-        } ) );
-        toolBar.add( new JButton( new AbstractAction( "New Page" )
-        {
-
-            public void actionPerformed( final ActionEvent e )
-            {
-            }
-
-        } ) );
-        toolBar.add( new JButton( new AbstractAction( "Zoom Out" )
-        {
-
-            public void actionPerformed( final ActionEvent e )
-            {
-            }
-
-        } ) );
-        toolBar.add( new JButton( new AbstractAction( "Zoom In" )
-        {
-
-            public void actionPerformed( final ActionEvent e )
-            {
-            }
-
-        } ) );
-        toolBar.add( new JButton( new AbstractAction( "Zoom to show all" )
-        {
-
-            public void actionPerformed( final ActionEvent e )
-            {
-            }
-
-        } ) );
-
-        toolBar.setVisible( true );
-        return toolBar;
-    }
-}

Modified: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java   
    2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java   
    2008-04-27 00:02:04 UTC (rev 485)
@@ -36,12 +36,12 @@
 
     private final Map<String, Menu> myMenus = new HashMap<String, Menu>( 10 );
     private final SimpleFrame myMainFrame;
+    private final Node myRoot3DNode;
 
     private Canvas3D myCanvas3D;
     private JToolBar myToolBar;
     private MenuBar myMenuBar;
     private Sketch mySketch;
-    private final Node myRoot3DNode;
 
     //======================================================================
     // Public Methods
@@ -52,7 +52,7 @@
     /**
      * Creates a new {@link org.skycastle.sketch.SketchView}.
      */
-    public SketchView( String applicationName )
+    public SketchView( final String applicationName )
     {
         ParameterChecker.checkNotNull( applicationName, "applicationName" );
 
@@ -63,7 +63,9 @@
         myCanvas3D.removeAllNavigationGestures();
         myRoot3DNode = new Node( "SketchView_RootNode" );
         myCanvas3D.set3DNode( myRoot3DNode );
+        myCanvas3D.setBackgroundColor( Color.WHITE );
 
+
         final JPanel panel = new JPanel( new BorderLayout() );
         panel.add( myCanvas3D.get3DView(), BorderLayout.CENTER );
         panel.add( myToolBar, BorderLayout.NORTH );
@@ -87,6 +89,7 @@
     //----------------------------------------------------------------------
     // Other Public Methods
 
+
     /**
      * @param closeAction an action that is called when the close button of 
the main window is pressed, or the
      *                    application is attempted to be closed in some other 
way.
@@ -209,9 +212,11 @@
 
         reRender( sketch );
 
+        //noinspection serial
         sketch.getRootGroup().addGroupListener( new 
CollectionListener<GroupElement>()
         {
-            public void onElementAdded( final 
ListenableCollection<GroupElement> groupElementListenableCollection,
+
+            public void onElementAdded( final 
ListenableCollection<GroupElement> collection,
                                         final GroupElement addedElement )
             {
                 // TODO: Instead of this, just modify the 3D object for the 
stroke that was changed,
@@ -219,16 +224,21 @@
                 reRender( sketch );
             }
 
-            public void onElementRemoved( final 
ListenableCollection<GroupElement> groupElementListenableCollection,
+
+            public void onElementRemoved( final 
ListenableCollection<GroupElement> collection,
                                           final GroupElement removedElement )
             {
                 // TODO: Instead of this, just modify the 3D object for the 
stroke that was changed,
                 // or add a new one, or remove an removed one.
                 reRender( sketch );
             }
+
         } );
     }
 
+    //======================================================================
+    // Private Methods
+
     private void reRender( final Sketch sketch )
     {
         // Clean out old nodes (NOTE: detach all is usually a bit buggy / 
weird.. )
@@ -237,6 +247,7 @@
         renderGroup( sketch.getRootGroup() );
     }
 
+
     private void renderGroup( final Group group )
     {
         for ( final GroupElement groupElement : group.getElements() )
@@ -246,7 +257,13 @@
             if ( groupElement instanceof Stroke )
             {
                 final Stroke stroke = (Stroke) groupElement;
-                myRoot3DNode.attachChild( new StrokeRenderer( stroke ) );
+
+                // TODO: add capability to render points.
+                if ( stroke.getPoints().size() >= 2 )
+                {
+                    myRoot3DNode.attachChild( new StrokeRenderer( stroke ) );
+                }
+
             }
             else if ( groupElement instanceof Group )
             {
@@ -255,8 +272,6 @@
         }
     }
 
-    //======================================================================
-    // Private Methods
 
     private Menu getOrCreateMenu( final String menuName )
     {

Modified: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java
  2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java
  2008-04-27 00:02:04 UTC (rev 485)
@@ -1,36 +1,13 @@
 package org.skycastle.sketch;
 
-import com.jme.bounding.BoundingBox;
-import com.jme.math.Vector3f;
-import com.jme.scene.Controller;
-import com.jme.scene.Spatial;
-import com.jme.scene.shape.Box;
-import com.jme.scene.state.LightState;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
 /**
  * A simple sketch program, supporting a pen tablet as input, and running in 
opengl.
  *
  * @author Hans Haggstrom
  */
-public class SkycastleSketch
+public final class SkycastleSketch
 {
 
-    //======================================================================
-    // Private Fields
-
-    private static float myBoxRotationCounter = 0;
-
-    //======================================================================
-    // Private Constants
-
-    private static final Logger LOGGER = Logger.getLogger( 
SkycastleSketch.class.getName() );
-
-    //======================================================================
-    // Public Methods
-
     //----------------------------------------------------------------------
     // Main Method
 
@@ -39,74 +16,20 @@
      */
     public static void main( String[] args )
     {
-
-        // Do not show logging output below the WARNING level (JME outputs a 
lot of debugging info at INFO level).
+        // TODO: Do not show logging output below the WARNING level (JME 
outputs a lot of debugging info at INFO level).
         // This way the console output is a bit more relevant.
-        LOGGER.setLevel( Level.WARNING );
 
 
         final SketchController sketchController = new SketchController();
 
         sketchController.start();
-
-/*
-        Sketch3DUI sketch3DUI = new Sketch3DUI();
-        sketch3DUI.start();
-*/
     }
 
     //======================================================================
     // Private Methods
 
-
-    /**
-     * Create the 3D scene. In this case, this is just the rotating box.
-     */
-    private static Spatial create3DScene()
+    private SkycastleSketch()
     {
-        final Vector3f axis = new Vector3f( 1, 1, 0.5f ).normalizeLocal();
-        final Box box = new Box( "Box",
-                                 new Vector3f( 5, 5, 5 ),
-                                 new Vector3f( -5, -5, -5 ) );
-
-        box.setModelBound( new BoundingBox() );
-        box.updateModelBound();
-        box.setLocalTranslation( new Vector3f( 0, 0, -10 ) );
-        box.setLightCombineMode( LightState.OFF );
-
-        box.setRandomColors();
-
-/*
-        TextureState ts = 
DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
-        ts.setEnabled( true );
-        ts.setTexture( TextureManager.loadTexture(
-                Sketch3DUI.class.getClassLoader().getResource(
-                        "org/skycastle/client/data/skycastle.png" ),
-                Texture.MM_LINEAR,
-                Texture.FM_LINEAR )
-        );
-        box.setRenderState( ts );
-*/
-
-        box.addController(
-                // Controller which rotates the box.
-                new Controller()
-                {
-
-                    private static final long serialVersionUID = 1L;
-
-                    @Override
-                    public void update( float time )
-                    {
-                        myBoxRotationCounter += time;
-                        box.getLocalRotation().fromAngleNormalAxis(
-                                myBoxRotationCounter, axis );
-                    }
-
-                }
-        );
-
-        return box;
     }
 
 }

Modified: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java
   2008-04-26 20:42:11 UTC (rev 484)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java
   2008-04-27 00:02:04 UTC (rev 485)
@@ -6,8 +6,13 @@
 import com.jme.math.Vector2f;
 import com.jme.math.Vector3f;
 import com.jme.renderer.ColorRGBA;
+import com.jme.renderer.Renderer;
 import com.jme.scene.TriMesh;
+import com.jme.scene.state.AlphaState;
 import com.jme.scene.state.TextureState;
+import com.jme.system.DisplaySystem;
+import com.jme.util.GameTaskQueue;
+import com.jme.util.GameTaskQueueManager;
 import com.jme.util.TextureManager;
 import com.jme.util.geom.BufferUtils;
 import com.jmex.awt.swingui.ImageGraphics;
@@ -19,12 +24,15 @@
 import java.awt.image.BufferedImage;
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
+import java.util.concurrent.Callable;
 
 /**
+ * A 3D node that renders a {@link Stroke}.
+ *
  * @author Hans Häggström
  */
 @SuppressWarnings( { "serial" } )
-public class StrokeRenderer
+public final class StrokeRenderer
         extends TriMesh
 {
 
@@ -88,6 +96,7 @@
         this( stroke, 0 );
     }
 
+
     /**
      * Creates a new {@link org.skycastle.sketch.StrokeRenderer}.
      *
@@ -124,7 +133,35 @@
         // Stich together the vertices into triangles
         initializeIndices();
 
+
         updateBounds();
+
+
+        GameTaskQueueManager.getManager().getQueue( GameTaskQueue.UPDATE 
).enqueue( new Callable<Object>()
+        {
+
+            public Object call() throws Exception
+            {
+                final Renderer renderer = 
DisplaySystem.getDisplaySystem().getRenderer();
+
+                final StrokeRenderer strokeRenderer = StrokeRenderer.this;
+
+                // strokeRenderer.setRenderQueueMode( 
Renderer.QUEUE_TRANSPARENT );
+                final AlphaState alphaState = renderer.createAlphaState();
+                alphaState.setBlendEnabled( true );
+                alphaState.setSrcFunction( AlphaState.SB_SRC_ALPHA );
+                alphaState.setDstFunction( AlphaState.DB_ONE_MINUS_SRC_ALPHA );
+                alphaState.setTestEnabled( false );
+                alphaState.setEnabled( true );
+
+                strokeRenderer.setRenderState( alphaState );
+                strokeRenderer.updateRenderState();
+
+                return null;
+            }
+
+        } );
+
     }
 
     //----------------------------------------------------------------------
@@ -249,15 +286,15 @@
 
         final Vector3f positionLeft = new Vector3f( xPos, yPos + width, zPos );
         final ColorRGBA colorLeft = strokePoint.getProperty( "color",
-                                                             new ColorRGBA( 
0.1f, 0.1f, 0.1f, 1.0f ) );
+                                                             new ColorRGBA( 0, 
0, 0, 0 ) );
 
         final Vector3f positionMid = new Vector3f( xPos, yPos, zPos );
         final ColorRGBA colorMid = strokePoint.getProperty( "color",
-                                                            new ColorRGBA( 
0.5f, 0.5f, 0.5f, 1.0f ) );
+                                                            new ColorRGBA( 0, 
0, 0, 1 ) );
 
         final Vector3f positionRight = new Vector3f( xPos, yPos - width, zPos 
);
         final ColorRGBA colorRight = strokePoint.getProperty( "color",
-                                                              new ColorRGBA( 
0.1f, 0.1f, 0.1f, 1.0f ) );
+                                                              new ColorRGBA( 
0, 0, 0, 0 ) );
 
         setPointData( index + 0, positionLeft, colorLeft );
         setPointData( index + 1, positionMid, colorMid );

Added: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java   
                            (rev 0)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java   
    2008-04-27 00:02:04 UTC (rev 485)
@@ -0,0 +1,189 @@
+package org.skycastle.sketch;
+
+import jpen.PButton;
+import jpen.PButtonEvent;
+import jpen.PLevel;
+import jpen.PLevelEvent;
+import org.skycastle.opengl.navigationgestures.AbstractNavigationGesture;
+import org.skycastle.sketch.model.group.Group;
+import org.skycastle.sketch.model.point.StrokePointImpl;
+import org.skycastle.sketch.model.stroke.Stroke;
+import org.skycastle.sketch.model.stroke.StrokeImpl;
+import org.skycastle.util.command.AbstractCommand;
+import org.skycastle.util.command.CommandStack;
+
+/**
+ * @author Hans Haggstrom
+ */
+public class StrokeTool
+        extends AbstractNavigationGesture
+{
+
+    //======================================================================
+    // Private Fields
+
+    private final CommandStack myCommandStack;
+    private Group myGroup;
+
+    private boolean myStrokeActive = false;
+
+    private float myStrokeX;
+    private float myStrokeY;
+    private float myStrokePressure;
+    private float myStrokeTiltX;
+    private float myStrokeTiltY;
+
+    private Stroke myStroke;
+
+    //======================================================================
+    // Public Methods
+
+    //----------------------------------------------------------------------
+    // Constructors
+
+    StrokeTool( final CommandStack commandStack )
+    {
+        super( 1 );
+        myCommandStack = commandStack;
+    }
+
+    StrokeTool( final Group group, final CommandStack commandStack )
+    {
+        super( 1 );
+
+        myGroup = group;
+        myCommandStack = commandStack;
+    }
+
+    //----------------------------------------------------------------------
+    // PenListener Implementation
+
+    @Override
+    public void penLevelEvent( final PLevelEvent ev )
+    {
+        if ( myStrokeActive )
+        {
+            for ( final PLevel level : ev.levels )
+            {
+                switch ( level.getType() )
+                {
+                    case X:
+                        myStrokeX = level.value;
+                        break;
+                    case Y:
+                        myStrokeY = level.value;
+                        break;
+                    case PRESSURE:
+                        myStrokePressure = level.value;
+                        break;
+                    case TILT_X:
+                        myStrokeTiltX = level.value;
+                        break;
+                    case TILT_Y:
+                        myStrokeTiltY = level.value;
+                        break;
+                    default:
+                }
+            }
+
+            addStrokeEvent( ev.getTime() );
+        }
+    }
+
+
+    @Override
+    public void penButtonEvent( final PButtonEvent ev )
+    {
+        if ( ev.button.getType() == PButton.Type.LEFT )
+        {
+            final Boolean pressed = ev.button.value;
+
+            if ( pressed )
+            {
+                startStroke();
+            }
+            else
+            {
+                endStroke();
+            }
+        }
+    }
+
+    //----------------------------------------------------------------------
+    // Other Public Methods
+
+    public Group getGroup()
+    {
+        return myGroup;
+    }
+
+
+    public void setGroup( final Group group )
+    {
+        endStroke();
+
+        myGroup = group;
+    }
+
+    //======================================================================
+    // Private Methods
+
+    private void addStrokeEvent( final long time )
+    {
+        if ( myStrokeActive )
+        {
+            // TODO: Get correct offset and scale (and rotation?) from camera 
to apply to the coordinates to
+            // project them to the canvas space.
+            final float x = myStrokeX + getCamera().getLocation().getX();
+            final float y = myStrokeY + getCamera().getLocation().getY();
+            final StrokePointImpl strokePoint = new StrokePointImpl( x, y );
+            strokePoint.setProperty( "tiltX", myStrokeTiltX );
+            strokePoint.setProperty( "tiltY", myStrokeTiltY );
+            strokePoint.setProperty( "pressure", myStrokePressure );
+            strokePoint.setProperty( "time", time );
+
+            myStroke.addPoint( strokePoint );
+        }
+    }
+
+
+    private void endStroke()
+    {
+        if ( myStrokeActive )
+        {
+            if ( myGroup != null )
+            {
+                final Stroke stroke = myStroke;
+                final Group group = myGroup;
+
+                myCommandStack.invoke( new AbstractCommand( "Stroke", true )
+                {
+                    public void doCommand()
+                    {
+                        group.add( stroke );
+
+                    }
+
+                    @Override
+                    public void undoCommand()
+                    {
+                        group.remove( stroke );
+
+                    }
+                } );
+
+            }
+
+            myStrokeActive = false;
+            myStroke = null;
+        }
+    }
+
+
+    private void startStroke()
+    {
+        myStrokeActive = true;
+        myStroke = new StrokeImpl();
+    }
+
+}

Copied: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java
 (from rev 481, 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java)
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java
                          (rev 0)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java
  2008-04-27 00:02:04 UTC (rev 485)
@@ -0,0 +1,147 @@
+package org.skycastle.sketch.old;
+
+import jpen.*;
+import jpen.event.PenListener;
+
+import javax.swing.*;
+
+/**
+ * @author Hans Haggstrom
+ */
+public class JPenExample
+        implements PenListener
+{
+
+    //----------------------------------------------------------------------
+    // Main Method
+
+    public static void main( String... args )
+    {
+        new JPenExample();
+    }
+
+    //----------------------------------------------------------------------
+    // Constructors
+
+    JPenExample()
+    {
+/*
+        JLabel l = new JLabel( "Move the pen or mouse over me!" );
+        PenManager pm = new PenManager( l );
+        pm.pen.addListener( this );
+
+        JFrame f = new JFrame( "JPen Example" );
+        f.getContentPane().add( l );
+        f.setSize( 300, 300 );
+        f.setVisible( true );
+*/
+
+        JLabel l = new JLabel( "Move the pen or mouse over me!" );
+        PenManager pm = new PenManager( l );
+        printSysInfo( pm ); // INSERTED LINE
+
+        pm.pen.addListener( this );
+
+        JFrame f = new JFrame( "JPen Example" );
+        f.getContentPane().add( l );
+        f.setSize( 300, 300 );
+        f.setVisible( true );
+    }
+
+    //----------------------------------------------------------------------
+    // Static Methods
+
+    static void printSysInfo( PenManager pm )
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append( "vvv JPen - System Info vvv" );
+        sb.append( "\n* Date: " + new java.util.Date() );
+        sb.append( "\n* JPen Version: " + jpen.provider.Utils.getDistVersion() 
);
+        sb.append( "\n* System Properties:" );
+        for ( Object propertyName : System.getProperties().keySet() )
+        {
+            sb.append( "\n\t - " + propertyName + " = " + System.getProperty( 
propertyName.toString() ) );
+        }
+        for ( PenProvider.Constructor constructor : pm.getConstructors() )
+        {
+            sb.append( "\n* Constructor: " + constructor.getName() );
+            Exception ex = pm.getConstructionException( constructor );
+            if ( ex != null )
+            {
+                java.io.StringWriter sw = new java.io.StringWriter();
+                java.io.PrintWriter pw = new java.io.PrintWriter( sw );
+                ex.printStackTrace( pw );
+                pw.close();
+                sb.append( "\n\t - Exception: " );
+                sb.append( sw.toString() );
+            }
+            if ( constructor.getName().equals( "System" ) )
+            {
+                for ( jpen.PenDevice device : pm.getProvider( constructor 
).getDevices() )
+                {
+                    device.setEnabled( false );
+                    sb.append( "\n\t - Disabled Device: " + device.getName() );
+                }
+            }
+        }
+        sb.append( "\n^^^ JPen - System Info ^^^\n" );
+
+        String sysInfo = sb.toString();
+        System.out.println( sysInfo );
+
+/*
+        try
+        {
+            java.io.Writer w = new java.io.FileWriter( new java.io.File( 
"JPen-sysInfo.txt" ) );
+            w.write( sysInfo );
+            w.close();
+        }
+        catch ( Exception ex )
+        {
+            ex.printStackTrace();
+        }
+*/
+    }
+
+    //----------------------------------------------------------------------
+    // PenListener Implementation
+
+    @Override
+    public void penKindEvent( PKindEvent
+            ev )
+    {
+        System.out.println( ev );
+    }
+
+
+    @Override
+    public void penLevelEvent( PLevelEvent
+            ev )
+    {
+        System.out.println( ev );
+    }
+
+
+    @Override
+    public void penButtonEvent( PButtonEvent
+            ev )
+    {
+        System.out.println( ev );
+    }
+
+
+    @Override
+    public void penScrollEvent( PScrollEvent
+            ev )
+    {
+        System.out.println( ev );
+    }
+
+
+    @Override
+    public void penTock( long availableMillis )
+    {
+        System.out.println( "TOCK - available period fraction: " + 
availableMillis );
+    }
+
+}

Copied: 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java
 (from rev 483, 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java)
===================================================================
--- 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java
                           (rev 0)
+++ 
trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java
   2008-04-27 00:02:04 UTC (rev 485)
@@ -0,0 +1,280 @@
+package org.skycastle.sketch.old;
+
+import com.jme.app.SimpleGame;
+import com.jme.bounding.BoundingBox;
+import com.jme.image.Texture;
+import com.jme.input.*;
+import com.jme.math.Vector3f;
+import com.jme.renderer.ColorRGBA;
+import com.jme.renderer.Renderer;
+import com.jme.scene.Controller;
+import com.jme.scene.Node;
+import com.jme.scene.SceneElement;
+import com.jme.scene.shape.Box;
+import com.jme.scene.state.LightState;
+import com.jme.scene.state.TextureState;
+import com.jme.util.TextureManager;
+import com.jmex.awt.swingui.JMEDesktop;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicInternalFrameUI;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.beans.PropertyVetoException;
+import java.util.logging.Logger;
+
+/**
+ * OpenGL main loop for the sketch program.
+ *
+ * @author Hans Haggstrom
+ */
+@SuppressWarnings( { "MagicNumber" } )
+public class Sketch3DUI
+        extends SimpleGame
+{
+
+    //======================================================================
+    // Private Fields
+
+    /**
+     * Keyboard look input handler.
+     */
+    private KeyboardLookHandler lookHandler = null;
+
+    /**
+     * Scene node for the GUI.
+     */
+    private Node guiNode = null;
+
+    /**
+     * JME desktop on which the GUI will be shown.
+     */
+    private JMEDesktop desktop = null;
+
+    //======================================================================
+    // Non-Private Fields
+
+    /**
+     * The color to be used as background color for the desktop. This is 
completely transparent right now.
+     */
+    protected static final Color DESKTOP_BACKGROUND_COLOR = new Color( 0.5f, 
0.5f, 0.5f, 0.0f );
+
+    //======================================================================
+    // Private Constants
+
+    private static final Logger LOGGER = Logger.getLogger( 
Sketch3DUI.class.getName() );
+
+    //======================================================================
+    // Public Methods
+
+    //----------------------------------------------------------------------
+    // Other Public Methods
+
+    /**
+     * Set up key bindings.
+     */
+    public void initKeyBindings()
+    {
+        /* Remove some keybindings established by BaseSimpleGame, since they
+           are needed for chatting.
+           TODO: Find a more elegant solution. Maybe bind/rebind depending on
+                 focus, or handling these during update.
+                 Eventually, we may also need to implement our own base game
+                 class.
+         */
+        KeyBindingManager.getKeyBindingManager().remove( "toggle_pause" );
+        KeyBindingManager.getKeyBindingManager().remove( "step" );
+        KeyBindingManager.getKeyBindingManager().remove( "toggle_wire" );
+        KeyBindingManager.getKeyBindingManager().remove( "toggle_lights" );
+        KeyBindingManager.getKeyBindingManager().remove( "toggle_bounds" );
+        KeyBindingManager.getKeyBindingManager().remove( "toggle_normals" );
+        KeyBindingManager.getKeyBindingManager().remove( "camera_out" );
+        KeyBindingManager.getKeyBindingManager().remove( "mem_report" );
+
+        // Bind the BaseSimpleGame functions to other keys.
+        KeyBindingManager.getKeyBindingManager().set( "toggle_pause", 
KeyInput.KEY_F4 );
+        KeyBindingManager.getKeyBindingManager().set( "step", KeyInput.KEY_F5 
);
+        KeyBindingManager.getKeyBindingManager().set( "toggle_wire", 
KeyInput.KEY_F6 );
+        KeyBindingManager.getKeyBindingManager().set( "toggle_lights", 
KeyInput.KEY_F7 );
+        KeyBindingManager.getKeyBindingManager().set( "toggle_bounds", 
KeyInput.KEY_F8 );
+        KeyBindingManager.getKeyBindingManager().set( "toggle_normals", 
KeyInput.KEY_F9 );
+        KeyBindingManager.getKeyBindingManager().set( "camera_out", 
KeyInput.KEY_F10 );
+        KeyBindingManager.getKeyBindingManager().set( "mem_report", 
KeyInput.KEY_F11 );
+    }
+
+    //======================================================================
+    // Protected Methods
+
+    /**
+     * Create the UI. Create the elements of the Swing UI.
+     */
+    protected void initUI()
+    {
+        /// JME part of the GUI creation.
+        guiNode = new Node( "gui" );
+        guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO );
+
+        desktop = new JMEDesktop(
+                "desktop",
+                display.getWidth(),
+                display.getHeight(),
+                input
+        );
+        guiNode.attachChild( desktop );
+        desktop.getLocalTranslation().set(
+                display.getWidth() / 2.0f,
+                display.getHeight() / 2.0f, 0
+        );
+
+        // AWT/Swing part of the GUI creation.
+        desktop.getJDesktop().setBackground( DESKTOP_BACKGROUND_COLOR );
+
+
+        JInternalFrame toolFrame = new JInternalFrame();
+//        toolFrame.setLocation( 10, 10 );
+//        toolFrame.setResizable( true );
+
+        toolFrame.setOpaque( false );
+        Container contentPane = toolFrame.getContentPane();
+        contentPane.setLayout( new BorderLayout() );
+        contentPane.setBackground( new Color( 0, 0, 0, 0 ) );
+
+        contentPane.add( new JLabel( "foo" ), BorderLayout.EAST );
+        contentPane.add( createNorthPanel(), BorderLayout.NORTH );
+
+        toolFrame.setBorder( BorderFactory.createEmptyBorder() );
+        toolFrame.setTitle( null );
+
+        toolFrame.setVisible( true );
+        toolFrame.pack();
+
+        final BasicInternalFrameUI basicInternalFrameUI = 
(BasicInternalFrameUI) toolFrame.getUI();
+        basicInternalFrameUI.setNorthPane( null );
+
+        desktop.getJDesktop().add( toolFrame );
+
+/*
+        toolFrame.putClientProperty(  );
+
+        a) internalFrame.putClientProperty("JInternalFrame.isPalette", 
Boolean.TRUE);
+*/
+
+/*
+        final JLabel jLabel = new JLabel( "fooo" );
+
+        jLabel.setForeground( Color.WHITE );
+        jDesktopPane.setLayout( new BorderLayout() );
+        jDesktopPane.add( jLabel, BorderLayout.CENTER );
+*/
+        try
+        {
+            toolFrame.setMaximum( true );
+        }
+        catch ( PropertyVetoException e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+    private JComponent createNorthPanel()
+    {
+        final JToolBar bar = new JToolBar();
+        bar.add( new JButton( "Foo" ) );
+        return bar;
+    }
+
+
+    /**
+     * Create the 3D scene. In this case, this is just the rotating box.
+     */
+    protected void create3DScene()
+    {
+        final Vector3f axis = new Vector3f( 1, 1, 0.5f ).normalizeLocal();
+        final Box box = new Box( "Box",
+                                 new Vector3f( -5, -5, -5 ),
+                                 new Vector3f( 5, 5, 5 ) );
+
+        box.setModelBound( new BoundingBox() );
+        box.updateModelBound();
+        box.setLocalTranslation( new Vector3f( 0, 0, -10 ) );
+        box.setLightCombineMode( LightState.OFF );
+
+        TextureState ts = display.getRenderer().createTextureState();
+        ts.setEnabled( true );
+        ts.setTexture( TextureManager.loadTexture(
+                Sketch3DUI.class.getClassLoader().getResource(
+                        "org/skycastle/client/data/skycastle.png" ),
+                Texture.MM_LINEAR,
+                Texture.FM_LINEAR )
+        );
+        box.setRenderState( ts );
+        box.addController(
+                // Controller which rotates the box.
+                new Controller()
+                {
+
+                    private static final long serialVersionUID = 1L;
+
+                    @Override
+                    public void update( float time )
+                    {
+                        box.getLocalRotation().fromAngleNormalAxis(
+                                timer.getTimeInSeconds(), axis );
+                    }
+
+                }
+        );
+
+        rootNode.attachChild( box );
+    }
+
+
+    /**
+     * Initialize game. Overridden from SimpleGame.
+     */
+    @Override
+    protected void simpleInitGame()
+    {
+        display.setTitle( "Skycastle 3D Client" );
+        display.getRenderer().setBackgroundColor( ColorRGBA.black );
+
+        // Set up the keyboard look handler.
+        input = new InputHandler();
+        lookHandler = new KeyboardLookHandler( cam, 50, 1 );
+        input.addToAttachedHandlers( lookHandler );
+        // Some changes to the BaseSimpleGame keyboard bindings.
+        initKeyBindings();
+
+        // Set up GUI, static 3D scene and chat client.
+        initUI();
+        create3DScene();
+
+        // Always show the the GUI.
+        guiNode.setCullMode( SceneElement.CULL_NEVER );
+        guiNode.setLightCombineMode( LightState.OFF );
+        guiNode.updateRenderState();
+        guiNode.updateGeometricState( 0, true );
+        MouseInput.get().setCursorVisible( true );
+    }
+
+
+    /**
+     * Update hook. Overridden from SimpleGame.
+     */
+    @Override
+    protected void simpleUpdate()
+    {
+    }
+
+
+    /**
+     * Render hook. Overridden from SimpleGame.
+     */
+    @Override
+    protected void simpleRender()
+    {
+        display.getRenderer().draw( guiNode );
+    }
+
+}


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

Other related posts:

  • » [skycastle-commits] SF.net SVN: skycastle: [485] trunk/skycastle/modules/ui/src/main/java/org/ skycastle