| /* |
| * Copyright 2008 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.user.client.ui; |
| |
| import com.google.gwt.i18n.client.LocaleInfo; |
| import com.google.gwt.user.client.DOM; |
| import com.google.gwt.user.client.Element; |
| |
| /** |
| * <p> |
| * A {@link SimplePanel} that wraps its contents in stylized boxes, which can be |
| * used to add rounded corners to a {@link Widget}. |
| * </p> |
| * <p> |
| * This widget will <em>only</em> work in quirks mode in most cases. |
| * Specifically, setting the height or width of the DecoratorPanel will result |
| * in rendering issues. |
| * </p> |
| * <p> |
| * Wrapping a {@link Widget} in a "9-box" allows users to specify images in each |
| * of the corners and along the four borders. This method allows the content |
| * within the {@link DecoratorPanel} to resize without disrupting the look of |
| * the border. In addition, rounded corners can generally be combined into a |
| * single image file, which reduces the number of downloaded files at startup. |
| * This class also simplifies the process of using AlphaImageLoaders to support |
| * 8-bit transparencies (anti-aliasing and shadows) in ie6, which does not |
| * support them normally. |
| * </p> |
| * <h3>Setting the Size:</h3> |
| * <p> |
| * If you set the width or height of the {@link DecoratorPanel}, you need to |
| * set the height and width of the middleCenter cell to 100% so that the |
| * middleCenter cell takes up all of the available space. If you do not set the |
| * width and height of the {@link DecoratorPanel}, it will wrap its contents |
| * tightly. |
| * </p> |
| * |
| * <pre> |
| * .gwt-DecoratorPanel .middleCenter { |
| * height: 100%; |
| * width: 100%; |
| * } |
| * </pre> |
| * |
| * <h3>CSS Style Rules</h3> |
| * <ul class='css'> |
| * <li>.gwt-DecoratorPanel { the panel }</li> |
| * <li>.gwt-DecoratorPanel .top { the top row }</li> |
| * <li>.gwt-DecoratorPanel .topLeft { the top left cell }</li> |
| * <li>.gwt-DecoratorPanel .topLeftInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .topCenter { the top center cell }</li> |
| * <li>.gwt-DecoratorPanel .topCenterInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .topRight { the top right cell }</li> |
| * <li>.gwt-DecoratorPanel .topRightInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .middle { the middle row }</li> |
| * <li>.gwt-DecoratorPanel .middleLeft { the middle left cell }</li> |
| * <li>.gwt-DecoratorPanel .middleLeftInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .middleCenter { the middle center cell }</li> |
| * <li>.gwt-DecoratorPanel .middleCenterInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .middleRight { the middle right cell }</li> |
| * <li>.gwt-DecoratorPanel .middleRightInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .bottom { the bottom row }</li> |
| * <li>.gwt-DecoratorPanel .bottomLeft { the bottom left cell }</li> |
| * <li>.gwt-DecoratorPanel .bottomLeftInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .bottomCenter { the bottom center cell }</li> |
| * <li>.gwt-DecoratorPanel .bottomCenterInner { the inner element of the cell }</li> |
| * <li>.gwt-DecoratorPanel .bottomRight { the bottom right cell }</li> |
| * <li>.gwt-DecoratorPanel .bottomRightInner { the inner element of the cell }</li> |
| * </ul> |
| */ |
| public class DecoratorPanel extends SimplePanel { |
| /** |
| * The default style name. |
| */ |
| private static final String DEFAULT_STYLENAME = "gwt-DecoratorPanel"; |
| |
| /** |
| * The default styles applied to each row. |
| */ |
| private static final String[] DEFAULT_ROW_STYLENAMES = { |
| "top", "middle", "bottom"}; |
| |
| /** |
| * Create a new row with a specific style name. The row will contain three |
| * cells (Left, Center, and Right), each prefixed with the specified style |
| * name. |
| * |
| * This method allows Widgets to reuse the code on a DOM level, without |
| * creating a DecoratorPanel Widget. |
| * |
| * @param styleName the style name |
| * @return the new row {@link Element} |
| */ |
| static Element createTR(String styleName) { |
| Element trElem = DOM.createTR(); |
| setStyleName(trElem, styleName); |
| if (LocaleInfo.getCurrentLocale().isRTL()) { |
| DOM.appendChild(trElem, createTD(styleName + "Right")); |
| DOM.appendChild(trElem, createTD(styleName + "Center")); |
| DOM.appendChild(trElem, createTD(styleName + "Left")); |
| } else { |
| DOM.appendChild(trElem, createTD(styleName + "Left")); |
| DOM.appendChild(trElem, createTD(styleName + "Center")); |
| DOM.appendChild(trElem, createTD(styleName + "Right")); |
| } |
| return trElem; |
| } |
| |
| /** |
| * Create a new table cell with a specific style name. |
| * |
| * @param styleName the style name |
| * @return the new cell {@link Element} |
| */ |
| private static Element createTD(String styleName) { |
| Element tdElem = DOM.createTD(); |
| Element inner = DOM.createDiv(); |
| DOM.appendChild(tdElem, inner); |
| setStyleName(tdElem, styleName); |
| setStyleName(inner, styleName + "Inner"); |
| return tdElem; |
| } |
| |
| /** |
| * The container element at the center of the panel. |
| */ |
| private Element containerElem; |
| |
| /** |
| * The table body element. |
| */ |
| private Element tbody; |
| |
| /** |
| * Create a new {@link DecoratorPanel}. |
| */ |
| public DecoratorPanel() { |
| this(DEFAULT_ROW_STYLENAMES, 1); |
| } |
| |
| /** |
| * Creates a new panel using the specified style names to apply to each row. |
| * Each row will contain three cells (Left, Center, and Right). The Center |
| * cell in the containerIndex row will contain the {@link Widget}. |
| * |
| * @param rowStyles an array of style names to apply to each row |
| * @param containerIndex the index of the container row |
| */ |
| DecoratorPanel(String[] rowStyles, int containerIndex) { |
| super(DOM.createTable()); |
| |
| // Add a tbody |
| Element table = getElement(); |
| tbody = DOM.createTBody(); |
| DOM.appendChild(table, tbody); |
| DOM.setElementPropertyInt(table, "cellSpacing", 0); |
| DOM.setElementPropertyInt(table, "cellPadding", 0); |
| |
| // Add each row |
| for (int i = 0; i < rowStyles.length; i++) { |
| Element row = createTR(rowStyles[i]); |
| DOM.appendChild(tbody, row); |
| if (i == containerIndex) { |
| containerElem = DOM.getFirstChild(DOM.getChild(row, 1)); |
| } |
| } |
| |
| // Set the overall style name |
| setStyleName(DEFAULT_STYLENAME); |
| } |
| |
| /** |
| * Get a specific Element from the panel. |
| * |
| * @param row the row index |
| * @param cell the cell index |
| * @return the Element at the given row and cell |
| */ |
| protected Element getCellElement(int row, int cell) { |
| Element tr = DOM.getChild(tbody, row); |
| Element td = DOM.getChild(tr, cell); |
| return DOM.getFirstChild(td); |
| } |
| |
| @Override |
| protected Element getContainerElement() { |
| return containerElem; |
| } |
| } |