blob: cdef14419756692cbec67d037bfa6cb9fa628618 [file] [log] [blame]
/*
* Copyright 2009 Google Inc.
*
* 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.google.gwt.layout.client;
import static com.google.gwt.dom.client.Style.Unit.EM;
import static com.google.gwt.dom.client.Style.Unit.EX;
import static com.google.gwt.dom.client.Style.Unit.PX;
import com.google.gwt.aria.client.State;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.layout.client.Layout.Layer;
/**
* Default implementation, which works with all browsers except for IE6. It uses
* only the "top", "left", "bottom", "right", "width", and "height" CSS
* properties.
*
* Note: This implementation class has state, so {@link Layout} must create a
* new instance for each layout-parent.
*
* <p>Deprecated, as this is the only implementation, it may be removed in a future
* release.</p>
*/
@Deprecated
class LayoutImpl {
private static DivElement fixedRuler;
static {
fixedRuler = createRuler(Unit.CM, Unit.CM);
Document.get().getBody().appendChild(fixedRuler);
}
protected static DivElement createRuler(Unit widthUnit, Unit heightUnit) {
DivElement ruler = Document.get().createDivElement();
ruler.setInnerHTML("&nbsp;");
Style style = ruler.getStyle();
style.setPosition(Position.ABSOLUTE);
style.setZIndex(-32767);
// Position the ruler off the top edge, double the size just to be
// extra sure it doesn't show up on the screen.
style.setTop(-20, heightUnit);
// Note that we are making the ruler element 10x10, because some browsers
// generate non-integral ratios (e.g., 1em == 13.3px), so we need a little
// extra precision.
style.setWidth(10, widthUnit);
style.setHeight(10, heightUnit);
style.setVisibility(Visibility.HIDDEN);
State.HIDDEN.set(ruler, true);
return ruler;
}
protected DivElement relativeRuler;
public Element attachChild(Element parent, Element child, Element before) {
DivElement container = Document.get().createDivElement();
container.appendChild(child);
container.getStyle().setPosition(Position.ABSOLUTE);
container.getStyle().setOverflow(Overflow.HIDDEN);
fillParent(child);
Element beforeContainer = null;
if (before != null) {
beforeContainer = before.getParentElement();
assert beforeContainer.getParentElement()
== parent : "Element to insert before must be a sibling";
}
parent.insertBefore(container, beforeContainer);
return container;
}
public void fillParent(Element elem) {
Style style = elem.getStyle();
style.setPosition(Position.ABSOLUTE);
style.setLeft(0, PX);
style.setTop(0, PX);
style.setRight(0, PX);
style.setBottom(0, PX);
}
/**
* @param parent the parent element
*/
public void finalizeLayout(Element parent) {
}
public double getUnitSizeInPixels(
Element parent, Unit unit, boolean vertical) {
if (unit == null) {
return 1;
}
switch (unit) {
case PCT:
return (vertical ? parent.getClientHeight() : parent.getClientWidth())
/ 100.0;
case EM:
return relativeRuler.getOffsetWidth() / 10.0;
case EX:
return relativeRuler.getOffsetHeight() / 10.0;
case CM:
return fixedRuler.getOffsetWidth() * 0.1; // 1.0 cm / cm
case MM:
return fixedRuler.getOffsetWidth() * 0.01; // 0.1 cm / mm
case IN:
return fixedRuler.getOffsetWidth() * 0.254; // 2.54 cm / in
case PT:
return fixedRuler.getOffsetWidth() * 0.00353; // 0.0353 cm / pt
case PC:
return fixedRuler.getOffsetWidth() * 0.0423; // 0.423 cm / pc
default:
case PX:
return 1;
}
}
public void initParent(Element parent) {
parent.getStyle().setPosition(Position.RELATIVE);
parent.appendChild(relativeRuler = createRuler(EM, EX));
}
public void layout(Layer layer) {
Style style = layer.container.getStyle();
if (layer.visible) {
style.clearDisplay();
} else {
style.setDisplay(Display.NONE);
}
style.setProperty(
"left", layer.setLeft ? (layer.left + layer.leftUnit.getType()) : "");
style.setProperty(
"top", layer.setTop ? (layer.top + layer.topUnit.getType()) : "");
style.setProperty("right",
layer.setRight ? (layer.right + layer.rightUnit.getType()) : "");
style.setProperty("bottom",
layer.setBottom ? (layer.bottom + layer.bottomUnit.getType()) : "");
style.setProperty("width",
layer.setWidth ? (layer.width + layer.widthUnit.getType()) : "");
style.setProperty("height",
layer.setHeight ? (layer.height + layer.heightUnit.getType()) : "");
style = layer.child.getStyle();
switch (layer.hPos) {
case BEGIN:
style.setLeft(0, Unit.PX);
style.clearRight();
break;
case END:
style.clearLeft();
style.setRight(0, Unit.PX);
break;
case STRETCH:
style.setLeft(0, Unit.PX);
style.setRight(0, Unit.PX);
break;
}
switch (layer.vPos) {
case BEGIN:
style.setTop(0, Unit.PX);
style.clearBottom();
break;
case END:
style.clearTop();
style.setBottom(0, Unit.PX);
break;
case STRETCH:
style.setTop(0, Unit.PX);
style.setBottom(0, Unit.PX);
break;
}
}
@SuppressWarnings("unused")
public void onAttach(Element parent) {
// Do nothing. This exists only to help LayoutImplIE6 avoid memory leaks.
}
@SuppressWarnings("unused")
public void onDetach(Element parent) {
// Do nothing. This exists only to help LayoutImplIE6 avoid memory leaks.
}
public void removeChild(Element container, Element child) {
container.removeFromParent();
// We want this code to be resilient to the child having already been
// removed from its container (perhaps by widget code).
if (child.getParentElement() == container) {
child.removeFromParent();
}
// Cleanup child styles set by fillParent().
Style style = child.getStyle();
style.clearPosition();
style.clearLeft();
style.clearTop();
style.clearWidth();
style.clearHeight();
}
}