/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * 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 org.onebusaway.webapp.gwt.common.layout; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.maps.client.MapWidget; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import java.util.ArrayList; import java.util.List; public class BoxLayoutManager { private List<Constraint> _constraints = new ArrayList<Constraint>(); private ResizeHandlerImpl _handler = new ResizeHandlerImpl(); public BoxLayoutManager() { Window.addResizeHandler(_handler); } public void addMatch(Widget parent, Widget child, EBoxLayoutDirection direction) { addConstraint(new MatchConstraint(direction, parent, child)); } public void addSetHeightConstraint(Box source, Widget... targets) { addConstraint(new BoxConstraint(EBoxLayoutDirection.VERTICAL,source,targets)); } public void addFillRemaining(EBoxLayoutDirection direction, ComplexPanel parent, Widget target, Widget... additional) { addConstraint(new FillRemainingSpace(direction, parent, target, additional)); } public void addMapWidget(MapWidget mapWidget) { addConstraint(new MapWidgetConstraint(mapWidget)); } public void refresh() { DeferredCommand.addCommand(new Command() { public void execute() { _handler.onResize(new ResizeEventImpl(Window.getClientWidth(), Window.getClientHeight())); } }); } /***************************************************************************** * ****************************************************************************/ public void addConstraint(Constraint c) { _constraints.add(c); } /***************************************************************************** * ****************************************************************************/ private class ResizeHandlerImpl implements ResizeHandler { public void onResize(ResizeEvent arg0) { for (Constraint constraint : _constraints) constraint.apply(); } } public interface Constraint { public void apply(); } private static abstract class DirectedConstraint implements Constraint { private EBoxLayoutDirection _direction; public DirectedConstraint(EBoxLayoutDirection direction) { _direction = direction; } protected int getDirectedSize(Widget widget) { return _direction.equals(EBoxLayoutDirection.VERTICAL) ? widget.getOffsetHeight() : widget.getOffsetWidth(); } protected void setDirectedSize(Widget widget, int size) { if (_direction.equals(EBoxLayoutDirection.VERTICAL)) widget.setHeight(size + "px"); else widget.setWidth(size + "px"); } } public static class BoxConstraint extends DirectedConstraint { private Box _box; private Widget[] _widgets; public BoxConstraint(EBoxLayoutDirection direction, Box box, Widget... widgets) { super(direction); _box = box; _widgets = widgets; } public void apply() { int size = _box.evaluate(); size = Math.max(0, size); Window.setStatus("Size: " + size); for (Widget widget : _widgets) setDirectedSize(widget, size); } } private static class MatchConstraint extends DirectedConstraint { private Widget _parent; private Widget _widget; public MatchConstraint(EBoxLayoutDirection direction, Widget parent, Widget widget) { super(direction); _parent = parent; _widget = widget; } public void apply() { int size = getDirectedSize(_parent); setDirectedSize(_widget, size); } } private class FillRemainingSpace extends DirectedConstraint { private ComplexPanel _parent; private Widget _widget; private Widget[] _additional; public FillRemainingSpace(EBoxLayoutDirection direction, ComplexPanel parent, Widget widget, Widget[] children) { super(direction); _parent = parent; _widget = widget; _additional = children; } public void apply() { System.out.println("=== HERE WE GO ==="); int totalSize = getDirectedSize(_parent); int otherSize = 0; for (int i = 0; i < _parent.getWidgetCount(); i++) { Widget w = _parent.getWidget(i); if (w.equals(_widget)) continue; otherSize += getDirectedSize(w); } int remainingSize = totalSize - otherSize; System.out.println(" total=" + totalSize + " other=" + otherSize + " remaining=" + remainingSize); remainingSize = Math.max(0, remainingSize); for (Widget widget : _additional) setDirectedSize(widget, remainingSize); setDirectedSize(_widget, remainingSize); } } private static class MapWidgetConstraint implements Constraint { private MapWidget _map; public MapWidgetConstraint(MapWidget map) { _map = map; } public void apply() { _map.checkResize(); } } private static class ResizeEventImpl extends ResizeEvent { protected ResizeEventImpl(int width, int height) { super(width, height); } } }