001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package nextapp.echo2.webcontainer.propertyrender;
031:
032: import org.w3c.dom.Element;
033:
034: import nextapp.echo2.app.Component;
035: import nextapp.echo2.app.ImageReference;
036: import nextapp.echo2.app.Insets;
037: import nextapp.echo2.app.layout.CellLayoutData;
038: import nextapp.echo2.webcontainer.RenderContext;
039: import nextapp.echo2.webcontainer.image.ImageRenderSupport;
040: import nextapp.echo2.webrender.output.CssStyle;
041:
042: /**
043: * Utility class for rendering
044: * <code>nextapp.echo2.app.layout.CellLayoutData</code>
045: * layout data properties to CSS.
046: */
047: public class CellLayoutDataRender {
048:
049: private static String IMAGE_ID_PREFIX_LAYOUT_DATA_BACKGROUND_IMAGE = "CellLayoutData.BackgroundImage.";
050: private static int IMAGE_ID_PREFIX_LAYOUT_DATA_BACKGROUND_IMAGE_LENGTH = IMAGE_ID_PREFIX_LAYOUT_DATA_BACKGROUND_IMAGE
051: .length();
052:
053: /**
054: * A delegate method to be invoked by the container <code>Component</code>'s
055: * <code>ComponentSynchronizePeer</code>'s
056: * <code>ImageRenderSupport.getImage()</code> implementation. This method
057: * will return the appropriate <code>CellLayoutData</code> background
058: * image if the identifier corresponds to one, otherwise null is returned.
059: *
060: * @param component the container <code>Component</code>
061: * @param imageId the identifier of the image
062: * @return the <code>ImageReference</code> or null if the specified
063: * <code>imageId</code> does not specify a
064: * <code>CellLayoutData</code> <code>BackgroundImage</code>
065: * @see #renderBackgroundImageToStyle(CssStyle, RenderContext,
066: * ImageRenderSupport, Component, Component)
067: */
068: public static ImageReference getCellLayoutDataBackgroundImage(
069: Component component, String imageId) {
070: if (imageId
071: .startsWith(IMAGE_ID_PREFIX_LAYOUT_DATA_BACKGROUND_IMAGE)) {
072: String childRenderId = imageId
073: .substring(IMAGE_ID_PREFIX_LAYOUT_DATA_BACKGROUND_IMAGE_LENGTH);
074: int childCount = component.getComponentCount();
075: for (int i = 0; i < childCount; ++i) {
076: Component child = component.getComponent(i);
077: if (child.getRenderId().equals(childRenderId)) {
078: return ((CellLayoutData) child
079: .getRenderProperty(Component.PROPERTY_LAYOUT_DATA))
080: .getBackgroundImage().getImage();
081: }
082: }
083: }
084: return null;
085: }
086:
087: /**
088: * Renders the <code>backgroundImage</code> property of a
089: * <code>CellLayoutDataRender</code> to a <code>CssStyle</code>.
090: * The image will be assigned an identifier by this object
091: * prefaced with the namespace "CellLayoutData".
092: * The <code>ImageRenderSupport.getImage()</code> implementation
093: * may obtain images based on these ids by invoking the
094: * <code>getCellLayoutDataBackgroundImage()</code> method. Note
095: * that any image id may be safely passed to
096: * <code>getCellLayoutDataBackgroundImage()</code> as it will return
097: * null if it does not have an image to match the specified id.
098: *
099: * @param cssStyle the target <code>CssStyle</code>
100: * @param rc the relevant <code>RenderContext</code>
101: * @param irs the <code>ImageRenderSupport</code> which will provide
102: * identified images
103: * @param parent the parent <code>Component</code>
104: * @param child the child <code>Component</code>
105: * @see #getCellLayoutDataBackgroundImage(Component, String)
106: */
107: public static void renderBackgroundImageToStyle(CssStyle cssStyle,
108: RenderContext rc, ImageRenderSupport irs, Component parent,
109: Component child) {
110: CellLayoutData layoutData = (CellLayoutData) child
111: .getRenderProperty(Component.PROPERTY_LAYOUT_DATA);
112: if (layoutData == null
113: || layoutData.getBackgroundImage() == null) {
114: return;
115: }
116: FillImageRender.renderToStyle(cssStyle, rc, irs, parent,
117: IMAGE_ID_PREFIX_LAYOUT_DATA_BACKGROUND_IMAGE
118: + child.getRenderId(), layoutData
119: .getBackgroundImage(), 0);
120: }
121:
122: /**
123: * Renders a <code>CellLayoutData</code> property to the given CSS style
124: * and HTML element. Null property values are handled properly (and default
125: * insets are still rendered if provided in such cases).
126: * <code>Alignment</code> information will be added to the
127: * <code>Element</code> such that block elements contained within it will
128: * be properly aligned. All other properties will be rendered using the
129: * <code>CssSyle</code>. Use of this method requires a "transitional"
130: * DOCTYPE.
131: *
132: * @param element the target <code>Element</code>
133: * @param cssStyle the target <code>CssStyle</code>
134: * @param component the child <code>Component</code> being laid out (used
135: * to determine <code>LayoutDirection</code> (LTR/RTL).
136: * @param layoutData the property value
137: * @param defaultInsetsAttributeValue the default insets for the cell
138: * (provided as a string in the interest of performance to avoid
139: * repeatedly rendering the same <code>Insets</code> object for
140: * each cell
141: */
142: public static void renderToElementAndStyle(Element element,
143: CssStyle cssStyle, Component component,
144: CellLayoutData layoutData,
145: String defaultInsetsAttributeValue) {
146: if (layoutData == null) {
147: if (defaultInsetsAttributeValue != null) {
148: cssStyle.setAttribute("padding",
149: defaultInsetsAttributeValue);
150: }
151: return;
152: }
153:
154: // Render padding.
155: Insets cellInsets = layoutData.getInsets();
156: if (cellInsets == null) {
157: if (defaultInsetsAttributeValue != null) {
158: cssStyle.setAttribute("padding",
159: defaultInsetsAttributeValue);
160: }
161: } else {
162: cssStyle.setAttribute("padding", InsetsRender
163: .renderCssAttributeValue(cellInsets));
164: }
165:
166: // Render background.
167: ColorRender.renderToStyle(cssStyle, null, layoutData
168: .getBackground());
169:
170: // Render alignment.
171: AlignmentRender.renderToElement(element, layoutData
172: .getAlignment(), component);
173: }
174:
175: /**
176: * Renders a <code>CellLayoutData</code> property to the given CSS style.
177: * Null property values are handled properly (and default insets are still
178: * rendered if provided in such cases).
179: *
180: * @param cssStyle the target <code>CssStyle</code>
181: * @param component the child <code>Component</code> being laid out (used
182: * to determine <code>LayoutDirection</code> (LTR/RTL).
183: * @param layoutData the property value
184: * @param defaultInsetsAttributeValue the default insets for the cell
185: * (provided as a string in the interest of performance to avoid
186: * repeatedly rendering the same <code>Insets</code> object for
187: * each cell
188: */
189: public static void renderToStyle(CssStyle cssStyle,
190: Component component, CellLayoutData layoutData,
191: String defaultInsetsAttributeValue) {
192: if (layoutData == null) {
193: if (defaultInsetsAttributeValue != null) {
194: cssStyle.setAttribute("padding",
195: defaultInsetsAttributeValue);
196: }
197: return;
198: }
199:
200: // Render padding.
201: Insets cellInsets = layoutData.getInsets();
202: if (cellInsets == null) {
203: if (defaultInsetsAttributeValue != null) {
204: cssStyle.setAttribute("padding",
205: defaultInsetsAttributeValue);
206: }
207: } else {
208: cssStyle.setAttribute("padding", InsetsRender
209: .renderCssAttributeValue(cellInsets));
210: }
211:
212: // Render background.
213: ColorRender.renderToStyle(cssStyle, null, layoutData
214: .getBackground());
215:
216: // Render alignment.
217: AlignmentRender.renderToStyle(cssStyle, layoutData
218: .getAlignment(), component);
219: }
220:
221: /** Non-instantiable class. */
222: private CellLayoutDataRender() {
223: }
224: }
|