From 61e5a7ae2ccd332b08d6509dd1769befd6b7f9b6 Mon Sep 17 00:00:00 2001 From: Jouni Koivuviita Date: Thu, 15 Nov 2007 13:38:58 +0000 Subject: [PATCH] MAJOR UPDATE: -Layout API changes: Layout extends Sizeable, Layout has two methods setMargin. -OrderedLayout and GridLayout got two new mehtods: setSpacing and setComponentAlignment. -Client-side layout implementations now mainly done using TABLE elements (changes to IOrderedLayout and IExpandLayout). -IScrollTable initial height calculation modified (small fix, clientHeight -> offsetHeight). -Some test modified to conform to new layout API. -Small typo fixes in comments. -OrderedLayout fix when changing orientation on the fly. -Panel and TabSheet are no longer Layouts, only ComponentContainers. -Refactored layout margins to use MarginInfo class, more readable, self-documenting code now. svn changeset:2827/svn branch:trunk --- .../toolkit/terminal/gwt/client/Util.java | 12 +- .../terminal/gwt/client/ui/ICustomLayout.java | 1 + .../terminal/gwt/client/ui/IExpandLayout.java | 87 ++++++++- .../gwt/client/ui/IOrderedLayout.java | 180 +++++++++++++----- .../terminal/gwt/client/ui/IScrollTable.java | 2 +- .../terminal/gwt/client/ui/MarginInfo.java | 54 ++++++ .../gwt/public/default/common/common.css | 27 +-- .../terminal/gwt/server/JsonPaintTarget.java | 2 +- .../toolkit/tests/TestCaptionWrapper.java | 32 +++- .../tests/TestComponentsAndLayouts.java | 8 +- src/com/itmill/toolkit/ui/AbstractLayout.java | 157 +++++++++++++-- src/com/itmill/toolkit/ui/ExpandLayout.java | 144 ++------------ src/com/itmill/toolkit/ui/GridLayout.java | 10 +- src/com/itmill/toolkit/ui/Layout.java | 2 +- src/com/itmill/toolkit/ui/OrderedLayout.java | 39 ++-- src/com/itmill/toolkit/ui/Panel.java | 6 +- src/com/itmill/toolkit/ui/SplitPanel.java | 136 +------------ src/com/itmill/toolkit/ui/TabSheet.java | 3 +- 18 files changed, 506 insertions(+), 396 deletions(-) create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/ui/MarginInfo.java diff --git a/src/com/itmill/toolkit/terminal/gwt/client/Util.java b/src/com/itmill/toolkit/terminal/gwt/client/Util.java index 6540e662ec..e440e28f84 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/Util.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/Util.java @@ -31,7 +31,7 @@ public class Util { } return false; }-*/; - + /** * Detects if current browser is IE6. * @@ -41,17 +41,17 @@ public class Util { var browser=$wnd.navigator.appName; if (browser=="Microsoft Internet Explorer") { var ua = navigator.userAgent; - var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); - if (re.exec(ua) != null) - rv = parseFloat(RegExp.$1); - if(rv == 6) return true; + var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); + if (re.exec(ua) != null) + rv = parseFloat(RegExp.$1); + if(rv == 6) return true; } return false; }-*/; /** * Nulls oncontextmenu function on given element. We need to manually clear - * context menu events due bad browsers memory leaks, since we GWT don't + * context menu events due bad browsers memory leaks, since GWT don't * support them. * * @param el diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomLayout.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomLayout.java index 24862dc56b..b8e2da7e8b 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomLayout.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomLayout.java @@ -47,6 +47,7 @@ public class ICustomLayout extends ComplexPanel implements Paintable, public ICustomLayout() { setElement(DOM.createDiv()); + DOM.setStyleAttribute(getElement(), "height", "100%"); } /** diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IExpandLayout.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IExpandLayout.java index 2a838fba1b..bde5b6c543 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IExpandLayout.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IExpandLayout.java @@ -30,16 +30,34 @@ public class IExpandLayout extends IOrderedLayout implements } public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + this.client = client; // Ensure correct implementation if (client.updateComponent(this, uidl, false)) return; - String h = uidl.getStringAttribute("height"); - setHeight(h); - String w = uidl.getStringAttribute("width"); - setWidth(w); + // Set size + if (uidl.hasAttribute("width")) { + setWidth(uidl.getStringAttribute("width")); + DOM.setStyleAttribute(DOM.getFirstChild(DOM + .getFirstChild(getElement())), "width", "100%"); + } else { + setWidth(""); + DOM.setStyleAttribute(DOM.getFirstChild(DOM + .getFirstChild(getElement())), "width", ""); + } + if (uidl.hasAttribute("height")) { + setHeight(uidl.getStringAttribute("height")); + DOM.setStyleAttribute(margin, "height", "100%"); + DOM.setStyleAttribute(DOM.getFirstChild(DOM + .getFirstChild(getElement())), "height", "100%"); + } else { + setHeight(""); + DOM.setStyleAttribute(margin, "height", ""); + DOM.setStyleAttribute(DOM.getFirstChild(DOM + .getFirstChild(getElement())), "height", ""); + } ArrayList uidlWidgets = new ArrayList(); for (Iterator it = uidl.getChildIterator(); it.hasNext();) { @@ -109,6 +127,9 @@ public class IExpandLayout extends IOrderedLayout implements removePaintable(p); } + // Modify layout margins + handleMargins(uidl); + if (uidlWidgets.size() == 0) return; @@ -120,21 +141,64 @@ public class IExpandLayout extends IOrderedLayout implements */ ((Paintable) expandedWidget).updateFromUIDL(expandedWidgetUidl, client); + // Component alignments as a comma separated list. + // See com.itmill.toolkit.ui.OrderedLayout.java for possible values. + String[] alignments = uidl.getStringAttribute("alignments").split(","); + int alignmentIndex = 0; + + // Insert alignment attributes + Iterator it = getPaintables().iterator(); + while (it.hasNext()) { + + // Calculate alignment info + int alignment = Integer.parseInt((alignments[alignmentIndex++])); + // Vertical alignment + String vAlign = "top"; + if ((alignment & ALIGNMENT_TOP) == ALIGNMENT_TOP) + vAlign = "top"; + else if ((alignment & ALIGNMENT_BOTTOM) == ALIGNMENT_BOTTOM) + vAlign = "bottom"; + else if ((alignment & ALIGNMENT_VERTICAL_CENTER) == ALIGNMENT_VERTICAL_CENTER) + vAlign = "middle"; + // Horizontal alignment + String hAlign = ""; + if ((alignment & ALIGNMENT_LEFT) == ALIGNMENT_LEFT) + hAlign = "left"; + else if ((alignment & ALIGNMENT_RIGHT) == ALIGNMENT_RIGHT) + hAlign = "right"; + else if ((alignment & ALIGNMENT_HORIZONTAL_CENTER) == ALIGNMENT_HORIZONTAL_CENTER) + hAlign = "center"; + + Element td = DOM.getParent(((Widget) it.next()).getElement()); + DOM.setStyleAttribute(td, "vertical-align", vAlign); + // TODO use one-cell table to implement horizontal alignments + DOM.setStyleAttribute(td, "text-align", hAlign); + } + } public void iLayout() { if (expandedWidget == null) { return; } - // ApplicationConnection.getConsole().log("EL layouting..."); + // Clear expanded elements height so we get the available height right Element expandedElement = DOM.getParent(expandedWidget.getElement()); + DOM.setStyleAttribute(expandedElement, "height", ""); + DOM.setStyleAttribute(DOM.getParent(expandedElement), "height", ""); + // Get available height + int availableHeight = getOffsetHeight(); + // Clear TABLE height temporarily, so we get used space right + Element table = DOM.getFirstChild(margin); + String height = DOM.getStyleAttribute(table, "height"); + DOM.setStyleAttribute(table, "height", ""); + + // take expanded element temporarely out of flow to make container // minimum sized - String origiginalPositioning = DOM.getStyleAttribute(expandedWidget + String originalPositioning = DOM.getStyleAttribute(expandedWidget .getElement(), "position"); DOM.setStyleAttribute(expandedWidget.getElement(), "position", "absolute"); - DOM.setStyleAttribute(expandedElement, "height", ""); // add temp element to make some measurements Element meter = createWidgetWrappper(); @@ -145,19 +209,22 @@ public class IExpandLayout extends IOrderedLayout implements - DOM.getElementPropertyInt(DOM.getFirstChild(childContainer), "offsetTop"); - int freeSpace = getOffsetHeight() - usedSpace; + int freeSpace = availableHeight - usedSpace; if (freeSpace < 0) freeSpace = 0; DOM.setStyleAttribute(expandedElement, "height", freeSpace + "px"); + DOM.setStyleAttribute(DOM.getParent(expandedElement), "height", + freeSpace + "px"); // Component margins will bleed if overflow is not hidden - DOM.setStyleAttribute(expandedElement, "overflow", "auto"); + //DOM.setStyleAttribute(expandedElement, "overflow", "hidden"); DOM.setStyleAttribute(expandedWidget.getElement(), "position", - origiginalPositioning); + originalPositioning); DOM.removeChild(childContainer, meter); + DOM.setStyleAttribute(table, "height", height); // TODO save previous size and only propagate if really changed Util.runDescendentsLayout(this); diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java index fdf50c4d43..7ac6598706 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java @@ -43,15 +43,21 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { protected ApplicationConnection client; /** - * Contains reference to Element where Paintables are wrapped. For - * horizontal layout this is TR and for vertical DIV. + * Contains reference to Element where Paintables are wrapped. Normally a TR + * or a TBODY element. */ protected Element childContainer; - + /* - * Element that provides margins. + * Elements that provides the Layout interface implementation. */ - private Element margin; + protected Element size; + protected Element margin; + + protected Element topMargin = null; + protected Element bottomMargin = null; + + private static final String structure = "
"; public IOrderedLayout(int orientation) { orientationMode = orientation; @@ -60,25 +66,16 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { } protected void constructDOM() { - switch (orientationMode) { - case ORIENTATION_HORIZONTAL: - Element table = DOM.createTable(); - Element tBody = DOM.createTBody(); + size = DOM.createDiv(); + DOM.setInnerHTML(size, structure); + margin = DOM.getFirstChild(size); + Element tBody = DOM.getFirstChild(DOM.getFirstChild(margin)); + if (orientationMode == ORIENTATION_HORIZONTAL) { childContainer = DOM.createTR(); - DOM.appendChild(table, tBody); DOM.appendChild(tBody, childContainer); - setElement(table); - // prevent unwanted spacing - DOM.setElementAttribute(table, "cellSpacing", "0"); - DOM.setElementAttribute(table, "cellPadding", "0"); - margin = table; - break; - default: - childContainer = DOM.createDiv(); - setElement(childContainer); - margin = childContainer; - break; - } + } else + childContainer = tBody; + setElement(size); } public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { @@ -89,6 +86,25 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { if (client.updateComponent(this, uidl, false)) return; + // Set size + if (uidl.hasAttribute("width")) { + setWidth(uidl.getStringAttribute("width")); + DOM.setStyleAttribute(DOM.getFirstChild(margin), "width", "100%"); + } else { + setWidth(""); + DOM.setStyleAttribute(DOM.getFirstChild(margin), "width", ""); + } + if (uidl.hasAttribute("height")) { + setHeight(uidl.getStringAttribute("height")); + // TODO override setHeight() method and move these there + DOM.setStyleAttribute(margin, "height", "100%"); + DOM.setStyleAttribute(DOM.getFirstChild(margin), "height", "100%"); + } else { + setHeight(""); + DOM.setStyleAttribute(margin, "height", ""); + DOM.setStyleAttribute(DOM.getFirstChild(margin), "height", ""); + } + ArrayList uidlWidgets = new ArrayList(); for (Iterator it = uidl.getChildIterator(); it.hasNext();) { UIDL uidlForChild = (UIDL) it.next(); @@ -155,7 +171,8 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { // Component alignments as a comma separated list. // See com.itmill.toolkit.ui.OrderedLayout.java for possible values. - String[] alignments = uidl.getStringAttribute("alignments").split(","); + int[] alignments = uidl.getIntArrayAttribute("alignments"); + int alignmentIndex = 0; // Insert alignment attributes @@ -163,9 +180,9 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { while (it.hasNext()) { // Calculate alignment info - int alignment = Integer.parseInt((alignments[alignmentIndex++])); + int alignment = alignments[alignmentIndex++]; // Vertical alignment - String vAlign = ""; + String vAlign = "top"; if ((alignment & ALIGNMENT_TOP) == ALIGNMENT_TOP) vAlign = "top"; else if ((alignment & ALIGNMENT_BOTTOM) == ALIGNMENT_BOTTOM) @@ -183,24 +200,11 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { Element td = DOM.getParent(((Widget) it.next()).getElement()); DOM.setStyleAttribute(td, "vertical-align", vAlign); + // TODO use one-cell table to implement horizontal alignments DOM.setStyleAttribute(td, "text-align", hAlign); } - // Modify layout marginals - String marginClasses = ""; - if (uidl.hasAttribute("marginTop")) - marginClasses += " " + StyleConstants.LAYOUT_MARGIN_TOP; - if (uidl.hasAttribute("marginRight")) - marginClasses += " " + StyleConstants.LAYOUT_MARGIN_RIGHT; - if (uidl.hasAttribute("marginBottom")) - marginClasses += " " + StyleConstants.LAYOUT_MARGIN_BOTTOM; - if (uidl.hasAttribute("marginLeft")) - marginClasses += " " + StyleConstants.LAYOUT_MARGIN_LEFT; - - if(marginClasses.equals("")) - DOM.setElementProperty(margin, "className", CLASSNAME); - else - DOM.setElementProperty(margin, "className", CLASSNAME + marginClasses); + handleMargins(uidl); } @@ -269,21 +273,35 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { DOM.insertChild(container, captionContainer, 0); insert(w, captionContainer, beforeIndex, false); } else { - Element container = createWidgetWrappper(); - DOM.insertChild(childContainer, container, beforeIndex); - insert(w, container, beforeIndex, false); + Element wrapper = createWidgetWrappper(); + DOM.insertChild(childContainer, wrapper, beforeIndex); + insert(w, getWidgetContainerFromWrapper(wrapper), beforeIndex, + false); } } - + + protected Element getWidgetContainerFromWrapper(Element wrapper) { + switch (orientationMode) { + case ORIENTATION_HORIZONTAL: + return wrapper; + default: + return DOM.getFirstChild(wrapper); + } + } + /** * creates an Element which will contain child widget */ protected Element createWidgetWrappper() { + Element td = DOM.createTD(); + //DOM.setStyleAttribute(td, "overflow", "hidden"); switch (orientationMode) { case ORIENTATION_HORIZONTAL: - return DOM.createTD(); + return td; default: - return DOM.createDiv(); + Element tr = DOM.createTR(); + DOM.appendChild(tr, td); + return tr; } } @@ -322,7 +340,8 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { public void add(Widget w) { Element wrapper = createWidgetWrappper(); DOM.appendChild(childContainer, wrapper); - super.add(w, wrapper); + super.add(w, orientationMode == ORIENTATION_HORIZONTAL ? wrapper : DOM + .getFirstChild(wrapper)); } public boolean remove(int index) { @@ -334,7 +353,9 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { boolean removed = super.remove(w); if (removed) { if (!(w instanceof Caption)) { - DOM.removeChild(childContainer, wrapper); + DOM.removeChild(childContainer, + orientationMode == ORIENTATION_HORIZONTAL ? wrapper + : DOM.getParent(wrapper)); } return true; } @@ -353,4 +374,67 @@ public abstract class IOrderedLayout extends ComplexPanel implements Container { return getChildren().indexOf(child); } + protected void handleMargins(UIDL uidl) { + // Modify layout margins + String marginClasses = ""; + MarginInfo margins = new MarginInfo(uidl.getIntAttribute("margins")); + + // Top margin + if (margins.hasTop()) { + marginClasses += " " + StyleConstants.LAYOUT_MARGIN_TOP; + if (topMargin == null) { + // We need to insert a new row in to the table + topMargin = createWidgetWrappper(); + DOM.appendChild(getWidgetContainerFromWrapper(topMargin), DOM + .createDiv()); + DOM.setElementProperty(topMargin, "className", CLASSNAME + + "-toppad"); + if (orientationMode == ORIENTATION_HORIZONTAL) { + DOM.setElementAttribute(DOM.getFirstChild(topMargin), + "colspan", "" + getPaintables().size()); + } + DOM.insertChild(childContainer, topMargin, 0); + } + } else { + if (topMargin != null) + DOM.removeChild(childContainer, DOM + .getFirstChild(childContainer)); + topMargin = null; + } + + // Right margin + if (margins.hasRight()) + marginClasses += " " + StyleConstants.LAYOUT_MARGIN_RIGHT; + + // Bottom margin + if (margins.hasBottom()) { + marginClasses += " " + StyleConstants.LAYOUT_MARGIN_BOTTOM; + if (bottomMargin == null) { + // We need to insert a new row in to the table + bottomMargin = createWidgetWrappper(); + DOM.appendChild(getWidgetContainerFromWrapper(bottomMargin), + DOM.createDiv()); + DOM.setElementProperty(bottomMargin, "className", CLASSNAME + + "-bottompad"); + if (orientationMode == ORIENTATION_HORIZONTAL) { + DOM.setElementAttribute(DOM.getFirstChild(bottomMargin), + "colspan", "" + getPaintables().size()); + } + DOM.appendChild(childContainer, bottomMargin); + } + } else { + if (bottomMargin != null) + DOM.removeChild(childContainer, DOM.getChild(childContainer, + DOM.getChildCount(childContainer) - 1)); + bottomMargin = null; + } + + // Left margin + if (margins.hasLeft()) + marginClasses += " " + StyleConstants.LAYOUT_MARGIN_LEFT; + + // Add + DOM.setElementProperty(margin, "className", marginClasses); + } + } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java index dcb6c6222b..5ff0e3e5c1 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java @@ -1982,7 +1982,7 @@ public class IScrollTable extends Composite implements Table, ScrollListener, DOM.setStyleAttribute(getElement(), "position", "absolute"); // get containers natural space for table int availPixels = DOM.getElementPropertyInt(parentElem, - "clientHeight"); + "offsetHeight"); // put table back to flow DOM.setStyleAttribute(getElement(), "position", "static"); // set 100% height with borders diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/MarginInfo.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/MarginInfo.java new file mode 100644 index 0000000000..e1aa952743 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/MarginInfo.java @@ -0,0 +1,54 @@ +package com.itmill.toolkit.terminal.gwt.client.ui; + +public class MarginInfo { + + private static final int TOP = 1; + private static final int RIGHT = 2; + private static final int BOTTOM = 4; + private static final int LEFT = 8; + + + private int bitMask; + + public MarginInfo(int bitMask) { + this.bitMask = bitMask; + } + + public MarginInfo(boolean top, boolean right, boolean bottom, boolean left) { + setMargins(top,right,bottom,left); + } + + public void setMargins(boolean top, boolean right, boolean bottom, boolean left) { + bitMask = top ? TOP : 0; + bitMask += right ? RIGHT : 0; + bitMask += bottom ? BOTTOM : 0; + bitMask += left ? LEFT : 0; + } + + public boolean hasLeft() { + return (bitMask & LEFT) == LEFT; + } + + public boolean hasRight() { + return (bitMask & RIGHT) == RIGHT; + } + + public boolean hasTop() { + return (bitMask & TOP) == TOP; + } + public boolean hasBottom() { + return (bitMask & BOTTOM) == BOTTOM; + } + + public int getBitMask() { + return bitMask; + } + + public void setMargins(boolean enabled) { + if(enabled) { + bitMask = TOP + RIGHT + BOTTOM + LEFT; + } else { + bitMask = 0; + } + } +} diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css b/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css index f989be5a63..993627c73a 100644 --- a/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css +++ b/src/com/itmill/toolkit/terminal/gwt/public/default/common/common.css @@ -88,27 +88,28 @@ vertical-align: middle; } -/* Provide some extra whitespace for wrapped elements - (these elements usually need the extra space, since - they aren't even handling their own caption) */ -.i-captionwrapper { - margin: 0.3em 0 0 0; -} +/* TODO move to layout.css */ /* Layout margin values */ -.i-layoutmargin-top { - margin-top: 15px; -} -.i-layoutmargin-bottom { - margin-bottom: 15px; + +.i-layoutmargin-top .i-orderedlayout-toppad div, +.i-layoutmargin-bottom .i-orderedlayout-bottompad div, +.i-layoutmargin-top .i-expandlayout-toppad div, +.i-layoutmargin-bottom .i-expandlayout-bottompad div, +.i-layoutmargin-top .i-orderedlayout-toppad td, +.i-layoutmargin-bottom .i-orderedlayout-bottompad td, +.i-layoutmargin-top .i-expandlayout-toppad td, +.i-layoutmargin-bottom .i-expandlayout-bottompad td { + height: 15px; + overflow: hidden; } .i-layoutmargin-left { - margin-left: 18px; + padding-left: 18px; } .i-layoutmargin-right { - margin-right: 18px; + padding-right: 18px; } .i-link { diff --git a/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java b/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java index 50e33c06c2..1361a485ff 100644 --- a/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java +++ b/src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java @@ -366,7 +366,7 @@ public class JsonPaintTarget implements PaintTarget { } /** - * Adds a resource attribute to component. Atributes must be added before + * Adds a resource attribute to component. Attributes must be added before * any content is written. * * @param name diff --git a/src/com/itmill/toolkit/tests/TestCaptionWrapper.java b/src/com/itmill/toolkit/tests/TestCaptionWrapper.java index 0fa2bc7165..9809617698 100644 --- a/src/com/itmill/toolkit/tests/TestCaptionWrapper.java +++ b/src/com/itmill/toolkit/tests/TestCaptionWrapper.java @@ -4,8 +4,32 @@ import com.itmill.toolkit.terminal.ClassResource; import com.itmill.toolkit.terminal.ErrorMessage; import com.itmill.toolkit.terminal.ExternalResource; import com.itmill.toolkit.terminal.UserError; - -import com.itmill.toolkit.ui.*; +import com.itmill.toolkit.ui.AbstractComponent; +import com.itmill.toolkit.ui.Button; +import com.itmill.toolkit.ui.CheckBox; +import com.itmill.toolkit.ui.CustomComponent; +import com.itmill.toolkit.ui.DateField; +import com.itmill.toolkit.ui.Embedded; +import com.itmill.toolkit.ui.ExpandLayout; +import com.itmill.toolkit.ui.GridLayout; +import com.itmill.toolkit.ui.Label; +import com.itmill.toolkit.ui.Layout; +import com.itmill.toolkit.ui.Link; +import com.itmill.toolkit.ui.NativeSelect; +import com.itmill.toolkit.ui.OptionGroup; +import com.itmill.toolkit.ui.OrderedLayout; +import com.itmill.toolkit.ui.Panel; +import com.itmill.toolkit.ui.ProgressIndicator; +import com.itmill.toolkit.ui.RichTextArea; +import com.itmill.toolkit.ui.Select; +import com.itmill.toolkit.ui.Slider; +import com.itmill.toolkit.ui.TabSheet; +import com.itmill.toolkit.ui.Table; +import com.itmill.toolkit.ui.TextField; +import com.itmill.toolkit.ui.Tree; +import com.itmill.toolkit.ui.TwinColSelect; +import com.itmill.toolkit.ui.Upload; +import com.itmill.toolkit.ui.Window; import com.itmill.toolkit.ui.Component.Listener; public class TestCaptionWrapper extends CustomComponent implements Listener { @@ -43,7 +67,7 @@ public class TestCaptionWrapper extends CustomComponent implements Listener { Panel panel = new Panel("Panel"); test(panel); - populateLayout(panel); + populateLayout(panel.getLayout()); TabSheet tabsheet = new TabSheet(); test(tabsheet); @@ -67,7 +91,7 @@ public class TestCaptionWrapper extends CustomComponent implements Listener { Window window = new Window("TEST: Window"); test(window); - populateLayout(window); + populateLayout(window.getLayout()); } diff --git a/src/com/itmill/toolkit/tests/TestComponentsAndLayouts.java b/src/com/itmill/toolkit/tests/TestComponentsAndLayouts.java index 2bf06d0193..8d985ed0d1 100644 --- a/src/com/itmill/toolkit/tests/TestComponentsAndLayouts.java +++ b/src/com/itmill/toolkit/tests/TestComponentsAndLayouts.java @@ -81,7 +81,7 @@ public class TestComponentsAndLayouts extends Application implements Listener, setMainWindow(main); // By default push all containers inside main window - Layout target = main; + Layout target = main.getLayout(); main .addComponent(new Label( @@ -97,10 +97,10 @@ public class TestComponentsAndLayouts extends Application implements Listener, if (false) { // push every container and their components inside window - target = window; + target = window.getLayout(); } else { // window is just one container to be tested - populateLayout(window); + populateLayout(window.getLayout()); } getMainWindow().addWindow(window); } @@ -148,7 +148,7 @@ public class TestComponentsAndLayouts extends Application implements Listener, "

