View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2008 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  // utgb-widget Project
18  //
19  // Icon.java
20  // Since: Apr 24, 2008
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.widget.client;
26  
27  import com.google.gwt.dom.client.Document;
28  import com.google.gwt.dom.client.NativeEvent;
29  import com.google.gwt.event.dom.client.ClickHandler;
30  import com.google.gwt.user.client.DOM;
31  import com.google.gwt.user.client.Element;
32  import com.google.gwt.user.client.Event;
33  import com.google.gwt.user.client.ui.FocusPanel;
34  import com.google.gwt.user.client.ui.Image;
35  
36  /**
37   * Icon image which flips on mouse over events
38   * 
39   * @author leo
40   * 
41   */
42  public class Icon extends FocusPanel {
43  
44  	private Element currentFace = null;
45  	private Image iconImage;
46  	private Image mouseOverIconImage;
47  
48  	//private ArrayList<ClickHandler> clickListenerList = new ArrayList<ClickHandler>();
49  
50  	// icon state
51  	private boolean isFocusing = false;
52  	private boolean isCapturing = false;
53  	private boolean isHovering = false;
54  
55  	public Icon(Image iconImage, Image mouseOverIconImage) {
56  		this.iconImage = iconImage;
57  		this.mouseOverIconImage = mouseOverIconImage;
58  
59  		Style.cursor(this, Style.CURSOR_POINTER);
60  
61  		updateIconFace(iconImage.getElement());
62  	}
63  
64  	public void setIcon(Icon newIcon) {
65  		this.iconImage = newIcon.getIconImage();
66  		this.mouseOverIconImage = newIcon.getMouseOverIconImage();
67  
68  		updateIconFace(iconImage.getElement());
69  	}
70  
71  	public void setIconImage(Image newIconImage) {
72  		this.iconImage = newIconImage;
73  		this.mouseOverIconImage = newIconImage;
74  
75  		updateIconFace(iconImage.getElement());
76  	}
77  
78  	private void updateIconFace(Element newFace) {
79  		if (currentFace != newFace) {
80  			if (currentFace != null)
81  				DOM.removeChild(getElement(), currentFace);
82  
83  			currentFace = newFace;
84  			DOM.appendChild(getElement(), currentFace);
85  		}
86  	}
87  
88  	public Image getIconImage() {
89  		return iconImage;
90  	}
91  
92  	public Image getMouseOverIconImage() {
93  		return mouseOverIconImage;
94  	}
95  
96  	public void addClickHanlder(ClickHandler listener) {
97  		this.addClickHandler(listener);
98  	}
99  
100 	private void setHovering(boolean hovering) {
101 		this.isHovering = hovering;
102 		updateIconFace(isHovering ? mouseOverIconImage.getElement() : iconImage.getElement());
103 	}
104 
105 	/**
106 	 * Called when the user finishes clicking on this button. The default behavior is to fire the click event to
107 	 * listeners. Subclasses that override {@link #onClickStart()} should override this method to restore the normal
108 	 * widget display.
109 	 */
110 	protected void onClick() {
111 		NativeEvent e = Document.get().createClickEvent(1, 0, 0, 0, 0, false, false, false, false);
112 
113 	}
114 
115 	/**
116 	 * Called when the user aborts a click in progress; for example, by dragging the mouse outside of the button before
117 	 * releasing the mouse button. Subclasses that override {@link #onClickStart()} should override this method to
118 	 * restore the normal widget display.
119 	 */
120 	protected void onClickCancel() {
121 
122 	}
123 
124 	/**
125 	 * Called when the user begins to click on this button. Subclasses may override this method to display the start of
126 	 * the click visually; such subclasses should also override {@link #onClick()} and {@link #onClickCancel()} to
127 	 * restore normal visual state. Each <code>onClickStart</code> will eventually be followed by either
128 	 * <code>onClick</code> or <code>onClickCancel</code>, depending on whether the click is completed.
129 	 */
130 	protected void onClickStart() {
131 
132 	}
133 
134 	@Override
135 	public void onBrowserEvent(Event event) {
136 		// Should not act on button if disabled.
137 
138 		int type = DOM.eventGetType(event);
139 		switch (type) {
140 		case Event.ONMOUSEDOWN:
141 			isFocusing = true;
142 			onClickStart();
143 			// DOM.setCapture(getElement());
144 			isCapturing = true;
145 			// Prevent dragging (on some browsers);
146 			DOM.eventPreventDefault(event);
147 			break;
148 		case Event.ONMOUSEUP:
149 			if (isCapturing) {
150 				isCapturing = false;
151 				// DOM.releaseCapture(getElement());
152 				if (isHovering) {
153 					onClick();
154 				}
155 			}
156 			break;
157 		case Event.ONMOUSEMOVE:
158 			if (isCapturing) {
159 				// Prevent dragging (on other browsers);
160 				DOM.eventPreventDefault(event);
161 			}
162 			break;
163 		case Event.ONMOUSEOUT:
164 			Element to = DOM.eventGetToElement(event);
165 			if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event)) && (to == null || !DOM.isOrHasChild(getElement(), to))) {
166 				if (isCapturing) {
167 					onClickCancel();
168 					// DOM.releaseCapture(getElement());
169 				}
170 			}
171 			setHovering(false);
172 			break;
173 		case Event.ONMOUSEOVER:
174 			if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event))) {
175 				setHovering(true);
176 				if (isCapturing) {
177 					onClickStart();
178 				}
179 			}
180 			break;
181 		case Event.ONCLICK:
182 			// we handle clicks ourselves
183 			return;
184 		case Event.ONBLUR:
185 			if (isFocusing) {
186 				isFocusing = false;
187 				onClickCancel();
188 			}
189 			break;
190 		case Event.ONLOSECAPTURE:
191 			if (isCapturing) {
192 				isCapturing = false;
193 				onClickCancel();
194 			}
195 			break;
196 		case Event.ONERROR:
197 			setHovering(false);
198 			break;
199 		}
200 
201 		super.onBrowserEvent(event);
202 
203 		// Synthesize clicks based on keyboard events AFTER the normal key handling.
204 		char keyCode = (char) DOM.eventGetKeyCode(event);
205 		switch (type) {
206 		case Event.ONKEYDOWN:
207 			if (keyCode == ' ') {
208 				isFocusing = true;
209 				onClickStart();
210 			}
211 			break;
212 		case Event.ONKEYUP:
213 			if (isFocusing && keyCode == ' ') {
214 				isFocusing = false;
215 				onClick();
216 			}
217 			break;
218 		case Event.ONKEYPRESS:
219 			if (keyCode == '\n' || keyCode == '\r') {
220 				onClickStart();
221 				onClick();
222 			}
223 			break;
224 		}
225 	}
226 
227 }