001: /* Image.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Mon Jul 18 20:57:18 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2004 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zul;
020:
021: import org.zkoss.lang.Objects;
022: import org.zkoss.util.media.Media;
023: import org.zkoss.xml.HTMLs;
024:
025: import org.zkoss.zk.ui.Desktop;
026: import org.zkoss.zk.ui.Execution;
027: import org.zkoss.zk.ui.UiException;
028: import org.zkoss.zk.ui.ext.render.DynamicMedia;
029:
030: import org.zkoss.zul.impl.XulElement;
031: import org.zkoss.zul.impl.Utils;
032:
033: /**
034: * An image.
035: *
036: * <p>Note: IE 5.5/6 (not 7) has a bug that failed to render PNG with
037: * alpha transparency. See http://homepage.ntlworld.com/bobosola/index.htm for details.
038: * Thus, if you want to display such image, you have to use the alphafix mold.
039: * <code><image mold="alphafix"/></code>
040: *
041: * @author tomyeh
042: */
043: public class Image extends XulElement {
044: private String _align, _border, _hspace, _vspace;
045: private String _src;
046: /** The image. If not null, _src is generated automatically. */
047: private org.zkoss.image.Image _image;
048: /** Count the version of {@link #_image}. */
049: private int _imgver;
050:
051: public Image() {
052: }
053:
054: public Image(String src) {
055: setSrc(src);
056: }
057:
058: /** Returns the alignment.
059: * <p>Default: null (use browser default).
060: */
061: public String getAlign() {
062: return _align;
063: }
064:
065: /** Sets the alignment: one of top, texttop, middle, absmiddle,
066: * bottom, absbottom, baseline, left, right and center.
067: */
068: public void setAlign(String align) {
069: if (align != null && align.length() == 0)
070: align = null;
071:
072: if (!Objects.equals(_align, align)) {
073: _align = align;
074: smartUpdate("align", _align);
075: }
076: }
077:
078: /** Returns the width of the border.
079: * <p>Default: null (use browser default).
080: */
081: public String getBorder() {
082: return _border;
083: }
084:
085: /** Sets the width of the border.
086: */
087: public void setBorder(String border) {
088: if (border != null && border.length() == 0)
089: border = null;
090:
091: if (!Objects.equals(_border, border)) {
092: _border = border;
093: smartUpdate("border", _border);
094: }
095: }
096:
097: /** Returns number of pixels of extra space to the left and right
098: * side of the image.
099: * <p>Default: null (use browser default).
100: */
101: public String getHspace() {
102: return _hspace;
103: }
104:
105: /** Sets number of pixels of extra space to the left and right
106: * side of the image.
107: */
108: public void setHspace(String hspace) {
109: if (hspace != null && hspace.length() == 0)
110: hspace = null;
111:
112: if (!Objects.equals(_hspace, hspace)) {
113: _hspace = hspace;
114: smartUpdate("hspace", _hspace);
115: }
116: }
117:
118: /** Returns number of pixels of extra space to the top and bottom
119: * side of the image.
120: * <p>Default: null (use browser default).
121: */
122: public String getVspace() {
123: return _vspace;
124: }
125:
126: /** Sets number of pixels of extra space to the top and bottom
127: * side of the image.
128: */
129: public void setVspace(String vspace) {
130: if (vspace != null && vspace.length() == 0)
131: vspace = null;
132:
133: if (!Objects.equals(_vspace, vspace)) {
134: _vspace = vspace;
135: smartUpdate("vspace", _vspace);
136: }
137: }
138:
139: /** Returns the source URI of the image.
140: * <p>Default: null.
141: */
142: public String getSrc() {
143: return _src;
144: }
145:
146: /** Sets the source URI of the image.
147: *
148: * <p>If {@link #setContent} is ever called with non-null,
149: * it takes heigher priority than this method.
150: *
151: * @param src the URI of the image source
152: */
153: public void setSrc(String src) {
154: if (src != null && src.length() == 0)
155: src = null;
156:
157: if (!Objects.equals(_src, src)) {
158: _src = src;
159: if (_image == null)
160: smartUpdateDeferred("src", new EncodedSrc()); //Bug 1850895
161: //_src is meaningful only if _image is null
162: }
163: }
164:
165: /** Returns the encoded src ({@link #getSrc}).
166: */
167: private String getEncodedSrc() {
168: final Desktop dt = getDesktop(); //it might not belong to any desktop
169: return _image != null ? getContentSrc() : //already encoded
170: dt != null ? dt.getExecution().encodeURL(
171: _src != null ? _src : "~./img/spacer.gif") : "";
172: }
173:
174: /** Sets the content directly.
175: * Default: null.
176: *
177: * @param image the image to display. If not null, it has higher
178: * priority than {@link #getSrc}.
179: */
180: public void setContent(org.zkoss.image.Image image) {
181: if (image != _image) {
182: _image = image;
183: if (_image != null)
184: ++_imgver; //enforce browser to reload image
185: smartUpdateDeferred("src", new EncodedSrc()); //Bug 1850895
186: }
187: }
188:
189: /** Returns the content set by {@link #setContent}.
190: * <p>Note: it won't fetch what is set thru by {@link #setSrc}.
191: * It simply returns what is passed to {@link #setContent}.
192: */
193: public org.zkoss.image.Image getContent() {
194: return _image;
195: }
196:
197: /** Returns the encoded URL for the current image content.
198: * Don't call this method unless _image is not null;
199: *
200: * <p>Used only for component template, not for application developers.
201: */
202: private String getContentSrc() {
203: return Utils.getDynamicMediaURI(this , _imgver,
204: _image.getName(), _image.getFormat());
205: }
206:
207: //-- super --//
208: public String getOuterAttrs() {
209: final String attrs = super .getOuterAttrs();
210: final String clkattrs = getAllOnClickAttrs(false);
211: if (!alphafix())
212: return clkattrs == null ? attrs : attrs + clkattrs;
213:
214: //Request 1522329
215: final StringBuffer sb = new StringBuffer(64).append(attrs);
216: if (clkattrs != null)
217: sb.append(clkattrs);
218: sb.append(" zk_alpha=\"true\"");
219: return sb.toString();
220: }
221:
222: /** Tests whether to apply Request 1522329.
223: * To limit the side effect, enable it only if mold is alphafix (and IE6).
224: */
225: private boolean alphafix() {
226: if ("alphafix".equals(getMold())) {
227: final Desktop dt = getDesktop();
228: if (dt != null) {
229: final Execution exec = dt.getExecution();
230: return exec != null && exec.isExplorer()
231: && !exec.isExplorer7();
232: }
233: }
234: return false;
235: }
236:
237: public String getInnerAttrs() {
238: final StringBuffer sb = new StringBuffer(64).append(super
239: .getInnerAttrs());
240: HTMLs.appendAttribute(sb, "align", _align);
241: HTMLs.appendAttribute(sb, "border", _border);
242: HTMLs.appendAttribute(sb, "hspace", _hspace);
243: HTMLs.appendAttribute(sb, "vspace", _vspace);
244: HTMLs.appendAttribute(sb, "src", getEncodedSrc());
245: return sb.toString();
246: }
247:
248: //-- Component --//
249: /** Default: not childable.
250: */
251: public boolean isChildable() {
252: return false;
253: }
254:
255: public void smartUpdate(String attr, String value) {
256: //Request 1522329: to simplify the client, we always invalidate if alphafix
257: if (alphafix())
258: invalidate();
259: else
260: super .smartUpdate(attr, value);
261: }
262:
263: //-- ComponentCtrl --//
264: protected Object newExtraCtrl() {
265: return new ExtraCtrl();
266: }
267:
268: /** A utility class to implement {@link #getExtraCtrl}.
269: * It is used only by component developers.
270: */
271: protected class ExtraCtrl extends XulElement.ExtraCtrl implements
272: DynamicMedia {
273: //-- DynamicMedia --//
274: public Media getMedia(String pathInfo) {
275: return _image;
276: }
277: }
278:
279: private class EncodedSrc implements
280: org.zkoss.zk.ui.util.DeferredValue {
281: public String getValue() {
282: return getEncodedSrc();
283: }
284: }
285: }
|