aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/itmill/toolkit/demo/featurebrowser/LabelExample.java61
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java9
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java2
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/IGridLayout.java802
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java3
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java1
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/layout/ChildComponentContainer.java2
7 files changed, 609 insertions, 271 deletions
diff --git a/src/com/itmill/toolkit/demo/featurebrowser/LabelExample.java b/src/com/itmill/toolkit/demo/featurebrowser/LabelExample.java
index 8f96602cdc..2747c1fdfe 100644
--- a/src/com/itmill/toolkit/demo/featurebrowser/LabelExample.java
+++ b/src/com/itmill/toolkit/demo/featurebrowser/LabelExample.java
@@ -4,10 +4,10 @@
package com.itmill.toolkit.demo.featurebrowser;
+import com.itmill.toolkit.ui.Component;
import com.itmill.toolkit.ui.CustomComponent;
import com.itmill.toolkit.ui.GridLayout;
import com.itmill.toolkit.ui.Label;
-import com.itmill.toolkit.ui.OrderedLayout;
import com.itmill.toolkit.ui.Panel;
/**
@@ -28,68 +28,61 @@ public class LabelExample extends CustomComponent {
+ " This is an indented row. \n Same indentation here.";
public LabelExample() {
-
- final OrderedLayout main = new OrderedLayout();
- main.setSizeFull();
- main.setMargin(true);
- setSizeFull();
- setCompositionRoot(main);
-
final GridLayout g = new GridLayout(2, 4);
- g.setSizeFull();
- main.addComponent(g);
+ g.setMargin(true);
+ setCompositionRoot(g);
+ g.setWidth("100%");
+
// plain w/o caption
- Panel p = new Panel("Plain");
- p.setWidth("100%");
- p.getLayout().setWidth("100%");
- p.setStyleName(Panel.STYLE_LIGHT);
+ Panel p = getExpamplePanel("Plain");
Label l = new Label("A plain label without caption.");
p.addComponent(l);
g.addComponent(p);
// plain w/ caption
- p = new Panel("Plain w/ caption + tooltip");
- p.setWidth("100%");
- p.getLayout().setWidth("100%");
- p.setStyleName(Panel.STYLE_LIGHT);
+ p = getExpamplePanel("Plain w/ caption + tooltip");
l = new Label("A plain label with caption.");
l.setCaption("Label caption");
l.setDescription("This is a description (tooltip) for the label.");
p.addComponent(l);
g.addComponent(p);
// plain w/ xhtml
- p = new Panel("Plain w/ XHTML content");
- p.setWidth("100%");
- p.getLayout().setWidth("100%");
- p.setStyleName(Panel.STYLE_LIGHT);
+ p = getExpamplePanel("Plain w/ XHTML content");
l = new Label(xhtml);
p.addComponent(l);
g.addComponent(p);
// xhtml w/ xhtml
- p = new Panel("XHTML-mode w/ XHTML content");
- p.setWidth("100%");
- p.getLayout().setWidth("100%");
- p.setStyleName(Panel.STYLE_LIGHT);
+ p = getExpamplePanel("XHTML-mode w/ XHTML content");
l = new Label(xhtml);
l.setContentMode(Label.CONTENT_XHTML);
p.addComponent(l);
g.addComponent(p);
// plain w/ preformatted
- p = new Panel("Plain w/ preformatted content");
- p.setWidth("100%");
- p.getLayout().setWidth("100%");
- p.setStyleName(Panel.STYLE_LIGHT);
+ p = getExpamplePanel("Plain w/ preformatted content");
l = new Label(pre);
p.addComponent(l);
g.addComponent(p);
// preformatted w/ preformatted
- p = new Panel("Preformatted-mode w/ preformatted content");
- p.setWidth("100%");
- p.getLayout().setWidth("100%");
- p.setStyleName(Panel.STYLE_LIGHT);
+ p = getExpamplePanel("Preformatted-mode w/ preformatted content");
l = new Label(pre);
l.setContentMode(Label.CONTENT_PREFORMATTED);
p.addComponent(l);
g.addComponent(p);
}
+
+ private Panel getExpamplePanel(String caption) {
+ Panel p = new Panel(caption) {
+
+ @Override
+ public void addComponent(Component c) {
+ c.setWidth("100%");
+ super.addComponent(c);
+ }
+
+ };
+ p.addStyleName(Panel.STYLE_LIGHT);
+ p.setWidth("100%");
+ p.getLayout().setWidth("100%");
+ return p;
+ }
}
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
index d73bbe1d74..e4f629180e 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
@@ -210,14 +210,7 @@ public class DefaultWidgetSet implements WidgetSet {
} else if ("link".equals(tag)) {
return "com.itmill.toolkit.terminal.gwt.client.ui.ILink";
} else if ("gridlayout".equals(tag)) {
- if (uidl.hasAttribute("height")) {
- // height needs to be set to use sizeable grid layout, with
- // width only or no size at all it fails to render properly.
- return "com.itmill.toolkit.terminal.gwt.client.ui.absolutegrid.ISizeableGridLayout";
- } else {
- // Fall back to GWT FlexTable based implementation.
- return "com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout";
- }
+ return "com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout";
} else if ("tree".equals(tag)) {
return "com.itmill.toolkit.terminal.gwt.client.ui.ITree";
} else if ("select".equals(tag)) {
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java
index 01ede8079c..00788b2972 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java
@@ -246,7 +246,7 @@ public class IAccordion extends ITabsheetBase implements
public void open() {
open = true;
- DOM.setStyleAttribute(content, "position", "");
+ DOM.setStyleAttribute(content, "position", "relative");
DOM.setStyleAttribute(content, "top", "");
DOM.setStyleAttribute(content, "left", "");
DOM.setStyleAttribute(content, "visibility", "");
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IGridLayout.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IGridLayout.java
index e7d4dd3c82..c868cc5a1f 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IGridLayout.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IGridLayout.java
@@ -4,332 +4,682 @@
package com.itmill.toolkit.terminal.gwt.client.ui;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Set;
+import java.util.Map.Entry;
-import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.HasHorizontalAlignment;
-import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
-import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
-import com.google.gwt.user.client.ui.HasVerticalAlignment.VerticalAlignmentConstant;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
-import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
import com.itmill.toolkit.terminal.gwt.client.Container;
-import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
-import com.itmill.toolkit.terminal.gwt.client.ICaptionWrapper;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
import com.itmill.toolkit.terminal.gwt.client.RenderSpace;
import com.itmill.toolkit.terminal.gwt.client.StyleConstants;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
+import com.itmill.toolkit.terminal.gwt.client.ui.layout.CellBasedLayout;
+import com.itmill.toolkit.terminal.gwt.client.ui.layout.ChildComponentContainer;
-public class IGridLayout extends SimplePanel implements Paintable, Container,
- ContainerResizedListener {
+public class IGridLayout extends SimplePanel implements Paintable, Container {
public static final String CLASSNAME = "i-gridlayout";
- private Grid grid = new Grid();
-
private boolean needsLayout = false;
- private boolean needsFF2Hack = BrowserInfo.get().isFF2();
-
private Element margin = DOM.createDiv();
- private Element meterElement;
+ private final AbsolutePanel canvas = new AbsolutePanel();
+
+ private ApplicationConnection client;
+
+ protected HashMap<Widget, ChildComponentContainer> widgetToComponentContainer = new HashMap<Widget, ChildComponentContainer>();
+
+ private HashMap<Paintable, Cell> paintableToCell = new HashMap<Paintable, Cell>();
+
+ private int spacingPixels;
+
+ private int[] columnWidths;
+ private int[] rowHeights;
+
+ private String height;
private String width;
- private ApplicationConnection client;
+ private int[] colExpandRatioArray;
+
+ private int[] rowExpandRatioArray;
+
+ private int[] minColumnWidths;
+
+ private int[] minRowHeights;
+
+ private boolean rendering;
public IGridLayout() {
super();
- DOM.appendChild(getElement(), margin);
- DOM.setStyleAttribute(getElement(), "overflow", "hidden");
+ getElement().getStyle().setProperty("overflow", "hidden");
+ getElement().appendChild(margin);
setStyleName(CLASSNAME);
- setWidget(grid);
+ setWidget(canvas);
}
protected Element getContainerElement() {
return margin;
}
- public void setWidth(String width) {
- this.width = width;
- if (width != null && !width.equals("")) {
- needsLayout = true;
- } else {
- needsLayout = false;
- grid.setWidth("");
- }
- }
-
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ rendering = true;
this.client = client;
if (client.updateComponent(this, uidl, true)) {
+ rendering = false;
return;
}
- final MarginInfo margins = new MarginInfo(uidl
- .getIntAttribute("margins"));
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_TOP,
- margins.hasTop());
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_RIGHT,
- margins.hasRight());
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_BOTTOM,
- margins.hasBottom());
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_LEFT,
- margins.hasLeft());
+ handleMargins(uidl);
+ detectSpacing(uidl);
- setStyleName(margin, CLASSNAME + "-" + "spacing", uidl
- .hasAttribute("spacing"));
- iLayout();
- grid.updateFromUIDL(uidl, client);
- }
+ int cols = uidl.getIntAttribute("w");
+ int rows = uidl.getIntAttribute("h");
- public boolean hasChildComponent(Widget component) {
- return grid.hasChildComponent(component);
- }
+ columnWidths = new int[cols];
+ rowHeights = new int[rows];
- public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
- grid.replaceChildComponent(oldComponent, newComponent);
- }
+ if (cells == null) {
+ cells = new Cell[cols][rows];
+ } else if (cells.length != cols || cells[0].length != rows) {
+ LinkedList<Cell> orphaned = new LinkedList<Cell>();
+ Cell[][] newCells = new Cell[cols][rows];
+ for (int i = 0; i < cells.length; i++) {
+ for (int j = 0; j < cells[i].length; j++) {
+ if (i < cols && j < rows) {
+ newCells[i][j] = cells[i][j];
+ }
+ }
+ }
+ cells = newCells;
+ // TODO clean orphaned list
+ for (Iterator iterator = orphaned.iterator(); iterator.hasNext();) {
+ Cell cell = (Cell) iterator.next();
+ }
+ }
- public void updateCaption(Paintable component, UIDL uidl) {
- grid.updateCaption(component, uidl);
- }
+ HashMap<Widget, ChildComponentContainer> nonRenderedWidgets = (HashMap<Widget, ChildComponentContainer>) widgetToComponentContainer
+ .clone();
+
+ final int[] alignments = uidl.getIntArrayAttribute("alignments");
+ int alignmentIndex = 0;
+ int column;
+ int row = 0;
+
+ LinkedList<Cell> pendingCells = new LinkedList<Cell>();
+
+ LinkedList<Cell> relativeHeighted = new LinkedList<Cell>();
+
+ for (final Iterator i = uidl.getChildIterator(); i.hasNext();) {
+ final UIDL r = (UIDL) i.next();
+ if ("gr".equals(r.getTag())) {
+ column = 0;
+ for (final Iterator j = r.getChildIterator(); j.hasNext();) {
+ final UIDL c = (UIDL) j.next();
+ if ("gc".equals(c.getTag())) {
+ Cell cell = getCell(c);
+ if (cell.hasContent()) {
+ boolean rendered = cell.renderIfNoRelativeWidth();
+ cell.alignment = alignments[alignmentIndex++];
+ column += cell.colspan;
+ if (!rendered) {
+ pendingCells.add(cell);
+ }
- public class Grid extends FlexTable implements Paintable, Container {
+ if (cell.colspan > 1) {
+ storeColSpannedCell(cell);
+ } else if (rendered) {
+ // strore non-colspanned widths to columnWidth
+ // array
+ if (columnWidths[cell.col] < cell.getWidth()) {
+ columnWidths[cell.col] = cell.getWidth();
+ }
+ }
+ if (cell.hasRelativeHeight()) {
+ relativeHeighted.add(cell);
+ }
+ }
+ }
+ }
+ row++;
+ }
+ }
- /** Widget to captionwrapper map */
- private final HashMap widgetToCaptionWrapper = new HashMap();
+ distributeColSpanWidths();
+ colExpandRatioArray = uidl.getIntArrayAttribute("colExpand");
+ rowExpandRatioArray = uidl.getIntArrayAttribute("rowExpand");
- public Grid() {
- super();
- setStyleName(CLASSNAME + "-grid");
+ minColumnWidths = cloneArray(columnWidths);
+ expandColumns();
+
+ renderRemainingComponentsWithNoRelativeHeight(pendingCells);
+
+ detectRowHeights();
+
+ minRowHeights = cloneArray(rowHeights);
+ expandRows();
+
+ renderRemainingComponents(pendingCells);
+
+ for (Cell cell : relativeHeighted) {
+ Widget widget2 = cell.cc.getWidget();
+ client.handleComponentRelativeSize(widget2);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ layoutCells();
+
+ for (Entry cc : nonRenderedWidgets.entrySet()) {
+ // TODO remove components
+ }
- int row = 0, column = 0;
+ rendering = false;
- final ArrayList oldWidgetWrappers = new ArrayList();
- for (final Iterator iterator = iterator(); iterator.hasNext();) {
- oldWidgetWrappers.add(iterator.next());
+ // canvas.add(uidl.print_r());
+ }
+
+ private static int[] cloneArray(int[] toBeCloned) {
+ int[] clone = new int[toBeCloned.length];
+ for (int i = 0; i < clone.length; i++) {
+ clone[i] = toBeCloned[i];
+ }
+ return clone;
+ }
+
+ private void expandRows() {
+ if (!"".equals(height)) {
+ int usedSpace = minRowHeights[0];
+ for (int i = 1; i < minRowHeights.length; i++) {
+ usedSpace += spacingPixels + minRowHeights[i];
}
+ int availableSpace = getOffsetHeight() - marginTopAndBottom;
+ int excessSpace = availableSpace - usedSpace;
+ int distributed = 0;
+ if (excessSpace > 0) {
+ for (int i = 0; i < rowHeights.length; i++) {
+ int ew = excessSpace * rowExpandRatioArray[i] / 1000;
+ rowHeights[i] = minRowHeights[i] + ew;
+ distributed += ew;
+ }
+ excessSpace -= distributed;
+ int c = 0;
+ while (excessSpace > 0) {
+ rowHeights[c % rowHeights.length]++;
+ excessSpace--;
+ c++;
+ }
+ }
+ }
+ }
- /* Clear() removes all widgets but leaves the tr and td tags */
- clear();
+ @Override
+ public void setHeight(String height) {
+ super.setHeight(height);
+ this.height = height;
+ if (!rendering) {
+ expandRows();
+ layoutCells();
+ }
+ }
- boolean structuralChange = uidl
- .getBooleanAttribute("structuralChange");
+ @Override
+ public void setWidth(String width) {
+ super.setWidth(width);
+ this.width = width;
+ if (!rendering) {
+ expandColumns();
+ layoutCells();
+ }
+ }
- /*
- * If a row has been inserted or removed at the middle of the table
- * we need to remove all old tr and td tags.
- */
- if (structuralChange) {
- while (getRowCount() > 0) {
- removeRow(0);
+ private void expandColumns() {
+ if (!"".equals(width)) {
+ int usedSpace = minColumnWidths[0];
+ for (int i = 1; i < minColumnWidths.length; i++) {
+ usedSpace += spacingPixels + minColumnWidths[i];
+ }
+ canvas.setWidth("");
+ int availableSpace = canvas.getOffsetWidth();
+ int excessSpace = availableSpace - usedSpace;
+ int distributed = 0;
+ if (excessSpace > 0) {
+ for (int i = 0; i < columnWidths.length; i++) {
+ int ew = excessSpace * colExpandRatioArray[i] / 1000;
+ columnWidths[i] = minColumnWidths[i] + ew;
+ distributed += ew;
+ }
+ excessSpace -= distributed;
+ int c = 0;
+ while (excessSpace > 0) {
+ columnWidths[c % columnWidths.length]++;
+ excessSpace--;
+ c++;
}
}
+ }
+ }
- final int[] alignments = uidl.getIntArrayAttribute("alignments");
- int alignmentIndex = 0;
-
- for (final Iterator i = uidl.getChildIterator(); i.hasNext();) {
- final UIDL r = (UIDL) i.next();
- if ("gr".equals(r.getTag())) {
- column = 0;
- for (final Iterator j = r.getChildIterator(); j.hasNext();) {
- final UIDL c = (UIDL) j.next();
- if ("gc".equals(c.getTag())) {
- prepareCell(row, column);
-
- // Set cell width
- int w;
- if (c.hasAttribute("w")) {
- w = c.getIntAttribute("w");
- } else {
- w = 1;
- }
+ private void layoutCells() {
+ int x = 0;
+ int y = 0;
+ for (int i = 0; i < cells.length; i++) {
+ y = 0;
+ for (int j = 0; j < cells[i].length; j++) {
+ Cell cell = cells[i][j];
+ if (cell != null) {
+ cell.layout(x, y);
+ }
+ y += rowHeights[j] + spacingPixels;
+ }
+ x += columnWidths[i] + spacingPixels;
+ }
+ // ensure canvas is right size
+ canvas.setPixelSize(x - spacingPixels, y - spacingPixels);
+ }
- FlexCellFormatter formatter = (FlexCellFormatter) getCellFormatter();
+ private void renderRemainingComponents(LinkedList<Cell> pendingCells) {
+ for (Cell cell : pendingCells) {
+ cell.render();
+ }
+ }
- // set col span
- formatter.setColSpan(row, column, w);
+ private void detectRowHeights() {
- String styleNames = CLASSNAME + "-cell";
- if (column == 0) {
- styleNames += " " + CLASSNAME + "-firstcol";
- }
- if (row == 0) {
- styleNames += " " + CLASSNAME + "-firstrow";
- }
- formatter.setStyleName(row, column, styleNames);
-
- // Set cell height
- int h;
- if (c.hasAttribute("h")) {
- h = c.getIntAttribute("h");
- } else {
- h = 1;
- }
- ((FlexCellFormatter) getCellFormatter())
- .setRowSpan(row, column, h);
-
- final UIDL u = c.getChildUIDL(0);
- if (u != null) {
-
- AlignmentInfo alignmentInfo = new AlignmentInfo(
- alignments[alignmentIndex++]);
-
- VerticalAlignmentConstant va;
- if (alignmentInfo.isBottom()) {
- va = HasVerticalAlignment.ALIGN_BOTTOM;
- } else if (alignmentInfo.isTop()) {
- va = HasVerticalAlignment.ALIGN_TOP;
- } else {
- va = HasVerticalAlignment.ALIGN_MIDDLE;
- }
+ // collect min rowheight from non-rowspanned cells
+ for (int i = 0; i < cells.length; i++) {
+ for (int j = 0; j < cells[i].length; j++) {
+ Cell cell = cells[i][j];
+ if (cell != null) {
+ if (cell.rowspan == 1) {
+ if (rowHeights[j] < cell.getHeight()) {
+ rowHeights[j] = cell.getHeight();
+ }
+ } else {
+ storeRowSpannedCell(cell);
+ }
+ }
+ }
+ }
+ distributeRowSpanHeights();
- HorizontalAlignmentConstant ha;
+ }
- if (alignmentInfo.isLeft()) {
- ha = HasHorizontalAlignment.ALIGN_LEFT;
- } else if (alignmentInfo.isHorizontalCenter()) {
- ha = HasHorizontalAlignment.ALIGN_CENTER;
- } else {
- ha = HasHorizontalAlignment.ALIGN_RIGHT;
- }
+ private void storeRowSpannedCell(Cell cell) {
+ SpanList l = null;
+ for (SpanList list : rowSpans) {
+ if (list.span < cell.rowspan) {
+ continue;
+ } else {
+ // insert before this
+ l = list;
+ break;
+ }
+ }
+ if (l == null) {
+ l = new SpanList(cell.rowspan);
+ rowSpans.add(l);
+ } else if (l.span != cell.rowspan) {
+ SpanList newL = new SpanList(cell.rowspan);
+ rowSpans.add(rowSpans.indexOf(l), newL);
+ l = newL;
+ }
+ l.cells.add(cell);
+ }
- formatter.setAlignment(row, column, ha, va);
-
- final Paintable child = client.getPaintable(u);
- ICaptionWrapper wr;
- if (widgetToCaptionWrapper.containsKey(child)) {
- wr = (ICaptionWrapper) widgetToCaptionWrapper
- .get(child);
- oldWidgetWrappers.remove(wr);
- } else {
- wr = new ICaptionWrapper(child, client);
- widgetToCaptionWrapper.put(child, wr);
- }
+ private void renderRemainingComponentsWithNoRelativeHeight(
+ LinkedList<Cell> pendingCells) {
- setWidget(row, column, wr);
+ for (Iterator iterator = pendingCells.iterator(); iterator.hasNext();) {
+ Cell cell = (Cell) iterator.next();
+ if (!cell.hasRelativeHeight()) {
+ cell.render();
+ iterator.remove();
+ }
+ }
- DOM.setStyleAttribute(wr.getElement(),
- "textAlign", alignmentInfo
- .getHorizontalAlignment());
+ }
- if (!u.getBooleanAttribute("cached")) {
- child.updateFromUIDL(u, client);
- }
+ /**
+ * Iterates colspanned cells, ensures cols have enough space to accommodate
+ * them
+ */
+ private void distributeColSpanWidths() {
+ for (SpanList list : colSpans) {
+ for (Cell cell : list.cells) {
+ int width = cell.getWidth();
+ int allocated = columnWidths[cell.col];
+ for (int i = 1; i < cell.colspan; i++) {
+ allocated += spacingPixels + columnWidths[cell.col + i];
+ }
+ if (allocated < width) {
+ // columnWidths needs to be expanded due colspanned cell
+ int neededExtraSpace = width - allocated;
+ int spaceForColunms = neededExtraSpace / cell.colspan;
+ for (int i = 0; i < cell.colspan; i++) {
+ int col = cell.col + i;
+ columnWidths[col] += spaceForColunms;
+ neededExtraSpace -= spaceForColunms;
+ }
+ if (neededExtraSpace > 0) {
+ for (int i = 0; i < cell.colspan; i++) {
+ int col = cell.col + i;
+ columnWidths[col] += 1;
+ neededExtraSpace -= 1;
+ if (neededExtraSpace == 0) {
+ break;
}
- column++;
}
}
- row++;
}
}
+ }
+ }
- // loop oldWidgetWrappers that where not re-attached and unregister
- // them
- for (final Iterator it = oldWidgetWrappers.iterator(); it.hasNext();) {
- final ICaptionWrapper w = (ICaptionWrapper) it.next();
- client.unregisterPaintable(w.getPaintable());
- widgetToCaptionWrapper.remove(w.getPaintable());
- }
- // fix rendering bug on FF2 (#1838)
- if (needsFF2Hack) {
- DeferredCommand.addCommand(new Command() {
- public void execute() {
- Element firstcell = getCellFormatter().getElement(0, 0);
- if (firstcell != null) {
- String styleAttribute = DOM.getStyleAttribute(
- firstcell, "verticalAlign");
- DOM.setStyleAttribute(firstcell, "verticalAlign",
- "");
- int elementPropertyInt = DOM.getElementPropertyInt(
- firstcell, "offsetWidth");
- DOM.setStyleAttribute(firstcell, "verticalAlign",
- styleAttribute);
- if (elementPropertyInt > 0) {
- needsFF2Hack = false;
+ /**
+ * Iterates rowspanned cells, ensures rows have enough space to accommodate
+ * them
+ */
+ private void distributeRowSpanHeights() {
+ for (SpanList list : rowSpans) {
+ for (Cell cell : list.cells) {
+ int height = cell.getHeight();
+ int allocated = rowHeights[cell.row];
+ for (int i = 1; i < cell.rowspan; i++) {
+ allocated += spacingPixels + rowHeights[cell.row + i];
+ }
+ if (allocated < height) {
+ // columnWidths needs to be expanded due colspanned cell
+ int neededExtraSpace = height - allocated;
+ int spaceForColunms = neededExtraSpace / cell.rowspan;
+ for (int i = 0; i < cell.rowspan; i++) {
+ int row = cell.row + i;
+ rowHeights[row] += spaceForColunms;
+ neededExtraSpace -= spaceForColunms;
+ }
+ if (neededExtraSpace > 0) {
+ for (int i = 0; i < cell.rowspan; i++) {
+ int row = cell.row + i;
+ rowHeights[row] += 1;
+ neededExtraSpace -= 1;
+ if (neededExtraSpace == 0) {
+ break;
}
}
}
- });
+ }
}
}
+ }
- public boolean hasChildComponent(Widget component) {
- if (widgetToCaptionWrapper.containsKey(component)) {
- return true;
- }
- return false;
- }
+ private LinkedList<SpanList> colSpans = new LinkedList<SpanList>();
+ private LinkedList<SpanList> rowSpans = new LinkedList<SpanList>();
- public void replaceChildComponent(Widget oldComponent,
- Widget newComponent) {
- // TODO Auto-generated method stub
+ private int marginTopAndBottom;
- }
+ private class SpanList {
+ final int span;
+ List<Cell> cells = new LinkedList<Cell>();
- public void updateCaption(Paintable component, UIDL uidl) {
- final ICaptionWrapper wrapper = (ICaptionWrapper) widgetToCaptionWrapper
- .get(component);
- wrapper.updateCaption(uidl);
+ public SpanList(int span) {
+ this.span = span;
}
+ }
- public boolean requestLayout(Set<Paintable> child) {
- // TODO Auto-generated method stub
- return false;
+ private void storeColSpannedCell(Cell cell) {
+ SpanList l = null;
+ for (SpanList list : colSpans) {
+ if (list.span < cell.colspan) {
+ continue;
+ } else {
+ // insert before this
+ l = list;
+ break;
+ }
+ }
+ if (l == null) {
+ l = new SpanList(cell.colspan);
+ colSpans.add(l);
+ } else if (l.span != cell.colspan) {
+
+ SpanList newL = new SpanList(cell.colspan);
+ colSpans.add(colSpans.indexOf(l), newL);
+ l = newL;
}
+ l.cells.add(cell);
+ }
- public RenderSpace getAllocatedSpace(Widget child) {
- // TODO Auto-generated method stub
- return null;
+ private void detectSpacing(UIDL uidl) {
+ if (uidl.getBooleanAttribute("spacing")) {
+ Element spacingmeter = DOM.createDiv();
+ spacingmeter.setClassName(CLASSNAME + "-" + "spacing-element");
+ spacingmeter.getStyle().setProperty("width", "0");
+ canvas.getElement().appendChild(spacingmeter);
+ spacingPixels = spacingmeter.getOffsetWidth();
+ canvas.getElement().removeChild(spacingmeter);
+ } else {
+ spacingPixels = 0;
}
+ }
+ private void handleMargins(UIDL uidl) {
+ final MarginInfo margins = new MarginInfo(uidl
+ .getIntAttribute("margins"));
+
+ setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_TOP,
+ margins.hasTop());
+ setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_RIGHT,
+ margins.hasRight());
+ setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_BOTTOM,
+ margins.hasBottom());
+ setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_LEFT,
+ margins.hasLeft());
+
+ marginTopAndBottom = margin.getOffsetHeight()
+ - canvas.getOffsetHeight();
}
- public void iLayout() {
- if (needsLayout) {
- super.setWidth(width);
- if (meterElement == null) {
- meterElement = DOM.createDiv();
- DOM.setStyleAttribute(meterElement, "overflow", "hidden");
- DOM.setStyleAttribute(meterElement, "height", "0");
- DOM.appendChild(getContainerElement(), meterElement);
- }
- int contentWidth = DOM.getElementPropertyInt(meterElement,
- "offsetWidth");
- int offsetWidth = getOffsetWidth();
+ public boolean hasChildComponent(Widget component) {
+ return paintableToCell.containsKey(component);
+ }
- grid.setWidth((offsetWidth - (offsetWidth - contentWidth)) + "px");
- } else {
- grid.setWidth("");
+ public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+ // TODO
+ }
+
+ public void updateCaption(Paintable component, UIDL uidl) {
+ ChildComponentContainer cc = widgetToComponentContainer.get(component);
+ if (cc != null) {
+ cc.updateCaption(uidl, client);
}
- client.runDescendentsLayout(this);
}
public boolean requestLayout(Set<Paintable> child) {
- // TODO Auto-generated method stub
- return false;
+ boolean mayNeedLayout = false;
+ int offsetHeight = canvas.getOffsetHeight();
+ int offsetWidth = canvas.getOffsetWidth();
+ if ("".equals(width) || "".equals(height)) {
+ mayNeedLayout = true;
+ } else {
+ for (Paintable paintable : child) {
+ Cell cell = paintableToCell.get(paintable);
+ if (!cell.hasRelativeHeight() || !cell.hasRelativeWidth()) {
+ // cell sizes will only stay still if only relatively sized
+ // components
+ mayNeedLayout = true;
+ }
+ }
+ }
+ if (mayNeedLayout) {
+ expandColumns();
+ expandRows();
+ layoutCells();
+ for (Paintable paintable : child) {
+ Cell cell = paintableToCell.get(paintable);
+ if (cell.hasRelativeHeight() || cell.hasRelativeWidth()) {
+ client.handleComponentRelativeSize((Widget) paintable);
+ }
+ }
+ }
+ if (canvas.getOffsetHeight() != offsetHeight
+ || canvas.getOffsetWidth() != offsetWidth) {
+ return false;
+ } else {
+ return true;
+ }
}
public RenderSpace getAllocatedSpace(Widget child) {
- // TODO Auto-generated method stub
- return null;
+ Cell cell = paintableToCell.get(child);
+ assert cell != null;
+ return cell.getAllocatedSpace();
+ }
+
+ private Cell[][] cells;
+
+ /**
+ * Private helper class.
+ */
+ private class Cell {
+ public Cell(UIDL c) {
+ // Set cell width
+ colspan = c.hasAttribute("w") ? c.getIntAttribute("w") : 1;
+ // Set cell height
+ rowspan = c.hasAttribute("h") ? c.getIntAttribute("h") : 1;
+ row = c.getIntAttribute("y");
+ col = c.getIntAttribute("x");
+ childUidl = c.getChildUIDL(0);
+ }
+
+ public boolean hasRelativeHeight() {
+ if (childUidl.hasAttribute("height")) {
+ String w = childUidl.getStringAttribute("height");
+ if (w.contains("%")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public RenderSpace getAllocatedSpace() {
+ return new RenderSpace(getAvailableWidth(), getAvailableHeight());
+ }
+
+ public boolean hasContent() {
+ return childUidl != null;
+ }
+
+ /**
+ * @return total of spanned cols
+ */
+ private int getAvailableWidth() {
+ int width = columnWidths[col];
+ for (int i = 1; i < colspan; i++) {
+ width += spacingPixels + columnWidths[col + i];
+ }
+ return width;
+ }
+
+ /**
+ * @return total of spanned rows
+ */
+ private int getAvailableHeight() {
+ int height = rowHeights[row];
+ for (int i = 1; i < rowspan; i++) {
+ height += spacingPixels + rowHeights[row + i];
+ }
+ return height;
+ }
+
+ public void layout(int x, int y) {
+ if (cc != null && cc.isAttached()) {
+ canvas.setWidgetPosition(cc, x, y);
+ cc.setContainerSize(getAvailableWidth(), getAvailableHeight());
+ cc.setAlignment(new AlignmentInfo(alignment));
+ }
+ }
+
+ public int getWidth() {
+ if (cc != null) {
+ return cc.getOffsetWidth();
+ } else {
+ return 0;
+ }
+ }
+
+ public int getHeight() {
+ if (cc != null) {
+ return cc.getOffsetHeight();
+ } else {
+ return 0;
+ }
+ }
+
+ public boolean renderIfNoRelativeWidth() {
+ if (childUidl == null) {
+ return false;
+ }
+ if (!hasRelativeWidth()) {
+ render();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private boolean hasRelativeWidth() {
+ if (childUidl.hasAttribute("width")) {
+ String w = childUidl.getStringAttribute("width");
+ if (w.contains("%")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected void render() {
+ Paintable paintable = client.getPaintable(childUidl);
+ if (cc == null) {
+ cc = new ChildComponentContainer((Widget) paintable,
+ CellBasedLayout.ORIENTATION_HORIZONTAL);
+ cc.setHeight("");
+ canvas.add(cc);
+ }
+ widgetToComponentContainer.put((Widget) paintable, cc);
+ paintableToCell.put(paintable, this);
+ cc.renderChild(childUidl, client);
+ }
+
+ public UIDL getChildUIDL() {
+ return childUidl;
+ }
+
+ int row;
+ int col;
+ int colspan = 1;
+ int rowspan = 1;
+ UIDL childUidl;
+ int alignment;
+ ChildComponentContainer cc;
}
+ private Cell getCell(UIDL c) {
+ int row = c.getIntAttribute("y");
+ int col = c.getIntAttribute("x");
+ Cell cell = cells[col][row];
+ if (cell == null) {
+ cell = new Cell(c);
+ cells[col][row] = cell;
+ }
+ return cell;
+ }
}
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java
index 7302724899..b0ef5c0837 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java
@@ -86,6 +86,7 @@ public class IPanel extends SimplePanel implements Container,
+ "-deco");
DOM.sinkEvents(getElement(), Event.ONKEYDOWN);
DOM.sinkEvents(contentNode, Event.ONSCROLL);
+ contentNode.getStyle().setProperty("position", "relative");
}
@Override
@@ -94,7 +95,7 @@ public class IPanel extends SimplePanel implements Container,
}
private void setCaption(String text) {
- DOM.setInnerText(captionText, text);
+ DOM.setInnerHTML(captionText, text);
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java
index e5e04c58a3..14c0f1c989 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java
@@ -362,6 +362,7 @@ public class ITabsheet extends ITabsheetBase implements
DOM.setStyleAttribute(contentNode, "height", contentHeight + "px");
renderSpace.setHeight(contentHeight);
DOM.setStyleAttribute(contentNode, "overflow", "auto");
+ contentNode.getStyle().setProperty("position", "relative");
} else {
DOM.setStyleAttribute(contentNode, "height", "");
DOM.setStyleAttribute(contentNode, "overflow", "");
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/ChildComponentContainer.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/ChildComponentContainer.java
index dc381227f7..f4f49041f2 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/ChildComponentContainer.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/layout/ChildComponentContainer.java
@@ -239,7 +239,7 @@ public class ChildComponentContainer extends Panel {
return getCaptionHeight();
}
- public int calculateVerticalAlignmentTopOffset(int emptySpace) {
+ private int calculateVerticalAlignmentTopOffset(int emptySpace) {
if (alignment.isTop()) {
return 0;
}