### Eclipse Workspace Patch 1.0
#P sophie
Index: modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/frame/rotate/FrameRotateHaloButton.java
===================================================================
--- modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/frame/rotate/FrameRotateHaloButton.java	(revision 9068)
+++ modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/frame/rotate/FrameRotateHaloButton.java	(working copy)
@@ -21,6 +21,7 @@
 import org.sophie2.base.skins.Message;
 import org.sophie2.base.skins.SkinElementId;
 import org.sophie2.base.visual.skins.VisualElementDef;
+import org.sophie2.main.app.commons.PageAreaMouseCapture;
 import org.sophie2.main.app.commons.frame.FrameView;
 import org.sophie2.main.app.commons.page.PageWorkArea;
 import org.sophie2.main.app.halos.common.AppHaloUtil;
@@ -63,7 +64,7 @@
 		final FrameH frame = frameView.model().get();
 		final double oldAngle = frame.getRotationAngle();
 
-		PageWorkArea pwa = AppHaloUtil.getWorkArea(this);
+		final PageWorkArea pwa = AppHaloUtil.getWorkArea(this);
 		final Scene scene = pwa.scene().get();
 		final ImmMatrix sceneToParent = SceneHelper.getElementToSceneTransform(scene,
 				frameView.parent().get().sceneElement().get()).inverse();
@@ -83,9 +84,9 @@
 		final ImmPoint oldControl = sceneToParent.transform(controlInScene);
 
 		final SceneVisual sceneVisual = pwa.sceneVisual().get();
-		sceneVisual.wantedViewRect().set(sceneVisual.actualViewRect().get());
+		sceneVisual.wantedViewRect().set(sceneVisual.lastViewRect().get());
 		
-		return new MouseCapture(0, 0, e) {
+		return new PageAreaMouseCapture(0, 0, e) {
 
 			@Override
 			public void shouldMove(int newX, int newY) {
@@ -100,7 +101,7 @@
 			}
 
 			@Override
-			public void released() {
+			public void onReleased() {
 				final Double angle = frame.getRotationAngle();
 				setAngle(angle, true);
 				sceneVisual.wantedViewRect().set(null);
@@ -159,6 +160,11 @@
 
 			}
 
+			@Override
+			public PageWorkArea getWorkArea() {
+				return pwa;
+			}
+
 		};
 	}
 
Index: modules/org.sophie2.base.commons/src/main/java/org/sophie2/base/commons/util/position/ImmRect.java
===================================================================
--- modules/org.sophie2.base.commons/src/main/java/org/sophie2/base/commons/util/position/ImmRect.java	(revision 9068)
+++ modules/org.sophie2.base.commons/src/main/java/org/sophie2/base/commons/util/position/ImmRect.java	(working copy)
@@ -348,4 +348,22 @@
 	public boolean contains(ImmPoint point) {
 		return this.toRectangle().contains(point.toPoint());
 	}
+	
+	/**
+		 * Creates rectangle by given point and size. The given point is the center
+		 * point for the rectangle. The size is the size of the rectangle.
+		 * 
+		 * @param centerPoint
+		 *            The center of the rectangle.
+		 * @param size
+		 *            The size of the rectangle.
+		 * @return New rectangle.
+		 */
+		public static ImmRect create(ImmPoint centerPoint, ImmSize size) {
+			ImmPoint topLeft = new ImmPoint(centerPoint.getX() - size.getWidth()/2, 
+					centerPoint.getY() - size.getHeight()/2);
+			ImmRect res = new ImmRect(topLeft, size);
+			
+			return res;
+		}
 }
Index: modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/PageAreaMouseCapture.java
===================================================================
--- modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/PageAreaMouseCapture.java	(revision 0)
+++ modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/PageAreaMouseCapture.java	(revision 0)
@@ -0,0 +1,43 @@
+package org.sophie2.main.app.commons;
+
+import java.awt.event.MouseEvent;
+
+import org.sophie2.base.commons.gui.MouseCapture;
+import org.sophie2.main.app.commons.page.PageWorkArea;
+
+/**
+ * Modified {@link MouseCapture} for {@link PageWorkArea}.
+ * 
+ * @author tanya
+ */
+public abstract class PageAreaMouseCapture extends MouseCapture {
+
+	/**
+	 * Initiates capture.  
+	 * @param initCompX The current X coordinate of the component.
+	 * @param initCompY The current Y coordinate of the component.
+	 * @param e The mouse event initiating the capture.
+	 */
+	public PageAreaMouseCapture(int initCompX, int initCompY, MouseEvent e) {
+		super(initCompX, initCompY, e);
+		getWorkArea().scrollsLocked().set(Boolean.TRUE);
+	}
+	
+	@Override
+	final public void released() {
+		onReleased();
+		getWorkArea().scrollsLocked().set(Boolean.FALSE);
+	}
+	
+	/**
+	 * Called when the user has released the mouse button. Should be overrided and called in the {@link #released()}.
+	 */
+	public abstract void onReleased();
+	
+	/**
+	 * Returns the {@link PageWorkArea} over which the {@link MouseCapture} is performed.
+	 * 
+	 * @return {@link PageWorkArea}
+	 */
+	public abstract PageWorkArea getWorkArea();
+}
\ No newline at end of file
Index: modules/org.sophie2.base.layout/src/test/java/org/sophie2/base/layout/model/LayoutDemo.java
===================================================================
--- modules/org.sophie2.base.layout/src/test/java/org/sophie2/base/layout/model/LayoutDemo.java	(revision 0)
+++ modules/org.sophie2.base.layout/src/test/java/org/sophie2/base/layout/model/LayoutDemo.java	(revision 0)
@@ -0,0 +1,59 @@
+package org.sophie2.base.layout.model;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+
+/**
+ * Demo for demonstrating the usage of {@link CustomLayout}.
+ * @author tanya
+ */
+public class LayoutDemo {
+
+	/**
+	 * Constructor that creates {@link JFrame}, adds a {@link JDesktopPane} with
+	 * {@link CustomLayout} and set different layers to be with different
+	 * layouts.
+	 */
+	public LayoutDemo() {
+		
+		JFrame frame = new JFrame();
+		frame.setSize(300, 300);
+		frame.setVisible(true);
+		
+		JDesktopPane pane = new JDesktopPane();
+		
+		frame.setContentPane(pane);
+		pane.setLayout(new CustomLayout(new BorderLayout()));
+		
+		JInternalFrame frame1 = new JInternalFrame();
+		frame1.setLocation(10, 10);
+		frame1.setSize(90, 90);
+		frame1.setVisible(true);
+		
+		pane.setLayer(frame1, JLayeredPane.DEFAULT_LAYER);
+		
+		pane.add(frame1, BorderLayout.CENTER);
+		
+		JInternalFrame frame2 = new JInternalFrame();
+		frame2.setLocation(110, 110);
+		frame2.setSize(90, 90);
+		frame2.setVisible(true);
+		
+		pane.setLayer(frame2, JLayeredPane.PALETTE_LAYER);
+		
+		pane.add(frame2, CustomLayout.CUSTOM);
+	}
+	
+	/**
+	 * The main method.
+	 * @param args
+	 */
+	public static void main(String args[]) {
+		new LayoutDemo();
+	}
+}
+
Index: modules/org.sophie2.extra.func.annotations/src/main/java/org/sophie2/extra/func/annotations/view/halos/StickyMoveHaloButton.java
===================================================================
--- modules/org.sophie2.extra.func.annotations/src/main/java/org/sophie2/extra/func/annotations/view/halos/StickyMoveHaloButton.java	(revision 9068)
+++ modules/org.sophie2.extra.func.annotations/src/main/java/org/sophie2/extra/func/annotations/view/halos/StickyMoveHaloButton.java	(working copy)
@@ -17,6 +17,7 @@
 import org.sophie2.base.skins.SkinElementId;
 import org.sophie2.base.visual.skins.VisualElementDef;
 import org.sophie2.extra.func.annotations.view.StickyView;
