1 include(bbq.gui.GUIWidget);
  2 include(bbq.util.BBQUtil);
  3 
  4 bbq.gui.button.GUIButton = Class.create(bbq.gui.GUIWidget, /** @lends bbq.gui.button.GUIButton.prototype */ {
  5 	_disabled: false,
  6 	_down: false,
  7 	_mouseDownOverButton: false,
  8 
  9 	/*
 10 	 * event onClick
 11 	 * event onMouseOut
 12 	 * event onMouseOver
 13 	 * event onMouseDown
 14 	 * event onMouseUp
 15 	 * event onButtonDown
 16 	 * event onButtonUp
 17 	 */
 18 	/**
 19 	 * This class creates a link which can be used to receive onclick events.
 20 	 *
 21 	 * @constructs
 22 	 * @extends bbq.gui.GUIWidget
 23 	 * @example
 24 	 * <pre><code class="language-javascript">
 25 	 * var button = new bbq.gui.button.GUIButton({
 26 	 *     text: "Click me",
 27 	 *     onClick: function() {
 28 	 *         Log.info("The button was clicked!");
 29 	 *     }
 30 	 * });
 31 	 * </code></pre>
 32 	 * @param {Object} options
 33 	 * @param {String} options.text This text will be displayed on the button.
 34 	 * @param {String} [options.toolTip] Will be displayed as a tooltip when the user hovers their mouse over the button.
 35 	 * @param {String} [options.anchor] The anchor will be set as the href value of the root node.
 36 	 * @param {boolean} [options.startDisabled] If true the button will not respond to clicks.
 37 	 * @param {boolean} [options.startDown] If true the button will start in the down state.
 38 	 * @param {boolean} [options.rememberDownState] If true the button will toggle on and off.
 39 	 * @param {Function} [options.onClick] Will be invoked when onclick events occur.
 40 	 * @param {Function} [options.onMouseOut] Will be invoked when onmouseout events occur.
 41 	 * @param {Function} [options.onMouseOver] Will be invoked when onmouseover events occur.
 42 	 * @param {Function} [options.onMouseDown] Will be invoked when onmousedown events occur.
 43 	 * @param {Function} [options.onMouseUp] Will be invoked when onmouseup events occur.
 44 	 * @param {Function} [options.onButtonDown] Will be invoked when the button enters the down state.
 45 	 * @param {Function} [options.onButtonUp] Will be invoked when the button enters the up state.
 46 	 */
 47 	initialize: function($super, options) {
 48 		$super(options);
 49 
 50 		this._setUpRootNode();
 51 
 52 		this.addClass("GUIButton");
 53 		this.setDisabled(this.options.startDisabled);
 54 		this.setDown(this.options.startDown);
 55 		this.getRootNode().onclick = this.buttonClicked.bindAsEventListener(this);
 56 		this.getRootNode().onmouseout = this.mouseOut.bindAsEventListener(this);
 57 		this.getRootNode().onmouseover = this.mouseOver.bindAsEventListener(this);
 58 		this.getRootNode().onmousedown = this.mouseDown.bindAsEventListener(this);
 59 		this.getRootNode().onmouseup = this.mouseUp.bindAsEventListener(this);
 60 
 61 		if(this.options.onClick) {
 62 			this.registerListener("onClick", this.options.onClick);
 63 		}
 64 
 65 		if (this.options.onMouseOut) {
 66 			this.registerListener("onMouseOut", this.options.onMouseOut);
 67 		}
 68 
 69 		if (this.options.onMouseOver) {
 70 			this.registerListener("onMouseOver", this.options.onMouseOver);
 71 		}
 72 
 73 		if (this.options.onMouseDown) {
 74 			this.registerListener("onMouseDown", this.options.onMouseDown);
 75 		}
 76 
 77 		if (this.options.onMouseUp) {
 78 			this.registerListener("onMouseUp", this.options.onMouseUp);
 79 		}
 80 
 81 		if (this.options.onButtonDown) {
 82 			this.registerListener("onButtonDown", this.options.onButtonDown);
 83 		}
 84 
 85 		if (this.options.onButtonUp) {
 86 			this.registerListener("onButtonUp", this.options.onButtonUp);
 87 		}
 88 	},
 89 
 90 	_setUpRootNode: function() {
 91 		this.setRootNode("a");
 92 
 93 		if (this.options.text) {
 94 			this.appendChild(this.options.text);
 95 		}
 96 
 97 		if (this.options.toolTip) {
 98 			this.setAttribute("title", this.options.toolTip);
 99 		}
100 
101 		if (this.options.anchor) {
102 			this.setAttribute("href", this.options.anchor);
103 		} else {
104 			this.setAttribute("href", ".");
105 		}
106 	},
107 
108 	/**
109 	 * Button clicked handler function
110 	 *
111 	 * @param {Event} event
112 	 */
113 	buttonClicked: function(event) {
114 		if(event) {
115 			if(this.options.onClick) {
116 				Event.stop(event);
117 			}
118 
119 			BBQUtil.clearFocus(event);
120 		}
121 
122 		if(this._disabled || this._down) {
123 			return false;
124 		}
125 
126 		if(this.options.rememberDownState) {
127 			this.setDown(true);
128 		}
129 
130 		this.notifyListeners("onClick");
131 
132 		// should we let the link take us to another page?
133 		if(this.options.anchor) {
134 			return true;
135 		}
136 
137 		return false;
138 	},
139 
140 	/**
141 	 * Mouse out handler function
142 	 *
143 	 * @param {Event} event
144 	 */
145 	mouseOut: function(event) {
146 		if(this._disabled) {
147 			return false;
148 		}
149 
150 		this.removeClass("buttonOver");
151 		this.notifyListeners("onMouseOut");
152 
153 		// mouse button was clicked, but user dragged out of button before releasing
154 		if(this._mouseDownOverButton) {
155 			this.removeClass("buttonDown");
156 		}
157 	},
158 
159 	/**
160 	 * Mouse over handler function
161 	 *
162 	 * @param {Event} event
163 	 */
164 	mouseOver: function(event) {
165 		if(this._disabled) {
166 			return false;
167 		}
168 
169 		this.addClass("buttonOver");
170 		this.notifyListeners("onMouseOver");
171 	},
172 
173 	/**
174 	 * Mouse down handler function
175 	 *
176 	 * @param {Event} event
177 	 */
178 	mouseDown: function(event) {
179 		if(this._disabled || this._down) {
180 			return false;
181 		}
182 
183 		if(!this.options.rememberDownState) {
184 			this.addClass("buttonDown");
185 		}
186 
187 		this._mouseDownOverButton = true;
188 
189 		this.notifyListeners("onMouseDown");
190 	},
191 
192 	/**
193 	 * Mouse up handler function
194 	 *
195 	 * @param {Event} event
196 	 */
197 	mouseUp: function(event) {
198 		if(this._disabled || this._down) {
199 			return false;
200 		}
201 
202 		this._mouseDownOverButton = false;
203 
204 		this.removeClass("buttonDown");
205 		this.notifyListeners("onMouseUp");
206 	},
207 
208 	/**
209 	 * Down state setter
210 	 *
211 	 * @param {boolean} down
212 	 */
213 	setDown: function(down) {
214 		if(this._down == down) {
215 			return;
216 		}
217 
218 		this._down = down;
219 		this[(this._down ? "add" : "remove") + "Class"]("buttonDown");
220 		this.notifyListener("onButton" + (this._down ? "Down" : "Up"));
221 	},
222 
223 	/**
224 	 * Clears button down state.
225 	 */
226 	clearDown: function() {
227 		this._down = false;
228 		this.removeClass("buttonDown");
229 	},
230 
231 	/**
232 	 * Checks if button is down.
233 	 *
234 	 * @return {boolean}
235 	 */
236 	isDown: function() {
237 		return this._down;
238 	},
239 
240 	/**
241 	 * Button disabled status setter.
242 	 *
243 	 * @param {boolean} disabled
244 	 */
245 	setDisabled: function(disabled) {
246 		this._disabled = disabled;
247 		this[(this._disabled ? "add" : "remove") + "Class"]("buttonDisabled");
248 		this[(this._disabled ? "remove" : "add") + "Class"]("buttonEnabled");
249 	},
250 
251 	/**
252 	 * @returns {boolean} True if the button is in the disabled state.
253 	 */
254 	isDisabled: function() {
255 		return this._disabled;
256 	},
257 
258 	/**
259 	 * Sets the text displayed on the button.
260 	 *
261 	 * @param {String} text
262 	 */
263 	setText: function(text) {
264 		this.empty();
265 		this.appendChild(text);
266 	}
267 });
268