001: /* Groupbox.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Fri Jul 29 16:55:24 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2005 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:
023: import org.zkoss.zk.ui.Component;
024: import org.zkoss.zk.ui.UiException;
025: import org.zkoss.zk.ui.event.Events;
026: import org.zkoss.zk.ui.ext.render.MultiBranch;
027: import org.zkoss.zk.ui.ext.client.Openable;
028: import org.zkoss.zul.impl.XulElement;
029:
030: /**
031: * Groups a set of child elements to have a visual effect.
032: *
033: * <p>To customize the visual style of the caption,
034: * refer to {@link #getCaptionLook}.
035: *
036: * @author tomyeh
037: */
038: public class Groupbox extends XulElement {
039: private Caption _caption;
040: /** The style used for the content block. */
041: private String _cntStyle;
042: /** The style class used for the content block. */
043: private String _cntscls;
044: private Boolean _legend;
045: private boolean _open = true, _closable = true;
046:
047: /** Returns the caption of this groupbox.
048: */
049: public Caption getCaption() {
050: return _caption;
051: }
052:
053: /** Returns whether this groupbox is open.
054: *
055: * <p>Note: the default mold ({@link #getMold}) doesn't support
056: * the open attribute.
057: *
058: * <p>Default: true.
059: */
060: public boolean isOpen() {
061: return _open;
062: }
063:
064: /** Opens or closes this groupbox.
065: */
066: public void setOpen(boolean open) {
067: if (_open != open) {
068: _open = open;
069: smartUpdate("z.open", _open);
070: }
071: }
072:
073: /** Returns whether user can open or close the group box.
074: * In other words, if false, users are no longer allowed to
075: * change the open status (by clicking on the title).
076: *
077: * <p>Default: true.
078: */
079: public boolean isClosable() {
080: return _closable;
081: }
082:
083: /** Sets whether user can open or close the group box.
084: */
085: public void setClosable(boolean closable) {
086: if (_closable != closable) {
087: _closable = closable;
088: smartUpdate("z.closable", closable);
089: }
090: }
091:
092: /** Returns the CSS style for the content block of the groupbox.
093: * Used only if {@link #getMold} is not default.
094: */
095: public String getContentStyle() {
096: return _cntStyle;
097: }
098:
099: /** Sets the CSS style for the content block of the groupbox.
100: * Used only if {@link #getMold} is not default.
101: *
102: * <p>Default: null.
103: */
104: public void setContentStyle(String style) {
105: if (!Objects.equals(_cntStyle, style)) {
106: _cntStyle = style;
107: smartUpdate("z.cntStyle", _cntStyle);
108: }
109: }
110:
111: /** Returns the style class used for the content block of the groupbox.
112: * Used only if {@link #getMold} is not default.
113: *
114: * <ul>
115: * <li>If {@link #setContentSclass} is called with non-null string,
116: * this method returns it.</li>
117: * <li>If {@link #getSclass} is null, "gc-default" is returned,</li>
118: * <li>Otherwise, "gc-<i>sclass</i>",
119: * where <i>sclass</i> is the value returned by {@link #getSclass}.</li>
120: * </ul>
121: */
122: public String getContentSclass() {
123: String cntscls = _cntscls;
124: if (cntscls != null)
125: return cntscls;
126:
127: cntscls = getSclass();
128: return cntscls == null ? "gc-default" : "gc-" + cntscls;
129: }
130:
131: /** Sets the style class used for the content block.
132: *
133: * @see #getContentSclass
134: * @since 3.0.0
135: */
136: public void setContentSclass(String scls) {
137: if (!Objects.equals(_cntscls, scls)) {
138: _cntscls = scls;
139: smartUpdate("z.cntScls", getContentSclass());
140: }
141: }
142:
143: /** Returns whether this groupbox is in the legend mold.
144: * By the legend mold we mean this group box is rendered with
145: * HTML FIELDSET tag.
146: *
147: * <p>Default: the legend mold is assumed if {@link #getMold}
148: * returns "default".
149: *
150: * <p>If it is not the case, you can call {@link #setLegend} to change
151: * it.
152: * @since 3.0.0
153: */
154: public boolean isLegend() {
155: return _legend != null ? _legend.booleanValue() : "default"
156: .equals(getMold());
157: }
158:
159: /** Sets whether this groupbox is in the legend mold.
160: * @see #isLegend
161: * @since 3.0.0
162: */
163: public void setLegend(boolean legend) {
164: _legend = Boolean.valueOf(legend);
165: }
166:
167: /** Returns the look of the caption.
168: * It is, in fact, a portion of the style class that are used
169: * to generate the style for the caption.
170: *
171: * <p>If the style class ({@link #getSclass}) of this groupbox is not
172: * defined and the mold is "default", then "groupbox" is returned.
173: *
174: * <p>If the mold is "default" or "3d", and the style class is defined,
175: * say "lite", then this method return "groupbox-lite".
176: *
177: * <p>If the mold is not "default", and the style class is not defined,
178: * this method returns:<br>
179: * <code>"groupbox-" + getMold()</code>
180: *
181: * <p>If the mold is not "default" and the style class is defined,
182: * this method returns<br/>
183: * <code>"groupbox-" + getMold() + "-" + getSclass()</code>
184: *
185: * <p>With this method, the caption generates the style class
186: * for the caption accordingly. For example, if the mold is "3d"
187: * and the style class not defined, then
188: * "groupbox-3d-tl" for the top-left corner of the caption,
189: * "groupbox-3d-tm" for the top-middle border, and so on.
190: *
191: * <p>Note: currenlty only the 3d mold supports this feature.
192: * In other words, the default mold ignores this method.
193: * @since 3.0,0
194: */
195: public String getCaptionLook() {
196: final String mold = getMold();
197: final String scls = getSclass();
198: final boolean noScls = scls == null || scls.length() == 0;
199: String val = "groupbox";
200: if (!"default".equals(mold) && (!"3d".equals(mold) || noScls))
201: val += '-' + mold;
202: return noScls ? val : val + '-' + scls;
203: }
204:
205: //-- super --//
206: public String getOuterAttrs() {
207: final StringBuffer sb = new StringBuffer(64).append(super
208: .getOuterAttrs());
209:
210: appendAsapAttr(sb, Events.ON_OPEN);
211: final String clkattrs = getAllOnClickAttrs(false);
212: if (clkattrs != null)
213: sb.append(clkattrs);
214: //though widget.js handles onclick (if 3d), it is useful
215: //to support onClick for groupbox
216:
217: if (!_closable)
218: sb.append(" z.closable=\"false\"");
219: return sb.toString();
220: }
221:
222: //-- Component --//
223: public boolean insertBefore(Component child, Component insertBefore) {
224: if (child instanceof Caption) {
225: if (_caption != null && _caption != child)
226: throw new UiException("Only one caption is allowed: "
227: + this );
228: insertBefore = getFirstChild();
229: //always makes caption as the first child
230: _caption = (Caption) child;
231: invalidate();
232: } else if (insertBefore instanceof Caption) {
233: throw new UiException("caption must be the first child");
234: }
235: return super .insertBefore(child, insertBefore);
236: }
237:
238: public void onChildRemoved(Component child) {
239: if (child instanceof Caption) {
240: _caption = null;
241: invalidate();
242: }
243: super .onChildRemoved(child);
244: }
245:
246: //-- ComponentCtrl --//
247: protected Object newExtraCtrl() {
248: return new ExtraCtrl();
249: }
250:
251: /** A utility class to implement {@link #getExtraCtrl}.
252: * It is used only by component developers.
253: */
254: protected class ExtraCtrl extends XulElement.ExtraCtrl implements
255: MultiBranch, Openable {
256: //-- MultiBranch --//
257: public boolean inDifferentBranch(Component child) {
258: return child instanceof Caption; //in different branch
259: }
260:
261: //-- Openable --//
262: public void setOpenByClient(boolean open) {
263: _open = open;
264: }
265: }
266: }
|