Components inside Panel

", Label.CONTENT_XHTML)); Panel panel = new Panel("Panel"); - populateLayout(panel); + populateLayout(panel.getLayout()); target.addComponent(panel); } diff --git a/src/com/itmill/toolkit/ui/AbstractLayout.java b/src/com/itmill/toolkit/ui/AbstractLayout.java index 10dc8694ba..6e7049bacc 100644 --- a/src/com/itmill/toolkit/ui/AbstractLayout.java +++ b/src/com/itmill/toolkit/ui/AbstractLayout.java @@ -2,6 +2,8 @@ package com.itmill.toolkit.ui; import com.itmill.toolkit.terminal.PaintException; import com.itmill.toolkit.terminal.PaintTarget; +import com.itmill.toolkit.terminal.Sizeable; +import com.itmill.toolkit.terminal.gwt.client.ui.MarginInfo; /** * An abstract class that defines default implementation for the {@link Layout} @@ -15,12 +17,31 @@ import com.itmill.toolkit.terminal.PaintTarget; public abstract class AbstractLayout extends AbstractComponentContainer implements Layout { + protected MarginInfo margins = new MarginInfo(false,false,false,false); + /** - * Layout edge margins, clockwise from top: top, right, bottom, left. Each - * is set to true, if the client-side implementation should leave extra - * space at that edge. + * Height of the layout. Set to -1 for undefined height. */ - protected boolean[] margins; + private int height = -1; + + /** + * Height unit. + * + * @see com.itmill.toolkit.terminal.Sizeable.UNIT_SYMBOLS; + */ + private int heightUnit = UNITS_PIXELS; + + /** + * Width of the layout. Set to -1 for undefined width. + */ + private int width = -1; + + /** + * Width unit. + * + * @see com.itmill.toolkit.terminal.Sizeable.UNIT_SYMBOLS; + */ + private int widthUnit = UNITS_PIXELS; /* * (non-Javadoc) @@ -35,7 +56,8 @@ public abstract class AbstractLayout extends AbstractComponentContainer * @see com.itmill.toolkit.ui.Layout#setMargin(boolean) */ public void setMargin(boolean enabled) { - margins = new boolean[] { enabled, enabled, enabled, enabled }; + margins.setMargins(enabled); + requestRepaint(); } /* @@ -46,8 +68,110 @@ public abstract class AbstractLayout extends AbstractComponentContainer */ public void setMargin(boolean topEnabled, boolean rightEnabled, boolean bottomEnabled, boolean leftEnabled) { - margins = new boolean[] { topEnabled, rightEnabled, bottomEnabled, - leftEnabled }; + margins.setMargins(topEnabled, rightEnabled, bottomEnabled, leftEnabled); + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#getHeight() + */ + public int getHeight() { + return height; + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#getHeightUnits() + */ + public int getHeightUnits() { + return heightUnit; + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#getWidth() + */ + public int getWidth() { + return width; + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#getWidthUnits() + */ + public int getWidthUnits() { + return widthUnit; + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#setHeight(int) + */ + public void setHeight(int height) { + this.height = height; + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#setHeightUnits(int) + */ + public void setHeightUnits(int units) { + this.heightUnit = units; + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#setSizeFull() + */ + public void setSizeFull() { + height = 100; + width = 100; + heightUnit = UNITS_PERCENTAGE; + widthUnit = UNITS_PERCENTAGE; + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#setSizeUndefined() + */ + public void setSizeUndefined() { + height = -1; + width = -1; + heightUnit = UNITS_PIXELS; + widthUnit = UNITS_PIXELS; + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#setWidth(int) + */ + public void setWidth(int width) { + this.width = width; + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.terminal.Sizeable#setWidthUnits(int) + */ + public void setWidthUnits(int units) { + this.widthUnit = units; + requestRepaint(); } /* @@ -58,16 +182,15 @@ public abstract class AbstractLayout extends AbstractComponentContainer public void paintContent(PaintTarget target) throws PaintException { // Add margin info. Defaults to false. - if (margins == null) - setMargin(false); - if (margins[0]) - target.addAttribute("marginTop", margins[0]); - if (margins[1]) - target.addAttribute("marginRight", margins[1]); - if (margins[2]) - target.addAttribute("marginBottom", margins[2]); - if (margins[3]) - target.addAttribute("marginLeft", margins[3]); + target.addAttribute("margins", margins.getBitMask()); + + // Size + if (getHeight() >= 0) + target.addAttribute("height", "" + getHeight() + + Sizeable.UNIT_SYMBOLS[getHeightUnits()]); + if (getWidth() >= 0) + target.addAttribute("width", "" + getWidth() + + Sizeable.UNIT_SYMBOLS[getWidthUnits()]); } } diff --git a/src/com/itmill/toolkit/ui/ExpandLayout.java b/src/com/itmill/toolkit/ui/ExpandLayout.java index c8bc8b23a0..33395956b2 100644 --- a/src/com/itmill/toolkit/ui/ExpandLayout.java +++ b/src/com/itmill/toolkit/ui/ExpandLayout.java @@ -21,34 +21,10 @@ import com.itmill.toolkit.terminal.Sizeable; * other components don't use. Or just provide expanded container. * */ -public class ExpandLayout extends OrderedLayout implements Sizeable { +public class ExpandLayout extends OrderedLayout { private Component expanded; - /** - * Height of the layout. Set to -1 for undefined height. - */ - private int height = -1; - - /** - * Height unit. - * - * @see com.itmill.toolkit.terminal.Sizeable.UNIT_SYMBOLS; - */ - private int heightUnit = UNITS_PIXELS; - - /** - * Width of the layout. Set to -1 for undefined width. - */ - private int width = -1; - - /** - * Width unit. - * - * @see com.itmill.toolkit.terminal.Sizeable.UNIT_SYMBOLS; - */ - private int widthUnit = UNITS_PIXELS; - public ExpandLayout() { setSizeFull(); } @@ -72,8 +48,9 @@ public class ExpandLayout extends OrderedLayout implements Sizeable { } public void paintContent(PaintTarget target) throws PaintException { - - //TODO should we add margins? + + // Add margin info. Defaults to false. + target.addAttribute("margins", margins.getBitMask()); // Size if (getHeight() >= 0) @@ -88,6 +65,10 @@ public class ExpandLayout extends OrderedLayout implements Sizeable { if (getOrientation() == ORIENTATION_HORIZONTAL) target.addAttribute("orientation", "horizontal"); + // Store alignment info in this String + StringBuffer alignments = new StringBuffer(); + + // Adds all items in all the locations for (Iterator i = getComponentIterator(); i.hasNext();) { Component c = (Component) i.next(); @@ -98,7 +79,14 @@ public class ExpandLayout extends OrderedLayout implements Sizeable { c.paint(target); target.endTag("cc"); } + alignments.append(getComponentAlignment(c)); + if (i.hasNext()) + alignments.append(","); + } + // Add child component alignment info to layout tag + target.addAttribute("alignments", alignments.toString()); + } public void addComponent(Component c, int index) { @@ -136,106 +124,4 @@ public class ExpandLayout extends OrderedLayout implements Sizeable { expanded = newComponent; } - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getHeight() - */ - public int getHeight() { - return height; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getHeightUnits() - */ - public int getHeightUnits() { - return heightUnit; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getWidth() - */ - public int getWidth() { - return width; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getWidthUnits() - */ - public int getWidthUnits() { - return widthUnit; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setHeight(int) - */ - public void setHeight(int height) { - this.height = height; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setHeightUnits(int) - */ - public void setHeightUnits(int units) { - this.heightUnit = units; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setSizeFull() - */ - public void setSizeFull() { - height = 100; - width = 100; - heightUnit = UNITS_PERCENTAGE; - widthUnit = UNITS_PERCENTAGE; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setSizeUndefined() - */ - public void setSizeUndefined() { - height = -1; - width = -1; - heightUnit = UNITS_PIXELS; - widthUnit = UNITS_PIXELS; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setWidth(int) - */ - public void setWidth(int width) { - this.width = width; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setWidthUnits(int) - */ - public void setWidthUnits(int units) { - this.widthUnit = units; - requestRepaint(); - } - } diff --git a/src/com/itmill/toolkit/ui/GridLayout.java b/src/com/itmill/toolkit/ui/GridLayout.java index 867e75b11a..e5a38efbef 100644 --- a/src/com/itmill/toolkit/ui/GridLayout.java +++ b/src/com/itmill/toolkit/ui/GridLayout.java @@ -825,7 +825,7 @@ public class GridLayout extends AbstractLayout { *

