replaced JigsawPuzzle#createSource(..) with new inner class
M core/src/net/dermetfan/jigsawPuzzle/Constants.java +1 -1
@@ 19,6 19,6 @@ public class Constants {
 
 	public static final boolean debug = true;
 
-	public static final float tolerance = 10, moveBackDuration = .5f;
+	public static final float tolerance = 10;
 
 }

          
M core/src/net/dermetfan/jigsawPuzzle/puzzle/JigsawPuzzle.java +97 -39
@@ 23,11 23,9 @@ import com.badlogic.gdx.scenes.scene2d.a
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop;
 import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Payload;
-import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Source;
 import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
 import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.Pools;
-import net.dermetfan.jigsawPuzzle.Constants;
 import net.dermetfan.jigsawPuzzle.utils.PolygonRegionDrawable;
 import net.dermetfan.utils.libgdx.scene2d.Scene2DUtils;
 

          
@@ 103,47 101,107 @@ public class JigsawPuzzle {
 		return pieces;
 	}
 
-	public Source createSource(final Group board, final DragAndDrop dnd) {
-		return new Source(board) {
-			Payload payload = new Payload(); // the Payload object we're gonna use (to avoid having to create new ones all the time/GC)
-			Vector2 tmp = new Vector2();
+	/** @author dermetfan */
+	public static class Source extends DragAndDrop.Source {
+
+		/** the DragAndDrop currently using this Source */
+		private DragAndDrop dragAndDrop;
+
+		/** the puzzle */
+		private JigsawPuzzle puzzle;
+
+		/** the time it takes for the piece to move back */
+		private float moveBackDuration = .5f;
+
+		/** temporary Payload for internal use */
+		private final Payload payload = new Payload();
+
+		/** temporary Vector2 for internal use */
+		private final Vector2 vec2 = new Vector2();
 
-			@Override
-			public Payload dragStart(InputEvent event, float x, float y, int pointer) {
-				Actor actor = getActor().hit(x, y, true); // select actor under the mouse
-				if(actor == board) // don't drag the board itself
-					return null;
+		/** @param dragAndDrop the {@link #dragAndDrop}
+		 *  @param puzzle the {@link #puzzle} */
+		public Source(Group board, DragAndDrop dragAndDrop, JigsawPuzzle puzzle) {
+			super(board);
+			this.dragAndDrop = dragAndDrop;
+			this.puzzle = puzzle;
+		}
 
-				payload.setDragActor(actor);
+		/** @param moveBackDuration the {@link #moveBackDuration}
+		 *  @see #Source(Group, DragAndDrop, JigsawPuzzle) */
+		public Source(final Group board, final DragAndDrop dragAndDrop, JigsawPuzzle puzzle, float moveBackDuration) {
+			this(board, dragAndDrop, puzzle);
+			this.moveBackDuration = moveBackDuration;
+		}
 
-				// put the actor in the right position under the mouse
-				board.localToDescendantCoordinates(actor, tmp.set(x, y));
-				dnd.setDragActorPosition(-tmp.x, -tmp.y + actor.getHeight());
+		@Override
+		public Payload dragStart(InputEvent event, float x, float y, int pointer) {
+			Actor actor = getActor().hit(x, y, true); // get actor under pointer
+			// don't drag the board itself or anything that's not a piece of the puzzle
+			if(actor == getActor() || !(actor instanceof Piece) || !puzzle.getPieces().contains((Piece) actor, true))
+				return null;
+			payload.setDragActor(actor);
 
-				tmp.set(actor.getX(), actor.getY()); // set tmp for dragStop (the current position, to return to it if it wasn't dragged on the board correctly)
-				return payload;
-			}
+			// put the actor in the right position under the pointer
+			((Group) getActor()).localToDescendantCoordinates(actor, vec2.set(x, y));
+			dragAndDrop.setDragActorPosition(-vec2.x, -vec2.y + actor.getHeight());
+
+			vec2.set(actor.getX(), actor.getY()); // set vec2 for dragStop (to the current position to be able to move the piece back)
+			return payload;
+		}
 
-			@Override
-			public void dragStop(InputEvent event, float x, float y, int pointer, Payload payload, DragAndDrop.Target target) {
-				final Actor actor = payload.getDragActor();
-				if(actor.getParent() == null) { // move back to where the piece was dragged from
-					// put it on the stage in the correct position
-					board.getStage().addActor(actor); // (could use something else instead of board's stage)
-					board.localToStageCoordinates(tmp);
-					// move back
-					actor.addAction(Actions.sequence(Actions.moveTo(tmp.x, tmp.y, Constants.moveBackDuration), Actions.run(new Runnable() {
-						@Override
-						public void run() {
-							board.addActor(actor);
-							// set position correctly on the board
-							board.stageToLocalCoordinates(tmp);
-							actor.setPosition(tmp.x, tmp.y);
-						}
-					})));
-				}
+		@Override
+		public void dragStop(InputEvent event, float x, float y, int pointer, Payload payload, DragAndDrop.Target target) {
+			final Actor actor = payload.getDragActor();
+			if(actor.getParent() == null) { // move back to where the piece was dragged from
+				// put it on the stage in the correct position
+				getActor().getStage().addActor(actor);
+				getActor().localToStageCoordinates(vec2);
+				// move back
+				actor.addAction(Actions.sequence(Actions.moveTo(vec2.x, vec2.y, moveBackDuration), Actions.run(new Runnable() {
+					@Override
+					public void run() {
+						((Group) getActor()).addActor(actor);
+						// set position correctly on the board
+						getActor().stageToLocalCoordinates(vec2);
+						actor.setPosition(vec2.x, vec2.y);
+					}
+				})));
 			}
-		};
+		}
+
+		// getters and setters
+
+		/** @return the {@link #dragAndDrop} */
+		public DragAndDrop getDragAndDrop() {
+			return dragAndDrop;
+		}
+
+		/** @param dragAndDrop the {@link #dragAndDrop} to set */
+		public void setDragAndDrop(DragAndDrop dragAndDrop) {
+			this.dragAndDrop = dragAndDrop;
+		}
+
+		/** @return the {@link #puzzle} */
+		public JigsawPuzzle getPuzzle() {
+			return puzzle;
+		}
+
+		/** @param puzzle the {@link #puzzle} to set */
+		public void setPuzzle(JigsawPuzzle puzzle) {
+			this.puzzle = puzzle;
+		}
+
+		/** @return the {@link #moveBackDuration} */
+		public float getMoveBackDuration() {
+			return moveBackDuration;
+		}
+
+		/** @param moveBackDuration the {@link #moveBackDuration} to set */
+		public void setMoveBackDuration(float moveBackDuration) {
+			this.moveBackDuration = moveBackDuration;
+		}
+
 	}
 
 	/** @author dermetfan */

          
@@ 163,12 221,12 @@ public class JigsawPuzzle {
 		}
 
 		@Override
-		public boolean drag(Source source, Payload payload, float x, float y, int pointer) {
+		public boolean drag(DragAndDrop.Source source, Payload payload, float x, float y, int pointer) {
 			return true;
 		}
 
 		@Override
-		public void drop(Source source, Payload payload, float x, float y, int pointer) {
+		public void drop(DragAndDrop.Source source, Payload payload, float x, float y, int pointer) {
 			Actor dragged = payload.getDragActor();
 			Scene2DUtils.addAtStageCoordinates(dragged, (Group) getActor());
 			if(dragged instanceof Piece) {

          
M core/src/net/dermetfan/jigsawPuzzle/screens/PlayScreen.java +2 -1
@@ 32,6 32,7 @@ import net.dermetfan.jigsawPuzzle.Assets
 import net.dermetfan.jigsawPuzzle.Constants;
 import net.dermetfan.jigsawPuzzle.puzzle.JigsawPuzzle;
 import net.dermetfan.jigsawPuzzle.puzzle.JigsawPuzzle.Piece;
+import net.dermetfan.jigsawPuzzle.puzzle.JigsawPuzzle.Source;
 import net.dermetfan.jigsawPuzzle.puzzle.JigsawPuzzle.Target;
 import net.dermetfan.jigsawPuzzle.utils.PolygonRegionDrawable;
 

          
@@ 93,7 94,7 @@ public class PlayScreen extends ScreenAd
 		}
 
 		DragAndDrop dnd = new DragAndDrop();
-		dnd.addSource(puzzle.createSource(board, dnd));
+		dnd.addSource(new Source(board, dnd, puzzle));
 		dnd.addTarget(new Target(board, puzzle, Constants.tolerance) {
 			@Override
 			protected void solved() {