Revision: 489 http://skycastle.svn.sourceforge.net/skycastle/?rev=489&view=rev Author: zzorn Date: 2008-04-27 15:40:12 -0700 (Sun, 27 Apr 2008) Log Message: ----------- Finished an update system that provides a new camera projection to the PenInputHandler when the camera is moved in the SketchView. The camera projection calculation in SketchView seems to be _almost_ right, but for some reason the scaling is not exactly right. Modified Paths: -------------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/InputHandler.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInputHandler.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 Added Paths: ----------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/ProjectionChangeListener.java Removed Paths: ------------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/InputHandler.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/InputHandler.java 2008-04-27 20:55:38 UTC (rev 488) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/InputHandler.java 2008-04-27 22:40:12 UTC (rev 489) @@ -82,6 +82,9 @@ mySketchController = sketchController; ParameterChecker.checkNotNull( penManager, "penManager" ); + // Listen to projection changes + sketchController.getView().addProjectionChangeListener( myPenInputHandler ); + // Convert pen events to DataSamples penManager.pen.addListener( myPenInputHandler ); Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInputHandler.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInputHandler.java 2008-04-27 20:55:38 UTC (rev 488) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInputHandler.java 2008-04-27 22:40:12 UTC (rev 489) @@ -13,9 +13,22 @@ @SuppressWarnings( { "ParameterNameDiffersFromOverriddenParameter" } ) public final class PenInputHandler extends AbstractSampleProducer - implements PenListener + implements PenListener, ProjectionChangeListener { + //====================================================================== + // Private Fields + + private final Object myProjectionLock = new Object(); + + private float myXOffs = 0; + private float myYOffs = 0; + private float myXScale = 1; + private float myYScale = 1; + + //====================================================================== + // Public Methods + //---------------------------------------------------------------------- // Constructors @@ -27,6 +40,24 @@ } //---------------------------------------------------------------------- + // ProjectionChangeListener Implementation + + + public void onProjectionChanged( final float xOffs, + final float yOffs, + final float xScale, + final float yScale ) + { + synchronized ( myProjectionLock ) + { + myXOffs = xOffs; + myYOffs = yOffs; + myXScale = xScale; + myYScale = yScale; + } + } + + //---------------------------------------------------------------------- // PenListener Implementation public void penKindEvent( final PKindEvent ev ) @@ -43,28 +74,31 @@ for ( final PLevel level : event.levels ) { + final float value = level.value; switch ( level.getType() ) { case X: - // TODO: Convert to canvas coordinates - final float x = level.value / 10f; - - dataSample.setVariable( "x", x ); + synchronized ( myProjectionLock ) + { + final float x = value * myXScale + myXOffs; + dataSample.setVariable( "x", x ); + } break; case Y: - // TODO: Convert to canvas coordinates - final float y = level.value / 10f; - - dataSample.setVariable( "y", y ); + synchronized ( myProjectionLock ) + { + final float y = value * myYScale + myYOffs; + dataSample.setVariable( "y", y ); + } break; case PRESSURE: - dataSample.setVariable( "pressure", level.value ); + dataSample.setVariable( "pressure", value ); break; case TILT_X: - dataSample.setVariable( "tiltX", level.value ); + dataSample.setVariable( "tiltX", value ); break; case TILT_Y: - dataSample.setVariable( "tiltY", level.value ); + dataSample.setVariable( "tiltY", value ); break; } } Added: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/ProjectionChangeListener.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/ProjectionChangeListener.java (rev 0) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/ProjectionChangeListener.java 2008-04-27 22:40:12 UTC (rev 489) @@ -0,0 +1,20 @@ +package org.skycastle.sketch; + +/** + * A listener that is notified when the camera projection changes. + * + * @author Hans Haggstrom + */ +public interface ProjectionChangeListener +{ + /** + * The new projection. + * + * @param xOffs + * @param yOffs + * @param xScale + * @param yScale + */ + // TODO: Later replace with a proper conversion matrix, to allow rotation and flips. + void onProjectionChanged( float xOffs, float yOffs, float xScale, float yScale ); +} 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-27 20:55:38 UTC (rev 488) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java 2008-04-27 22:40:12 UTC (rev 489) @@ -218,4 +218,11 @@ return stroke; } + /** + * @return the {@link SketchView} that handles the 3D window and such. + */ + public SketchView getView() + { + return mySketchView; + } } 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-27 20:55:38 UTC (rev 488) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java 2008-04-27 22:40:12 UTC (rev 489) @@ -24,7 +24,9 @@ import java.awt.Color; import java.awt.Component; import java.awt.Frame; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -194,9 +196,26 @@ } ); } + + notifyListenerAboutProjectionChange( myProjectionChangeListenerDelegate ); } + private void notifyListenerAboutProjectionChange( final ProjectionChangeListener listener ) + { + final Component view = myCanvas3D.get3DView(); + if ( view != null ) + { + final float width = view.getWidth(); + final float height = view.getHeight(); + final float scale = myViewSizeHorizontally / width; + listener.onProjectionChanged( myCameraX + 0.5f * width * scale, + myCameraY - 0.5f * height * scale, + -scale, + scale ); + } + } + /** * Rotates the camera. * @@ -409,4 +428,51 @@ return menu; } + private final List<ProjectionChangeListener> myProjectionChangeListeners = new ArrayList<ProjectionChangeListener>(); + + private final ProjectionChangeListener myProjectionChangeListenerDelegate = new ProjectionChangeListener() + { + public void onProjectionChanged( final float xOffs, + final float yOffs, + final float xScale, + final float yScale ) + { + for ( final ProjectionChangeListener listener : myProjectionChangeListeners ) + { + listener.onProjectionChanged( xOffs, yOffs, xScale, yScale ); + } + } + }; + + /** + * @param listener a listener that is notified whenever the projection changes. + */ + public void addProjectionChangeListener( final ProjectionChangeListener listener ) + { + ParameterChecker.checkNotNull( listener, "listener" ); + ParameterChecker.checkNotAlreadyContained( listener, + myProjectionChangeListeners, + "myProjectionChangeListeners" ); + + myProjectionChangeListeners.add( listener ); + + notifyListenerAboutProjectionChange( listener ); + } + + /** + * Removes the specified ProjectionChangeListener. + * + * @param listener should not be null, and should be present. + */ + public void removeProjectionChangeListener( final ProjectionChangeListener listener ) + { + ParameterChecker.checkNotNull( listener, "listener" ); + ParameterChecker.checkContained( listener, + myProjectionChangeListeners, + "myProjectionChangeListeners" ); + + myProjectionChangeListeners.remove( listener ); + } + + } Deleted: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java 2008-04-27 20:55:38 UTC (rev 488) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java 2008-04-27 22:40:12 UTC (rev 489) @@ -1,195 +0,0 @@ -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 float x = myStrokeX / 20f - 30; - final float y = -myStrokeY / 20f + 20; - - - 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(); - } - -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.