com.vaadin.client.MeasuredSize Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaadin-client Show documentation
Show all versions of vaadin-client Show documentation
Vaadin is a web application framework for Rich Internet Applications (RIA).
Vaadin enables easy development and maintenance of fast and
secure rich web
applications with a stunning look and feel and a wide browser support.
It features a server-side architecture with the majority of the logic
running
on the server. Ajax technology is used at the browser-side to ensure a
rich
and interactive user experience.
/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client;
import java.util.logging.Logger;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Element;
public class MeasuredSize {
private final static boolean debugSizeChanges = false;
public static class MeasureResult {
private final boolean widthChanged;
private final boolean heightChanged;
private MeasureResult(boolean widthChanged, boolean heightChanged) {
this.widthChanged = widthChanged;
this.heightChanged = heightChanged;
}
public boolean isHeightChanged() {
return heightChanged;
}
public boolean isWidthChanged() {
return widthChanged;
}
public boolean isChanged() {
return heightChanged || widthChanged;
}
}
private int width = -1;
private int height = -1;
private int[] paddings = new int[4];
private int[] borders = new int[4];
private int[] margins = new int[4];
private FastStringSet dependents = FastStringSet.create();
public int getOuterHeight() {
return height;
}
public int getOuterWidth() {
return width;
}
public void addDependent(String pid) {
dependents.add(pid);
}
public void removeDependent(String pid) {
dependents.remove(pid);
}
public boolean hasDependents() {
return !dependents.isEmpty();
}
public JsArrayString getDependents() {
return dependents.dump();
}
private static int sumWidths(int[] sizes) {
return sizes[1] + sizes[3];
}
private static int sumHeights(int[] sizes) {
return sizes[0] + sizes[2];
}
public int getInnerHeight() {
return height - sumHeights(margins) - sumHeights(borders)
- sumHeights(paddings);
}
public int getInnerWidth() {
return width - sumWidths(margins) - sumWidths(borders)
- sumWidths(paddings);
}
public boolean setOuterHeight(int height) {
if (this.height != height) {
this.height = height;
return true;
} else {
return false;
}
}
public boolean setOuterWidth(int width) {
if (this.width != width) {
this.width = width;
return true;
} else {
return false;
}
}
public int getBorderHeight() {
return sumHeights(borders);
}
public int getBorderWidth() {
return sumWidths(borders);
}
public int getPaddingHeight() {
return sumHeights(paddings);
}
public int getPaddingWidth() {
return sumWidths(paddings);
}
public int getMarginHeight() {
return sumHeights(margins);
}
public int getMarginWidth() {
return sumWidths(margins);
}
public int getMarginTop() {
return margins[0];
}
public int getMarginRight() {
return margins[1];
}
public int getMarginBottom() {
return margins[2];
}
public int getMarginLeft() {
return margins[3];
}
public int getBorderTop() {
return borders[0];
}
public int getBorderRight() {
return borders[1];
}
public int getBorderBottom() {
return borders[2];
}
public int getBorderLeft() {
return borders[3];
}
public int getPaddingTop() {
return paddings[0];
}
public int getPaddingRight() {
return paddings[1];
}
public int getPaddingBottom() {
return paddings[2];
}
public int getPaddingLeft() {
return paddings[3];
}
public MeasureResult measure(Element element) {
Profiler.enter("MeasuredSize.measure");
boolean heightChanged = false;
boolean widthChanged = false;
Profiler.enter("new ComputedStyle");
ComputedStyle computedStyle = new ComputedStyle(element);
int[] paddings = computedStyle.getPadding();
// Some browsers do not reflow until accessing data from the computed
// style object
Profiler.leave("new ComputedStyle");
Profiler.enter("Measure paddings");
if (!heightChanged && hasHeightChanged(this.paddings, paddings)) {
debugSizeChange(element, "Height (padding)", this.paddings,
paddings);
heightChanged = true;
}
if (!widthChanged && hasWidthChanged(this.paddings, paddings)) {
debugSizeChange(element, "Width (padding)", this.paddings, paddings);
widthChanged = true;
}
this.paddings = paddings;
Profiler.leave("Measure paddings");
Profiler.enter("Measure margins");
int[] margins = computedStyle.getMargin();
if (!heightChanged && hasHeightChanged(this.margins, margins)) {
debugSizeChange(element, "Height (margins)", this.margins, margins);
heightChanged = true;
}
if (!widthChanged && hasWidthChanged(this.margins, margins)) {
debugSizeChange(element, "Width (margins)", this.margins, margins);
widthChanged = true;
}
this.margins = margins;
Profiler.leave("Measure margins");
Profiler.enter("Measure borders");
int[] borders = computedStyle.getBorder();
if (!heightChanged && hasHeightChanged(this.borders, borders)) {
debugSizeChange(element, "Height (borders)", this.borders, borders);
heightChanged = true;
}
if (!widthChanged && hasWidthChanged(this.borders, borders)) {
debugSizeChange(element, "Width (borders)", this.borders, borders);
widthChanged = true;
}
this.borders = borders;
Profiler.leave("Measure borders");
Profiler.enter("Measure height");
int requiredHeight = WidgetUtil.getRequiredHeight(element);
int marginHeight = sumHeights(margins);
int oldHeight = height;
int oldWidth = width;
if (setOuterHeight(requiredHeight + marginHeight)) {
debugSizeChange(element, "Height (outer)", oldHeight, height);
heightChanged = true;
}
Profiler.leave("Measure height");
Profiler.enter("Measure width");
int requiredWidth = WidgetUtil.getRequiredWidth(element);
int marginWidth = sumWidths(margins);
if (setOuterWidth(requiredWidth + marginWidth)) {
debugSizeChange(element, "Width (outer)", oldWidth, width);
widthChanged = true;
}
Profiler.leave("Measure width");
Profiler.leave("MeasuredSize.measure");
return new MeasureResult(widthChanged, heightChanged);
}
private void debugSizeChange(Element element, String sizeChangeType,
int[] changedFrom, int[] changedTo) {
debugSizeChange(element, sizeChangeType,
java.util.Arrays.asList(changedFrom).toString(),
java.util.Arrays.asList(changedTo).toString());
}
private void debugSizeChange(Element element, String sizeChangeType,
int changedFrom, int changedTo) {
debugSizeChange(element, sizeChangeType, String.valueOf(changedFrom),
String.valueOf(changedTo));
}
private void debugSizeChange(Element element, String sizeChangeType,
String changedFrom, String changedTo) {
if (debugSizeChanges) {
getLogger()
.info(sizeChangeType + " has changed from " + changedFrom
+ " to " + changedTo + " for " + element.toString());
}
}
private static boolean hasWidthChanged(int[] sizes1, int[] sizes2) {
return sizes1[1] != sizes2[1] || sizes1[3] != sizes2[3];
}
private static boolean hasHeightChanged(int[] sizes1, int[] sizes2) {
return sizes1[0] != sizes2[0] || sizes1[2] != sizes2[2];
}
private static Logger getLogger() {
return Logger.getLogger(MeasuredSize.class.getName());
}
}