001: /* Layoutregion.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Aug 27, 2007 3:30:53 PM , Created by jumperchen
010: }}IS_NOTE
011:
012: Copyright (C) 2007 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.zkex.zul;
020:
021: import org.zkoss.lang.Objects;
022: import org.zkoss.xml.HTMLs;
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.client.Openable;
027: import org.zkoss.zul.impl.XulElement;
028: import org.zkoss.zul.impl.Utils;
029:
030: /**
031: * This class represents a region in a layout manager.
032: * <p>
033: * Events:<br/> onOpen, onSize.<br/>
034: *
035: * The default class of CSS is specified "layout-region" and
036: * "layout-region-normal". If the border specifies "none" or null or "0", the
037: * "layout-region-normal" class will remove.
038: *
039: * @author jumperchen
040: * @since 3.0.0
041: */
042: public abstract class LayoutRegion extends XulElement {
043:
044: private boolean _flex;
045:
046: private boolean _splittable;
047:
048: private boolean _collapsible;
049:
050: private boolean _open = true;
051:
052: private boolean _autoscroll;
053:
054: private String _border = "normal";
055:
056: private int _maxsize = 2000;
057:
058: private int _minsize = 0;
059:
060: private int[] _margins = new int[] { 0, 0, 0, 0 };
061:
062: public LayoutRegion() {
063: addSclass("layout-region");
064: addSclass("layout-region-normal");
065: }
066:
067: /**
068: * Returns the border.
069: * <p>
070: * The border actually controls what CSS class to use: If border is null, it
071: * implies "none".
072: *
073: * <p>
074: * If you also specify the CSS class ({@link #setClass}), it overwrites
075: * whatever border you specify here.
076: *
077: * <p>
078: * Default: "normal".
079: */
080: public String getBorder() {
081: return _border;
082: }
083:
084: /**
085: * Sets the border (either none or normal).
086: *
087: * @param border
088: * the border. If null or "0", "none" is assumed.
089: */
090: public void setBorder(String border) {
091: if (border == null || "0".equals(border))
092: border = "none";
093: if (!_border.equals(border)) {
094: _border = border;
095: if (_border.equals("none")) {
096: removeSclass("layout-region-normal");
097: } else {
098: addSclass("layout-region-normal");
099: }
100: }
101: }
102:
103: /**
104: * Returns whether enable the split functionality.
105: * <p>
106: * Default: false.
107: */
108: public boolean isSplittable() {
109: return _splittable;
110: }
111:
112: /**
113: * Sets whether enable the split functionality.
114: */
115: public void setSplittable(boolean splittable) {
116: if (_splittable != splittable) {
117: _splittable = splittable;
118: smartUpdate("z.splt", _splittable);
119: }
120: }
121:
122: /**
123: * Sets the maximum size of the resizing element.
124: */
125: public void setMaxsize(int maxsize) {
126: if (_maxsize != maxsize) {
127: _maxsize = maxsize;
128: smartUpdate("z.maxs", _maxsize);
129: }
130: }
131:
132: /**
133: * Returns the maximum size of the resizing element.
134: * <p>
135: * Default: 2000.
136: */
137: public int getMaxsize() {
138: return _maxsize;
139: }
140:
141: /**
142: * Sets the minimum size of the resizing element.
143: */
144: public void setMinsize(int minsize) {
145: if (_minsize != minsize) {
146: _minsize = minsize;
147: smartUpdate("z.mins", _minsize);
148: }
149: }
150:
151: /**
152: * Returns the minimum size of the resizing element.
153: * <p>
154: * Default: 0.
155: */
156: public int getMinsize() {
157: return _minsize;
158: }
159:
160: /**
161: * Returns whether to grow and shrink vertical/horizontal to fit their given
162: * space, so called flexibility.
163: *
164: * <p>
165: * Default: false.
166: */
167: public final boolean isFlex() {
168: return _flex;
169: }
170:
171: /**
172: * Sets whether to grow and shrink vertical/horizontal to fit their given
173: * space, so called flexibility.
174: *
175: */
176: public void setFlex(boolean flex) {
177: if (_flex != flex) {
178: _flex = flex;
179: invalidate();
180: }
181: }
182:
183: /**
184: * Returns the margins, which is a list of numbers separated by comma.
185: *
186: * <p>
187: * Default: "0,0,0,0".
188: */
189: public String getMargins() {
190: return Utils.intsToString(_margins);
191: }
192:
193: /**
194: * Sets margins for the element "0,1,2,3" that direction is
195: * "top,left,right,bottom"
196: */
197: public void setMargins(String margins) {
198: final int[] imargins = Utils.stringToInts(margins, 0);
199: if (!Objects.equals(imargins, _margins)) {
200: _margins = imargins;
201: smartUpdate("z.mars", Utils.intsToString(_margins));
202: }
203: }
204:
205: /**
206: * Returns whether set the initial display to collapse.
207: * <p>
208: * Default: false.
209: */
210: public boolean isCollapsible() {
211: return _collapsible;
212: }
213:
214: /**
215: * Sets whether set the initial display to collapse.
216: */
217: public void setCollapsible(boolean collapsible) {
218: if (collapsible != _collapsible) {
219: _collapsible = collapsible;
220: smartUpdate("z.colps", _collapsible);
221: }
222: }
223:
224: /**
225: * Returns whether enable overflow scrolling.
226: * <p>
227: * Default: false.
228: */
229: public boolean isAutoscroll() {
230: return _autoscroll;
231: }
232:
233: /**
234: * Sets whether enable overflow scrolling.
235: */
236: public void setAutoscroll(boolean autoscroll) {
237: if (_autoscroll != autoscroll) {
238: _autoscroll = autoscroll;
239: smartUpdate("z.autoscl", _autoscroll);
240: }
241: }
242:
243: /**
244: * Returns whether it is opne (i.e., not collapsed. Meaningful only if
245: * {@link #isCollapsible} is not false.
246: * <p>
247: * Default: true.
248: */
249: public boolean isOpen() {
250: return _open;
251: }
252:
253: /**
254: * Opens or collapses the splitter. Meaningful only if
255: * {@link #isCollapsible} is not false.
256: */
257: public void setOpen(boolean open) {
258: if (_open != open) {
259: _open = open;
260: smartUpdate("z.open", open);
261: }
262: }
263:
264: /**
265: * Returns this regions position (north/south/east/west/center).
266: *
267: * @see Borderlayout#NORTH
268: * @see Borderlayout#SOUTH
269: * @see Borderlayout#EAST
270: * @see Borderlayout#WEST
271: * @see Borderlayout#CENTER
272: */
273: abstract public String getPosition();
274:
275: /**
276: * Sets the size of this region. This method is shortcut for
277: * {@link #setHeight(String)} and {@link #setWidth(String)}. If this region
278: * is {@link North} or {@link South}, this method will invoke
279: * {@link #setHeight(String)}. If this region is {@link West} or
280: * {@link East}, this method will invoke {@link #setWidth(String)}.
281: * Otherwise it will throw a {@link UnsupportedOperationException}.
282: */
283: abstract public void setSize(String size);
284:
285: /**
286: * Returns the size of this region. This method is shortcut for
287: * {@link #getHeight()} and {@link #getWidth()}. If this region is
288: * {@link North} or {@link South}, this method will invoke
289: * {@link #getHeight()}. If this region is {@link West} or {@link East},
290: * this method will invoke {@link #getWidth()}. Otherwise it will throw a
291: * {@link UnsupportedOperationException}.
292: */
293: abstract public String getSize();
294:
295: protected void addSclass(String cls) {
296: final String sclass = getSclass();
297: if (!hasSclass(cls))
298: setSclass(sclass == null ? cls : sclass + " " + cls);
299: }
300:
301: protected boolean hasSclass(String cls) {
302: String sclass = getSclass();
303: if (sclass == null)
304: sclass = "";
305: return cls == null
306: || ((" " + sclass + " ").indexOf(" " + cls + " ") > -1);
307: }
308:
309: protected void removeSclass(String cls) {
310: final String sclass = getSclass();
311: if (sclass != null && cls != null && hasSclass(cls)) {
312: setSclass(sclass.replaceAll("(?:^|\\s+)" + cls
313: + "(?:\\s+|$)", " "));
314: }
315: }
316:
317: public void onChildRemoved(Component child) {
318: smartUpdate("z.cid", "zk_n_a");
319: if (child instanceof Borderlayout) {
320: setFlex(false);
321: removeSclass("layout-nested");
322: }
323: }
324:
325: public boolean insertBefore(Component child, Component insertBefore) {
326: if (getChildren().size() > 0)
327: throw new UiException("Only one child is allowed: " + this );
328: if (super .insertBefore(child, insertBefore)) {
329: smartUpdate("z.cid", child.getUuid());
330: if (child instanceof Borderlayout) {
331: setFlex(true);
332: addSclass("layout-nested");
333: }
334: return true;
335: }
336: return false;
337: }
338:
339: public String getOuterAttrs() {
340: final StringBuffer sb = new StringBuffer(80).append(super
341: .getOuterAttrs());
342: appendAsapAttr(sb, Events.ON_OPEN);
343: appendAsapAttr(sb, Events.ON_SIZE);
344: HTMLs.appendAttribute(sb, "z.cid",
345: getChildren().isEmpty() ? "zk_n_a"
346: : ((Component) getChildren().get(0)).getUuid());
347: HTMLs.appendAttribute(sb, "z.pos", getPosition());
348: HTMLs.appendAttribute(sb, "z.flex", isFlex());
349: HTMLs.appendAttribute(sb, "z.mars", getMargins());
350: HTMLs.appendAttribute(sb, "z.colps", isCollapsible());
351: HTMLs.appendAttribute(sb, "z.open", isOpen());
352: HTMLs.appendAttribute(sb, "z.splt", isSplittable());
353: HTMLs.appendAttribute(sb, "z.maxs", getMaxsize());
354: HTMLs.appendAttribute(sb, "z.mins", getMinsize());
355: HTMLs.appendAttribute(sb, "z.autoscl", isAutoscroll());
356: return sb.toString();
357: }
358:
359: //-- ComponentCtrl --//
360: protected Object newExtraCtrl() {
361: return new ExtraCtrl();
362: }
363:
364: /** A utility class to implement {@link #getExtraCtrl}.
365: * It is used only by component developers.
366: */
367: protected class ExtraCtrl extends XulElement.ExtraCtrl implements
368: Openable {
369: //-- Openable --//
370: public void setOpenByClient(boolean open) {
371: _open = open;
372: }
373: }
374: }
|