KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > user > client > ui > SplitPanel


1 /*
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.user.client.ui;
17
18 import com.google.gwt.user.client.DOM;
19 import com.google.gwt.user.client.Element;
20 import com.google.gwt.user.client.Event;
21
22 import java.util.Iterator JavaDoc;
23
24 /**
25  * Abstract base class for {@link HorizontalSplitPanel} and
26  * {@link VerticalSplitPanel}.
27  */

28 abstract class SplitPanel extends Panel {
29
30   /**
31    * Adds clipping to an element.
32    *
33    * @param elem the element
34    */

35   static final void addElementClipping(final Element elem) {
36     DOM.setStyleAttribute(elem, "overflow", "hidden");
37   }
38
39   /**
40    * Adds as-needed scrolling to an element.
41    *
42    * @param elem the element
43    */

44   static final void addElementScrolling(final Element elem) {
45     DOM.setStyleAttribute(elem, "overflow", "auto");
46   }
47
48   /**
49    * Adds zero or none css values for padding, margin and border to prevent
50    * stylesheet overrides. Returns the element for convienence to support
51    * builder pattern.
52    *
53    * @param elem the element
54    * @return the element
55    */

56   static final Element preventElementBoxStyles(final Element elem) {
57     DOM.setIntStyleAttribute(elem, "padding", 0);
58     DOM.setIntStyleAttribute(elem, "margin", 0);
59     DOM.setStyleAttribute(elem, "border", "none");
60     return elem;
61   }
62
63   /**
64    * Adds zero size padding to an element.
65    *
66    * @param elem the element.
67    */

68   static final void preventElementPadding(final Element elem) {
69     DOM.setStyleAttribute(elem, "padding", "0");
70   }
71
72   /**
73    * Sets the elements css class name.
74    *
75    * @param elem the element
76    * @param className the class name
77    */

78   static final void setElementClassname(final Element elem,
79       final String JavaDoc className) {
80     DOM.setElementProperty(elem, "className", className);
81   }
82
83   // The enclosed widgets.
84
private final Widget[] widgets = new Widget[2];
85
86   // The elements containing the widgets.
87
private final Element[] elements = new Element[2];
88
89   // The element that acts as the splitter.
90
private final Element splitElem;
91
92   // Indicates whether drag resizing is active.
93
private boolean isResizing = false;
94
95   /**
96    * Initializes the split panel.
97    *
98    * @param mainElem the root element for the split panel
99    * @param splitElem the element that acts as the splitter
100    * @param headElem the element to contain the top or left most widget
101    * @param tailElem the element to contain the bottom or right most widget
102    */

103   SplitPanel(Element mainElem, Element splitElem, Element headElem,
104       Element tailElem) {
105     setElement(mainElem);
106     this.splitElem = splitElem;
107     elements[0] = headElem;
108     elements[1] = tailElem;
109     sinkEvents(Event.MOUSEEVENTS);
110   }
111
112   public void add(Widget w) {
113     if (getWidget(0) == null) {
114       setWidget(0, w);
115     } else if (getWidget(1) == null) {
116       setWidget(1, w);
117     } else {
118       throw new IllegalStateException JavaDoc(
119           "A Splitter can only contain two Widgets.");
120     }
121   }
122
123   /**
124    * Indicates whether the split panel is being resized.
125    *
126    * @return <code>true</code> if the user is dragging the splitter,
127    * <code>false</code> otherwise
128    */

129   public boolean isResizing() {
130     return isResizing;
131   }
132
133   public Iterator JavaDoc iterator() {
134     return WidgetIterators.createWidgetIterator(this, widgets);
135   }
136
137   public void onBrowserEvent(Event event) {
138     switch (DOM.eventGetType(event)) {
139
140       case Event.ONMOUSEDOWN: {
141         Element target = DOM.eventGetTarget(event);
142         if (DOM.isOrHasChild(splitElem, target)) {
143           startResizingFrom(DOM.eventGetClientX(event) - getAbsoluteLeft(),
144               DOM.eventGetClientY(event) - getAbsoluteTop());
145           DOM.eventPreventDefault(event);
146         }
147         break;
148       }
149
150       case Event.ONMOUSEUP: {
151         stopResizing();
152         break;
153       }
154
155       case Event.ONMOUSEMOVE: {
156         if (isResizing()) {
157           onSplitterResize(DOM.eventGetClientX(event) - getAbsoluteLeft(),
158               DOM.eventGetClientY(event) - getAbsoluteTop());
159           DOM.eventPreventDefault(event);
160         }
161         break;
162       }
163     }
164   }
165
166   public boolean remove(Widget widget) {
167     if (widget == null) {
168       throw new IllegalArgumentException JavaDoc("Widget must not be null");
169     }
170
171     if (widgets[0] == widget) {
172       setWidget(0, null);
173       return true;
174     } else if (widgets[1] == widget) {
175       setWidget(1, null);
176       return true;
177     }
178
179     return false;
180   }
181
182   /**
183    * Moves the position of the splitter.
184    *
185    * @param size the new size of the left region in CSS units (e.g. "10px",
186    * "1em")
187    */

188   public abstract void setSplitPosition(String JavaDoc size);
189
190   /**
191    * Gets the content element for the given index.
192    *
193    * @param index the index of the element, only 0 and 1 are valid.
194    * @return the element
195    */

196   protected Element getElement(int index) {
197     return elements[index];
198   }
199
200   /**
201    * Gets the element that is acting as the splitter.
202    *
203    * @return the element
204    */

205   protected Element getSplitElement() {
206     return splitElem;
207   }
208
209   /**
210    * Gets one of the contained widgets.
211    *
212    * @param index the index of the widget, only 0 and 1 are valid.
213    * @return the widget
214    */

215   protected Widget getWidget(int index) {
216     return widgets[index];
217   }
218
219   /**
220    * Sets one of the contained widgets.
221    *
222    * @param index the index, only 0 and 1 are valid
223    * @param w the widget
224    */

225   protected final void setWidget(int index, Widget w) {
226     if (widgets[index] != null) {
227       disown(widgets[index]);
228     }
229
230     widgets[index] = w;
231
232     if (w != null) {
233       adopt(w, elements[index]);
234     }
235   }
236
237   /**
238    * Called on each mouse drag event as the user is dragging the splitter.
239    *
240    * @param x the x coordinate of the mouse relative to the panel's extent
241    * @param y the y coordinate of the mosue relative to the panel's extent
242    */

243   abstract void onSplitterResize(int x, int y);
244
245   /**
246    * Called when the user starts dragging the splitter.
247    *
248    * @param x the x coordinate of the mouse relative to the panel's extent
249    * @param y the y coordinate of the mouse relative to the panel's extent
250    */

251   abstract void onSplitterResizeStarted(int x, int y);
252
253   private void startResizingFrom(int x, int y) {
254     isResizing = true;
255     onSplitterResizeStarted(x, y);
256   }
257
258   private void stopResizing() {
259     isResizing = false;
260   }
261 }
262
Popular Tags