View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2007 utgenome.org
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of 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,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *--------------------------------------------------------------------------*/
16  //--------------------------------------
17  // GenomeBrowser Project
18  //
19  // Window.java
20  // Since: Jun 27, 2007
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.utgb.client.ui;
26  
27  import java.util.ArrayList;
28  import java.util.Iterator;
29  
30  import org.utgenome.gwt.utgb.client.track.Design;
31  import org.utgenome.gwt.widget.client.Style;
32  
33  import com.google.gwt.event.dom.client.ClickEvent;
34  import com.google.gwt.event.dom.client.ClickHandler;
35  import com.google.gwt.event.dom.client.MouseDownEvent;
36  import com.google.gwt.event.dom.client.MouseDownHandler;
37  import com.google.gwt.event.dom.client.MouseMoveEvent;
38  import com.google.gwt.event.dom.client.MouseMoveHandler;
39  import com.google.gwt.event.dom.client.MouseOutEvent;
40  import com.google.gwt.event.dom.client.MouseOutHandler;
41  import com.google.gwt.event.dom.client.MouseOverEvent;
42  import com.google.gwt.event.dom.client.MouseOverHandler;
43  import com.google.gwt.event.dom.client.MouseUpEvent;
44  import com.google.gwt.event.dom.client.MouseUpHandler;
45  import com.google.gwt.user.client.DOM;
46  import com.google.gwt.user.client.ui.Composite;
47  import com.google.gwt.user.client.ui.FocusPanel;
48  import com.google.gwt.user.client.ui.Grid;
49  import com.google.gwt.user.client.ui.Label;
50  import com.google.gwt.user.client.ui.PopupPanel;
51  import com.google.gwt.user.client.ui.VerticalPanel;
52  import com.google.gwt.user.client.ui.Widget;
53  import com.google.gwt.user.client.ui.HTMLTable.ColumnFormatter;
54  
55  public class WindowBox extends PopupPanel implements SourcesWindowEvents {
56  	public static int BUTTON_CONFIG = 1;
57  	public static int BUTTON_PACK = 1 << 1;
58  	public static int BUTTON_MINIMIZE = 1 << 2;
59  	public static int BUTTON_CLOSE = 1 << 3;
60  	// listener
61  	private ArrayList<WindowListener> _listenerList = new ArrayList<WindowListener>();
62  	// widgets
63  	private final Widget _content;
64  	private final WindowImpl _windowImpl;
65  
66  	public WindowBox(Widget content) {
67  		super();
68  		this._content = content;
69  		this.setStyleName("window");
70  		_windowImpl = new WindowImpl(this);
71  		this.setWidget(_windowImpl);
72  	}
73  
74  	public Widget getContent() {
75  		return _content;
76  	}
77  
78  	public void setWindowTitle(String title) {
79  		_windowImpl.getNavigationBar().setWindowTitle(title);
80  	}
81  
82  	public void addWindowListener(WindowListener listener) {
83  		_listenerList.add(listener);
84  	}
85  
86  	public void removeWindowListener(WindowListener listener) {
87  		_listenerList.remove(listener);
88  	}
89  
90  	ArrayList<WindowListener> getWindowListenerList() {
91  		return _listenerList;
92  	}
93  }
94  
95  /**
96   * 
97   * @author leo
98   * 
99   */
100 class WindowImpl extends Composite {
101 	private final WindowBox _window;
102 	private final RoundCornerFrame _windowFrame;
103 	private final WindowNavigationBar _navigationBar;
104 	private int _currentWindowWidth = -1;
105 	private int _currentWindowHeight = -1;
106 	public static int BORDER_THICKNESS = 4;
107 	private static int SCROLLBAR_THICKNESS = 20;
108 
109 	public WindowImpl(WindowBox window) {
110 		this._window = window;
111 		_navigationBar = new WindowNavigationBar(_window);
112 		this._windowFrame = new RoundCornerFrame("CCCCFF");
113 		this._windowFrame.setPixelSize(200, 300);
114 		// _windowFrame.add(_navigationBar, 0, 0);
115 		// _windowFrame.add(_window.getContent(), 0, 20);
116 		initWidget(_windowFrame);
117 	}
118 
119 	protected void onLoad() {
120 		super.onLoad();
121 		// setWindowSize(_window.getpanel.getOffsetWidth(), panel.getOffsetHeight());
122 	}
123 
124 	public WindowNavigationBar getNavigationBar() {
125 		return _navigationBar;
126 	}
127 
128 	public int getCurrentWindowWidth() {
129 		return _currentWindowWidth;
130 	}
131 
132 	public int getCurrentWindowHeight() {
133 		return _currentWindowHeight;
134 	}
135 
136 	public WindowBox getWindow() {
137 		return _window;
138 	}
139 
140 	/*
141 	 * public void setSize(int width, int height) { setWindowSize(width - BORDER_THICKNESS, height -
142 	 * _navigationBar.getOffsetHeight() - BORDER_THICKNESS); }
143 	 */
144 	public void setWindowSize(int width, int height) {
145 		if (width <= 0)
146 			width = 1;
147 		if (height <= 0)
148 			height = 1;
149 		if (_currentWindowWidth != width) {
150 			_currentWindowWidth = width;
151 			_navigationBar.setWidth(_currentWindowWidth + "px");
152 		}
153 		if (_currentWindowHeight != height) {
154 			_currentWindowHeight = height;
155 		}
156 	}
157 }
158 
159 class ResizeBar extends FocusPanel implements MouseDownHandler, MouseOverHandler, MouseOutHandler, MouseMoveHandler, MouseUpHandler {
160 	public static final int DIRECTION_H = 1;
161 	public static final int DIRECTION_V = 1 << 1;
162 	private boolean _resizeH = false;
163 	private boolean _resizeV = false;
164 	private final IconImage _iconImage;
165 	private boolean isDragged = false;
166 	private int dragStartX;
167 	private int dragStartY;
168 	private int initialWindowWidth;
169 	private int initialWindowHeight;
170 	private final WindowImpl _windowFrame;
171 
172 	public ResizeBar(WindowImpl windowFrame, final IconImage iconImage, int directionFlag) {
173 		super();
174 		this._windowFrame = windowFrame;
175 		this._iconImage = iconImage;
176 		// Style.backgroundImage(this, iconImage.getImageURL());
177 		// Style.backgroundRepeat(this);
178 		// Style.border(this, 1, Style.BORDER_SOLID, "#CCFFFF");
179 		_resizeH = (directionFlag & DIRECTION_H) != 0;
180 		_resizeV = (directionFlag & DIRECTION_V) != 0;
181 		if (_resizeH) {
182 			Style.cursor(this, Style.CURSOR_RESIZE_E);
183 		}
184 		if (_resizeV) {
185 			Style.cursor(this, Style.CURSOR_RESIZE_N);
186 		}
187 		if (_resizeH || _resizeV) {
188 			addMouseDownHandler(this);
189 			addMouseOverHandler(this);
190 			addMouseMoveHandler(this);
191 			addMouseUpHandler(this);
192 		}
193 	}
194 
195 	public void onMouseDown(MouseDownEvent e) {
196 		isDragged = true;
197 		dragStartX = e.getX() + this.getAbsoluteLeft();
198 		dragStartY = e.getY() + this.getAbsoluteTop();
199 		initialWindowWidth = _windowFrame.getOffsetWidth();
200 		initialWindowHeight = _windowFrame.getOffsetHeight();
201 		DOM.setCapture(this.getElement());
202 	}
203 
204 	public void onMouseOver(MouseOverEvent e) {
205 		Style.backgroundImage(this, _iconImage.getMouseOverImageURL());
206 	}
207 
208 	public void onMouseOut(MouseOutEvent e) {
209 		Style.backgroundImage(this, _iconImage.getImageURL());
210 	}
211 
212 	public void onMouseMove(MouseMoveEvent e) {
213 		if (isDragged) {
214 			int offsetX = this.getAbsoluteLeft() + e.getX() - dragStartX;
215 			int offsetY = this.getAbsoluteTop() + e.getY() - dragStartY;
216 			int newWidth = _resizeH ? initialWindowWidth + offsetX : initialWindowWidth;
217 			int newHeight = _resizeV ? initialWindowHeight + offsetY : initialWindowHeight;
218 			// newHeight = newHeight -
219 			// _windowFrame.getNavigationBar().getOffsetHeight();
220 			// _windowFrame.setWindowSize(newWidth, newHeight);
221 			// _windowFrame.setSize(newWidth, newHeight);
222 		}
223 	}
224 
225 	public void onMouseUp(MouseUpEvent e) {
226 		if (isDragged) {
227 			int newWindowWidth = _windowFrame.getCurrentWindowWidth();
228 			int newWindowHeight = _windowFrame.getCurrentWindowHeight();
229 			for (Iterator<WindowListener> it = _windowFrame.getWindow().getWindowListenerList().iterator(); it.hasNext();) {
230 				WindowListener listener = it.next();
231 				listener.onResizeWindow(_windowFrame.getWindow(), newWindowWidth);
232 			}
233 		}
234 		isDragged = false;
235 		DOM.releaseCapture(this.getElement());
236 	}
237 
238 }
239 
240 class WindowNavigationBar extends Composite {
241 	private int _enabledButttonFlag = WindowBox.BUTTON_CONFIG | WindowBox.BUTTON_PACK | WindowBox.BUTTON_MINIMIZE | WindowBox.BUTTON_CLOSE;
242 	private Grid _iconGrid;
243 	private Label _windowLabel = new Label(" ");
244 	private Icon _configButton = new Icon(Design.getIconImage(Design.ICON_CONFIG));
245 	private Icon _packButton = new Icon(Design.getIconImage(Design.ICON_PACK));
246 	private Icon _minimizeButton = new Icon(Design.getIconImage(Design.ICON_HIDE));
247 	private Icon _closeButton = new Icon(Design.getIconImage(Design.ICON_CLOSE));
248 	// private HashMap _buttonTable = new HashMap();
249 	private ArrayList<WindowListener> _buttonListener;
250 	private WindowBox _window;
251 
252 	public WindowNavigationBar(WindowBox window) {
253 		this._window = window;
254 		this._buttonListener = window.getWindowListenerList();
255 		init();
256 	}
257 
258 	private int numButtonOnTheBar() {
259 		int count = 0;
260 		for (int i = 0; i < 4; i++) {
261 			if ((_enabledButttonFlag & (1 << i)) != 0)
262 				count++;
263 		}
264 		return count;
265 	}
266 
267 	private boolean isEnabled(int buttonType) {
268 		return (_enabledButttonFlag & buttonType) != 0;
269 	}
270 
271 	public void setWindowTitle(String title) {
272 		_windowLabel.setText(title);
273 	}
274 
275 	public void init() {
276 		// prepare button table
277 		int numButton = numButtonOnTheBar();
278 		_iconGrid = new Grid(1, numButton + 1);
279 		_iconGrid.setWidth("100%");
280 		_iconGrid.getRowFormatter().setVerticalAlign(0, VerticalPanel.ALIGN_MIDDLE);
281 		// _iconGrid.setHeight("21px");
282 		Style.borderCollapse(_iconGrid);
283 		_iconGrid.setCellPadding(0);
284 		_iconGrid.setCellSpacing(0);
285 		_iconGrid.setBorderWidth(0);
286 		_iconGrid.setStyleName("window-navbar");
287 		// set the label & icon width
288 		{
289 			ColumnFormatter formatter = _iconGrid.getColumnFormatter();
290 			for (int i = 0; i < numButton; i++) {
291 				formatter.setWidth(i + 1, "14px");
292 			}
293 		}
294 		int x = 0;
295 		_iconGrid.setWidget(0, x++, _windowLabel);
296 		if (isEnabled(WindowBox.BUTTON_CONFIG)) {
297 			_iconGrid.setWidget(0, x++, _configButton);
298 			_configButton.addClickHandler(new IconButtonListner(WindowBox.BUTTON_CONFIG));
299 		}
300 		if (isEnabled(WindowBox.BUTTON_PACK)) {
301 			_iconGrid.setWidget(0, x++, _packButton);
302 			_packButton.addClickHandler(new IconButtonListner(WindowBox.BUTTON_PACK));
303 		}
304 		if (isEnabled(WindowBox.BUTTON_MINIMIZE)) {
305 			_iconGrid.setWidget(0, x++, _minimizeButton);
306 			_minimizeButton.addClickHandler(new IconButtonListner(WindowBox.BUTTON_MINIMIZE));
307 		}
308 		if (isEnabled(WindowBox.BUTTON_CLOSE)) {
309 			_iconGrid.setWidget(0, x++, _closeButton);
310 			_closeButton.addClickHandler(new IconButtonListner(WindowBox.BUTTON_CLOSE));
311 		}
312 		// set CSS style
313 		_windowLabel.setStyleName("window-title");
314 		Style.fullBlock(_windowLabel);
315 		Style.cursor(_windowLabel, Style.CURSOR_MOVE);
316 		Style.overflowHidden(_windowLabel);
317 		// drag & drop mover
318 
319 		new MouseMoveListener(_window).register(_windowLabel);
320 		// layout
321 		initWidget(_iconGrid);
322 	}
323 
324 	class IconButtonListner implements ClickHandler {
325 		private int buttonType;
326 
327 		/**
328 		 * @param buttonType
329 		 */
330 		public IconButtonListner(int buttonType) {
331 			this.buttonType = buttonType;
332 		}
333 
334 		public void onClick(ClickEvent e) {
335 			for (Iterator<WindowListener> it = _buttonListener.iterator(); it.hasNext();) {
336 				WindowListener listener = it.next();
337 				listener.onButtonClick(_window, buttonType);
338 			}
339 		}
340 	}
341 }