basic RootBox

The RootBox is the root of the box model. It has a fixed width and it
expands in vertical direction. There are is no margin, padding, or any
visual representation of the root box.

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/boxes/TestRootBox.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/boxes/TestRootBox.java
new file mode 100644
index 0000000..e9d631f
--- /dev/null
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/boxes/TestRootBox.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * 		Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.boxes;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Florian Thienel
+ */
+public class TestRootBox {
+
+	private RootBox box;
+
+	@Before
+	public void setUp() throws Exception {
+		box = new RootBox();
+	}
+
+	@Test
+	public void whenCreated_hasNoWidth() throws Exception {
+		assertEquals(0, box.getWidth());
+	}
+
+	@Test
+	public void widthIsSetable() throws Exception {
+		box.setWidth(100);
+		assertEquals(100, box.getWidth());
+	}
+
+}
diff --git a/org.eclipse.vex.core/META-INF/MANIFEST.MF b/org.eclipse.vex.core/META-INF/MANIFEST.MF
index 2bb22bb..3aac23c 100644
--- a/org.eclipse.vex.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.vex.core/META-INF/MANIFEST.MF
@@ -17,6 +17,7 @@
  org.eclipse.jface.text;bundle-version="[3.8.0,4.0.0)"
 Export-Package: org.eclipse.vex.core,
  org.eclipse.vex.core.internal;x-friends:="org.eclipse.vex.ui,org.eclipse.vex.core.tests,org.eclipse.vex.ui.tests",
+ org.eclipse.vex.core.internal.boxes;x-friends:="org.eclipse.vex.core.tests",
  org.eclipse.vex.core.internal.core;x-friends:="org.eclipse.vex.ui,org.eclipse.vex.core.tests,org.eclipse.vex.ui.tests",
  org.eclipse.vex.core.internal.css;x-friends:="org.eclipse.vex.ui,org.eclipse.vex.core.tests,org.eclipse.vex.ui.tests",
  org.eclipse.vex.core.internal.dom;x-friends:="org.eclipse.vex.ui,org.eclipse.vex.core.tests,org.eclipse.vex.ui.tests",
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/BaseBoxVisitor.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/BaseBoxVisitor.java
new file mode 100644
index 0000000..8290c88
--- /dev/null
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/BaseBoxVisitor.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * 		Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.boxes;
+
+/**
+ * @author Florian Thienel
+ */
+public class BaseBoxVisitor implements IBoxVisitor {
+
+	@Override
+	public void visit(final RootBox box) {
+		// ignore
+	}
+
+}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBox.java
new file mode 100644
index 0000000..24546c5
--- /dev/null
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBox.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * 		Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.boxes;
+
+/**
+ * @author Florian Thienel
+ */
+public interface IBox {
+
+	int getWidth();
+
+	int getHeight();
+
+	void accept(IBoxVisitor visitor);
+}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBoxVisitor.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBoxVisitor.java
new file mode 100644
index 0000000..96311b4
--- /dev/null
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBoxVisitor.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * 		Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.boxes;
+
+/**
+ * @author Florian Thienel
+ */
+public interface IBoxVisitor {
+
+	void visit(RootBox box);
+}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/RootBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/RootBox.java
new file mode 100644
index 0000000..51b7498
--- /dev/null
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/RootBox.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * 		Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.boxes;
+
+/**
+ * @author Florian Thienel
+ */
+public class RootBox implements IBox {
+
+	private int width;
+
+	public int getWidth() {
+		return width;
+	}
+
+	public void setWidth(final int width) {
+		this.width = width;
+	}
+
+	public int getHeight() {
+		return 0;
+	}
+
+	public void accept(final IBoxVisitor visitor) {
+		visitor.visit(this);
+	}
+
+}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java
index e272949..e308379 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java
@@ -11,6 +11,8 @@
 package org.eclipse.vex.core.internal.widget.swt;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
 import org.eclipse.swt.events.PaintEvent;
 import org.eclipse.swt.events.PaintListener;
 import org.eclipse.swt.events.SelectionEvent;
@@ -18,6 +20,7 @@
 import org.eclipse.swt.widgets.Canvas;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.vex.core.internal.boxes.RootBox;
 
 /**
  * A widget to show the new box model.
@@ -26,15 +29,20 @@
  */
 public class BoxWidget extends Canvas {
 
+	private final RootBox rootBox;
+
 	public BoxWidget(final Composite parent, final int style) {
 		super(parent, style);
-		connectPainting();
+		connectPaintControl();
+		connectResize();
 		if ((style & SWT.V_SCROLL) == SWT.V_SCROLL) {
-			connectVerticalBar();
+			connectScrollVertically();
 		}
+
+		rootBox = new RootBox();
 	}
 
-	private void connectPainting() {
+	private void connectPaintControl() {
 		addPaintListener(new PaintListener() {
 			@Override
 			public void paintControl(final PaintEvent e) {
@@ -43,7 +51,21 @@
 		});
 	}
 
-	private void connectVerticalBar() {
+	private void connectResize() {
+		addControlListener(new ControlListener() {
+			@Override
+			public void controlResized(final ControlEvent e) {
+				resize(e);
+			}
+
+			@Override
+			public void controlMoved(final ControlEvent e) {
+				// ignore
+			}
+		});
+	}
+
+	private void connectScrollVertically() {
 		getVerticalBar().addSelectionListener(new SelectionListener() {
 			@Override
 			public void widgetSelected(final SelectionEvent e) {
@@ -62,6 +84,10 @@
 		event.gc.fillRectangle(getClientArea());
 	}
 
+	private void resize(final ControlEvent event) {
+		rootBox.setWidth(getClientArea().width);
+	}
+
 	private void scrollVertically(final SelectionEvent event) {
 
 	}