1 /*
  2 * A pushbutton widget that issues a signal when clicked.
  3 * @param {String} label The text to be displayed by the button label or None if no label is required
  4 * @param {String} stock The stock id identifying the stock image and text to be used in the button or None if no stock id is to be used
  5 */
  6 gtk.Button = function(label, stock){
  7 	gtk.Widget.apply(this);
  8 	
  9 	var self 			= this;
 10 	this._stock 		= stock || "";
 11 	this._label 		= label || "";
 12 	this._widget1 		= null;
 13 	this._widget2 		= null;
 14 	this._isEnable 		= true;
 15 	this._signalClicked = null;
 16 	
 17 	this._width 		= this._minWidth = 16;
 18 	this._height 		= this._minHeight = 16;
 19 	
 20 	/** @private */		
 21 	this._render = function(){
 22 
 23 	    this._domObj.className += " gtk_button";
 24 	    var domObjStyle = this._domObj.style;
 25 	    domObjStyle.position = "relative";
 26 	    var jsgtkDom = jsgtk.Dom;
 27 	        this._gradient = jsgtkDom.create({"append": this._domObj, "tag": "div", "class": "gtk_button_gradient"});
 28 	        this._gradient.style.height = this._height / 2 + "px";
 29 		    this._imageDom = jsgtkDom.create({"tag": "div", "style": "float: left; position: relative;"});
 30 		    this._labelDom = jsgtkDom.create({"tag": "div", "style": "float: left; position: relative;"});
 31 
 32 		domObjStyle.width = this._width - this.borderWidth + "px";
 33 		domObjStyle.height = this._height - this.borderWidth + "px";
 34 		if(label) this.setLabel(new gtk.Label(label));
 35 	};
 36     this._render();
 37     this._initEvent();
 38 };
 39 
 40 gtk.Button.prototype = new gtk.Widget();
 41 gtk.Button.prototype.constructor = gtk.Button;
 42 
 43 /** @private */
 44 gtk.Button.prototype._initEvent = function(){
 45     var self = this;
 46     var jsgtkEvent = jsgtk.Event;
 47     this._signalClicked = jsgtkEvent.addDomListener(this._domObj, "click", function(e){
 48 		if(self._isEnable === true) self.emit("clicked");
 49 	}, false);
 50 	
 51     jsgtkEvent.addDomListener(this._domObj, "keyup", function(e){
 52 	    if(e.keyCode == gtk.ENTER_KEY){
 53 	        if(self._isEnable === true) self.emit("enterkeypressed");
 54 	    }
 55 	}, false);
 56 
 57 	jsgtkEvent.addDomListener(this._domObj, "mouseover", function(e){
 58 		self.emit("mouseover");
 59 	}, false);
 60 	
 61 	jsgtkEvent.addDomListener(this._domObj, "mouseout", function(e){
 62 		self.emit("mouseout");
 63 	}, false);
 64 };
 65 
 66 /** @private */
 67 gtk.Button.prototype._positionWidget = function(widget, widgetDom){
 68     var top = (this._height  - widget.getHeight()) / 2;
 69     var left = (this._width - widget.getWidth() - this.borderWidth)/2;
 70  
 71     widgetDom.style.top = top + "px";
 72     widgetDom.style.left = left + "px";
 73 };
 74 
 75 /** @private */
 76 gtk.Button.prototype.resize = function(width, height){
 77 
 78     this._resizeWidth(width);
 79     this._resizeHeight(height);
 80     
 81     if(this._widget2 && this._widget1){
 82         var imageDomStyle = this._imageDom.style;
 83         var labelDomStyle = this._labelDom.style;
 84         if(this._imagePosition == "topPosition"){
 85             imageDomStyle.cssFloat = "";
 86             labelDomStyle.ccsFloat = "";
 87             labelDomStyle.top = "0px";
 88             imageDomStyle.left = (this._width / 2) - (this._widget2.getWidth() / 2) + "px";
 89             labelDomStyle.left = (this._width / 2) - (this._widget1.getWidth() / 2) + "px";
 90         }
 91         else{
 92             var imageTop = (this._height / 2) - (this._widget2.getHeight() / 2);
 93             var imageLeft = (this._width - this._widget2.getWidth() - this._widget1.getWidth() - this.borderWidth)/2;
 94             imageDomStyle.top = imageTop + "px";
 95             imageDomStyle.left = imageLeft + "px";
 96             
 97             var labelTop = (this._height / 2) - (this._widget1.getHeight() / 2);
 98             labelDomStyle.top = labelTop + "px";
 99             labelDomStyle.left = parseInt(imageDomStyle.left) + "px";        
100         }    
101         return;
102     }
103     
104     if(this._widget2) this._positionWidget(this._widget2, this._imageDom);
105     
106     if(this._widget1) this._positionWidget(this._widget1, this._labelDom);
107 };
108 
109 /** @private */
110 gtk.Button.prototype._getMaxChildrenHeight = function(){
111     var maxHeight = this._height;
112     if(this._widget2) maxHeight = maxHeight > this._widget2.getHeight() ? maxHeight : this._widget2.getHeight();
113     if(this._widget1) maxHeight = maxHeight > this._widget1.getHeight() ? maxHeight : this._widget1.getHeight();
114     
115     return maxHeight;
116 };
117 
118 /** @private */
119 gtk.Button.prototype._getMaxChildrenWidth = function(){
120     var maxWidth = 0;
121     if(this._widget2) maxWidth += this._widget2.getWidth();
122     if(this._widget1) maxWidth += this._widget1.getWidth();
123     maxWidth += 15;
124     maxWidth = maxWidth < this._width ? this._width : maxWidth;
125     return maxWidth;
126 };
127 
128 /** 
129  * Set the "image" property to the value of image
130  * @param {gtk.Widget} image Sets the "image" property to the value of image
131  */
132 gtk.Button.prototype.setImage = function(image){
133     if(this._imageDom.childNodes) this._imageDom.innerHTML = "";
134     this._widget2 = image;
135     
136     this._minWidth = this._getMaxChildrenWidth();
137     this._minHeight = this._getMaxChildrenHeight();
138 
139     this.resize(this._minWidth, this._minHeight);
140     
141     this._widget2._domObj.style.display = "";
142     
143     this._imageDom.appendChild(this._widget2._domObj);
144     this._domObj.insertBefore(this._imageDom, this._domObj.childNodes[1]);
145 };
146 
147 /**
148  * Change the button shape to be image shape
149  * @param {gtk.Image} image The image widget
150  */
151 gtk.Button.prototype.setButtonShape = function(imageObj){
152 	this.setAsImage(imageObj);
153 	console.log("gtk.Button.setButtonShape() will be soon renamed to gtk.Button.setAsImage()");
154 	console.log("Please change it immediately if you see this message!!!");
155 };
156 
157 /**
158  * Method to set button as image 
159  * @param {gtk.Image} image The image widget
160  */
161 gtk.Button.prototype.setAsImage = function(imageObj){
162 	this._domObj.className += " gtk_button_with_image_shape";
163 	this._gradient.style.display = "none";
164 	this._domObj.style.backgroundImage = "url("+imageObj._dom.src+")";
165 	this.setSizeRequest(imageObj._width, imageObj._height);
166 	this.resize(imageObj._width, imageObj._height);
167 };
168 
169 /**
170  * Returns the value of the "image" property
171  * @return The gtk.Widget used as the button image or None if there is no image
172  */
173 gtk.Button.prototype.getImage = function(){
174     return this._widget2;
175 };
176 
177 /**
178  * Sets the text of the button label to label
179  * @param {gtk.Label} A label to be set as the text in the button label
180  */
181 gtk.Button.prototype.setLabel = function(label){
182     if(this._labelDom.childNodes) this._labelDom.innerHTML = "";
183     this._widget1 = label;
184     this._label = label.getText();
185     label.setStyle({cursor: "pointer"});
186     
187     this._minWidth = this._getMaxChildrenWidth();
188     this._minHeight = this._getMaxChildrenHeight();
189     
190     this.resize(this._minWidth, this._minHeight);
191     this._widget1.setJustify("center");
192     this._widget1._domObj.style.display = "";
193 
194     this._labelDom.appendChild(this._widget1._domObj);
195     this._domObj.appendChild(this._labelDom);
196 };
197 
198 /**
199  * Set label name of Button
200  * @param {String}, strName name of button
201  */
202 gtk.Button.prototype.setTextLabel = function(strName){
203     if(strName != null) this.setLabel(new gtk.Label(strName));
204 };
205 
206 /**
207  * Retrieves the text from the label of the button
208  * @return The text of the label widget
209  */
210 gtk.Button.prototype.getLabel = function(){
211     return this._label;
212 };
213 
214 /** @private */
215 gtk.Button.prototype._resizeHeight = function(height){
216 	this._domObj.style.height = height + "px";
217 	this._domObj.childNodes[0].style.height = height / 2 + "px";
218 	this._height = height;
219 };
220 
221 /** @private */
222 gtk.Button.prototype._resizeWidth = function(width){
223 	this._domObj.style.width = width - this.borderWidth + "px";
224 	this._width = width;
225 };
226 
227 /** @private */
228 gtk.Button.prototype._setImagePosition = function(position){
229     this._imagePosition = position;
230     if(position == "topPosition"){
231     	var imageDomStyle = this._imageDom.style;
232     	var labelDomStyle = this._labelDom.style;
233         imageDomStyle.cssFloat = "";
234         labelDomStyle.ccsFloat = "";
235         labelDomStyle.top = "0px";
236         imageDomStyle.left = (this._width / 2) - (this._widget2.getWidth() / 2) + "px";
237         labelDomStyle.left = (this._width / 2) - (this._widget1.getWidth() / 2) + "px";
238         
239         var imageLabelHeight = this._widget1.getHeight() + this._widget2.getHeight();
240         this._height = (this._height > imageLabelHeight)? this._height : imageLabelHeight;
241         this._domObj.style.height = this._height + "px";
242 	    this._domObj.childNodes[0].style.height = this._height / 2 + "px";
243     }
244 };
245 
246 /**
247  * show loading image on button
248  */
249 gtk.Button.prototype.showLoading = function(){
250 	this._labelDom.style.display = "none";
251 	this._imageDom.style.display = "none";
252 	jsgtk.Event.removeListener(this._signalClicked);
253 	
254 	if(!this._loading) this._loading = jsgtk.Dom.create({tag:"div", className: "gtk_button_loading", append: this._domObj});
255 };
256 
257 /**
258  * Hide loading image on button
259  */
260 gtk.Button.prototype.hideLoading = function(){
261 	jsgtk.Event.addDomListener(this._signalClicked.obj, this._signalClicked.type, this._signalClicked.callback);
262 	this._labelDom.style.display = "";
263 	this._imageDom.style.display = "";
264 	if(this._loading){
265 		this._domObj.removeChild(this._loading);
266 		this._loading = null;
267 	} 
268 };
269 
270 /** 
271  * Resize the width of Button
272  * @param {Integer} width The value of width to be set to Button
273  */
274 gtk.Button.prototype.resizeWidthComposite = function(width){
275     this.setWidth(width);
276     this.resize(this._width, this._height);
277 };
278 
279 /**
280  * Resize the height of Button
281  * @param {Integer} width The value of height to be set to Button
282  */
283 gtk.Button.prototype.resizeHeightComposite = function(height){
284     this.setHeight(height);
285     this.resize(this._width, this._height);
286 };
287 
288 /**
289  * Method to set tab index
290  * @param {Integer}, the index value to be assigned
291  */
292 gtk.Button.prototype.setTabindex = function(index){
293     this._domObj.tabIndex = index;
294 };
295 
296 /**
297  * Method to set diabled onto button
298  */
299 gtk.Button.prototype.disable = function(){
300 	this._isEnable = false;
301 	this._domObj.className +=" gtk_button_disabled";
302 	this._gradient.className += " gradisable";
303 	if(this._widget1 !== null) this._widget1.setStyle({cursor: "default"});
304 };
305 
306 /**
307  * Method to set enabled to button
308  */
309 gtk.Button.prototype.enable = function(){
310 	this._isEnable = true;
311 	this._domObj.className = "gtk_widget gtk_container gtk_button";
312 	this._gradient.className = "gtk_button_gradient";
313 	if(this._widget1 !== null) this._widget1.setStyle({cursor: "pointer"});
314 };
315 
316 /** Button signal: clicked */
317 gobject.signalNew("clicked", gtk.Button, null, null, []);
318 gobject.signalNew("mouseout", gtk.Button, null, null, []);
319 gobject.signalNew("mouseover", gtk.Button, null, null, []);
320 gobject.signalNew("enterkeypressed", gtk.Button, null, null, []);
321