+import org.sophie2.main.app.commons.PageAreaMouseCapture;
 import org.sophie2.main.app.commons.page.PageWorkArea;
 import org.sophie2.main.app.halos.page.element.PageElementMoveHaloButton;
 
@@ -49,7 +50,7 @@
 		// lock the view rect, so that we don't have auto-scrolls while moving.
 		final PageWorkArea workArea = workArea().get();
 		final SceneVisual sv = workArea.sceneVisual().get();
-		sv.wantedViewRect().set(sv.actualViewRect().get());
+		sv.wantedViewRect().set(sv.lastViewRect().get());
 
 		StickyView stickyView = findParentElement(StickyHaloMenu.class).stickyView().get(); 
 		final TimePos time = stickyView.getTime();  
@@ -62,7 +63,7 @@
 				workArea.getSel().getEditScope().sceneElement().get()).inverse(); 
 		final ImmPoint zero = sceneToParent.transform(ImmPoint.ZERO); 
 
-		MouseCapture result = new MouseCapture(0, 0, e) {
+		MouseCapture result = new PageAreaMouseCapture(0, 0, e) {
 
 			private void releaseAction(final LocationChannel locationChannel) {
 				final ImmPoint newlocation = 
@@ -95,16 +96,20 @@
 			}
 
 			@Override
-			public void released() {
+			public void onReleased() {
 				sv.wantedViewRect().set(null);
 				releaseAction(channel);
-
 			}
 
 			@Override
 			public void shouldMove(final int newX, final int newY) {
 				moveAction(channel, newX, newY);
 			}
+
+			@Override
+			public PageWorkArea getWorkArea() {
+				return workArea;
+			}
 		};
 
 		return result;
Index: modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/interfaces/Scene.java
===================================================================
--- modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/interfaces/Scene.java	(revision 9068)
+++ modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/interfaces/Scene.java	(working copy)
@@ -1,6 +1,7 @@
 package org.sophie2.base.scene.interfaces;
 
 import org.sophie2.base.commons.util.ImmColor;
+import org.sophie2.base.commons.util.position.ImmRect;
 import org.sophie2.base.scene.helpers.SceneHelper;
 import org.sophie2.core.prolib.impl.BaseProObject;
 import org.sophie2.core.prolib.interfaces.Prop;
@@ -35,7 +36,14 @@
 	 * @return property
 	 */
 	public abstract Prop<? extends SceneElement> rootElement();
-
+	
+	/**
+	 * The rectangle over which the actual view rectangle will be centered.
+	 * 
+	 * @return property
+	 */
+	public abstract RwProp<ImmRect> centeringRect();
+	
 	/**
 	 * The background color of the scene. This is the infinite area that is
 	 * outside of any object. Note that, you should usually use elements that
Index: modules/org.sophie2.base.scene/src/test/java/org/sophie2/base/scene/SceneDemo.java
===================================================================
--- modules/org.sophie2.base.scene/src/test/java/org/sophie2/base/scene/SceneDemo.java	(revision 9068)
+++ modules/org.sophie2.base.scene/src/test/java/org/sophie2/base/scene/SceneDemo.java	(working copy)
@@ -443,7 +443,7 @@
 			return component;
 		}
 
-		public Prop<ImmRect> actualViewRect() {
+		public RwProp<ImmRect> lastViewRect() {
 			return getBean().makeValueProp("actualViewRect", ImmRect.class,
 					ImmRect.ZERO_RECT);
 		}
@@ -471,11 +471,17 @@
 
 		public RwProp<ImmRect> minimalViewRect() { 
 		        return getBean().makeValueProp("minimalViewRect", ImmRect.class, null); 
-		} 
+		}
 
-		public RwProp<ImmRect> actualViewRectCache() { 
-		        return getBean().makeValueProp("actualViewRectCache", ImmRect.class, null); 
-		} 
+		public RwProp<ImmRect> actualViewRect() {
+//			return getBean().makeValueProp("halosBoundSize", ImmRect.class, ImmRect.ZERO_RECT);
+			return null;
+		}
+
+//		public RwProp<ImmRect> lastViewRect() {
+//			// TODO Auto-generated method stub
+//			return null;
+//		} 
 	}
 
 	/**
Index: modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/BaseSceneVisual.java
===================================================================
--- modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/BaseSceneVisual.java	(revision 9068)
+++ modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/BaseSceneVisual.java	(working copy)
@@ -1,12 +1,15 @@
 package org.sophie2.base.scene;
 
-import java.awt.Dimension;
+import java.awt.Container;
 import java.util.List;
 
 import javax.swing.JComponent;
+import javax.swing.JScrollPane;
 
 import org.sophie2.base.commons.util.OSUtil;
+import org.sophie2.base.commons.util.position.ImmPoint;
 import org.sophie2.base.commons.util.position.ImmRect;
+import org.sophie2.base.commons.util.position.ImmSize;
 import org.sophie2.base.dnd.SophieDragDropHandler;
 import org.sophie2.base.scene.helpers.ElementHelper;
 import org.sophie2.base.scene.helpers.SceneHelper;
@@ -69,33 +72,48 @@
 		SELECT_PREVIOUS_BOOK;
 	}
 
-	private static final int DEFAULT_PADDING_L = 18;
-	private static final int DEFAULT_PADDING_R = 18;
-	private static final int DEFAULT_PADDING_T = 48;
-	private static final int DEFAULT_PADDING_B = 18;
-
+	/**
+	 * Default padding of the left side.
+	 */
+	public static final int DEFAULT_PADDING_L = 18;
+	/**
+	 * Default padding of the right side.
+	 */
+	public static final int DEFAULT_PADDING_R = 18;
+	/**
+	 * Default padding of the top side.
+	 */
+	public static final int DEFAULT_PADDING_T = 42;
+	/**
+	 * Default padding of the bottom side.
+	 */
+	public static final int DEFAULT_PADDING_B = 18;
+	
 	public RwProp<ImmRect> wantedViewRect() {
 		return getBean().makeValueProp("wantedViewRect", ImmRect.class, null);
 	}
 
-	public RwProp<ImmRect> minimalViewRect() { 
-		return getBean().makeValueProp("minimalViewRect", ImmRect.class, null); 
-	} 
-
-	public RwProp<ImmRect> actualViewRectCache() { 
-		return getBean().makeValueProp("actualViewRectCache", ImmRect.class, null); 
-	} 
-
 	@Own
 	public RwProp<Scene> scene() {
 		return getBean().makeValueProp("scene", Scene.class);
 	}
+	
+	/**
+	 * The size of the component where the scene is painted. This is the size which will be used for centering into it.
+	 * 
+	 * @return The property.
+	 */
+	public RwProp<ImmSize> viewportSize() {
+		return getBean().makeValueProp("viewportSize", ImmSize.class, ImmSize.ZERO);
+	}
 
 	public Prop<JComponent> swingComponent() {
 		class swingComponent extends ResourceProperty<JComponent> {
 			@Override
 			protected JComponent create() {
 				JComponent res = createSwingComponent();
+				res.setLayout(null);
+
 				SwingEventAdapter.registerComponent(res,
 						BaseSceneVisual.this, null, res);
 
@@ -112,11 +130,13 @@
 
 			@Override
 			protected void setup(JComponent res) {
-				Dimension size = actualViewRect().get().getSize().toDimension();
-				res.setSize(size);
-				res.setPreferredSize(size);
-				res.setLayout(null);
+				ImmRect bound = SceneHelper.getBoundingRect(scene().get(),
+							scene().get().rootElement().get());
+				ImmSize preferredSize = new ImmSize(bound.getWidth() + DEFAULT_PADDING_R + DEFAULT_PADDING_L, bound.getHeight()
+						+ DEFAULT_PADDING_B + DEFAULT_PADDING_T);
+				res.setPreferredSize(preferredSize.toDimension());
 				res.revalidate();
+				res.repaint();
 			}
 
 			@SuppressWarnings("unused")
@@ -157,15 +177,25 @@
 		return getBean().makeProp(swingComponent.class);
 	}
 
+	
+	
 	/**
 	 * A view rectangle, if it can not be determined automatically (such as,
 	 * when no scene is set).
 	 */
 	protected static final ImmRect DEFAULT_VIEW_RECT =
 		new ImmRect(0, 0, 256, 256);
-
-	public Prop<ImmRect> actualViewRect() {
-		class actualViewRect extends AutoProperty<ImmRect> {
+	
+	public RwProp<ImmRect> actualViewRect(){
+		return getBean().makeValueProp("actualViewRect", ImmRect.class, ImmRect.ZERO_RECT);
+	}
+	
+	public RwProp<ImmRect> lastViewRect(){
+		return getBean().makeValueProp("lastViewRect", ImmRect.class, ImmRect.ZERO_RECT);
+	}
+	
+	public Prop<ImmRect> minimalViewRect() {
+		class minimalViewRect extends AutoProperty<ImmRect> {
 
 			@Override
 			protected ImmRect compute() {
@@ -177,46 +207,37 @@
 						&& scene().get().rootElement().get() != null) {
 					ImmRect bound = SceneHelper.getBoundingRect(scene().get(),
 							scene().get().rootElement().get());
+					res = bound;
+						
 					res = new ImmRect(
-							bound.getX() - DEFAULT_PADDING_L, 
-							bound.getY() - DEFAULT_PADDING_T, 
-							bound.getWidth() + DEFAULT_PADDING_R + DEFAULT_PADDING_L, 
-							bound.getHeight() + DEFAULT_PADDING_B + DEFAULT_PADDING_T);
+					res.getX() - DEFAULT_PADDING_L, 
+					res.getY() - DEFAULT_PADDING_T, 
+					res.getWidth() + DEFAULT_PADDING_R + DEFAULT_PADDING_L, 
+					res.getHeight() + DEFAULT_PADDING_B + DEFAULT_PADDING_T);
+
+					ImmRect centeringRect = scene().get().centeringRect().get();
+
+					if (!centeringRect.equals(ImmRect.ZERO_RECT)) {
+						ImmPoint centerPoint = new ImmPoint(centeringRect.getWidth()/2,
+								centeringRect.getHeight()/2);
+						ImmRect toUnite = ImmRect.create(centerPoint, viewportSize().get());
+						res = res.union(toUnite);
+					} else {
+						ImmRect toUnite = new ImmRect(ImmPoint.ZERO, viewportSize().get());
+						res = res.union(toUnite);
+					}
 				} else {
 					// can not determine...
 					// just make something...
 					res = DEFAULT_VIEW_RECT;
 				}
-
-				// Center the actualRect on the minimalViewRect 
-				// wantedViewRect is set by halo mouse tracking to limit the rect,  
-				// so do nothing if wantedViewRect is not null 
-				if (wantedViewRect().get() == null) { 
-					ImmRect myMinimalViewRect = minimalViewRect().get(); 
-					if (myMinimalViewRect != null) { 
-						float xOffset =
-							Math.max((myMinimalViewRect.getWidth() - res.getWidth()) / 2, 0); 
-						float yOffset =
-							Math.max((myMinimalViewRect.getHeight() - res.getHeight()) / 2, 0); 
-						res = new ImmRect(res.getX() - xOffset, 
-								res.getY() - yOffset, 
-								Math.max(res.getWidth(), myMinimalViewRect.getWidth()), 
-								Math.max(res.getHeight(), myMinimalViewRect.getHeight())); 
-					} 
-
-					if (!res.equals(actualViewRectCache().get())) { 
-						actualViewRectCache().set(res); 
-					} 
-				}
-
 				assert res != null;
 				return res;
 			}
 		}
-
-		return getBean().makeProp(actualViewRect.class);
+		return getBean().makeProp(minimalViewRect.class);
 	}
-
+	
 	/**
 	 * Override this to provide logic for the creation of the Swing Component
 	 * of this {@link SceneVisual}.
@@ -229,4 +250,29 @@
 	protected boolean computeVisible() {
 		return true;
 	}
+	
+	/**
+	 *  Finds possible {@link JScrollPane} parent, to a specific depth 
+	 * @param res
+	 * 			The starting component.
+	 * @param depth
+	 * 			The depth to which we search
+	 * @return nearest {@link JScrollPane} parent, null if not.
+	 */
+	public static JScrollPane findParentScrollPane(JComponent res, int depth) {
+		Container component = res;
+		int i = 0;
+		
+		while (i < depth && component != null) {
+			
+			if (component instanceof JScrollPane) {
+				return (JScrollPane) component;
+			} 
+			
+			component = component.getParent();
+			++i;
+		}
+		
+		return null;
+	}
 }
Index: modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/helpers/SceneHelper.java
===================================================================
--- modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/helpers/SceneHelper.java	(revision 9068)
+++ modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/helpers/SceneHelper.java	(working copy)
@@ -248,7 +248,7 @@
 		SophieLog.trace("sceneToSwing: sceneRect=" + sceneRect);
 		assert sceneRect != null;
 		// only translation...
-		ImmRect viewRect = visual.actualViewRect().get();
+		ImmRect viewRect = visual.lastViewRect().get();
 		assert viewRect != null;
 		SophieLog.trace("sceneToSwing: viewRect=" + viewRect);
 		ImmRect res = Position.translate(sceneRect, -viewRect.getX(), -viewRect
@@ -271,7 +271,7 @@
 		SophieLog.trace("sceneToSwing: sceneRect=" + scenePoint);
 		assert scenePoint != null;
 		// only translation...
-		ImmRect viewRect = visual.actualViewRect().get();
+		ImmRect viewRect = visual.lastViewRect().get();
 		assert viewRect != null;
 		SophieLog.trace("sceneToSwing: viewRect=" + viewRect);
 		ImmPoint res = scenePoint.translate(-viewRect.getX(), -viewRect.getY());
@@ -291,7 +291,7 @@
 	 */
 	public static ImmRect swingToScene(SceneVisual visual, ImmRect swingRect) {
 		// only translation...
-		ImmRect viewRect = visual.actualViewRect().get();
+		ImmRect viewRect = visual.lastViewRect().get();
 		return Position.translate(swingRect, viewRect.getX(), viewRect.getY());
 	}
 
@@ -306,7 +306,7 @@
 	 */
 	public static ImmPoint swingToScene(SceneVisual visual, ImmPoint swingPoint) {
 		// only translation...
-		ImmRect viewRect = visual.actualViewRect().get();
+		ImmRect viewRect = visual.lastViewRect().get();
 		assert viewRect != null;
 		return swingPoint.translate(viewRect.getX(), viewRect.getY());
 	}
Index: modules/org.sophie2.base.layout/src/main/java/org/sophie2/base/layout/model/CustomLayout.java
===================================================================
--- modules/org.sophie2.base.layout/src/main/java/org/sophie2/base/layout/model/CustomLayout.java	(revision 0)
+++ modules/org.sophie2.base.layout/src/main/java/org/sophie2/base/layout/model/CustomLayout.java	(revision 0)
@@ -0,0 +1,121 @@
+package org.sophie2.base.layout.model;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.LayoutManager2;
+import java.io.Serializable;
+
+import javax.swing.JDesktopPane;
+import javax.swing.JLayeredPane;
+
+/**
+ * LayoutManager that supports adding of components with different layouts - null
+ * and some specific layout. An object is created with a specific
+ * {@link LayoutManager2}. When different components are added, they can be with
+ * constraint - CustomLayout.CUSTOM. This means that for laying out of these
+ * components will be used null layout. For all other components added, it will
+ * be used the given layout manager. This layout manager can be used for example
+ * for {@link JDesktopPane}. For example, components at
+ * {@link JLayeredPane#DEFAULT_LAYER} can be with {@link BorderLayout} and the
+ * components at {@link JLayeredPane#PALETTE_LAYER} to be with null layout.
+ * 
+ * @author tanya
+ */
+public class CustomLayout implements LayoutManager2, Serializable {
+
+	/**
+	 * Used for serialization.
+	 */
+	private static final long serialVersionUID = 810513263396699528L;
+
+	private LayoutManager2 layoutManager;
+	
+	/**
+	 * The constraint for the objects which we want to be with null layout.
+	 */
+	public static final String CUSTOM   = "Custom";
+	
+	/**
+	 * Constructs an object with another layout manager. The components added
+	 * will be with null layout or will be added according
+	 * 
+	 * @param manager
+	 *            The manager which will be responsible for how the components
+	 *            will be added and how will be laid out.
+	 */
+	public CustomLayout(LayoutManager2 manager) {
+		this.layoutManager = manager;
+	}
+	
+	public void addLayoutComponent(Component comp, Object constraints) {
+		if (constraints != CUSTOM && this.layoutManager != null) {
+			this.layoutManager.addLayoutComponent(comp, constraints);
+		}
+	}
+
+	public float getLayoutAlignmentX(Container target) {
+		if (this.layoutManager != null) {
+			return this.layoutManager.getLayoutAlignmentX(target);
+		}
+
+		return 0f;
+	}
+
+	public float getLayoutAlignmentY(Container target) {
+		if (this.layoutManager != null) {
+			return this.layoutManager.getLayoutAlignmentY(target);
+		}
+		
+		return 0f;
+	}
+
+	public void invalidateLayout(Container target) {
+		if (this.layoutManager != null) {
+			this.layoutManager.invalidateLayout(target);
+		}
+	}
+
+	public Dimension maximumLayoutSize(Container target) {
+		if (this.layoutManager != null) {
+			return this.layoutManager.maximumLayoutSize(target);
+		}
+		
+		return null;
+	}
+
+	public void addLayoutComponent(String name, Component comp) {
+		if (this.layoutManager != null) {
+			this.layoutManager.addLayoutComponent(name, comp);
+		}
+	}
+
+	public void layoutContainer(Container parent) {
+		if (this.layoutManager != null) {
+			this.layoutManager.layoutContainer(parent);
+		}
+	}
+
+	public Dimension minimumLayoutSize(Container parent) {
+		if (this.layoutManager != null) {
+			return this.layoutManager.minimumLayoutSize(parent);
+		}
+		
+		return null;
+	}
+
+	public Dimension preferredLayoutSize(Container parent) {
+		if (this.layoutManager != null) {
+			return this.layoutManager.preferredLayoutSize(parent);
+		}
+		
+		return null;
+	}
+
+	public void removeLayoutComponent(Component comp) {
+		if (this.layoutManager != null) {
+			this.layoutManager.removeLayoutComponent(comp);
+		}
+	}
+}
\ No newline at end of file
Index: modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/page/PageWorkArea.java
===================================================================
--- modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/page/PageWorkArea.java	(revision 9068)
+++ modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/page/PageWorkArea.java	(working copy)
@@ -1,5 +1,6 @@
 package org.sophie2.main.app.commons.page;
 
+import java.awt.BorderLayout;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -10,7 +11,11 @@
 import org.sophie2.base.commons.util.ImmColor;
 import org.sophie2.base.commons.util.position.ImmArea;
 import org.sophie2.base.commons.util.position.ImmMatrix;
+import org.sophie2.base.commons.util.position.ImmPoint;
 import org.sophie2.base.commons.util.position.ImmRect;
+import org.sophie2.base.commons.util.position.ImmSize;
+import org.sophie2.base.layout.model.CustomLayout;
+import org.sophie2.base.layout.model.DocView;
 import org.sophie2.base.model.book.PageH;
 import org.sophie2.base.scene.SceneVisual;
 import org.sophie2.base.scene.effects.ColorEffect;
@@ -31,9 +36,11 @@
 import org.sophie2.core.prolib.impl.ResourceProperty;
 import org.sophie2.core.prolib.interfaces.Prop;
 import org.sophie2.core.prolib.interfaces.RwProp;
+import org.sophie2.main.app.commons.app.AppMainWindow;
 import org.sophie2.main.app.commons.book.BookDocView;
 import org.sophie2.main.app.commons.book.BookView;
 import org.sophie2.main.app.commons.element.ElementView;
+import org.sophie2.main.app.commons.util.AppViewUtil;
 
 /**
  * A view, displaying the content on a page. It is responsible for selection and
@@ -44,7 +51,16 @@
  */
 @VisualElementDef(parent = BookDocView.class, sortKey = "kkk-page-work-area")
 public class PageWorkArea extends BaseVisualElement {
-
+	/**
+	 * Default horizontal padding.
+	 */
+	public static final int PADDING_HORIZONTAL = 48;
+	
+	/**
+	 * Default padding of the top side.
+	 */
+	public static final int PADDING_VERTICAL = 62;
+	
 	/**
 	 * The <code>BookView</code> of the book this PageWorkArea shows.
 	 * 
@@ -152,11 +168,24 @@
 			@Override
 			protected Scene compute() {
 				assert getLastValue() == null;
+				
 				return new BaseScene() {
 
 					@Override
 					protected void setupScene() {
 						rootElement().set(rootSceneElement().get());
+
+						boolean isDesktopBook = !(bookView().get().getViewOptions().isShowControls()); 
+						if (!isDesktopBook) {
+							ImmPoint pageLocation = ImmPoint.ZERO;
+							float zoom = bookView().get().getViewOptions().getZoom();
+							ImmSize pageSize = bookView().get().model().get().getPageSize();
+							pageSize = new ImmSize(pageSize.getWidth() * zoom, pageSize.getHeight() * zoom);
+							ImmRect centeringRect = new ImmRect(pageLocation, pageSize);
+
+							centeringRect().set(centeringRect);
+						}
+
 						topEventSource().set(PageWorkArea.this);
 					}
 				};
@@ -208,27 +237,34 @@
 			@Override
 			protected void setup(JDesktopPane res) {
 			
+				res.setLayout(new CustomLayout(new BorderLayout()));
+				
 				JComponent sceneComp = sceneVisual().get().swingComponent().get();
 
 				sceneComp.setLocation(0, 0);
 				SophieLog.debug("PageWorkArea.layeredPage: sceneComp:" + sceneComp);
 
 				res.removeAll();
-				res.add(sceneComp, JLayeredPane.DEFAULT_LAYER);
+				res.setLayer(sceneComp, JLayeredPane.DEFAULT_LAYER);
+				
+				res.add(sceneComp, BorderLayout.CENTER);
 
 				res.revalidate();
 				res.repaint();
 			}
 
-			// TODO (r4) reimplement the page-work-area centering
 			@SuppressWarnings("unused")
 			@Setup
 			protected void setupActualSize(JLayeredPane res) {
-
-				// grab the value to set up the property sync
-				ImmRect actualCache = sceneVisual().get().actualViewRect().get();
-
 				JDesktopPane desktopPane = swingComponent().get();
+				AppMainWindow appMainWindow = AppViewUtil.findMainWindow(PageWorkArea.this);
+				DocView parentBookView = findParentElement(BookDocView.class);
+				if (appMainWindow != null && appMainWindow.desktopDocument().get() == parentBookView) {
+					ImmRect bound = SceneHelper.getBoundingRect(scene().get(), scene().get().rootElement().get());
+					ImmSize prefSize = new ImmSize(bound.getWidth() + PADDING_HORIZONTAL, bound.getHeight()
+							+ PADDING_VERTICAL);
+					desktopPane.setPreferredSize(prefSize.toDimension());
+				}
 				desktopPane.revalidate();
 				desktopPane.repaint();
 			}
@@ -427,4 +463,14 @@
 		}
 		return getBean().makeProp(selectionRisenElement.class);
 	}
+	
+	/**
+	 * Property which have True or False value depending on whether mouse capture event is started or not.
+	 * <b>true</b> if mouse capture is on, <b>false</b> otherwise.
+	 * 
+	 * @return property
+	 */
+	public RwProp<Boolean> scrollsLocked() {
+		return getBean().makeValueProp("scrollsLocked", Boolean.class, Boolean.FALSE);	
+	}
 }
\ No newline at end of file
Index: modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/page/resize/PageResizeHaloButton.java
===================================================================
--- modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/page/resize/PageResizeHaloButton.java	(revision 9068)
+++ modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/page/resize/PageResizeHaloButton.java	(working copy)
@@ -23,6 +23,7 @@
 import org.sophie2.base.visual.skins.SkinPartDef;
 import org.sophie2.base.visual.skins.VisualElementDef;
 import org.sophie2.core.prolib.interfaces.Prop;
+import org.sophie2.main.app.commons.PageAreaMouseCapture;
 import org.sophie2.main.app.commons.page.PageWorkArea;
 import org.sophie2.main.app.halos.common.AppHaloUtil;
 
@@ -65,12 +66,12 @@
 
 	@Override
 	protected MouseCapture captureClick(MouseEvent e) {
-		PageWorkArea pwa = AppHaloUtil.getWorkArea(PageResizeHaloButton.this);
+		final PageWorkArea pwa = AppHaloUtil.getWorkArea(PageResizeHaloButton.this);
 
 		if(pwa !=null ){
 
 			final SceneVisual sv = pwa.sceneVisual().get();
-			sv.wantedViewRect().set(sv.actualViewRect().get());
+			sv.wantedViewRect().set(sv.lastViewRect().get());
 
 			final BookH book = pwa.bookView().get().model().get();
 
@@ -79,14 +80,13 @@
 			final ImmMatrix transf = SceneHelper.getElementToSceneTransform(pwa.scene().get(), pwa.rootSceneElement().get());
 
 			ImmVector resizedSize = transf.transform(v);
-			return new MouseCapture((int) resizedSize.getPointX(), (int) resizedSize.getPointY(),
+			return new PageAreaMouseCapture((int) resizedSize.getPointX(), (int) resizedSize.getPointY(),
 					e) {
 
 				@Override
-				public void released() {
+				public void onReleased() {
 					sv.wantedViewRect().set(null);
 
-
 					new AutoAction(Message.create(SET_PAGE_SIZE), true) {
 
 						@Override
@@ -128,6 +128,11 @@
 					}.register(book.getAccess());
 				}
 
+				@Override
+				public PageWorkArea getWorkArea() {
+					return pwa;
+				}
+
 			};
 		}
 		return null;
Index: modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/page/ScenePageLogic.java
===================================================================
--- modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/page/ScenePageLogic.java	(revision 9068)
+++ modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/page/ScenePageLogic.java	(working copy)
@@ -4,7 +4,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.sophie2.base.commons.gui.MouseCapture;
 import org.sophie2.base.commons.util.position.ImmArea;
 import org.sophie2.base.commons.util.position.ImmMatrix;
 import org.sophie2.base.commons.util.position.ImmPoint;
@@ -25,6 +24,7 @@
 import org.sophie2.core.mvc.LogicR3;
 import org.sophie2.core.mvc.OperationDef;
 import org.sophie2.core.mvc.events.EventR3;
+import org.sophie2.main.app.commons.PageAreaMouseCapture;
 import org.sophie2.main.app.commons.app.AppMainWindow;
 import org.sophie2.main.app.commons.book.BookDocView;
 import org.sophie2.main.app.commons.element.ElementView;
@@ -120,10 +120,10 @@
 
 			MouseEvent cause = event.getCausingEvent(EventR3.class).getCausingEvent(
 					MouseEvent.class);
-			new MouseCapture(0, 0, cause) {
+			new PageAreaMouseCapture(0, 0, cause) {
 
 				@Override
-				public void released() {
+				public void onReleased() {
 					pwa.selectionArea().set(ImmArea.EMPTY);
 				}
 
@@ -159,6 +159,11 @@
 								pwa.getSel().select(toSelect, false);
 							}
 				}
+
+				@Override
+				public PageWorkArea getWorkArea() {
+					return pwa;
+				}
 			};
 			return true;
 		}
Index: modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/AppMainWindow.java
===================================================================
--- modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/AppMainWindow.java	(revision 9068)
+++ modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/AppMainWindow.java	(working copy)
@@ -14,6 +14,7 @@
 import org.sophie2.base.commons.util.position.ImmRect;
 import org.sophie2.base.halos.HaloMenu;
 import org.sophie2.base.layout.impl.DefaultMainWindow;
+import org.sophie2.base.layout.model.CustomLayout;
 import org.sophie2.base.layout.model.DocView;
 import org.sophie2.base.media.MediaComposite;
 import org.sophie2.base.media.MediaUtil;
@@ -211,7 +212,9 @@
 					if (hm.visible().get()) {
 						for (JComponent c : hm.swingComponents().get()) {
 
-							res.add(c, JLayeredPane.PALETTE_LAYER);
+							res.setLayer(c, JLayeredPane.PALETTE_LAYER);
+							res.add(c, CustomLayout.CUSTOM);
+							
 						}
 					}
 				}
@@ -235,25 +238,26 @@
 				}
 				PageWorkArea workArea = bookDocView.workArea().get();
 
-				JDesktopPane res = workArea.swingComponent().get(); 
-
-				// The scene bounds
-				ImmRect bounds = workArea.sceneVisual().get().actualViewRect().get();
-				// The bounds of visible huds
-				for (HaloMenu hm : haloMenus().get()) {
+				if (!workArea.scrollsLocked().get()) {
 
-					bounds = bounds.union(SceneHelper.swingToScene(
-							workArea.sceneVisual().get(), hm.activeBounds().get()));
-				}
+					JDesktopPane res = workArea.swingComponent().get(); 
 
-				bounds = SceneHelper.sceneToSwing(workArea.sceneVisual().get(), bounds);
-				Dimension d = bounds.getSize().toDimension();
+					// The scene bounds
+					ImmRect bounds = workArea.sceneVisual().get().minimalViewRect().get();
+					// The bounds of visible huds
+					for (HaloMenu hm : haloMenus().get()) {
+						bounds = bounds.union(SceneHelper.swingToScene(
+								workArea.sceneVisual().get(), hm.activeBounds().get()));
+					}
+					bounds = SceneHelper.sceneToSwing(workArea.sceneVisual()
+							.get(), bounds);
 
-				res.setPreferredSize(d);
-				res.setSize(d);
-				res.revalidate();
+					Dimension dim = bounds.getSize().toDimension();
+					workArea.sceneVisual().get().actualViewRect().set(
+							new ImmRect(workArea.sceneVisual().get().minimalViewRect().get().getX(), 
+									workArea.sceneVisual().get().minimalViewRect().get().getY(), dim.width, dim.height));
+				}
 			}
-
 		}
 		return getBean().makeProp(haloSync.class);
 	}
Index: modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/frame/FrameLogic.java
===================================================================
--- modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/frame/FrameLogic.java	(revision 9068)
+++ modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/frame/FrameLogic.java	(working copy)
@@ -2,7 +2,6 @@
 
 import java.awt.event.MouseEvent;
 
-import org.sophie2.base.commons.gui.MouseCapture;
 import org.sophie2.base.commons.util.position.ImmMatrix;
 import org.sophie2.base.commons.util.position.ImmPoint;
 import org.sophie2.base.commons.util.position.ImmSize;
@@ -26,6 +25,7 @@
 import org.sophie2.core.mvc.EventFilterBuilder;
 import org.sophie2.core.mvc.OperationDef;
 import org.sophie2.core.mvc.events.EventR3;
+import org.sophie2.main.app.commons.PageAreaMouseCapture;
 import org.sophie2.main.app.commons.element.ElementView;
 import org.sophie2.main.app.commons.element.ResizeAreaSceneElement.ResizeSubAreaElement;
 import org.sophie2.main.app.commons.page.PageWorkArea;
@@ -57,7 +57,7 @@
 			final ElementView elementView = event.getSource(ElementView.class);
 			final ResourceAccess access = elementView.getAccess();
 
-			PageWorkArea pwa = elementView.getPwa();
+			final PageWorkArea pwa = elementView.getPwa();
 			Mode sizeTemplateMode = ResizableElement.KEY_SIZE.getMode(access);
 			Mode locTemplateMode = MemberElement.KEY_LOCATION.getMode(access);
 
@@ -78,14 +78,15 @@
 			// lock the view rect, so that we don't have auto-scrolls while moving.
 			final SceneVisual sv = pwa.sceneVisual().get();
 			sv.wantedViewRect().set(sv.actualViewRect().get());
-
+			
 			MouseEvent cause = event.getCausingEvent(EventR3.class).getCausingEvent(
 					MouseEvent.class);
 
-			new MouseCapture(0, 0, cause) {
+			new PageAreaMouseCapture(0, 0, cause) {
 				@Override
-				public void released() {
+				public void onReleased() {
 					AutoAction.registerEndChange(access, Message.create(RESIZE_FRAME_FINISHED));
+
 					sv.wantedViewRect().set(null);
 				}
 
@@ -93,6 +94,7 @@
 						final ImmPoint newLocationInPage, final ImmSize newSize) {
 					TimePos time = elementView.getTime();
 					final LocationChannel newChannel = oldChannel.setValue(time, newLocationInPage);
+
 					new AutoAction(Message.create(FRAME_RESIZE), false) {
 						@Override
 						public void performAuto() {
@@ -157,6 +159,11 @@
 
 					}
 				}
+
+				@Override
+				public PageWorkArea getWorkArea() {
+					return pwa;
+				}
 			};
 
 			return true;
Index: modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/impl/BaseScene.java
===================================================================
--- modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/impl/BaseScene.java	(revision 9068)
+++ modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/impl/BaseScene.java	(working copy)
@@ -1,6 +1,7 @@
 package org.sophie2.base.scene.impl;
 
 import org.sophie2.base.commons.util.ImmColor;
+import org.sophie2.base.commons.util.position.ImmRect;
 import org.sophie2.base.scene.interfaces.Scene;
 import org.sophie2.base.scene.interfaces.SceneElement;
 import org.sophie2.core.prolib.impl.ResourceProperty;
@@ -20,6 +21,11 @@
 	}
 
 	@Override
+	public RwProp<ImmRect> centeringRect() {
+		return getBean().makeValueProp("centeringRect", ImmRect.class, ImmRect.ZERO_RECT);
+	}
+	
+	@Override
 	public RwProp<ImmColor> backgroundColor() {
 		return getBean().makeValueProp("backgroundColor", ImmColor.class,
 				ImmColor.GRAY);
Index: modules/org.sophie2.main.scene.simple/src/main/java/org/sophie2/main/scene/simple/SimpleSceneVisual.java
===================================================================
--- modules/org.sophie2.main.scene.simple/src/main/java/org/sophie2/main/scene/simple/SimpleSceneVisual.java	(revision 9068)
+++ modules/org.sophie2.main.scene.simple/src/main/java/org/sophie2/main/scene/simple/SimpleSceneVisual.java	(working copy)
@@ -5,8 +5,10 @@
 
 import javax.swing.JComponent;
 import javax.swing.JPanel;
+import javax.swing.JScrollPane;
 
 import org.sophie2.base.commons.util.position.ImmRect;
+import org.sophie2.base.commons.util.position.ImmSize;
 import org.sophie2.base.scene.BaseSceneVisual;
 import org.sophie2.base.scene.SceneVisual;
 import org.sophie2.base.scene.helpers.SceneHelper;
@@ -16,7 +18,7 @@
 /**
  * Simple scene implementation.
  * 
- * @author milo, peko, nenko, mira, gogov
+ * @author milo, peko, nenko, mira, gogov, tanya, stefan
  */
 @SkinElementId("main.scene.simple.simple-scene-visual")
 public class SimpleSceneVisual extends BaseSceneVisual {
@@ -37,7 +39,9 @@
 		private static final long serialVersionUID = 4801814966438437503L;
 
 		private long lastPaintTime = System.currentTimeMillis();
-
+		
+		private static final int OFFSET = 2;
+		
 		@Override
 		protected void paintComponent(Graphics graphics) {
 
@@ -53,12 +57,45 @@
 			SophieLog.trace("paintComponent: parent=" + getParent());
 
 			Graphics2D g2d = (Graphics2D) graphics.create();
-			ImmRect visRect = actualViewRect().get();
+			//Centering the actual view rectangle.
+			
+			SophieLog.debugf("\n%s\n\t%s\n\t\t%s\n\t\t\t%s",
+					this.getParent().getParent().getParent().toString(),
+					this.getParent().getParent().toString(),
+					this.getParent().toString(), this.toString());
+			
+			JScrollPane container = findParentScrollPane(this, 6);
+			
+			if (container != null) {
+				viewportSize().set(new ImmSize(container.getWidth(), container.getHeight()));
+			}
+			
+			ImmRect actRect = actualViewRect().get();
+			ImmRect lstRect = lastViewRect().get();
 
-			SceneHelper.paint(g2d, visRect, scene().get());
-
+			if (container != null) {
+				if (!lstRect.equals(actRect)) {
+					if (lstRect.getY() > actRect.getY()) {			
+						container.getVerticalScrollBar().setValue(0);
+					} else if (lstRect.getHeight() + OFFSET + lstRect.getY() < actRect.getHeight() + actRect.getY()
+							&& lstRect.getY() <= actRect.getY()) {
+						container.getVerticalScrollBar().setValue(container.getVerticalScrollBar().getMaximum());
+					}
+					
+					if (lstRect.getX() > actRect.getX()) {
+						container.getHorizontalScrollBar().setValue(0);						
+					} else if (lstRect.getWidth() + OFFSET + lstRect.getX() < actRect.getWidth() + actRect.getX()
+							&& lstRect.getX() <= actRect.getX()) {
+						container.getHorizontalScrollBar().setValue(container.getHorizontalScrollBar().getMaximum());
+					}
+				}
+			}
+			
+			lastViewRect().set(actualViewRect().get());
+			SceneHelper.paint(g2d, actualViewRect().get(), scene().get());
 			SophieLog.debug("paintComponent: total paint time="
 					+ (System.currentTimeMillis() - startTime));
+			
 		}
 	}
 }
Index: modules/org.sophie2.main.scene.sprites/src/main/java/org/sophie2/main/scene/sprites/SpritesSceneVisual.java
===================================================================
--- modules/org.sophie2.main.scene.sprites/src/main/java/org/sophie2/main/scene/sprites/SpritesSceneVisual.java	(revision 9068)
+++ modules/org.sophie2.main.scene.sprites/src/main/java/org/sophie2/main/scene/sprites/SpritesSceneVisual.java	(working copy)
@@ -52,7 +52,7 @@
 			SophieLog.trace("paintComponent: parent=" + getParent());
 
 			Graphics2D g2d = (Graphics2D) graphics.create();
-			ImmRect visRect = actualViewRect().get();
+			ImmRect visRect = lastViewRect().get();
 			
 			SceneHelper.paintSprite(g2d, visRect, scene().get());
 
Index: modules/org.sophie2.dev/src/main/java/org/sophie2/dev/author/FakeAuthorMain.java
===================================================================
--- modules/org.sophie2.dev/src/main/java/org/sophie2/dev/author/FakeAuthorMain.java	(revision 9068)
+++ modules/org.sophie2.dev/src/main/java/org/sophie2/dev/author/FakeAuthorMain.java	(working copy)
@@ -114,6 +114,11 @@
 		SophieLog.setMinLevel("org.sophie2.base.commons.util", LogLevel.DEBUG);
 		SophieLog.setMinLevel("org.sophie2.base.model.resources.r4.model", LogLevel.DEBUG);
 		SophieLog.setMinLevel("org.sophie2.main.app.commons.book", LogLevel.DEBUG);
+		SophieLog.setMinLevel("org.sophie2.base.scene.BaseSceneVisual", LogLevel.DEBUG);
+//		SophieLog.setMinLevel("org.sophie2.main.scene.simple.SimpleSceneVisual", LogLevel.DEBUG);
+		SophieLog.setMinLevel("org.sophie2.base.layout.impl.DesktopManager", LogLevel.DEBUG);
+		
+		SophieLog.setMinLevel("org.sophie2.main.app.commons.frame", LogLevel.DEBUG);
 		
 		assert System.getProperty(SophieEditions.PROP_ID) == null :
 			"You have set edition in fake mode?" ;
Index: modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/SceneVisual.java
===================================================================
--- modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/SceneVisual.java	(revision 9068)
+++ modules/org.sophie2.base.scene/src/main/java/org/sophie2/base/scene/SceneVisual.java	(working copy)
@@ -32,25 +32,7 @@
 	 * @return property
 	 */
 	RwProp<ImmRect> wantedViewRect();
-
-	/** 
-	 * The smallest rectangle this scene should have. 
-	 *  
-	 * Use this to tell the scene it should be larger than its components, for example, 
-	 * to fill out a window. 
-	 *  
-	 * @return property 
-	 */ 
-	RwProp<ImmRect> minimalViewRect(); 
-
-	/** 
-	 * Last known value of the actual view rect, so PageWorkArea can listen for changes 
-	 *  
-	 * Only set this value when it has actually changed 
-	 *  
-	 * @return property 
-	 */ 
-	RwProp<ImmRect> actualViewRectCache(); 
+	
 	/**
 	 * The swing component displaying the scene.
 	 * 
@@ -72,5 +54,20 @@
 	 * 
 	 * @return property
 	 */
-	Prop<ImmRect> actualViewRect();
+	RwProp<ImmRect> lastViewRect();
+	
+	/**
+	 * Minimal part of the scene that will be displayed.
+	 * 
+	 * @return property
+	 */
+	Prop<ImmRect> minimalViewRect();
+
+	/**
+	 * Contains what the dimension of the visible part of the scene should be if
+	 * we want the visible part of the scene to surround the halos.
+	 * 
+	 * @return property
+	 */
+	RwProp<ImmRect> actualViewRect();
 }
Index: modules/org.sophie2.main.scene.jogl/src/main/java/org/sophie2/main/scene/jogl/JoglSceneVisual.java
===================================================================
--- modules/org.sophie2.main.scene.jogl/src/main/java/org/sophie2/main/scene/jogl/JoglSceneVisual.java	(revision 9068)
+++ modules/org.sophie2.main.scene.jogl/src/main/java/org/sophie2/main/scene/jogl/JoglSceneVisual.java	(working copy)
@@ -64,7 +64,7 @@
 		public void display(GLAutoDrawable drawable) {
 			final GL2 gl = drawable.getGL().getGL2();
 			
-			SceneHelper.paint(gl, actualViewRect().get(),	scene().get());
+			SceneHelper.paint(gl, lastViewRect().get(),	scene().get());
 		}
 		
 		public void reshape(GLAutoDrawable drawable,
Index: modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/DocumentsLogic.java
===================================================================
--- modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/DocumentsLogic.java	(revision 9068)
+++ modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/DocumentsLogic.java	(working copy)
@@ -4,7 +4,6 @@
 import org.sophie2.base.layout.impl.DefaultDocView;
 import org.sophie2.base.model.resources.r4.ResourceRefR4;
 import org.sophie2.base.model.resources.r4.access.ResourceAccess;
-import org.sophie2.core.logging.SophieLog;
 import org.sophie2.core.modularity.SortKey;
 import org.sophie2.core.mvc.EventFilterBuilder;
 import org.sophie2.core.mvc.EventParams;
@@ -128,28 +127,6 @@
 			
 			return true;
 		}
-		
-	},
-
-	
-	/**
-	 * Handles resizing of the window by the user. Should center the page in the
-	 * window.
-	 */
-	@SortKey("fff-document-resize")
-	ON_RESIZE {
-
-		public void defineFilter(EventFilterBuilder filter) {
-			filter.setEventId(DefaultDocView.EventIds.RESIZE);
-			filter.setSourceClass(DefaultDocView.class);
-		}
-
-		public boolean handle(EventR3 event) {
-			// FIXME (R4) Reimplement page centering. This might need to go down to the layout.
-			SophieLog.warn("(R4) Reimplement page centering!");
-			return false;
-		}
-
 	};
 	
 	/**
Index: modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/frame/MainTitleBarHalo.java
===================================================================
--- modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/frame/MainTitleBarHalo.java	(revision 9068)
+++ modules/org.sophie2.main.app.halos/src/main/java/org/sophie2/main/app/halos/frame/MainTitleBarHalo.java	(working copy)
@@ -46,6 +46,7 @@
 import org.sophie2.core.prolib.interfaces.RwProp;
 import org.sophie2.core.prolib.list.ComposingProList;
 import org.sophie2.core.prolib.list.ProList;
+import org.sophie2.main.app.commons.PageAreaMouseCapture;
 import org.sophie2.main.app.commons.element.ElementView;
 import org.sophie2.main.app.commons.element.GroupView;
 import org.sophie2.main.app.commons.frame.FrameView;
@@ -260,9 +261,11 @@
 	 */
 	protected MouseCapture captureClick(MouseEvent e) {
 
+		final PageWorkArea pwa = workArea().get(); 
+
 		// lock the view rect, so that we don't have auto-scrolls while moving.
-		final SceneVisual sv = workArea().get().sceneVisual().get();
-		sv.wantedViewRect().set(sv.actualViewRect().get());
+		final SceneVisual sv = pwa.sceneVisual().get();
+		sv.wantedViewRect().set(sv.lastViewRect().get());
 
 		// get the selected frame locations before start moving
 		ResourceRefList frameRefs = ResourceRefList.EMPTY;
@@ -296,7 +299,7 @@
 
 
 		//TODO: rewrite --milo
-		MouseCapture result = new MouseCapture(0, 0, e) {
+		PageAreaMouseCapture result = new PageAreaMouseCapture(0, 0, e) {
 
 			private void releasedAction(
 					final ImmList<ImmPoint> oldPositions,
@@ -311,7 +314,7 @@
 			private void moveAction(
 					ImmList<ImmPoint> oldPositions,
 					ResourceRefList refs, ImmList<TimePos> times, final int newX, final int newY) {
-
+				
 				if (currentPage().get() == null) {
 					return;
 				}
@@ -340,7 +343,7 @@
 			}
 
 			@Override
-			public void released() {
+			public void onReleased() {
 				sv.wantedViewRect().set(null);
 				releasedAction(finalOldLocations, finalFrameRefs, finalTimes);
 			}
@@ -348,7 +351,11 @@
 			@Override
 			public void shouldMove(final int newX, final int newY) {
 				moveAction(finalOldLocations, finalFrameRefs, finalTimes, newX, newY);
+			}
 
+			@Override
+			public PageWorkArea getWorkArea() {
+				return pwa;
 			}
 		};
 		return result;


