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.syncpeer;
031:
032: import nextapp.echo2.app.Alignment;
033: import nextapp.echo2.app.Color;
034: import nextapp.echo2.app.Component;
035: import nextapp.echo2.app.Extent;
036: import nextapp.echo2.app.Font;
037: import nextapp.echo2.app.ImageReference;
038: import nextapp.echo2.app.Label;
039: import nextapp.echo2.app.update.ServerComponentUpdate;
040: import nextapp.echo2.webcontainer.ContainerInstance;
041: import nextapp.echo2.webcontainer.DomUpdateSupport;
042: import nextapp.echo2.webcontainer.RenderContext;
043: import nextapp.echo2.webcontainer.ComponentSynchronizePeer;
044: import nextapp.echo2.webcontainer.image.ImageRenderSupport;
045: import nextapp.echo2.webcontainer.propertyrender.AlignmentRender;
046: import nextapp.echo2.webcontainer.propertyrender.ColorRender;
047: import nextapp.echo2.webcontainer.propertyrender.FontRender;
048: import nextapp.echo2.webcontainer.propertyrender.ImageReferenceRender;
049: import nextapp.echo2.webcontainer.propertyrender.LayoutDirectionRender;
050: import nextapp.echo2.webrender.output.CssStyle;
051: import nextapp.echo2.webrender.servermessage.DomUpdate;
052: import nextapp.echo2.webrender.util.DomUtil;
053:
054: import org.w3c.dom.Document;
055: import org.w3c.dom.DocumentFragment;
056: import org.w3c.dom.Element;
057: import org.w3c.dom.Node;
058:
059: /**
060: * Synchronization peer for <code>nextapp.echo2.app.Label</code> components.
061: * <p>
062: * This class should not be extended or used by classes outside of the
063: * Echo framework.
064: */
065: public class LabelPeer implements DomUpdateSupport, ImageRenderSupport,
066: ComponentSynchronizePeer {
067:
068: private static final Alignment DEFAULT_TEXT_POSITION = new Alignment(
069: Alignment.TRAILING, Alignment.DEFAULT);
070: private static final Extent DEFAULT_ICON_TEXT_MARGIN = new Extent(3);
071: private static final String IMAGE_ID_ICON = "icon";
072:
073: /**
074: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderAdd(nextapp.echo2.webcontainer.RenderContext,
075: * nextapp.echo2.app.update.ServerComponentUpdate, java.lang.String, nextapp.echo2.app.Component)
076: */
077: public void renderAdd(RenderContext rc,
078: ServerComponentUpdate update, String targetId,
079: Component component) {
080: Element domAddElement = DomUpdate.renderElementAdd(rc
081: .getServerMessage());
082: DocumentFragment htmlFragment = rc.getServerMessage()
083: .getDocument().createDocumentFragment();
084: renderHtml(rc, update, htmlFragment, component);
085: DomUpdate.renderElementAddContent(rc.getServerMessage(),
086: domAddElement, targetId, htmlFragment);
087: }
088:
089: /**
090: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#getContainerId(nextapp.echo2.app.Component)
091: */
092: public String getContainerId(Component child) {
093: throw new UnsupportedOperationException(
094: "Component does not support children.");
095: }
096:
097: /**
098: * @see nextapp.echo2.webcontainer.image.ImageRenderSupport#getImage(nextapp.echo2.app.Component, java.lang.String)
099: */
100: public ImageReference getImage(Component component, String imageId) {
101: if (IMAGE_ID_ICON.equals(imageId)) {
102: return (ImageReference) component
103: .getRenderProperty(Label.PROPERTY_ICON);
104: } else {
105: return null;
106: }
107: }
108:
109: /**
110: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderDispose(nextapp.echo2.webcontainer.RenderContext,
111: * nextapp.echo2.app.update.ServerComponentUpdate, nextapp.echo2.app.Component)
112: */
113: public void renderDispose(RenderContext rc,
114: ServerComponentUpdate update, Component component) {
115: // Do nothing.
116: }
117:
118: /**
119: * @see nextapp.echo2.webcontainer.DomUpdateSupport#renderHtml(nextapp.echo2.webcontainer.RenderContext,
120: * nextapp.echo2.app.update.ServerComponentUpdate, org.w3c.dom.Node, nextapp.echo2.app.Component)
121: */
122: public void renderHtml(RenderContext rc,
123: ServerComponentUpdate update, Node parentNode,
124: Component component) {
125: Label label = (Label) component;
126: ImageReference icon = (ImageReference) label
127: .getRenderProperty(Label.PROPERTY_ICON);
128: String text = (String) label
129: .getRenderProperty(Label.PROPERTY_TEXT);
130:
131: if (icon != null) {
132: if (text != null) {
133: renderIconTextLabel(rc, parentNode, label);
134: } else {
135: renderIconLabel(rc, parentNode, label);
136: }
137: } else if (text != null) {
138: renderTextLabel(rc, parentNode, label);
139: }
140: }
141:
142: /**
143: * Renders a label containing only an icon.
144: *
145: * @param rc the relevant <code>RenderContext</code>
146: * @param parentNode the parent node
147: * @param label the <code>Label</code>
148: */
149: private void renderIconLabel(RenderContext rc, Node parentNode,
150: Label label) {
151: Element imgElement = ImageReferenceRender
152: .renderImageReferenceElement(rc, this , label,
153: IMAGE_ID_ICON);
154: imgElement.setAttribute("id", ContainerInstance
155: .getElementId(label));
156: imgElement.setAttribute("style", "border:0px none;");
157:
158: String toolTipText = (String) label
159: .getRenderProperty(Label.PROPERTY_TOOL_TIP_TEXT);
160: if (toolTipText != null) {
161: imgElement.setAttribute("title", toolTipText);
162: }
163:
164: parentNode.appendChild(imgElement);
165: }
166:
167: /**
168: * Renders a label containing both an icon and text.
169: *
170: * @param rc the relevant <code>RenderContext</code>
171: * @param parentNode the parent node
172: * @param label the <code>Label</code>
173: */
174: private void renderIconTextLabel(RenderContext rc, Node parentNode,
175: Label label) {
176: // TriCellTable rendering note:
177: // Cell 0 = Text
178: // Cell 1 = Icon
179:
180: Document document = rc.getServerMessage().getDocument();
181: String text = (String) label
182: .getRenderProperty(Label.PROPERTY_TEXT);
183: Alignment textPosition = (Alignment) label.getRenderProperty(
184: Label.PROPERTY_TEXT_POSITION, DEFAULT_TEXT_POSITION);
185: Extent iconTextMargin = (Extent) label.getRenderProperty(
186: Label.PROPERTY_ICON_TEXT_MARGIN,
187: DEFAULT_ICON_TEXT_MARGIN);
188: String elementId = ContainerInstance.getElementId(label);
189:
190: int orientation = TriCellTableConfigurator
191: .convertIconTextPositionToOrientation(textPosition,
192: label);
193: TriCellTable tct = new TriCellTable(rc, document, elementId,
194: orientation, iconTextMargin);
195: tct.addCellCssText("padding:0px;");
196:
197: Element textTdElement = tct.getTdElement(0);
198: CssStyle textTdCssStyle = new CssStyle();
199: textTdCssStyle.setAttribute("border", "0px none");
200: if (Boolean.FALSE.equals(label
201: .getRenderProperty(Label.PROPERTY_LINE_WRAP))) {
202: textTdCssStyle.setAttribute("white-space", "nowrap");
203: }
204: AlignmentRender.renderToStyle(textTdCssStyle, (Alignment) label
205: .getRenderProperty(Label.PROPERTY_TEXT_ALIGNMENT),
206: label);
207: textTdElement.setAttribute("style", textTdElement
208: .getAttribute("style")
209: + textTdCssStyle.renderInline());
210: DomUtil.setElementText(textTdElement, text);
211:
212: Element imgElement = ImageReferenceRender
213: .renderImageReferenceElement(rc, this , label,
214: IMAGE_ID_ICON);
215: Element iconTdElement = tct.getTdElement(1);
216: iconTdElement.appendChild(imgElement);
217:
218: Element tableElement = tct.getTableElement();
219: tableElement.setAttribute("id", elementId);
220:
221: String toolTipText = (String) label
222: .getRenderProperty(Label.PROPERTY_TOOL_TIP_TEXT);
223: if (toolTipText != null) {
224: tableElement.setAttribute("title", toolTipText);
225: }
226:
227: CssStyle cssStyle = new CssStyle();
228: LayoutDirectionRender.renderToStyle(cssStyle, label
229: .getLayoutDirection(), label.getLocale());
230: ColorRender.renderToStyle(cssStyle, (Color) label
231: .getRenderProperty(Label.PROPERTY_FOREGROUND),
232: (Color) label
233: .getRenderProperty(Label.PROPERTY_BACKGROUND));
234: FontRender.renderToStyle(cssStyle, (Font) label
235: .getRenderProperty(Label.PROPERTY_FONT));
236: cssStyle.setAttribute("border", "0px none");
237: cssStyle.setAttribute("border-collapse", "collapse");
238: tableElement.setAttribute("style", cssStyle.renderInline());
239:
240: parentNode.appendChild(tableElement);
241: }
242:
243: /**
244: * Renders a label containing only text
245: *
246: * @param rc the relevant <code>RenderContext</code>
247: * @param parentNode the parent node
248: * @param label the <code>Label</code>
249: */
250: private void renderTextLabel(RenderContext rc, Node parentNode,
251: Label label) {
252: Document document = rc.getServerMessage().getDocument();
253:
254: Element spanElement = document.createElement("span");
255: spanElement.setAttribute("id", ContainerInstance
256: .getElementId(label));
257: DomUtil.setElementText(spanElement, (String) label
258: .getRenderProperty(Label.PROPERTY_TEXT));
259:
260: CssStyle cssStyle = new CssStyle();
261: if (Boolean.FALSE.equals(label
262: .getRenderProperty(Label.PROPERTY_LINE_WRAP))) {
263: cssStyle.setAttribute("white-space", "nowrap");
264: }
265: ColorRender.renderToStyle(cssStyle, (Color) label
266: .getRenderProperty(Label.PROPERTY_FOREGROUND),
267: (Color) label
268: .getRenderProperty(Label.PROPERTY_BACKGROUND));
269: FontRender.renderToStyle(cssStyle, (Font) label
270: .getRenderProperty(Label.PROPERTY_FONT));
271: if (cssStyle.hasAttributes()) {
272: spanElement.setAttribute("style", cssStyle.renderInline());
273: }
274:
275: String toolTipText = (String) label
276: .getRenderProperty(Label.PROPERTY_TOOL_TIP_TEXT);
277: if (toolTipText != null) {
278: spanElement.setAttribute("title", toolTipText);
279: }
280:
281: parentNode.appendChild(spanElement);
282: }
283:
284: /**
285: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderUpdate(nextapp.echo2.webcontainer.RenderContext,
286: * nextapp.echo2.app.update.ServerComponentUpdate, java.lang.String)
287: */
288: public boolean renderUpdate(RenderContext rc,
289: ServerComponentUpdate update, String targetId) {
290: DomUpdate.renderElementRemove(rc.getServerMessage(),
291: ContainerInstance.getElementId(update.getParent()));
292: renderAdd(rc, update, targetId, update.getParent());
293: return false;
294: }
295: }
|