+ (updateDuration.elapsedMillis() - startProcessing)
+ " ms");
- doLayout(false);
+ LayoutManager layoutManager = getLayoutManager();
+ layoutManager.setEverythingNeedsMeasure();
+ layoutManager.layoutNow();
updateDuration
.logDuration(" * Layout processing completed", 10);
}
- /*
- * Helper to run layout functions triggered by child components with a
- * decent interval.
- */
- private final Timer layoutTimer = new Timer() {
-
- private boolean isPending = false;
-
- @Override
- public void schedule(int delayMillis) {
- if (!isPending) {
- super.schedule(delayMillis);
- isPending = true;
- }
- }
-
- @Override
- public void run() {
- VConsole.log("Running re-layout of " + view.getClass().getName());
- runDescendentsLayout(view.getWidget());
- isPending = false;
- }
- };
-
private ConnectorMap connectorMap = GWT.create(ConnectorMap.class);
- /**
- * Components can call this function to run all layout functions. This is
- * usually done, when component knows that its size has changed.
- */
- public void requestLayoutPhase() {
- layoutTimer.schedule(500);
- }
-
protected String getUidlSecurityKey() {
return uidlSecurityKey;
}
eventIdentifier);
}
- private boolean layoutPending = false;
- private ScheduledCommand layoutCommand = new ScheduledCommand() {
- public void execute() {
- /*
- * Layout again if a new layout is requested while the current one
- * is running.
- */
- while (layoutPending) {
- layoutPending = false;
- layoutManager.doLayout();
- }
- }
- };
-
- public void doLayout(boolean lazy) {
- if (!lazy) {
- layoutPending = true;
- layoutCommand.execute();
- } else if (!layoutPending) {
- layoutPending = true;
- /*
- * Current layoutCommand will do layouts again if layoutScheduled is
- * set to true -> no need to schedule another command
- */
- if (!layoutManager.isLayoutRunning()) {
- Scheduler.get().scheduleDeferred(layoutCommand);
- }
- }
- }
-
LayoutManager getLayoutManager() {
return layoutManager;
}
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.Timer;
import com.vaadin.terminal.gwt.client.MeasuredSize.MeasureResult;
import com.vaadin.terminal.gwt.client.ui.ManagedLayout;
import com.vaadin.terminal.gwt.client.ui.PostLayoutListener;
private final Collection<ManagedLayout> needsHorizontalLayout = new HashSet<ManagedLayout>();
private final Collection<ManagedLayout> needsVerticalLayout = new HashSet<ManagedLayout>();
+ private final Collection<ComponentConnector> needsMeasure = new HashSet<ComponentConnector>();
+
private final Collection<ComponentConnector> pendingOverflowFixes = new HashSet<ComponentConnector>();
private final Map<Element, Collection<ElementResizeListener>> elementResizeListeners = new HashMap<Element, Collection<ElementResizeListener>>();
private final Set<Element> listenersToFire = new HashSet<Element>();
+ private boolean layoutPending = false;
+ private Timer layoutTimer = new Timer() {
+ @Override
+ public void run() {
+ cancel();
+ layoutNow();
+ }
+ };
+ private boolean everythingNeedsMeasure = false;
+
public void setConnection(ApplicationConnection connection) {
if (this.connection != null) {
throw new RuntimeException(
}
}
- public void doLayout() {
+ private void layoutLater() {
+ if (!layoutPending) {
+ layoutPending = true;
+ layoutTimer.schedule(100);
+ }
+ }
+
+ public void layoutNow() {
if (isLayoutRunning()) {
throw new IllegalStateException(
"Can't start a new layout phase before the previous layout phase ends.");
}
+ layoutPending = false;
+ try {
+ currentDependencyTree = new LayoutDependencyTree();
+ doLayout();
+ } finally {
+ currentDependencyTree = null;
+ }
+ }
+
+ private void doLayout() {
VConsole.log("Starting layout phase");
Map<ManagedLayout, Integer> layoutCounts = new HashMap<ManagedLayout, Integer>();
int passes = 0;
Duration totalDuration = new Duration();
- currentDependencyTree = new LayoutDependencyTree();
-
for (ManagedLayout layout : needsHorizontalLayout) {
currentDependencyTree.setNeedsHorizontalLayout(layout, true);
}
}
needsHorizontalLayout.clear();
needsVerticalLayout.clear();
+
+ for (ComponentConnector connector : needsMeasure) {
+ currentDependencyTree.setNeedsMeasure(connector, true);
+ }
+ needsMeasure.clear();
+
measureNonPaintables();
VConsole.log("Layout init in " + totalDuration.elapsedMillis() + " ms");
passes++;
int measuredConnectorCount = measureConnectors(
- currentDependencyTree, passes == 1);
+ currentDependencyTree, everythingNeedsMeasure);
+ everythingNeedsMeasure = false;
int measureTime = passDuration.elapsedMillis();
VConsole.log(" Measured " + measuredConnectorCount
VConsole.log("Invoke post layout listeners in "
+ (totalDuration.elapsedMillis() - postLayoutStart) + " ms");
- currentDependencyTree = null;
VConsole.log("Total layout phase time: "
+ totalDuration.elapsedMillis() + "ms");
}
setNeedsUpdate((ManagedLayout) connector);
}
}
- doLayout();
+ setEverythingNeedsMeasure();
+ layoutNow();
}
// TODO Rename to setNeedsLayout
}
public void reportOuterHeight(ComponentConnector component, int outerHeight) {
- if (!isLayoutRunning()) {
- throw new IllegalStateException(
- "Can only report sizes when layout is running");
- }
MeasuredSize measuredSize = getMeasuredSize(component);
- boolean heightChanged = measuredSize.setOuterHeight(outerHeight);
+ if (isLayoutRunning()) {
+ boolean heightChanged = measuredSize.setOuterHeight(outerHeight);
- if (heightChanged) {
- onConnectorChange(component, false, true);
- notifyListenersAndDepdendents(component.getWidget().getElement(),
- false, true);
+ if (heightChanged) {
+ onConnectorChange(component, false, true);
+ notifyListenersAndDepdendents(component.getWidget()
+ .getElement(), false, true);
+ }
+ currentDependencyTree.setNeedsVerticalMeasure(component, false);
+ } else if (measuredSize.getOuterHeight() != outerHeight) {
+ setNeedsMeasure(component);
}
- currentDependencyTree.setNeedsVerticalMeasure(component, false);
}
public void reportHeightAssignedToRelative(ComponentConnector component,
}
public void reportOuterWidth(ComponentConnector component, int outerWidth) {
- if (!isLayoutRunning()) {
- throw new IllegalStateException(
- "Can only report sizes when layout is running");
- }
-
MeasuredSize measuredSize = getMeasuredSize(component);
- boolean widthChanged = measuredSize.setOuterWidth(outerWidth);
+ if (isLayoutRunning()) {
+ boolean widthChanged = measuredSize.setOuterWidth(outerWidth);
- if (widthChanged) {
- onConnectorChange(component, true, false);
- notifyListenersAndDepdendents(component.getWidget().getElement(),
- true, false);
+ if (widthChanged) {
+ onConnectorChange(component, true, false);
+ notifyListenersAndDepdendents(component.getWidget()
+ .getElement(), true, false);
+ }
+ currentDependencyTree.setNeedsHorizontalMeasure(component, false);
+ } else if (measuredSize.getOuterWidth() != outerWidth) {
+ setNeedsMeasure(component);
}
- currentDependencyTree.setNeedsHorizontalMeasure(component, false);
}
public void addElementResizeListener(Element element,
setMeasuredSize(element, null);
}
}
+
+ public void setNeedsMeasure(ComponentConnector component) {
+ if (isLayoutRunning()) {
+ currentDependencyTree.setNeedsMeasure(component, true);
+ } else {
+ needsMeasure.add(component);
+ layoutLater();
+ }
+ }
+
+ public void setEverythingNeedsMeasure() {
+ everythingNeedsMeasure = true;
+ }
}
* @param widget
* @param lazy
* run componentSizeUpdated lazyly
+ *
+ * @deprecated since 7.0, use
+ * {@link LayoutManager#setNeedsMeasure(ComponentConnector)}
+ * instead
*/
+ @Deprecated
public static void notifyParentOfSizeChange(Widget widget, boolean lazy) {
- ApplicationConnection applicationConnection = findApplicationConnectionFor(widget);
- if (applicationConnection != null) {
- applicationConnection.doLayout(lazy);
+ ComponentConnector connector = findConnectorFor(widget);
+ if (connector != null) {
+ connector.getLayoutManager().setNeedsMeasure(connector);
+ if (!lazy) {
+ connector.getLayoutManager().layoutNow();
+ }
}
}
- private static boolean findAppConnectionWarningDisplayed = false;
-
- private static ApplicationConnection findApplicationConnectionFor(
- Widget widget) {
- if (!findAppConnectionWarningDisplayed) {
- findAppConnectionWarningDisplayed = true;
- VConsole.log("Warning: Using Util.findApplicationConnectionFor which should be eliminated once there is a better way to find the ApplicationConnection for a Paintable");
- }
-
+ private static ComponentConnector findConnectorFor(Widget widget) {
List<ApplicationConnection> runningApplications = ApplicationConfiguration
.getRunningApplications();
for (ApplicationConnection applicationConnection : runningApplications) {
continue;
}
if (connector.getConnection() == applicationConnection) {
- return applicationConnection;
+ return connector;
}
}
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Widget;
}
public void postLayout() {
- getWidget().sizeInit();
+ VScrollTable table = getWidget();
+ if (table.sizeNeedsInit) {
+ table.sizeInit();
+ Scheduler.get().scheduleFinally(new ScheduledCommand() {
+ public void execute() {
+ getLayoutManager().setNeedsUpdate(TableConnector.this);
+ getLayoutManager().layoutNow();
+ }
+ });
+ }
}
@Override
(pixelPosition + getSplitterSize()) + "px");
LayoutManager layoutManager = LayoutManager.get(client);
- if (layoutManager.isLayoutRunning()) {
- ConnectorMap connectorMap = ConnectorMap.get(client);
- if (firstChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(firstChild);
- if (connector.isRelativeWidth()) {
- layoutManager.reportWidthAssignedToRelative(connector,
- pixelPosition);
- }
+ ConnectorMap connectorMap = ConnectorMap.get(client);
+ if (firstChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(firstChild);
+ if (connector.isRelativeWidth()) {
+ layoutManager.reportWidthAssignedToRelative(connector,
+ pixelPosition);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
- if (secondChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(secondChild);
- if (connector.isRelativeWidth()) {
- layoutManager.reportWidthAssignedToRelative(connector,
- secondContainerWidth);
- }
+ }
+ if (secondChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(secondChild);
+ if (connector.isRelativeWidth()) {
+ layoutManager.reportWidthAssignedToRelative(connector,
+ secondContainerWidth);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
}
break;
(pixelPosition + getSplitterSize()) + "px");
layoutManager = LayoutManager.get(client);
- if (layoutManager.isLayoutRunning()) {
- ConnectorMap connectorMap = ConnectorMap.get(client);
- if (firstChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(firstChild);
- if (connector.isRelativeHeight()) {
- layoutManager.reportHeightAssignedToRelative(connector,
- pixelPosition);
- }
+ connectorMap = ConnectorMap.get(client);
+ if (firstChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(firstChild);
+ if (connector.isRelativeHeight()) {
+ layoutManager.reportHeightAssignedToRelative(connector,
+ pixelPosition);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
- if (secondChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(secondChild);
- if (connector.isRelativeHeight()) {
- layoutManager.reportHeightAssignedToRelative(connector,
- secondContainerHeight);
- }
+ }
+ if (secondChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(secondChild);
+ if (connector.isRelativeHeight()) {
+ layoutManager.reportHeightAssignedToRelative(connector,
+ secondContainerHeight);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
}
}
setSplitPosition(newX + "px");
- client.doLayout(false);
}
private void onVerticalMouseMove(int y) {
}
setSplitPosition(newY + "px");
- client.doLayout(false);
}
public void onMouseUp(Event event) {
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ComponentConnector;
import com.vaadin.terminal.gwt.client.ConnectorMap;
+import com.vaadin.terminal.gwt.client.LayoutManager;
import com.vaadin.terminal.gwt.client.MouseEventDetailsBuilder;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
+ emphasizedHDrop.toString().toLowerCase(), false);
}
if (doLayout) {
- client.doLayout(false);
+ notifySizePotentiallyChanged();
}
}
+ private void notifySizePotentiallyChanged() {
+ LayoutManager.get(client).setNeedsMeasure(
+ ConnectorMap.get(client).getConnector(getElement()));
+ }
+
protected void emphasis(VDragEvent drag) {
deEmphasis(false);
VDragAndDropWrapper.setStyleName(getElement(), OVER_STYLE, true);
emphasizedVDrop = verticalDropLocation;
emphasizedHDrop = horizontalDropLocation;
- // TODO build (to be an example) an emphasis mode where drag image
- // is fitted before or after the content
- client.doLayout(false);
+ notifySizePotentiallyChanged();
}
}
int serverCacheFirst = -1;
int serverCacheLast = -1;
- private boolean sizeNeedsInit = true;
+ boolean sizeNeedsInit = true;
/**
* Used to recall the position of an open context menu if we need to close
* * Makes deferred request to get some cache rows
*/
void sizeInit() {
- if (!sizeNeedsInit) {
- return;
- }
sizeNeedsInit = false;
scrollBody.setContainerHeight();
Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement());
}
});
-
- client.doLayout(true);
}
/**
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.ConnectorMap;
import com.vaadin.terminal.gwt.client.Focusable;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VConsole;
*/
protected void windowSizeMaybeChanged(int newWidth, int newHeight) {
boolean changed = false;
+ ComponentConnector connector = ConnectorMap.get(connection)
+ .getConnector(this);
if (width != newWidth) {
width = newWidth;
changed = true;
+ connector.getLayoutManager().reportOuterWidth(connector, newWidth);
VConsole.log("New window width: " + width);
}
if (height != newHeight) {
height = newHeight;
+ connector.getLayoutManager()
+ .reportOuterHeight(connector, newHeight);
changed = true;
VConsole.log("New window height: " + height);
}
VConsole.log("Running layout functions due to window resize");
sendClientResized();
- connection.doLayout(false);
+ connector.getLayoutManager().layoutNow();
}
}
client.runDescendentsLayout((HasWidgets) layout.getWidget());
}
- client.doLayout(false);
+ LayoutManager layoutManager = LayoutManager.get(client);
+ layoutManager.setNeedsMeasure(ConnectorMap.get(client).getConnector(
+ this));
+ layoutManager.layoutNow();
}
@Override