*/ public void setWidth(int width) { - // super.setWidth(width); + super.setWidth(width); } /** @@ -839,8 +839,7 @@ public class GridLayout extends AbstractLayout { *

*/ public int getWidth() { - // return super.getWidth(); - return -1; + return super.getWidth(); } /** @@ -894,7 +893,7 @@ public class GridLayout extends AbstractLayout { *

*/ public void setHeight(int height) { - // super.setHeight(height); + super.setHeight(height); } /** @@ -908,8 +907,7 @@ public class GridLayout extends AbstractLayout { *

*/ public int getHeight() { - // return super.getHeight(); - return -1; + return super.getHeight(); } /** diff --git a/src/com/itmill/toolkit/ui/Layout.java b/src/com/itmill/toolkit/ui/Layout.java index 245675f90b..53c4ed791d 100644 --- a/src/com/itmill/toolkit/ui/Layout.java +++ b/src/com/itmill/toolkit/ui/Layout.java @@ -42,7 +42,7 @@ import com.itmill.toolkit.terminal.Sizeable; * @VERSION@ * @since 3.0 */ -public interface Layout extends ComponentContainer { +public interface Layout extends ComponentContainer, Sizeable { /** * Enable layout margins. Affects all four sides of the layout. This will diff --git a/src/com/itmill/toolkit/ui/OrderedLayout.java b/src/com/itmill/toolkit/ui/OrderedLayout.java index a19c501b50..ac5f0e349e 100644 --- a/src/com/itmill/toolkit/ui/OrderedLayout.java +++ b/src/com/itmill/toolkit/ui/OrderedLayout.java @@ -103,6 +103,8 @@ public class OrderedLayout extends AbstractLayout { */ public static final int ALIGNMENT_VERTICAL_CENTER = 32; + private static final int ALIGNMENT_DEFAULT = ALIGNMENT_TOP + ALIGNMENT_LEFT; + /** * Orientation of the layout. */ @@ -225,30 +227,20 @@ public class OrderedLayout extends AbstractLayout { if (this.spacing) target.addAttribute("spacing", this.spacing); - // Store alignment info in this String - String alignments = ""; - + String[] alignmentsArray = new String[components.size()]; // Adds all items in all the locations + int index = 0; for (Iterator i = components.iterator(); i.hasNext();) { Component c = (Component) i.next(); if (c != null) { // Paint child component UIDL c.paint(target); - - // Get alignment info for component - if (componentToAlignment.containsKey(c)) - alignments += ((Integer) componentToAlignment.get(c)) - .intValue(); - else - // Default alignment is top-left - alignments += (ALIGNMENT_TOP + ALIGNMENT_LEFT); - if (i.hasNext()) - alignments += ","; + alignmentsArray[index++] = String.valueOf(getComponentAlignment(c)); } } // Add child component alignment info to layout tag - target.addAttribute("alignments", alignments); + target.addAttribute("alignments", alignmentsArray); } /** @@ -274,7 +266,16 @@ public class OrderedLayout extends AbstractLayout { throw new IllegalArgumentException(); this.orientation = orientation; - requestRepaint(); + + // requestRepaint() + // FIXME remove lines below and uncomment above + // Workaround to bypass IOrderedLayouts limitations (separate classes + // for different orientation + subtreecacing) + Iterator it = getComponentIterator(); + while (it.hasNext()) { + Component c = (Component) it.next(); + c.requestRepaint(); + } } /* Documented in superclass */ @@ -337,6 +338,14 @@ public class OrderedLayout extends AbstractLayout { componentToAlignment.put(childComponent, new Integer( horizontalAlignment + verticalAlignment)); } + + public int getComponentAlignment(Component childComponent) { + Integer bitMask = (Integer) componentToAlignment.get(childComponent); + if(bitMask != null) + return bitMask.intValue(); + else + return ALIGNMENT_DEFAULT; + } /** * Enable spacing between child components within this layout. diff --git a/src/com/itmill/toolkit/ui/Panel.java b/src/com/itmill/toolkit/ui/Panel.java index 9e8e686e64..69cc3fe2d9 100644 --- a/src/com/itmill/toolkit/ui/Panel.java +++ b/src/com/itmill/toolkit/ui/Panel.java @@ -49,8 +49,8 @@ import com.itmill.toolkit.terminal.Sizeable; * @VERSION@ * @since 3.0 */ -public class Panel extends AbstractLayout implements Sizeable, Scrollable, - ComponentContainer.ComponentAttachListener, +public class Panel extends AbstractComponentContainer implements Sizeable, + Scrollable, ComponentContainer.ComponentAttachListener, ComponentContainer.ComponentDetachListener, Action.Container { public static final String STYLE_LIGHT = "light"; @@ -210,8 +210,6 @@ public class Panel extends AbstractLayout implements Sizeable, Scrollable, public void paintContent(PaintTarget target) throws PaintException { layout.paint(target); - super.paintContent(target); - // Add size info as variables if (getHeight() > -1) target.addVariable(this, "height", getHeight() diff --git a/src/com/itmill/toolkit/ui/SplitPanel.java b/src/com/itmill/toolkit/ui/SplitPanel.java index 3ae1a90c73..be17d4ef72 100644 --- a/src/com/itmill/toolkit/ui/SplitPanel.java +++ b/src/com/itmill/toolkit/ui/SplitPanel.java @@ -45,7 +45,7 @@ import com.itmill.toolkit.terminal.Sizeable; * @VERSION@ * @since 5.0 */ -public class SplitPanel extends AbstractLayout implements Sizeable { +public class SplitPanel extends AbstractLayout { /* Predefined orientations ***************************************** */ @@ -72,30 +72,6 @@ public class SplitPanel extends AbstractLayout implements Sizeable { private int posUnit = UNITS_PERCENTAGE; - /** - * Height of the layout. Set to -1 for undefined height. - */ - private int height = -1; - - /** - * Height unit. - * - * @see com.itmill.toolkit.terminal.Sizeable.UNIT_SYMBOLS; - */ - private int heightUnit = UNITS_PIXELS; - - /** - * Width of the layout. Set to -1 for undefined width. - */ - private int width = -1; - - /** - * Width unit. - * - * @see com.itmill.toolkit.terminal.Sizeable.UNIT_SYMBOLS; - */ - private int widthUnit = UNITS_PIXELS; - /** * Creates a new split panel. The orientation of the panels is * ORIENTATION_VERTICAL. @@ -240,14 +216,6 @@ public class SplitPanel extends AbstractLayout implements Sizeable { target.addAttribute("position", position); - // Add size info - if (getHeight() > -1) - target.addAttribute("height", getHeight() - + UNIT_SYMBOLS[getHeightUnits()]); - if (getWidth() > -1) - target.addAttribute("width", getWidth() - + UNIT_SYMBOLS[getWidthUnits()]); - if (firstComponent != null) firstComponent.paint(target); else @@ -317,106 +285,4 @@ public class SplitPanel extends AbstractLayout implements Sizeable { this.posUnit = unit; } - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getHeight() - */ - public int getHeight() { - return height; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getHeightUnits() - */ - public int getHeightUnits() { - return heightUnit; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getWidth() - */ - public int getWidth() { - return width; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#getWidthUnits() - */ - public int getWidthUnits() { - return widthUnit; - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setHeight(int) - */ - public void setHeight(int height) { - this.height = height; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setHeightUnits(int) - */ - public void setHeightUnits(int units) { - this.heightUnit = units; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setSizeFull() - */ - public void setSizeFull() { - height = 100; - width = 100; - heightUnit = UNITS_PERCENTAGE; - widthUnit = UNITS_PERCENTAGE; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setSizeUndefined() - */ - public void setSizeUndefined() { - height = -1; - width = -1; - heightUnit = UNITS_PIXELS; - widthUnit = UNITS_PIXELS; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setWidth(int) - */ - public void setWidth(int width) { - this.width = width; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.terminal.Sizeable#setWidthUnits(int) - */ - public void setWidthUnits(int units) { - this.widthUnit = units; - requestRepaint(); - } - } diff --git a/src/com/itmill/toolkit/ui/TabSheet.java b/src/com/itmill/toolkit/ui/TabSheet.java index 494310aa57..48df4dc09e 100644 --- a/src/com/itmill/toolkit/ui/TabSheet.java +++ b/src/com/itmill/toolkit/ui/TabSheet.java @@ -48,7 +48,7 @@ import com.itmill.toolkit.terminal.Sizeable; * @VERSION@ * @since 3.0 */ -public class TabSheet extends AbstractLayout implements Sizeable { +public class TabSheet extends AbstractComponentContainer implements Sizeable { /** * Linked list of component tabs. @@ -219,7 +219,6 @@ public class TabSheet extends AbstractLayout implements Sizeable { * if the paint operation failed. */ public void paintContent(PaintTarget target) throws PaintException { - super.paintContent(target); // Add size info if (getHeight() > -1) -- 2.39.5