Created
February 22, 2019 14:12
-
-
Save branflake2267/107911bf2e9e235136462c174eb13e4b to your computer and use it in GitHub Desktop.
GXT 4.0.2 BorderLayoutContainer override. getCollapsedHeaderHeight(panel) added.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import com.google.gwt.core.client.EntryPoint; | |
| import com.google.gwt.event.logical.shared.AttachEvent; | |
| import com.google.gwt.event.logical.shared.AttachEvent.Handler; | |
| import com.google.gwt.user.client.ui.RootPanel; | |
| import com.sencha.gxt.core.client.util.Margins; | |
| import com.sencha.gxt.widget.core.client.ContentPanel; | |
| import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer; | |
| import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData; | |
| import com.sencha.gxt.widget.core.client.container.MarginData; | |
| import com.sencha.gxt.widget.core.client.container.Viewport; | |
| public class BLCwithCollapsedWidthExample implements EntryPoint { | |
| private ContentPanel centerContainer; | |
| private ContentPanel westContainer; | |
| @Override | |
| public void onModuleLoad() { | |
| centerContainer = new ContentPanel(); | |
| centerContainer.setHeading("Center"); | |
| westContainer = new ContentPanel(); | |
| westContainer.setHeading("West"); | |
| westContainer.addAttachHandler(new Handler() { | |
| @Override | |
| public void onAttachOrDetach(AttachEvent event) { | |
| if (westContainer.isAttached()) { | |
| } | |
| } | |
| }); | |
| BorderLayoutData layoutData = new BorderLayoutData(200); | |
| layoutData.setMargins(new Margins(10)); | |
| layoutData.setCollapsible(true); | |
| layoutData.setCollapsed(true); | |
| final BorderLayoutContainer blc = new BorderLayoutContainer() { | |
| @Override | |
| protected int getCollapsedHeaderHeight(ContentPanel panel) { | |
| if (panel == westContainer) { | |
| return 35; | |
| } | |
| return super.getCollapsedHeaderHeight(panel); | |
| } | |
| }; | |
| blc.setWestWidget(westContainer, layoutData); | |
| blc.setCenterWidget(centerContainer, new MarginData(10)); | |
| Viewport vp = new Viewport(); | |
| vp.add(blc); | |
| RootPanel.get().add(vp); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Sencha GXT 4.0.2 - Sencha for GWT | |
| * Copyright (c) 2006-2016, Sencha Inc. | |
| * | |
| * [email protected] | |
| * http://www.sencha.com/products/gxt/license/ | |
| * | |
| * ================================================================================ | |
| * Commercial License | |
| * ================================================================================ | |
| * This version of Sencha GXT is licensed commercially and is the appropriate | |
| * option for the vast majority of use cases. | |
| * | |
| * Please see the Sencha GXT Licensing page at: | |
| * http://www.sencha.com/products/gxt/license/ | |
| * | |
| * For clarification or additional options, please contact: | |
| * [email protected] | |
| * ================================================================================ | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * ================================================================================ | |
| * Disclaimer | |
| * ================================================================================ | |
| * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND | |
| * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE | |
| * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, | |
| * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND | |
| * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING. | |
| * ================================================================================ | |
| */ | |
| package com.sencha.gxt.widget.core.client.container; | |
| import java.util.logging.Logger; | |
| 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.Element; | |
| import com.google.gwt.dom.client.Style.Visibility; | |
| import com.google.gwt.event.shared.HandlerRegistration; | |
| import com.google.gwt.safehtml.shared.SafeHtmlBuilder; | |
| import com.google.gwt.uibinder.client.UiChild; | |
| import com.google.gwt.uibinder.client.UiConstructor; | |
| import com.google.gwt.user.client.ui.IsWidget; | |
| import com.google.gwt.user.client.ui.Widget; | |
| import com.sencha.gxt.core.client.GXTLogConfiguration; | |
| import com.sencha.gxt.core.client.Style.Direction; | |
| import com.sencha.gxt.core.client.Style.LayoutRegion; | |
| import com.sencha.gxt.core.client.Style.Side; | |
| import com.sencha.gxt.core.client.dom.XDOM; | |
| import com.sencha.gxt.core.client.dom.XElement; | |
| import com.sencha.gxt.core.client.resources.CommonStyles; | |
| import com.sencha.gxt.core.client.util.Margins; | |
| import com.sencha.gxt.core.client.util.Rectangle; | |
| import com.sencha.gxt.core.client.util.Size; | |
| import com.sencha.gxt.widget.core.client.CollapsePanel; | |
| import com.sencha.gxt.widget.core.client.Collapsible; | |
| import com.sencha.gxt.widget.core.client.Component; | |
| import com.sencha.gxt.widget.core.client.ContentPanel; | |
| import com.sencha.gxt.widget.core.client.SplitBar; | |
| import com.sencha.gxt.widget.core.client.button.IconButton.IconConfig; | |
| import com.sencha.gxt.widget.core.client.button.ToolButton; | |
| import com.sencha.gxt.widget.core.client.event.BeforeCollapseEvent; | |
| import com.sencha.gxt.widget.core.client.event.BeforeCollapseEvent.BeforeCollapseHandler; | |
| import com.sencha.gxt.widget.core.client.event.BeforeExpandEvent; | |
| import com.sencha.gxt.widget.core.client.event.BeforeExpandEvent.BeforeExpandHandler; | |
| import com.sencha.gxt.widget.core.client.event.CollapseItemEvent; | |
| import com.sencha.gxt.widget.core.client.event.CollapseItemEvent.CollapseItemHandler; | |
| import com.sencha.gxt.widget.core.client.event.CollapseItemEvent.HasCollapseItemHandlers; | |
| import com.sencha.gxt.widget.core.client.event.ExpandItemEvent; | |
| import com.sencha.gxt.widget.core.client.event.ExpandItemEvent.ExpandItemHandler; | |
| import com.sencha.gxt.widget.core.client.event.ExpandItemEvent.HasExpandItemHandlers; | |
| import com.sencha.gxt.widget.core.client.event.SelectEvent; | |
| import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler; | |
| import com.sencha.gxt.widget.core.client.event.SplitBarDragEvent; | |
| import com.sencha.gxt.widget.core.client.event.SplitBarDragEvent.SplitBarDragHandler; | |
| /** | |
| * <p>A multi-pane, application-oriented layout container that supports multiple regions, automatic split bars between | |
| * regions and built-in expanding and collapsing of regions.</p> | |
| * <p>Region positions are specified using compass points (e.g. north for top, west for left, east for right, south for | |
| * bottom) and center. The center region is a privileged position that receives the remaining space not allocated to | |
| * other regions. Border layout containers should generally specify a center region and one or more other regions.</p> | |
| * <p>Region layout parameters are specified using {@link BorderLayoutData} which controls the margin between the regions, | |
| * the size of the region, the minimum and maximum size, whether the region has a split bar, whether the region is | |
| * collapsible and other details.</p> | |
| * <p>Region size may be specified as a percent of the parent container size or a fixed number of pixels. The region size | |
| * is specified as a single value that describes the orientation associated with the region (height for north and south, | |
| * width for west and east).</p> | |
| * <p>The size, split bar and collapsible attributes are specified in the <code>BorderLayoutData</code> for the region | |
| * adjacent to the center region.</p> | |
| * <p>Code Snippet:</p> | |
| * | |
| * <pre><code> | |
| * BorderLayoutContainer con = new BorderLayoutContainer(); | |
| * | |
| * ContentPanel cp = new ContentPanel(); | |
| * cp.setHeading("North"); | |
| * cp.add(new Label("North Content")); | |
| * BorderLayoutData d = new BorderLayoutData(.20); | |
| * d.setMargins(new Margins(5)); | |
| * d.setCollapsible(true); | |
| * d.setSplit(true); | |
| * con.setNorthWidget(cp, d); | |
| * | |
| * cp = new ContentPanel(); | |
| * cp.setHeading("West"); | |
| * cp.add(new Label("West Content")); | |
| * d = new BorderLayoutData(.20); | |
| * d.setMargins(new Margins(0, 5, 5, 5)); | |
| * d.setCollapsible(true); | |
| * d.setSplit(true); | |
| * d.setCollapseMini(true); | |
| * con.setWestWidget(cp, d); | |
| * | |
| * cp = new ContentPanel(); | |
| * cp.setHeading("Center"); | |
| * cp.add(new Label("Center Content")); | |
| * d = new BorderLayoutData(); | |
| * d.setMargins(new Margins(0, 5, 5, 0)); | |
| * con.setCenterWidget(cp, d); | |
| * | |
| * Viewport v = new Viewport(); | |
| * v.add(con); | |
| * RootPanel.get().add(v); | |
| * </code></pre> | |
| */ | |
| public class BorderLayoutContainer extends SimpleContainer implements HasCenterWidget, HasNorthWidget, HasSouthWidget, | |
| HasEastWidget, HasWestWidget, HasCollapseItemHandlers<ContentPanel>, HasExpandItemHandlers<ContentPanel> { | |
| @SuppressWarnings("javadoc") | |
| public interface BorderLayoutAppearance { | |
| XElement getContainerTarget(XElement parent); | |
| void onInsert(Widget child); | |
| void onRemove(Widget child); | |
| void render(SafeHtmlBuilder sb); | |
| } | |
| /** | |
| * Specifies region layout parameters which control the margin between the regions, the size of the region, the | |
| * minimum and maximum size, whether the region has a split bar, whether the region is collapsible and other details. | |
| * The size, split bar and collapsible attributes are specified in the <code>BorderLayoutData</code> for the region | |
| * adjacent to the center region. The center region is allocated the remaining space. | |
| */ | |
| public static class BorderLayoutData extends MarginData implements HasSize, LayoutData { | |
| private double size = 100; | |
| private boolean split; | |
| private boolean hidden; | |
| private int minSize = 50; | |
| private int maxSize = 500; | |
| private boolean collapsible; | |
| private boolean collapseMini; | |
| private boolean collapseHeaderVisible = false; | |
| private boolean collapseHidden; | |
| private boolean floatable = true; | |
| private boolean collapsed; | |
| /** | |
| * Creates a border layout data with default values for <code>size</code> (100), <code>minSize</code> (50) and | |
| * <code>maxSize</code> (500). | |
| */ | |
| public BorderLayoutData() { | |
| } | |
| /** | |
| * Creates a border layout data with default values for <code>minSize</code> (50) and <code>maxSize</code> (500) and | |
| * the specified value for size. | |
| * | |
| * @param size the region size (height for north and south, width for west and east) | |
| */ | |
| @UiConstructor | |
| public BorderLayoutData(double size) { | |
| setSize(size); | |
| } | |
| /** | |
| * Returns the region's maximum size. | |
| * | |
| * @return the maximum size | |
| */ | |
| public int getMaxSize() { | |
| return maxSize; | |
| } | |
| /** | |
| * Returns the region's minimum size. | |
| * | |
| * @return the minimum size | |
| */ | |
| public int getMinSize() { | |
| return minSize; | |
| } | |
| @Override | |
| public double getSize() { | |
| return size; | |
| } | |
| /** | |
| * Returns the collapsed state | |
| * | |
| * @return the collapsed state | |
| */ | |
| public boolean isCollapsed() { | |
| return collapsed; | |
| } | |
| /** | |
| * Returns true if the collapse header is visible. | |
| * | |
| * @return true if the collapse header is visible | |
| */ | |
| public boolean isCollapseHeaderVisible() { | |
| return collapseHeaderVisible; | |
| } | |
| /** | |
| * Returns true if the collapse panel is hidden. | |
| * | |
| * @return the collapse hidden state | |
| */ | |
| public boolean isCollapseHidden() { | |
| return collapseHidden; | |
| } | |
| /** | |
| * Returns true if the mini split bar collapse tool is enabled. | |
| * | |
| * @return true if the mini split bar collapse tool is enabled | |
| */ | |
| public boolean isCollapseMini() { | |
| return collapseMini; | |
| } | |
| /** | |
| * Returns true if collapsing is enabled. | |
| * | |
| * @return the collapse state | |
| */ | |
| public boolean isCollapsible() { | |
| return collapsible; | |
| } | |
| /** | |
| * Returns true if the region is floatable. | |
| * | |
| * @return the float state | |
| */ | |
| public boolean isFloatable() { | |
| return floatable; | |
| } | |
| /** | |
| * Returns true if the component is hidden. | |
| * | |
| * @return the hidden state | |
| */ | |
| public boolean isHidden() { | |
| return hidden; | |
| } | |
| /** | |
| * Returns true if the region is split. | |
| * | |
| * @return the split state | |
| */ | |
| public boolean isSplit() { | |
| return split; | |
| } | |
| /** | |
| * Sets the collapsed state. | |
| * | |
| * @param collapsed true to render collapsed | |
| */ | |
| public void setCollapsed(boolean collapsed) { | |
| this.collapsed = collapsed; | |
| } | |
| /** | |
| * True to make the collapse panel header text visible when a region is collapsed (defaults to false). | |
| * | |
| * @param collapseHeaderVisible true to make the collapse panel header text visible | |
| */ | |
| public void setCollapseHeaderVisible(boolean collapseHeaderVisible) { | |
| this.collapseHeaderVisible = collapseHeaderVisible; | |
| } | |
| /** | |
| * True to hide the collapse panel when a region is collapsed (defaults to false). | |
| * | |
| * @param collapseHidden the collapse hidden state | |
| */ | |
| public void setCollapseHidden(boolean collapseHidden) { | |
| this.collapseHidden = collapseHidden; | |
| } | |
| /** | |
| * True to add a mini-collapase tool in the split bar. Enabling will make the region resizable. | |
| * | |
| * @param collapseMini true to add tool | |
| */ | |
| public void setCollapseMini(boolean collapseMini) { | |
| this.collapseMini = collapseMini; | |
| this.split = true; | |
| } | |
| /** | |
| * True to allow the user to collapse this region (defaults to false). If true, an expand/collapse tool button will | |
| * automatically be rendered into the title bar of the region, otherwise the button will not be shown. | |
| * | |
| * @param collapsible true to enable collapsing | |
| */ | |
| public void setCollapsible(boolean collapsible) { | |
| this.collapsible = collapsible; | |
| } | |
| /** | |
| * True to allow clicking a collapsed region's bar to display the region's panel floated above the layout, false to | |
| * force the user to fully expand a collapsed region by clicking the expand button to see it again (defaults to | |
| * true). | |
| * | |
| * @param floatable true to enable floating | |
| */ | |
| public void setFloatable(boolean floatable) { | |
| this.floatable = floatable; | |
| } | |
| /** | |
| * True to hide the component. | |
| * | |
| * @param hidden true to hide | |
| */ | |
| public void setHidden(boolean hidden) { | |
| this.hidden = hidden; | |
| } | |
| /** | |
| * Sets the maximum allowable size in pixels for this region (defaults to 500). | |
| * | |
| * @param maxSize the max size | |
| */ | |
| public void setMaxSize(int maxSize) { | |
| this.maxSize = maxSize; | |
| } | |
| /** | |
| * Sets the minimum allowable size in pixels for this region (defaults to 50). | |
| * | |
| * @param minSize the min size | |
| */ | |
| public void setMinSize(int minSize) { | |
| this.minSize = minSize; | |
| } | |
| @Override | |
| public void setSize(double size) { | |
| this.size = size; | |
| } | |
| /** | |
| * True to display a {@link SplitBar} between this region and its neighbor, allowing the user to resize the regions | |
| * dynamically (defaults to false). When split = true, it is common to specify a {@link #minSize} and | |
| * {@link #maxSize} for the region. | |
| * | |
| * @param split true to enable a split bar | |
| */ | |
| public void setSplit(boolean split) { | |
| this.split = split; | |
| } | |
| } | |
| private class Handler implements BeforeCollapseHandler, BeforeExpandHandler { | |
| @Override | |
| public void onBeforeCollapse(BeforeCollapseEvent event) { | |
| event.setCancelled(true); | |
| onCollapse((ContentPanel) event.getSource()); | |
| } | |
| @Override | |
| public void onBeforeExpand(BeforeExpandEvent event) { | |
| event.setCancelled(true); | |
| onExpand((ContentPanel) event.getSource()); | |
| } | |
| } | |
| protected Widget east; | |
| protected Widget north; | |
| protected Widget south; | |
| protected Widget west; | |
| private Handler collapseHandler = new Handler(); | |
| private Rectangle lastCenter; | |
| private final BorderLayoutAppearance appearance; | |
| private static Logger logger = Logger.getLogger(BorderLayoutContainer.class.getName()); | |
| /** | |
| * Creates a border layout container with the default appearance. | |
| */ | |
| public BorderLayoutContainer() { | |
| this(GWT.<BorderLayoutAppearance> create(BorderLayoutAppearance.class)); | |
| } | |
| /** | |
| * Creates a border layout container with the specified appearance. | |
| * | |
| * @param appearance the appearance of the border layout container | |
| */ | |
| public BorderLayoutContainer(BorderLayoutAppearance appearance) { | |
| super(true); | |
| this.appearance = appearance; | |
| SafeHtmlBuilder builder = new SafeHtmlBuilder(); | |
| this.appearance.render(builder); | |
| setElement((Element) XDOM.create(builder.toSafeHtml())); | |
| getElement().makePositionable(); | |
| } | |
| @Override | |
| public HandlerRegistration addCollapseHandler(CollapseItemHandler<ContentPanel> handler) { | |
| return addHandler(handler, CollapseItemEvent.getType()); | |
| } | |
| @Override | |
| public HandlerRegistration addExpandHandler(ExpandItemHandler<ContentPanel> handler) { | |
| return addHandler(handler, ExpandItemEvent.getType()); | |
| } | |
| /** | |
| * Collapses the panel in the given region. If the target widget is hidden no action will be performed. | |
| * | |
| * @param region the region to be collapsed | |
| */ | |
| public void collapse(LayoutRegion region) { | |
| Widget w = getRegionWidget(region); | |
| if (w != null && w instanceof ContentPanel && !(w instanceof CollapsePanel)) { | |
| BorderLayoutData data = getLayoutData(w); | |
| if (data.isHidden()) { | |
| return; | |
| } | |
| onCollapse((ContentPanel) w); | |
| } | |
| } | |
| /** | |
| * Expands the panel in the given region. If the target widget is hidden no action will be performed. | |
| * | |
| * @param region the region to expand | |
| */ | |
| public void expand(LayoutRegion region) { | |
| Widget w = getRegionWidget(region); | |
| if (w != null && w instanceof CollapsePanel) { | |
| BorderLayoutData data = getLayoutData(w); | |
| if (data.isHidden()) { | |
| return; | |
| } | |
| CollapsePanel collapse = (CollapsePanel) w; | |
| ContentPanel cp = (ContentPanel) collapse.getData("panel"); | |
| onExpand(cp); | |
| } | |
| } | |
| public BorderLayoutAppearance getAppearance() { | |
| return appearance; | |
| } | |
| @Override | |
| public Widget getCenterWidget() { | |
| return getWidget(); | |
| } | |
| @Override | |
| public Widget getEastWidget() { | |
| return east; | |
| } | |
| @Override | |
| public Widget getNorthWidget() { | |
| return north; | |
| } | |
| /** | |
| * Returns the split bar, or null, for the given region. | |
| * | |
| * @param region the region whose split bar is being returned | |
| * @return the split bar | |
| */ | |
| public SplitBar getSplitBar(LayoutRegion region) { | |
| Widget component = null; | |
| switch (region) { | |
| case NORTH: | |
| component = north; | |
| break; | |
| case EAST: | |
| component = east; | |
| break; | |
| case SOUTH: | |
| component = south; | |
| break; | |
| case WEST: | |
| component = west; | |
| break; | |
| } | |
| SplitBar splitBar = null; | |
| if (component != null && component instanceof Component) { | |
| splitBar = ((Component) component).getData("splitBar"); | |
| } | |
| return splitBar; | |
| } | |
| /** | |
| * Returns the widget in the specified region, or null if there is no widget for that region. | |
| * | |
| * @param region the region | |
| * @return the widget in the specified region, or null if there is no widget for that region | |
| */ | |
| public Widget getRegionWidget(LayoutRegion region) { | |
| switch (region) { | |
| case CENTER: | |
| return getCenterWidget(); | |
| case NORTH: | |
| return getNorthWidget(); | |
| case EAST: | |
| return getEastWidget(); | |
| case SOUTH: | |
| return getSouthWidget(); | |
| case WEST: | |
| return getWestWidget(); | |
| } | |
| return null; | |
| } | |
| @Override | |
| public Widget getSouthWidget() { | |
| return south; | |
| } | |
| @Override | |
| public Widget getWestWidget() { | |
| return west; | |
| } | |
| /** | |
| * Hides the component in the given region. | |
| * | |
| * @param region the layout region | |
| */ | |
| public void hide(LayoutRegion region) { | |
| Widget c = getRegionWidget(region); | |
| if (c != null) { | |
| BorderLayoutData data = (BorderLayoutData) c.getLayoutData(); | |
| data.setHidden(true); | |
| doLayout(); | |
| } | |
| } | |
| @Override | |
| public void setCenterWidget(IsWidget child) { | |
| setWidget(child); | |
| } | |
| /** | |
| * Sets the widget in the center region of the border layout container. The center region is a privileged position | |
| * that receives the remaining space not allocated to other regions. Border layout containers should generally specify | |
| * a center region and one or more other regions. | |
| * | |
| * @param child the widget to put in the center region | |
| * @param layoutData the layout data for the widget | |
| */ | |
| @UiChild(limit = 1, tagname = "center") | |
| public void setCenterWidget(IsWidget child, MarginData layoutData) { | |
| if (child != null) { | |
| child.asWidget().setLayoutData(layoutData); | |
| } | |
| setCenterWidget(child); | |
| } | |
| @Override | |
| public void setEastWidget(IsWidget child) { | |
| if (east != null) { | |
| remove(east); | |
| } | |
| if (child != null) { | |
| east = child.asWidget(); | |
| insert(east, 0); | |
| } | |
| } | |
| /** | |
| * <p>Sets the widget in the east (right) region of the border layout container.</p> | |
| * | |
| * <ul> | |
| * <li>In order to use layoutData.setCollapsible(true) the child has to be a {@link ContentPanel}</li> | |
| * <li>When using layoutData.setSplit(true) the child can implement {@link Collapsible}. | |
| * When the child implements collapsible, on selection of the split, it will collapse the child.</li> | |
| * </ul> | |
| * | |
| * @param child the widget to put in the east region | |
| * @param layoutData the layout data for the widget | |
| */ | |
| @UiChild(limit = 1, tagname = "east") | |
| public void setEastWidget(IsWidget child, BorderLayoutData layoutData) { | |
| assertLayoutDataFeaturesUsed("setEastWidget", child, layoutData); | |
| if (child != null) { | |
| child.asWidget().setLayoutData(layoutData); | |
| } | |
| setEastWidget(child); | |
| } | |
| @Override | |
| public void setNorthWidget(IsWidget child) { | |
| if (north != null) { | |
| remove(north); | |
| } | |
| if (child != null) { | |
| north = child.asWidget(); | |
| insert(north, 0); | |
| } | |
| } | |
| /** | |
| * <p>Sets the widget in the north (top) region of the border layout container.</p> | |
| * | |
| * <ul> | |
| * <li>In order to use layoutData.setCollapsible(true) the child has to be a {@link ContentPanel}</li> | |
| * <li>When using layoutData.setSplit(true) the child can implement {@link Collapsible}. | |
| * When the child implements collapsible, on selection of the split, it will collapse the child.</li> | |
| * </ul> | |
| * | |
| * @param child the widget to put in the north region | |
| * @param layoutData the layout data for the widget | |
| */ | |
| @UiChild(limit = 1, tagname = "north") | |
| public void setNorthWidget(IsWidget child, BorderLayoutData layoutData) { | |
| assertLayoutDataFeaturesUsed("setNorthWidget", child, layoutData); | |
| if (child != null) { | |
| child.asWidget().setLayoutData(layoutData); | |
| } | |
| setNorthWidget(child); | |
| } | |
| @Override | |
| public void setSouthWidget(IsWidget child) { | |
| if (south != null) { | |
| remove(south); | |
| } | |
| if (child != null) { | |
| south = child.asWidget(); | |
| insert(south, 0); | |
| } | |
| } | |
| /** | |
| * <p>Sets the widget in the south (bottom) region of the border layout container.</p> | |
| * | |
| * <ul> | |
| * <li>In order to use layoutData.setCollapsible(true) the child has to be a {@link ContentPanel}</li> | |
| * <li>When using layoutData.setSplit(true) the child can implement {@link Collapsible}. | |
| * When the child implements collapsible, on selection of the split, it will collapse the child.</li> | |
| * </ul> | |
| * | |
| * @param child the widget to put in the south region | |
| * @param layoutData the layout data for the widget | |
| */ | |
| @UiChild(limit = 1, tagname = "south") | |
| public void setSouthWidget(IsWidget child, BorderLayoutData layoutData) { | |
| assertLayoutDataFeaturesUsed("setSouthWidget", child, layoutData); | |
| if (child != null) { | |
| child.asWidget().setLayoutData(layoutData); | |
| } | |
| setSouthWidget(child); | |
| } | |
| @Override | |
| public void setWestWidget(IsWidget child) { | |
| if (west != null) { | |
| remove(west); | |
| } | |
| if (child != null) { | |
| west = child.asWidget(); | |
| insert(west, 0); | |
| } | |
| } | |
| /** | |
| * <p>Sets the widget in the west (left) region of the border layout container.</p> | |
| * | |
| * <ul> | |
| * <li>In order to use layoutData.setCollapsible(true) the child has to be a {@link ContentPanel}</li> | |
| * <li>When using layoutData.setSplit(true) the child can implement {@link Collapsible}. | |
| * When the child implements collapsible, on selection of the split, it will collapse the child.</li> | |
| * </ul> | |
| * | |
| * @param child the widget to put in the west region | |
| * @param layoutData the layout data for the widget | |
| */ | |
| @UiChild(limit = 1, tagname = "west") | |
| public void setWestWidget(IsWidget child, BorderLayoutData layoutData) { | |
| assertLayoutDataFeaturesUsed("setWestWidget", child, layoutData); | |
| if (child != null) { | |
| child.asWidget().setLayoutData(layoutData); | |
| } | |
| setWestWidget(child); | |
| } | |
| /** | |
| * Shows the component in the given region. | |
| * | |
| * @param region the layout region | |
| */ | |
| public void show(LayoutRegion region) { | |
| Widget c = getRegionWidget(region); | |
| if (c != null) { | |
| BorderLayoutData data = (BorderLayoutData) c.getLayoutData(); | |
| data.setHidden(false); | |
| doLayout(); | |
| } | |
| } | |
| @Override | |
| protected void applyLayout(Widget component, Rectangle box) { | |
| super.applyLayout(component, box); | |
| if (component instanceof Component) { | |
| final SplitBar bar = ((Component) component).getData("splitBar"); | |
| if (bar != null) { | |
| Scheduler.get().scheduleDeferred(new ScheduledCommand() { | |
| @Override | |
| public void execute() { | |
| bar.getElement().getStyle().setVisibility(Visibility.VISIBLE); | |
| } | |
| }); | |
| } | |
| } | |
| } | |
| protected CollapsePanel createCollapsePanel(ContentPanel panel, BorderLayoutData data, LayoutRegion region) { | |
| return new CollapsePanel(panel, data, region) { | |
| @Override | |
| protected void onExpandButton() { | |
| super.onExpandButton(); | |
| onExpandClick(this); | |
| } | |
| }; | |
| } | |
| protected SplitBar createSplitBar(Component component) { | |
| if (component == north) { | |
| return new SplitBar(LayoutRegion.SOUTH, component); | |
| } else if (component == south) { | |
| return new SplitBar(LayoutRegion.NORTH, component); | |
| } else if (component == west) { | |
| return new SplitBar(LayoutRegion.EAST, component); | |
| } else if (component == east) { | |
| return new SplitBar(LayoutRegion.WEST, component); | |
| } | |
| return null; | |
| } | |
| @Override | |
| protected void doLayout() { | |
| for (int i = 0; i < getWidgetCount(); i++) { | |
| Widget w = getWidget(i); | |
| if (w instanceof ContentPanel && w.getLayoutData() instanceof BorderLayoutData) { | |
| BorderLayoutData data = (BorderLayoutData) w.getLayoutData(); | |
| if (getRegion((Component) w) != LayoutRegion.CENTER) { | |
| if (data.isCollapsed()) { | |
| switchPanels((ContentPanel) w); | |
| } | |
| } | |
| } | |
| } | |
| Size size = getContainerTarget().getStyleSize(); | |
| if (GXTLogConfiguration.loggingIsEnabled()) { | |
| logger.finest(getId() + " doLayout size: " + size); | |
| } | |
| int w = size.getWidth(); | |
| int h = size.getHeight(); | |
| int sLeft = getContainerTarget().getPadding(Side.LEFT); | |
| int sTop = getContainerTarget().getPadding(Side.TOP); | |
| int centerW = w, centerH = h, centerY = 0, centerX = 0; | |
| if (north != null) { | |
| BorderLayoutData data = getLayoutData(north); | |
| north.setVisible(!data.isHidden()); | |
| if (north.isVisible()) { | |
| Rectangle b = new Rectangle(); | |
| Margins m = data.getMargins() != null ? data.getMargins() : new Margins(); | |
| double s = data.getSize() <= 1 ? data.getSize() * size.getHeight() : data.getSize(); | |
| b.setHeight((int) s); | |
| b.setWidth(w - (m.getLeft() + m.getRight())); | |
| b.setX(m.getLeft()); | |
| b.setY(m.getTop()); | |
| centerY = b.getHeight() + b.getY() + m.getBottom(); | |
| centerH -= centerY; | |
| b.setX(b.getX() + sLeft); | |
| b.setY(b.getY() + sTop); | |
| applyLayout(north, b); | |
| } | |
| } | |
| if (south != null) { | |
| BorderLayoutData data = getLayoutData(south); | |
| south.setVisible(!data.isHidden()); | |
| if (south.isVisible()) { | |
| Rectangle b = new Rectangle(); | |
| Margins m = data.getMargins() != null ? data.getMargins() : new Margins(); | |
| double s = data.getSize() <= 1 ? data.getSize() * size.getHeight() : data.getSize(); | |
| b.setHeight((int) s); | |
| b.setWidth(w - (m.getLeft() + m.getRight())); | |
| b.setX(m.getLeft()); | |
| int totalHeight = (b.getHeight() + m.getTop() + m.getBottom()); | |
| b.setY(h - totalHeight + m.getTop()); | |
| centerH -= totalHeight; | |
| b.setX(b.getX() + sLeft); | |
| b.setY(b.getY() + sTop); | |
| applyLayout(south, b); | |
| } | |
| } | |
| if (west != null) { | |
| BorderLayoutData data = getLayoutData(west); | |
| west.setVisible(!data.isHidden()); | |
| if (west.isVisible()) { | |
| Rectangle box = new Rectangle(); | |
| Margins m = data.getMargins() != null ? data.getMargins() : new Margins(); | |
| double s = data.getSize() <= 1 ? data.getSize() * size.getWidth() : data.getSize(); | |
| box.setWidth((int) s); | |
| box.setHeight(centerH - (m.getTop() + m.getBottom())); | |
| box.setX(m.getLeft()); | |
| box.setY(centerY + m.getTop()); | |
| int totalWidth = (box.getWidth() + m.getLeft() + m.getRight()); | |
| centerX += totalWidth; | |
| centerW -= totalWidth; | |
| box.setX(box.getX() + sLeft); | |
| box.setY(box.getY() + sTop); | |
| applyLayout(west, box); | |
| } | |
| } | |
| if (east != null) { | |
| BorderLayoutData data = getLayoutData(east); | |
| east.setVisible(!data.isHidden()); | |
| if (east.isVisible()) { | |
| Rectangle b = new Rectangle(); | |
| Margins m = data.getMargins() != null ? data.getMargins() : new Margins(); | |
| double s = data.getSize() <= 1 ? data.getSize() * size.getWidth() : data.getSize(); | |
| b.setWidth((int) s); | |
| b.setHeight(centerH - (m.getTop() + m.getBottom())); | |
| int totalWidth = (b.getWidth() + m.getLeft() + m.getRight()); | |
| b.setX(w - totalWidth + m.getLeft()); | |
| b.setY(centerY + m.getTop()); | |
| centerW -= totalWidth; | |
| b.setX(b.getX() + sLeft); | |
| b.setY(b.getY() + sTop); | |
| applyLayout(east, b); | |
| } | |
| } | |
| if (widget != null) { | |
| Object data = widget.getLayoutData(); | |
| Margins m = null; | |
| if (data instanceof HasMargins) { | |
| m = ((HasMargins) data).getMargins(); | |
| } | |
| if (m == null) { | |
| m = new Margins(0); | |
| } | |
| lastCenter = new Rectangle(centerX, centerY, centerW, centerH); | |
| lastCenter.setX(centerX + (m.getLeft() + sLeft)); | |
| lastCenter.setY(centerY + (m.getTop() + sTop)); | |
| lastCenter.setWidth(centerW - (m.getLeft() + m.getRight())); | |
| lastCenter.setHeight(centerH - (m.getTop() + m.getBottom())); | |
| applyLayout(widget, lastCenter); | |
| } | |
| } | |
| @Override | |
| protected XElement getContainerTarget() { | |
| return appearance.getContainerTarget(getElement()); | |
| } | |
| protected LayoutRegion getRegion(Component component) { | |
| if (component == north) { | |
| return LayoutRegion.NORTH; | |
| } else if (component == south) { | |
| return LayoutRegion.SOUTH; | |
| } else if (component == west) { | |
| return LayoutRegion.WEST; | |
| } else if (component == east) { | |
| return LayoutRegion.EAST; | |
| } | |
| return null; | |
| } | |
| protected void onCollapse(ContentPanel panel) { | |
| switchPanels(panel); | |
| doLayout(); | |
| CollapsePanel cp = (CollapsePanel) panel.getData("collapse"); | |
| SplitBar bar = cp.getSplitBar(); | |
| if (bar != null) { | |
| bar.sync(); | |
| } | |
| fireEvent(new CollapseItemEvent<ContentPanel>(panel)); | |
| } | |
| protected void onExpand(ContentPanel panel) { | |
| CollapsePanel cp = panel.getData("collapse"); | |
| LayoutRegion region = getRegion(cp); | |
| switch (region) { | |
| case WEST: | |
| setWestWidget(panel); | |
| break; | |
| case EAST: | |
| setEastWidget(panel); | |
| break; | |
| case NORTH: | |
| setNorthWidget(panel); | |
| break; | |
| case SOUTH: | |
| setSouthWidget(panel); | |
| break; | |
| case CENTER: | |
| // do nothing | |
| break; | |
| } | |
| setCollapsed(panel, false); | |
| BorderLayoutData data = (BorderLayoutData) panel.getLayoutData(); | |
| data.setCollapsed(false); | |
| doLayout(); | |
| fireEvent(new ExpandItemEvent<ContentPanel>(panel)); | |
| } | |
| protected void onExpandClick(CollapsePanel collapse) { | |
| ContentPanel panel = collapse.getContentPanel(); | |
| onExpand(panel); | |
| } | |
| @Override | |
| protected void onInsert(int index, Widget child) { | |
| child.addStyleName(CommonStyles.get().positionable()); | |
| appearance.onInsert(child); | |
| if (!(child instanceof Component)) { | |
| return; | |
| } | |
| final Component c = (Component) child; | |
| if (c == getWidget()) { | |
| return; | |
| } | |
| final BorderLayoutData data = getLayoutData(c); | |
| if (c instanceof CollapsePanel) { | |
| final CollapsePanel collapse = (CollapsePanel) c; | |
| final BorderLayoutData panelData = (BorderLayoutData) collapse.getContentPanel().getLayoutData(); | |
| SplitBar bar = collapse.getData("splitBar"); | |
| if (bar == null || bar.getTargetWidget() != c) { | |
| bar = collapse.getSplitBar(); | |
| bar.setCollapsible(panelData.isCollapseMini()); | |
| c.setData("splitBar", bar); | |
| if (panelData.isCollapseHidden()) { | |
| collapse.collapseHidden(); | |
| } | |
| bar.addSelectHandler(new SelectHandler() { | |
| @Override | |
| public void onSelect(SelectEvent event) { | |
| onExpandClick((CollapsePanel) c); | |
| } | |
| }); | |
| } | |
| } | |
| if (data.isCollapsible() && c instanceof ContentPanel && !c.isRendered()) { | |
| final ContentPanel cp = (ContentPanel) c; | |
| cp.setCollapsible(true); | |
| cp.setHideCollapseTool(true); | |
| IconConfig config = ToolButton.DOUBLELEFT; | |
| switch (getRegion(cp)) { | |
| case NORTH: | |
| config = ToolButton.DOUBLEUP; | |
| break; | |
| case SOUTH: | |
| config = ToolButton.DOUBLEDOWN; | |
| break; | |
| case EAST: | |
| config = ToolButton.DOUBLERIGHT; | |
| break; | |
| case WEST: | |
| case CENTER: | |
| // do nothing | |
| } | |
| cp.getHeader().addTool(new ToolButton(config, new SelectHandler() { | |
| @Override | |
| public void onSelect(SelectEvent event) { | |
| cp.collapse(); | |
| } | |
| })); | |
| cp.addBeforeCollapseHandler(collapseHandler); | |
| cp.addBeforeExpandHandler(collapseHandler); | |
| } | |
| if (data.isSplit()) { | |
| SplitBar bar = c.getData("splitBar"); | |
| if (bar == null || bar.getTargetWidget() != c) { | |
| bar = createSplitBar(c); | |
| final SplitBar fbar = bar; | |
| bar.setCollapsible(data.isCollapseMini()); | |
| if (data.isCollapseMini()) { | |
| switch (getRegion(c)) { | |
| case EAST: | |
| bar.updateMini(Direction.RIGHT); | |
| break; | |
| case WEST: | |
| bar.updateMini(Direction.LEFT); | |
| break; | |
| case NORTH: | |
| bar.updateMini(Direction.UP); | |
| break; | |
| case SOUTH: | |
| bar.updateMini(Direction.DOWN); | |
| break; | |
| case CENTER: | |
| // do nothing | |
| } | |
| bar.addSelectHandler(new SelectHandler() { | |
| @Override | |
| public void onSelect(SelectEvent event) { | |
| if (c instanceof Collapsible) { | |
| ((Collapsible) c).collapse(); | |
| } | |
| } | |
| }); | |
| } | |
| bar.addSplitBarDragHandler(new SplitBarDragHandler() { | |
| @Override | |
| public void onDragEvent(SplitBarDragEvent event) { | |
| LayoutRegion region = getRegion(c); | |
| if (event.isStart()) { | |
| fbar.setMinSize(data.getMinSize()); | |
| boolean side = region == LayoutRegion.WEST || region == LayoutRegion.EAST; | |
| int size = side ? c.getOffsetWidth() : c.getOffsetHeight(); | |
| if (lastCenter != null) { | |
| int centerSize = side ? lastCenter.getWidth() : lastCenter.getHeight(); | |
| fbar.setMaxSize(Math.min(size + centerSize, data.getMaxSize())); | |
| } | |
| } else { | |
| if (event.getSize() < 1) { | |
| return; | |
| } | |
| data.setSize(event.getSize()); | |
| doLayout(); | |
| } | |
| } | |
| }); | |
| } | |
| bar.getElement().getStyle().setVisibility(Visibility.HIDDEN); | |
| c.setData("splitBar", bar); | |
| bar.setMinSize(data.getMinSize()); | |
| bar.setMaxSize(data.getMaxSize() == 0 ? bar.getMaxSize() : data.getMaxSize()); | |
| bar.setAutoSize(false); | |
| } | |
| } | |
| @Override | |
| protected void onRemove(Widget child) { | |
| super.onRemove(child); | |
| appearance.onRemove(child); | |
| if (north == child) { | |
| north = null; | |
| } else if (south == child) { | |
| south = null; | |
| } else if (east == child) { | |
| east = null; | |
| } else if (west == child) { | |
| west = null; | |
| } | |
| child.removeStyleName(CommonStyles.get().positionable()); | |
| } | |
| private BorderLayoutData getLayoutData(Widget w) { | |
| Object o = w.getLayoutData(); | |
| return (BorderLayoutData) ((o instanceof BorderLayoutData) ? o : new BorderLayoutData(100)); | |
| } | |
| private native void setCollapsed(ContentPanel panel, boolean collapse) /*-{ | |
| [email protected]::collapsed = collapse; | |
| }-*/; | |
| private void switchPanels(ContentPanel panel) { | |
| LayoutRegion region = getRegion(panel); | |
| BorderLayoutData data = getLayoutData(panel); | |
| int size = getCollapsedHeaderHeight(panel); | |
| remove(panel); | |
| CollapsePanel cp = (CollapsePanel) panel.getData("collapse"); | |
| if (cp == null) { | |
| cp = createCollapsePanel(panel, data, region); | |
| BorderLayoutData collapseData = new BorderLayoutData(); | |
| collapseData.setSize(data.isCollapseHidden() ? 0 : size); | |
| Margins m = data.getMargins(); | |
| if (m == null) { | |
| m = new Margins(); | |
| data.setMargins(m); | |
| } | |
| collapseData.setMargins(new Margins(m.getTop(), m.getRight(), m.getBottom(), m.getLeft())); | |
| if (data.isCollapseHidden()) { | |
| cp.collapseHidden(); | |
| collapseData.setSize(0); | |
| switch (region) { | |
| case WEST: | |
| collapseData.getMargins().setLeft(0); | |
| break; | |
| case EAST: | |
| collapseData.getMargins().setRight(0); | |
| break; | |
| case NORTH: | |
| collapseData.getMargins().setTop(0); | |
| break; | |
| case SOUTH: | |
| collapseData.getMargins().setBottom(0); | |
| break; | |
| case CENTER: | |
| // do nothing | |
| } | |
| } | |
| cp.setLayoutData(collapseData); | |
| cp.setData("panel", panel); | |
| panel.setData("collapse", cp); | |
| } | |
| cp.clearSizeCache(); | |
| setCollapsed(panel, true); | |
| switch (region) { | |
| case WEST: | |
| setWestWidget(cp); | |
| break; | |
| case EAST: | |
| setEastWidget(cp); | |
| break; | |
| case NORTH: | |
| setNorthWidget(cp); | |
| break; | |
| case SOUTH: | |
| setSouthWidget(cp); | |
| break; | |
| case CENTER: | |
| // do nothing | |
| } | |
| } | |
| private void assertLayoutDataFeaturesUsed(String from, IsWidget child, BorderLayoutData layoutData) { | |
| if (layoutData == null || child == null) { | |
| return; | |
| } | |
| assert !layoutData.isCollapsible() || child.asWidget() instanceof ContentPanel : "In order to use layoutData.setCollapsible(true) " + from + "(child, layoutData) a GXT ContentPanel has to be used as the child widget."; | |
| } | |
| protected int getCollapsedHeaderHeight(ContentPanel panel) { | |
| return panel.getAppearance().getHeaderSize(panel.getElement()).getHeight(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment