1 /**
  2  * gtk is a conventional namespace for jsgtk. All classes must have prefix name gtk.
  3  * For example: gtk.Widget, gtk.Entry, ... and so on.
  4  * @namespace gtk namespace
  5  */
  6 gtk = {};
  7 
  8 
  9 
 10 /**
 11  * @constructor
 12  */
 13 gobject = {
 14 	_signals: [],
 15 	_signalCount: 0,
 16 
 17 	/**
 18 	* The gobject.signalNew() registers specified object type to a specified signal_name
 19 	* @param  {string}  signalName  : a string containing the name of the signal
 20     * @param  {object}  type 		: the object type that the signal is associated with
 21 	* @return {integer} signalId    :a unique integer signal ID
 22 	*/
 23 	signalNew: function(signalName, type) {
 24 		var signal = {};
 25 		if(this.signalLookup(signalName, type)) throw("RuntimeError: this signal is already binned to the type");
 26 		this._signalCount++;
 27 		signal[signalName] = {'type': type, 'id': this._signalCount};
 28 		this._signals.push(signal);
 29 		return this._signalCount;
 30 	},
 31 
 32 	/**
 33 	* find the specified the signal that is associated to the object type
 34 	* @param {string} name       : the name of a signal
 35 	* @param {object} type       : object type
 36     * @return {iteger} or {null} : the integer id of a signal supported by type or 0.
 37 	*/
 38 	signalLookup: function(name, type) {
 39 		for(var i = this._signals.length; i--;){
 40 			if(this._signals[i][name] && this._signals[i][name].type === type ) return this._signals[i][name].id;
 41 			if(this._signals[i][name] && type instanceof this._signals[i][name].type ) return this._signals[i][name].id;
 42 		}
 43 		return null;
 44 	}
 45 };
 46 /**
 47  * Base class of all widgets, handle signal binding and triggering
 48  * @constructor
 49  */
 50 gobject.GObject = function(){
 51 	this.props = {};
 52 	this._signalHandlers = {};
 53 
 54 	/**
 55 	 * Trigger the the registered signal
 56 	 * @param {String} detailedSignal The name of signal
 57 	 * @param {Arguments} arguments value that will be used as argument by handler
 58 	 */
 59 	this.emit = function(detailedSignal){
 60 		if(this._signalHandlers[detailedSignal]){
 61 			var args = [];
 62 			for(var i=1; i<arguments.length; i++) args.push(arguments[i]);
 63 			for(var i=0; i<this._signalHandlers[detailedSignal].length; i++){
 64 				this._signalHandlers[detailedSignal][i].handler.apply(this, args.concat(this._signalHandlers[detailedSignal][i].args));
 65 			}
 66 		}
 67 	};
 68 
 69 	/**
 70 	 * Listen to the signal being triggered
 71 	 * @param {String} detailedSignal The name of signal
 72 	 * @param {Function} handler function to be executed when the signal is triggered
 73 	 * @return The id of handler
 74 	 */
 75 	this.connect = function(detailedSignal, handler){
 76 		this._signalCheck(detailedSignal);
 77 		if(!this._signalHandlers[detailedSignal]){
 78 			this._signalHandlers[detailedSignal] = [];
 79 			this._handlerId++;
 80 		}
 81 		var args = [];
 82 		var handlerId = new UUID().id;
 83 		for(var i=2; i<arguments.length; i++) args.push(arguments[i]);
 84 		this._signalHandlers[detailedSignal].push({'handler': handler, 'args': args, id: handlerId});
 85 		return handlerId;
 86 	};
 87 
 88     /**
 89      * Disconnect the function from the signal
 90      * @param {String} signal handlerId id
 91      */
 92 	this.disconnect = function(handlerId){
 93 		for(var el in this._signalHandlers){
 94 			var handlers = this._signalHandlers[el];
 95 			for(var i = 0, len = handlers.length; i < len; i++){
 96 				if(handlers[i].id === handlerId) {
 97 					handlers.splice(i, 1);
 98 					break;
 99 				}
100 			}
101 		}
102 	};
103 
104 	/** @private */
105 	this._signalCheck = function(detailedSignal){
106 		var signal = gobject.signalLookup(detailedSignal, this);
107 		if(signal) return signal;
108 		throw("Undefined signal name: " + detailedSignal);
109 	};
110 
111     /** @private */
112 	this._removeSignal = function(handlerId){
113 		for (var el in this._signalHandlers){
114 			if(el == handlerId) delete this._signalHandlers.handlerId;
115 		}
116 	};
117 };
118 /**
119  * Object is parent class of most of all widgets
120  * @constructor
121  * @base gobject.GObject
122  */
123 gtk.Object = function() {
124 	gobject.GObject.apply(this);
125 };
126 /**
127  * Widget is a main base class of all widgets, this widget inherit from gtk.Object.
128  * It is used to create any widget such gtk.Entry, gtk.ComboBox, ... and so on.
129  * @constructor
130  * @base gtk.Object
131  */
132 gtk.Widget = function() {
133 	gtk.Object.apply(this);
134 
135     var self 					= this;
136 	this._domObj;
137 	this._minWidth 				= 16;
138 	this._minHeight 			= 16;
139 	this._width 				= this._minWidth;
140 	this._height 				= this._minHeight;
141 	this._isMinWidthChanged 	= false;
142 	this._isMinHeightChanged 	= false;
143 	this._activated 			= false;
144 	this._tag 					= null;
145 	this._domObj;
146 	this._signalName 			= "";
147 	this._parent 				= null;
148 	this._tooltipObj 			= null;
149 	this._enabled				= true;
150 	this.borderWidth 			= 2 ;
151 
152 	this._render = function(){
153 		this._domObj = jsgtk.Dom.create({tag: "div", className: "gtk_widget"});
154 		var domObjStyle = this._domObj.style;
155 		domObjStyle.width = this._width + 'px';
156 		domObjStyle.height = this._height + 'px';
157 		domObjStyle.boder = "1px";
158         domObjStyle.position = "relative";
159 	};
160 
161 	this._render();
162 };
163 
164 gtk.Widget.prototype = new gtk.Object();
165 gtk.Widget.prototype.constructor = gtk.Widget;
166 
167 /**
168  * A method to show the loading image while loading
169  */
170 gtk.Widget.prototype.showLoading = function(){
171     if(!this._loadingImgContainer){
172 		this._loadingImgContainer = this._constructLoading();
173         this._appendLoading();
174     }else this._loadingImgContainer.style.display = "table";
175 };
176 
177 /**
178  * A method to hide loading image inside the widget
179  */
180 gtk.Widget.prototype.hideLoading = function(){
181     jsgtk.Dom.hideElement(this._loadingImgContainer);
182 };
183 
184 /**
185  * A method to enable widget, widget will turn to its normal state
186  * @see gtk.Widget#disable
187  * @see gtk.Widget#setEnable
188  */
189 gtk.Widget.prototype.enable = function(){};
190 
191 /**
192  * A method to disable widget, widget will be no more functioning
193  * @see gtk.Widget#enable
194  * @see gtk.Widget#setEnable
195  */
196 gtk.Widget.prototype.disable = function(){};
197 
198 /**
199  * A method to set enabled or disabled
200  * @param {Boolean}, true to set enabled, false to set disabled
201  * @see gtk.Widget#enable
202  * @see gtk.Widget#disable
203  */
204 gtk.Widget.prototype.setEnable = function(isEnabled){
205 	this._enabled = (typeof isEnabled != 'undefined' && typeof isEnabled == 'boolean') ? isEnabled : true;
206     this._enabled ? this.enable() : this.disable();
207 };
208 
209 /**
210  * A method to set tag onto it
211  * @param {String} tag The tag name to be set
212  */
213 gtk.Widget.prototype.setTag = function(tag){
214     this._tag = tag;
215 };
216 
217 /**
218  * A method to get its tag
219  * @return {String} The tag name of the widget
220  * @type String
221  */
222 gtk.Widget.prototype.getTag = function(){
223     return this._tag;
224 };
225 
226 /**
227  * A method to store the reference of widget's parent
228  * @param {Object} widget The parent to be set
229  */
230 gtk.Widget.prototype.setParent = function(widget){
231     this._parent = widget;
232 };
233 
234 /**
235  * A method to get reference of wiget's parent widget
236  * @return {Object} The parent object of the widget
237  * @type Object
238  */
239 gtk.Widget.prototype.getParent = function(){
240     return this._parent;
241 };
242 
243 /**
244  * A method to show or hide tooltip on widget
245  * @param {Boolean} isToShow The boolean value true is to show, false is not
246  * @see gtk.Widget#hideTooltip
247  * @see gtk.Widget#setTooltip
248  */
249 gtk.Widget.prototype.showTooltip = function(isToShow){
250 	this._isToShow = (typeof isToShow != 'undefined' && typeof isToShow == 'boolean') ? isToShow : true;
251 	if(this._tooltipObj !== null){
252 		this._isToShow ? this._tooltipObj.show() : this._tooltipObj.hide();
253 	}
254 };
255 
256 /**
257  * A method to hide tooltip
258  * @see gtk.Widget#showTooltip
259  * @see gtk.Widget#setTooltip
260  */
261 gtk.Widget.prototype.hideTooltip = function(){
262 	if(this._tooltipObj !== null) this._tooltipObj.hide();
263 };
264 
265 /**
266  * A method to set tooltip content into its body
267  * @param {String} textMessage The content message inside the tooltip to be display
268  * @see gtk.Widget#showTooltip
269  * @see gtk.Widget#hideTooltip
270  */
271 gtk.Widget.prototype.setTooltip = function(textMessage){
272 	var contentMessage = textMessage || "  <span style='color: #7F7F7F'>Value is undefined</span>    ";
273 	var contentObj = jsgtk.Dom.create({"tag": "div","style": "display: block;"});
274 		contentObj.innerHTML = contentMessage;
275 
276 	if(this._tooltipObj === null){
277 		this._tooltipObj = new gtk.Bubble(contentObj, this._domObj, "", 8);
278 		this._tooltipObj.setTooltip();
279 		this._tooltipObj.hide();
280 
281 	}
282 	else {
283 		this._tooltipObj.addContent(contentObj);
284 		this._tooltipObj.hide();
285 	}
286 };
287 
288 /**
289  * A method to reload or refresh the contents inside the widget
290  */
291 gtk.Widget.prototype.refresh = function(){
292 	var minWidth = this.getMinWidthComposite();
293 	minWidth = minWidth < this._width ? this._width : minWidth;
294     this.resizeWidthComposite(minWidth);
295 
296 	var minHeight = this.getMinHeightComposite();
297 	minHeight = minHeight < this._height ? this._height : minHeight;
298     this.resizeHeightComposite(minHeight);
299 };
300 
301 /**
302  * A method to set title to bold style
303  * @param {Boolean} bold The boolean value true is bold and false is not
304  */
305 gtk.Widget.prototype.setBoldTitle = function(bold){
306 	if(bold){
307 		this._domTitle.style.fontWeight = "bold";
308 	} else 	this._domTitle.style.fontWeight = "normal";
309 };
310 
311 /**
312  * A method to return Dom wiget as an object
313  * @return {Object} The Dom object value to be appended to any HTML element
314  * @type Object
315  */
316 gtk.Widget.prototype.getNode = function(){
317 	return this._domObj;
318 };
319 
320 /**
321  * A method to show the widget
322  * @see gtk.Widget#hide
323  */
324 gtk.Widget.prototype.show = function(){
325 	this._domObj.style.display = "";
326 };
327 
328 /**
329  * A method to hide the widget
330  * @see gtk.Widget#show
331  */
332 gtk.Widget.prototype.hide = function(){
333 	this._domObj.style.display = "none";
334 };
335 
336 /**
337  * A method to return true if widget is hidden and vice versa
338  * @return {Boolean} The boolean value, true or false
339  */
340 gtk.Widget.prototype.isHidden = function(){
341 	return !jsgtk.Dom.isShowed(this._domObj);
342 };
343 
344 /**
345  * A method to emit the "activated" signal on the widget
346  * @return {Boolean} The boolean value which is true or false
347  * @type Boolean
348  */
349 gtk.Widget.prototype.activate = function(){
350 	var signal = this.getActivateSignal();
351 
352 	if(signal){
353 		this._activated = true;
354 		this.emit(signal);
355 	}
356 	else this._activated = false;
357 
358 	return this._activated;
359 };
360 /**
361  * A method to set the activate signal name
362  * @param {String} signal The signal name to be set. And it must be from any conventional name of JSGTK
363  */
364 gtk.Widget.prototype.setActivateSignal = function(signal){
365 	this._signalName = signal;
366 };
367 
368 /**
369  * A method to return the name of the signal that is emitted when the widget is activated.
370  * @return {String} The signal name that is registered
371  * @type String
372  */
373 gtk.Widget.prototype.getActivateSignal = function(){
374 	return this._signalName;
375 };
376 
377 /**
378  * A method to reset the minimum width and height of widget
379  * @param {Integer} width  The minimum width value to be set
380  * @param {Integer} height The minimum height value to be set
381  */
382 gtk.Widget.prototype.setSizeRequest = function(width, height){
383 	this._isMinWidthChanged = width ? true : false;
384 	this._isMinHeightChanged = height ? true : false;
385 
386 	this._minHeight = height;
387 	this._minWidth = width;
388 };
389 /**
390  * Reset the mininimum width and minimum height of widget
391  * @param {Integer} width  The new minimum width value of the widget
392  * @param {Integer} height  The new minimum height value of the widget
393  */
394 gtk.Widget.prototype.resetMinSize = function(minWidth, minHeight){
395 	this.resetMinWidth(minWidth);
396 	this.resetMinHeight(minHeight);
397 };
398 /**
399  * A method to reset the mininimum width of widget
400  * @param {Integer} width  The new minimum width value of the widget
401  */
402 gtk.Widget.prototype.resetMinWidth = function(width){
403 	this._isMinWidthChanged = width ? true : false;
404 	this._minWidth = width;
405     this._width = width;
406 };
407 /**
408  * A method to reset the mininimum height of widget
409  * @param {Integer} height  The new minimum height value in pixel
410  */
411 gtk.Widget.prototype.resetMinHeight = function(height){
412 	this._isMinHeightChanged = height ? true : false;
413 	this._minHeight = height;
414     this._height = height;
415 };
416 
417 /**
418  * A method to set the width and height of widget
419  * @param {Integer} width  The integer width value to be set
420  * @param {Integer} height The integer height value to be set
421  */
422 gtk.Widget.prototype.setSize = function(width, height){
423 	this._height = height;
424 	this._width = width;
425 };
426 
427 /**
428  * A method to set new width to widget
429  * @param {Integer} width : new width of widget
430  */
431 gtk.Widget.prototype.setWidth = function(width){
432 	this._width = width;
433 };
434 
435 /**
436  * A method to return the current width to widget
437  * @return {Integer} The integer width value of the widget
438  * @type Integer
439  */
440 gtk.Widget.prototype.getWidth = function(){
441 	return this._width;
442 };
443 
444 /**
445  * A method to set new height to the widget
446  * @param {Integer} height The integer height value in pixel to be set
447  */
448 gtk.Widget.prototype.setHeight = function(height){
449 	this._height = height;
450 };
451 
452 /**
453  * A method to return the current height to widget
454  * @return {Integer} The height value in pixel of the widget
455  * @type Integer
456  */
457 gtk.Widget.prototype.getHeight = function(){
458 	return this._height;
459 };
460 
461 /**
462  * A method to return the minimum width and height of widget
463  * @return {Array} The array values of minimum width and height
464  * @type Array
465  */
466 gtk.Widget.prototype.getSizeRequest = function(){
467 	return [this._minWidth, this._minHeight];
468 };
469 
470 /**
471  * A method to get width and height
472  * @return {Array} The array value contains width and height
473  * @type Array
474  */
475 gtk.Widget.prototype.sizeRequest = function(){
476 	return [
477 		this._width,
478 		this._height
479 	];
480 };
481 
482 /**
483  * A method to return an array of current width and height
484  * @param {Array} The array values contains width and height
485  * @type Array
486  */
487 gtk.Widget.prototype.getSize = function(){
488 	return [
489 		this._width,
490 		this._height
491 	];
492 };
493 
494 /** @private */
495 gtk.Widget.prototype._constructLoading = function(){
496     var loadingImgContainer = jsgtk.Dom.create({tag: "table", 'class': 'gtk_loading_bar_container_widget'});
497     	var tr = jsgtk.Dom.create({append: loadingImgContainer, tag: "tr"});
498 			var td = jsgtk.Dom.create({append: tr, tag: "td"});
499                 this._loadingImgFrame = jsgtk.Dom.create({"append": td, "tag": "div", "class": "gtk_loading_frame"});
500                     this._loadingImg      = jsgtk.Dom.create({"append": this._loadingImgFrame, "tag": "div", "class": "gtk_loading_bar_widget"});
501     return loadingImgContainer;
502 };
503 
504 /** @private */
505 gtk.Widget.prototype._appendLoading = function(){
506     var firstChild = this._domObj.firstChild;
507     if(firstChild)
508         this._domObj.insertBefore(this._loadingImgContainer, firstChild);
509     else
510         this._domObj.appendChild(this._loadingImgContainer);
511 };
512 
513 /** @private */
514 gtk.Widget.prototype._resizeHeight = function(height){
515 	this._domObj.style.height = height + 'px';
516 	this._height = height;
517 };
518 
519 /** @private */
520 gtk.Widget.prototype._resizeWidth = function(width){
521 	this._domObj.style.width = width + 'px';
522 	this._width = width;
523 };
524 
525 /**
526  * A method to return the minimum composite width, if the widget contains children,
527  * the minWidth will be smallest with that the widget and its children can be shrinken
528  * @return {Integer} The minimum width value in pixel
529  * @type Integer
530  */
531 gtk.Widget.prototype.getMinWidthComposite = function(){
532 	return this._minWidth;
533 };
534 
535 /**
536  * A method to return the minimum composite height, if the widget contains children,
537  * the minHeight will be the smallest height that the widget and its children can be shrinken
538  * @return {Integer} The minimum height value in pixel
539  * @type Integer
540  */
541 gtk.Widget.prototype.getMinHeightComposite = function(){
542 	return this._minHeight;
543 };
544 
545 /**
546  * A method to resize the wiget and its children's width
547  * @param {Integer} width The integer width value in pixel to be set
548  */
549 gtk.Widget.prototype.resizeWidthComposite = function(width){
550 	this._width = width;
551 	this._domObj.style.width = this._width + 'px';
552 };
553 
554 /**
555  * A method to resize the wiget and its children's heights
556  * @param {Integer} height The height in pixel value to be set
557  */
558 gtk.Widget.prototype.resizeHeightComposite = function(height){
559 	this._height = height;
560 	this._domObj.style.height = this._height + 'px';
561 };
562 
563 /**
564  * A method to reset to default composite height
565  */
566 gtk.Widget.prototype.resetHeightComposite = function(){
567 	var minSize = this.getSizeRequest();
568 	this.setHeight(minSize[1]);
569 };
570 
571 /**
572  * A method to reset to default composite width
573  */
574 gtk.Widget.prototype.resetWidthComposite = function(){
575 	var minSize = this.getSizeRequest();
576 	this.setWidth(minSize[0]);
577 };
578 /**
579  * Button is a class to create a button
580  * @constructor
581  * @base gtk.Widget
582  * @param {String} Label text to be displayed by in the middle of button
583  */
584 gtk.Button = function(label){
585 	gtk.Widget.apply(this);
586 
587 	var self 			= this;
588 	this._label 		= label || "";
589 	this._widget1 		= null;
590 	this._widget2 		= null;
591 	this._isEnable 		= true;
592 	this._signalClicked = null;
593 
594 	this._width 		= this._minWidth = 16;
595 	this._height 		= this._minHeight = 24;
596 
597     /** 'clicked' signal */
598 	this.BUTTON_CLICKED = "clicked";
599 	/** 'mouseout' signal */
600 	this.BUTTON_MOUSEOUT = "mouseout";
601 	/** 'mouseover' signal */
602 	this.BUTTON_MOUSEOVER = "mouseover";
603 	/** 'enterkeypressed' signal */
604 	this.BUTTON_ENTERKEYPRESSED = "enterkeypressed";
605 
606 	/** @private */
607 	this._render = function(){
608 
609 	    this._domObj.className += " gtk_button";
610 	    var domObjStyle = this._domObj.style;
611 	    domObjStyle.position = "relative";
612 	    var jsgtkDom = jsgtk.Dom;
613 	        this._gradient = jsgtkDom.create({"append": this._domObj, "tag": "div", "class": "gtk_button_gradient"});
614 	        this._gradient.style.height = this._height / 2 + "px";
615 		    this._imageDom = jsgtkDom.create({"tag": "div", "style": "float: left; position: relative;"});
616 		    this._labelDom = jsgtkDom.create({"tag": "div", "style": "float: left; position: relative;"});
617 
618 		domObjStyle.width = this._width - this.borderWidth + "px";
619 		domObjStyle.height = this._height - this.borderWidth + "px";
620 		if(label) this.setLabel(new gtk.Label(label));
621 	};
622     this._render();
623     this._initEvent();
624 };
625 
626 gtk.Button.prototype = new gtk.Widget();
627 gtk.Button.prototype.constructor = gtk.Button;
628 
629 /** @private */
630 gtk.Button.prototype._initEvent = function(){
631     var self = this;
632     var jsgtkEvent = jsgtk.Event;
633     this._signalClicked = jsgtkEvent.addDomListener(this._domObj, "click", function(e){
634 		if(self._isEnable === true) self.emit("clicked");
635 	}, false);
636 
637     jsgtkEvent.addDomListener(this._domObj, "keyup", function(e){
638 	    if(e.keyCode == gtk.ENTER_KEY){
639 	        if(self._isEnable === true) self.emit("enterkeypressed");
640 	    }
641 	}, false);
642 
643 	jsgtkEvent.addDomListener(this._domObj, "mouseover", function(e){
644 		self.emit("mouseover");
645 	}, false);
646 
647 	jsgtkEvent.addDomListener(this._domObj, "mouseout", function(e){
648 		self.emit("mouseout");
649 	}, false);
650 };
651 
652 /** @private */
653 gtk.Button.prototype._positionWidget = function(widget, widgetDom){
654     var top = (this._height  - widget.getHeight()) / 2;
655     var left = (this._width - widget.getWidth() - this.borderWidth)/2;
656 
657     widgetDom.style.top = top + "px";
658     widgetDom.style.left = left + "px";
659 };
660 
661 /** @private */
662 gtk.Button.prototype.resize = function(width, height){
663 
664     this._resizeWidth(width);
665     this._resizeHeight(height);
666 
667     if(this._widget2 && this._widget1){
668         var imageDomStyle = this._imageDom.style;
669         var labelDomStyle = this._labelDom.style;
670         if(this._imagePosition == "topPosition"){
671             imageDomStyle.cssFloat = "";
672             labelDomStyle.ccsFloat = "";
673             labelDomStyle.top = "0px";
674             imageDomStyle.left = (this._width / 2) - (this._widget2.getWidth() / 2) + "px";
675             labelDomStyle.left = (this._width / 2) - (this._widget1.getWidth() / 2) + "px";
676         }
677         else{
678             var imageTop = (this._height / 2) - (this._widget2.getHeight() / 2);
679             var imageLeft = (this._width - this._widget2.getWidth() - this._widget1.getWidth() - this.borderWidth)/2;
680             imageDomStyle.top = imageTop + "px";
681             imageDomStyle.left = imageLeft + "px";
682 
683             var labelTop = (this._height / 2) - (this._widget1.getHeight() / 2);
684             labelDomStyle.top = labelTop + "px";
685             labelDomStyle.left = parseInt(imageDomStyle.left) + "px";
686         }
687         return;
688     }
689 
690     if(this._widget2) this._positionWidget(this._widget2, this._imageDom);
691 
692     if(this._widget1) this._positionWidget(this._widget1, this._labelDom);
693 };
694 
695 /** @private */
696 gtk.Button.prototype._getMaxChildrenHeight = function(){
697     var maxHeight = this._height;
698     if(this._widget2) maxHeight = maxHeight > this._widget2.getHeight() ? maxHeight : this._widget2.getHeight();
699     if(this._widget1) maxHeight = maxHeight > this._widget1.getHeight() ? maxHeight : this._widget1.getHeight();
700 
701     return maxHeight;
702 };
703 
704 /** @private */
705 gtk.Button.prototype._getMaxChildrenWidth = function(){
706     var maxWidth = 0;
707     if(this._widget2) maxWidth += this._widget2.getWidth();
708     if(this._widget1) maxWidth += this._widget1.getWidth();
709     maxWidth += 15;
710     maxWidth = maxWidth < this._width ? this._width : maxWidth;
711     return maxWidth;
712 };
713 
714 /**
715  * Set the image to be displayed next to the label
716  * @param {gtk.Image} imageWidget
717  */
718 gtk.Button.prototype.setImage = function(image){
719     if(this._imageDom.childNodes) this._imageDom.innerHTML = "";
720     this._widget2 = image;
721 
722     this._minWidth = this._getMaxChildrenWidth();
723     this._minHeight = this._getMaxChildrenHeight();
724 
725     this.resize(this._minWidth, this._minHeight);
726 
727     this._widget2._domObj.style.display = "";
728 
729     this._imageDom.appendChild(this._widget2._domObj);
730     this._domObj.insertBefore(this._imageDom, this._domObj.childNodes[1]);
731 };
732 
733 /**
734  * @deprecated
735  */
736 gtk.Button.prototype.setButtonShape = function(imageObj){
737 	this.setAsImage(imageObj);
738 	console.log("gtk.Button.setButtonShape() will be soon renamed to gtk.Button.setAsImage()");
739 	console.log("Please change it immediately if you see this message!!!");
740 };
741 
742 /**
743  * Change the button shape to be image shape
744  * @param {gtk.Image} imageWidget
745  */
746 gtk.Button.prototype.setAsImage = function(imageObj){
747 	this._domObj.className += " gtk_button_with_image_shape";
748 	this._gradient.style.display = "none";
749 	this._domObj.style.backgroundImage = "url("+imageObj._dom.src+")";
750 	this.setSizeRequest(imageObj._width, imageObj._height);
751 	this.resize(imageObj._width, imageObj._height);
752 };
753 
754 /**
755  * Returns the image widget
756  * @return {gtk.Image} imageWidget
757  */
758 gtk.Button.prototype.getImage = function(){
759     return this._widget2;
760 };
761 
762 /**
763  * Sets label to be displayed in the button
764  * @param {gtk.Label} labeWidget
765  */
766 gtk.Button.prototype.setLabel = function(label){
767     if(this._labelDom.childNodes) this._labelDom.innerHTML = "";
768     this._widget1 = label;
769     this._label = label.getText();
770     label.setStyle({cursor: "pointer"});
771 
772     this._minWidth = this._getMaxChildrenWidth();
773     this._minHeight = this._getMaxChildrenHeight();
774 
775     this.resize(this._minWidth, this._minHeight);
776     this._widget1.setJustify("center");
777     this._widget1._domObj.style.display = "";
778 
779     this._labelDom.appendChild(this._widget1._domObj);
780     this._domObj.appendChild(this._labelDom);
781 };
782 
783 /**
784  * Set text to button
785  * @param {String} strName name of button
786  */
787 gtk.Button.prototype.setTextLabel = function(strName){
788     if(strName != null) this.setLabel(new gtk.Label(strName));
789 };
790 
791 /**
792  * Returns the text from the label of the button
793  * @return {gtk.Label} labelWidget
794  */
795 gtk.Button.prototype.getLabel = function(){
796     return this._label;
797 };
798 
799 /** @private */
800 gtk.Button.prototype._resizeHeight = function(height){
801 	this._domObj.style.height = height + "px";
802 	this._domObj.childNodes[0].style.height = height / 2 + "px";
803 	this._height = height;
804 };
805 
806 /** @private */
807 gtk.Button.prototype._resizeWidth = function(width){
808 	this._domObj.style.width = width - this.borderWidth + "px";
809 	this._width = width;
810 };
811 
812 /** @private */
813 gtk.Button.prototype._setImagePosition = function(position){
814     this._imagePosition = position;
815     if(position == "topPosition"){
816     	var imageDomStyle = this._imageDom.style;
817     	var labelDomStyle = this._labelDom.style;
818         imageDomStyle.cssFloat = "";
819         labelDomStyle.ccsFloat = "";
820         labelDomStyle.top = "0px";
821         imageDomStyle.left = (this._width / 2) - (this._widget2.getWidth() / 2) + "px";
822         labelDomStyle.left = (this._width / 2) - (this._widget1.getWidth() / 2) + "px";
823 
824         var imageLabelHeight = this._widget1.getHeight() + this._widget2.getHeight();
825         this._height = (this._height > imageLabelHeight)? this._height : imageLabelHeight;
826         this._domObj.style.height = this._height + "px";
827 	    this._domObj.childNodes[0].style.height = this._height / 2 + "px";
828     }
829 };
830 
831 /**
832  * show loading Image
833  */
834 gtk.Button.prototype.showLoading = function(){
835 	this._labelDom.style.display = "none";
836 	this._imageDom.style.display = "none";
837 	jsgtk.Event.removeListener(this._signalClicked);
838 
839 	if(!this._loading) this._loading = jsgtk.Dom.create({tag:"div", className: "gtk_button_loading", append: this._domObj});
840 };
841 
842 /**
843  * Hide loading Image
844  */
845 gtk.Button.prototype.hideLoading = function(){
846 	jsgtk.Event.addDomListener(this._signalClicked.obj, this._signalClicked.type, this._signalClicked.callback);
847 	this._labelDom.style.display = "";
848 	this._imageDom.style.display = "";
849 	if(this._loading){
850 		this._domObj.removeChild(this._loading);
851 		this._loading = null;
852 	}
853 };
854 
855 /**
856  * Set tab index
857  * @param {Integer} index
858  */
859 gtk.Button.prototype.setTabindex = function(index){
860     this._domObj.tabIndex = index;
861 };
862 
863 /**
864  * Disable button button no longer function
865  */
866 gtk.Button.prototype.disable = function(){
867 	this._isEnable = false;
868 	this._domObj.className +=" gtk_button_disabled";
869 	this._gradient.className += " gradisable";
870 	if(this._widget1 !== null) this._widget1.setStyle({cursor: "default"});
871 };
872 
873 /**
874  * Enable button button functions normally
875  */
876 gtk.Button.prototype.enable = function(){
877 	this._isEnable = true;
878 	this._domObj.className = "gtk_widget gtk_container gtk_button";
879 	this._gradient.className = "gtk_button_gradient";
880 	if(this._widget1 !== null) this._widget1.setStyle({cursor: "pointer"});
881 };
882 
883 gtk.Button.prototype.resizeWidthComposite = function(width){
884     this.setWidth(width);
885     this.resize(this._width, this._height);
886 };
887 
888 gtk.Button.prototype.resizeHeightComposite = function(height){
889     this.setHeight(height);
890     this.resize(this._width, this._height);
891 };
892 
893 /** Button signal: clicked */
894 gobject.signalNew("clicked", gtk.Button, null, null, []);
895 gobject.signalNew("mouseout", gtk.Button, null, null, []);
896 gobject.signalNew("mouseover", gtk.Button, null, null, []);
897 gobject.signalNew("enterkeypressed", gtk.Button, null, null, []);
898 /**
899  * @constructor
900  * @base gtk.Widget
901  * @param {String} text The text to be displayed in label
902  */
903 gtk.Label = function(text) {
904 	gtk.Widget.apply(this);
905 
906 	/** 'clicked' signal */
907 	this.LABEL_CLICKED = "clicked";
908 	/** 'mouseover' signal */
909 	this.LABEL_MOUSEOVER = "mouseover";
910 	/** 'mouseout' signal */
911 	this.LABEL_MOUSEOUT = "mouseout";
912 
913 	this._dom = null;
914 	this._attribute = null;
915 	this._isSelectable = false;
916     this._isEnable = true;
917 
918 	this._render = function(){
919 		this._domObj.className += " gtk_label";
920 			var table = jsgtk.Dom.create({append: this._domObj, tag: "table", style: 'width: 100%; height: 100%;'});
921 				var tr = jsgtk.Dom.create({append: table, tag: "tr"});
922 					var td = jsgtk.Dom.create({append: tr, tag: "td", "className": "gtk_label_align"});
923 						this._dom = jsgtk.Dom.create({append: td, tag: "label", 'className': 'gtk_none_selectable'});
924 						this._dom.innerHTML = text || "";
925 
926 		this._disabledLabel = jsgtk.Dom.create({append: this._domObj, tag: "div", "class": "gtk_label_disabled"});
927 
928         this._minWidth = this._width = this._calculateMinWidthMinHeight()[0];
929         this._minHeight = this._height = this._calculateMinWidthMinHeight()[1];
930 
931         this.resizeWidthComposite(this._minWidth);
932         this.resizeHeightComposite(this._minHeight);
933 	};
934 
935 	this._render();
936 	this._initEvent();
937 };
938 
939 gtk.Label.prototype = new gtk.Widget();
940 gtk.Label.prototype.constructor = gtk.Label;
941 
942 gtk.Label.prototype._initEvent = function(){
943     var self = this;
944     jsgtk.Event.addDomListener(this._domObj, "click", function(e){
945        self.emit("clicked");
946     }, false);
947 
948 	jsgtk.Event.addDomListener(this._domObj, "mouseover", function(e){
949        self.emit("mouseover");
950     }, false);
951 
952     jsgtk.Event.addDomListener(this._domObj, "mouseout", function(e){
953         if(self._isEnable) self.emit("mouseout");
954     }, false);
955 };
956 /**
957  * Set text to label
958  * @param {String} text
959  */
960 gtk.Label.prototype.setText = function(text){
961 	this._dom.innerHTML = text;
962 	var size = this._calculateMinWidthMinHeight();
963 	this.resetMinSize(size[0], size[1]);
964     this.resizeWidthComposite(size[0]);
965 };
966 /**
967  * Get text from label
968  * @return {String} text
969  */
970 gtk.Label.prototype.getText = function(){
971 	return this._dom.innerHTML;
972 };
973 /** @private */
974 gtk.Label.prototype.disable = function(){
975 	this._isEnable = false;
976     this._domObj.className = "gtk_widget gtk_label gtk_label_disable";
977 
978 	if(this._attribute) jsgtk.Dom.applyAttributes(this._dom, {"cursor":"default","color":"#ccc"});
979 
980 	var domHref = this._dom.firstChild;
981 	if(domHref.tagName == "A") jsgtk.Dom.applyAttributes(domHref, {"cursor":"default","color":"#ccc"});
982 	jsgtk.Dom.showElement(this._disabledLabel);
983 };
984 /** @private */
985 gtk.Label.prototype.enable = function(){
986 	this._isEnable = true;
987 	this._domObj.className = "gtk_widget gtk_label";
988 
989 	if(this._isHover) this.enableHoverStyle();
990 	this.setAttribute(this._attribute);
991 
992 	var domHref = this._dom.firstChild;
993 	if(domHref.tagName == "A") jsgtk.Dom.applyAttributes(domHref, {"cursor":"","color":""});
994 	jsgtk.Dom.hideElement(this._disabledLabel);
995 };
996 /** @private */
997 gtk.Label.prototype.resize = function(width, height){
998 	this._resizeWidth(width);
999 	this._resizeHeight(height);
1000 };
1001 /** set tab index */
1002 gtk.Label.prototype.setTabindex = function(index){
1003 	this._domObj.tabIndex = index;
1004 };
1005 
1006 /** @private */
1007 gtk.Label.prototype._calculateMinWidthMinHeight = function(){
1008     var tempDom = this._dom.cloneNode(true);
1009         var width = jsgtk.Util.fullWidth(tempDom);
1010 	    var height = jsgtk.Util.fullHeight(tempDom);
1011 
1012 	return [width , height];
1013 };
1014 /** display border left yellow when mouse hovered label text */
1015 gtk.Label.prototype.enableHoverStyle = function(){
1016     this._isHover = true;
1017     this._domObj.className += " gtk_label_enable_hover";
1018 };
1019 /** @private */
1020 gtk.Label.prototype._calculateHeight = function(){
1021     var tempDom = this._dom.cloneNode(true);
1022     var tempSpan = jsgtk.Dom.create({tag: "div"});
1023     tempSpan.style.width = this._width + "px";
1024     tempSpan.appendChild(tempDom);
1025 	var height = jsgtk.Util.fullHeight(tempSpan);
1026 
1027 	return height;
1028 };
1029 /**
1030  * Set attributes(style) to label
1031  * @param {array} array of attributes object
1032  */
1033 gtk.Label.prototype.setAttribute = function(attribute){
1034     if(this._isEnable){
1035         this._attribute = attribute;
1036 	    jsgtk.Dom.applyAttributes(this._dom, this._attribute);
1037 
1038 	    var size = this._calculateMinWidthMinHeight();
1039 		this.resetMinSize(size[0], size[1]);
1040         this.resizeWidthComposite(size[0]);
1041         this.resizeHeightComposite(size[1]);
1042     }
1043 };
1044 /**
1045  * Get attributes
1046  * @return {Array} array of attributes object
1047  */
1048 gtk.Label.prototype.getAttribute = function(){
1049 	return this._attribute;
1050 };
1051 /**
1052  * Set label's text selectable
1053  * @param {boolean} isSelectable
1054  */
1055 gtk.Label.prototype.setSelectable = function(isSelectable){
1056 	this._isSelectable = isSelectable;
1057     this._dom.className = this._isSelectable ? "gtk_selectable" : "gtk_none_selectable";
1058 };
1059 /**
1060  * Get label's text selectable
1061  * @return {boolean}
1062  */
1063 gtk.Label.prototype.getSelectable = function(){
1064 	return this._isSelectable;
1065 };
1066 /** @private */
1067 gtk.Label.prototype.show = function(){
1068 	if(this._domObj.style.display != 'inline') this._domObj.style.display = 'block';
1069 };
1070 /**
1071  * Set the width of Label
1072  * @param {Interger} width The length of width to be set
1073  */
1074 gtk.Label.prototype.setWidthChars = function(width){
1075     this._minWidth = this._width = width;
1076     this._minHeight = this._height = this._calculateHeight();
1077 
1078     this.resizeWidthComposite(this._width);
1079     this.resizeHeightComposite(this._height);
1080 };
1081 /**
1082  * Set the justify of Label
1083  * @param {String} justify The justify type to be set to label
1084  */
1085 gtk.Label.prototype.setJustify = function(justify){
1086     this._dom.parentNode.style.textAlign = justify;
1087 };
1088 /**
1089  * Set the label style
1090  * @param {Object} properties The properties to be set to Label style
1091  */
1092 gtk.Label.prototype.setStyle = function(properties){
1093 	var domStyle = this._domObj.style;
1094     var labelStyle = this._dom.style;
1095     for(var i in properties){
1096     	domStyle[i] = properties[i];
1097     	if(i == "cursor") labelStyle[i] = properties[i];
1098     }
1099 };
1100 /** @private */
1101 gtk.Label.prototype._resizeWidth = function(width){
1102     this._width = width;
1103     this._domObj.style.width = width + 1 + "px";
1104 };
1105 /** @private */
1106 gtk.Label.prototype._resizeHeight = function(height){
1107     this._height = height;
1108     this._domObj.style.height = height + "px";
1109 };
1110 /** @private */
1111 gtk.Label.prototype.resizeWidthComposite = function(width){
1112     var minWidth = this.getMinWidthComposite();
1113     minWidth = width > minWidth ? width : minWidth;
1114     this._resizeWidth(minWidth);
1115 };
1116 /** @private */
1117 gtk.Label.prototype.resizeHeightComposite = function(height){
1118     var minHeight = this.getMinHeightComposite();
1119     minHeight = height > minHeight ? height : minHeight;
1120     this._resizeHeight(minHeight);
1121 };
1122 gobject.signalNew("clicked", gtk.Label, null, null, []);
1123 gobject.signalNew("mouseover", gtk.Label, null, null, []);
1124 gobject.signalNew("mouseout", gtk.Label, null, null, []);
1125 /**
1126  * RadioButton is a class to create a radio button
1127  * @constructor
1128  * @base gtk.Widget
1129  * @param {gtk.RadioButton} group The group name that it belongs to
1130  * @param {string} label The text of radio button
1131  */
1132 gtk.RadioButton = function(group, label){
1133     gtk.Widget.apply(this);
1134 
1135     this._activated = false;
1136     this._name = group ? group.getName() : new UUID().id;
1137 	this._addToGroup(this);
1138 
1139     this._imageSize   = 16;
1140     this._space       = 4;
1141     this._imageClassUnchecked  = "gtk_radio_button_img_unchecked";
1142     this._imageClassChecked    = "gtk_radio_button_img_checked"
1143     this._isFocus  = false;
1144     this._labelWidget = new gtk.Label(label);
1145 
1146     /** @private */
1147     this._render = function(){
1148         this._domObj.className += " gtk_radio_button";
1149             this._radioImgLabelContainer = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_radio_button_img_label_container"});
1150                 this._radioImage = jsgtk.Dom.create({"append": this._radioImgLabelContainer, "tag": "div", "className": this._imageClassUnchecked});
1151                 this._radioLabel = jsgtk.Dom.create({"append": this._radioImgLabelContainer, "tag": "div", "class": "gtk_radio_button_label"});
1152                 this._radioLabel.appendChild(this._labelWidget.getNode());
1153 
1154         this._width  = this._minWidth  = this._imageSize + this._labelWidget.getMinWidthComposite() + this._space;
1155         this._height = this._minHeight = this._labelWidget.getMinHeightComposite();
1156     };
1157     this._render();
1158 
1159     this._initEvent();
1160 
1161     this.resizeWidthComposite(this._width);
1162     this.resizeHeightComposite(this._height);
1163 };
1164 
1165 gtk.RadioButton.prototype = new gtk.Widget();
1166 gtk.RadioButton.prototype.constructor = gtk.RadioButton;
1167 
1168 /** @private */
1169 gtk.RadioButton.group = [];
1170 
1171 /** @private */
1172 gtk.RadioButton.prototype._initEvent = function(){
1173     var self = this;
1174     var jsgtkEvent = jsgtk.Event;
1175 
1176     jsgtkEvent.addDomListener(this._domObj, "mouseup", function(){
1177             self._unMarkeOther(self);
1178             self._unFocusOther(self)
1179             self._select();
1180             self.emit("toggled");
1181     });
1182     jsgtkEvent.addDomListener(this._domObj, 'keyup', function(e){
1183 	    if(e.keyCode == gtk.ENTER_KEY){
1184             self._unMarkeOther(self);
1185             self._unFocusOther(self)
1186             self.setFocus(self);
1187             self._select();
1188 	    }
1189 	});
1190 	jsgtkEvent.addDomListener(this._domObj, "focus", function(){
1191         self.setFocus(self);
1192     });
1193     jsgtkEvent.addDomListener(this._domObj, "blur", function(){
1194         self._unFocusOther(self)
1195     });
1196 };
1197 
1198 /**
1199  * A method to set the tab index value onto the gtk.RadioButton
1200  * @param {integer} index The integer index value to be set
1201  */
1202 gtk.RadioButton.prototype.setTabindex = function(index){
1203 	this._domObj.tabIndex = index;
1204 };
1205 
1206 /** @private */
1207 gtk.RadioButton.prototype._unFocusOther = function(btn){
1208 	var group = gtk.RadioButton.group;
1209     for(var i = group.length; i--;){
1210         if(group[i].name === btn.getName()) {
1211             for(var j = group[i].children.length; j--;){
1212                 this._unFocus(group[i].children[j]);
1213             }
1214             return;
1215         }
1216     }
1217 };
1218 
1219 /** @private */
1220 gtk.RadioButton.prototype._unFocus = function(btn){
1221 	btn.getNode().firstChild.lastChild.className = "gtk_radio_button_label"
1222 };
1223 
1224 /**
1225  * A method to set focus onto the gtk.RadioButton
1226  */
1227 gtk.RadioButton.prototype.setFocus = function(){
1228 	this._domObj.firstChild.lastChild.className += " gtk_radio_focus"
1229 };
1230 
1231 /**
1232  * A method to set active onto the radio button
1233  * @param {Boolean} isActive The state to define whether it is true or false
1234  */
1235 gtk.RadioButton.prototype.setActive = function(isActive){
1236 	this._activated = isActive;
1237 };
1238 
1239 /**
1240  * A method to get/return the state of radio button whether it is activated or not
1241  * @return {Boolean} The state as true or false
1242  * @type Boolean
1243  */
1244 gtk.RadioButton.prototype.getActive = function(){
1245 	return this._activated;
1246 };
1247 
1248 /** @private */
1249 gtk.RadioButton.prototype._select = function(){
1250     this._radioImage.className = this._imageClassUnchecked + " " + this._imageClassChecked;
1251 	this.setActive(true);
1252 };
1253 
1254 /** @private */
1255 gtk.RadioButton.prototype._deSelect = function(){
1256     this._radioImage.className = this._imageClassUnchecked;
1257 	this.setActive(false);
1258 };
1259 
1260 /**
1261  * A method to get the group
1262  * @return {gtk.RadioButton} The group name as an object of gtk.RadioButton
1263  * @type gtk.RadioButton
1264  */
1265 gtk.RadioButton.prototype.getGroup = function(){
1266     var group = gtk.RadioButton.group;
1267     var tmpGroup = [];
1268     for(var i = group.length; i--;){
1269         if(group[i].getName() === this.getName()) tmpGroup.push(group[i]);
1270     }
1271     return tmpGroup;
1272 };
1273 
1274 /**
1275  * A method to get the name of group that it belongs to
1276  * @return {String} The name of the gtk.RadioButton belongs to
1277  * @type String
1278  */
1279 gtk.RadioButton.prototype.getName = function(){
1280     return this._name;
1281 };
1282 
1283 /**
1284  * A method to set the name of group that it is to belongs to
1285  * @param {String} name The name of the group
1286  */
1287 gtk.RadioButton.prototype.setName = function(name){
1288     this._name = name;
1289 };
1290 
1291 /** @private */
1292 gtk.RadioButton.prototype._addToGroup = function(group){
1293     var radioGroup = gtk.RadioButton.group;
1294     if(radioGroup != []){
1295         for(var i = radioGroup.length; i--;){
1296             if(radioGroup[i].name == group._name){
1297                 radioGroup[i].children.push(group);
1298                 return;
1299             }
1300         }
1301     }
1302     var groupObj = {name: group._name, children: [group]};
1303     radioGroup.push(groupObj);
1304 };
1305 
1306 /** @private */
1307 gtk.RadioButton.prototype._unMarkeOther = function(btn){
1308     var group = gtk.RadioButton.group;
1309     for(var i = group.length; i--;){
1310         if(group[i].name === btn.getName()) {
1311             for(var j = group[i].children.length; j--;){
1312                 group[i].children[j]._deSelect();
1313             }
1314             return;
1315         }
1316     }
1317 };
1318 
1319 /** @private */
1320 gtk.RadioButton.prototype._resizeHeight = function(height){
1321     this._height = height;
1322     this._domObj.style.height = height + "px";
1323         this._radioImgLabelContainer.style.height = this._minHeight + "px";
1324 };
1325 
1326 /** @private */
1327 gtk.RadioButton.prototype._resizeWidth = function(width){
1328     this._width = width;
1329     this._domObj.style.width = width + "px";
1330         this._radioImgLabelContainer.style.width = width + "px";
1331 };
1332 
1333 /**
1334  * A method to resize its composite width of gtk.Radiobutton
1335  * @param {Integer} width The integer value as width to be set
1336  */
1337 gtk.RadioButton.prototype.resizeWidthComposite = function(width){
1338     var minWidth = this._minWidth < width ? width : this._minWidth;
1339     this._resizeWidth(minWidth);
1340 };
1341 
1342 /**
1343  * A method to resize its composite height of gtk.Radiobutton
1344  * @param {Integer} height The integer value as height to be set
1345  */
1346 gtk.RadioButton.prototype.resizeHeightComposite = function(height){
1347     var minHeight = this._minHeight < height ? height : this._minHeight;
1348     this._resizeHeight(minHeight);
1349     this._positionCheckBox();
1350 };
1351 
1352 /** @private */
1353 gtk.RadioButton.prototype._positionCheckBox = function(height){
1354     this._radioImgLabelContainer.style.top = this._height / 2 - this._minHeight / 2 + "px";
1355 };
1356 
1357 /** It allows user to connect to a registered signal event "toggled" when click on the radio button */
1358 gobject.signalNew("toggled", gtk.RadioButton, null, null, []);
1359 /**
1360 * @constructor
1361 * @base gtk.Widget
1362 * @param {String} Label text to be displayed by in the middle of button
1363 */
1364 gtk.CheckButton = function(label){
1365     gtk.Widget.apply(this);
1366 
1367 	/** 'checked' signal*/
1368 	this.CHECKBUTTON_CHECKED = 'checked';
1369 	/** 'unchecked' signal*/
1370 	this.CHECKBUTTON_UNCHECKED = "unchecked";
1371 	/** 'focused' signal*/
1372 	this.CHECKBUTTON_FOCUSED = "focused";
1373 	/** 'blurred' signal*/
1374 	this.CHECKBUTTON_BLURRED = "blurred";
1375 
1376     this._isChecked   	= false;
1377     this._imageSize   	= 16;
1378     this._space       	= 7;
1379     this._imageClass  	= "gtk_check_button_img";
1380     this._disabledModal	= null;
1381 
1382     this._labelWidget = new gtk.Label(label);
1383 
1384     /** @private */
1385     this._render = function(){
1386         this._domObj.className += " gtk_check_button";
1387             this._checkImgLabelContainer = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_check_button_img_label_container"});
1388                 this._checkImage = jsgtk.Dom.create({"append": this._checkImgLabelContainer, "tag": "div", "className": "gtk_check_button_img"});
1389                 this._checkLabel = jsgtk.Dom.create({"append": this._checkImgLabelContainer, "tag": "div", "class": "gtk_check_button_label"});
1390                 this._checkLabel.appendChild(this._labelWidget.getNode());
1391 
1392         this._width  = this._minWidth  = this._imageSize + this._labelWidget.getMinWidthComposite() + this._space;
1393         this._height = this._minHeight = this._labelWidget.getMinHeightComposite();
1394     };
1395     this._render();
1396 
1397     this._initEvent();
1398 
1399     this.resizeWidthComposite(this._width);
1400     this.resizeHeightComposite(this._height);
1401 };
1402 
1403 gtk.CheckButton.prototype = new gtk.Widget();
1404 gtk.CheckButton.prototype.constructor = gtk.CheckButton;
1405 
1406 /** @private */
1407 gtk.CheckButton.prototype._initEvent = function(){
1408     var self = this;
1409 	var jsgtkEvent = jsgtk.Event;
1410 
1411 	this._mouseupHandler = jsgtkEvent.addDomListener(this._domObj, 'mouseup', function(){
1412 	    if(!self._isChecked) self.setChecked();
1413         else self.setUnchecked();
1414 	});
1415 	this._mouseoverHandler = jsgtkEvent.addDomListener(this._checkImgLabelContainer, 'mouseover', function(){
1416 		if(self._isChecked) self._checkImage.className = "gtk_check_button_img gtk_check_button_checked_hover";
1417 		else self._checkImage.className = "gtk_check_button_img gtk_check_button_unchecked_hover";
1418 	});
1419 
1420 	this._mouseoutHandler = jsgtkEvent.addDomListener(this._checkImgLabelContainer, 'mouseout', function(){
1421 		if(self._isChecked) self._checkImage.className = "gtk_check_button_img gtk_check_button_checked";
1422 		else   self._checkImage.className = "gtk_check_button_img";
1423 	});
1424 
1425 	jsgtkEvent.addDomListener(this._domObj, "focus", function(){
1426 		self.emit("focused");
1427     });
1428 
1429     jsgtkEvent.addDomListener(this._domObj, "blur", function(){
1430     	self.emit("blurred");
1431     });
1432 
1433     this._keyupHandler = jsgtkEvent.addDomListener(this._domObj, 'keyup', function(e){
1434 	    if(e.keyCode == gtk.ENTER_KEY){
1435            if(!self._isChecked) self.setChecked();
1436            else self.setUnchecked();
1437 	    }
1438 	});
1439 };
1440 
1441 /**
1442  * Method to set tab index value
1443  */
1444 gtk.CheckButton.prototype.setTabindex = function(index){
1445     this._domObj.tabIndex = index;
1446 };
1447 
1448 /**
1449  * set default checked on check button
1450  */
1451 gtk.CheckButton.prototype.setChecked = function(){
1452     this._checkImage.className = this._imageClass +" gtk_check_button_checked";
1453     this._isChecked = true;
1454     this.emit("checked", this._labelWidget.getText());
1455 };
1456 
1457 /**
1458  * uncheck the checked
1459  */
1460 gtk.CheckButton.prototype.setUnchecked = function(){
1461     this._checkImage.className ="gtk_check_button_img gtk_check_button_unchecked";
1462 	this._isChecked = false;
1463 	this.emit("unchecked", this._labelWidget.getText());
1464 };
1465 
1466 /**
1467  * return state of checkbutton
1468  * @return {boolean}
1469  */
1470 gtk.CheckButton.prototype.getCheckedState = function(){
1471     return this._isChecked;
1472 };
1473 
1474 /**
1475  * All functionalities are disabled
1476  */
1477 gtk.CheckButton.prototype.disable = function(){
1478 	var jsgtkEvent = jsgtk.Event;
1479 	jsgtkEvent.removeListener(this._mouseupHandler);
1480 	jsgtkEvent.removeListener(this._keyupHandler);
1481 	jsgtkEvent.removeListener(this._mouseoutHandler);
1482 	jsgtkEvent.removeListener(this._mouseoverHandler);
1483 	this._labelWidget.setAttribute({color: "#6F6F6F"});
1484 };
1485 
1486 /**
1487  * All functionalities are enabled
1488  */
1489 gtk.CheckButton.prototype.enable = function(){
1490 	var jsgtkEvent = jsgtk.Event;
1491 	jsgtkEvent.registerHandler(this._mouseupHandler);
1492 	jsgtkEvent.registerHandler(this._keyupHandler);
1493 	jsgtkEvent.registerHandler(this._mouseoutHandler);
1494 	jsgtkEvent.registerHandler(this._mouseoverHandler);
1495 	this._labelWidget.setAttribute({color: ""});
1496 };
1497 
1498 /** @private */
1499 gtk.CheckButton.prototype._resizeHeight = function(height){
1500     this._height = height;
1501     this._domObj.style.height = height + "px";
1502         this._checkImgLabelContainer.style.height = this._minHeight + "px";
1503 };
1504 
1505 /** @private */
1506 gtk.CheckButton.prototype._resizeWidth = function(width){
1507     this._width = width;
1508     this._domObj.style.width = width + "px";
1509         this._checkImgLabelContainer.style.width = width + "px";
1510 };
1511 
1512 /** @private */
1513 gtk.CheckButton.prototype.resizeWidthComposite = function(width){
1514     var minWidth = this._minWidth < width ? width : this._minWidth;
1515     this._resizeWidth(minWidth);
1516 };
1517 
1518 /** @private */
1519 gtk.CheckButton.prototype.resizeHeightComposite = function(height){
1520     var minHeight = this._minHeight < height ? height : this._minHeight;
1521     this._resizeHeight(minHeight);
1522     this._positionCheckBox();
1523 };
1524 
1525 /** @private */
1526 gtk.CheckButton.prototype._positionCheckBox = function(height){
1527     this._checkImgLabelContainer.style.top = this._height / 2 - this._minHeight / 2 + "px";
1528 };
1529 
1530 /** Signal in CheckButton widget: checked */
1531 gobject.signalNew("checked", gtk.CheckButton, null, null, []);
1532 gobject.signalNew("unchecked", gtk.CheckButton, null, null, []);
1533 gobject.signalNew("focused", gtk.CheckButton, null, null, []);
1534 gobject.signalNew("blurred", gtk.CheckButton, null, null, []);
1535 /**
1536  * @constructor
1537  * @base gtk.Widget
1538  */
1539 gtk.Image = function(imagePath, imageWidth, imageHeight) {
1540 	gtk.Widget.apply(this);
1541 	var self = this;
1542 
1543 	/** 'clicked' signal */
1544 	this.IMAGE_CLICKED = "clicked";
1545 
1546 	this._size         = null;
1547 	this._dom          = null;
1548 	this._defaultImage = "images/icons/ajax_loader.gif";
1549 
1550 	this._width        = this._minWidth = imageWidth || 16;
1551 	this._height       = this._minHeight = imageHeight || 16;
1552 
1553     this._attribute;
1554 
1555 	/** @private */
1556 	this._render = function(){
1557 		this._domObj.className += " gtk_image";
1558 			this.header = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_image_header"});
1559 				this.headerDom = jsgtk.Dom.create({"append": this.header, "tag": "div", "class": "gtk_image_header_dom"});
1560 					this.closeButton = jsgtk.Dom.create({"append":this.headerDom, "tag": "div","className": "gtk_image_header_close_button"});
1561 
1562 			var table = jsgtk.Dom.create({append: this._domObj, tag: "table", "className": "gtk_image_table"});
1563 				var tr = jsgtk.Dom.create({append: table, tag: "tr"});
1564 					var td = jsgtk.Dom.create({append: tr, tag: "td", "className": "gtk_image_table_td"});
1565 						this._dom = jsgtk.Dom.create({append: td, tag: "img", src: this._defaultImage});
1566 
1567             this._disableLayer = jsgtk.Dom.create({append: this._domObj, tag: "div", 'class': "gtk_image_div_disable"});
1568 
1569 		this._invisibleOverlay = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "className": "gtk_image_invisible_overlay"});
1570 
1571 		if(imagePath !== undefined){
1572 		    this.setFromFile(imagePath, imageWidth, imageHeight);
1573 		}
1574 	};
1575 
1576 	this._render();
1577 
1578 	jsgtk.Event.addDomListener(this._dom, "click", function(){
1579 		self.emit("clicked");
1580 	});
1581 
1582 	jsgtk.Event.addDomListener(this._dom, "mouseover", function(){
1583 		self.emit("mouseover");
1584 	});
1585 
1586 	jsgtk.Event.addDomListener(this._dom, "mouseout", function(){
1587 		self.emit("mouseout");
1588 	});
1589 };
1590 
1591 gtk.Image.prototype = new gtk.Widget();
1592 gtk.Image.prototype.constructor = gtk.Image;
1593 
1594 
1595 /**
1596 * Set Image src from given file
1597 * @param {String} filename which is assigned when we call the method.
1598 */
1599 gtk.Image.prototype.setFromFile = function(fileName, imageWidth, imageHeight){
1600     var file = fileName || this._defaultImage;
1601 	this._dom.src = file;
1602 
1603     this.resetMinWidth(imageWidth || this._minWidth);
1604     this.resetMinHeight(imageHeight || this._minHeight);
1605 
1606     this.resizeWidthComposite(this._minWidth);
1607     this.resizeHeightComposite(this._minHeight);
1608 };
1609 
1610 /**
1611 * when mouseover the image, the frame will be visible
1612 */
1613 gtk.Image.prototype.enableDelete = function(){
1614 	gtk.ImageAnimator.init(this);
1615 };
1616 
1617 /** @private */
1618 gtk.Image.prototype.resize = function(width, height){
1619    this._resizeWidth(width, height);
1620 	this._resizeHeight(width, height);
1621 };
1622 
1623 /** @private */
1624 gtk.Image.prototype.resetWidth = function(width){
1625 	this._dom.setAttribute("width", width || this._minWidth);
1626 	this.resetMinWidth(width || this._minWidth);
1627 };
1628 
1629 /** @private */
1630 gtk.Image.prototype.resetHeight = function(height){
1631 	this._dom.setAttribute("height", height || this._minHeight);
1632 	this.resetMinHeight(height || this._minHeight);
1633 };
1634 
1635 /**
1636 * reset the size of image
1637 * @param {number} width
1638 * @param {number} height
1639 */
1640 gtk.Image.prototype.resetSize = function(width, height){
1641 	 if(width !== null) this.resetWidth(width);
1642 	 if(height !== null) this.resetHeight(height);
1643 };
1644 
1645 /**
1646 * reset to the defualt size
1647 */
1648 gtk.Image.prototype.resetDefaultSize = function(){
1649 	var actualImageSize = this._getActualImageSize();
1650 	this.resetSize(actualImageSize[0], actualImageSize[1]);
1651 };
1652 
1653 gtk.Image.prototype._getActualImageSize = function(){
1654 	var imageNode = this.getChildNode();
1655 	var imageObj = new Image();
1656 		 imageObj.src = imageNode.src;
1657 	return [imageObj.width, imageObj.height];
1658 };
1659 
1660 gtk.Image.prototype._resizeWidth = function(width){
1661 	this._width = width;
1662     this._domObj.style.width = width + "px";
1663 		this._dom.width = this._minWidth;
1664 };
1665 
1666 gtk.Image.prototype._resizeHeight = function(height){
1667 	this._height = height;
1668     this._domObj.style.height = height + "px";
1669 		this._dom.height = this._minHeight;
1670 };
1671 
1672 /**
1673  * Set attributes
1674  * @param {array} array of attributes object
1675  */
1676 gtk.Image.prototype.setAttribute = function(attribute){
1677 	this._attribute = attribute;
1678 	this._applyAttribute();
1679 };
1680 
1681 /** @private */
1682 gtk.Image.prototype.getChildNode = function(){
1683 	return this._dom;
1684 };
1685 
1686 /**
1687  * Assign property disabled to image
1688  */
1689 gtk.Image.prototype.disable = function(){
1690     jsgtk.Dom.showElement(this._disableLayer);
1691 };
1692 
1693 /**
1694  * Assign property enabled to image
1695  */
1696 gtk.Image.prototype.enable = function(){
1697     jsgtk.Dom.hideElement(this._disableLayer);
1698 };
1699 
1700 /** @private */
1701 gtk.Image.prototype._applyAttribute = function(){
1702 	for(var el in this._attribute)
1703 		this._dom.style[el] = this._attribute[el];
1704 };
1705 
1706 gobject.signalNew('closed', gtk.Image, [], null, null);
1707 gobject.signalNew('clicked', gtk.Image, [], null, null);
1708 gobject.signalNew('mouseout', gtk.Image, [], null, null);
1709 gobject.signalNew('mouseover', gtk.Image, [], null, null);
1710 
1711 /**@constructor*/
1712 gtk.ImageAnimator = {
1713 	_timeoutId1: null,
1714 	_timeoutId2: null,
1715 	_isHeaderActive: false,
1716 	_isImageMousovered: false,
1717 	_imageObj: null,
1718 	init: function(imageObj){
1719 		this._imageObj = imageObj;
1720 
1721 		jsgtk.Dom.showElement(this._imageObj._invisibleOverlay);
1722 
1723 		var self = this;
1724 
1725 		jsgtk.Event.addDomListener(this._imageObj._invisibleOverlay, "mouseover", function(e){
1726 			self._handleImageMouseovered();
1727 			jsgtk.Event.stopBubble(e);
1728 		});
1729 
1730 		jsgtk.Event.addDomListener(this._imageObj._invisibleOverlay, "mouseout", function(e){
1731 			self._handleImageMouseOut();
1732 			jsgtk.Event.stopBubble(e);
1733 		});
1734 
1735 		jsgtk.Event.addDomListener(this._imageObj.header, "mouseover", function(e){
1736 			clearTimeout(self._timeoutId2);
1737 			jsgtk.Event.stopBubble(e)
1738 		});
1739 
1740 		jsgtk.Event.addDomListener(this._imageObj.header, "mouseout", function(e){
1741 			self._handleImageMouseOut();
1742 			jsgtk.Event.stopBubble(e)
1743 		});
1744 
1745 		jsgtk.Event.addDomListener(this._imageObj._invisibleOverlay, "click", function(){
1746 			self._imageObj.emit("clicked");
1747 		});
1748 
1749 		jsgtk.Event.addDomListener(this._imageObj.closeButton, "click", function(){
1750 			self._imageObj.emit("closed");
1751 		});
1752 	},
1753 	_handleImageMouseovered: function(){
1754 		clearTimeout(this._timeoutId2);
1755 		if(this._isHeaderActive) return;
1756 		var self = this;
1757 		self._imageObj._domObj.className += " gtk_image_enable_delete";
1758 		this._timeoutId1 = window.setTimeout(function(){
1759 			jsgtk.Dom.showElement(self._imageObj.header);
1760 			self._imageObj.headerDom.style.top = 18 + "px";
1761 			var i = 18;
1762 			var intervalId = window.setInterval(function(){
1763 				i -= 4;
1764 				self._imageObj.headerDom.style.top = i + "px";
1765 				if(i < 0){
1766 					self._imageObj.headerDom.style.top = 0 + "px";
1767 
1768 					self._isHeaderActive = true;
1769 					self._isImageMousovered = true;
1770 
1771 	 				clearInterval(intervalId);
1772 				}
1773 			}, 40);
1774 		}, 200);
1775 	},
1776 	_handleImageMouseOut: function(){
1777 		var self = this;
1778 		clearTimeout(this._timeoutId1);
1779 		self._timeoutId2 = window.setTimeout(function(){
1780 			var i = 0;
1781 			var intervalId = window.setInterval(function(){
1782 				i += 4;
1783 				self._imageObj.headerDom.style.top = i + "px";
1784 				if(i >18){
1785 					self._imageObj.headerDom.style.top = 18 + "px";
1786 					jsgtk.Dom.hideElement(self._imageObj.header);
1787 
1788 					self._isHeaderActive = false;
1789 					self._isImageMousovered = false;
1790 
1791 					self._imageObj._domObj.className = "gtk_image";
1792 					clearInterval(intervalId);
1793 				}
1794 			}, 40);
1795 		}, 50);
1796 	}
1797 };
1798 /**
1799 * @constructor
1800 * @base gtk.Widget
1801 * @param {Interger} columns The numbers of columns that slider can contain
1802 * @param {Interger} spacing The value of spacing to set between each columns
1803 */
1804 gtk.Slider = function(columns, spacing) {
1805 	gtk.Widget.apply(this);
1806 
1807     var self = this;
1808 
1809 	this._width      = this._minWidth  = 300;
1810 	this._height     = this._minHeight = 200;
1811 
1812 	this._visibleColumns    = columns || 1;
1813 	this._spacing    = spacing || 1;
1814 	this._marginLeft = 50;
1815 
1816 	this._slideWidth = this._getSlideWidth(this._width);
1817 
1818 	this._slides     = [];
1819 	this._currentLeft= 0;
1820 	this._arrowWidth = 27;
1821 	this._arrowHeight= 37;
1822 	this._slideWidths;
1823 
1824 	this._isMoving = false;
1825 
1826 	/** @private */
1827 	this._render = function(){
1828 		this._domObj.className   += " gtk_slider";
1829 		    this._viewport = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_slides_viewport", "style": "position: relative;"});
1830 		    this._viewport.style.left  = this._marginLeft + "px";
1831 		    this._viewport.style.overflowY = "hidden";
1832 		        this._slidesContainer = jsgtk.Dom.create({"append": this._viewport, "tag": "div", "class": "gtk_slides_container"});
1833 		        this._slidesContainer.style.height = this._height + "px";
1834 
1835         this._leftArrow = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_slider_leftarrow"});
1836         this._leftArrowDisabled = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_slider_leftarrow_disabled"});
1837         this._positionArrowLeft(this._leftArrow);
1838         this._positionArrowLeft(this._leftArrowDisabled);
1839         jsgtk.Dom.hideElement(this._leftArrow);
1840 
1841         this._rightArrow = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_slider_rightarrow"});
1842         this._rightArrowDisabled = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_slider_rightarrow_disabled"});
1843         this._positionArrowRight(this._rightArrow);
1844         this._positionArrowRight(this._rightArrowDisabled);
1845         jsgtk.Dom.hideElement(this._rightArrowDisabled);
1846 
1847  		this.resize(this._width, this._height);
1848 	};
1849 
1850     this._render();
1851 
1852     jsgtk.Event.addDomListener(this._leftArrow, "click", function(e){
1853 
1854         if(!self._isMoving && self._currentLeft !== 0)self._moveRight();
1855 	    jsgtk.Event.stopBubble(e);
1856 	}, false);
1857 
1858     jsgtk.Event.addDomListener(this._rightArrow, "click", function(e){
1859 
1860         if(!self._isMoving){
1861             var len = self._slides.length >= self._visibleColumns ? self._visibleColumns : 1;
1862             var left = self._slideWidth * (self._slides.length - len);
1863             var isMovable = left + self._currentLeft;
1864             if(isMovable >= 0) self._moveLeft();
1865         }
1866         jsgtk.Event.stopBubble(e);
1867 	}, false);
1868 };
1869 
1870 gtk.Slider.prototype = new gtk.Widget();
1871 gtk.Slider.prototype.constructor = gtk.Slider;
1872 
1873 /**
1874 * Append gtk.Widget(any type)
1875 * @param {gtk.Widget} widget
1876 * @param {boolean} isCloseButtonVisible
1877 */
1878 gtk.Slider.prototype.appendChild = function(widget, closeButtonVisible){
1879 
1880     var self = this;
1881     var isCloseButtonVisible = closeButtonVisible === undefined || closeButtonVisible === null ? false : closeButtonVisible;
1882     var scroller = this._getScroller(widget);
1883 
1884     var slide = this._constructSlide(scroller);
1885     this._resizeElement(slide, this._slideWidth, this._height - 12);
1886 
1887     var space = this._constructSpace();
1888     this._resizeElement(space, this._spacing, this._height);
1889 
1890     var closeButton = slide.lastChild;
1891 
1892     this._slides.push({
1893         "slide"  : slide,
1894         "space"  : space,
1895         "widget" : scroller
1896     });
1897     scroller.resizeWidthComposite(this._slideWidth);
1898     scroller.resizeHeightComposite(this._height - 12);
1899 
1900     var slideWidth = this._slideWidth + this._spacing + 2;
1901     this._setSlideWidths(slideWidth * (this._slides.length));
1902 
1903     this.resize(this._width, this._height);
1904 
1905     var jsgtkDom = jsgtk.Dom;
1906     var jsgtkEvent = jsgtk.Event;
1907 
1908     if(this._slides.length <= this._visibleColumns) {
1909         jsgtkDom.hideElement(this._rightArrow);
1910         jsgtkDom.showElement(this._rightArrowDisabled);
1911     }else{
1912         jsgtkDom.hideElement(this._rightArrowDisabled);
1913         jsgtkDom.showElement(this._rightArrow);
1914     }
1915 
1916     jsgtk.Event.addDomListener(slide, "mouseover", function(e){
1917         if(isCloseButtonVisible)
1918         	jsgtkDom.showElement(this.lastChild);
1919         jsgtkEvent.stopBubble(e);
1920     });
1921 
1922     jsgtk.Event.addDomListener(slide, "mouseout", function(e){
1923         jsgtkDom.hideElement(this.lastChild);
1924         jsgtkEvent.stopBubble(e);
1925     });
1926 
1927     jsgtk.Event.addDomListener(closeButton, "mousedown", function(e){
1928         self._removeSlide(slide, space);
1929         if(self._slides.length <= self._visibleColumns){
1930             self._disableArrow();
1931         }
1932         jsgtkEvent.stopBubble(e);
1933     });
1934 };
1935 
1936 /** @private */
1937 gtk.Slider.prototype.resetMinWidth = function(width){
1938 	this._isMinWidthChanged = width ? true : false;
1939 	this._minWidth = width;
1940     this._width = width;
1941     this.resizeWidthComposite(this._width);
1942 };
1943 
1944 /** @private */
1945 gtk.Slider.prototype.resetMinHeight = function(height){
1946 	this._isMinHeightChanged = height ? true : false;
1947 	this._minHeight = height;
1948     this._height = height;
1949     this.resizeHeightComposite(this._height);
1950 };
1951 
1952 /**
1953 * clear all gtk.Widget inside gtk.Slider
1954 */
1955 gtk.Slider.prototype.clearSlides = function(){
1956     this._slides = [];
1957     this._slidesContainer.innerHTML = "";
1958     this._disableArrow();
1959     this._viewport.scrollLeft = 0;
1960 };
1961 
1962 /** @private */
1963 gtk.Slider.prototype._disableArrow = function(){
1964 	var domUtil = jsgtk.Dom;
1965     domUtil.hideElement(this._rightArrow);
1966     domUtil.showElement(this._rightArrowDisabled);
1967 
1968     domUtil.hideElement(this._leftArrow);
1969     domUtil.showElement(this._leftArrowDisabled);
1970 };
1971 
1972 /** @private */
1973 gtk.Slider.prototype._removeSlide = function(slide, space){
1974     var self = this;
1975     for(var i = this._slides.length; i--;){
1976         if(this._slides[i].slide === slide) {
1977             this._slides.splice(i, 1);
1978             break;
1979         }
1980     }
1981 
1982     var width = parseInt(slide.style.width);
1983     var intervalID = window.setInterval(function(){
1984         width -= 20;
1985         slide.style.width = width + "px";
1986         if(width <= 0) {
1987             var slideWidth = self._slideWidth + self._spacing + 2;
1988 
1989             self._setSlideWidths(slideWidth * (self._slides.length));
1990 
1991             self._slidesContainer.style.width = self._slideWidths + "px";
1992 
1993             var left = self._currentLeft - slideWidth;
1994 
1995             var slideParent = slide.parentNode;
1996 
1997             if(slideParent.lastChild === space) self._viewport.scrollLeft -= 5;
1998 
1999             if(left >0) self._currentLeft = left;
2000 
2001             slideParent.removeChild(space);
2002             slideParent.removeChild(slide);
2003 
2004             clearInterval(intervalID);
2005         }
2006     }, 5);
2007 };
2008 
2009 /** @private */
2010 gtk.Slider.prototype._setSlideWidths = function(width){
2011     this._slideWidths = width;
2012 };
2013 
2014 /** @private */
2015 gtk.Slider.prototype._resizeSlides = function(width, height){
2016     var slide;
2017 
2018     this._slideWidth = this._getSlideWidth(width);
2019 
2020     var slideWidth = this._slideWidth + this._spacing + 2;
2021     this._setSlideWidths(slideWidth * (this._slides.length));
2022 
2023     for(var i = 0, len = this._slides.length; i<len; i++){
2024         slide = this._slides[i];
2025         this._resizeElement(slide["slide"], this._slideWidth, height - 13);
2026         this._resizeElement(slide["space"], this._spacing, height);
2027         slide["widget"].resizeWidthComposite(this._slideWidth);
2028         slide["widget"].resizeHeightComposite(height - 13);
2029     }
2030     this.resize(width, height);
2031 
2032     this._positionArrowLeft(this._leftArrow);
2033     this._positionArrowLeft(this._leftArrowDisabled);
2034     this._positionArrowRight(this._rightArrow);
2035     this._positionArrowRight(this._rightArrowDisabled);
2036 };
2037 
2038 /** @private */
2039 gtk.Slider.prototype._getSlideWidth = function(width){
2040     width = ( (width - this._marginLeft * 2) - ( (this._visibleColumns - 1) * this._spacing) - this._visibleColumns * 2) / this._visibleColumns;
2041     return width;
2042 };
2043 
2044 /** @private */
2045 gtk.Slider.prototype.resize = function(width, height){
2046     this._resizeWidth(width);
2047     this._resizeHeight(height);
2048 };
2049 
2050 /** @private */
2051 gtk.Slider.prototype._resizeElement = function(element, width, height){
2052     element.style.width = width + "px";
2053     element.style.height= height + "px";
2054 };
2055 
2056 /** @private */
2057 gtk.Slider.prototype._constructSpace = function(){
2058     var space = jsgtk.Dom.create({"append": this._slidesContainer, "tag": "div", "style": "float: left;"});
2059     return space;
2060 };
2061 
2062 /** @private */
2063 gtk.Slider.prototype._constructSlide = function(scrolledWindow){
2064     var slide = jsgtk.Dom.create({"append": this._slidesContainer, "tag": "div", "class": "gtk_slider_slide", "style": "float: left;"});
2065     slide.appendChild(scrolledWindow._domObj);
2066 	var closeButton = jsgtk.Dom.create({"append": slide, "tag": "div", "class": "gtk_slider_close_button"});
2067 	jsgtk.Dom.hideElement(closeButton);
2068     return slide;
2069 };
2070 
2071 /** @private */
2072 gtk.Slider.prototype._getScroller = function(widget){
2073     var scroller = new gtk.Scroller();
2074     scroller.show();
2075     scroller.appendChild(widget, true);
2076     scroller.disableHScrolled();
2077 
2078     return scroller;
2079 };
2080 
2081 /** @private */
2082 gtk.Slider.prototype._moveRight = function(){
2083     var self = this;
2084     var left = this._currentLeft - (this._slideWidth + this._spacing + 2);
2085 
2086     var intervalID = window.setInterval(function(){
2087         self._currentLeft -= 20;
2088         self._isMoving = true;
2089         self._viewport.scrollLeft = self._currentLeft;
2090 
2091         if(self._currentLeft <= left){
2092             self._viewport.scrollLeft = left;
2093             self._currentLeft = left;
2094             clearInterval(intervalID);
2095             self._enableRightArrow();
2096             if(self._viewport.scrollLeft === 0) self._disableRightArrow();
2097             self._isMoving = false;
2098         }
2099     }, 10);
2100 };
2101 
2102 /** @private */
2103 gtk.Slider.prototype._moveLeft = function(){
2104 
2105     var self = this;
2106     var left = this._currentLeft + this._slideWidth + this._spacing + 2;
2107 
2108     var intervalID = window.setInterval(function(){
2109         self._currentLeft += 20;
2110         self._viewport.scrollLeft = self._currentLeft;
2111         self._isMoving = true;
2112         if(self._currentLeft >= left){
2113             self._viewport.scrollLeft = left;
2114             self._currentLeft = left;
2115 
2116             self._enableLeftArrow();
2117 
2118             var actualSlideWidth = self._slideWidth + self._spacing + 2;
2119             var width = Math.floor(self._slideWidths - self._viewport.scrollLeft);
2120             if(width <= actualSlideWidth * self._visibleColumns) self._disableLeftArrow();
2121             clearInterval(intervalID);
2122 
2123             self._isMoving = false;
2124         }
2125     }, 10);
2126 };
2127 
2128 /** @private */
2129 gtk.Slider.prototype._positionArrowLeft = function(leftArrow){
2130 	var leftArrowStyle = leftArrow.style;
2131     leftArrowStyle.width  = this._arrowWidth + "px";
2132     leftArrowStyle.height = this._arrowHeight + "px";
2133     leftArrowStyle.top = this._height / 2 - this._arrowHeight/2 + "px";
2134     leftArrowStyle.left = "16px";
2135 };
2136 
2137 /** @private */
2138 gtk.Slider.prototype._positionArrowRight = function(rightArrow){
2139 	var rightArrowStyle = rightArrow.style;
2140     rightArrowStyle.width  = this._arrowWidth + "px";
2141     rightArrowStyle.height = this._arrowHeight + "px";
2142     rightArrowStyle.top = this._height / 2 - this._arrowHeight/2 + "px";
2143     rightArrowStyle.right = "8px";
2144 };
2145 
2146 /** @private */
2147 gtk.Slider.prototype._enableRightArrow = function(){
2148 	var jsgtkDom = jsgtk.Dom;
2149     jsgtkDom.hideElement(this._rightArrowDisabled);
2150     jsgtkDom.showElement(this._rightArrow);
2151 };
2152 
2153 /** @private */
2154 gtk.Slider.prototype._disableRightArrow = function(){
2155 	var jsgtkDom = jsgtk.Dom;
2156     jsgtkDom.hideElement(this._leftArrow);
2157     jsgtkDom.showElement(this._leftArrowDisabled);
2158 };
2159 
2160 /** @private */
2161 gtk.Slider.prototype._enableLeftArrow = function(){
2162 	var jsgtkDom = jsgtk.Dom;
2163     jsgtkDom.hideElement(this._leftArrowDisabled);
2164     jsgtkDom.showElement(this._leftArrow);
2165 };
2166 
2167 /** @private */
2168 gtk.Slider.prototype._disableLeftArrow = function(){
2169 	var jsgtkDom = jsgtk.Dom;
2170     jsgtkDom.showElement(this._rightArrowDisabled);
2171     jsgtkDom.hideElement(this._rightArrow);
2172 };
2173 
2174 /** @private */
2175 gtk.Slider.prototype._resizeWidth = function(width){
2176     this._width = width;
2177     this._domObj.style.width  = this._width + "px";
2178     this._viewport.style.width = this._width  - this._marginLeft * 2 + 6 + "px";
2179     this._slidesContainer.style.width = this._slideWidths + "px";
2180 };
2181 
2182 /** @private */
2183 gtk.Slider.prototype._resizeHeight= function(height){
2184     this._height = height;
2185     this._viewport.style.height= this._height + 25 + "px";
2186     this._domObj.style.height = this._height + "px";
2187     this._slidesContainer.style.height = this._height + "px";
2188 };
2189 
2190 /** @private */
2191 gtk.Slider.prototype.getMinHeightComposite = function(){
2192     return this._minHeight;
2193 };
2194 
2195 /** @private */
2196 gtk.Slider.prototype.getMinWidthComposite = function(){
2197     return this._minWidth;
2198 };
2199 
2200 /** @private */
2201 gtk.Slider.prototype.resizeWidthComposite = function(width){
2202 	var minWidthComposite = this.getMinWidthComposite();
2203 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
2204 	this._resizeSlides(minWidth, this._height);
2205 };
2206 
2207 /** @private */
2208 gtk.Slider.prototype.resizeHeightComposite = function(height){
2209 	var minHeightComposite = this.getMinHeightComposite();
2210 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
2211 	this._resizeSlides(this._width, minHeight);
2212 };
2213 /**
2214  * A single line text entry field
2215  * @constructor
2216  * @param {String} maxLength The maximum length of the entry
2217  */
2218 gtk.Entry = function(maxLength){
2219 	gtk.Widget.apply(this);
2220 
2221 	/** 'keypressed' signal */
2222 	this.ENTRY_KEYPRESSED = "keypressed";
2223 	/** 'enterkeypressed' signal */
2224 	this.ENTRY_ENTERKEYPRESSED = "enterkeypressed";
2225 	/** 'focused' signal */
2226 	this.ENTRY_FOCUSED = "focused";
2227 	/** 'blurred' signal */
2228 	this.ENTRY_BLURRED = "blurred";
2229 	/** 'changed' signal */
2230 	this.ENTRY_CHANGED = "changed";
2231 	/** 'clicked' signal */
2232 	this.ENTRY_CLICKED = "clicked";
2233 
2234     var self 				= this;
2235 	this._dom 				= null;
2236 	this._text 				= "";
2237 	this._maxLength 		= maxLength || "";
2238 	this._width 			= this._minWidth = 60;
2239 	this._height 			= this._minHeight = 18;
2240 	this._widthChars;
2241 	this._span;
2242 	this._visible 			= true;
2243 	this._entryFirstValue 	= "";
2244 	this._showError 		= true;
2245 
2246 	/** @private */
2247 	this._render = function(){
2248 		var _self = this;
2249 		this._domObj.className += " gtk_entry";
2250 			this._span = jsgtk.Dom.create({append: this._domObj, tag: "span"});
2251 				this._dom = jsgtk.Dom.create({append: this._span, tag: "input", "className":"gtk_entry_input", type: "text", style:"border:0;"});
2252 
2253         this.resize(this._width, this._height);
2254 
2255 	};
2256 
2257 	this._render();
2258 
2259 	this._initEvent();
2260 };
2261 
2262 gtk.Entry.prototype = new gtk.Widget();
2263 gtk.Entry.prototype.constructor = gtk.Entry;
2264 
2265 /** @private */
2266 gtk.Entry.prototype._initEvent = function(){
2267 	var self = this;
2268 	var jsgtkEvent = jsgtk.Event;
2269 
2270 	jsgtkEvent.addDomListener(this._dom, "keyup", function(e){
2271         if(e.keyCode === gtk.ENTER_KEY){
2272         	self.emit("enterkeypressed", self._dom.value, e);
2273         	return;
2274         }
2275         if(self._dom.value != self._entryFirstValue){
2276 			self.emit("changed", self._dom.value);
2277         }
2278 
2279         self.emit("keypressed", self._dom.value, e);
2280 	    jsgtkEvent.stopBubble(e);
2281 	}, false);
2282 
2283 	jsgtkEvent.addDomListener(this._span, "click", function(){
2284 	    self._dom.focus();
2285 	    self.emit("clicked", self._dom.value);
2286 	});
2287 
2288 	jsgtkEvent.addDomListener(this._dom, "keypress", function(){
2289 	    self._entryFirstValue = self._dom.value;
2290 	});
2291 
2292 	jsgtkEvent.addDomListener(this._dom, "focus", function(e){
2293 	    self.emit("focused", self._dom.value, e);
2294 	    self._domObj.style.border = "1px groove #F9CF06";
2295 	    if(self._label) self._label.style.display = "none";
2296 	});
2297 
2298 	jsgtkEvent.addDomListener(this._dom, "blur", function(e){
2299 	    self.emit("blurred", self._dom.value, e);
2300 	    self._domObj.style.border = "";
2301 	    if(self._label) if(!self._dom.value) self._label.style.display = "";
2302 	}, false);
2303 };
2304 
2305 
2306 /**
2307  * Focus the cursor in the entry
2308  */
2309 gtk.Entry.prototype.setFocus = function(){
2310     this._dom.focus();
2311 };
2312 
2313 /**
2314  * Method to show error or not
2315  * @param {Boolean} isOnError to show error, false to hide
2316  */
2317 gtk.Entry.prototype.showError = function(isOnError){
2318 	this._showError = (typeof isOnError !== 'undefined' && typeof isOnError === 'boolean') ? isOnError : true;
2319     if(this._showError) this._domObj.className += " gtk_entry_onerror";
2320     else this._domObj.className = "gtk_widget gtk_entry";
2321 };
2322 
2323 /**
2324  * Method to set tab index value
2325  * @param {Integer} index integer value to be set
2326  */
2327 gtk.Entry.prototype.setTabindex = function(index){
2328     this._dom.tabIndex = index;
2329 };
2330 /**
2331  * @depricate
2332  */
2333 gtk.Entry.prototype.setTextSelectable = function(isSelectable){
2334     if(isSelectable){
2335 		this.activateTextSelectable();
2336 		console.log("gtk.Entry.setTextSelectable() will be depricated, please use gtk.Entry.activateTextSelectable()")
2337 	}else{
2338 		this.deactivateTextSelectable();
2339 		console.log("gtk.Entry.setTextSelectable() will be depricated, please use gtk.Entry.deactivateTextSelectable()")
2340 	}
2341 };
2342 
2343 /** make gtk.Entry selectabe*/
2344 gtk.Entry.prototype.activateTextSelectable = function(){this._dom.className = ""};
2345 
2346 /** make gtk.Entry unselectable*/
2347 gtk.Entry.prototype.deactivateTextSelectable = function(){this._dom.className = "gtk_entry_non_selectable"};
2348 
2349 /**
2350  * set the entry border to be visible or invisible
2351  * @param {Boolean} isBorderVisible If true, the entry border is visible. If false, the entry border is invisible
2352  */
2353 gtk.Entry.prototype.setBorderVisible = function(isBorderVisible){
2354     this._domObj.style.borderColor = isBorderVisible ? "1px solid grey" : "transparent";
2355 	console.log("gtk.Entry.setBorderVisible() will be depricated, please use gtk.Entry.showBorder() or gtk.Entry.hideBorder()");
2356 };
2357 
2358 gtk.Entry.prototype.showBorder = function(){this._domObj.style.borderColor = "1px solid grey"};
2359 gtk.Entry.prototype.hideBorder = function(){this._domObj.style.borderColor = "transparent"};
2360 
2361 /**
2362  * Sets the "text" property to the value of text. The string in text replaces the current contents of the entry.
2363  * @param {String} text A string to use as the new contents of the entry
2364  */
2365 gtk.Entry.prototype.setText = function(text){
2366 	this._text = text;
2367 	this._dom.value = text === undefined ? "" : this._text;
2368 
2369 	if(this._label) this._removeLabel();
2370 
2371 	this.emit("changed");
2372 };
2373 
2374 gtk.Entry.prototype._removeLabel = function(){
2375 	this._span.removeChild(this._label);
2376 	this._label = null;
2377 };
2378 
2379 /**
2380  * Returns the value of the "text" property which is a string containing the contents of the entry.
2381  * @return {String} text the content of the entry as a string
2382  */
2383 gtk.Entry.prototype.getText = function(){
2384 	return this._dom.value;
2385 };
2386 
2387 /**
2388  * sets the "width-chars" property to the value of n_char
2389  * @param {interger} nChars Width in chars
2390  */
2391 gtk.Entry.prototype.setWidthChars = function(nChars){
2392  	this._widthChars = nChars;
2393  	this._updateWidthHeight(nChars);
2394     this._resizeWidth(this._width);
2395 };
2396 
2397 /**
2398  * gets the value of the "widthChars" property which is set by the setWidthChars() method
2399  * @return {integer} number of chars to request space for
2400  */
2401 gtk.Entry.prototype.getWidthChars = function(){
2402 	return this._widthChars;
2403 };
2404 
2405 /**
2406  * sets the "max-length" property to the value of max
2407  * @param {interger} max The maximum length of the entry. The value passed in will be clamped to the range 0-65536.
2408  */
2409 gtk.Entry.prototype.setMaxLength = function(max){
2410  	this._maxLength = max;
2411  	this._dom.setAttribute("maxlength", max);
2412 };
2413 
2414 /**
2415  * retrieves the value of the "max-length" property that specifies the maximum allowed length of the text in the entry.
2416  * @return {integer} The maximum allowed number of characters
2417  */
2418 gtk.Entry.prototype.getMaxLength = function(){
2419 	return this._maxLength;
2420 };
2421 
2422 /**
2423  * sets the "visibility" property to the value of visible. If visible is True  the contents of the entry are displayed as plain text. If visible is False, the contents are obscured by replacing the characters with the invisible character
2424  * @param {boolean} visible If False the contents are obscured using the "invisible-char"
2425  */
2426 gtk.Entry.prototype.setVisibility = function(visible){
2427  	this._visible = visible;
2428  	this._visible? this._dom.setAttribute("type", "text"): this._dom.setAttribute("type", "password");
2429 };
2430 
2431 /**
2432  * retrieves the value of the "visibility" property that determines whether the text in entry is visible.
2433  * @return {boolean} True if the text is currently visible
2434  */
2435 gtk.Entry.prototype.getVisibility = function(){
2436 	return this._visible;
2437 };
2438 
2439 /**
2440  * Retrieves the current length of the text in entry
2441  * @return {interger} Return the current number of characters in GtkEntry, or 0 if there are none.
2442  */
2443 gtk.Entry.prototype.getTextLength = function(){
2444 	var charLength = this._dom.value.length;
2445 	return charLength;
2446 };
2447 
2448 /** @private */
2449 gtk.Entry.prototype._updateWidthHeight = function(size){
2450 	var input = this._dom.cloneNode(true);
2451 	if(size){
2452 		var inputStyle = input.style;
2453 		input.setAttribute("size", size);
2454 		inputStyle.width = "";
2455 	}
2456 	document.body.appendChild(input);
2457 	this._width = input.clientWidth;
2458     this._minWidth = this._width;
2459 	document.body.removeChild(input);
2460 };
2461 
2462 /**
2463  * Set the displayed label in Entry. When the entry is focus, the label will be remove from entry
2464  * @param {String} label The label to be displayed in entry
2465  */
2466 gtk.Entry.prototype.setDisplayLabel = function(label){
2467 	if(this._label) this._label.innerHTML = label || "";
2468     else this._label = jsgtk.Dom.create({"tag": "span", "append": this._span, "className": "gtk_entry_label", "text": label});
2469 };
2470 
2471 /**
2472  * Method to select text in entry
2473  */
2474 gtk.Entry.prototype.select = function(){
2475     this._dom.select();
2476 };
2477 
2478 /**
2479 * Entry will be enabled or disabled
2480 * @param {boolean} isEnabled
2481 */
2482 gtk.Entry.prototype.setEnable = function(isEnabled){
2483 	isEnabled ? this.enable() : this.disable();
2484 };
2485 
2486 /**
2487  *  enable gtk.Entry
2488  */
2489 gtk.Entry.prototype.enable = function(){
2490     this._dom.disabled = false;
2491     this._domObj.style.backgroundColor = "";
2492     this._dom.style.backgroundColor = "";
2493 };
2494 
2495 /**
2496  * disable gtk.Entry
2497  */
2498 gtk.Entry.prototype.disable = function(){
2499     this._dom.disabled = true;
2500     this._dom.style.width = parseInt(this._domObj.style.width) - 4  + "px";
2501     this._domObj.style.backgroundColor = "#EDECEC";
2502     this._dom.style.backgroundColor = "#EDECEC";
2503 };
2504 
2505 /** @private */
2506 gtk.Entry.prototype.getMinWidthComposite = function(){
2507 	return this._minWidth;
2508 };
2509 
2510 /** @private */
2511 gtk.Entry.prototype.getMinHeightComposite = function(){
2512 	return this._minHeight;
2513 };
2514 
2515 /** @private */
2516 gtk.Entry.prototype.resetMinHeightComposite = function(){
2517 	var minSize = this.getSizeRequest();
2518 	this.setHeight(minSize[1]);
2519 };
2520 
2521 /** @private */
2522 gtk.Entry.prototype.resetMinWidthComposite = function(){
2523 	var minSize = this.getSizeRequest();
2524 	this.setWidth(minSize[0]);
2525 };
2526 
2527 /** @private */
2528 gtk.Entry.prototype.resize = function(width, height){
2529     this._resizeWidth(width);
2530     this._resizeHeight(height);
2531 };
2532 
2533 /** @private */
2534 gtk.Entry.prototype._resizeWidth = function(width){
2535 	this._domObj.style.width = width - 2 + "px";
2536 	this._dom.style.width = width - 8 + 'px';
2537 	this._width = width;
2538 };
2539 /** @private */
2540 gtk.Entry.prototype._resizeHeight = function(height){
2541    	this._domObj.style.height = height + "px";
2542    	this._dom.style.height = height - 2 + "px";
2543 	this._span.style.lineHeight = height + "px";
2544 	this._height = height;
2545 };
2546 
2547 /** @private */
2548 gtk.Entry.prototype._resizeHeightByFont = function(height){
2549     this._height = this._minHeight = height;
2550    	this._domObj.style.height = height + "px";
2551    	this._dom.style.height = height - 2 + "px";
2552 	this._span.style.lineHeight = height + "px";
2553 };
2554 
2555 /**
2556  * Reset height by font size
2557  * @param {Interger} size The size of font in pixel
2558  */
2559 gtk.Entry.prototype.resizeEntryByFont = function(size){
2560     this._dom.style.fontSize = size + "px";
2561 	var tmpNode = this._dom.cloneNode(true);
2562 	var tempStyle = tmpNode.style;
2563 	tempStyle.fontSize = size + "px";
2564 	tempStyle.width = "";
2565 	tempStyle.height = "";
2566 	var height = jsgtk.Util.fullHeight(tmpNode);
2567     this._resizeHeightByFont(height);
2568 };
2569 
2570 /** @private */
2571 gtk.Entry.prototype.resizeWidthComposite = function(width){
2572     this._width = width;
2573 	this._resizeWidth(width);
2574 };
2575 
2576 /** @private */
2577 gtk.Entry.prototype.resizeHeightComposite = function(height){
2578     this._height = height;
2579 	this._resizeHeight(height);
2580 };
2581 
2582 gobject.signalNew("keypressed", gtk.Entry, null, null, []);
2583 gobject.signalNew("enterkeypressed", gtk.Entry, null, null, []);
2584 gobject.signalNew("focused", gtk.Entry, null, null, []);
2585 gobject.signalNew("blurred", gtk.Entry, null, null, []);
2586 gobject.signalNew("changed", gtk.Entry, null, null, []);
2587 gobject.signalNew("clicked", gtk.Entry, null, null, []);
2588 /**
2589  * EntryDropDown is a class to create a text entry dropdown or text entry with auto suggestion.
2590  * The EntryDropDown store data as a model from gtk.TreeStore
2591  * @constructor
2592  * @param {Integer} maximum length of characters
2593  * @extends gtk.Entry
2594  * @see gtk.TreeStore
2595  */
2596 gtk.EntryDropDown = function(maxLength){
2597 	gtk.Entry.apply(this, [maxLength]);
2598 
2599 	/** 'selected' signal */
2600 	this.ENTRYDROPDOWN_SELECTED = "selected";
2601 
2602 	this._selectedRowText = "";
2603 	this._selectRowIndex = 0;
2604 	this._filteredData = [];
2605 	this._selectedRowValue = null;
2606 	this._hasScroller = false;
2607 	/** @private */
2608 	this._render = function(){
2609 		var _self = this;
2610 		this._domObj.className += " gtk_entry_drop_down";
2611 
2612 		this.__dropDown = jsgtk.Dom.create({tag: "div", className: "gtk_entry_drop_down_holder", append: document.body});
2613 		this._hideDropDown();
2614 	};
2615 
2616 	this._render();
2617 	this._bindInputEvent();
2618 	this._bindDropDownEvent();
2619 };
2620 
2621 gtk.EntryDropDown.prototype = new gtk.Entry();
2622 gtk.EntryDropDown.prototype.constructor = gtk.EntryDropDown;
2623 
2624 /**
2625  * A method to set selected item by any value
2626  * @param {String} key to search for
2627  * @param {any type} value that will match the value of given key
2628  */
2629 gtk.EntryDropDown.prototype.setSelectedItemBy = function(valueMember, value){
2630 	this.emit("_searchModelByValueMember", valueMember, value);
2631 };
2632 
2633 /** @private */
2634 gtk.EntryDropDown.prototype._bindDropDownEvent = function(){
2635 	var self = this;
2636 	var jsgtkEvent = jsgtk.Event;
2637 
2638 	jsgtkEvent.addDomListener(this.__dropDown, "click", function(e){
2639 		var node = e.target;
2640 		if(/gtk_entry_drop_down_element/.test(node.className)){
2641 			self.emit("_searchbypath", self._selectedRowNode.id);
2642         }
2643         jsgtkEvent.stopBubble(e);
2644 	});
2645 
2646 	jsgtkEvent.addDomListener(this.__dropDown, "mouseover", function(e){
2647 		var node = e.target;
2648         if(/gtk_entry_drop_down_element/.test(node.className)){
2649             self._deHilightRow(self._selectedRowNode);
2650 		    self._selectedRowNode = node;
2651 		    self._hilightRow(node);
2652 		    self._selectRowIndex = self._getSelectedIndex(node);
2653         }
2654         node.className += " gtk_entry_drop_down_hover";
2655 	});
2656 
2657 	jsgtkEvent.addDomListener(document.body, "click", function(e){
2658 		self._hideDropDown();
2659 		jsgtkEvent.stopBubble(e);
2660 	});
2661 };
2662 
2663 /**
2664  * Set model to Entry
2665  * @param {gtk.ListStore} model ListStore model to be set to Entry
2666  */
2667 gtk.EntryDropDown.prototype.setModel = function(model){
2668 	this._model = model;
2669 	new gtk.EntryDropDownController(this, model);
2670 };
2671 
2672 /** @private */
2673 gtk.EntryDropDown.prototype._constructRowNode = function(data){
2674 	this._filteredData  = data;
2675 	var docFragment = document.createDocumentFragment();
2676     for(var i = 0; i < data.length; i++){
2677 		var dataObj = data[i]
2678         var element = jsgtk.Dom.create({tag: "div", append: docFragment, text: dataObj["display"], className: "gtk_entry_drop_down_element"});
2679         element.id = dataObj.path;
2680 	}
2681 	return docFragment;
2682 };
2683 
2684 gtk.EntryDropDown.prototype._renderDropDown = function(data){
2685 	var rowsNode = this._constructRowNode(data);
2686 	this._appendToDropDown(rowsNode);
2687 };
2688 
2689 /** @private */
2690 gtk.EntryDropDown.prototype._appendToDropDown = function(dropDown){
2691 	this.__dropDown.innerHTML = "";
2692 	if(dropDown.textContent != "")
2693 	    this.__dropDown.appendChild(dropDown);
2694 	else this._hideDropDown();
2695 };
2696 
2697 /** @private */
2698 gtk.EntryDropDown.prototype._deHilightRow = function(selectedRow){
2699 	if(selectedRow) selectedRow.className = "gtk_entry_drop_down_element";
2700 };
2701 
2702 /** @private */
2703 gtk.EntryDropDown.prototype._hilightRow = function(selectedRow){
2704 	if(selectedRow) selectedRow.className += " gtk_entry_drop_down_selected";
2705 };
2706 
2707 /** @private */
2708 gtk.EntryDropDown.prototype._hilightRowByDownArrowKey = function(){
2709 	if(this._selectedRowNode !==  null){
2710 	    if(this._selectedRowNode.nextSibling === null){
2711 	        this._deHilightRow(this._selectedRowNode);
2712 	        this._selectedRowNode = this.__dropDown.childNodes[0];
2713 	        this._selectRowIndex = 0;
2714 	    }
2715 	    else{
2716 	        this._deHilightRow(this._selectedRowNode);
2717 	        this._selectedRowNode = this._selectedRowNode.nextSibling;
2718 	        this._selectRowIndex = this._selectRowIndex + 1;
2719 	    }
2720 	    this._selectedRowNode.className += " gtk_entry_drop_down_selected";
2721 	}
2722 	else{
2723 	    this._selectedRowNode = this.__dropDown.childNodes[0];
2724 	    this._selectRowIndex = 0;
2725 	    this._selectedRowNode.className += " gtk_entry_drop_down_selected";
2726 	}
2727 };
2728 
2729 /** @private */
2730 gtk.EntryDropDown.prototype._hilightRowByUpArrowKey = function(){
2731 	if(this._selectedRowNode !==  null){
2732 	    if(this._selectedRowNode.previousSibling === null){
2733 	        this._deHilightRow(this._selectedRowNode);
2734 	        this._selectedRowNode = this.__dropDown.lastChild;
2735 	        this._selectRowIndex = this.__dropDown.childNodes.length - 1;
2736 	    }
2737 	    else{
2738 	        this._deHilightRow(this._selectedRowNode);
2739 	        this._selectedRowNode = this._selectedRowNode.previousSibling;
2740 	        this._selectRowIndex = this._selectRowIndex - 1;
2741 	    }
2742 	    this._selectedRowNode.className += " gtk_entry_drop_down_selected";
2743 	}
2744 	else{
2745 	    this._selectedRowNode = this.__dropDown.lastChild;
2746 	    this._selectRowIndex = this.__dropDown.childNodes.length - 1;
2747 	    this._selectedRowNode.className += " gtk_entry_drop_down_selected";
2748 	}
2749 };
2750 
2751 /** @private */
2752 gtk.EntryDropDown.prototype._bindInputEvent = function(){
2753 	var jsgtkEvent = jsgtk.Event;
2754     var self = this;
2755 
2756     var entry = this._domObj.firstChild.firstChild;
2757 	jsgtkEvent.addDomListener(entry, "keydown", function(e){
2758         var keyInCode = e.keyCode;
2759 		switch(keyInCode){
2760 			case gtk.DOWN_ARROW_KEY:
2761 			    self._changeSelectedByArrowDown();
2762 				return;
2763 			case gtk.UP_ARROW_KEY:
2764 			    self._changeSelectedByArrowUp();
2765 				return;
2766 			case gtk.ESC_KEY:
2767                 self._hideDropDown();
2768 				return;
2769 			case gtk.TAB_KEY:
2770                 if(self._selectedRowNode) self.emit("_searchbypath", self._selectedRowNode.id);
2771 				return;
2772 			case gtk.ENTER_KEY:
2773 				if(self._selectedRowNode) self.emit("_searchbypath", self._selectedRowNode.id);
2774 				jsgtkEvent.stopBubble(e);
2775 				return;
2776 		}
2777 
2778 	});
2779 
2780 	this.connect("changed", function(value){
2781 	    self._selectedRowNode = null;
2782 	    self._selectedRowValue = null;
2783         self._showDropDown();
2784         self.emit("_modelfiltered", value);
2785 	});
2786 };
2787 
2788 /** @private */
2789 gtk.EntryDropDown.prototype._scrollByArroyKey = function(index){
2790     if(index == 0) this.__dropDown.scrollTop = 0;
2791     else this.__dropDown.scrollTop = index * 20 - 20;
2792 };
2793 
2794 /** @private */
2795 gtk.EntryDropDown.prototype._changeSelectedByArrowUp = function(){
2796         if(this._filteredData.length > 0){
2797         	this._scrollByArroyKey(this._selectRowIndex);
2798             this._showDropDown();
2799             this._hilightRowByUpArrowKey();
2800 		    this.setText(this._selectedRowNode.textContent);
2801         }
2802 
2803 };
2804 
2805 /** @private */
2806 gtk.EntryDropDown.prototype._changeSelectedByArrowDown = function(){
2807     if(this._filteredData.length > 0){
2808     	this._scrollByArroyKey(this._selectRowIndex);
2809         this._showDropDown();
2810 	    this._hilightRowByDownArrowKey();
2811 	    this.setText(this._selectedRowNode.textContent);
2812     }
2813 };
2814 
2815 /** @private */
2816 gtk.EntryDropDown.prototype._getSelectedIndex = function(){
2817 	var tempNodes = this.__dropDown.cloneNode(true).childNodes;
2818 	var found = false;
2819 	for(var i = 0, len = tempNodes.length; i < len; i++){
2820 		if(/gtk_entry_drop_down_selected/.test(tempNodes[i].className))
2821 			break;
2822 	}
2823 	return i;
2824 };
2825 
2826 /**
2827  * Set display default value into EntryDropDown
2828  * @param {String} text value to be set
2829  */
2830 gtk.EntryDropDown.prototype.setText = function(text){
2831     var input = this._domObj.firstChild.firstChild;
2832 	input.value = text === undefined ? "" : text;
2833 };
2834 
2835 /**
2836 * Return the text display in gtk.Entry
2837 * @return {string} text
2838 */
2839 gtk.EntryDropDown.prototype.getText = function(text){
2840     return this._domObj.firstChild.firstChild.value;
2841 };
2842 
2843 /**
2844  * Set selected value to display by default
2845  * @param {Integer} index an integer value to be passed
2846  */
2847 gtk.EntryDropDown.prototype.setSelectedIndex = function(index){
2848 	this.emit("_searchbyindex", index);
2849 };
2850 
2851 /** @private */
2852 gtk.EntryDropDown.prototype._setSelectedRowValue = function(value){
2853 	this._selectedRowValue = value;
2854 };
2855 
2856 /**
2857  *  Method to get/return an object of selected row value
2858  *  @param {Object}, it return selected object value
2859  */
2860 gtk.EntryDropDown.prototype.getSelectedRowValue = function(){
2861 	return this._selectedRowValue !== null ? this._selectedRowValue : this.getText();
2862 };
2863 
2864 /**
2865  * Get/Return an object valau if exists
2866  */
2867 gtk.EntryDropDown.prototype.getValue = function(){
2868     return this.getSelectedRowValue();
2869 };
2870 
2871 /** @private */
2872 gtk.EntryDropDown.prototype._hideDropDown = function(){
2873 	this.__dropDown.style.display = "none";
2874 	this._selectedRowNode = null;
2875 	this._filteredData  = [];
2876 };
2877 
2878 /** @private */
2879 gtk.EntryDropDown.prototype._showDropDown = function(){
2880     this.__dropDown.style.width = this._width - 2 + "px";
2881     this.__dropDown.style.left = "-1px";
2882     this.__dropDown.style.top = "1px";
2883 	this.__dropDown.style.display = "";
2884 	this._setPosition();
2885 };
2886 /** @private */
2887 gtk.EntryDropDown.prototype._setPosition = function(e){
2888     var top = jsgtk.Util.pageY(this._domObj);
2889     var left = jsgtk.Util.pageX(this._domObj);
2890     var header = parseInt(this._height);
2891     var scrollY = this._getNearestScrollerY();
2892     this.__dropDown.style.top = top + header + 2 - scrollY + "px";
2893     this.__dropDown.style.left = left + "px";
2894 };
2895 
2896 /** @private */
2897 gtk.EntryDropDown.prototype._getNearestScrollerY = function(){
2898     var scrollY = 0;
2899     var parentNode = this._domObj.parentNode;
2900     while(parentNode.parentNode != null){
2901         if(/gtk_scrolled_window/.test(parentNode.className)){
2902             scrollY = parentNode.scrollTop;
2903             this._hasScroller = true;
2904             this._addEventMouseWheel(parentNode);
2905             break;
2906         }
2907         parentNode = parentNode.parentNode;
2908     }
2909     return scrollY;
2910 };
2911 
2912 /** @private */
2913 gtk.EntryDropDown.prototype._addEventMouseWheel = function(scrollObj){
2914     var _self = this;
2915     jsgtk.Event.addDomListener(scrollObj, 'scroll', function(e){
2916 	    _self._hideDropDown();
2917 	}, false);
2918 };
2919 
2920 gobject.signalNew("_searchbyindex", gtk.EntryDropDown, null, null, []);
2921 gobject.signalNew("_searchbypath", gtk.EntryDropDown, null, null, []);
2922 gobject.signalNew("_checkvaluechanged", gtk.EntryDropDown, null, null, []);
2923 gobject.signalNew("_searchModelByValueMember", gtk.EntryDropDown, null, null, []);
2924 gobject.signalNew("_modelfiltered", gtk.EntryDropDown, null, null, []);
2925 gobject.signalNew("selected", gtk.EntryDropDown, null, null, []);
2926 /**
2927  * PopupWindow is a class to create pop-up window to appear on the top most of the screen.
2928  * There are five types: Window Default, Window Confirm, Window Warning, Window Info, and Window Error or Critical
2929  * @param {String} title The header title of the pop-up window
2930  * @param {String} textMessage The body text/content of the pop-up window
2931  * @param {String} type It must be a constant variable to create pop-up window:
2932  * <br>These are the constant values to be passed:
2933  * <br> - gtk.WINDOW_CONFIRM The flag constant value to define as Window Confirm
2934  * <br> - gtk.WINDOW_WARNING The flag constant value to define as Window Warning
2935  * <br> - gtk.WINDOW_INFO The flag constant value to define as Window Info
2936  * <br> - gtk.WINDOW_ERROR The flag constant value to define as Window Error
2937  * <br> - gtk.WINDOW_Default The flag constant value to define as Window Default
2938  * @constructor
2939  */
2940 gtk.PopupWindow = function(title, textMessage, type){
2941     switch (type){
2942 		case gtk.WINDOW_CONFIRM:
2943 			return new gtk.PopupWindowConfirm(title, textMessage);
2944 			break;
2945 		case gtk.WINDOW_WARNING:
2946 			return new gtk.PopupWindowWarning(title, textMessage);
2947 			break;
2948 		case gtk.WINDOW_INFO:
2949 			return new gtk.PopupWindowInfo(title, textMessage);
2950 			break;
2951 		case gtk.WINDOW_ERROR:
2952 			return new gtk.PopupWindowError(title, textMessage);
2953 			break;
2954 		default:
2955 			return new gtk.PopupWindowDefault(title, textMessage);
2956     }
2957 };
2958 /**
2959  * PopupWindowDefault is a class to create pop-up window type Default
2960  * @param {String} title The header title of the pop-up window
2961  * @param {String} textMessage The body text/content of the pop-up window
2962  * @constructor
2963  * @base gtk.Widget
2964  * @extends gtk.Widget
2965  */
2966 gtk.PopupWindowDefault = function(title, textMessage){
2967     gtk.Widget.apply(this);
2968 
2969     this._offsetX;
2970     this._offsetY;
2971     this._title     = title;
2972     this._bodyText  = textMessage;
2973 
2974     this._maxWidth  = 678;
2975     this._maxHeight = 600;
2976     this._width     = this._minWidth = 380;
2977     this._height    = this._minHeight = 130;
2978     this._iconWidth = 0;
2979     this._okBtnHandler = null;
2980     this._closeBtnHandler;
2981 
2982     /** It allows user to connect to a registered signal event "ok" when click OK button */
2983     this.POPUPWINDOWDEFAULT_OK = "";
2984     /** It allows user to connect to a registered signal event "closed" when click close button */
2985     this.POPUPWINDOWDEFAULT_CLOSED = "";
2986 
2987     this._render = function(){
2988 
2989         this._domObj.className += " gtk_popup_window";
2990         this._domObj.style.position = "absolute";
2991             this._header =  jsgtk.Dom.create({"append" : this._domObj, "tag": "div", "className": "gtk_popup_window_header"});
2992                 this._titleDiv = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_title", "append": this._header});
2993                 this._titleDiv.innerHTML = this._title;
2994                 this._closeButton = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_button_close", "append": this._header});
2995 
2996             this._body = jsgtk.Dom.create({"append" : this._domObj, "tag": "div", "className": "gtk_popup_window_body"});
2997                 this._bodyDiv = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_body_text", "append": this._body});
2998                     this._bodyDiv.innerHTML = this._bodyText;
2999 
3000             this._footer = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "className": "gtk_popup_window_footer"});
3001             this._footerButtonOk = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_footer_buttonOk", "append": this._footer});
3002 
3003             this._titleDiv.style.width = this._width - 22 + "px";
3004     };
3005 
3006     this._render();
3007 };
3008 
3009 gtk.PopupWindowDefault.prototype = new gtk.Widget();
3010 gtk.PopupWindowDefault.prototype.constructor = gtk.PopupWindowDefault;
3011 
3012 /**
3013  * A method to set title to the header of the pop-up window
3014  * @param {String} title The title of the pop-up window to be set
3015  * type {String}
3016  */
3017 gtk.PopupWindowDefault.prototype.setTitle = function(title){
3018     this._title = title;
3019     this._resizePopupWindow();
3020 };
3021 
3022 /**
3023  * A method to set content to the body of the pop-up window
3024  * @param {String} textMessage The text content of the body of the pop-up window to be set
3025  * type {String}
3026  */
3027 gtk.PopupWindowDefault.prototype.setBody = function(textMessage){
3028     this._bodyText = textMessage;
3029     this._bodyDiv.innerHTML = this._bodyText;
3030     this._resizePopupWindow();
3031 };
3032 
3033 /**
3034  * A method to set focus onto the pop-up window
3035  */
3036 gtk.PopupWindowDefault.prototype.setFocus = function(){
3037     this._domObj.focus();
3038 };
3039 
3040 /**
3041  * A method to display the pop-up window after it is instantiated
3042  */
3043 gtk.PopupWindowDefault.prototype.draw = function(){
3044         this._drawOkButton();
3045         this._resizePopupWindow();
3046         this._setCenterScreen();
3047         this._disableBackground();
3048         this._initEvent();
3049         document.body.appendChild(this._domObj);
3050 };
3051 
3052 /** @private */
3053 gtk.PopupWindowDefault.prototype._drawOkButton = function(){
3054     this._footerButtonOk.innerHTML = "";
3055     var buttonOk = new gtk.Button("OK");
3056     buttonOk.resizeWidthComposite(75);
3057     buttonOk.resizeHeightComposite(22);
3058     this._footerButtonOk.appendChild(buttonOk.getNode());
3059 };
3060 
3061 /** @private */
3062 gtk.PopupWindowDefault.prototype._calculateHeight = function(dom){
3063     var tempDom = dom.cloneNode(true);
3064     tempDom.style.display = "none";
3065     tempDom.style.position = "absolute";
3066 
3067     var height = jsgtk.Util.fullHeight(tempDom);
3068 
3069     return height;
3070 };
3071 
3072 /** @private */
3073 gtk.PopupWindowDefault.prototype._initEvent = function(){
3074     var self = this;
3075     var jsgtkEvent = jsgtk.Event;
3076 
3077     jsgtkEvent.addDomListener(this._header, "mouseover", function(e){
3078         self._enableDrag();
3079         jsgtkEvent.stopBubble(e);
3080     });
3081 
3082     jsgtkEvent.addDomListener(this._header, "mouseout", function(e){
3083         self._disableDrag();
3084     });
3085 
3086     this._closeBtnHandler = jsgtkEvent.addDomListener(this._closeButton, "mouseup", function(e){
3087         self.emit("closed");
3088         self.close();
3089     });
3090 
3091     this._okBtnHandler = jsgtkEvent.addDomListener(this._footerButtonOk, "mouseup", function(){
3092         self.emit("ok");
3093         self.close();
3094     });
3095 };
3096 
3097 /** @private */
3098 gtk.PopupWindowDefault.prototype._detachOkBtnHandler = function(){
3099     jsgtk.Event.removeListener(this._okBtnHandler);
3100     this._okBtnHandler = null;
3101 };
3102 
3103 /** @private */
3104 gtk.PopupWindowDefault.prototype._detachCloseBtnHandler = function(){
3105     jsgtk.Event.removeListener(this._closeBtnHandler);
3106     this._closeBtnHandler = null;
3107 };
3108 
3109 /**
3110  * A method to close/remove pop-up window
3111  */
3112 gtk.PopupWindowDefault.prototype.close = function(){
3113     if(!this._domObj.parentNode) return;
3114     this._domObj.parentNode.removeChild(this._domObj);
3115     this._disableDiv.parentNode.removeChild(this._disableDiv);
3116     this._detachOkBtnHandler();
3117     this._detachCloseBtnHandler();
3118 
3119 };
3120 
3121 /** @private */
3122 gtk.PopupWindowDefault.prototype._resizeWidth = function(width){
3123     this._width = width;
3124     this._domObj.style.width = width + "px";
3125         this._header.style.width = width + "px";
3126         this._bodyDiv.style.width = width - this._iconWidth + "px";
3127         this._titleDiv.innerHTML = this._title;
3128         this._titleDiv.style.width = this._width - 32 + "px";
3129 };
3130 
3131 /** @private */
3132 gtk.PopupWindowDefault.prototype._resizeHeight = function(height){
3133     this._height = height;
3134     this._domObj.style.height = height + "px";
3135         this._bodyDiv.style.height = height - 62 + "px";
3136 };
3137 
3138 /** @private */
3139 gtk.PopupWindowDefault.prototype._getMaxHeight = function(){
3140     var height = jsgtk.Util.calculateTextWidthHeight(this._bodyText)[1] + 62;
3141     if(height < this._minHeight) height = this._minHeight;
3142     return height;
3143 };
3144 
3145 /** @private */
3146 gtk.PopupWindowDefault.prototype._getMaxWidth = function(){
3147     var width = jsgtk.Util.calculateTextWidthHeight(this._bodyText)[0];
3148     if(width > this._maxWidth - 20) width = this._maxWidth;
3149     else if(width < this._minWidth) width = this._minWidth;
3150     return width;
3151 };
3152 
3153 /** @private */
3154 gtk.PopupWindowDefault.prototype._resizePopupWindow = function(){
3155     this._resizeWidth(this._getMaxWidth());
3156     this._resizeHeight(this._getMaxHeight());
3157 };
3158 
3159 /** @private */
3160 gtk.PopupWindowDefault.prototype._calculateOffsetCenter = function(){
3161     var jsgtkUtil = jsgtk.Util;
3162 
3163     var windowWidth = jsgtkUtil.getWindowWidth();
3164     var windowHeight = jsgtkUtil.getWindowHeight();
3165 
3166     var scrollY = jsgtkUtil.getScrollY();
3167     var scrollX = jsgtkUtil.getScrollX();
3168 
3169     var offsetX =(windowWidth - this._width)/2 + scrollX;
3170     var offsetY =(windowHeight - this._height)/2 + scrollY;
3171     return [offsetX, offsetY];
3172 };
3173 
3174 /** @private */
3175 gtk.PopupWindowDefault.prototype._setCenterScreen = function(){
3176     var offset = this._calculateOffsetCenter();
3177     var domObjStyle = this._domObj.style;
3178     domObjStyle.top = offset[1] + "px";
3179     domObjStyle.left= offset[0] + "px";
3180 };
3181 
3182 /** @private */
3183 gtk.PopupWindowDefault.prototype._disableBackground = function(){
3184     this._disableDiv = jsgtk.Dom.create({"tag": "div", "className": "gtk_disable_body"});
3185     var widthHeight = jsgtk.Util.getPageSize();
3186 
3187     var disableDivStyle = this._disableDiv.style;
3188     disableDivStyle.width = widthHeight[0] + "px";
3189     disableDivStyle.height = widthHeight[1] + "px";
3190     disableDivStyle.opacity = 0.3;
3191     disableDivStyle.backgroundColor = "#ADADAD";
3192 
3193     document.body.appendChild(this._disableDiv);
3194 };
3195 
3196 /** @private */
3197 gtk.PopupWindowDefault.prototype._getMinimizedTitle = function(titleDom, minimizedWidth){
3198 
3199     var tmpNode = titleDom.cloneNode(true);
3200     var title = tmpNode.innerHTML;
3201 
3202     var titleWidth = jsgtk.Util.fullWidth(tmpNode);
3203     if( titleWidth < minimizedWidth){
3204         return title;
3205     }
3206 
3207     var charWidth = 0;
3208     var title = title.replace(/\s+/g,'`');
3209 
3210     for(var i = 0, len = title.length; i < len; i++){
3211         var character = title.substring(i, i+1);
3212         tmpNode.innerHTML = character;
3213         charWidth += jsgtk.Util.fullWidth(tmpNode);
3214 
3215         if(charWidth >= minimizedWidth){
3216             break;
3217         }
3218     }
3219 
3220     var minimizedTitle = title.substring(0, i);
3221     return minimizedTitle.split("`").join(" ") + "...";
3222 };
3223 
3224 /** @private */
3225 gtk.PopupWindowDefault.prototype._enableDrag = function(){
3226     var minX = 1, maxX =jsgtk.Util.getWindowWidth()-this._width - 17;
3227     var minY = 0, maxY = jsgtk.Util.getWindowHeight()-this._height - 17;
3228     jsgtk.Util.DomDraggableAdapter.dragInit(this._domObj, minX, maxX, minY, maxY);
3229 };
3230 
3231 /** @private */
3232 gtk.PopupWindowDefault.prototype._disableDrag = function(){
3233     var minX = maxX = parseInt(this._domObj.style.left);
3234     var minY = maxY = parseInt(this._domObj.style.top);
3235     jsgtk.Util.DomDraggableAdapter.dragInit(this._domObj, minX, maxX, minY, maxY);
3236 };
3237 
3238 gobject.signalNew("ok", gtk.PopupWindowDefault, null, null, []);
3239 gobject.signalNew("closed", gtk.PopupWindowDefault, null, null, []);
3240 /**
3241  * PopupWindowConfirm is a class to create pop-up window type Confirmation
3242  * @param {String} title The header title of the pop-up window
3243  * @param {String} textMessage The body text/content of the pop-up window
3244  * @constructor
3245  * @base gtk.PopupWindowDefault
3246  * @extends gtk.PopupWindowDefault
3247  */
3248 gtk.PopupWindowConfirm = function(title, textMessage){
3249     gtk.PopupWindowDefault.apply(this, [title, textMessage]);
3250     var self = this;
3251     this._iconWidth = 95;
3252     this._cancelBtnHandler = null;
3253     /** It allows user to connect to a registered signal event "cancelled" when click Cancel button */
3254     this.POPUPWINDOWCONFIRM_CANCELLED = "";
3255 
3256     this._render = function(){
3257 
3258         var imageDiv = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_confirm_image"});
3259         this._body.insertBefore(imageDiv,this._bodyDiv);
3260         this._bodyDiv.style.margin = "0px 0px 0px 66px";
3261         this._footerButtonCancel = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_footer_buttonConcel"});
3262     };
3263     this._render();
3264 };
3265 
3266 gtk.PopupWindowConfirm.prototype = new gtk.PopupWindowDefault();
3267 gtk.PopupWindowConfirm.prototype.constructor = gtk.PopupWindowConfirm;
3268 
3269 /**
3270  * A method to display the pop-up window after it is instantiated
3271  */
3272 gtk.PopupWindowConfirm.prototype.draw = function(){
3273         this._drawOkButton();
3274         this._drawCancelButton();
3275         this._resizePopupWindow();
3276         this._setCenterScreen();
3277         this._disableBackground();
3278         this._initEvent();
3279         this._attachCancelBtnEvent();
3280         document.body.appendChild(this._domObj);
3281 };
3282 
3283 /** @private */
3284 gtk.PopupWindowConfirm.prototype._attachCancelBtnEvent = function(){
3285     var self = this;
3286     this._cancelBtnHandler = jsgtk.Event.addDomListener(this._footerButtonCancel, "click", function(){
3287 		self.emit("cancelled");
3288         self.close();
3289     });
3290 };
3291 
3292 /** @private */
3293 gtk.PopupWindowConfirm.prototype._drawCancelButton = function(){
3294         this._footerButtonCancel.innerHTML = "";
3295         var buttonCancel = new gtk.Button("Cancel");
3296             buttonCancel.resizeWidthComposite(75);
3297             buttonCancel.resizeHeightComposite(22);
3298 
3299         this._footerButtonCancel.appendChild(buttonCancel.getNode());
3300         this._footer.insertBefore(this._footerButtonCancel, this._footerButtonOk);
3301 };
3302 
3303 /**
3304  * A method to close/remove pop-up window
3305  */
3306 gtk.PopupWindowConfirm.prototype.close = function(){
3307     if(!this._domObj.parentNode) return;
3308 
3309     this._domObj.parentNode.removeChild(this._domObj);
3310     this._disableDiv.parentNode.removeChild(this._disableDiv);
3311     this._detachOkBtnHandler();
3312     this._detachCancelBtnHandler();
3313     this._detachCloseBtnHandler();
3314 };
3315 
3316 /** @private */
3317 gtk.PopupWindowConfirm.prototype._detachCancelBtnHandler = function(){
3318     jsgtk.Event.removeListener(this._cancelBtnHandler);
3319     this._cancelBtnHandler = null;
3320 };
3321 
3322 gobject.signalNew("cancelled", gtk.PopupWindowConfirm, null, null, []);
3323 /**
3324  * PopupWindowError is a class to create pop-up window type Error
3325  * @param {String} title The header title of the pop-up window
3326  * @param {String} textMessage The body text/content of the pop-up window
3327  * @constructor
3328  * @base gtk.PopupWindowDefault
3329  * @extends gtk.PopupWindowDefault
3330  */
3331 gtk.PopupWindowError = function(title, textMessage){
3332     gtk.PopupWindowDefault.apply(this, [title, textMessage]);
3333     this._iconWidth = 95;
3334 
3335     this._render = function(){
3336         var imageDiv = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_error_image"});
3337         this._body.insertBefore(imageDiv,this._bodyDiv);
3338         this._bodyDiv.style.margin = "0px 0px 0px 66px";
3339     };
3340     this._render();
3341 };
3342 
3343 gtk.PopupWindowError.prototype = new gtk.PopupWindowDefault();
3344 gtk.PopupWindowError.prototype.constructor = gtk.PopupWindowError;
3345 /**
3346  * PopupWindowInfo is a class to create pop-up window type Info
3347  * @param {String} title The header title of the pop-up window
3348  * @param {String} textMessage The body text/content of the pop-up window
3349  * @constructor
3350  * @base gtk.PopupWindowDefault
3351  * @extends gtk.PopupWindowDefault
3352  */
3353 gtk.PopupWindowInfo = function(title, textMessage){
3354     gtk.PopupWindowDefault.apply(this, [title, textMessage]);
3355     this._iconWidth = 95;
3356 
3357     this._render = function(){
3358         var imageDiv = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_info_image"});
3359         this._body.insertBefore(imageDiv,this._bodyDiv);
3360         this._bodyDiv.style.margin = "0px 0px 0px 66px";
3361     };
3362     this._render();
3363 };
3364 
3365 gtk.PopupWindowInfo.prototype = new gtk.PopupWindowDefault();
3366 gtk.PopupWindowInfo.prototype.constructor = gtk.PopupWindowInfo;
3367 /**
3368  * PopupWindowWarning is a class to create pop-up window type Warning
3369  * @param {String} title The header title of the pop-up window
3370  * @param {String} textMessage The body text/content of the pop-up window
3371  * @constructor
3372  * @base gtk.PopupWindowDefault
3373  * @extends gtk.PopupWindowDefault
3374  */
3375 gtk.PopupWindowWarning = function(title, textMessage){
3376     gtk.PopupWindowDefault.apply(this, [title, textMessage]);
3377     this._iconWidth = 95;
3378 
3379     this._render = function(){
3380         var imageDiv = jsgtk.Dom.create({"tag": "div", "className": "gtk_popup_window_warning_image"});
3381         this._body.insertBefore(imageDiv,this._bodyDiv);
3382         this._bodyDiv.style.margin = "0px 0px 0px 66px";
3383     };
3384     this._render();
3385 };
3386 
3387 gtk.PopupWindowWarning.prototype = new gtk.PopupWindowDefault();
3388 gtk.PopupWindowWarning.prototype.constructor = gtk.PopupWindowWarning;
3389 /**
3390  * NullObject is a class to create a null object
3391  * @constructor
3392  */
3393 gtk.NullObject = {
3394 	getMinWidthComposite: function(){},
3395 	getMinHeightComposite: function(){},
3396 	resizeWidthComposite: function(){},
3397 	resizeHeightComposite: function(){}
3398 }
3399 /**
3400  * Panel is a class to create a container called panel
3401  * @param {String} title The header title of the panel
3402  * @param {Integer} padding The integer value of padding of the panel
3403  * @constructor
3404  * @base gtk.Widget
3405  * @extends gtk.Widget
3406  */
3407 gtk.Panel = function(title, padding) {
3408 	gtk.Widget.apply(this);
3409 
3410 	/** 'minimzed' signal */
3411 	this.PANEL_MINIMIZED = "minimized";
3412 	/** 'minimizedpanelmouseovered' signal */
3413 	this.PANEL_MINIMIZEDPANEL_MOUSEOVERED = "minimizedpanelmouseovered";
3414 	/** 'minimizedpanelmouseovered' signal */
3415 	this.PANEL_MINIMIZEDPANEL_MOUSEOUT = "minimizedpanelmouseout";
3416 	/** 'restored' signal */
3417 	this.PANEL_RESTORED = "restored";
3418 	/** 'closed' signal */
3419 	this.PANEL_CLOSED = "closed";
3420 
3421 	this._width               = this._minWidth  = 20;
3422 	this._height              = this._minHeight = 20;
3423 	this._title               = title || "gtk Title";
3424 	this._minimizedWidth      = 150;
3425 	this._inconsWidth         = 45;
3426 	this._headerHeight        = 22;
3427 	this._padding             = padding === undefined ? 10 : padding * 2;
3428 	this._bodyHeight          = this._height - this._headerHeight;
3429 	this._child               = null;
3430 	this._isCloseButtonActive = false;
3431 	this._minimizedPanel      = null;
3432 	var self = this;
3433 	this._createTooltip = false;
3434 
3435 	/** @private */
3436 	this._render = function(){
3437 		var jsgtkDom = jsgtk.Dom;
3438 		var domObj = this._domObj;
3439 
3440 		domObj.id = new UUID().id;
3441 		domObj.className   += " gtk_panel";
3442         domObj.style.position = "absolute";
3443 
3444 		    this._header = jsgtkDom.create({'append': domObj, 'tag': 'div', 'className': 'gtk_panel_header'});
3445     		        this._domTitle = jsgtkDom.create({"append": this._header, "tag": "div", "text": this._title, 'className': 'gtk_none_selectable gtk_panel_header_title'});
3446 
3447                 this._closeButton = jsgtkDom.create({"append": this._header, "tag": "div", "title": "Close Panel","className": "gtk_panel_close_button", "style": "display:none;"});
3448                 this._minimizeButton = jsgtkDom.create({'append': this._header, 'tag': 'div', "title": "Minimize Panel", 'className': 'gtk_panel_minimize_button'});
3449 
3450 		    this._body = jsgtk.Dom.create({'append': domObj, 'tag': 'div', 'className': 'gtk_panel_body'});
3451 	};
3452 
3453     this._render();
3454 
3455     jsgtk.Event.addDomListener(this._minimizeButton, "mousedown", function(e){
3456         self.minimize();
3457         jsgtk.Event.stopBubble(e);
3458     }, false);
3459 };
3460 
3461 gtk.Panel.prototype = new gtk.Widget();
3462 gtk.Panel.prototype.constructor = gtk.Panel;
3463 
3464 /**
3465  * A method to set the top most given a boolean value
3466  * @param {Boolean} isTop The boolean value to be topmost of not
3467  */
3468 gtk.Panel.prototype.setTopMost = function(isTop){
3469     if(isTop) this._domObj.style.zIndex = "1001";
3470     else this._domObj.style.zIndex = "0";
3471 };
3472 
3473 /**
3474  * A method to hide the minimized button from the panel
3475  */
3476 gtk.Panel.prototype.hideMinimizeButton = function(){
3477     this._minimizeButton.style.display = "none";
3478 };
3479 
3480 /** @private */
3481 gtk.Panel.prototype._isNodeExistInMinimizedHolder = function(holder){
3482     var clonedHolder = holder.cloneNode(true);
3483     for(var i = 0, len = clonedHolder.childNodes.length; i < len; i++){
3484         if(this._domObj.id == clonedHolder.childNodes[i].id) return true;
3485     }
3486     return false;
3487 }
3488 
3489 /** @private */
3490 gtk.Panel.prototype._createMinimizedHolder = function(){
3491     var id = "gtk_minimized_widget_holder";
3492     var holder = document.getElementById(id);
3493     if(!holder) var holder = jsgtk.Dom.create({"append": document.body, "tag": "div", "id": id});
3494     return holder;
3495 };
3496 
3497 /**
3498  * A method to call setting the panel to minimized state
3499  */
3500 gtk.Panel.prototype.minimize = function(){
3501     jsgtk.Dom.hideElement(this._domObj);
3502 
3503     var holder = this._createMinimizedHolder();
3504     if(this._isNodeExistInMinimizedHolder(holder)){
3505         jsgtk.Dom.showElement(this._minimizedPanel);
3506         return;
3507     }
3508 
3509     this._minimizedPanel = this._createMinimizedPanel();
3510     holder.appendChild(this._minimizedPanel);
3511 
3512     this._initMinimizedEvents();
3513 };
3514 
3515 /** @private */
3516 gtk.Panel.prototype._initMinimizedEvents = function(){
3517     var self = this;
3518     var jsgtkEvent = jsgtk.Event;
3519 
3520     var restoreButton = this._minimizedPanel.childNodes[2];
3521     jsgtkEvent.addDomListener(restoreButton, "mousedown", function(){
3522 		self.restore();
3523     });
3524 
3525     jsgtkEvent.addDomListener(restoreButton, "mouseover", function(){
3526 		restoreButton.setAttribute("title", "Restore Panel");
3527     });
3528 
3529 	var closeButton = this._minimizedPanel.childNodes[1];
3530 	jsgtkEvent.addDomListener(closeButton, "mousedown", function(e){
3531 	    self._minimizedPanel.parentNode.removeChild(self._minimizedPanel);
3532 	    self.emit("closed", self);
3533 	    jsgtkEvent.stopBubble(e);
3534 	});
3535 
3536 
3537     jsgtkEvent.addDomListener(this._minimizedPanel, "dblclick", function(e){
3538         self.restore();
3539     });
3540     jsgtk.Event.addDomListener(this._minimizedPanel, "mouseover", function(e){
3541         self.emit("minimizedpanelmouseovered", self._title);
3542         jsgtk.Event.stopBubble(e);
3543     });
3544     jsgtk.Event.addDomListener(this._minimizedPanel, "mouseout", function(e){
3545         self.emit("minimizedpanelmouseout", self._title);
3546         jsgtk.Event.stopBubble(e);
3547     });
3548     self.emit('minimized', self);
3549 };
3550 
3551 /**
3552  * A method to justified title of the panel
3553  * @param {String} justify The contant varaiable of gtk
3554  */
3555 gtk.Panel.prototype.setTitleJustify = function(justify){
3556     this._header.childNodes[0].style.textAlign = justify;
3557 };
3558 
3559 /** @private */
3560 gtk.Panel.prototype._isPanelRestored = function(id){
3561     if(!document.getElementById(id)){
3562         this._domObj.id = id;
3563         return true;
3564     }
3565     return false;
3566 };
3567 
3568 /**
3569  * A method to restore the state of the panel to the previsous state
3570  */
3571 gtk.Panel.prototype.restore = function(){
3572     var id = this._domObj.id;
3573     this._domObj.id = "";
3574     if(this._isPanelRestored(id)) return;
3575     this.emit('restored', this);
3576 
3577     jsgtk.Dom.showElement(this._domObj);
3578     this._resizeDomTitleWidth(this._width - this._inconsWidth);
3579 
3580     jsgtk.Dom.hideElement(this._minimizedPanel);
3581     this._domObj.id = id;
3582 };
3583 
3584 gtk.Panel.prototype.setCloseButton = function(isClose){
3585 	isClose ? this.hideCloseButton() : this.showCloseButton();
3586 };
3587 
3588 /** @private */
3589 gtk.Panel.prototype.hideCloseButton = function(){
3590     if(this._closeButton){
3591 		this._closeButton.style.display = "none";
3592 		this._minimizeButton.style.right = "5px";
3593 	}
3594 	else{
3595 		this.hideCloseButton();
3596 	}
3597 };
3598 
3599 /** @private */
3600 gtk.Panel.prototype.showCloseButton = function(){
3601     var self = this,
3602         jsgtkEvent = jsgtk.Event,
3603         jsgtkDom = jsgtk.Dom;
3604 
3605     jsgtkDom.showElement(this._closeButton);
3606 	this._minimizeButton.style.right = "22px";
3607 
3608 	jsgtkEvent.addDomListener(this._closeButton, "click", function(e){
3609 	    self._domObj.parentNode.removeChild(self._domObj);
3610 	    self.emit("closed", self);
3611 	    self._domObj = null;
3612 	    jsgtkEvent.stopBubble(e);
3613 	});
3614 };
3615 
3616 /**
3617  * A method to hide/remove close button from panel
3618  */
3619 gtk.Panel.prototype.hideCloseButton = function(){
3620 	if(this._closeButton){
3621 		this._closeButton.style.display = "none";
3622 		this._minimizeButton.style.right = "5px";
3623 	}
3624 };
3625 
3626 /**
3627  * A method to get/return the title of the panel
3628  * @return {String} The name of the panel
3629  * @type String
3630  */
3631 gtk.Panel.prototype.getTitle = function(){
3632     return this._title;
3633 };
3634 
3635 /**
3636  * A method to append or add a new child into the panel
3637  * @param {Dom} widget The dom widget to be passed for adding
3638  */
3639 gtk.Panel.prototype.appendChild = function(widget){
3640     this._child = widget;
3641     this._child.setParent(this);
3642     this._positionChild(widget.getNode());
3643 
3644     this.resizeHeightComposite(this._height);
3645     this.resizeWidthComposite(this._width);
3646 };
3647 
3648 /** @private */
3649 gtk.Panel.prototype._positionChild = function(childNode){
3650     this._body.appendChild(childNode);
3651     var childNodeStyle = childNode.style;
3652     childNodeStyle.left = this._padding / 2 + "px";
3653     childNodeStyle.top  = this._padding / 2 + "px";
3654 };
3655 
3656 /**
3657  * A method to flush the child inside the panel
3658  */
3659 gtk.Panel.prototype.flushChild = function(){
3660     this._body.removeChild(this._child.getNode());
3661     this._child = null;
3662 };
3663 
3664 /**
3665  * A method to set the panel title to bold
3666  * @param {Boolean} bold The boolean value to display bold or not
3667  */
3668 gtk.Panel.prototype.setBoldTitle = function(bold){
3669 	if(bold){
3670 		this._domTitle.style.fontWeight = "bold";
3671 	} else 	this._domTitle.style.fontWeight = "normal";
3672 };
3673 
3674 /** @private */
3675 gtk.Panel.prototype._resetTitle = function(title){
3676     this._domTitle.innerHTML = title;
3677 };
3678 
3679 /**
3680  * A method to set the new title to the panel
3681  * @param {String} title The string title of the panel
3682  * @param {String} xalign The constant variable of jsgtk
3683  */
3684 gtk.Panel.prototype.setTitle = function(title, xalign){
3685     this._title = title;
3686     var xalign = xalign || 1.0;
3687     this._domTitle.innerHTML = this._title;
3688 };
3689 
3690 /** @private */
3691 gtk.Panel.prototype._resizeDomTitleWidth = function(width){
3692     this._domTitle.style.width = width + "px";
3693 };
3694 
3695 /** @private */
3696 gtk.Panel.prototype._createMinimizedPanel = function(){
3697     this._resizeDomTitleWidth(this._minimizedWidth - this._inconsWidth);
3698 
3699     var minimizePanel = this._header.cloneNode(true);
3700 	minimizePanel.className = "gtk_panel_minimize";
3701     minimizePanel.removeAttribute("style");
3702     minimizePanel.style.width = this._minimizedWidth + "px";
3703     minimizePanel.id = this._domObj.id;
3704 
3705     return minimizePanel;
3706 };
3707 
3708 /** @private */
3709 gtk.Panel.prototype._getSubElementsHeight = function(){
3710     return this._headerHeight + this._subHeaderHeight + this._footerHeight;
3711 };
3712 
3713 /**
3714  * A method to resize both width and height the panel
3715  * @param {Integer} width The integer width value to be set
3716  * @param {Integer} height The integer height value to be set
3717  */
3718 gtk.Panel.prototype.resize = function(width, height){
3719     this._resizeWidth(width);
3720     this._resizeHeight(height);
3721 };
3722 
3723 /** @private */
3724 gtk.Panel.prototype._resizeWidth = function(width){
3725 	this._width = width;
3726 	this._domObj.style.width    = this._width - 2 + 'px';
3727 	    this._domTitle.style.width = this._width - this._inconsWidth + "px";
3728     	this._body.style.width      = this._width - 3 + 'px';
3729 };
3730 
3731 /** @private */
3732 gtk.Panel.prototype._resizeHeight = function(height){
3733 	this._height = height;
3734 	this._bodyHeight = this._height - this._headerHeight;
3735 	this._domObj.style.height    = this._height - 2 + "px";
3736 	this._body.style.height      = this._bodyHeight + "px";
3737 };
3738 
3739 /**
3740  * A method to get/return body height of the panel
3741  * @return {Integer} The body height of the panel
3742  * @type Integer
3743  */
3744 gtk.Panel.prototype.getBodyHeight = function(){
3745     return this._bodyHeight;
3746 };
3747 
3748 /**
3749  * A method to get/return the minimum composite width
3750  * @return {Integer} The minimum composite width of the panel
3751  * @type Integer
3752  */
3753 gtk.Panel.prototype.getMinWidthComposite = function(){
3754     return this._child.getMinWidthComposite() + this._padding;
3755 };
3756 
3757 /**
3758  * A method to get/return the minimum composite height
3759  * @return {Integer} The minimum composite height of the panel
3760  * @type Integer
3761  */
3762 gtk.Panel.prototype.getMinHeightComposite = function(){
3763     return this._child.getMinHeightComposite() + this._headerHeight + this._padding;
3764 };
3765 
3766 /**
3767  * A method to resize its composite width
3768  * @param {Integer} The composite width to be set
3769  */
3770 gtk.Panel.prototype.resizeWidthComposite = function(width){
3771 	var minWidthComposite = this.getMinWidthComposite();
3772 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
3773 	this._child.resizeWidthComposite(minWidth - this._padding);
3774     this._resizeWidth(minWidth);
3775 };
3776 
3777 /**
3778  * A method to resize its composite height
3779  * @param {Integer} The composite height to be set
3780  */
3781 gtk.Panel.prototype.resizeHeightComposite = function(height){
3782 	var minHeightComposite = this.getMinHeightComposite();
3783 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
3784 	this._child.resizeHeightComposite(minHeight - this._padding - this._headerHeight);
3785     this._resizeHeight(minHeight);
3786 };
3787 
3788 gobject.signalNew('minimized', gtk.Panel, [], null, null);
3789 gobject.signalNew('minimizedpanelmouseovered', gtk.Panel,[], null, null);
3790 gobject.signalNew('minimizedpanelmouseout', gtk.Panel, [], null, null);
3791 gobject.signalNew('restored', gtk.Panel, [], null, null);
3792 gobject.signalNew('closed', gtk.Panel, [], null, null);
3793 /**
3794  * A class to create vertical box or container
3795  * @constructor
3796  * @base gtk.Widget
3797  * @param {Integer} spacing
3798  * @param {Integer} padding
3799  */
3800 gtk.VBox = function(spacing, padding) {
3801 	gtk.Widget.apply(this);
3802 
3803 	this._spacing = (spacing === undefined || spacing == 0) ? 0 : spacing;
3804 	this._padding = (padding === undefined || padding == 0) ? 0 : padding;
3805 	this._children = [];
3806 	this._width = this._minWidth = 10;
3807 	this._height = this._minHeight = 10;
3808 	this._isSizeLocked = false;
3809 
3810 	this._render = function(){
3811 	    var domObj = this._domObj;
3812 		domObj.className += " vbox";
3813 	};
3814 
3815 	this._render();
3816 	this._initEvent();
3817 };
3818 
3819 gtk.VBox.prototype = new gtk.Widget();
3820 gtk.VBox.prototype.constructor = gtk.VBox;
3821 
3822 gtk.VBox.prototype._initEvent = function(){
3823 	var self = this;
3824 	jsgtk.Event.addDomListener(this._domObj, "click", function(e){
3825 		self.emit("clicked");
3826     });
3827 };
3828 
3829 /**
3830  * Return all children widget
3831  * @return {array} children inside the VBox
3832  */
3833 gtk.VBox.prototype.getChildren = function(){
3834 	var childWidgets = [], children = this._children, len = children.length;
3835 	for(var i = 0; i < len; i++){
3836 		childWidgets.push(children[i].childWidget);
3837 	}
3838 	return childWidgets;
3839 };
3840 
3841 /**
3842  * Return the first child
3843  * @return {gtk.Widget} widget first child inside the HBox
3844  */
3845 gtk.VBox.prototype.getFirstChild = function(){
3846     return this._children[0]["childWidget"];
3847 };
3848 
3849 /**
3850  * Return the last child
3851  * @return {gtk.Widget} widget the last child inside the HBox
3852  */
3853 gtk.VBox.prototype.getLastChild = function(){
3854     return this._children[this._children.length - 1]["childWidget"];
3855 };
3856 
3857 /**
3858  * Return a next child widget given current widget as reference
3859  * @return {gtk.Widget} widget the child to be returned
3860  */
3861 gtk.VBox.prototype.getNextSibling = function(childWidget){
3862     var childIndex = this._isChild(childWidget);
3863     if(childIndex === this._children.length - 1) return null;
3864     return this._children[childIndex + 1]["childWidget"];
3865 };
3866 
3867 /**
3868  * Return a previous child widget given a current widget as reference
3869  * @return {Object} widget the child to be returned
3870  */
3871 gtk.VBox.prototype.getPreviousSibling = function(childWidget){
3872     var childIndex = this._isChild(childWidget);
3873     if(childIndex === 0) return null;
3874     return this._children[childIndex - 1]["childWidget"];
3875 };
3876 
3877 /**
3878  * Method to refresh HBox
3879  * if gtk.HBox.lockSize() has been called, then the size of HBox will not decrease when some child have been remove
3880  * else vice versa
3881  */
3882 gtk.VBox.prototype.refresh = function(){
3883 	this._refreshSelf();
3884 	this._refreshChildren();
3885 };
3886 
3887 /** @private */
3888 gtk.VBox.prototype._refreshChildren = function(){
3889 	for(var i = this._children.length; i--;){
3890 		this._children[i]['childWidget'].refresh();
3891 	}
3892 };
3893 
3894 /**
3895  * Make sure, the HBox size will not decrease when some children have been remove
3896  */
3897 gtk.VBox.prototype.lockSize = function(){
3898     this._isSizeLocked = true;
3899 };
3900 
3901 /**
3902  * HBox size will decrease when some children have been remove
3903  */
3904 gtk.VBox.prototype.unlockSize = function(){
3905     this._isSizeLocked = false;
3906 };
3907 
3908 /** @private */
3909 gtk.VBox.prototype._refreshSelf = function(){
3910 	var minWidth = this.getMinWidthComposite();
3911 	if(this._isSizeLocked) minWidth = minWidth < this._width ? this._width : minWidth;
3912     this.resizeWidthComposite(minWidth);
3913 
3914 	var minHeight = this.getMinHeightComposite();
3915 	if(this._isSizeLocked) minHeight = minHeight < this._height ? this._height : minHeight;
3916     this.resizeHeightComposite(minHeight);
3917 };
3918 
3919 /**
3920  * Append child gtk.Widget to HBox
3921  * @param {Object} widget
3922  * @param {Object} packOption {fill: true || false, expand: true || false, padding: any integer, resizableHeight: true || false}
3923  */
3924 gtk.VBox.prototype.appendChild = function(childWidget, packOption){
3925     childWidget.setParent(this);
3926 
3927     var childObject = this._createChildObject(childWidget, packOption);
3928 	this._children.push(childObject);
3929 	this.resizeWidthComposite(this._width);
3930 	this.resizeHeightComposite(this._height);
3931 };
3932 
3933 /**
3934  * Method to add a separator between children widget inside HBox
3935  */
3936 gtk.VBox.prototype.addSeparator = function(){
3937     var space = this._children[this._children.length - 1]["space"];
3938     jsgtk.Dom.showElement(space.childNodes[0]);
3939 };
3940 
3941 /**
3942  * Method to clone the child widget
3943  * @return {Object} widget new cloned widget
3944  */
3945 gtk.VBox.prototype.cloneWidget = function(){
3946     return jsgtk.Util.clone(this);
3947 };
3948 
3949 /**
3950  * Insert a child widget infront of give child reference
3951  * @param {gtk.Widget} newWidget
3952  * @param {gtk.Widget} reference widget
3953  * @param {Object} packOption {fill: true || false, expand: true || false, padding: any integer, resizableHeight: true || false}
3954  */
3955 gtk.VBox.prototype.insertBefore = function(newChildWidget, oldChildWidget, packOption){
3956 
3957     newChildWidget.setParent(this);
3958 
3959     var index = this._isChild(oldChildWidget);
3960     this._children.splice(index,0, this._createChildObject(newChildWidget, packOption));
3961 
3962 	this.resizeWidthComposite(this._width);
3963 	this.resizeHeightComposite(this._height);
3964 };
3965 
3966 /**
3967  * Replace an existing child widget with new child widget
3968  * @param {gtk.Widget} newWidget
3969  * @param {gtk.Widget} reference widget
3970  * @param {Object} packOption {fill: true || false, expand: true || false, padding: any integer, resizableHeight: true || false}
3971  */
3972 gtk.VBox.prototype.replaceChild = function(newChildWidget, oldChildWidget, packOption){
3973     newChildWidget.setParent(this);
3974 
3975     var index = this._isChild(oldChildWidget);
3976     if(!index) jsgtk.Util.debug("target child widget not found");
3977 
3978     var child = this._children[index];
3979     child["element"].insertBefore(newChildWidget.getNode(), oldChildWidget.getNode());
3980     child["element"].removeChild(oldChildWidget.getNode());
3981 
3982     child["childWidget"]    = newChildWidget;
3983 	child["expand"]         = packOption["expand"]         === undefined ? child["expand"]         : packOption["expand"];
3984     child["fill"]           = packOption["fill"]           === undefined ? child["fill"]           : packOption["fill"];
3985 	child["padding"]        = packOption["padding"]        === undefined ? child["padding"]        : packOption["padding"];
3986 	child["resizableWidth"] = packOption["resizableWidth"] === undefined ? child["resizableWidth"] : packOption["resizableWidth"];
3987 
3988 	this.resizeWidthComposite(this._width);
3989 	this.resizeHeightComposite(this._height);
3990 };
3991 
3992 /**
3993  * Remove a child widget from the HBox
3994  * @param {Object} widget
3995  */
3996 gtk.VBox.prototype.removeChild = function(childWidget){
3997     var childIndex = this._isChild(childWidget);
3998     if( childIndex === false ) jsgtk.Util.debug("The widget has not yet been packed to vbox");
3999 
4000     this.removeChildByIndex(childIndex);
4001 };
4002 
4003 /**
4004  * Remove a child widget given an index
4005  * @param {Integer} index value of the child to be removed
4006  */
4007 gtk.VBox.prototype.removeChildByIndex = function(index){
4008     if(!this._children[index]) jsgtk.Util.debug("The index is out of range");
4009 
4010     this._resizeHeight(this._height - parseInt(this._children[index]["element"].style.height));
4011 
4012     this._domObj.removeChild(this._children[index]["element"]);
4013     this._domObj.removeChild(this._children[index]["space"]);
4014 
4015     this._children.splice(index, 1);
4016 };
4017 
4018 /**
4019  * Re-order or relocatte the child widget
4020  * @param{gtk.Widget} widget
4021  * @param{integer} position The new position for child in the children list of the box starting from 0
4022  */
4023 gtk.VBox.prototype.reorderChild = function(childWidget, position) {
4024 
4025     var childIndex = this._isChild(childWidget);
4026     if( childIndex === false ) jsgtk.Util.debug("The widget has not yet been packed to vbox");
4027     if( position >= this._children.length || position < 0 ) jsgtk.Util.debug("Position is undefined or out of range");
4028     if( childIndex === position ) return;
4029 
4030     var child = this._children[childIndex];
4031     var targetChild = this._children[position];
4032 
4033     this._children[position] = child;
4034     this._children[childIndex] = targetChild;
4035 
4036 	var tmpNode1 = jsgtk.Dom.create({append: this._domObj, tag: 'div'});
4037 	var tmpNode2 = jsgtk.Dom.create({append: this._domObj, tag: 'div'});
4038 
4039 	this._domObj.replaceChild(tmpNode2, targetChild["element"]);
4040 	this._domObj.replaceChild(tmpNode1, child["element"]);
4041 
4042 	this._domObj.appendChild(child["element"]);
4043 	this._domObj.appendChild(targetChild["element"]);
4044 
4045 	this._domObj.replaceChild(child["element"], tmpNode2);
4046 	this._domObj.replaceChild(targetChild["element"], tmpNode1);
4047 };
4048 
4049 /** @private */
4050 gtk.VBox.prototype._createChildObject = function(childWidget, packOption){
4051     var element = this._createChildNodeHolder(childWidget.getNode());
4052 
4053 	var space = this._createSpace();
4054 
4055 	this._appendChild(element, space);
4056 
4057     var childObject = {
4058 		"element" : element,
4059 		"childWidget"   : childWidget,
4060 		"space"   : space,
4061 		"expand"  : packOption["expand"] === undefined ? true : packOption["expand"],
4062 		"fill"    : packOption["fill"] === undefined ? true : packOption["fill"],
4063 		"padding" : packOption["padding"] === undefined ? 0 : packOption["padding"],
4064 		"resizableWidth" : packOption["resizableWidth"] === undefined ? true : packOption["resizableWidth"]
4065 	};
4066 	return childObject;
4067 };
4068 
4069 /** @private */
4070 gtk.VBox.prototype._isChild = function(child){
4071     for(var i = 0, len = this._children.length; i < len; i++){
4072         if(this._children[i]["childWidget"] === child) return i;
4073     }
4074     return false;
4075 };
4076 
4077 /** @private */
4078 gtk.VBox.prototype._appendChild = function(element, space){
4079     this._domObj.appendChild(element);
4080     this._domObj.appendChild(space);
4081 };
4082 
4083 /**
4084  * Return number of children inside HBox
4085  * @return {integer} length
4086  */
4087 gtk.VBox.prototype.getChildrenLength = function(){
4088     return this._children.length;
4089 };
4090 
4091 /** @private */
4092 gtk.VBox.prototype._createChildNodeHolder = function(childNode) {
4093     var verticleElement = jsgtk.Dom.create({tag: 'div', style: 'position: relative; display: block;'});
4094     verticleElement.appendChild(childNode);
4095 	return verticleElement;
4096 };
4097 
4098 /** @private */
4099 gtk.VBox.prototype._createSpace = function(){
4100     var space = jsgtk.Dom.create({"tag": 'div', "class": "gtk_vbox_space"});
4101         var separator = jsgtk.Dom.create({"append": space , "tag": 'div', "class": "gtk_vbox_separator"});
4102 	return space;
4103 };
4104 
4105 /** @private */
4106 gtk.VBox.prototype._hideLastSpace = function(){
4107     this._domObj.childNodes[this._domObj.childNodes.length - 1].style.height = "0px";
4108 };
4109 
4110 /**
4111  * Assign property to enabled
4112  */
4113 gtk.VBox.prototype.enable = function(){
4114     for(var i = this._children.length; i--;){
4115         this._children[i]["childWidget"].enable();
4116     }
4117 };
4118 
4119 /**
4120  * Assign property to disabled
4121  */
4122 gtk.VBox.prototype.disable = function(){
4123     for(var i = this._children.length; i--;){
4124         this._children[i]["childWidget"].disable();
4125     }
4126 };
4127 
4128 /** @private */
4129 gtk.VBox.prototype._handleHiddenChild = function(child){
4130 	if(child["childWidget"].isHidden()) {
4131 		jsgtk.Dom.hideElement(child["element"]);
4132 		jsgtk.Dom.hideElement(child["space"]);
4133 	}
4134 	else {
4135 		jsgtk.Dom.showElement(child["element"]);
4136 		jsgtk.Dom.showElement(child["space"]);
4137 	}
4138 };
4139 
4140 /** @private */
4141 gtk.VBox.prototype.getMinWidthComposite = function(){
4142     var maxChildWidth = this._children[0]["childWidget"].getMinWidthComposite();
4143     var childWidth;
4144     for(var i = 1, len = this._children.length; i < len; i++){
4145         childWidth = this._children[i]["childWidget"].getMinWidthComposite();
4146         maxChildWidth = maxChildWidth < childWidth ? childWidth : maxChildWidth;
4147     }
4148 
4149 	var minWidth = maxChildWidth + this._padding * 2;
4150 	minWidth     = minWidth < this._minWidth ? this._minWidth : minWidth;
4151 
4152     return minWidth;
4153 };
4154 
4155 /** @private */
4156 gtk.VBox.prototype._resizeChildrenWidth = function(width){
4157     var child;
4158     for(var i = 0, len = this._children.length; i < len; i++){
4159         child = this._children[i];
4160         child["element"].style.left = this._padding + "px";
4161         child["space"].style.left = this._padding + "px";
4162         if(child["resizableWidth"]){
4163             child["element"].style.width = width + "px";
4164             child["childWidget"].resizeWidthComposite(width);
4165             child["space"].style.width = width + "px";
4166         }else{
4167             var childWidth = child["childWidget"].getMinWidthComposite();
4168             child["element"].style.width = childWidth + "px";
4169             child["space"].style.width = childWidth + "px";
4170         }
4171     }
4172 };
4173 
4174 /** @private */
4175 gtk.VBox.prototype.resizeWidthComposite = function(width){
4176     var minWidth = this.getMinWidthComposite();
4177     minWidth = minWidth < width ? width : minWidth;
4178     this._resizeWidth(minWidth);
4179     this._resizeChildrenWidth(minWidth - this._padding * 2);
4180 };
4181 
4182 gobject.signalNew('clicked', gtk.VBox, [], null, null);
4183 /**
4184  * VBoxFactory is a class to create a vertical box as a container.
4185  * @param {Boolean} homogeneous The boolean value whether true or false
4186  * @param {Integer} spacing The integer value in pixel as spacing to be set
4187  * @param {Integer} padding The integer value in pixel as padding to be set
4188  * @see gtk.VBox
4189  * @constructor
4190  */
4191 gtk.VBoxFactory = function(homogeneous, spacing, padding) {
4192     return homogeneous ?
4193            new gtk.VBoxHomogeneous(spacing, padding) :
4194            new gtk.VBoxNoneHomogeneous(spacing, padding);
4195 };
4196 /**
4197  * A class to create horizontal box or container
4198  * @constructor
4199  * @base gtk.Widget
4200  * @param {Integer} spacing
4201  * @param {Integer} padding
4202  */
4203 gtk.HBox = function(spacing, padding) {
4204 	gtk.Widget.apply(this);
4205 
4206 	this._padding = (padding === undefined || padding == 0) ? 0 : padding;
4207 	this._spacing = (spacing === undefined || spacing == 0) ? 0 : spacing;
4208 	this._children = [];
4209 	this._width = this._minWidth = 10;
4210 	this._height = this._minHeight = 10;
4211     this._isSizeLocked = false;
4212 
4213 	this._render = function(){
4214 	    var domObj = this._domObj;
4215 		domObj.className += " hbox";
4216 		domObj.style.width = this._width + 'px';
4217 		domObj.style.height = this._height + 'px';
4218 	};
4219 
4220 	this._render();
4221 	this._initEvent();
4222 };
4223 
4224 gtk.HBox.prototype = new gtk.Widget();
4225 gtk.HBox.prototype.constructor = gtk.HBox;
4226 
4227 gtk.HBox.prototype._initEvent = function(){
4228 	var self = this;
4229 	jsgtk.Event.addDomListener(this._domObj, "click", function(e){
4230 		self.emit("clicked");
4231     });
4232 };
4233 
4234 /**
4235  * Return all children widget
4236  * @return {array} children inside the HBox
4237  */
4238 gtk.HBox.prototype.getChildren = function(){
4239 	var childWidgets = [],
4240 		children = this._children,
4241 	 	len = children.length;
4242 	for(var i = 0; i < len; i++){
4243 		childWidgets.push(children[i].childWidget);
4244 	}
4245 	return childWidgets;
4246 }
4247 
4248 /**
4249  * Return the first child
4250  * @return {gtk.Widget} widget first child inside the HBox
4251  */
4252 gtk.HBox.prototype.getFirstChild = function(){
4253     return this._children[0]["childWidget"];
4254 };
4255 
4256 /**
4257  * Method to set enabled
4258  */
4259 gtk.HBox.prototype.enable = function(){
4260     for(var i = this._children.length; i--;){
4261         this._children[i]["childWidget"].enable();
4262     }
4263 };
4264 
4265 /**
4266  * Method to set disabled
4267  */
4268 gtk.HBox.prototype.disable = function(){
4269     for(var i = this._children.length; i--;){
4270         this._children[i]["childWidget"].disable();
4271     }
4272 };
4273 
4274 /**
4275  * Return the last child
4276  * @return {gtk.Widget} widget the last child inside the HBox
4277  */
4278 gtk.HBox.prototype.getLastChild = function(){
4279     return this._children[this._children.length - 1]["childWidget"];
4280 };
4281 
4282 /**
4283  * Return a next child widget given current widget as reference
4284  * @return {gtk.Widget} widget the child to be returned
4285  */
4286 gtk.HBox.prototype.getNextSibling = function(childWidget){
4287     var childIndex = this._isChild(childWidget);
4288     if(childIndex === this._children.length - 1) return null;
4289     return this._children[childIndex + 1]["childWidget"];
4290 };
4291 
4292 /**
4293  * Return a previous child widget given a current widget as reference
4294  * @return {Object} widget the child to be returned
4295  */
4296 gtk.HBox.prototype.getPreviousSibling = function(childWidget){
4297     var childIndex = this._isChild(childWidget);
4298     if(childIndex === 0) return null;
4299     return this._children[childIndex - 1]["childWidget"];
4300 };
4301 
4302 /**
4303  * Method to refresh HBox
4304  * if gtk.HBox.lockSize() has been called, then the size of HBox will not decrease when some child have been remove
4305  * else vice versa
4306  */
4307 gtk.HBox.prototype.refresh = function(){
4308 	this._refreshSelf();
4309 	this._refreshChildren();
4310 };
4311 
4312 /** @private */
4313 gtk.HBox.prototype._refreshChildren = function(){
4314 	for(var i = this._children.length; i--;){
4315 		this._children[i]['childWidget'].refresh();
4316 	}
4317 };
4318 
4319 /**
4320  * Make sure, the HBox size will not decrease when some children have been remove
4321  */
4322 gtk.HBox.prototype.lockSize = function(){
4323     this._isSizeLocked = true;
4324 };
4325 
4326 /**
4327  * HBox size will decrease when some children have been remove
4328  */
4329 gtk.HBox.prototype.unlockSize = function(){
4330     this._isSizeLocked = false;
4331 };
4332 
4333 /** @private */
4334 gtk.HBox.prototype._refreshSelf = function(){
4335 	var minWidth = this.getMinWidthComposite();
4336 	if(this._isSizeLocked) minWidth = minWidth < this._width ? this._width : minWidth;
4337     this.resizeWidthComposite(minWidth);
4338 
4339 	var minHeight = this.getMinHeightComposite();
4340 	if(this._isSizeLocked) minHeight = minHeight < this._height ? this._height : minHeight;
4341     this.resizeHeightComposite(minHeight);
4342 };
4343 
4344 /**
4345  * Append child gtk.Widget to HBox
4346  * @param {Object} widget
4347  * @param {Object} packOption {fill: true || false, expand: true || false, padding: any integer, resizableWidth: true || false}
4348  */
4349 gtk.HBox.prototype.appendChild = function(childWidget, packOption) {
4350 
4351     childWidget.setParent(this);
4352 
4353 	this._children.push(this._createChildObject(childWidget, packOption));
4354 
4355 	this.resizeWidthComposite(this._width);
4356 	this.resizeHeightComposite(this._height);
4357 };
4358 
4359 /**
4360  * Method to add a separator between children widget inside HBox
4361  */
4362 gtk.HBox.prototype.addSeparator = function(){
4363     var space = this._children[this._children.length - 1]["space"];
4364     jsgtk.Dom.showElement(space.childNodes[0]);
4365 };
4366 
4367 /**
4368  * Method to clone the child widget
4369  * @return {Object} widget new cloned widget
4370  */
4371 gtk.HBox.prototype.cloneWidget = function(){
4372     return jsgtk.Util.clone(this);
4373 };
4374 
4375 /**
4376  * Insert a child widget infront of give child reference
4377  * @param {gtk.Widget} newWidget
4378  * @param {gtk.Widget} reference widget
4379  * @param {Object} packOption {fill: true || false, expand: true || false, padding: any integer, resizableWidth: true || false}
4380  */
4381 gtk.HBox.prototype.insertBefore = function(newChildWidget, oldChildWidget, packOption){
4382 
4383     childWidget.setParent(this);
4384 
4385     var index = this._isChild(oldChildWidget);
4386     this._children.splice(index,0, this._createChildObject(newChildWidget, packOption));
4387 
4388 	this.resizeWidthComposite(this._width);
4389 	this.resizeHeightComposite(this._height);
4390 };
4391 
4392 /**
4393  * Replace an existing child widget with new child widget
4394  * @param {gtk.Widget} newWidget
4395  * @param {gtk.Widget} reference widget
4396  * @param {Object} packOption {fill: true || false, expand: true || false, padding: any integer, resizableWidth: true || false}
4397  */
4398 gtk.HBox.prototype.replaceChild = function(newChildWidget, oldChildWidget, packOption){
4399     newChildWidget.setParent(this);
4400 
4401     var index = this._isChild(oldChildWidget);
4402     if(!index) jsgtk.Util.debug("target child widget not found");
4403 
4404     var child = this._children[index];
4405     child["element"].insertBefore(newChildWidget.getNode(), oldChildWidget.getNode());
4406     child["element"].removeChild(oldChildWidget.getNode());
4407 
4408     child["childWidget"]    = newChildWidget;
4409 	child["expand"]         = packOption["expand"]         === undefined ? child["expand"]         : packOption["expand"];
4410     child["fill"]           = packOption["fill"]           === undefined ? child["fill"]           : packOption["fill"];
4411 	child["padding"]        = packOption["padding"]        === undefined ? child["padding"]        : packOption["padding"];
4412 	child["resizableHeight"] = packOption["resizableHeight"] === undefined ? child["resizableHeight"] : packOption["resizableHeight"];
4413 
4414 	this.resizeWidthComposite(this._width);
4415 	this.resizeHeightComposite(this._height);
4416 };
4417 
4418 /**
4419  * Remove a child widget from the HBox
4420  * @param {Object} widget
4421  */
4422 gtk.HBox.prototype.removeChild = function(childWidget){
4423     var childIndex = this._isChild(childWidget);
4424     if( childIndex === false ) jsgtk.Util.debug("The widget has not yet been packed to vbox");
4425 
4426     this._resizeWidth(this._width - parseInt(this._children[childIndex]["element"].style.width));
4427 
4428     this._domObj.removeChild(this._children[childIndex]["element"]);
4429     this._domObj.removeChild(this._children[childIndex]["space"]);
4430 
4431     this._children.splice(childIndex, 1);
4432 };
4433 
4434 /**
4435  * Remove a child widget given an index
4436  * @param {Integer} index value of the child to be removed
4437  */
4438 gtk.HBox.prototype.removeChildByIndex = function(index){
4439     if(!this._children[index]) jsgtk.Util.debug("The index is out of range");
4440 
4441     this._resizeWidth(this._width - parseInt(this._children[index]["element"].style.width));
4442 
4443     this._domObj.removeChild(this._children[index]["element"]);
4444     this._domObj.removeChild(this._children[index]["space"]);
4445 
4446     this._children.splice(index, 1);
4447 };
4448 
4449 /**
4450  * Re-order or relocatte the child widget
4451  * @param{gtk.Widget} widget
4452  * @param{integer} position The new position for child in the children list of the box starting from 0
4453  */
4454 gtk.HBox.prototype.reorderChild = function(childWidget, position) {
4455 
4456     var childIndex = this._isChild(childWidget);
4457     if( childIndex === false ) jsgtk.Util.debug("The widget has not yet been packed to vbox");
4458     if( position >= this._children.length || position < 0 ) jsgtk.Util.debug("Position is undefined or out of range");
4459     if( childIndex === position ) return;
4460 
4461     var child = this._children[childIndex];
4462     var targetChild = this._children[position];
4463 
4464     this._children[position] = child;
4465     this._children[childIndex] = targetChild;
4466 
4467 	var tmpNode1 = jsgtk.Dom.create({append: this._domObj, tag: 'div'});
4468 	var tmpNode2 = jsgtk.Dom.create({append: this._domObj, tag: 'div'});
4469 
4470 	this._domObj.replaceChild(tmpNode2, targetChild["element"]);
4471 	this._domObj.replaceChild(tmpNode1, child["element"]);
4472 
4473 	this._domObj.appendChild(child["element"]);
4474 	this._domObj.appendChild(targetChild["element"]);
4475 
4476 	this._domObj.replaceChild(child["element"], tmpNode2);
4477 	this._domObj.replaceChild(targetChild["element"], tmpNode1);
4478 };
4479 
4480 /** @private */
4481 gtk.HBox.prototype._createChildObject = function(childWidget, packOption){
4482 
4483     var element = this._createChildNodeHolder(childWidget.getNode());
4484 
4485 	var space = this._createSpace();
4486 
4487 	this._appendChild(element, space);
4488 
4489 	var childObject = {
4490 		"element" : element,
4491 		"childWidget"   : childWidget,
4492 		"space"   : space,
4493 		"expand"  : packOption["expand"] === undefined ? true : packOption["expand"],
4494 		"fill"    : packOption["fill"] === undefined ? true : packOption["fill"],
4495 		"padding" : packOption["padding"] === undefined ? 0 : packOption["padding"],
4496 		"resizableHeight" : packOption["resizableHeight"] === undefined ? true : packOption["resizableHeight"]
4497 	};
4498 
4499 	return childObject;
4500 };
4501 
4502 /**
4503  * Return number of children inside HBox
4504  * @return {integer} length
4505  */
4506 gtk.HBox.prototype.getChildrenLength = function(){
4507     return this._children.length;
4508 };
4509 
4510 /** @private */
4511 gtk.HBox.prototype._isChild = function(child){
4512     for(var i = 0, len = this._children.length; i < len; i++){
4513         if(this._children[i]["childWidget"] === child) return i;
4514     }
4515     return false;
4516 };
4517 
4518 /** @private */
4519 gtk.HBox.prototype._appendChild = function(element, space){
4520     this._domObj.appendChild(element);
4521     this._domObj.appendChild(space);
4522 };
4523 
4524 /** @private */
4525 gtk.HBox.prototype._createChildNodeHolder = function(childNode) {
4526     var element = jsgtk.Dom.create({tag: 'div', style: 'position: relative; float: left;'});
4527     element.appendChild(childNode);
4528 	return element;
4529 };
4530 
4531 /** @private */
4532 gtk.HBox.prototype._createSpace = function(){
4533     var space = jsgtk.Dom.create({tag: 'div', "class": "gtk_hbox_space"});
4534         var separator = jsgtk.Dom.create({"append": space , "tag": 'div', "class": "gtk_hbox_separator"});
4535 	return space;
4536 };
4537 
4538 /** @private */
4539 gtk.HBox.prototype._hideLastSpace = function(){
4540 	if(this._domObj.childNodes.length >= 1)
4541 		this._domObj.childNodes[this._domObj.childNodes.length - 1].style.width = "0px";
4542 };
4543 
4544 /** @private */
4545 gtk.HBox.prototype._resizeChildrenHeight = function(height){
4546     var child;
4547     for(var i = 0, len = this._children.length; i < len; i++){
4548         child = this._children[i];
4549         child["element"].style.top = this._padding + "px";
4550         child["space"].style.top = this._padding + "px";
4551         if(child["resizableHeight"]){
4552             child["element"].style.height = height + "px";
4553             child["childWidget"].resizeHeightComposite(height);
4554             child["space"].style.height = height + "px";
4555         }else{
4556             var childHeight = child["childWidget"].getMinHeightComposite();
4557             child["element"].style.height = childHeight + "px";
4558             child["space"].style.height = childHeight + "px";
4559         }
4560     }
4561 };
4562 
4563 /** @private */
4564 gtk.HBox.prototype.getMinHeightComposite = function(){
4565     var maxChildHeight = this._children[0]["childWidget"].getMinHeightComposite();
4566     var childHeight;
4567     for(var i = 1, len = this._children.length; i < len; i++){
4568         childHeight = this._children[i]["childWidget"].getMinHeightComposite();
4569         maxChildHeight = maxChildHeight < childHeight ? childHeight : maxChildHeight;
4570     }
4571     var paddings = this._padding * 2;
4572 
4573 	var minHeight = maxChildHeight + paddings;
4574 	minHeight	  = minHeight < this._minHeight ? this._minHeight : minHeight;
4575 
4576     return minHeight;
4577 };
4578 
4579 /** @private */
4580 gtk.HBox.prototype.resizeHeightComposite = function(height){
4581     var minHeight = this.getMinHeightComposite();
4582     minHeight = minHeight < height ? height : minHeight;
4583     this._resizeHeight(minHeight);
4584     this._resizeChildrenHeight(minHeight - this._padding * 2);
4585 };
4586 gobject.signalNew('clicked', gtk.HBox, [], null, null);
4587 /**
4588  * HBoxFactory is a class to create horizontal box as a container. It can contain JSGTK widgets.
4589  * @param {Boolean} homogeneous The boolean value to be set if the box is homogeneous or not
4590  * @param {Interger} spacing The integer value in pixel as spacing to be set
4591  * @param {Interger} padding The integer value in pixel as padding to be set
4592  * @see gtk.HBox
4593  * @constructor
4594  */
4595 gtk.HBoxFactory = function(homogeneous, spacing, padding) {
4596     return homogeneous ?
4597            new gtk.HBoxHomogeneous(spacing, padding) :
4598            new gtk.HBoxNoneHomogeneous(spacing, padding);
4599 };
4600 /**
4601  * The base class of gtk.HPaned and gtk.HPaned
4602  * @constructor
4603  * @base gtk.Widget
4604  * @see gtk.VPaned
4605  */
4606 gtk.Paned = function(){
4607 	gtk.Widget.apply(this);
4608 
4609 	this._minWidth = 200;
4610 	this._minHeight = 200;
4611 	this._width = this._minWidth;
4612 	this._height = this._minHeight;
4613 
4614 	/** @private */
4615 	this._render = function(){
4616 		this._domObj.className += " gtk_paned";
4617 	};
4618 
4619 	this._render();
4620 };
4621 
4622 gtk.Paned.prototype = new gtk.Widget();
4623 gtk.Paned.prototype.constructor = gtk.Paned;
4624 
4625 /**
4626  * Adds the widget specified by child to the top or left of the paned
4627  * @param {gtk.Widget} widget
4628  */
4629 gtk.Paned.prototype.pack1 = function(widget){
4630 	this._child1 = widget;
4631 	this._paned1.appendChild(this._child1.getNode());
4632 	this._resizePaned1(true);
4633 };
4634 
4635 /**
4636  * Adds the widget specified by child to the top or left of the paned
4637  * @param {gtk.Widget} widget
4638  */
4639 gtk.Paned.prototype.pack2 = function(widget){
4640 	this._child2 = widget;
4641 	this._paned2.appendChild(this._child2.getNode());
4642 	this._resizePaned2(true);
4643 };
4644 
4645 /** @private */
4646 gtk.Paned.prototype.resize = function(width, height){
4647 	this._resizePaned1(false);
4648 	this._resizePaned2(false);
4649 };
4650 
4651 /** @private */
4652 gtk.Paned.prototype._resizePaned1 = function(isInit){
4653 	this._resizePaned1Width(isInit);
4654 	this._resizePaned1Height(isInit);
4655 };
4656 
4657 /** @private */
4658 gtk.Paned.prototype._resizePaned2 = function(isInit){
4659 	this._resizePaned2Width(isInit);
4660 	this._resizePaned2Height(isInit);
4661 };
4662 
4663 /** @private */
4664 gtk.Paned.prototype._showGhostDivider = function(){
4665 	var ghostDividerStyle = this._ghostDivider.style;
4666 	ghostDividerStyle.backgroundColor = "#838B8B";
4667 	ghostDividerStyle.opacity = 1;
4668 };
4669 
4670 /** @private */
4671 gtk.Paned.prototype._hideGhostDivider = function(){
4672 	var ghostDividerStyle = this._ghostDivider.style;
4673 	ghostDividerStyle.disply = "none";
4674 	ghostDividerStyle.opacity = 0.1;
4675 };
4676 
4677 gobject.signalNew("childrendminimize", gtk.Paned, null, null, []);
4678 gobject.signalNew("childrestore", gtk.Paned, null, null, []);
4679 /**
4680  * VPaned is a class to create vertical pane as a container
4681  * @base gtk.Paned
4682  * @constructor
4683  * @see gtk.Paned
4684  */
4685 gtk.VPaned = function() {
4686 	gtk.Paned.apply(this);
4687 
4688 	this._dividerHeight = 6;
4689 	this._paned1Height = (this._height / 2) - (this._dividerHeight/2);
4690 	this._paned2Height = (this._height / 2) - (this._dividerHeight/2);
4691 	this._isPaned1Restore = true;
4692 	this._isPaned2Restore = true;
4693     this._topAnchored = 0;
4694 	this._render = function(){
4695 		this._domObj.className += " gtk_vPaned";
4696 		this._domObj.style.width = this._width + 'px';
4697 		this._domObj.style.height = this._height + 'px';
4698 		this._domObj.style.position = 'relative';
4699 
4700 			this._paned1 = jsgtk.Dom.create({'tag': 'div', 'class': 'gtk_paned1'});
4701 			this._paned1.style.width = this._width + 'px';
4702 			this._paned1.style.height = this._paned1Height + 'px';
4703 
4704 			this._domDivider = jsgtk.Dom.create({'tag': 'div', 'class': 'gtk_dom_divider'});
4705 				this._dom = jsgtk.Dom.create({'append': this._domDivider, 'tag': "div", 'class': 'gtk_paned_divider_image'});
4706 
4707 			this._domDivider.style.width = this._width + 'px';
4708 			this._domDivider.style.height = this._dividerHeight + "px";
4709 			this._domDivider.style.top = this._paned1Height + 'px';
4710 
4711 			this._ghostDivider = this._domDivider.cloneNode(true);
4712 			this._ghostDivider.className = "gtk_paned_ghost_divider";
4713 
4714 			this._paned2 = jsgtk.Dom.create({'tag': 'div', 'class': 'gtk_paned2'});
4715 			this._paned2.style.width = this._width + 'px';
4716 			this._paned2.style.height = this._paned1Height + 'px';
4717 
4718 		this._domObj.appendChild(this._paned1);
4719 		this._domObj.appendChild(this._domDivider);
4720 		this._domObj.appendChild(this._paned2);
4721 		this._domObj.appendChild(this._ghostDivider);
4722 	};
4723 
4724 	this._render();
4725 
4726 	this._vBehaviour(0, this._height - this._dividerHeight);
4727 };
4728 
4729 gtk.VPaned.prototype = new gtk.Paned();
4730 gtk.VPaned.prototype.constructor = gtk.VPaned;
4731 
4732 /**
4733  * A method to set position of the vertical paned
4734  * @param {Integer} position The integer value to define the height
4735  */
4736 gtk.VPaned.prototype.setPosition = function(position){
4737     var widget1Height = this._child1.getMinHeightComposite();
4738     this._topAnchored = (widget1Height < position)? position : widget1Height;
4739 };
4740 
4741 /**
4742  * A method to set autoresize given a widget
4743  * @param {Dom} widget The Dom widget to be passed
4744  */
4745 gtk.VPaned.prototype.autoResize = function(widget){
4746 	var paned1 = this._paned1;
4747 	var paned2 = this._paned2;
4748 	this._originalPaned1Height = paned1.style.height;
4749 	this._originalPaned1ChildHeight = paned1.childNodes[0].style.height;
4750 	this._originalPaned2Height= paned2.style.height;
4751 	this._originalPaned2ChildHeight = paned2.childNodes[0].style.height;
4752 
4753 	if(widget._domObj.parentNode.className == "gtk_paned1" ){
4754 		this._child2.resizeHeightComposite(this._height);
4755 		this._child1.hide();
4756 		paned1.style.height = '0px';
4757 		this._isPaned1Restore = false;
4758 	}
4759 
4760 	if(widget._domObj.parentNode.className == "gtk_paned2" ){
4761 		this._child1.resizeHeightComposite(this._height);
4762 		this._child2.hide();
4763 		paned2.style.height = '0px';
4764 		this._isPaned2Restore = false;
4765 	}
4766 	this._domDivider.style.display = 'none';
4767 	this._ghostDivider.style.display = 'none';
4768 
4769 	if(!this._isPaned1Restore && !this._isPaned2Restore){
4770 		this.emit('childrendminimize');
4771 	}
4772 
4773 };
4774 
4775 /**
4776  * A method to restore its status
4777  * @param {Dom} widget The Dom widget to be passed
4778  */
4779 gtk.VPaned.prototype.restoreStatus = function(widget){
4780 	if(widget === this._child1){
4781 		if(this._isPaned2Restore){
4782 			this._paned1.style.height = this._paned1Height + "px";
4783 			this._child1.resizeHeightComposite(this._paned1Height);
4784             this._child1.show();
4785 
4786 			this._paned2.style.height = this._paned2Height + "px";
4787 			this._child2.resizeHeightComposite(this._paned2Height);
4788             this._child2.show();
4789 
4790 			this._domDivider.style.display = 'block';
4791 			this._ghostDivider.style.display = 'block';
4792 		}else{
4793 			this._paned1.style.height = this._height + "px";
4794 			this._child1.resizeHeightComposite(this._height);
4795 			this._child1.show();
4796 		}
4797 		this._isPaned1Restore = true;
4798 	}
4799 
4800 	if(widget === this._child2){
4801 		if(this._isPaned1Restore){
4802 			this._paned2.style.height = this._paned2Height + "px";
4803 			this._child2.resizeHeightComposite(this._paned2Height);
4804             this._child2.show();
4805 
4806 			this._paned1.style.height = this._paned1Height + "px";
4807 			this._child1.resizeHeightComposite(this._paned1Height);
4808             this._child1.show();
4809 
4810 			this._domDivider.style.display = 'block';
4811 			this._ghostDivider.style.display = 'block';
4812 		}else{
4813 			this._paned2.style.height = this._height + "px";
4814 			this._child2.resizeHeightComposite(this._height);
4815 			this._child2.show();
4816 		}
4817 		this._isPaned2Restore = true;
4818 	}
4819 
4820 	if(this._isPaned1Restore || this._isPaned2Restore) {
4821 		this.emit('childrestore');
4822 	}
4823 };
4824 
4825 /** @private */
4826 gtk.VPaned.prototype._resizePaned1Width = function(){
4827 	if(this._width > this._child1.getWidth())
4828 		this._child1.resizeWidthComposite(this._width);
4829 	else this._resizeWidth(this._child1.getWidth());
4830 };
4831 
4832 /** @private */
4833 gtk.VPaned.prototype._resizePaned1Height = function(isInit){
4834 
4835 	if(isInit) this._initModifyPaned1Height();
4836 	else this._modifyPaned1Height();
4837 
4838 	this._resizeHeight(this._paned1Height, this._paned2Height);
4839 	this._topMinY = this._child1.getMinHeightComposite();
4840 
4841 	this._vBehaviour( this._topMinY, this._height - this._dividerHeight);
4842 };
4843 
4844 /** @private */
4845 gtk.VPaned.prototype._resizePaned2Width = function(){
4846 	if(this._width > this._child2.getWidth())
4847 		this._child2.resizeWidthComposite(this._width);
4848 	else{
4849 		this._resizeWidth(this._child2.getWidth());
4850 	}
4851 };
4852 
4853 /** @private */
4854 gtk.VPaned.prototype._resizePaned2Height = function(isInit){
4855 
4856 	if(isInit) this._initModifyPaned2Height();
4857 	else this._modifyPaned2Height();
4858 
4859 	this._resizeHeight(this._paned1Height, this._paned2Height);
4860 	this._bottomMinY = this._child2.getMinHeightComposite();
4861 	var maxY = this._height - this._dividerHeight - this._bottomMinY;
4862 
4863 	this._vBehaviour( this._topMinY, maxY);
4864 };
4865 
4866 /** @private */
4867 gtk.VPaned.prototype._initModifyPaned1Height = function(){
4868 	if(this._paned1Height > this._child1.getHeight())
4869 		this._child1.resizeHeightComposite(this._paned1Height);
4870 	else{
4871 		this._paned1Height = this._child1.getHeight();
4872 	}
4873 };
4874 
4875 /** @private */
4876 gtk.VPaned.prototype._initModifyPaned2Height = function(){
4877 	if(this._paned2Height > this._child2.getHeight())
4878 		this._child2.resizeHeightComposite(this._paned2Height);
4879 	else
4880 		this._paned2Height = this._child2.getHeight();
4881 };
4882 
4883 /** @private */
4884 gtk.VPaned.prototype._modifyPaned1Height = function(){
4885 	this._child1.resizeHeightComposite(this._paned1Height);
4886 	this._paned1Height = this._child1.getHeight();
4887 };
4888 
4889 /** @private */
4890 gtk.VPaned.prototype._modifyPaned2Height = function(){
4891 	this._child2.resizeHeightComposite(this._paned2Height);
4892 	this._paned2Height = this._child2.getHeight();
4893 };
4894 
4895 /** @private */
4896 gtk.VPaned.prototype._vBehaviour = function(minY, maxY){
4897 	var self = this;
4898 	jsgtk.Util.DomDraggableAdapter.vDragInit(this._ghostDivider, minY, maxY);
4899 
4900 	this._ghostDivider.onDragStart = function(){
4901         this.style.background = "#DFE8F6";
4902         this.style.opacity = "0.9";
4903         if(this.firstChild) this.removeChild(this.firstChild);
4904 	};
4905 
4906 	this._ghostDivider.onDragEnd = function(x, y){
4907 
4908 		var topHeight = y;
4909 		var bottomHeight = self._height - topHeight - self._dividerHeight;
4910 
4911         self.setPosition(topHeight);
4912 		self._resizePaned12Dom(topHeight, bottomHeight);
4913 
4914 		self._child1.resizeHeightComposite(topHeight);
4915 		self._child2.resizeHeightComposite(bottomHeight);
4916 
4917         this.style.background = "";
4918         this.style.opacity = "0.5";
4919 	};
4920 };
4921 
4922 /** @private */
4923 gtk.VPaned.prototype._resizePaned12Dom = function(topHeight, bottomHeight){
4924 	this._paned1Height = topHeight;
4925 	this._paned2Height = bottomHeight;
4926 	this._paned1.style.height = topHeight + 'px';
4927 	this._paned2.style.height = bottomHeight + 'px';
4928 };
4929 
4930 /** @private */
4931 gtk.VPaned.prototype._resizeWidth = function(width){
4932 	this._width = width;
4933 	this._domObj.style.width = this._width + 'px';
4934 		this._paned1.style.width = this._width + 'px';
4935 		this._domDivider.style.width = this._width + 'px';
4936 		this._ghostDivider.style.width = this._width + 'px';
4937 		this._paned2.style.width = this._width + 'px';
4938 };
4939 
4940 /** @private */
4941 gtk.VPaned.prototype._resizeHeight = function(paned1Height, paned2Height){
4942 	this._height = paned1Height + paned2Height + this._dividerHeight;
4943 	this._domObj.style.height = this._height + 'px';
4944 		this._paned1.style.height = paned1Height + 'px';
4945 		this._ghostDivider.style.top = paned1Height + 'px';
4946 		this._paned2.style.height = paned2Height + 'px';
4947 };
4948 
4949 /**
4950  * A method to get or return minimum composite width
4951  * @return {Integer} The minimum composite width to be passed
4952  * @type Integer
4953  */
4954 gtk.VPaned.prototype.getMinWidthComposite = function(){
4955 	var widget1Width = this._child1.getMinWidthComposite();
4956 	var widget2Width = this._child2.getMinWidthComposite();
4957 	var minWidth = this.getSizeRequest()[0] > widget1Width ? this.getSizeRequest()[0] : widget1Width;
4958 	minWidth = minWidth > widget2Width ? minWidth : widget2Width;
4959 
4960 	return minWidth;
4961 };
4962 
4963 /**
4964  * A method to get or return minimum composite height
4965  * @return {Integer} The minimum composite height to be passed
4966  * @type Integer
4967  */
4968 gtk.VPaned.prototype.getMinHeightComposite = function(){
4969 	var widget1Height = this._child1.getMinHeightComposite();
4970 	var widget2Height = this._child2.getMinHeightComposite();
4971 	var minHeight = widget1Height + widget2Height;
4972 	minHeight = minHeight > this.getSizeRequest()[1] ? minHeight : this.getSizeRequest()[1];
4973 
4974 	return minHeight;
4975 };
4976 
4977 /**
4978  * A method to resize composite width of the widget and its childres
4979  * @param {Integer} width The integer value as width to be set
4980  */
4981 gtk.VPaned.prototype.resizeWidthComposite = function(width){
4982 	var minWidthComposite = this.getMinWidthComposite();
4983 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
4984 
4985 	this._resizeWidth(minWidth);
4986 
4987 	this._child1.resizeWidthComposite(minWidth);
4988 	this._child2.resizeWidthComposite(minWidth);
4989 
4990 	if(this._isPaned1Restore && this._isPaned2Restore) {
4991         this.resize();
4992 	}
4993 };
4994 
4995 /**
4996  * A method to resize composite height of the widget and its childres
4997  * @param {Integer} width The integer value as height to be set
4998  */
4999 gtk.VPaned.prototype.resizeHeightComposite = function(height){
5000 	var minHeightComposite = this.getMinHeightComposite();
5001 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
5002 
5003 	var offsetHeight = (minHeight - this.getHeight()) / 2 ;
5004 
5005 	this._resizeHeight(minHeight);
5006 
5007 	var height1 = this._paned1Height + offsetHeight;
5008 	var height2 = this._paned2Height + offsetHeight;
5009 
5010 	if(
5011 		this._paned2Height === this._child2.getMinHeightComposite() ||
5012 		this._paned1Height === this._child1.getMinHeightComposite() ||
5013 		height1 			<  this._child1.getMinHeightComposite() ||
5014 		height2   			<  this._child2.getMinHeightComposite()
5015 	){
5016 		if(this._paned2Height === this._child2.getMinHeightComposite() ||
5017 		   height2 			   <  this._child2.getMinHeightComposite()
5018 		){
5019 		    this._paned1Height = this._paned1Height + offsetHeight * 2;
5020 		    this._paned2Height = this._child2.getMinHeightComposite();
5021 		}
5022 
5023 		if(this._paned1Height === this._child1.getMinHeightComposite() ||
5024 		   height1 			   <  this._child1.getMinHeightComposite()
5025 		){
5026 		    this._paned2Height = this._paned2Height + offsetHeight * 2;
5027    		    this._paned1Height = this._child1.getMinHeightComposite();
5028 		}
5029 
5030 	}else{
5031 		this._paned1Height = height1;
5032 		this._paned2Height = height2;
5033 	}
5034 
5035 	if(this._topAnchored !== 0){
5036         var widget1Height = this._child1.getMinHeightComposite();
5037 	    var widget2Height = this._child2.getMinHeightComposite();
5038 
5039 	    var height = this._topAnchored + widget2Height;
5040 	    this._paned1Height = height < minHeight ? this._topAnchored : minHeight - widget2Height;
5041 		this._paned2Height = minHeight - this._paned1Height;
5042 	}
5043 
5044     this._paned1Height -= 2;
5045 	this._paned2Height -= 2;
5046 
5047 	if(this._isPaned1Restore && this._isPaned2Restore) {
5048         this.resize();
5049 	}
5050 };
5051 /**
5052  * Separate the paned into two vertical paned
5053  * @constructor
5054  * @base gtk.Paned
5055  */
5056 gtk.HPaned = function() {
5057 	gtk.Paned.apply(this);
5058 
5059     var self = this;
5060 	this._dividerWidth    = 6;
5061 	this._paned1Width     = (this._width / 2) - (this._dividerWidth / 2);
5062 	this._paned2Width     = (this._width / 2) - (this._dividerWidth / 2);
5063 	this._isPaned1Restore = true;
5064 	this._isPaned2Restore = true;
5065 	this._isDrawer        = false;
5066 	this._drawerWidth     = 6;
5067 	this._isDrawed        = false;
5068 	this._isDrawedToLeft  = false;
5069 	this._isDrawerLeftEnabled = false;
5070 	this._isDrawerRightEnabled = false;
5071 	this._leftAnchored      = 0;
5072 	this._drawerEventId = null;
5073 	this._isDragged = false;
5074 
5075 	/** @private */
5076 	this._render = function(){
5077 		var domObj = this._domObj,
5078 			domObjStyle = this._domObj.style,
5079 			jsgtkDom = jsgtk.Dom;
5080 
5081 		domObj.className += " gtk_hPaned";
5082 		domObjStyle.width = this._width + 'px';
5083 		domObjStyle.height = this._height + 'px';
5084 
5085 			this._paned1 = jsgtkDom.create({'tag': 'div', 'class': 'gtk_paned1'});
5086 			var paned1Style = this._paned1.style;
5087 			paned1Style.width = this._paned1Width + 'px';
5088 			paned1Style.height = this._height + 'px';
5089 
5090 			this._domDivider = jsgtkDom.create({'tag': 'div', 'class': 'gtk_dom_divider'});
5091 			    this._dom = jsgtkDom.create({'append': this._domDivider, 'tag': "div", 'class': 'gtk_paned_divider_image'});
5092 
5093 			this._drawer = jsgtkDom.create({"append": domObj, "tag": "div", "class": "gtk_hPaned_drawer"});
5094 			    this._restoreButton = jsgtkDom.create({"append": this._drawer, "tag": "div", "class": "gtk_hPaned_drawer_restore_icon"});
5095 			var drawerStyle = this._drawer.style;
5096 			drawerStyle.width = this._drawerWidth + "px";
5097 			drawerStyle.height= this._height + "px";
5098 			jsgtkDom.hideElement(this._drawer);
5099 
5100 			this._draw = jsgtkDom.create({"append": domObj, "tag": "div", "class": "gtk_hPaned_draw"});
5101 			jsgtkDom.hideElement(this._draw);
5102 
5103 			var domDividerStyle = this._domDivider.style;
5104 			domDividerStyle.width = this._dividerWidth + 'px';
5105 			domDividerStyle.height =  this._height+ "px";
5106 			domDividerStyle.left = this._paned1Width + 'px';
5107 
5108 			this._ghostDivider = this._domDivider.cloneNode(false);
5109 			this._ghostDivider.className = "gtk_paned_ghost_divider";
5110 
5111 			this._paned2 = jsgtk.Dom.create({'tag': 'div', 'class': 'gtk_paned2'});
5112 			var paned2Style = this._paned2.style;
5113 			paned2Style.width = this._paned1Width + 'px';
5114 			paned2Style.height = this._height + 'px';
5115 
5116 		domObj.appendChild(this._paned1);
5117 		domObj.appendChild(this._domDivider);
5118 		domObj.appendChild(this._paned2);
5119 		domObj.appendChild(this._ghostDivider);
5120 	};
5121 
5122 	this._render();
5123 
5124 	this._hBehaviour(0, this._width - this._dividerWidth);
5125 
5126 	jsgtk.Event.addDomListener(this._drawer, "click", function(e){
5127         self._isDrawed = false;
5128         if(self._isDrawedToLeft){
5129             self._child1.show();
5130             self._paned1.appendChild(self._child1.getNode());
5131             self.restoreStatus(self._child1, true);
5132         }else{
5133             self._child2.show();
5134             self._paned2.appendChild(self._child2.getNode());
5135             self.restoreStatus(self._child2, true);
5136         }
5137 
5138         jsgtk.Dom.hideElement(self._drawer);
5139 	});
5140 
5141 };
5142 
5143 gtk.HPaned.prototype = new gtk.Paned();
5144 gtk.HPaned.prototype.constructor = gtk.HPaned;
5145 
5146 /**
5147  * set position of the left paned x pixel from the left
5148  * @param {integer} position number of pixel from the left
5149  */
5150 gtk.HPaned.prototype.setPosition = function(position){
5151     var widget1Width = this._child1.getMinWidthComposite();
5152     this._leftAnchored = (widget1Width < position)? position : widget1Width;
5153 };
5154 
5155 /**
5156  * anble drawer to the right. When user click on the drawer, the right paned will be shrunk
5157  */
5158 gtk.HPaned.prototype.enableDrawerRight = function(){
5159     this._enableDrawer(this._child2, "gtk_enabled_drawer_right");
5160 	this._isDrawerRightEnabled = true;
5161 };
5162 
5163 /**
5164  * anble drawer to the right. When user click on the drawer, the left paned will be shrunk
5165  */
5166 gtk.HPaned.prototype.enableDrawerLeft = function(){
5167     this._enableDrawer(this._child1, "gtk_enabled_drawer_left");
5168     this._isDrawerLeftEnabled = true;
5169 };
5170 
5171 /** @private */
5172 gtk.HPaned.prototype._enableDrawer = function(widget, className){
5173     var self = this;
5174     this._domDivider.className += " gtk_dom_divider_drawer";
5175     this._domDivider.style.width = 5 + "px";
5176 
5177    	this._dom.className = className;
5178 
5179     var jsgtkEvent = jsgtk.Event;
5180     /** @private */
5181     this._drawerEventId = jsgtkEvent.addDomListener(this._ghostDivider, "click", function(e){
5182         self._isDrawed = true;
5183         self.autoResize(widget, true);
5184         jsgtkEvent.stopBubble(e);
5185     });
5186 
5187     /** @private */
5188     jsgtkEvent.addDomListener(this._dom, "click", function(e){
5189         self._isDrawed = true;
5190         self.autoResize(widget, true);
5191         jsgtkEvent.stopBubble(e);
5192     });
5193 
5194     this.resize();
5195 
5196     /** @private */
5197     jsgtkEvent.addDomListener(this._ghostDivider, "mouseover", function(e){
5198         if(self._isDragged){
5199             jsgtk.Event.addDomListener(
5200                 self._drawerEventId["obj"],
5201                 self._drawerEventId["type"],
5202                 self._drawerEventId["callback"]
5203             );
5204         }
5205         jsgtkEvent.stopBubble(e);
5206     });
5207 };
5208 
5209 /** @private */
5210 gtk.HPaned.prototype._resizeChild1 = function(){
5211 	var width = this._width - this._drawerWidth;
5212 	var paned1     = this._paned1;
5213 	var paned2     = this._paned2;
5214 
5215     if(this._isDrawer){
5216         this._child1.resizeWidthComposite(this._width - this._drawerWidth);
5217 	    this._child2.hide();
5218 
5219         paned2.style.width = this._drawerWidth + "px";
5220         paned1.style.width = width + "px";
5221 
5222         this._drawer.style.right = "0px";
5223         this._isDrawedToLeft = false;
5224 
5225         this._restoreButton.className += " draw_right";
5226         jsgtk.Dom.showElement(this._drawer);
5227     }else{
5228         this._child1.resizeWidthComposite(this._width);
5229 	    this._child2.hide();
5230 	    paned2.style.width = '0px';
5231     }
5232 	this._isPaned2Restore = false;
5233 };
5234 
5235 /** @private */
5236 gtk.HPaned.prototype._resizeChild2 = function(){
5237 	var width = this._width - this._drawerWidth;
5238 	var paned1     = this._paned1;
5239 	var paned2     = this._paned2;
5240 
5241     if(this._isDrawer){
5242         this._child2.resizeWidthComposite(width);
5243         this._child1.hide();
5244 
5245         paned1.style.width = this._drawerWidth + "px";
5246         paned2.style.width = width + "px";
5247 
5248         this._isDrawedToLeft = true;
5249 
5250         this._restoreButton.className += " draw_left";
5251         jsgtk.Dom.showElement(this._drawer);
5252     }else{
5253         this._child2.resizeWidthComposite(this._width);
5254         this._child1.hide();
5255         paned1.style.width = '0px';
5256     }
5257     this._isPaned1Restore = false;
5258 };
5259 
5260 /**
5261  * shrinken the widget inside each paned
5262  * @param {gtk.Widget} widget will be shrinken along with its paned
5263  * @param {boolean} isDrawer if drawer enabled, will show the pooler after paned was shrunk
5264  */
5265 gtk.HPaned.prototype.autoResize = function(widget, isDrawer){
5266 	this._isDrawer = isDrawer === undefined ? false : isDrawer;
5267 
5268 	if(widget._domObj.parentNode.className == "gtk_paned1" )
5269 	    this._resizeChild2();
5270 
5271 	if(widget._domObj.parentNode.className == "gtk_paned2" )
5272 	    this._resizeChild1();
5273 
5274 	jsgtk.Dom.hideElement(this._domDivider);
5275     jsgtk.Dom.hideElement(this._ghostDivider);
5276 
5277 	if(!this._isPaned1Restore && !this._isPaned2Restore){
5278         jsgtk.Dom.hideElement(this._drawer);
5279 		this.emit('childrendminimize', this);
5280 	}
5281 };
5282 
5283 /** @private */
5284 gtk.HPaned.prototype._restoreWidget1 = function(){
5285     var drawerWidth = 0;
5286     if(this._isDrawerRightEnabled){
5287         if(this._isDrawed){
5288             jsgtk.Dom.showElement(this._drawer);
5289             drawerWidth = this._drawerWidth;
5290         }
5291     }
5292     if(this._isPaned2Restore){
5293 		this._paned1.style.width = this._paned1Width + "px";
5294 		this._child1.resizeWidthComposite(this._paned1Width);
5295 
5296 		this._paned2.style.width = this._paned2Width + "px";
5297 		this._child2.resizeWidthComposite(this._paned2Width);
5298 
5299 		this._domDivider.style.display = 'block';
5300 		if(!this._isDrawerRightEnabled)this._ghostDivider.style.display = 'block';
5301 
5302 	}else{
5303 		this._paned1.style.width = this._width - drawerWidth + "px";
5304 		this._child1.resizeWidthComposite(this._width - drawerWidth);
5305 	}
5306 	this._isPaned1Restore = true;
5307 };
5308 
5309 /** @private */
5310 gtk.HPaned.prototype._restoreWidget2 = function(){
5311 
5312     var drawerWidth = 0;
5313     if(this._isDrawerLeftEnabled){
5314         if(this._isDrawed){
5315             jsgtk.Dom.showElement(this._drawer);
5316             drawerWidth = this._dividerWidth;
5317         }
5318     }
5319     if(this._isPaned1Restore){
5320 	    this._paned2.style.width = this._paned2Width + "px";
5321 	    this._child2.resizeWidthComposite(this._paned2Width);
5322 
5323 	    this._paned1.style.width = this._paned1Width + "px";
5324 	    this._child1.resizeWidthComposite(this._paned1Width);
5325 
5326 	    this._domDivider.style.display = 'block';
5327 	    if(!this._isDrawerLeftEnabled)this._ghostDivider.style.display = 'block';
5328     }else{
5329 	    this._paned2.style.width = this._width - drawerWidth + "px";
5330 	    this._child2.resizeWidthComposite(this._width - drawerWidth);
5331     }
5332     this._isPaned2Restore = true;
5333 };
5334 
5335 /**
5336  * Restore the shrunk widget and its paned
5337  * @param {gtk.Widget} widget will be shrinken along with its paned
5338  */
5339 gtk.HPaned.prototype.restoreStatus = function(widget){
5340 	if(widget === this._child1) this._restoreWidget1();
5341 	if(widget === this._child2) this._restoreWidget2();
5342 
5343 	if(this._isPaned1Restore || this._isPaned2Restore) {
5344 		this.emit('childrestore', this);
5345 	}
5346 };
5347 
5348 /** @private */
5349 gtk.HPaned.prototype._resizePaned1Height = function(){
5350 	if(this._height > this._child1.getHeight())
5351 		this._child1.resizeHeightComposite(this._height);
5352 	else this._resizeHeight(this._child1.getHeight());
5353 };
5354 
5355 /** @private */
5356 gtk.HPaned.prototype._resizePaned1Width = function(isInit){
5357 
5358 	if(isInit) this._initModifyPaned1Width();
5359 	else this._modifyPaned1Width();
5360 
5361 	this._resizeWidth(this._paned1Width, this._paned2Width);
5362 	this._leftMinX = this._child1.getMinWidthComposite();
5363 
5364 	this._hBehaviour( this._leftMinX, this._width - this._dividerWidth);
5365 };
5366 
5367 /** @private */
5368 gtk.HPaned.prototype._resizePaned2Height = function(){
5369 	if(this._height > this._child2.getHeight())
5370 	    this._child2.resizeHeightComposite(this._height);
5371 	else{
5372 		this._resizeHeight(this._child2.getHeight());
5373 		this._child1.resizeHeightComposite(this._child2.getHeight());
5374 	}
5375 };
5376 
5377 /** @private */
5378 gtk.HPaned.prototype._resizePaned2Width = function(isInit){
5379 
5380 	if(isInit) this._initModifyPaned2Width();
5381 	else this._modifyPaned2Width();
5382 
5383 	this._resizeWidth(this._paned1Width, this._paned2Width);
5384 	this._rightMinX = this._child2.getMinWidthComposite();
5385 	var maxX = this._width - this._dividerWidth - this._rightMinX;
5386 
5387 	this._hBehaviour(this._child1.getMinWidthComposite(), maxX);
5388 };
5389 
5390 /** @private */
5391 gtk.HPaned.prototype._initModifyPaned1Width = function(){
5392 	if(this._paned1Width > this._child1.getWidth())
5393 		this._child1.resize(this._paned1Width, this._child1.getHeight());
5394 	else{
5395 		this._paned1Width = this._child1.getWidth();
5396 	}
5397 };
5398 
5399 /** @private */
5400 gtk.HPaned.prototype._initModifyPaned2Width = function(){
5401 	if(this._paned2Width > this._child2.getWidth()){
5402 	    this._child2.resizeWidthComposite(this._paned2Width);
5403 	}
5404 	else{
5405 		this._paned2Width = this._child2.getWidth();
5406 	}
5407 };
5408 
5409 /** @private */
5410 gtk.HPaned.prototype._modifyPaned1Width = function(width){
5411     if(typeof width != 'undefined') this._child1.resizeWidthComposite(width);
5412 	else this._child1.resizeWidthComposite(this._paned1Width);
5413 };
5414 
5415 /** @private */
5416 gtk.HPaned.prototype._modifyPaned2Width = function(width){
5417     if(typeof width != 'undefined') this._child2.resizeWidthComposite(width);
5418 	else{
5419 	    this._child2.resizeWidthComposite(this._paned2Width);
5420     	this._paned2Width = this._child2.getWidth();
5421 	}
5422 };
5423 
5424 /** @private */
5425 /** @ignore */
5426 gtk.HPaned.prototype._hBehaviour = function(minX, maxX){
5427 
5428 	var self = this;
5429 
5430 	/** @ignore */
5431 	jsgtk.Util.DomDraggableAdapter.hDragInit(this._ghostDivider, minX, maxX);
5432 
5433 	/** @ignore */
5434     this._ghostDivider.onDragStart = function(){
5435         self._isDragged = false;
5436         this.style.background = "#DFE8F6";
5437         this.style.opacity = "0.9";
5438         if(this.firstChild) this.removeChild(this.firstChild);
5439     };
5440 
5441 	/** @ignore */
5442     this._ghostDivider.onDrag = function(){
5443         if(self._drawerEventId) jsgtk.Event.removeListener(self._drawerEventId);
5444     };
5445 
5446 	/** @ignore */
5447 	this._ghostDivider.onDragEnd = function(x, y){
5448 		var width1 = x;
5449 		var width2 = self._width - width1 - self._dividerWidth;
5450 
5451         self.setPosition(width1);
5452 		self._resizePaned12Dom(width1, width2);
5453 
5454 		self._child1.resizeWidthComposite(width1);
5455 		self._child2.resizeWidthComposite(width2);
5456 
5457 		self._isDragged = true;
5458 
5459         this.style.background = "";
5460         this.style.opacity = "0.9";
5461 	};
5462 };
5463 
5464 /** @private */
5465 gtk.HPaned.prototype._resizePaned12Dom = function(width1, width2){
5466 	this._paned1Width = width1;
5467 	this._paned2Width = width2;
5468 	this._paned1.style.width = width1 + 'px';
5469 	this._paned2.style.width = width2 + 'px';
5470 };
5471 
5472 /** @private */
5473 gtk.HPaned.prototype._resizeWidth = function(paned1Width, paned2Width){
5474 	this._width = paned1Width + paned2Width + this._dividerWidth;
5475 	this._domObj.style.width = this._width + 1 + 'px';
5476 		this._paned1.style.width = paned1Width + 'px';
5477 		this._ghostDivider.style.left = paned1Width + 'px';
5478 		this._paned2.style.width = paned2Width + 'px';
5479 };
5480 
5481 /** @private */
5482 gtk.HPaned.prototype._resizeHeight = function(height){
5483 	this._height = height;
5484 	this._domObj.style.height = this._height + 'px';
5485 		this._paned1.style.height = this._height + 'px';
5486 		this._domDivider.style.height = this._height + 'px';
5487 		this._ghostDivider.style.height = this._height + 'px';
5488 		this._paned2.style.height = this._height + 'px';
5489 
5490 		this._drawer.style.height = this._height + "px";
5491 };
5492 
5493 /** @private */
5494 gtk.HPaned.prototype.getMinWidthComposite = function(){
5495 	var widget1Width = this._child1.getMinWidthComposite();
5496 	var widget2Width = this._child2.getMinWidthComposite();
5497 	var minWidth = widget1Width + widget2Width + this._dividerWidth;
5498 	minWidth = minWidth > this._minWidth ? minWidth : this._minWidth;
5499 
5500 	return minWidth;
5501 };
5502 
5503 /** @private */
5504 gtk.HPaned.prototype.getMinHeightComposite = function(){
5505 	var widget1Height = this._child1.getMinHeightComposite();
5506 	var widget2Height = this._child2.getMinHeightComposite();
5507 	var minHeight = this._minHeight > widget1Height ? this._minHeight : widget1Height;
5508 	minHeight = minHeight > widget2Height ? minHeight : widget2Height;
5509 
5510 	return minHeight;
5511 };
5512 
5513 /** @private */
5514 gtk.HPaned.prototype.resizeWidthComposite = function(width){
5515 
5516 	var minWidthComposite = this.getMinWidthComposite();
5517 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
5518 
5519 	var offsetWidth = (minWidth - this.getWidth()) / 2 ;
5520 
5521 	this.setWidth(minWidth);
5522 
5523 	var width1 = this._paned1Width + offsetWidth;
5524 	var width2 = this._paned2Width + offsetWidth;
5525 
5526 	if(this._isDrawedToLeft){
5527 	    this._modifyPaned2Width(minWidth - this._drawerWidth);
5528 	    this._resizeWidth(0, minWidth);
5529 	}
5530 	else{
5531 	    this._modifyPaned1Width(minWidth - this._drawerWidth);
5532         this._resizeWidth(minWidth, 0);
5533 	}
5534 
5535 	if(
5536 		this._paned2Width === this._child2.getMinWidthComposite() ||
5537 		this._paned1Width === this._child1.getMinWidthComposite() ||
5538 		width1			   <  this._child1.getMinWidthComposite() ||
5539 		width2			   <  this._child2.getMinWidthComposite()
5540  	){
5541 		if(this._paned2Width === this._child2.getMinWidthComposite() ||
5542 		   width2			  < this._child2.getMinWidthComposite()
5543 		){
5544 		    this._paned1Width = (this._paned1Width + offsetWidth * 2) - 1;
5545 		    this._paned2Width = (this._child2.getMinWidthComposite()) - 1;
5546 		}
5547 		if(this._paned1Width === this._child1.getMinWidthComposite() ||
5548 		   width1			  <  this._child1.getMinWidthComposite()
5549 		){
5550 		    this._paned2Width = (this._paned2Width + offsetWidth * 2) - 1;
5551 		    this._paned1Width = (this._child1.getMinWidthComposite()) - 1;
5552 		}
5553 	}else{
5554 		this._paned1Width = this._paned1Width + offsetWidth - 1;
5555 		this._paned2Width = this._paned2Width + offsetWidth - 1;
5556 	}
5557 
5558 	if(this._leftAnchored !== 0){
5559 	    var widget1Width = this._child1.getMinWidthComposite();
5560 	    var widget2Width = this._child2.getMinWidthComposite();
5561 	    var width = this._leftAnchored + widget2Width;
5562 	    this._paned1Width = width < minWidth ? this._leftAnchored : minWidth - widget2Width;
5563 		this._paned2Width = minWidth - this._paned1Width;
5564 	}
5565 
5566     this._paned1Width -= this._dividerWidth / 2;
5567     this._paned2Width -= this._dividerWidth / 2;
5568 
5569 	if(this._isPaned1Restore && this._isPaned2Restore) {
5570         this.resize();
5571 	}
5572 };
5573 
5574 /** @private */
5575 gtk.HPaned.prototype.resizeHeightComposite = function(height){
5576 	var minHeightComposite = this.getMinHeightComposite();
5577 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
5578 
5579 	this.setHeight(minHeight);
5580 
5581 	this._child1.resizeHeightComposite(minHeight);
5582 	this._child2.resizeHeightComposite(minHeight);
5583 
5584     if(this._isDrawedToLeft) this._resizePaned1Height();
5585     else this._resizePaned2Height();
5586 
5587 	if(this._isPaned1Restore && this._isPaned2Restore) {
5588         this.resize();
5589 	}
5590 };
5591 /**
5592 * @constructor
5593 * @base gtk.Widget
5594 */
5595 gtk.JustifiedLabel = function(labelValues) {
5596 	gtk.Widget.apply(this);
5597 
5598 	/** 'clicked' signals*/
5599  	this.JUSTIFIEDLABEL_CLICKED = "clicked";
5600 	/** 'focused' signals*/
5601 	this.JUSTIFIEDLABEL_FOCUSED = "focused";
5602 	/** 'mouseover' signals*/
5603 	this.JUSTIFIEDLABEL_MOUSEOVER = "mouseover";
5604 	/** 'blurred' signals*/
5605 	this.JUSTIFIEDLABEL_BLURRED = "blurred";
5606 	/** 'mouseout' signals*/
5607 	this.JUSTIFIEDLABEL_MOUSEOUT = "mouseout";
5608 	/** 'refreshed' signals*/
5609 	this.JUSTIFIEDLABEL_REFRESHED = "refreshed";
5610 	/** 'cleared' signals*/
5611 	this.JUSTIFIEDLABEL_CLEARED = "cleared";
5612 
5613 	this._labelValues    = labelValues;
5614 	this._width          = this._minWidth  = 16;
5615 	this._height         = this._minHeight = 16;
5616 	this._rowHeight      = 20;
5617 	this._seperatorWidth = 80;
5618 	this._applyYellow = false;
5619 
5620 	this._render = function(){
5621 		this._domObj.className   += " gtk_justified_label";
5622 	};
5623 
5624 	this._render();
5625 };
5626 
5627 gtk.JustifiedLabel.prototype = new gtk.Widget();
5628 gtk.JustifiedLabel.prototype.constructor = gtk.JustifiedLabelgtk;
5629 
5630 /** @private */
5631 gtk.JustifiedLabel.prototype._clearChild = function(){
5632     this._domObj.innerHTML = "";
5633 };
5634 
5635 /**
5636  * Set the width of dote separator
5637  * @param {number} width
5638  */
5639 gtk.JustifiedLabel.prototype.setSeparatorWidth = function(width){
5640     this._seperatorWidth = width;
5641 };
5642 
5643 /**
5644  * Set the model
5645  * @param {gtk.LabelStore} model
5646  */
5647 gtk.JustifiedLabel.prototype.setModel = function(model){
5648 	this._clearChild();
5649 	new gtk.JustifiedLabelController(this, model);
5650     this._resize();
5651 	this.emit("refreshed");
5652 };
5653 
5654 /**
5655  * clear model and refresh
5656  */
5657 gtk.JustifiedLabel.prototype.clearModel = function(){
5658     this._clearChild();
5659     this._width =  this._minWidth = 0;
5660     this._height = this._minHeight = 0;
5661     this.emit("cleared");
5662 };
5663 
5664 /** @private */
5665 gtk.JustifiedLabel.prototype.constructLabelRows = function(data){
5666     this._labelValues = data;
5667     var domObj = this._domObj;
5668     this._rowNode;
5669 
5670     for(var i = 0, len = data.length; i < len; i++){
5671         var leftLabel = data[i]["leftLabel"];
5672         var rightLabel = data[i]["rightLabel"];
5673         var tabindex = data[i]["tabindex"];
5674 
5675 
5676         var rowNode = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "gtk_justified_label_row"});
5677         this._rowNode = rowNode;
5678         rowNode.style.height = this._rowHeight + "px";
5679 
5680             var dotsSeperator  = jsgtk.Dom.create({"append": rowNode, "tag": "div", "class": "gtk_justified_label_row_dot_separator_node"});
5681             var leftLabelNode  = jsgtk.Dom.create({"append": rowNode, "tag": "div", "class": "gtk_justified_label_row_left_node"});
5682                 leftLabelNode.innerHTML = leftLabel.getText();
5683 
5684             var rightLabelNode = jsgtk.Dom.create({"append": rowNode, "tag": "div", "class": "gtk_justified_label_row_right_node"});
5685                 rightLabelNode.innerHTML = rightLabel.getText();
5686 
5687         this._handleMouseOver(rowNode, rightLabel.getText());
5688         if(tabindex !=null)this._setTabIndex(rowNode,tabindex);
5689     }
5690     this._resize();
5691 };
5692 
5693 /** @private */
5694 gtk.JustifiedLabel.prototype._setTabIndex = function(row, index){
5695     row.tabIndex = index;
5696 };
5697 
5698 /** @private */
5699 gtk.JustifiedLabel.prototype._handleMouseOver = function(rowNode, rightLabel){
5700     var self = this;
5701     var jsgtkEvent = jsgtk.Event;
5702 
5703     jsgtkEvent.addDomListener(rowNode, "mouseover", function(e){
5704         self.emit("mouseover", rightLabel);
5705         self._setYellowBorderLeft(rowNode);
5706         jsgtkEvent.stopBubble(e);
5707     });
5708 
5709     jsgtkEvent.addDomListener(rowNode, "mouseout", function(){
5710     	  self.emit("mouseout", rightLabel);
5711         self._resetYellowBorderLeft(rowNode);
5712     });
5713 
5714     jsgtkEvent.addDomListener(rowNode, "click", function(e){
5715         self.emit("clicked", rightLabel);
5716         jsgtkEvent.stopBubble(e);
5717     });
5718 
5719     jsgtkEvent.addDomListener(rowNode, "focus", function(e){
5720         self.emit("focused", rightLabel);
5721         self._setYellowBorderLeft(rowNode);
5722         jsgtkEvent.stopBubble(e);
5723     });
5724 
5725     jsgtkEvent.addDomListener(rowNode, "blur", function(){
5726         self._resetYellowBorderLeft(rowNode);
5727         self.emit("blurred", rightLabel);
5728     });
5729 
5730 };
5731 
5732 /** @private */
5733 gtk.JustifiedLabel.prototype._getMaxRowWidth = function(){
5734     var labelValues = this._labelValues;
5735     var maxWidth = labelValues[0]["leftLabel"].getMinWidthComposite() +
5736                    this._seperatorWidth +
5737                    labelValues[0]["rightLabel"].getMinWidthComposite();
5738 
5739     for(var i = 1, len = this._labelValues.length; i < len; i++){
5740         var width = labelValues[i]["leftLabel"].getMinWidthComposite() +
5741                     this._seperatorWidth +
5742                     labelValues[i]["rightLabel"].getMinWidthComposite();
5743         maxWidth = width > maxWidth ? width : maxWidth;
5744     }
5745     return maxWidth;
5746 };
5747 
5748 /** @private */
5749 gtk.JustifiedLabel.prototype._resizeWidth = function(width){
5750     this._minWidth = this._width = width;
5751     this._domObj.style.width = width + "px";
5752 };
5753 
5754 /** @private */
5755 gtk.JustifiedLabel.prototype._setYellowBorderLeft = function(rowNode){
5756     rowNode.style.borderLeft = "4px solid #FFCC00";
5757     rowNode.childNodes[0].style.marginLeft = "8px";
5758     rowNode.childNodes[1].style.marginLeft = "8px";
5759 };
5760 
5761 /** @private */
5762 gtk.JustifiedLabel.prototype._resetYellowBorderLeft = function(rowNode){
5763     rowNode.style.borderLeft = "0";
5764     rowNode.childNodes[0].style.marginLeft = "0";
5765     rowNode.childNodes[1].style.marginLeft = "0";
5766 };
5767 
5768 /** @private */
5769 gtk.JustifiedLabel.prototype._resizeHeight = function(height){
5770     this._minHeight = this._height = height;
5771     this._domObj.style.height = height + "px";
5772 };
5773 
5774 /** @private */
5775 gtk.JustifiedLabel.prototype._resize = function(){
5776     var width  = this._getMaxRowWidth();
5777     this._resizeWidth(width);
5778 
5779     var height = this._labelValues.length * this._rowHeight;
5780     this._resizeHeight(height);
5781 };
5782 
5783 /** @private */
5784 gtk.JustifiedLabel.prototype.getMinWidthComposite = function(){
5785     return this._minWidth;
5786 };
5787 
5788 /** @private */
5789 gtk.JustifiedLabel.prototype.getMinHeightComposite = function(){
5790     return this._minHeight;
5791 };
5792 
5793 /**
5794  * Set attributes
5795  * @param {array} array of attributes object style
5796  */
5797 gtk.JustifiedLabel.prototype.setAttribute = function(attribute){
5798 	this._attribute = attribute;
5799 	this._applyAttribute();
5800 };
5801 
5802 /** @private */
5803 gtk.JustifiedLabel.prototype._applyAttribute = function(){
5804     var childLength = this._domObj.childNodes.length;
5805 
5806 	for(el in this._attribute){
5807 	    if(el == "backgroundColor"){
5808 	        for(var i = 0; i < childLength; i++){
5809 	            this._domObj.style[el] = this._attribute[el];
5810                 this._domObj.childNodes[i].childNodes[1].style[el] = this._attribute[el];
5811                 this._domObj.childNodes[i].childNodes[2].style[el] = this._attribute[el];
5812             }
5813 	    }else{
5814             this._domObj.style[el] = this._attribute[el];
5815         }
5816 	}
5817 };
5818 
5819 /** @private */
5820 gtk.JustifiedLabel.prototype.setWidth = function(width){
5821     this._width = this._minWidth  = width;
5822     this._resizeWidth(width);
5823 };
5824 
5825 /** @private */
5826 gtk.JustifiedLabel.prototype.resizeWidthComposite = function(width){
5827     this._width = width;
5828     this._resizeWidth(width);
5829 };
5830 
5831 /** @private */
5832 gtk.JustifiedLabel.prototype.resetMinWidth = function(width){
5833     this._width = this._minWidth  = width;
5834     this._resizeWidth(width);
5835 };
5836 
5837 /** @private */
5838 gtk.JustifiedLabel.prototype.resetMinHeight = function(height){
5839     this._height = this._minHeight  = height;
5840     this._resizeHeight(height);
5841 };
5842 
5843 /** @private */
5844 gtk.JustifiedLabel.prototype.resizeHeightComposite = function(height){
5845     this._height = height;
5846     this._resizeHeight(height);
5847 };
5848 
5849 gobject.signalNew('clicked', gtk.JustifiedLabel, [], null, null);
5850 gobject.signalNew('focused', gtk.JustifiedLabel, [], null, null);
5851 gobject.signalNew('mouseover', gtk.JustifiedLabel, [], null, null);
5852 gobject.signalNew('blurred', gtk.JustifiedLabel, [], null, null);
5853 gobject.signalNew('mouseout', gtk.JustifiedLabel, [], null, null);
5854 gobject.signalNew('refreshed', gtk.JustifiedLabel, [], null, null);
5855 gobject.signalNew('cleared', gtk.JustifiedLabel, [], null, null);
5856 /**
5857  * @constructor
5858  * @base gtk.Widget
5859  * @param {integer} width of liquidboxWidget
5860  * @param {integer} space between child widget
5861  */
5862 gtk.LiquidBox = function(width, space) {
5863 	gtk.Widget.apply(this);
5864 
5865 	/** 'refreshed' signal */
5866 	this.LIQUIDBOX_REFRESHED = "refreshed";
5867 
5868 	this._width          = this._minWidth = width;
5869 	this._height         = this._minHeight = 10;
5870     this._spacing        = space || 0;
5871     this._children       = [];
5872     this._maxChildWidth  = 0;
5873     this._maxChildHeight = 0;
5874     this._columns        = 0;
5875     this._rows           = 1;
5876 
5877 	this._render = function(){
5878 	    var domObj = this._domObj;
5879 		domObj.className += " liquidbox";
5880 	};/**
5881  * Append child widget into liquidbox
5882  * @param {gtk.Widget} childWidget
5883  * @param {object} options {'fill': true || false, 'padding': any number}
5884  */
5885 
5886 	this._render();
5887 };
5888 
5889 gtk.LiquidBox.prototype = new gtk.Widget();
5890 gtk.LiquidBox.prototype.constructor = gtk.LiquidBox;
5891 
5892 /**
5893  * Append child widget into liquidbox
5894  * @param {gtk.Widget} childWidget
5895  * @param {object} options {'fill': true || false, 'padding': any number}
5896  */
5897 gtk.LiquidBox.prototype.appendChild = function(childWidget, options){
5898     childWidget.setParent(this);
5899 
5900     var nodeHolder = this._createChildNodeHolder();
5901     nodeHolder.appendChild(childWidget.getNode());
5902 
5903     this._children.push({
5904         "childWidget": childWidget,
5905         "nodeHolder" : nodeHolder,
5906         "fill"       : options["fill"] || false,
5907         "padding"    : options["padding"] || 0
5908     });
5909 
5910     this._resetMaxChildWidth(childWidget, options["padding"] || 0 );
5911     this._resetMaxChildHeight(childWidget, options["padding"] || 0);
5912 
5913     this.resizeWidthComposite(this._width);
5914 
5915     var rows = Math.ceil(this._children.length / this._columns);
5916     if(rows > this._rows) {
5917         this._rows = rows;
5918         this.emit("refreshed");
5919     }
5920 };
5921 
5922 /**
5923  * Return the length of chidren
5924  * @return {integer}
5925  */
5926 gtk.LiquidBox.prototype.getChildrenLength = function(){
5927 	return this._children.length;
5928 };
5929 
5930 /**
5931  * Append child widget into liquidbox
5932  * @param {gtk.Widget} newChildWidget
5933  * @param {gtk.Widget} oldChildWidget
5934  * @param {object} options {'fill': true || false, 'padding': any number}
5935  */
5936 gtk.LiquidBox.prototype.insertBefore = function(newChildWidget, oldChildWidget, options){
5937 	this.appendChild(newChildWidget, options);
5938 
5939 	this._swapChildWidgetsDom(newChildWidget, oldChildWidget);
5940 
5941 	this.refresh();
5942 };
5943 
5944 /**
5945  * Refresh the gtk.LiquidBox
5946  */
5947 gtk.LiquidBox.prototype.refresh = function(){
5948     this._resetMaxChildrenWidthAndMaxChildrenHeight();
5949     this.resizeWidthComposite(this._width);
5950 };
5951 
5952 /** @private */
5953 gtk.LiquidBox.prototype._swapChildWidgetsDom = function(newChildWidget, oldChildWidget){
5954 	var newChildWidgetObject = this._children[this._getIndexOfChild(newChildWidget)];
5955 	var newChildWidgetNodeHolder = newChildWidgetObject["nodeHolder"];
5956 	this._domObj.removeChild(newChildWidgetNodeHolder);
5957 
5958 	var targetChildWidgetObject = this._children[this._getIndexOfChild(oldChildWidget)];
5959 	var targetChildWidgetNodeHolder = targetChildWidgetObject["nodeHolder"];
5960 	this._domObj.insertBefore(newChildWidgetNodeHolder, targetChildWidgetNodeHolder);
5961 
5962 	jsgtk.Util.arraySwapElements(this._children, newChildWidgetObject, targetChildWidgetObject);
5963 };
5964 
5965 /**
5966  * Remove child from gtk.LiquidBox by index
5967  * @param {integer} index
5968  */
5969 gtk.LiquidBox.prototype.removeByIndex = function(index){
5970     var childNode = this._children[index]["nodeHolder"];
5971     childNode.parentNode.removeChild(childNode);
5972 
5973     this._children.splice(index, 1);
5974     this.resizeWidthComposite(this._width);
5975 
5976     var rows = Math.ceil(this._children.length / this._columns);
5977     if(rows < this._rows) {
5978         this._rows = rows;
5979         this.emit("refreshed");
5980     }
5981 };
5982 
5983 /** @private */
5984 gtk.LiquidBox.prototype._getIndexOfChild = function(childWidget){
5985     for(var i = 0, len = this._children.length; i < len; i++){
5986         if(this._children[i]["childWidget"] === childWidget) return i;
5987     }
5988     return -1;
5989 }
5990 
5991 /**
5992  * Remove child from gtk.LiquidBox
5993  * @param {gtk.Widget} widget
5994  */
5995 gtk.LiquidBox.prototype.removeChild = function(object){
5996     var index = this._getIndexOfChild(object);
5997     if(index === -1) jsgtk.Util.debug("The child does not belong to the parent");
5998 
5999     this._children.splice(index, 1);
6000     this._domObj.removeChild(object.getNode().parentNode);
6001 
6002     this.resizeWidthComposite(this._width);
6003 
6004     var rows = Math.ceil(this._children.length / this._columns);
6005     if(rows < this._rows) {
6006         this._rows = rows;
6007         this.emit("refreshed");
6008     }
6009 };
6010 
6011 /** @private */
6012 gtk.LiquidBox.prototype._resetColumns = function(width){
6013     this._columns = Math.floor(width / this._maxChildWidth);
6014 };
6015 
6016 /** @private */
6017 gtk.LiquidBox.prototype._resetMaxChildWidth = function(childWidget, padding){
6018     var childWidth = childWidget.getMinWidthComposite() + padding * 2;
6019     this._maxChildWidth = childWidth > this._maxChildWidth ? childWidth : this._maxChildWidth;
6020 };
6021 
6022 /** @private */
6023 gtk.LiquidBox.prototype._resetMaxChildHeight = function(childWidget, padding){
6024     var childHeight = childWidget.getMinHeightComposite() + padding * 2;
6025     this._maxChildHeight = childHeight > this._maxChildHeight ? childHeight : this._maxChildHeight;
6026 };
6027 
6028 /** @private */
6029 gtk.LiquidBox.prototype._handleFilledChild = function(child){
6030     child["childWidget"].resizeWidthComposite(this._maxChildWidth - child["padding"] * 2);
6031     child["childWidget"].resizeHeightComposite(this._maxChildHeight - child["padding"] * 2);
6032     child["childWidget"].getNode().style.left = child["padding"] + "px";
6033     child["childWidget"].getNode().style.top  = child["padding"] + "px";
6034 };
6035 
6036 /** @private */
6037 gtk.LiquidBox.prototype._handleNoneFillChild = function(child){
6038     var childWidth = child["childWidget"].getMinWidthComposite();
6039     var childHeight = child["childWidget"].getMinHeightComposite();
6040     child["childWidget"].getNode().style.left = this._maxChildWidth / 2 - childWidth / 2 + "px";
6041     child["childWidget"].getNode().style.top  = this._maxChildHeight / 2 - childHeight / 2 + "px";
6042 };
6043 
6044 /** @private */
6045 gtk.LiquidBox.prototype._resizeChildNodeHolder = function(nodeHolder){
6046     nodeHolder.style.width  = this._maxChildWidth + "px";
6047     nodeHolder.style.height = this._maxChildHeight + "px"
6048 };
6049 
6050 /** @private */
6051 gtk.LiquidBox.prototype._positionChildNodeHolder = function(nodeHolder, column, rows){
6052     var vspacings = column > 0 ? this._spacing : 0;
6053     var hspacings = rows > 0 ? this._spacing : 0;
6054     nodeHolder.style.left = (this._maxChildWidth + vspacings) * column +"px";
6055     nodeHolder.style.top  = (this._maxChildHeight + hspacings) * rows + "px";
6056 };
6057 
6058 /** @private */
6059 gtk.LiquidBox.prototype._resize = function(){
6060 
6061     var column = 0;
6062     var rows   = 0;
6063 
6064     var docFragment = document.createDocumentFragment();
6065     for(var i = 0, len = this._children.length; i < len; i++){
6066 
6067         var child = this._children[i];
6068         var nodeHolder = child["nodeHolder"];
6069 
6070         docFragment.appendChild(nodeHolder);
6071 
6072         this._positionChildNodeHolder(nodeHolder, column, rows);
6073         this._resizeChildNodeHolder(nodeHolder);
6074 
6075         if(child["fill"]) this._handleFilledChild(child);
6076         else this._handleNoneFillChild(child);
6077 
6078         var spacings = this._spacing * (this._children.length);
6079         this._minHeight = (this._maxChildHeight * (rows+1) + spacings);
6080         this._resizeHeight(this._minHeight);
6081         if(column < this._columns - 1){
6082             column++;
6083         }else{
6084             column = 0;
6085             rows += 1;
6086         }
6087     }
6088     this._domObj.appendChild(docFragment);
6089 };
6090 
6091 /** @private */
6092 gtk.LiquidBox.prototype._createChildNodeHolder = function(){
6093     var nodeHolder = jsgtk.Dom.create({"tag": "div", "class": "gtk_liquid_box_childnode_holder"});
6094     nodeHolder.style.position = "absolute";
6095     return nodeHolder;
6096 };
6097 
6098 /** @private */
6099 gtk.LiquidBox.prototype._resetMaxChildrenWidthAndMaxChildrenHeight = function(){
6100     for(var i = 0, len = this._children.length; i < len; i++){
6101         var child = this._children[i];
6102         this._resetMaxChildWidth(child["childWidget"], child["padding"]);
6103         this._resetMaxChildHeight(child["childWidget"], child["padding"]);
6104     }
6105 };
6106 
6107 /** @private */
6108 gtk.LiquidBox.prototype.getMinHeightComposite = function(){
6109     return this._minHeight + this._spacing * (this._children.length - 1);
6110 };
6111 
6112 /** @private */
6113 gtk.LiquidBox.prototype.getMinWidthComposite = function(){
6114     return this._minWidth + this._spacing * (this._children.length - 1);
6115 };
6116 
6117 /** @private */
6118 gtk.LiquidBox.prototype.resizeWidthComposite = function(width){
6119     var minWidth = this.getMinWidthComposite();
6120     minWidth = minWidth < width ? width : minWidth;
6121     this._resizeWidth(minWidth);
6122 
6123     var spacings = this._spacing * (this._children.length - 1);
6124     this._resetColumns(minWidth - spacings);
6125     this._resize();
6126 };
6127 
6128 gobject.signalNew('refreshed', gtk.LiquidBox, null, null, []);
6129 /**
6130  *	Window is a class to create window which can contain a child widget
6131  * @param {String} type A constant variable value to define type of window.
6132  * <br>The type of window is optional.
6133  * <br>These are the constant values to be passed:
6134  * <br> - gtk.WINDOW_TOPLEVEL The flag constant value to define as top level or top most
6135  * <br> - gtk.WINDOW_POPUP The flag constant value to define as window popup
6136  * @extends gtk.WindowBase
6137  * @base gtk.WindowBase
6138  * @see gtk.WindowBase
6139  * @constructor
6140  */
6141 gtk.Window = function(type) {
6142 	gtk.WindowBase.apply(this);
6143 
6144 	this._sideBarsWidth = 10;
6145 	this._state = new gtk.StateWindowRestored(this, null);
6146 
6147 	this._childWidget = null;
6148 
6149 	this._headerHeight = 27;
6150 
6151 	this._render = function(){
6152 	    var domObj = this._domObj;
6153         domObj.className += " gtk_window_new";
6154 
6155             this._ghostWindowDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "gtk_window_ghost_new"});
6156             jsgtk.Dom.hideElement(this._ghostWindowDom);
6157 
6158             this._leftBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar gtk_window_left_bar_new"});
6159             this._rightBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar gtk_window_right_bar_new"});
6160             this._topBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar gtk_window_top_bar_new"});
6161             this._bottomBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar gtk_window_bottom_bar_new"});
6162 
6163             this._topLeftBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar_corner gtk_window_top_left_bar_new"});
6164             this._topRightBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar_corner gtk_window_top_right_bar_new"});
6165             this._bottomLeftBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar_corner gtk_window_bottom_left_bar_new"});
6166             this._bottomRightBarDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "resizeable_bar_corner gtk_window_bottom_right_bar_new"});
6167 	};
6168 
6169 	this._render();
6170 };
6171 
6172 gtk.Window.prototype = new gtk.WindowBase();
6173 gtk.Window.prototype.constructor = gtk.Window;
6174 /**
6175  * A method to draw or show the window after instantiated
6176  */
6177 gtk.Window.prototype.draw = function(){
6178     document.body.appendChild(this._domObj);
6179 };
6180 /**
6181  * A method to draw a modal layer
6182  */
6183 gtk.Window.prototype.drawModal = function(){
6184     this._showModal();
6185     document.body.appendChild(this._domObj);
6186 };
6187 /**
6188  * A method to append or add or replace child into its body
6189  * @param {Dom} childWidget The child widget or Dom object to be passed
6190  */
6191 gtk.Window.prototype.appendChild = function(childWidget){
6192 	if(this._childWidget) this._clearChild();
6193 
6194     this._childWidget = childWidget;
6195     this._bodyDom.appendChild(this._childWidget.getNode());
6196 
6197     this.resizeWidthComposite(this.getMinWidthComposite());
6198     this.resizeHeightComposite(this.getMinHeightComposite());
6199 
6200     this._initEvent();
6201 };
6202 /**
6203  * A method to set maximized the window
6204  */
6205 gtk.Window.prototype.maximize = function(){
6206 	this.emit("maximized", this);
6207 
6208 	if(!this.getParent()){
6209 	    this._restoredOption = {
6210             "width": this._width,
6211             "height": this._height,
6212             "left": parseInt(this._domObj.style.left),
6213             "top": parseInt(this._domObj.style.top)
6214         };
6215 
6216         this._state.maximize();
6217 	}
6218 };
6219 /**
6220  * A method to restore window to its previous state
6221  */
6222 gtk.Window.prototype.restore = function(){
6223     this._state.restore();
6224 
6225     var id = this._domObj.id;
6226     this._domObj.id = "";
6227     if(this._isWindowRestored(id)) return;
6228     this.emit('restored', this);
6229 
6230     jsgtk.Dom.showElement(this._domObj);
6231 	jsgtk.Dom.showElement(this._minimizeButton);
6232     this._resizeDomTitleWidth(this._width - this._inconsWidth);
6233 
6234     jsgtk.Dom.hideElement(this._minimizedWindow);
6235     this._domObj.id = id;
6236 };
6237 /**
6238  * A method to set minimized the window
6239  */
6240 gtk.Window.prototype.minimize = function(){
6241     this.emit('minimized', this);
6242 
6243     this._state.minimize();
6244 
6245     jsgtk.Dom.hideElement(this._domObj);
6246 	jsgtk.Dom.hideElement(this._minimizeButton);
6247 
6248     var holder = this._createMinimizedHolder();
6249     if(this._isNodeExistInMinimizedHolder(holder)){
6250         jsgtk.Dom.showElement(this._minimizedWindow);
6251         return;
6252     }
6253 
6254     this._minimizedWindow = this._createMinimizedWindow();
6255     holder.appendChild(this._minimizedWindow);
6256 
6257     this._initMinimizedEvents();
6258 };
6259 /** @private */
6260 gtk.Window.prototype._initEvent = function(){
6261     var self = this;
6262 
6263     jsgtk.Event.addDomListener(this._bodyDom, "mousedown", function(e){
6264         jsgtk.Event.stopBubble(e);
6265     });
6266 
6267     self._resizeLeftBar();
6268     self._resizeRightBar();
6269     self._resizeTopBar();
6270     self._resizeBottomBar();
6271 
6272     self._resizeTopLeftBar();
6273     self._resizeTopRightBar();
6274     self._resizeBottomLeftBar();
6275     self._resizeBottomRightBar();
6276 
6277     jsgtk.Util.DomDraggableAdapter.dragInit(this._domObj, 1, jsgtk.Util.getWindowWidth()-this._width-17, 0, jsgtk.Util.getWindowHeight()-this._height-17);
6278 
6279 	/** @private */
6280 	this._domObj.onDrag = function(){
6281 		self._checkAndHideComboDropdown();
6282     	self._checkAndHideToolTip();
6283 	};
6284 };
6285 /** @private */
6286 gtk.Window.prototype._resizeToLeft = function(x){
6287     var currentLeft = parseInt(this._domObj.style.left);
6288     this._domObj.style.left = currentLeft + x + "px";
6289     this.resizeWidthComposite(parseInt(this._ghostWindowDom.style.width));
6290     this._resetGhostWidth(parseInt(this._ghostWindowDom.style.width));
6291 };
6292 /** @private */
6293 gtk.Window.prototype._resizeToTop = function(y){
6294     var currentTop = parseInt(this._domObj.style.top);
6295     this._domObj.style.top = currentTop + y + "px";
6296     this.resizeHeightComposite(parseInt(this._ghostWindowDom.style.height));
6297     this._resetGhostHeight(parseInt(this._ghostWindowDom.style.height));
6298 };
6299 /** @private */
6300 gtk.Window.prototype._resizeToRight = function(x){
6301     this.resizeWidthComposite(x);
6302     this._resetGhostWidth(x);
6303 };
6304 /** @private */
6305 gtk.Window.prototype._resizeToBottom = function(y){
6306     this.resizeHeightComposite(y);
6307     this._resetGhostHeight(y);
6308 };
6309 /** @private */
6310 gtk.Window.prototype._resizeLeftBar = function(){
6311     var self = this;
6312     var minX = parseInt(window.innerWidth);
6313     jsgtk.Util.DomDraggableAdapter.hDragInit(self._leftBarDom, -minX, self._width - self._minWidth);
6314 
6315     /** @private */
6316     this._leftBarDom.onDragStart = function(x, y, e){
6317         jsgtk.Dom.showElement(self._ghostWindowDom);
6318         jsgtk.Event.stopBubble(e);
6319     };
6320 
6321     /** @private */
6322     this._leftBarDom.onDrag = function(x, y, e){
6323         self._ghostWindowDom.style.left = x + "px";
6324         self._ghostWindowDom.style.width = self._ghostWidth - x + "px";
6325     };
6326 
6327     /** @private */
6328     this._leftBarDom.onDragEnd = function(x, y){
6329         jsgtk.Dom.hideElement(self._ghostWindowDom);
6330         self._resizeToLeft(x);
6331 
6332         self._resizeLeftBar();
6333     };
6334 };
6335 /** @private */
6336 gtk.Window.prototype._resizeRightBar = function(){
6337     var isResized = false;
6338     var self = this;
6339     var minX = self._minWidth;
6340     jsgtk.Util.DomDraggableAdapter.hDragInit(self._rightBarDom, minX);
6341 
6342 	/** @private */
6343     this._rightBarDom.onDragStart = function(x, y, e){
6344         jsgtk.Dom.showElement(self._ghostWindowDom);
6345         jsgtk.Event.stopBubble(e);
6346     };
6347 
6348 	/** @private */
6349     this._rightBarDom.onDrag = function(x, y, e){
6350         self._ghostWindowDom.style.width = x + "px";
6351         isResized = true;
6352     };
6353 
6354 	/** @private */
6355     this._rightBarDom.onDragEnd = function(x, y){
6356         jsgtk.Dom.hideElement(self._ghostWindowDom);
6357 
6358         if(!isResized) return;
6359 
6360         self._resizeToRight(x);
6361 
6362         self._resizeRightBar();
6363     };
6364 };
6365 /** @private */
6366 gtk.Window.prototype._resizeTopBar = function(){
6367     var self = this;
6368     var minY = parseInt(window.innerHeight);
6369     jsgtk.Util.DomDraggableAdapter.vDragInit(self._topBarDom, -minY, self._height - self._minHeight);
6370 
6371 	/** @private */
6372     this._topBarDom.onDragStart = function(x, y, e){
6373         jsgtk.Dom.showElement(self._ghostWindowDom);
6374         jsgtk.Event.stopBubble(e);
6375     };
6376 
6377 	/** @private */
6378     this._topBarDom.onDrag = function(x, y, e){
6379         self._ghostWindowDom.style.top = y + "px";
6380         self._ghostWindowDom.style.height = self._ghostHeight - y + "px";
6381     };
6382 
6383 	/** @private */
6384     this._topBarDom.onDragEnd = function(x, y){
6385         jsgtk.Dom.hideElement(self._ghostWindowDom);
6386 
6387         self._resizeToTop(y);
6388 
6389         self._resizeTopBar();
6390     };
6391 };
6392 /** @private */
6393 gtk.Window.prototype._resizeBottomBar = function(){
6394     var self = this;
6395     var isResized = false;
6396     jsgtk.Util.DomDraggableAdapter.vDragInit(self._bottomBarDom, self._minHeight);
6397 
6398 	/** @private */
6399     this._bottomBarDom.onDragStart = function(x, y, e){
6400         jsgtk.Dom.showElement(self._ghostWindowDom);
6401         jsgtk.Event.stopBubble(e);
6402     };
6403 
6404 	/** @private */
6405     this._bottomBarDom.onDrag = function(x, y, e){
6406         self._ghostWindowDom.style.height = y + "px";
6407         isResized = true;
6408     };
6409 
6410 	/** @private */
6411     this._bottomBarDom.onDragEnd = function(x, y){
6412         jsgtk.Dom.hideElement(self._ghostWindowDom);
6413 
6414         if(!isResized) return;
6415 
6416         self._resizeToBottom(y);
6417 
6418         self._resizeBottomBar();
6419     };
6420 };
6421 /** @private */
6422 gtk.Window.prototype._resizeTopLeftBar = function(){
6423     var self = this;
6424     var minX = parseInt(window.innerWidth);
6425     var maxX = this._width - this._minWidth;
6426     var minY = parseInt(window.innerHeight);
6427     var maxY = this._height - this._minHeight;
6428 
6429     jsgtk.Util.DomDraggableAdapter.dragInit(this._topLeftBarDom, -minX, maxX, -minY, maxY);
6430 
6431     /** @private */
6432     this._topLeftBarDom.onDragStart = function(x, y, e){
6433         jsgtk.Dom.showElement(self._ghostWindowDom);
6434         jsgtk.Event.stopBubble(e);
6435     };
6436 
6437     /** @private */
6438     this._topLeftBarDom.onDrag = function(x, y, e){
6439         self._ghostWindowDom.style.left = x + "px";
6440         self._ghostWindowDom.style.width = self._ghostWidth - x + "px";
6441 
6442         self._ghostWindowDom.style.top = y + "px";
6443         self._ghostWindowDom.style.height = self._ghostHeight - y + "px";
6444     };
6445 
6446     /** @private */
6447     this._topLeftBarDom.onDragEnd = function(x, y){
6448         jsgtk.Dom.hideElement(self._ghostWindowDom);
6449 
6450         self._resizeToTop(y);
6451         self._resizeToLeft(x);
6452 
6453         self._resizeTopLeftBar();
6454     };
6455 };
6456 /** @private */
6457 gtk.Window.prototype._resizeTopRightBar = function(){
6458     var isResized = false;
6459     var self = this;
6460     var minX = this._minWidth;
6461     var maxX = parseInt(window.innerWidth);
6462     var minY = parseInt(window.innerHeight);
6463     var maxY = this._height - this._minHeight;
6464 
6465     jsgtk.Util.DomDraggableAdapter.dragInit(this._topRightBarDom, minX, maxX, -minY, maxY);
6466 
6467     /** @private */
6468     this._topRightBarDom.onDragStart = function(x, y, e){
6469         jsgtk.Dom.showElement(self._ghostWindowDom);
6470         jsgtk.Event.stopBubble(e);
6471     };
6472 
6473     /** @private */
6474     this._topRightBarDom.onDrag = function(x, y, e){
6475         self._ghostWindowDom.style.width = x + "px";
6476 
6477         self._ghostWindowDom.style.top = y + "px";
6478         self._ghostWindowDom.style.height = self._ghostHeight - y + "px";
6479 
6480         isResized = true;
6481     };
6482 
6483     /** @private */
6484     this._topRightBarDom.onDragEnd = function(x, y){
6485         jsgtk.Dom.hideElement(self._ghostWindowDom);
6486 
6487         if(!isResized) return;
6488 
6489         self._resizeToTop(y);
6490         self._resizeToRight(x);
6491 
6492         self._resizeTopRightBar();
6493     };
6494 };
6495 /** @private */
6496 gtk.Window.prototype._resizeBottomLeftBar = function(){
6497     var isResized = false;
6498     var self = this;
6499     var minX = parseInt(window.innerWidth);
6500     var maxX = this._width - this._minWidth;
6501     var minY = self._minHeight;
6502     var maxY = parseInt(window.innerHeight);
6503 
6504     jsgtk.Util.DomDraggableAdapter.dragInit(this._bottomLeftBarDom, -minX, maxX, minY, maxY);
6505 
6506     /** @private */
6507     this._bottomLeftBarDom.onDragStart = function(x, y, e){
6508         jsgtk.Dom.showElement(self._ghostWindowDom);
6509         jsgtk.Event.stopBubble(e);
6510     };
6511 
6512     /** @private */
6513     this._bottomLeftBarDom.onDrag = function(x, y, e){
6514         self._ghostWindowDom.style.left = x + "px";
6515         self._ghostWindowDom.style.width = self._ghostWidth - x + "px";
6516 
6517         self._ghostWindowDom.style.height = y + "px";
6518         isResized = true;
6519     };
6520 
6521     /** @private */
6522     this._bottomLeftBarDom.onDragEnd = function(x, y){
6523         jsgtk.Dom.hideElement(self._ghostWindowDom);
6524 
6525         if(!isResized) return;
6526 
6527         self._resizeToLeft(x);
6528         self._resizeToBottom(y);
6529 
6530         self._resizeBottomLeftBar();
6531     };
6532 };
6533 /** @private */
6534 gtk.Window.prototype._resizeBottomRightBar = function(){
6535     var isResized = false;
6536     var self = this;
6537     var minX = self._minWidth;
6538     var maxX = parseInt(window.innerWidth);
6539     var minY = self._minHeight;
6540     var maxY = parseInt(window.innerHeight);
6541 
6542     jsgtk.Util.DomDraggableAdapter.dragInit(this._bottomRightBarDom, minX, maxX, minY, maxY);
6543 
6544     /** @private */
6545     this._bottomRightBarDom.onDragStart = function(x, y, e){
6546         jsgtk.Dom.showElement(self._ghostWindowDom);
6547         jsgtk.Event.stopBubble(e);
6548     };
6549 
6550     /** @private */
6551     this._bottomRightBarDom.onDrag = function(x, y, e){
6552         self._ghostWindowDom.style.width = x + "px";
6553         self._ghostWindowDom.style.height = y + "px";
6554         isResized = true;
6555     };
6556 
6557     /** @private */
6558     this._bottomRightBarDom.onDragEnd = function(x, y){
6559         jsgtk.Dom.hideElement(self._ghostWindowDom);
6560 
6561         if(!isResized) return;
6562 
6563         self._resizeToRight(x);
6564         self._resizeToBottom(y);
6565 
6566         self._resizeBottomRightBar();
6567     };
6568 };
6569 /** @private */
6570 gtk.Window.prototype._resetGhostWidth = function(width){
6571     this._ghostWidth = width;
6572 };
6573 /** @private */
6574 gtk.Window.prototype._resetGhostHeight = function(height){
6575     this._ghostHeight = height;
6576 };
6577 /** @private */
6578 gtk.Window.prototype._repositionResizeableBars = function(){
6579     this._leftBarDom.style.left = "0px";
6580     this._rightBarDom.style.left = this._width - 3 + "px";
6581     this._topBarDom.style.top = "0px";
6582     this._bottomBarDom.style.top = this._height - 3 + "px";
6583 
6584     this._topLeftBarDom.style.left = "0px";
6585     this._topLeftBarDom.style.top = "0px";
6586 
6587     this._topRightBarDom.style.left = this._width - 3 + "px";
6588     this._topRightBarDom.style.top = "0px";
6589 
6590     this._bottomLeftBarDom.style.top = this._height - 3 + "px";
6591     this._bottomLeftBarDom.style.left = "0px";
6592 
6593     this._bottomRightBarDom.style.top = this._height - 3 + "px";
6594     this._bottomRightBarDom.style.left = this._width - 3 + "px";
6595 
6596     this._ghostWindowDom.style.left = "0px";
6597     this._ghostWindowDom.style.top = "0px";
6598 };
6599 /** @private */
6600 gtk.Window.prototype._repositionElements = function(){
6601     this._repositionResizeableBars();
6602 };
6603 /** @private */
6604 gtk.Window.prototype._resizeWidth = function(width){
6605     this._width = width;
6606     this._domObj.style.width = width + "px";
6607         this._bodyDom.style.width = width - this._sideBarsWidth + "px";
6608         this._ghostWindowDom.style.width = width + "px";
6609 
6610     this._repositionElements();
6611 };
6612 /** @private */
6613 gtk.Window.prototype._resizeHeight = function(height){
6614     this._height = height;
6615     this._domObj.style.height = height + "px";
6616         this._bodyDom.style.height = height - this._headerHeight + "px";
6617         this._ghostWindowDom.style.height = height + "px";
6618 
6619     this._repositionElements();
6620 };
6621 /** @private */
6622 gtk.Window.prototype.resetMinWidth = function(width){
6623     this._minWidth = width;
6624     this._ghostWidth = width;
6625 };
6626 /** @private */
6627 gtk.Window.prototype.resetMinHeight = function(height){
6628     this._minHeight = height;
6629     this._ghostHeight = height;
6630 };
6631 /** @private */
6632 gtk.Window.prototype.getMinWidthComposite = function(){
6633     var childMinWidth = this._childWidget.getMinWidthComposite() + this._sideBarsWidth;
6634     this.resetMinWidth(childMinWidth);
6635     return childMinWidth;
6636 };
6637 /** @private */
6638 gtk.Window.prototype.getMinHeightComposite = function(){
6639     var childMinHeight = this._childWidget.getMinHeightComposite() + this._headerHeight;
6640     this.resetMinHeight(childMinHeight)
6641     return childMinHeight;
6642 };
6643 /** @private */
6644 gtk.Window.prototype.resizeWidthComposite = function(width){
6645     var minWidth = this.getMinWidthComposite();
6646 
6647     minWidth = minWidth < width ? width : minWidth;
6648 
6649     this._childWidget.resizeWidthComposite(minWidth - this._sideBarsWidth);
6650 
6651     this._resizeWidth(minWidth);
6652 };
6653 /** @private */
6654 gtk.Window.prototype.resizeHeightComposite = function(height){
6655     var minHeight = this.getMinHeightComposite();
6656     minHeight = minHeight < height ? height : minHeight;
6657 
6658     this._childWidget.resizeHeightComposite(minHeight - this._headerHeight - 2);
6659 
6660     this._resizeHeight(minHeight);
6661 };
6662 /**
6663 * @constructor
6664 * @base gtk.Widget
6665 */
6666 gtk.WindowBase = function() {
6667 	gtk.Widget.apply(this);
6668 
6669 	this._minWidth = this._width = this._ghostWidth = this._noneMaximizedWidth = 20;
6670 	this._minHeight = this._height = this._ghostHeight = this._noneMaximizedHeight = 20;
6671 	this._headerHeight = 22;
6672 	this._minimizedWidth      = 150;
6673 	this._inconsWidth         = 62;
6674 	this._minimizedWindow      = null;
6675 	this._childWidget = null;
6676 	this._isCloseButtonActive = false;
6677 
6678 	this._enableControl = true;
6679 	this._enableCloseButton = true;
6680 	this._enableMaximizeButton = true;
6681 	this._enableMinimizeButton = true;
6682 
6683 	this._isModal = false;
6684 	var self = this;
6685 
6686 
6687 	this._render = function(){
6688 	    var domObj = this._domObj;
6689         domObj.className += " gtk_window_base";
6690 		domObj.id = new UUID().id;
6691         domObj.style.position = "absolute";
6692 
6693             this._headerDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "gtk_window_header_base"});
6694 
6695                 this._titleDom = jsgtk.Dom.create({"append": this._headerDom, "text": "Window Title","tag": "div", "class": "gtk_window_title_base"});
6696                 this._minimizeButton = jsgtk.Dom.create({"append": this._headerDom,"tag": "div", "title": "Minimize Window", "class": "gtk_window_minimized_botton_base"});
6697 				this._maximizeButton = jsgtk.Dom.create({"append": this._headerDom,"tag": "div", "title": "Maximize Window", "class": "gtk_window_maximized_botton_base"});
6698 				this._returnToPreviousSizeButton = jsgtk.Dom.create({"append": this._headerDom,"tag": "div", "title": "Restore Window", "class": "gtk_window_return_size_botton_base"});
6699 				this._closeButton = jsgtk.Dom.create({"append": this._headerDom,"tag": "div", "title": "Close Window", "class": "gtk_window_close_botton_base"});
6700 
6701             this._bodyDom = jsgtk.Dom.create({"append": domObj, "tag": "div", "class": "gtk_window_body_new"});
6702 	};
6703 
6704 	this._render();
6705 
6706 	jsgtk.Dom.hideElement(this._returnToPreviousSizeButton);
6707 	jsgtk.Dom.showElement(this._maximizeButton);
6708 
6709     jsgtk.Event.addDomListener(this._minimizeButton, "mouseup", function(e){
6710     	self._checkAndHideComboDropdown();
6711     	self._checkAndHideToolTip();
6712     	self._checkAndHideSmartEntryDropdown();
6713         self.minimize();
6714     }, false);
6715 
6716 	jsgtk.Event.addDomListener(this._maximizeButton, "mouseup", function(e){
6717 		self._checkAndHideComboDropdown();
6718 		self._checkAndHideToolTip();
6719 		self._checkAndHideSmartEntryDropdown();
6720         self.maximize();
6721     }, false);
6722 
6723 	jsgtk.Event.addDomListener(this._returnToPreviousSizeButton, "mouseup", function(e){
6724 		self._checkAndHideComboDropdown();
6725 		self._checkAndHideToolTip();
6726 		self._checkAndHideSmartEntryDropdown();
6727         self.restore();
6728     }, false);
6729 
6730 	this.setCloseButton(true);
6731 };
6732 
6733 gtk.WindowBase.prototype = new gtk.Widget();
6734 gtk.WindowBase.prototype.constructor = gtk.WindowBase;
6735 
6736 /**
6737  * A method to enable resizeable of the window.
6738  * The window will be resisizeable.
6739  */
6740 gtk.WindowBase.prototype.enableResize = function(){
6741 	var jsgtkDom = jsgtk.Dom;
6742 	jsgtkDom.showElement(this._leftBarDom);
6743 	jsgtkDom.showElement(this._rightBarDom);
6744 	jsgtkDom.showElement(this._topBarDom);
6745 	jsgtkDom.showElement(this._bottomBarDom);
6746 	jsgtkDom.showElement(this._topLeftBarDom);
6747 	jsgtkDom.showElement(this._topRightBarDom);
6748 	jsgtkDom.showElement(this._bottomLeftBarDom);
6749 	jsgtkDom.showElement(this._bottomRightBarDom);
6750 };
6751 
6752 /**
6753  * A method to disable resizeable of the window.
6754  * It will not allow user to resize the window.
6755  */
6756 gtk.WindowBase.prototype.disableResize = function(){
6757 	var jsgtkDom = jsgtk.Dom;
6758 	jsgtkDom.hideElement(this._leftBarDom);
6759 	jsgtkDom.hideElement(this._rightBarDom);
6760 	jsgtkDom.hideElement(this._topBarDom);
6761 	jsgtkDom.hideElement(this._bottomBarDom);
6762 	jsgtkDom.hideElement(this._topLeftBarDom);
6763 	jsgtkDom.hideElement(this._topRightBarDom);
6764 	jsgtkDom.hideElement(this._bottomLeftBarDom);
6765 	jsgtkDom.hideElement(this._bottomRightBarDom);
6766 };
6767 
6768 /**
6769  * A method to disable and hide all control buttons
6770  */
6771 gtk.WindowBase.prototype.disableControl = function(){
6772 	var jsgtkDom = jsgtk.Dom;
6773 	jsgtkDom.hideElement(this._closeButton);
6774 	jsgtkDom.hideElement(this._minimizeButton);
6775 	jsgtkDom.hideElement(this._maximizeButton);
6776 	jsgtkDom.hideElement(this._returnToPreviousSizeButton);
6777 	this._enableControl=false;
6778 };
6779 
6780 /**
6781  * A method to enable and display all control buttons
6782  */
6783 gtk.WindowBase.prototype.enableControl = function(){
6784     this._enableControl = true;
6785     if(this._enableMinimizeButton)this.enableMinimizeButton();
6786     if(this._enableMaximizeButton)this.enableMaximizeButton();
6787     if(this._enableCloseButton) this.enableCloseButton();
6788 };
6789 
6790 /**
6791  * A method to enable and display close button
6792  */
6793 gtk.WindowBase.prototype.enableCloseButton = function(){
6794     if(this._enableControl){
6795         jsgtk.Dom.showElement(this._closeButton);
6796         if(this._enableMaximizeButton){
6797             this._minimizeButton.style.right = "40px"
6798             this._maximizeButton.style.right =this._returnToPreviousSizeButton.style.right= "24px";
6799         }else this._minimizeButton.style.right = "24px"
6800         this._enableCloseButton = true;
6801     }
6802 };
6803 
6804 /**
6805  * A method to enable and display minimize button
6806  */
6807 gtk.WindowBase.prototype.enableMinimizeButton = function(){
6808     if(this._enableControl){
6809          jsgtk.Dom.showElement(this._minimizeButton);
6810          if((!this._enableCloseButton)&&(!this._enableMaximizeButton)) this._minimizeButton.style.right = "5px";
6811          else if(this._enableCloseButton && this._enableMaximizeButton) this._minimizeButton.style.right = "40px";
6812          else this._minimizeButton.style.right = "24px";
6813          this._enableMinimizeButton = true;
6814      }
6815 };
6816 
6817 /**
6818  * A method to enable and display maximize button
6819  */
6820 gtk.WindowBase.prototype.enableMaximizeButton = function(){
6821    if(this._enableControl){
6822        jsgtk.Dom.showElement(this._returnToPreviousSizeButton);
6823        if(this._enableCloseButton){
6824             this._minimizeButton.style.right = "40px"
6825             this._maximizeButton.style.right =this._returnToPreviousSizeButton.style.right= "24px";
6826        }
6827        this._enableMaximizeButton = true;
6828    }
6829 };
6830 
6831 /**
6832  * A method to disable and hide close button
6833  */
6834 gtk.WindowBase.prototype.disableCloseButton = function(){
6835     jsgtk.Dom.hideElement(this._closeButton);
6836 
6837     if(this._enableMaximizeButton){
6838         this._maximizeButton.style.right =this._returnToPreviousSizeButton.style.right= "5px";
6839         this._minimizeButton.style.right = "24px"
6840     }else this._minimizeButton.style.right = "5px"
6841 
6842     this._enableCloseButton = false;
6843 };
6844 
6845 /**
6846  * A method to disable and hide minimize button
6847  */
6848 gtk.WindowBase.prototype.disableMinimizeButton = function(){
6849     jsgtk.Dom.hideElement(this._minimizeButton);
6850     this._enableMinimizeButton = false;
6851 };
6852 
6853 /**
6854  * A method to disable and hide maximize button
6855  */
6856 gtk.WindowBase.prototype.disableMaximizeButton = function(){
6857     jsgtk.Dom.hideElement(this._maximizeButton);
6858     jsgtk.Dom.hideElement(this._returnToPreviousSizeButton);
6859 
6860     if(this._enableCloseButton)this._minimizeButton.style.right = "24px"
6861     else this._minimizeButton.style.right = "5px"
6862 
6863     this._enableMaximizeButton = false;
6864 };
6865 
6866 /**
6867  * A method to show maximize header
6868  */
6869 gtk.WindowBase.prototype.showMaximizedHeader = function(){
6870 	jsgtk.Dom.showElement(this._returnToPreviousSizeButton);
6871 	jsgtk.Dom.hideElement(this._maximizeButton);
6872 };
6873 
6874 /**
6875  * A method to show restore header
6876  */
6877 gtk.WindowBase.prototype.showRestoredHeader = function(){
6878 	jsgtk.Dom.hideElement(this._returnToPreviousSizeButton);
6879 	jsgtk.Dom.showElement(this._maximizeButton);
6880 };
6881 
6882 /**
6883  * A method to show minimize header
6884  */
6885 gtk.WindowBase.prototype.showMinimizedHeader = function(){
6886     jsgtk.Dom.showElement(this._returnToPreviousSizeButton);
6887     jsgtk.Dom.hideElement(this._maximizeButton);
6888 };
6889 
6890 /**
6891  * A method to set state of the window
6892  * @param {String} state The constant value to be passed.
6893  * <br>These are the constant values to be passed:
6894  * <br> - gtk.WINDOW_RESTORED The flag constant value to set as restored state
6895  * <br> - gtk.WINDOW_MAXIMIZED The flag constant value to set as maximized state
6896  * <br> - gtk.WINDOW_MINIMIZED The flag constant value to set as minimixed state
6897  */
6898 gtk.WindowBase.prototype.setState = function(state){
6899     this._state = state;
6900 };
6901 
6902 /**
6903  * A method to get or return the current state of window
6904  * @return {String} The constant state value of the window
6905  * <br>These are the constant values to be returned:
6906  * <br> - gtk.WINDOW_RESTORED The flag constant value to set as restored state
6907  * <br> - gtk.WINDOW_MAXIMIZED The flag constant value to set as maximized state
6908  * <br> - gtk.WINDOW_MINIMIZED The flag constant value to set as minimixed state
6909  */
6910 gtk.WindowBase.prototype.getState = function(){
6911     return this._state;
6912 };
6913 
6914 gtk.WindowBase.prototype.setTitle = function(title){
6915     this._titleDom.innerHTML = title;
6916 };
6917 
6918 /**
6919  * A method to set the title of the window to be bold
6920  * @param {Boolean} bold The boolean value true is bold, fasle it not bold
6921  */
6922 gtk.WindowBase.prototype.setBoldTitle = function(bold){
6923 	if(bold){
6924 		this._titleDom.style.fontWeight = "bold";
6925 	} else 	this._titleDom.style.fontWeight = "normal";
6926 };
6927 
6928 /**
6929  * A method to set position of the window
6930  * @param {String} position The constant value to be passed.
6931  * <br>This is the constant value to be passed:
6932  * <br> - gtk.JUSTIFY_CENTER The flag constant value to set as center screen
6933  */
6934 gtk.WindowBase.prototype.setPosition = function(position){
6935     if(position == gtk.JUSTIFY_CENTER) this._positionCenter();
6936 };
6937 
6938 /** @private */
6939 gtk.WindowBase.prototype._positionCenter = function(){
6940     var pageSize = jsgtk.Util.getPageSize();
6941     var left = (pageSize[0] - this._width )/2;
6942     var top = (pageSize[1] - this._height )/2;
6943     this.move(left, top);
6944 };
6945 
6946 /** @private */
6947 gtk.WindowBase.prototype._clearChild = function(){
6948 	this._bodyDom.removeChild(this._childWidget.getNode());
6949 };
6950 
6951 /**
6952  * A method to move or set position of window given left and top values in pixel
6953  * @param {Integer} left The left value in pixel
6954  * @param {Integer} top The top value in pixel
6955  */
6956 gtk.WindowBase.prototype.move = function(left, top){
6957 	var domObjStyle = this._domObj.style;
6958     domObjStyle.top = top + "px";
6959     domObjStyle.left = left + "px";
6960 };
6961 
6962 /** @private */
6963 gtk.WindowBase.prototype._initMinimizedEvents = function(){
6964     var self = this;
6965     var jsgtkEvent = jsgtk.Event;
6966 
6967     var restoreButton = this._minimizedWindow.childNodes[3];
6968 
6969     jsgtkEvent.addDomListener(restoreButton, "mouseup", function(e){
6970 		self.restore();
6971 		jsgtkEvent.stopBubble(e);
6972     });
6973 
6974 	var closeButton = this._minimizedWindow.childNodes[4];
6975 	jsgtkEvent.addDomListener(closeButton, "mouseup", function(e){
6976 	    self._minimizedWindow.parentNode.removeChild(self._minimizedWindow);
6977 	    self.emit("closed", self);
6978 	    self._checkAndRemoveComboDropdown();
6979 	    self._checkAndRemoveToolTip();
6980 	    self._checkAndRemoveSmartEntryDropdown();
6981 	    jsgtkEvent.stopBubble(e);
6982 	});
6983 
6984     jsgtkEvent.addDomListener(this._minimizedWindow, "mouseup", function(e){
6985         self.emit("minimizedmouseovered", self._title);
6986         self._checkAndHideComboDropdown();
6987         self._checkAndHideToolTip();
6988         self._checkAndHideSmartEntryDropdown();
6989         self.restore();
6990         jsgtkEvent.stopBubble(e);
6991     });
6992 
6993     jsgtkEvent.addDomListener(this._minimizedWindow, "dblclick", function(e){
6994         self.restore();
6995     });
6996 };
6997 
6998 /** @private */
6999 gtk.WindowBase.prototype._createMinimizedHolder = function(){
7000     var id = "gtk_minimized_widget_holder";
7001     var holder = document.getElementById(id);
7002     if(!holder) var holder = jsgtk.Dom.create({"append": document.body, "tag": "div", "id": id});
7003     return holder;
7004 };
7005 
7006 /** @private */
7007 gtk.WindowBase.prototype._isNodeExistInMinimizedHolder = function(holder){
7008     var clonedHolder = holder.cloneNode(true);
7009     for(var i = 0, len = clonedHolder.childNodes.length; i < len; i++){
7010         if(this._domObj.id == clonedHolder.childNodes[i].id) return true;
7011     }
7012     return false;
7013 };
7014 
7015 /** @private */
7016 gtk.WindowBase.prototype._createMinimizedWindow = function(){
7017     this._resizeDomTitleWidth(this._minimizedWidth - this._inconsWidth);
7018 
7019     var minimizeWindow = this._headerDom.cloneNode(true);
7020 	minimizeWindow.className = "gtk_window_base_minimize";
7021     minimizeWindow.removeAttribute("style");
7022     minimizeWindow.style.width = this._minimizedWidth + "px";
7023     minimizeWindow.id = this._domObj.id;
7024 
7025     return minimizeWindow;
7026 };
7027 
7028 /** @private */
7029 gtk.WindowBase.prototype._resizeDomTitleWidth = function(width){
7030     this._titleDom.style.width = width + "px";
7031 };
7032 
7033 /** @private */
7034 gtk.WindowBase.prototype._hideCloseButton = function(){
7035     if(this._closeButton){
7036 		this._closeButton.style.display = "none";
7037 		this._minimizeButton.style.right = "21px";
7038 		this._maximizeButton.style.right = "5px";
7039 	}
7040 };
7041 
7042 /** @private */
7043 gtk.WindowBase.prototype._showCloseButton = function(){
7044     var self = this,
7045         jsgtkEvent = jsgtk.Event,
7046         jsgtkDom = jsgtk.Dom;
7047 
7048     jsgtkDom.showElement(this._closeButton);
7049 	this._minimizeButton.style.right = "41px";
7050 
7051 	jsgtkEvent.addDomListener(this._closeButton, "mouseup", function(e){
7052 	    self.emit("closed", self);
7053 	    self._closeModal();
7054 	    self._domObj.parentNode.removeChild(self._domObj);
7055 	    self._domObj = null;
7056 	    self._checkAndRemoveComboDropdown();
7057 	    self._checkAndRemoveToolTip();
7058 	    self._checkAndRemoveSmartEntryDropdown();
7059 	    jsgtkEvent.stopBubble(e);
7060 	});
7061 };
7062 
7063 /**
7064  * A method to hide minimize button
7065  */
7066 gtk.WindowBase.prototype.hideMinimizeButton = function(){
7067     this._minimizeButton.style.display = "none";
7068 };
7069 
7070 /** @private */
7071 gtk.WindowBase.prototype._checkAndRemoveComboDropdown = function(){
7072     var comboDropDown = document.getElementsByClassName("gtk_combobox_holder");
7073     if(comboDropDown !== null){
7074 		var comboDropDownLength = comboDropDown.length;
7075 		if(comboDropDownLength > 0){
7076 			for(var i = 0; i < comboDropDownLength; i++){
7077 				var childTobeRemoved = comboDropDown[0];
7078 				childTobeRemoved.parentNode.removeChild(childTobeRemoved);
7079 			}
7080 		}
7081 	}
7082 };
7083 
7084 /** @private */
7085 gtk.WindowBase.prototype._checkAndRemoveSmartEntryDropdown = function(){
7086     var smartEntryDropDown = document.getElementsByClassName("gtk_smart_entry_drop_down_widget_holder");
7087     if(smartEntryDropDown !== null){
7088 		var smartEntryDropDownLength = smartEntryDropDown.length;
7089 		if(smartEntryDropDownLength > 0){
7090 			for(var i = 0; i < smartEntryDropDownLength; i++){
7091 				var childTobeRemoved = smartEntryDropDown[0];
7092 				childTobeRemoved.parentNode.removeChild(childTobeRemoved);
7093 			}
7094 		}
7095 	}
7096 };
7097 
7098 /** @private */
7099 gtk.WindowBase.prototype._checkAndHideSmartEntryDropdown = function(){
7100     var smartEntryDropDown = document.getElementsByClassName("gtk_smart_entry_drop_down_widget_holder");
7101     if(smartEntryDropDown !== null){
7102 		var smartEntryDropDownLength = smartEntryDropDown.length;
7103 		if(smartEntryDropDownLength > 0){
7104 			for(var i = 0; i < smartEntryDropDownLength; i++){
7105 				var childTobeHidden = smartEntryDropDown[i];
7106 				childTobeHidden.style.display = "none";
7107 			}
7108 		}
7109 	}
7110 };
7111 
7112 /** @private */
7113 gtk.WindowBase.prototype._checkAndHideComboDropdown = function(){
7114     var comboDropDown = document.getElementsByClassName("gtk_combobox_holder");
7115     if(comboDropDown !== null){
7116     	var comboDropDownLength = comboDropDown.length;
7117 		if(comboDropDownLength > 0){
7118 			for(var i = 0; i < comboDropDownLength; i++){
7119 				var childTobeHidden = comboDropDown[i];
7120 				childTobeHidden.style.display = "none";
7121 			}
7122 		}
7123     }
7124 };
7125 
7126 /** @private */
7127 gtk.WindowBase.prototype._checkAndRemoveToolTip = function(){
7128     var toolTip = document.getElementsByClassName("gtk_widget gtk_bubble");
7129     if(toolTip !== null){
7130 		var toolTipLength = toolTip.length;
7131 		if(toolTipLength > 0){
7132 			for(var i = 0; i < toolTipLength; i++){
7133 				var childTobeRemoved = toolTip[0];
7134 				childTobeRemoved.parentNode.removeChild(childTobeRemoved);
7135 			}
7136 		}
7137 	}
7138 };
7139 
7140 /** @private */
7141 gtk.WindowBase.prototype._checkAndHideToolTip = function(){
7142     var toolTip = document.getElementsByClassName("gtk_widget gtk_bubble");
7143     if(toolTip !== null){
7144 		var toolTipLength = toolTip.length;
7145 		if(toolTipLength > 0){
7146 			for(var i = 0; i < toolTipLength; i++){
7147 				var childTobeHidden = toolTip[i];
7148 				childTobeHidden.style.display = "none";
7149 			}
7150 		}
7151 	}
7152 };
7153 
7154 /** @private */
7155 gtk.WindowBase.prototype._isWindowRestored = function(id){
7156     if(!document.getElementById(id)){
7157         this._domObj.id = id;
7158         return true;
7159     }
7160     return false;
7161 };
7162 
7163 /**
7164  * A method to set or show close button give a boolean value
7165  * @param {Boolean} isCloseButtonActive The boolean value true is to show, or false to hide
7166  */
7167 gtk.WindowBase.prototype.setCloseButton = function(isCloseButtonActive){
7168 	this._isCloseButtonActive = isCloseButtonActive;
7169 	if(this._isCloseButtonActive) this._showCloseButton();
7170 	else this._hideCloseButton();
7171 };
7172 
7173 /**
7174  * A method to close or remove window
7175  */
7176 gtk.WindowBase.prototype.close = function(){
7177     this.emit("closed", self);
7178     this._closeModal();
7179     this._domObj.parentNode.removeChild(this._domObj);
7180     this._checkAndRemoveComboDropdown();
7181     this._checkAndRemoveToolTip();
7182     this._checkAndRemoveSmartEntryDropdown();
7183 
7184 };
7185 
7186 /** @private */
7187 gtk.WindowBase.prototype._showModal = function(){
7188     if(!this._isModal)this._createModal();
7189     this._domObj.style.zIndex = "8001";
7190 };
7191 
7192 /** @private */
7193 gtk.WindowBase.prototype._closeModal = function(){
7194 	if(typeof this._modal !== 'undefined')
7195     	this._modal.parentNode.removeChild(this._modal);
7196 	this._domObj.style.zIndex = "8000";
7197 };
7198 
7199 /** @private */
7200 gtk.WindowBase.prototype._hideModal = function(){
7201     this._modal.style.display = "none";
7202     this._domObj.style.zIndex = "8000";
7203 };
7204 
7205 /** @private */
7206 gtk.WindowBase.prototype._createModal = function(){
7207     this._modal = jsgtk.Dom.create({"append":document.body, "tag": "div", "id": "gtk_window_modal"});
7208     var widthHeight = jsgtk.Util.getPageSize();
7209     this._modal.style.width = widthHeight[0] + "px";
7210     this._modal.style.height = widthHeight[1] + "px";
7211     this._isModal = true;
7212 };
7213 gobject.signalNew('maximized', gtk.WindowBase, [], null, null);
7214 gobject.signalNew('minimized', gtk.WindowBase, [], null, null);
7215 gobject.signalNew('minimizedmouseovered', gtk.WindowBase, [], null, null);
7216 gobject.signalNew('restored', gtk.WindowBase, [], null, null);
7217 gobject.signalNew('closed', gtk.WindowBase, [], null, null);
7218 /**
7219  * ComboBoxController is a core class of gtk.ComboBox to control all logic matters
7220  * to perform any specific action.
7221  * @constructor
7222  * @see gtk.ComboBox
7223  */
7224 gtk.ComboBoxController = function(view){
7225 	this._model = null;
7226 	var self = this;
7227 
7228 	this._render = function(model, parentNode){
7229 		var mashedUpdata = this.__mashupModel(model.getChildren());
7230 		view._renderDropDown(mashedUpdata, parentNode);
7231 	};
7232 
7233 	view.connect("_rendersubnodes", function(path, parentNode){
7234 		var childModel = self._model.getChildByPath(path);
7235 		self._render(childModel, parentNode);
7236 	});
7237 
7238 	view.connect("_search", function(value){
7239 		var model = self._model.search(value);
7240 		var path = model ? model.getPath() : "";
7241 		view._hilightRow(path);
7242 	});
7243 
7244 	view.connect("_itemselected", function(path){
7245 	    var childModel = self._model.getChildByPath(path);
7246 	    view._setSelectedItem(childModel.getValue())
7247 	});
7248 
7249 	view.connect("_valueMembersearched", function(valueMember, value){
7250 	    var childModel = self._model._searchByValueMember(valueMember, value);
7251 	    view._setSelectedItem(childModel.getValue())
7252 	});
7253 };
7254 
7255 /** @private */
7256 gtk.ComboBoxController.prototype.setModel = function(model){
7257 	this._model = model;
7258 	this._render(this._model, null);
7259 };
7260 
7261 /** @private */
7262 gtk.ComboBoxController.prototype.__mashupModel = function(nodes){
7263     var data = [], node, hasChild;
7264     for(var i = 0, len = nodes.length; i < len; i++){
7265         node = nodes[i];
7266         hasChild = node.getChildren().length  > 0;
7267         data.push({"display": node.getValue()["display"], "hasChildNodes": hasChild, "path": node.getPath(), "valueObject": node.getValue()});
7268     }
7269     return data;
7270 };
7271 /**
7272  * ComboBox is a class to create a combobox dropdown list that contains many optional choices
7273  * The combobox dropdown list stores data as model from gtk.TreeStore.
7274  * @see gtk.TreeStore
7275  * @constructor
7276  * @base gtk.Widget
7277  */
7278 gtk.ComboBox = function(){
7279     gtk.Widget.apply(this);
7280 
7281 	/** 'clicked' signal */
7282 	this.COMBOBOX_CLICKED = "clicked";
7283 	/** 'changed' signal */
7284 	this.COMBOBOX_CHANGED = "changed";
7285 
7286     this._minWidth = this._width = 150;
7287     this._minHeight = this._height = 30;
7288 
7289 	this._isToogled = false;
7290 	this._vBarWidth = 25;
7291 	this._isDropDownCreated = false;
7292 	this._selectedItem;
7293 
7294 	this._render = function(){
7295 	    this._domObj.className += " gtk_combobox";
7296 			this._entryHolder = jsgtk.Dom.create({tag: "div", append: this._domObj, className: "gtk_combobox_input_holder"});
7297 				this._entry = jsgtk.Dom.create({tag: "input", append: this._entryHolder, className: "gtk_combobox_input"});
7298 
7299 		    this._gradient = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_button_gradient"});
7300 
7301 			this._activeLayer = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_combobox_active_layer"});
7302 
7303 			this._labelContainer = jsgtk.Dom.create({'append': this._domObj, 'tag': 'div','class': 'gtk_combobox_label_container'});
7304     			var table = jsgtk.Dom.create({append: this._labelContainer, tag: "table"});
7305 	    			var tr = jsgtk.Dom.create({append: table, tag: "tr"});
7306 	    				var td = jsgtk.Dom.create({append: tr, tag: "td"});
7307 		    				this._labelDom = jsgtk.Dom.create({"append": td, "text": "- Please Select -", "tag": "div", 'class': 'gtk_combobox_label'});
7308 
7309 			var arrowImge = jsgtk.Dom.create({'append': this._domObj, 'tag': 'div','class': 'gtk_combobox_image_container'});
7310             arrowImge.style.width = this._vBarWidth + 'px';
7311     			var table = jsgtk.Dom.create({append: arrowImge, tag: "table"});
7312 	    			var tr = jsgtk.Dom.create({append: table, tag: "tr"});
7313 	    				var td = jsgtk.Dom.create({append: tr, tag: "td"});
7314 	    					jsgtk.Dom.create({append: td, tag: "div", "class": "gtk_combobox_image"});
7315 
7316 			this.__dropDown = jsgtk.Dom.create({tag: "div", append: document.body, className: "gtk_combobox_holder"});
7317 			jsgtk.Dom.hideElement(this.__dropDown);
7318 	};
7319 
7320 	this._render();
7321 	this._initEvent();
7322 	this._dropDownRendere = new gtk.SmartEntryDropDownRendere(this);
7323 	this._controller = new gtk.ComboBoxController(this);
7324 };
7325 
7326 gtk.ComboBox.prototype = new gtk.Widget();
7327 gtk.ComboBox.prototype.constructor = gtk.ComboBox;
7328 
7329 /**
7330  * A method to to set model onto the widget
7331  * @param {Object} model The object model value from gtk.TreeStore
7332  */
7333 gtk.ComboBox.prototype.setModel = function(model){
7334 	this._controller.setModel(model);
7335 };
7336 
7337 /**
7338  * A method to set selected item by any value member
7339  * @param {String} valueMember The name of value member assigned
7340  * @param {String or Integer} value The field value in accordance with its value member
7341  */
7342 gtk.ComboBox.prototype.setSelectedItemBy = function(valueMember, value){
7343     if(value) this.emit("_valueMembersearched", valueMember, value);
7344 };
7345 
7346 /**
7347  * A method to get/return object of selected item
7348  * @return {Object}, The object value of the selected item
7349  * @type Object
7350  */
7351 gtk.ComboBox.prototype.getSelectedItem = function(){
7352     return this._selectedItem;
7353 };
7354 
7355 /**
7356  * A method to set its tab index number
7357  * @param {Interger} index The tab index value to be set
7358  */
7359 gtk.ComboBox.prototype.setTabindex = function(index){
7360     this._domObj.tabIndex = index;
7361 };
7362 
7363 /** @private */
7364 gtk.ComboBox.prototype._addEventMouseWheel = function(scrollObj){
7365     var self = this;
7366     jsgtk.Event.addDomListener(scrollObj, 'scroll', function(e){
7367 	    self._deactivate();
7368 	}, false);
7369 };
7370 
7371 /**
7372  * A method to set displaying error or not
7373  * @param {Boolean} isOnError The boolean value to be passed: true is to show error, false is to hide
7374  */
7375 gtk.ComboBox.prototype.showError = function(isOnError){
7376 	this._showError = (typeof isOnError !== 'undefined' && typeof isOnError === 'boolean') ? isOnError : true;
7377 
7378     if(this._showError) this._domObj.className += " gtk_combobox_on_error";
7379     else this._domObj.className = "gtk_widget gtk_combobox";
7380 };
7381 
7382 /**
7383  * A method to get/return string value of selected item
7384  * @return {String} The text value of selected item
7385  * @type String
7386  */
7387 gtk.ComboBox.prototype.getActiveText = function(){
7388     return this._labelDom.innerHTML;
7389 };
7390 
7391 /**
7392  * A method to reload or refresh its contents
7393  */
7394 gtk.ComboBox.prototype.refresh = function(){
7395     this._isDropDownCreated = false;
7396     this._deactivate();
7397     this._clearDropDown();
7398 	this._labelDom.innerHTML = "- Please Select -";
7399 };
7400 
7401 /** @private */
7402 gtk.ComboBox.prototype._setSelectedItem = function(value){
7403     if(this._selectedItem === value) return;
7404     this._selectedItem = value;
7405     this._labelDom.innerHTML = value["display"];
7406     this.emit("changed", value);
7407 };
7408 
7409 /** @private */
7410 gtk.ComboBox.prototype._renderDropDown = function(children, parentNode){
7411 	var rowNodes = this._dropDownRendere._constructRowNodes(children, parentNode);
7412 	this._appendDropDown(rowNodes);
7413     this._isDropDownCreated = true;
7414 };
7415 
7416 /** @private */
7417 gtk.ComboBox.prototype._clearDropDown = function(){
7418 	this.__dropDown.innerHTML = "";
7419 };
7420 
7421 /** @private */
7422 gtk.ComboBox.prototype._handleRowNodeSelected = function(){
7423 	var selectedRowNode = this._dropDownRendere.getSelectedRowNode();
7424 	this.emit("_itemselected", selectedRowNode.id);
7425 	this._deactivate();
7426 };
7427 
7428 /** @private */
7429 gtk.ComboBox.prototype.__bindInputEvent = function(){
7430 	var jsgtkEvent = jsgtk.Event, self = this;
7431 	var timeoutId;
7432 	this.__inputKeyupId = jsgtkEvent.addDomListener(this._entry, "keydown", function(e){
7433 
7434 		switch(e.keyCode){
7435 			case gtk.DOWN_ARROW_KEY:
7436 				self.__fireDownArrowKey();
7437 				return;
7438 			case gtk.UP_ARROW_KEY:
7439 				self.__fireUpArrowKey();
7440 				return
7441 			case gtk.ENTER_KEY:
7442 				self.__fireEnterKey();
7443 				return;
7444 			case gtk.TAB_KEY:
7445 				self.__fireEnterKey();
7446 				jsgtk.Event.stopDefault(e);
7447 				return;
7448 		}
7449 
7450 		if(self._entry.value){
7451 
7452 			clearTimeout(timeoutId);
7453 
7454 			timeoutId = setTimeout(function(){
7455 
7456                 var text = self._entry.value;
7457                 var selectedRowNode = self._dropDownRendere.getSelectedRowNode();
7458 
7459 			    if(selectedRowNode) {
7460                     var isMatched = self._compareText(selectedRowNode.innerHTML, text);
7461                     if(!isMatched) self._handleSearch(text);
7462                 }else self._handleSearch(text);
7463 			}, 200);
7464 		}
7465 	});
7466 };
7467 
7468 /** @private */
7469 gtk.ComboBox.prototype._handleSearch = function(text){
7470     var lastCharacter = text[text.length - 1];
7471     this.emit("_search", lastCharacter);
7472     this._entry.value = lastCharacter;
7473 };
7474 
7475 /** @private */
7476 gtk.ComboBox.prototype._initEvent = function(){
7477 	var self = this;
7478 
7479 	jsgtk.Event.addDomListener(this._domObj, "mousedown", function(e){
7480 		if(self._isToogled)
7481 		    self._deactivate();
7482 		else
7483             self._activate();
7484 
7485 	    if(!self._isDropDownCreated) {
7486 	        self.emit("clicked");
7487 	        self._showLoading();
7488 	    }
7489 
7490 		jsgtk.Event.stopBubble(e);
7491 		jsgtk.Event.stopDefault(e);
7492 	});
7493 
7494 	jsgtk.Event.addDomListener(this.__dropDown, "mousedown", function(e){
7495 		var node = e.target;
7496 		if(jsgtk.Util.isMatched("gtk_smart_entry_drop_down_element", node.className)){
7497 			self._handleRowNodeSelected();
7498 		}
7499 		jsgtk.Event.stopBubble(e);
7500 	});
7501 
7502 	jsgtk.Event.addDomListener(this.__dropDown, "mouseover", function(e){
7503 		var node = e.target;
7504 		if(jsgtk.Util.isMatched("gtk_smart_entry_drop_down_element", node.className))
7505 			self._dropDownRendere.hilightRowNode(node);
7506 	});
7507 
7508 	jsgtk.Event.addDomListener(this._entry, "blur", function(e){
7509 		self._deactivate();
7510 		jsgtk.Event.stopBubble(e);
7511 	});
7512 
7513 	this.__bindInputEvent();
7514 };
7515 
7516 /** @private */
7517 gtk.ComboBox.prototype._compareText = function(text1, text2){
7518     var re = new RegExp("^" + text2.toLowerCase());
7519     var result = text1.toLowerCase().match(re);
7520     return result;
7521 };
7522 
7523 /** @private */
7524 gtk.ComboBox.prototype._hilightRow = function(path){
7525 	this._dropDownRendere.hilightRowById(path)
7526 };
7527 
7528 /** @private */
7529 gtk.ComboBox.prototype.setFocus = function(){
7530 	this._dropDownRendere._deHilightSelectedRow();
7531 	this._entry.focus();
7532 }
7533 
7534 /** @private */
7535 gtk.ComboBox.prototype.lostFocus = function(){
7536 	this._entry.blur();
7537 };
7538 
7539 /** @private */
7540 gtk.ComboBox.prototype._appendDropDown = function(dropDown){
7541 	this._hideLoading();
7542 	this.__dropDown.appendChild(dropDown);
7543 };
7544 
7545 /** @private */
7546 gtk.ComboBox.prototype._showLoading = function(){
7547 	this.__dropDown.className += " gtk_combobox_loading";
7548 };
7549 /** @private */
7550 gtk.ComboBox.prototype._hideLoading = function(){
7551 	this.__dropDown.className = "gtk_combobox_holder";
7552 };
7553 /** @private */
7554 gtk.ComboBox.prototype.__removeInputEvent = function(){
7555 	var jsgtkEvent = jsgtk.Event;
7556 	if(this.__inputKeypressId) jsgtkEvent.removeListener(this.__inputKeypressId);
7557 	if(this.__inputKeyupId) jsgtkEvent.removeListener(this.__inputKeyupId);
7558 };
7559 
7560 /** @private */
7561 gtk.ComboBox.prototype.__fireDownArrowKey = function(){
7562 	this._dropDownRendere.hilightNextRowNode();
7563 };
7564 
7565 /** @private */
7566 gtk.ComboBox.prototype.__fireUpArrowKey = function(){
7567 	this._dropDownRendere.hilightPreviousRowNode();
7568 };
7569 
7570 /** @private */
7571 gtk.ComboBox.prototype.__fireEnterKey = function(){
7572 	if(this._dropDownRendere.getSelectedRowNode()){
7573 		this._handleRowNodeSelected();
7574 
7575 		this._dropDownRendere._deHilightSelectedRow();
7576 	}
7577 };
7578 
7579 /** @private */
7580 gtk.ComboBox.prototype._setPosition = function(){
7581     var top = jsgtk.Util.pageY(this._domObj);
7582     var left = jsgtk.Util.pageX(this._domObj);
7583     var header = parseInt(this._domObj.style.height);
7584     var scrollY = this._getNearestScrollerY();
7585 
7586     this.__dropDown.style.top = top + header + 2 - scrollY + "px";
7587     this.__dropDown.style.left = left + 1 + "px";
7588 };
7589 
7590 /** @private */
7591 gtk.ComboBox.prototype._getNearestScrollerY = function(){
7592     var scrollY = 0;
7593     var parentNode = this._domObj.parentNode;
7594     while(parentNode.parentNode != null){
7595         if(/gtk_scroller_base/.test(parentNode.className)){
7596             scrollY = parentNode.scrollTop;
7597             this._addEventMouseWheel(parentNode);
7598             break;
7599         }
7600         parentNode = parentNode.parentNode;
7601     }
7602     return scrollY;
7603 };
7604 
7605 /** @private*/
7606 gtk.ComboBox.prototype._activate = function(){
7607 	this._isToogled = true;
7608 	this.setFocus();
7609 	jsgtk.Dom.showElement(this.__dropDown);
7610     jsgtk.Dom.showElement(this._activeLayer);
7611     this._domObj.className += " gtk_combobox_active";
7612 	this._setPosition();
7613 };
7614 
7615 /** @private*/
7616 gtk.ComboBox.prototype._deactivate = function(){
7617 	this._isToogled = false;
7618 	this.lostFocus();
7619 	jsgtk.Dom.hideElement(this.__dropDown);
7620     jsgtk.Dom.hideElement(this._activeLayer);
7621     this._domObj.className = "gtk_widget gtk_combobox";
7622 };
7623 
7624 /** @private */
7625 gtk.ComboBox.prototype.resizeWidthComposite = function(width){
7626 	this._width = width;
7627 	this._domObj.style.width = width + 'px';
7628 		this._labelContainer.style.width = width - this._vBarWidth - 9 + "px";
7629 		this.__dropDown.style.width = width + "px";
7630 };
7631 
7632 /** @private */
7633 gtk.ComboBox.prototype.resizeHeightComposite = function(height){
7634 	this._height = height;
7635 	this._domObj.style.height = height + 'px';
7636 };
7637 
7638 gobject.signalNew("_rendersubnodes", gtk.ComboBox, null, null, []);
7639 gobject.signalNew("_setselectedvalues", gtk.ComboBox, null, null, []);
7640 gobject.signalNew("_search", gtk.ComboBox, null, null, []);
7641 gobject.signalNew("_itemselected", gtk.ComboBox, null, null, []);
7642 gobject.signalNew("_valueMembersearched", gtk.ComboBox, null, null, []);
7643 gobject.signalNew("changed", gtk.ComboBox, null, null, []);
7644 gobject.signalNew("clicked", gtk.ComboBox, null, null, []);
7645 /**
7646  * TreeIter is an assistant class to create model or structure of a model
7647  * @constructor
7648  * @base gtk.Object
7649  */
7650 gtk.TreeIter = function(path){
7651 	gtk.Object.apply(this);
7652 
7653 	this._modelType = gtk.TREE_ITER;
7654  	this.path = path ? path : "0";
7655  	this.hasNode = false;
7656  	this.children = [];
7657  	this._value;
7658 };
7659 
7660 gtk.TreeIter.prototype = new gtk.Object();
7661 gtk.TreeIter.prototype.constructor = gtk.TreeIter;
7662 
7663 gtk.TreeIter.prototype.getChldBy = function(valueMember, value){
7664     var strValue = String(this._value[valueMember]).toLowerCase();
7665     var strToCompare = String(value).toLowerCase();
7666 
7667 	if(strValue === strToCompare) return this;
7668 	for(var i = this.children.length; i--;){
7669 		return this.children[i].getChldBy(valueMember, value);
7670 	}
7671 };
7672 
7673 gtk.TreeIter.prototype.setRow = function(value){
7674 	this._value = value;
7675 };
7676 
7677 gtk.TreeIter.prototype.getValue = function(){
7678 	return this._value;
7679 };
7680 
7681 gtk.TreeIter.prototype.getModelType = function(){
7682 	return this._modelType;
7683 };
7684 
7685 /**
7686  * Returns a copy of the treeiter.
7687  * return {object} treeiter
7688  */
7689 gtk.TreeIter.prototype.copy = function(){
7690  	return this;
7691 };
7692 
7693 gtk.TreeIter.prototype.getChildByPath = function(path){
7694     var paths = path.split(":");
7695 
7696     var child = this._getChildByPath( parseInt(paths[0]) );
7697 
7698     paths.splice(0,1);
7699     if(paths.length === 1) return child;
7700 
7701     return child.getChildByPath(paths.join(":"));
7702 };
7703 
7704 gtk.TreeIter.prototype._getChildByPath = function(path){
7705 	for(var i = this.children.length; i--;){
7706 		var childPath = this.children[i].path.split(":");
7707 		if(parseInt(childPath[childPath.length - 2]) === path) return this.children[i];
7708 	}
7709 	return null;
7710 };
7711 
7712 gtk.TreeIter.prototype.updateValue = function(value){
7713     this._value["value"] = value;
7714     this.emit("valueupdated", this.path, value);
7715 };
7716 
7717 gtk.TreeIter.prototype.getPath = function(){
7718 	return this.path;
7719 };
7720 
7721 /**
7722 * getChildren() method
7723 * @param {array} children: array of children of gtk.TreeIter type
7724 */
7725 gtk.TreeIter.prototype.getChildren = function(){
7726 	return this.children;
7727 };
7728 
7729 /**
7730 * add() method
7731 * @param{object} child: object of of gtk.TreeIter type
7732 */
7733 gtk.TreeIter.prototype.add = function(child){
7734 	this.children.push(child);
7735 };
7736 
7737 /*
7738 * remove() method : remove a child
7739 * @param {object} child: child of gtk.TreeIter type
7740 */
7741 gtk.TreeIter.prototype.remove = function(child){
7742 	for(var i = this.children.length; i--;){
7743 		if(this.children[i] === child){
7744 			this.children.splice(i, 1);
7745 			break;
7746 		}
7747 	}
7748 };
7749 
7750 /**
7751 * getChild() method
7752 * @param {integer} index : index of child
7753 * @return {object} child: child of gtk.TreeIter type
7754 */
7755 gtk.TreeIter.prototype.getChild = function(index){
7756 	return this.children[index] || null;
7757 };
7758 
7759 /** @private */
7760 gtk.TreeIter.prototype._search = function(text){
7761 	var re = new RegExp("^" + text.toLowerCase());
7762 
7763     var children = this.getChildren();
7764     var len = children.length;
7765     if(len > 0){
7766 		for(var i = 0 ; i < len; i++){
7767 			var child = children[i];
7768 	    	this._child = child._search(text);
7769 	    	if(this._child) return this._child;
7770 		}
7771 	}
7772 	else{
7773     	var row = this.getValue()["display"];
7774 	    var result = row.toLowerCase().match(re);
7775 		if(result)
7776 			return this;
7777 	}
7778 };
7779 
7780 gobject.signalNew('valueupdated', gtk.TreeIter, [], null, null);
7781 /**
7782  * @constructor
7783  * @param {array} headers columns of header
7784  * @base gtk.Object
7785  */
7786 gtk.ListStore = function(headers){
7787  	gtk.Object.apply(this);
7788 	this._modelType = gtk.ListStore;
7789  	this.children   = new Array();
7790 	this._headers   = headers || [];
7791  };
7792 
7793 gtk.ListStore.prototype = new gtk.Object();
7794 gtk.ListStore.prototype.constructor = gtk.ListStore;
7795 
7796 /**
7797  * appends a new row to the liststore
7798  * @param {object} json object
7799  * @return {gtk.TreeIter}
7800  * @see gtk.TreeIter
7801  */
7802 gtk.ListStore.prototype.append = function(row){
7803     var self = this;
7804 	row["value"] = this._filterRow(row["value"]);
7805 	var iter = new gtk.TreeIter(this.children.length.toString() + ':');
7806 	iter.setRow(row);
7807 	this.add(iter);
7808 	iter.connect("valueupdated", function(path, value){
7809         self.emit("rowupdated", path, value);
7810 	});
7811 	return iter;
7812 };
7813 
7814 /** @private */
7815 gtk.ListStore.prototype.appendToHeader = function(header){
7816     this._headers.push(header);
7817 };
7818 
7819 /**
7820  * appends new rows to the liststore
7821  * @param {array} arrow of json object
7822  * @return {array} array of gtk.TreeIter object
7823  * @see gtk.TreeIter
7824  */
7825 gtk.ListStore.prototype.appendRows = function(rows){
7826     if(rows.length > 0){
7827         var payloadRows = [];
7828 
7829         for(var i = 0, len = rows.length; i < len; i++){
7830             payloadRows.push(this.append(rows[i]));
7831         }
7832 
7833         this.emit("rowsupdated", payloadRows);
7834     }
7835 	return payloadRows;
7836 };
7837 
7838 /**
7839  * Return gtk.TreeIter object
7840  * @param {string} path which is id of each gtk.TreeIter object
7841  * @return {gtk.TreeIter}
7842  */
7843 gtk.ListStore.prototype.getChildByPath = function(path){
7844     for(var i = this.children.length; i--;){
7845         var child = this.children[i];
7846         if(child.getPath() === path) return child;
7847     }
7848 };
7849 
7850 /** @private */
7851 gtk.ListStore.prototype.getModelType = function(){
7852 	return this._modelType;
7853 };
7854 
7855 /** @private */
7856 gtk.ListStore.prototype.getColumnsWidth = function(){
7857     var widths = [];
7858     for(var i = 0, len = this._headers.length; i < len; i++){
7859         widths.push(this._headers[i].width);
7860     }
7861     return widths;
7862 };
7863 
7864 /** @private */
7865 gtk.ListStore.prototype.getWidths = function(){
7866     var width = 0;
7867     for(var i = this._headers.length; i--;){
7868         width += this._headers[i].width;
7869     }
7870     return width;
7871 };
7872 
7873 /** @private */
7874 gtk.ListStore.prototype._filterRow = function(row){
7875 	var filters = [];
7876 	for(var i = 0, len = this._headers.length; i < len; i++){
7877 		if(row[i] === null || row[i] === "" || row[i] === " " || row[i] === undefined){
7878 			filters.push('N/A');
7879 			continue;
7880 		}
7881 		filters.push(row[i]);
7882  	}
7883  	return	filters;
7884 };
7885 
7886 /**
7887  * Return all gtk.TreeIter
7888  * @return {array}
7889  */
7890 gtk.ListStore.prototype.getChildren = function(){
7891 	return this.children;
7892 };
7893 
7894 /** @private */
7895 gtk.ListStore.prototype.getHeaders = function(){
7896 	return this._headers;
7897 };
7898 
7899 /** @private */
7900 gtk.ListStore.prototype.add = function(child){
7901 	this.children.push(child);
7902 };
7903 
7904 /**
7905  * Remove gtk.TreeIter from gtk.ListStor
7906  * @param {gtk.TreeIter}
7907  */
7908 gtk.ListStore.prototype.remove = function(child){
7909 	for(var i = this.children.length; i--;){
7910 		if(this.children[i] === child){
7911 			this.children.splice(i, 1);
7912 			break;
7913 		}
7914 	}
7915 };
7916 
7917 /**
7918  * Return gtk.TreeIter by index
7919  * @param {integer} index
7920  */
7921 gtk.ListStore.prototype.getChild = function(index){
7922 	return this.children[index] || null;
7923 };
7924 
7925 /** @private */
7926 gtk.ListStore.prototype._getColumn = function(valueMember){
7927     for(var i = 0, len = this._headers.length; i < len; i++){
7928         if(this._headers[i]["title"] === valueMember) return i;
7929     }
7930     return 0;
7931 };
7932 
7933 /**
7934  * @private
7935  */
7936 gtk.ListStore.prototype.search = function(valueMember, value){
7937     var column = this._getColumn(valueMember);
7938     var re = new RegExp("^" + value.toString().toLowerCase());
7939     var children = this.children;
7940     var result = "";
7941     for(var i = 0, len = children.length; i < len; i++){
7942         result = children[i].getValue().value[column].toString().toLowerCase().match(re);
7943         if(result){
7944             return children[i];
7945         }
7946     }
7947     return children[0];
7948 };
7949 
7950 /** @private */
7951 gtk.ListStore.prototype.filter = function(value, valueMember){
7952     var column = this._getColumn(valueMember);
7953     var filteredChildren = [];
7954     var re = new RegExp("^" + value.toString().toLowerCase());
7955     var children = this.children;
7956     var result = "";
7957 
7958     for(var i = 0, len = children.length; i < len; i++){
7959         result = children[i].getValue().value[column].toString().toLowerCase().match(re);
7960         if(result){
7961             filteredChildren.push(children[i]);
7962         }
7963     }
7964     return filteredChildren;
7965 };
7966 
7967 gobject.signalNew('rowsupdated', gtk.ListStore, [], null, null);
7968 gobject.signalNew('rowupdated', gtk.ListStore, [], null, null);
7969 /**
7970  * @constructor
7971  * @base gtk.Widget
7972  * @param {gtk.ListStor} model
7973  * @link gtk.ListStor
7974  */
7975 gtk.ListView = function(model){
7976 	gtk.Widget.apply(this);
7977 
7978 	/** 'rowselected' signal */
7979 	this.LISTVIEW_ROWSELECTED = 'rowselected';
7980 	/** 'rowclicked' signal */
7981 	this.LISTVIEW_ROWCLICKED = 'rowclicked';
7982 	/** 'rowover' signal */
7983 	this.LISTVIEW_ROWOVER = 'rowover';
7984 	/** 'rowout' signal */
7985 	this.LISTVIEW_ROWOUT = 'rowout';
7986 	/** 'rowdoubleclicked' signal */
7987 	this.LISTVIEW_ROWDOUBLECLICKED = 'rowdoubleclicked';
7988 
7989 	this._width            = this._minWidth = 400;
7990 	this._height           = this._minHeight = 100;
7991     this._titleHeight      = 19;
7992     this._cellHeight       = 18;
7993 	this._bodyHeight       = this._height - this._cellHeight;
7994 	this._columnsWidth     = [];
7995 
7996 	this._headerVisible    = true;
7997 	this._leftPadding      = 4;
7998 	this._model            = model || null;
7999 	this._selectedRow      = null;
8000 	this._emptyRows        = [];
8001 	this._rowIndex         = -1;
8002 	this._border           = 2;
8003 	this._selectedRowPath  = "";
8004 	this._hilightedRowNode    = null;
8005 	this._parentWidth      = this._width;
8006 	this._valueMember      = "";
8007 	this._createTooltip    = false;
8008 	this._selectedRowIndex = 0;
8009 
8010 	this._render = function(){
8011 		this._domObj.className   += " gtk_listview";
8012             this._tableDom = jsgtk.Dom.create({"append": this._domObj, "tag": "TABLE", "BORDER": "0","CELLPADDING": "6", "class": "gtk_listview_table"});
8013                 this._headerDom = jsgtk.Dom.create({"append": this._tableDom, "tag": "THEAD", "class": "gtk_listview_table_head"});
8014                 this._bodyDom   = jsgtk.Dom.create({"append": this._tableDom, "tag": "TBODY", "class": "gtk_listview_table_body"});
8015                 this._footerDom = jsgtk.Dom.create({"append": this._tableDom, "tag": "TFOOT", "class": "gtk_listview_table_footer"});
8016 
8017             this._vGhost = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_listview_vghost"});
8018             jsgtk.Dom.hideElement(this._vGhost);
8019 
8020             this._headerDomGhost = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_listview_table_head_ghost"});
8021             jsgtk.Dom.hideElement(this._headerDomGhost);
8022 
8023         this._hiddenTextBox = jsgtk.Dom.create({"append":  document.body, "tag": "input", "type": "text",  "class": "gtk_listview_hiddent_textbox"});
8024 
8025         this._grayOutBackground   = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_gray_out"});
8026         this._loadingImgContainer = jsgtk.Dom.create({"append": this._domObj, "tag": "div", "class": "gtk_loading_bar_container_listview"});
8027             this._loadingImg      = jsgtk.Dom.create({"append": this._loadingImgContainer, "tag": "div", "class": "gtk_loading_bar_listview"});
8028 
8029         jsgtk.Dom.hideElement(this._grayOutBackground);
8030         jsgtk.Dom.hideElement(this._loadingImgContainer);
8031 	};
8032 	this._render();
8033 
8034 	this._model = model;
8035 	new gtk.ListViewController(this, this._model);
8036 
8037 	this._enableSortable();
8038 
8039 	this._keyControllEvent();
8040 };
8041 
8042 gtk.ListView.prototype = new gtk.Widget();
8043 gtk.ListView.prototype.constructor = gtk.ListView;
8044 
8045 /**
8046  * Show loading bar
8047  */
8048 gtk.ListView.prototype.showLoading = function(){
8049     jsgtk.Dom.showElement(this._grayOutBackground);
8050     jsgtk.Dom.showElement(this._loadingImgContainer);
8051 };
8052 
8053 
8054 /**
8055  * Hide loading bar
8056  */
8057 gtk.ListView.prototype.hideLoading = function(){
8058     jsgtk.Dom.hideElement(this._grayOutBackground);
8059     jsgtk.Dom.hideElement(this._loadingImgContainer);
8060 };
8061 
8062 /**
8063  * Return number of none empty row
8064  * @return {integer}
8065  */
8066 gtk.ListView.prototype.getNumberOfActiveRow = function(){
8067     var rowNodes = this._bodyDom.childNodes, count = 0;
8068     for(var i = 0, len = rowNodes.length; i < len; i++){
8069         var emptyRowId = new RegExp("^" + "empty_");
8070         if(!rowNodes[i].id.match(emptyRowId)) count++;
8071     }
8072     return count;
8073 };
8074 
8075 /**
8076  * set the next row of current selected row selected
8077  */
8078 gtk.ListView.prototype.setNextSelectedRow = function(){
8079     var nextRow = this._hilightedRowNode ? this._hilightedRowNode.nextSibling : this._bodyDom.firstChild;
8080     this._rowIndex = this._getIndex(nextRow);
8081     this._hilightCell(this._rowIndex);
8082     this._emitSelectedRowSignalToController(nextRow.id);
8083 };
8084 
8085 /**
8086  * set selected row by index
8087  * @param {integer} index
8088  */
8089 gtk.ListView.prototype.setSelectedRowByIndex = function(index){
8090     var childLen = this._model.children.length;
8091     this._rowIndex = index > childLen ? childLen-1 : index;
8092     this._hilightCell(this._rowIndex);
8093     var path = this._bodyDom.childNodes[this._rowIndex].id;
8094     this._emitSelectedRowSignalToController(path);
8095     this.emit("rowclicked", this.getSelectedRow());
8096 };
8097 
8098 /**
8099  * set selected row by key value
8100  * @param {any type} key
8101  * @param {any type} value
8102  */
8103 gtk.ListView.prototype.setSelectedRowByValue = function(valueMember, value){
8104     this.emit("searchcontenttocontroller", valueMember, value);
8105     this.emit("rowclicked", this.getSelectedRow());
8106 };
8107 
8108 /**
8109  * filter row by key value
8110  * @param {any type} key
8111  * @param {any type} value
8112  */
8113 gtk.ListView.prototype.filterRowsByValue = function(valueMember, value){
8114     this.emit("filterrowstocontroller", valueMember, value);
8115 };
8116 
8117 /** @private */
8118 gtk.ListView.prototype.hilightSelectedRow = function(path){
8119     this._rowIndex = this._getRowIndexById(path);
8120     this._hilightCell(this._rowIndex);
8121 
8122     this._scrollTableBodyByIndex(this._rowIndex);
8123 };
8124 
8125 /**
8126  * set model for gtk.ListView
8127  * @param {gtk.ListStor} model
8128  */
8129 gtk.ListView.prototype.setModel = function(model){
8130     this._model = model;
8131     this._refreshView();
8132     this.emit("refreshmodel", model);
8133 
8134     this.resizeHeightComposite(this._height + 2);
8135     this.resizeWidthComposite(this._parentWidth);
8136 };
8137 
8138 /** @private */
8139 gtk.ListView.prototype._getRowById = function(id){
8140     var rows = this._bodyDom.childNodes;
8141     for(var i = 0, len = rows.length; i < len; i++){
8142         if(rows[i].id === id) return rows[i];
8143     }
8144     return rows[0];
8145 };
8146 
8147 /** @private */
8148 gtk.ListView.prototype._getRowIndexById = function(id){
8149     var rows = this._bodyDom.childNodes;
8150     for(var i = 0, len = rows.length; i < len; i++){
8151         if(rows[i].id === id) return i;
8152     }
8153     return 0;
8154 };
8155 
8156 /** @private */
8157 gtk.ListView.prototype.getCellHeight = function(){
8158     return this._cellHeight;
8159 };
8160 
8161 /**
8162  * enale row selection by using arrow key
8163  */
8164 gtk.ListView.prototype.activateArrowKey = function(){
8165     this._hiddenTextBox.focus();
8166 };
8167 
8168 /** @private */
8169 gtk.ListView.prototype._scrollTableBodyByIndex = function(rowIndex){
8170     var bodyHeight = this._height - this._cellHeight;
8171     var currentScrollTop = rowIndex * this._cellHeight;
8172     var offsetTop = currentScrollTop - bodyHeight;
8173     this._bodyDom.scrollTop += offsetTop + 36;
8174 };
8175 
8176 /** @private */
8177 gtk.ListView.prototype._refreshView = function(){
8178     this._headerDom.innerHTML = "";
8179     this._bodyDom.innerHTML = "";
8180     this._hilightedRowNode = null;
8181 };
8182 
8183 /** @private */
8184 gtk.ListView.prototype._hilightCell = function(index){
8185     if(this._hilightedRowNode) jsgtk.Dom.applyAttributes(this._hilightedRowNode, {"backgroundColor": ""});
8186     this._hilightedRowNode = this._bodyDom.childNodes[index];
8187     jsgtk.Dom.applyAttributes(this._hilightedRowNode, {"backgroundColor": "#FFFF66"});
8188 
8189     if(index !== this._selectedRowIndex){
8190         var selectedRowNode = this._bodyDom.childNodes[this._selectedRowIndex];
8191         jsgtk.Dom.applyAttributes(selectedRowNode, {"backgroundColor": ""});
8192     }
8193 };
8194 
8195 /** @private */
8196 gtk.ListView.prototype._hilightCellByArrowKey = function(index){
8197     if(this._hilightedRowNode){
8198         jsgtk.Dom.applyAttributes(this._hilightedRowNode, {"backgroundColor": ""});
8199     }
8200     this._hilightedRowNode = this._bodyDom.childNodes[index];
8201     jsgtk.Dom.applyAttributes(this._hilightedRowNode, {"backgroundColor": "#FFFFCC"});
8202 
8203     if(index !== this._selectedRowIndex){
8204         var selectedRowNode = this._bodyDom.childNodes[this._selectedRowIndex];
8205         jsgtk.Dom.applyAttributes(selectedRowNode, {"backgroundColor": "#FEFA89"});
8206     }
8207 };
8208 
8209 /** @private */
8210 gtk.ListView.prototype._emitSelectedRowSignalToController = function(path){
8211     var emptyRowId = new RegExp("^" + "empty_");
8212 
8213     if(!path.match(emptyRowId) && this._selectedRowPath !== path) {
8214         this.emit("_rowselectedtocontroller", path);
8215         this._selectedRowPath = path;
8216     }
8217 };
8218 
8219 /** @private */
8220 gtk.ListView.prototype._enableSortable = function(){
8221     jsgtk.Dom.SortTable(this._tableDom);
8222 };
8223 
8224 /** @private */
8225 gtk.ListView.prototype.updateRowValue = function(path, value){
8226     var childNodes = this._getRowById(path).childNodes;
8227     for(var i = 0, len = childNodes.length; i < len; i++){
8228         childNodes[i].firstChild.innerHTML = value[i];
8229     }
8230 };
8231 
8232 /** @private */
8233 gtk.ListView.prototype._constructRowColumns = function(tr, columns, columnsData){
8234     for(var j = 0, len = columns; j < len; j++){
8235         var td = jsgtk.Dom.create({"append": tr, "tag": "TD", "class": "gtk_listview_table_body_td"});
8236             var cell = jsgtk.Dom.create({"append": td, "tag": "DIV", "class": "gtk_listview_table_body_td_cell"});
8237             if(columnsData[j]) cell.innerHTML = columnsData[j];
8238             cell.style.height =  this._cellHeight + "px";
8239             if( j === len - 1) jsgtk.Dom.hideElement(cell);
8240     }
8241 };
8242 
8243 /** @private */
8244 gtk.ListView.prototype._constructBodyRow = function(index, path, columns, columnsData){
8245     var tr = jsgtk.Dom.create({"tag": "TR", "class": "gtk_listview_table_body_tr", "id": path});
8246 
8247     if(index % 2 === 0) tr.className += " gtk_listview_table_body_tr_even";
8248     else tr.className += " gtk_listview_table_body_tr_odd";
8249 
8250     this._constructRowColumns(tr, columns, columnsData);
8251 
8252     return tr;
8253 };
8254 
8255 /** @private */
8256 gtk.ListView.prototype._storeEmptyRows = function(tr, path){
8257     var emptyRowId = new RegExp("^" + "empty_");
8258     if(path.match(emptyRowId)) this._emptyRows.push(tr);
8259 };
8260 
8261 /** @private */
8262 gtk.ListView.prototype._resetSelectedRowPath = function(){
8263     this._selectedRowPath = "";
8264 
8265 };
8266 
8267 /** @private */
8268 gtk.ListView.prototype.renderEmptyRows = function(children, columns){
8269     this.constructBody(children, columns);
8270 };
8271 
8272 /** @private */
8273 gtk.ListView.prototype.renderRows = function(children, columns){
8274     this.constructBody(children, columns);
8275 };
8276 
8277 /** @private */
8278 gtk.ListView.prototype.constructBody = function(children, columns){
8279     this._resetSelectedRowPath();
8280 	var docFragment = document.createDocumentFragment();
8281 	for(var i = 0, len = children.length; i < len; i++){
8282 	    var path = children[i]["path"];
8283 
8284 	    var tr = this._constructBodyRow(i, path, columns, children[i]["rows"]);
8285         docFragment.appendChild(tr);
8286 
8287 	    this._handleRowEvent(tr, path);
8288 
8289 	    this._storeEmptyRows(tr, path);
8290 	}
8291 
8292 	this._bodyDom.appendChild(docFragment);
8293 	this._enableSortable();
8294 };
8295 
8296 /** @private */
8297 gtk.ListView.prototype.refreshRows = function(){
8298     this._bodyDom.innerHTML = "";
8299     this._hilightedRowNode = null;
8300 };
8301 
8302 /** @private */
8303 gtk.ListView.prototype.clearEmptyRows = function(){
8304     for(var i = 0, len = this._emptyRows.length; i < len; i++){
8305         if(this._emptyRows[i].parentNode) this._bodyDom.removeChild(this._emptyRows[i]);
8306     }
8307     this._emptyRows = [];
8308 };
8309 
8310 /** @private */
8311 gtk.ListView.prototype.constructHeader = function(headers){
8312 	var tr = jsgtk.Dom.create({"append": this._headerDom, "tag": "TR", "class": "gtk_listview_table_head_tr"});
8313 
8314 	var docFragment = document.createDocumentFragment();
8315 
8316 	for(var i = 0, len = headers.length; i < len; i++){
8317 	    var td = jsgtk.Dom.create({"append": docFragment, "tag": "TD", "width": headers[i].width, "height": this._titleHeight, "class": "gtk_listview_table_head_td"});
8318 	        var div = jsgtk.Dom.create({"append": td, "tag": "div", "width": headers[i].width, "class": "gtk_listview_table_head_td_div"});
8319 
8320                 var textSpan = jsgtk.Dom.create({"append": div, "tag": "span", "text": headers[i].title, "style" : "float: left;", "class": "gtk_listview_table_head_td_div_span"});
8321 	            var sortArrow = jsgtk.Dom.create({"append": div, "tag": "div", "style" : "float: left;", "class": "gtk_listview_table_head_td_div_sortarrow arrowdown"});
8322 	            jsgtk.Dom.hideElement(sortArrow);
8323 
8324 	            var vbar = jsgtk.Dom.create({"append": div, "tag": "div", "class": "gtk_listview_table_head_td_div_vbar"});
8325 	            vbar.style.left = headers[i].width - this._leftPadding + "px";
8326 
8327 	            this._handleColumnResizeEvent(i, vbar);
8328 	            this._handleCellEvent(i, div, sortArrow);
8329 
8330 	            if( i === len - 1){
8331 	                jsgtk.Dom.hideElement(vbar);
8332                     div.removeChild(sortArrow);
8333 	            }
8334     }
8335     tr.appendChild(docFragment);
8336 };
8337 
8338 /** @private */
8339 gtk.ListView.prototype._getIndex = function(row){
8340     var rows = this._bodyDom.childNodes;
8341     for(var i = 0, len = rows.length; i < len; i++){
8342         if(rows[i] === row) return i;
8343     }
8344 };
8345 
8346 /** @private */
8347 gtk.ListView.prototype._increaseColumnWidth = function(offsetWidth){
8348 
8349     var secondLastColumnMinColWidth = this._model.getColumnsWidth()[this._columnsWidth.length - 2];
8350 
8351     var width = this._columnsWidth[this._columnsWidth.length - 2] - offsetWidth;
8352     width = width < secondLastColumnMinColWidth ? secondLastColumnMinColWidth : width;
8353 
8354     if(width > secondLastColumnMinColWidth){
8355         this._columnsWidth[this._columnsWidth.length - 2] = width;
8356         this._resizeWidth(this._width);
8357     }else this._resizeWidth(this._width + offsetWidth);
8358 };
8359 
8360 /** @private */
8361 gtk.ListView.prototype._decreaseColumnWidth = function(offsetWidth){
8362     this._columnsWidth[this._columnsWidth.length - 2] -= offsetWidth;
8363     this._resizeWidth(this._width);
8364 };
8365 
8366 /** @private */
8367 gtk.ListView.prototype._isSecondLastColumn = function(index){
8368     return index === this._columnsWidth.length - 2;
8369 };
8370 
8371 /** @private */
8372 gtk.ListView.prototype._updateColumWidth = function(index, offsetWidth){
8373 
8374     this._columnsWidth[index] += offsetWidth;
8375 
8376     if(this._isSecondLastColumn()) {
8377         this._resizeWidth(this._width + offsetWidth);
8378         return;
8379     }
8380 
8381     if(offsetWidth > 0)
8382         this._increaseColumnWidth(offsetWidth);
8383     else
8384         this._decreaseColumnWidth(offsetWidth);
8385 };
8386 
8387 /** @private */
8388 gtk.ListView.prototype._getGhostPosition = function(index){
8389     var left = 0;
8390     for(var i = 0; i <= index; i++){
8391         left += this._columnsWidth[i];
8392     }
8393     return left;
8394 };
8395 
8396 /**
8397  * Return model of gtk.ListView
8398  * @return {gtk.ListStor} model
8399  */
8400 gtk.ListView.prototype.getModel = function(){
8401 	return this._model;
8402 };
8403 
8404 /** @private */
8405 gtk.ListView.prototype.resetMinHeight = function(minHeight){
8406     this._minHeight = minHeight;
8407     this._resizeHeight(minHeight);
8408 };
8409 
8410 /** @private */
8411 gtk.ListView.prototype.resize = function(width, height){
8412     this._resizeWidth(width);
8413     this._resizeHeight(height);
8414 };
8415 
8416 /** @private */
8417 gtk.ListView.prototype.setMinColumnsWidth = function(columnsWidth, width){
8418     this._columnsWidth = [];
8419 
8420     for(var i = 0, len = columnsWidth.length; i < len; i++){
8421         this._columnsWidth.push(columnsWidth[i]);
8422     }
8423     this._minWidth = width;
8424     this._width = this._minWidth;
8425 };
8426 
8427 /** @private */
8428 gtk.ListView.prototype.getMinWidthComposite = function(){
8429     return this._minWidth;
8430 };
8431 
8432 /** @private */
8433 gtk.ListView.prototype._resizeHeight = function(height){
8434     this._height = height;
8435     this._domObj.style.height = this._height + "px";
8436     this._vGhost.style.height = this._height + "px";
8437 
8438     this._tableDom.style.height = this._height + "px";
8439     this._bodyHeight = this._height - this._cellHeight;
8440     this._bodyDom.style.height = this._bodyHeight + "px";
8441 };
8442 
8443 /** @private */
8444 gtk.ListView.prototype._resizeHeaderWidth = function(){
8445     var headerNodes = this._headerDom.firstChild.childNodes;
8446     for(var i = 0, len = this._columnsWidth.length; i < len; i++){
8447         headerNodes[i].width = this._columnsWidth[i];
8448         headerNodes[i].firstChild.style.width = this._columnsWidth[i] + "px";
8449         headerNodes[i].firstChild.lastChild.style.left = this._columnsWidth[i] - this._leftPadding + "px";
8450     }
8451 };
8452 
8453 /** @private */
8454 gtk.ListView.prototype._resizeWidth = function(width){
8455     this._width = width > this._width ? width : this._width;
8456     this._domObj.style.width = this._width - 2 + "px";
8457     this._resizeHeaderWidth();
8458 };
8459 
8460 /** @private */
8461 gtk.ListView.prototype.setSelectedRow = function(data){
8462     this._selectedRow = data;
8463 };
8464 
8465 /**
8466  * Return the selected row's value
8467  * @return {object}
8468  */
8469 gtk.ListView.prototype.getSelectedRow = function(data){
8470     return this._selectedRow;
8471 };
8472 
8473 /** @private */
8474 gtk.ListView.prototype.setParentWidth = function(width){
8475     this._parentWidth = width;
8476 };
8477 
8478 /** @private */
8479 gtk.ListView.prototype.resizeHeightComposite = function(height){
8480     if(height >= this._minHeight){
8481         this._resizeHeight(height - 2);
8482         this.emit("_renderemptyrows", height - this._cellHeight, this._cellHeight);
8483     }
8484 };
8485 
8486 /** @private */
8487 gtk.ListView.prototype.resizeWidthComposite = function(width){
8488     if(width >= this._minWidth){
8489 
8490         var offsetWidth = Math.ceil((width - this._width) / (this._columnsWidth.length - 1));
8491 
8492         for(var i = this._columnsWidth.length - 1; i--;) this._columnsWidth[i] += offsetWidth;
8493 
8494         this._width = width;
8495         this._resizeWidth(width);
8496     }
8497 };
8498 
8499 /** @private */
8500 gtk.ListView.prototype._handleRowEvent = function(row, path){
8501     var self = this;
8502     var jsgtkEvent = jsgtk.Event;
8503     jsgtkEvent.addDomListener(row, "click", function(e){
8504 
8505         self.activateArrowKey();
8506         self._emitSelectedRowSignalToController(path);
8507         self.hideTooltip();
8508 
8509         self._rowIndex = self._getIndex(this);
8510         self._selectedRowIndex = self._rowIndex;
8511 
8512         if(!self._isEmptyRowClicked(self._rowIndex)){
8513             self.emit("rowclicked", self.getSelectedRow());
8514             self._hilightCell(self._rowIndex);
8515         }
8516         jsgtkEvent.stopBubble(e);
8517     });
8518    jsgtkEvent.addDomListener(row, "mouseover", function(e){
8519         var rowOver = e.target.parentNode.parentNode;
8520         self.emit("rowover",e,rowOver);
8521         jsgtkEvent.stopBubble(e);
8522     });
8523     jsgtkEvent.addDomListener(row, "mouseout", function(e){
8524         self.emit("rowout");
8525         jsgtkEvent.stopBubble(e);
8526     });
8527 
8528     jsgtkEvent.addDomListener(row, "dblclick", function(e){
8529         self._selectedRowIndex = self._rowIndex;
8530         self.hideTooltip();
8531 
8532         if(!self._isEmptyRowClicked(self._rowIndex)){
8533             self.emit("rowdoubleclicked", self.getSelectedRow());
8534         }
8535         jsgtkEvent.stopBubble(e);
8536     });
8537 };
8538 
8539 /** @private */
8540 gtk.ListView.prototype._isEmptyRowClicked = function(selectedIndex){
8541     var isEmptyRow = false;
8542     if(this._model !== null){
8543         var LastChildIndex = this._model.children.length - 1;
8544         if(LastChildIndex < selectedIndex){
8545             isEmptyRow = true;
8546         }
8547     }
8548     return isEmptyRow;
8549 };
8550 
8551 /** @private */
8552 gtk.ListView.prototype._showVGhost = function(index){
8553     var left = this._getGhostPosition(index);
8554     this._vGhost.style.left = left - 4 + "px";
8555     jsgtk.Dom.showElement(this._vGhost);
8556 };
8557 
8558 /** @private */
8559 gtk.ListView.prototype._handleColumnResizeEvent = function(i, dom){
8560     var j = i;
8561     var self = this;
8562     var jsgtkDom =  jsgtk.Dom;
8563 
8564     jsgtk.Event.addDomListener(dom, "mouseover", function(){
8565 
8566         self._showVGhost(j);
8567 
8568         var minX = self._getGhostPosition(j - 1) + self._model.getColumnsWidth()[j];
8569 
8570        jsgtk.Util.DomDraggableAdapter.hDragInit(self._vGhost, minX, null);
8571 
8572         var currentX;
8573 
8574         self._vGhost.onDragStart = function(x){
8575             self._vGhost.className = "gtk_listview_vghost_visible";
8576             currentX = x;
8577 
8578             self._headerDomGhost.style.cursor = "col-resize";
8579             jsgtkDom.showElement(self._headerDomGhost);
8580         };
8581 
8582         self._vGhost.onDragEnd = function(x, y){
8583             self._vGhost.className = "gtk_listview_vghost";
8584             var offsetWidth = x - currentX;
8585 
8586             self._updateColumWidth(j, offsetWidth);
8587             currentX = x;
8588 
8589             jsgtkDom.hideElement(self._vGhost);
8590 
8591             jsgtkDom.hideElement(self._headerDomGhost);
8592 	    };
8593     });
8594 };
8595 
8596 /** @private */
8597 gtk.ListView.prototype._handleCellEvent = function(i, cell, sortArrow){
8598     var index = i;
8599     var jsgtkEvent = jsgtk.Event;
8600     var jsgtkDom =  jsgtk.Dom;
8601 
8602     jsgtkEvent.addDomListener(cell, "mouseover", function(e){
8603        jsgtkDom.showElement(sortArrow);
8604         jsgtkEvent.stopBubble(e);
8605     });
8606 
8607     jsgtkEvent.addDomListener(cell, "mouseout", function(e){
8608         jsgtkDom.hideElement(sortArrow);
8609         jsgtkEvent.stopBubble(e);
8610     });
8611 
8612     var isDecending = true;
8613     jsgtkEvent.addDomListener(cell, "click", function(e){
8614         if(isDecending){
8615             sortArrow.id = "gtk_listview_table_head_td_div_sortarrow_arrowup";
8616             isDecending = false;
8617         }else{
8618             sortArrow.id = "gtk_listview_table_head_td_div_sortarrow_arrowdown";
8619             isDecending = true;
8620         }
8621     });
8622 };
8623 
8624 /** @private */
8625 gtk.ListView.prototype._keyControllEvent = function(){
8626     var self = this;
8627     var jsgtkEvent = jsgtk.Event;
8628 
8629 	jsgtkEvent.addDomListener(this._hiddenTextBox, "keyup", function(e){
8630 	    var topIndex = self._model.children.length;
8631         if(e.keyCode === 13){
8632 	        var path = self._bodyDom.childNodes[self._rowIndex].id;
8633 	        self._emitSelectedRowSignalToController(path);
8634 	        self._hilightCell(self._rowIndex);
8635 	        self._selectedRowIndex = self._rowIndex;
8636 
8637 	        if(!self._isEmptyRowClicked(self._rowIndex)){
8638                 self.emit("rowclicked", self.getSelectedRow());
8639             }
8640 	    }
8641 
8642 	    if(e.keyCode === 40){
8643             if(self._rowIndex === topIndex - 1) self._rowIndex = -1;
8644             self._rowIndex++;
8645 
8646             if(!self._isEmptyRowClicked(self._rowIndex)){
8647                 self._hilightCellByArrowKey(self._rowIndex);
8648             }
8649         }
8650 
8651         if(e.keyCode === 38){
8652             if(self._rowIndex <= 0) self._rowIndex = topIndex;
8653             self._rowIndex--;
8654 
8655             if(!self._isEmptyRowClicked(self._rowIndex)){
8656                 self._hilightCellByArrowKey(self._rowIndex);
8657             }
8658         }
8659         self._scrollTableBodyByIndex(self._rowIndex);
8660 
8661         jsgtkEvent.stopBubble(e);
8662     });
8663 };
8664 
8665 gobject.signalNew('refreshmodel', gtk.ListView, [], null, null);
8666 gobject.signalNew('_rowselectedtocontroller', gtk.ListView, [], null, null);
8667 gobject.signalNew('_renderemptyrows', gtk.ListView, [], null, null);
8668 gobject.signalNew('searchcontenttocontroller', gtk.ListView, [], null, null);
8669 gobject.signalNew('filterrowstocontroller', gtk.ListView, [], null, null);
8670 gobject.signalNew('rowselected', gtk.ListView, [], null, null);
8671 gobject.signalNew('rowclicked', gtk.ListView, [], null, null);
8672 gobject.signalNew('rowover', gtk.ListView, [], null, null);
8673 gobject.signalNew('rowout', gtk.ListView, [], null, null);
8674 gobject.signalNew('rowdoubleclicked', gtk.ListView, [], null, null);
8675 /**
8676  * @constructor
8677  * @base gtk.Widget
8678  */
8679 gtk.MultiPanelContainer = function() {
8680 	gtk.Widget.apply(this);
8681 
8682 	this._width           = this._minWidth  = 20;
8683     this._height          = this._minHeight = 20;
8684     this._loadingImgWidth = 150;
8685     this._activeChild     = null;
8686     this._children        = [];
8687 
8688 	/** @private */
8689 	this._render = function(){
8690 		var jsgtkDom = jsgtk.Dom;
8691 		var domObj = this._domObj;
8692 		domObj.className   += " gtk_MultiPanelContainer";
8693 		    this._grayText = jsgtk.Dom.create({"append": domObj, "tag": "table", "class": "gtk_MultiPanelContainer_table"});
8694 		        var tr = jsgtk.Dom.create({"append": this._grayText, "tag": "tr"});
8695                     var td = jsgtk.Dom.create({"append": tr, "tag": "td", "class": "gtk_MultiPanelContainer_tr_gray_text","text": "Text"});
8696 
8697             this._loadingDom = jsgtk.Dom.create({"append": domObj, "tag": "table", "class": "gtk_MultiPanelContainer_loading"});
8698 		        var tr = jsgtk.Dom.create({"append": this._loadingDom, "tag": "tr"});
8699                     var td = jsgtk.Dom.create({"append": tr, "tag": "td", "class": "gtk_MultiPanelContainer_tr_loading"});
8700                         this._loadingImg = jsgtk.Dom.create({"append": td, "tag": "div", "class": "gtk_MultiPanelContainer_tr_loaing_img"});
8701             jsgtk.Dom.hideElement(this._loadingDom);
8702 	};
8703 
8704     this._render();
8705 };
8706 
8707 gtk.MultiPanelContainer.prototype = new gtk.Widget();
8708 gtk.MultiPanelContainer.prototype.constructor = gtk.MultiPanelContainer;
8709 
8710 /**
8711  * show loading bar
8712  */
8713 gtk.MultiPanelContainer.prototype.showLoading = function(){
8714     jsgtk.Dom.showElement(this._loadingDom);
8715     jsgtk.Dom.hideElement(this._grayText);
8716 };
8717 
8718 /**
8719  * hide loading bar
8720  */
8721 gtk.MultiPanelContainer.prototype.hideLoading = function(){
8722     jsgtk.Dom.showElement(this._grayText);
8723     jsgtk.Dom.hideElement(this._loadingDom);
8724 };
8725 
8726 /** @private */
8727 gtk.MultiPanelContainer.prototype._resetMinWidthMinHeight = function(childWidget){
8728     var childWidth = childWidget.getMinWidthComposite();
8729     this._minWidth = childWidth > this._minWidth ? childWidth : this._minWidth;
8730 
8731     var childHeight = childWidget.getMinHeightComposite();
8732     this._minHeight = childHeight > this._minHeight ? childHeight : this._minHeight;
8733 };
8734 
8735 /**
8736  * Set text inside gtk.MultiPanelContainer
8737  * @param {string} text
8738  */
8739 gtk.MultiPanelContainer.prototype.setText = function(text){
8740     this._grayText.rows[0].firstChild.innerHTML = text;
8741 };
8742 
8743 /**
8744  * Return gtk.Widget whic is active inside gtk.MultiPanelContainer
8745  * @param {gtk.Widget || null} gtk.Widget
8746  */
8747 gtk.MultiPanelContainer.prototype.getActiveChild = function(){
8748     var isActive = false;
8749     for(var i = 2, len = this._domObj.childNodes.length; i < len; i++){
8750         var node = this._domObj.childNodes[i].firstChild;
8751         if(node.style.display !== "none") isActive = true;
8752     }
8753     if(isActive) return this._activeChild;
8754     else return null;
8755 
8756 }
8757 
8758 /**
8759  * Remove gtk.Widget (child) from gtk.MultiPanelContainer
8760  * @param {gtk.Widget} childWiget
8761  */
8762 gtk.MultiPanelContainer.prototype.removeChild = function(childWidget){
8763     for(var i = 0, len = this._children.length; i < len; i++){
8764         var child = this._children[i];
8765         if(child["childWidget"] === childWidget) {
8766             child["holder"].parentNode.removeChild(child["holder"]);
8767             this._children.splice(i, 1);
8768             return;
8769         }
8770     }
8771 };
8772 
8773 /**
8774  * Append gtk.Widget to gtk.MultiPanelContainer
8775  * @param {gtk.Widget} childWidget
8776  */
8777 gtk.MultiPanelContainer.prototype.appendChild = function(childWidget){
8778     this._resetMinWidthMinHeight(childWidget);
8779 
8780     var holder = this._createChildHolder();
8781     holder.appendChild(childWidget.getNode());
8782 
8783     this.setActiveChild(childWidget);
8784 
8785     var childObject = {
8786         "holder": holder,
8787         "childWidget": childWidget
8788     };
8789 
8790     this._children.push(childObject);
8791     this._domObj.appendChild(holder);
8792 
8793     this.resizeWidthComposite(this._width);
8794     this.resizeHeightComposite(this._height);
8795 
8796     if(this._children.length > 1) this._minimizePreviousChild();
8797 
8798     var self = this;
8799     childWidget.connect("restored", function(panel){
8800         for(var i = self._children.length; i--;){
8801             var child = self._children[i];
8802             if(child["childWidget"] ===  panel){
8803                 self.setActiveChild(panel);
8804                 child["holder"].style.zIndex = 2;
8805                 jsgtk.Dom.showElement(child["holder"]);
8806             }else{
8807                 child["childWidget"].minimize();
8808                 child["holder"].style.zIndex = 1;
8809             }
8810         }
8811     });
8812 
8813     childWidget.connect("closed", function(panel){
8814         self.removeChild(panel)
8815     });
8816 };
8817 
8818 /**
8819  * Set the gtk.Widget (child) active
8820  * @param {gtk.Widget} childWidget
8821  */
8822 gtk.MultiPanelContainer.prototype.setActiveChild = function(childWidget){
8823     this._activeChild = childWidget;
8824 };
8825 
8826 /** @private */
8827 gtk.MultiPanelContainer.prototype._minimizePreviousChild = function(){
8828     this._children[this._children.length - 2]["childWidget"].minimize();
8829     jsgtk.Dom.hideElement(this._children[this._children.length - 2]["holder"]);
8830 };
8831 
8832 /** @private */
8833 gtk.MultiPanelContainer.prototype._getIndexOfChild = function(childWidget){
8834     for(var i = 0, len = this._children.length; i < len; i++){
8835         var child = this._children[i];
8836         if(child["childWidget"] === childWidget) return i;
8837     }
8838     return null;
8839 };
8840 
8841 /**
8842  * Replace existing childWidget with new childWidget
8843  * @param {gtk.Widget} newChildWidget
8844  * @param {gtk.Widget} oldChildWidget
8845  */
8846 gtk.MultiPanelContainer.prototype.replaceChild = function(newChildWidget, oldChildWidget){
8847     var index = this._getIndexOfChild(oldChildWidget);
8848     if(!index) return;
8849 
8850     this._domObj.removeChild(this._children[index]["holder"]);
8851 
8852     this._children.splice(index, 1);
8853     this.appendChild(newChildWidget);
8854 };
8855 
8856 /**
8857  * Return children widget
8858  * @return {array} children widget
8859  */
8860 gtk.MultiPanelContainer.prototype.getChildren = function(){
8861     var children = []
8862     for(var i = 0, len = this._children.length; i < len; i++){
8863         children.push(this._children[i]["childWidget"]);
8864     }
8865     return children;
8866 };
8867 
8868 /** @private */
8869 gtk.MultiPanelContainer.prototype._positionLoadingImg = function(width){
8870     this._loadingImg.style.left = width / 2 - this._loadingImgWidth / 2 + "px";
8871 }
8872 
8873 /** @private */
8874 gtk.MultiPanelContainer.prototype._resizeChildrenWidth = function(width){
8875     for(var i = this._children.length; i--;){
8876         var child = this._children[i];
8877         child["childWidget"].resizeWidthComposite(width);
8878         child["holder"].style.width = width + "px";
8879     }
8880 };
8881 
8882 /** @private */
8883 gtk.MultiPanelContainer.prototype._resizeChildrenHeight = function(height){
8884     for(var i = this._children.length; i--;){
8885         var child = this._children[i];
8886         child["childWidget"].resizeHeightComposite(height);
8887         child["holder"].style.height = height + "px";
8888     }
8889 };
8890 
8891 /** @private */
8892 gtk.MultiPanelContainer.prototype._createChildHolder = function(){
8893     var holder = jsgtk.Dom.create({"tag": "div", "class": "gtk_multiPanelContainer_widget_holder"});
8894     return  holder;
8895 };
8896 
8897 /** @private */
8898 gtk.MultiPanelContainer.prototype.resizeWidthComposite = function(width){
8899     var minWidth = this._minWidth < width ? width : this._minWidth;
8900     this._resizeWidth(minWidth);
8901     this._positionLoadingImg(minWidth);
8902     if(this._children.length > 0) this._resizeChildrenWidth(minWidth);
8903 };
8904 
8905 /** @private */
8906 gtk.MultiPanelContainer.prototype.resizeHeightComposite = function(height){
8907     var minHeight = this._minHeight < height ? height : this._minHeight;
8908     this._resizeHeight(minHeight);
8909     if(this._children.length > 0) this._resizeChildrenHeight(minHeight);
8910 };
8911 /**
8912  * @constructor
8913  * @base gtk.Widget
8914  */
8915 gtk.NoteBook = function() {
8916 	gtk.Widget.apply(this);
8917 
8918 	/** 'tabchanged' signal */
8919 	this.NOTEBOOK_TABCHANGED = "tabchanged";
8920 
8921 	this._minWidth        = 200;
8922 	this._minHeight       = 200;
8923 	this._width           = this._minWidth;
8924 	this._height          = this._minHeight;
8925 	this._tabHeight       = 32;
8926     this._hBarHeight      = 3;
8927     this._loadingImgWidth = 16;
8928     this._extraWidthRight = 10;
8929     this._border          = 2;
8930     this._vspaceWidth     = 2;
8931     this._numberTabs      = 0;
8932 	this._tabs = new gtk.Tabs(this._width, this._tabHeight, this._vspaceWidth);
8933 
8934     var contentsHeight = this._height - this._tabHeight - this._hBarHeight;
8935 	this._contents = new gtk.Contents(this._width, contentsHeight);
8936 
8937 	this._render = function(){
8938 		this._domObj.className += " gtk_notebook";
8939 		this._domObj.style.width = this._width + 'px';
8940 		this._domObj.style.height = this._height + 'px';
8941 		    var hBar = jsgtk.Dom.create({'tag' : 'div', 'className': 'gtk_hbar'});
8942 		this._appendChild(this._contents, this._tabs, hBar);
8943 	};
8944 	this._initEvent();
8945 	this._render();
8946 };
8947 
8948 gtk.NoteBook.prototype = new gtk.Widget();
8949 gtk.NoteBook.prototype.constructor = gtk.NoteBook;
8950 
8951 /** @private */
8952 gtk.NoteBook.prototype._initEvent = function(){
8953     var self = this;
8954     this._tabs.connect('active', function(id){
8955 		var content = self._contents.activateContent(id);
8956 		self.emit("tabchanged", self.getActiveTab());
8957 	});
8958     jsgtk.Event.addDomListener(this._domObj, 'keyup', function(e){
8959 	    if(e.keyCode == gtk.RIGHT_ARROW_KEY){
8960 		    var activeTabIndex = self._tabs.getIndex(self._tabs._activeTab);
8961             if(activeTabIndex < self.getNumberTabs()-1)self.setActiveTab(activeTabIndex+1);
8962 	    }
8963 	    else if(e.keyCode == gtk.LEFT_ARROW_KEY){
8964 	       var activeTabIndex = self._tabs.getIndex(self._tabs._activeTab);
8965             if(activeTabIndex > 0)self.setActiveTab(activeTabIndex -1);
8966 	    }
8967 	});
8968 	jsgtk.Event.addDomListener(this._domObj, 'focus', function(e){
8969 	   self._tabs._setFocus(self._tabs._activeTab);
8970 	});
8971 	jsgtk.Event.addDomListener(this._domObj, 'blur', function(e){
8972 	   self._unFocus(self._tabs._activeTab);
8973 	});
8974 };
8975 
8976 /**
8977  * Turn border on || off
8978  * @param {boolean}
8979  */
8980 gtk.NoteBook.prototype.setBorderVisible = function(visible){
8981     if(visible) this._contents.showBorder();
8982     else this._contents.hideBorder();
8983 };
8984 
8985 
8986 /**
8987  * Update the content of selected tab
8988  * @param {object} pageObj {"content": gtk.Widget, "padding": 5}
8989  */
8990 gtk.NoteBook.prototype.updatePage = function(pageObj){
8991 	var index = this._tabs.getIndex(pageObj['tab']);
8992 	this._contents.updateContent(pageObj["content"], index);
8993 
8994 	this._contents.activate(index);
8995 
8996 	this.resizeWidthComposite(this._width);
8997 	this.resizeHeightComposite(this._height);
8998 };
8999 
9000 /**
9001  * Appends a page to the notebook
9002  * @param {object} tabObj {"tab": label1, "padding": 55}
9003  * @param {object} contentObj {"content": content2, "padding": 5}
9004  */
9005 gtk.NoteBook.prototype.appendPage = function(tabObj, contentObj){
9006 	contentObj["content"] = contentObj["content"] || new gtk.Blank();
9007 
9008     var id = new UUID();
9009 	tabObj["id"] = id;
9010     contentObj["id"] = id;
9011 
9012 	this._contents.addChild(contentObj);
9013 	this._tabs.addTab(tabObj);
9014 
9015 	this._tabs.activateDefault();
9016 	this._contents.activateDefault();
9017 
9018 	this.resizeWidthComposite(this._width);
9019 	this.resizeHeightComposite(this._height);
9020 
9021     return {
9022         "tab": tabObj["tab"],
9023         "content": contentObj["content"],
9024 		"isBlanked": contentObj.type === gtk.BLANK_WIDGET ? true : false
9025     };
9026 };
9027 
9028 /**
9029  * Insert a page to the notebook at index
9030  * @param {object} tabObj {"tab": label1, "padding": 55}
9031  * @param {object} contentObj {"content": content2, "padding": 5}
9032  * @param {integer} index
9033  */
9034 gtk.NoteBook.prototype.insertAt = function(tabObj, contentObj,index){
9035 
9036 	contentObj["content"] = contentObj["content"] || new gtk.Blank();
9037 
9038     var id = new UUID();
9039 	tabObj["id"] = id;
9040     contentObj["id"] = id;
9041 
9042 	this._contents.insertAt(contentObj, index);
9043 	this._tabs.insertAt(tabObj, index);
9044 
9045 	this.resizeWidthComposite(this._width);
9046 	this.resizeHeightComposite(this._height);
9047 
9048    return {
9049         "tab": tabObj["tab"],
9050         "content": contentObj["content"],
9051 		"isBlanked": contentObj.type === gtk.BLANK_WIDGET ? true : false
9052     };
9053 };
9054 
9055 /**
9056  * Remove tabe by index
9057  * @param {intger} index of tab to be removed
9058  */
9059 gtk.NoteBook.prototype.removeTab = function(index){
9060     var len = this._tabs.getChildren().length;
9061     if(len == 1) jsgtk.Util.debug("The tab can not be removed");
9062     if(index < 0 || index >= len) jsgtk.Util.debug("The index out of range");
9063 
9064     this._tabs.removeTab(index);
9065     this._contents.removeChild(index);
9066 
9067     if(index === 0) this._activatePreviousTab(index + 1);
9068     if(this._tabs.getActiveTab() === this._tabs.getChildren()[index]) this._activatePreviousTab(index);
9069     else this._activateActiveTab();
9070 };
9071 
9072 /** @private */
9073 gtk.NoteBook.prototype.setTabindex = function(index){
9074     this._tabs.getNode().tabIndex = index;
9075 };
9076 
9077 /**
9078  * Return number of tabs
9079  * @return {intger}
9080  */
9081 gtk.NoteBook.prototype.getNumberTabs = function(){
9082     return this._tabs._tabs.length;
9083 };
9084 
9085 /** @private */
9086 gtk.NoteBook.prototype.showLoading = function(activeTab){
9087     this._tabs.showLoading(activeTab["tab"]);
9088 };
9089 
9090 /** @private */
9091 gtk.NoteBook.prototype.hideLoading = function(activeTab){
9092     this._tabs.hideLoading(activeTab["tab"]);
9093 };
9094 
9095 /** @private */
9096 gtk.NoteBook.prototype._activateActiveTab = function(){
9097     this._tabs.activateByObject(this._tabs.getActiveTab());
9098     this._contents.activateByObject(this._contents.getActiveContent());
9099 };
9100 
9101 /** @private */
9102 gtk.NoteBook.prototype._activatePreviousTab = function(index){
9103     this._tabs.activate(index - 1);
9104     this._contents.activate(index -1);
9105 };
9106 
9107 /**
9108  * activate the tab by tab
9109  * @param {gtk.Widget} tab
9110  */
9111 gtk.NoteBook.prototype.setActiveTabByTab = function(tab){
9112     var index = this._tabs.getIndex(tab);
9113     this.setActiveTab(index);
9114 };
9115 
9116 /**
9117  * activate the tab by index
9118  * @param {integer} index
9119  */
9120 gtk.NoteBook.prototype.setActiveTab = function(index){
9121     this._tabs.activate(index);
9122     this._contents.activate(index);
9123     this.emit("tabchanged", this.getActiveTab());
9124 };
9125 
9126 /** @private */
9127 gtk.NoteBook.prototype.setFocusTab = function(index){
9128     this._tabs.setFocus(index);
9129 };
9130 
9131 /**
9132  * Return all tabs objects
9133  * @return {array} array of tabs of object
9134  */
9135 gtk.NoteBook.prototype.getTabs = function(){
9136     var tabs = [];
9137     for(var i = 0, len = this._tabs.getChildren().length; i < len; i++){
9138         tabs.push({
9139             "tab": this._tabs.getChildren()[i]["tab"],
9140             "content": this._contents.getChildren()[i]["content"],
9141 			"isBlanked": this._contents.getChildren()[i]["content"].type === gtk.BLANK_WIDGET ? true : false
9142         });
9143     }
9144     return tabs;
9145 };
9146 
9147 /**
9148  * Return active tab
9149  */
9150 gtk.NoteBook.prototype.getActiveTab = function(){
9151     return {
9152         "tab": this._tabs.getActiveTab(),
9153         "content": this._contents.getActiveContent(),
9154 		"isBlanked": this._contents.getActiveContent().type === gtk.BLANK_WIDGET ? true : false
9155     };
9156 };
9157 
9158 /** @private */
9159 gtk.NoteBook.prototype._appendChild = function(contents, tabs, hBar){
9160 	this._domObj.appendChild(tabs._domObj);
9161 	this._domObj.appendChild(hBar);
9162 	this._domObj.appendChild(contents._domObj);
9163 };
9164 
9165 
9166 /** @private */
9167 gtk.NoteBook.prototype._resizeHeight = function(height){
9168     this._domObj.style.height = height - this._border + 'px';
9169 	this._height = height;
9170 };
9171 
9172 /** @private */
9173 gtk.NoteBook.prototype._resizeWidth = function(width){
9174 	this._domObj.style.width = width - this._border + 'px';
9175 	this._width = width;
9176 };
9177 
9178 gtk.NoteBook.prototype._getLoadingImgWidths = function(){
9179     var children = this._tabs.getChildren();
9180     var width = 0;
9181     for(var i = 0, len = children.length; i < len; i++){
9182         pageObj = children[i];
9183         width += pageObj["padding"] > this._loadingImgWidth ? pageObj["padding"] : this._loadingImgWidth;
9184     }
9185     return width;
9186 };
9187 
9188 /** @private */
9189 gtk.NoteBook.prototype.getMinWidthComposite = function(){
9190 	var minWidth = this._minWidth;
9191 
9192 	var tabsWidth = this._tabs.getMinWidthComposite();
9193 	var contentsWidth = this._contents.getMinWidthComposite();
9194 
9195 	if(tabsWidth > minWidth) minWidth = tabsWidth;
9196 	if(contentsWidth > minWidth) minWidth = contentsWidth;
9197     this._getLoadingImgWidths();
9198 	return minWidth + this._extraWidthRight + this._getLoadingImgWidths();
9199 };
9200 
9201 /** @private */
9202 gtk.NoteBook.prototype.getMinHeightComposite = function(){
9203 	var minHeight = this._minHeight - this._tabs.getHeight();
9204 	var contentsHeight = this._contents.getMinHeightComposite();
9205 
9206 	if(contentsHeight > minHeight) minHeight = contentsHeight;
9207 
9208 	return minHeight + this._tabs.getHeight();
9209 };
9210 
9211 /** @private */
9212 gtk.NoteBook.prototype.resizeHeightComposite = function(height){
9213 	var minHeightComposite = this.getMinHeightComposite();
9214 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
9215 	this._contents.resizeHeightComposite(minHeight - this._tabs.getHeight() - this._border);
9216 
9217     this._resizeHeight(minHeight);
9218 };
9219 
9220 /** @private */
9221 gtk.NoteBook.prototype.resizeWidthComposite = function(width){
9222 	var minWidthComposite = this.getMinWidthComposite();
9223 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
9224 
9225 	this._tabs.resizeWidthComposite(minWidth - 1);
9226 	this._contents.resizeWidthComposite(minWidth - this._border);
9227 
9228     this._resizeWidth(minWidth);
9229 };
9230 
9231 gobject.signalNew('tabchanged', gtk.NoteBook, [], null, null);
9232 /**
9233  * Scroller is a class to create a scroller with horizontal and vertical scrollbars
9234  * @constructor
9235  * @base gtk.Widget
9236  */
9237 gtk.Scroller = function() {
9238 	gtk.Widget.apply(this);
9239 
9240 	/** 'scrolled' signal */
9241 	this.SCROLLER_SCROLLED = "scrolled";
9242 
9243 	this._width          = this._minWidth  = 100;
9244 	this._height         = this._minHeight = 50;
9245 	this._childResizable = false;
9246 	this._isScrolledX    = true;
9247 	this._isScrolledY    = true;
9248 	this._vScrolledBar   = null;
9249 	this._child          = null;
9250 	this._scrollYDefault = 0;
9251 	this._attribute		= null;
9252 	this._padding	= 0;
9253 
9254 	this._render = function(){
9255         this._domObj.className       += " gtk_scroller_base";
9256         this._domObj.style.width      = this._width + "px";
9257         this._domObj.style.height     = this._height + "px";
9258 	};
9259 	this._render();
9260 	this._initEvent();
9261 };
9262 
9263 gtk.Scroller.prototype = new gtk.Widget();
9264 gtk.Scroller.prototype.constructor = gtk.Scroller;
9265 
9266 /**
9267  * Append child to scroller
9268  * @param {gtk.Widget} widget
9269  * @param {boolean} resizable true child expand false vice versa
9270  * @param {integer} padding
9271  */
9272 gtk.Scroller.prototype.appendChild = function(widget, resizable, padding){
9273     this._childResizable = resizable === undefined || resizable === null ? false : resizable;
9274 
9275    this._padding = (typeof padding !== "undefined") ? padding : 0;
9276 
9277 	this._child = widget;
9278 	this._domObj.appendChild(widget._domObj);
9279 
9280 	if(typeof padding !== "undefined") this.setAttribute({padding: padding + "px"});
9281 
9282     this.resizeWidthComposite(this._minWidth);
9283     this.resizeHeightComposite(this._minHeight);
9284 
9285 	this._child.setParent(this);
9286 };
9287 
9288 /** @private */
9289 gtk.Scroller.prototype.add = function(widget, resizable){
9290 	this.appendChild(widget, resizable);
9291 	console.log("gtk.Scroller.add(), will be depricated in next release, please use gtk.Scroller.appendChild() instead");
9292 };
9293 
9294 /**
9295  * Scroll to top
9296  */
9297 gtk.Scroller.prototype.scrollToTop = function(){
9298     this.scrollTo(null, 0);
9299 };
9300 
9301 /**
9302  * Scroll to bottom
9303  */
9304 gtk.Scroller.prototype.scrollToBottom = function(){
9305 	var childHeight = this._child.getMinHeightComposite();
9306 
9307     this.scrollTo(null, this._height > childHeight ? this._height : childHeight);
9308 };
9309 
9310 /**
9311  * Scroll to left
9312  */
9313 gtk.Scroller.prototype.scrollToLeft = function(){
9314     this.scrollTo(0);
9315 };
9316 
9317 /**
9318  * Scroll to right
9319  */
9320 gtk.Scroller.prototype.scrollToRight = function(){
9321     this.scrollTo(this._width);
9322 };
9323 
9324 /**
9325  * Scroll to right x pixel, Scroll to bottom y pixel
9326  * @param {integer} x
9327  * @param {integer} y
9328  */
9329 gtk.Scroller.prototype.scrollTo = function(x , y){
9330     this._domObj.scrollTop = y;
9331     this._domObj.scrollLeft = x;
9332 };
9333 
9334 /**
9335  * Return child widget gtk.Widget
9336  * @return {gtk.Widget}
9337  */
9338 gtk.Scroller.prototype.getChildren = function(){
9339 	return this._child;
9340 };
9341 
9342 /** @private */
9343 gtk.Scroller.prototype._initEvent = function(){
9344     var _self = this;
9345     jsgtk.Event.addDomListener(this._domObj, "scroll", function(e){
9346         var scrollY = _self._domObj.scrollTop;
9347         var scrollHeight = _self._domObj.scrollHeight;
9348         var minScrolledY = scrollHeight-(scrollHeight - _self._domObj.scrollTop);
9349         if(scrollY > 0 && minScrolledY >= 15){
9350             _self.emit("scrolled");
9351         }
9352     });
9353 };
9354 
9355 /**
9356  * Refresh gtk.Scroller and its child widget
9357  */
9358 gtk.Scroller.prototype.refresh = function(){
9359     this.resizeWidthComposite(this._width);
9360     this.resizeHeightComposite(this._height);
9361 };
9362 
9363 /**
9364  * Show loading bar
9365  */
9366 gtk.Scroller.prototype.showLoading = function(){
9367     if(this._isScrolledY) this._domObj.style.overflowY = "hidden";
9368     if(this._isScrolledX) this._domObj.style.overflowX = "hidden";
9369 
9370     if(!this._loadingImgContainer){
9371 		this._loadingImgContainer = this._constructLoading();
9372         this._appendLoading();
9373     }else this._loadingImgContainer.style.display = "table";
9374 };
9375 
9376 
9377 /**
9378  * Hide loading bar
9379  */
9380 gtk.Scroller.prototype.hideLoading = function(){
9381     if(this._isScrolledY) this._domObj.style.overflowY = "auto";
9382     if(this._isScrolledX) this._domObj.style.overflowX = "auto";
9383 
9384     jsgtk.Dom.hideElement(this._loadingImgContainer);
9385 };
9386 
9387 /**
9388  * Remove event from scroller
9389  */
9390 gtk.Scroller.prototype.removeScrolledEvent = function(){
9391     jsgtk.Event.removeListener(this._onScroll);
9392 };
9393 
9394 /** @private */
9395 gtk.Scroller.prototype.getScrolledDom = function(){
9396     return this._domObj;
9397 };
9398 
9399 /**
9400  * Set style to the scroller
9401  * @param {object} attribute {'height': ..px, 'border': '...', 'fontColor': ..}
9402  */
9403 gtk.Scroller.prototype.setAttribute = function(attribute){
9404 	this._attribute = attribute;
9405 	this._applyAttribute();
9406 
9407 	this.resizeWidthComposite(this._minWidth);
9408     this.resizeHeightComposite(this._minHeight);
9409 };
9410 
9411 /** @private */
9412 gtk.Scroller.prototype._applyAttribute = function(){
9413 	for(var el in this._attribute){
9414 		if(el == "padding") this._padding = parseInt(this._attribute[el]);
9415 		this._domObj.style[el] = this._attribute[el];
9416 	}
9417 
9418 };
9419 
9420 /**
9421  * Disable horizontal scrollbar
9422  */
9423 gtk.Scroller.prototype.disableHScrolled = function(){
9424     this._domObj.style.overflowX = "hidden";
9425     this._isScrolledX = false;
9426 };
9427 
9428 /**
9429  * Disable vertical scrollbar
9430  */
9431 gtk.Scroller.prototype.disableVScrolled = function(){
9432     this._domObj.style.overflowY = "hidden";
9433     this._isScrolledY = false;
9434 };
9435 
9436 /**
9437  * Enable horizontal scrollbar
9438  */
9439 gtk.Scroller.prototype.enableHScrolled = function(){
9440     this._domObj.style.overflowX = "auto";
9441     this._isScrolledX = true;
9442 };
9443 
9444 /**
9445  * Enable vertical scrollbar
9446  */
9447 gtk.Scroller.prototype.enableVScrolled = function(){
9448     this._domObj.style.overflowY = "auto";
9449     this._isScrolledY = true;
9450     this._width = this._width - 200;
9451     this._resize(this._width, this._height);
9452 };
9453 
9454 /** @private */
9455 gtk.Scroller.prototype.getScrollHeight = function(){
9456     return this._child.getHeight();
9457 };
9458 
9459 /** @private */
9460 gtk.Scroller.prototype.resize = function(width, height){
9461     this._resizeWidth(width);
9462     this._resizeHeight(height);
9463 };
9464 
9465 /** @private */
9466 gtk.Scroller.prototype._resizeWidth = function(width){
9467 	this._width = width;
9468 	this._domObj.style.width            = width + "px";
9469 };
9470 
9471 /** @private */
9472 gtk.Scroller.prototype._resizeHeight = function(height){
9473     this._height = height;
9474 	this._domObj.style.height            = height + "px";
9475 	if(!this._isScrolledY && this._child !== null){
9476 	    this._child._domObj.style.height = this._height - 2 + "px";
9477 	}
9478 };
9479 
9480 /** @private */
9481 gtk.Scroller.prototype.getMinHeightComposite = function(){
9482     return this._minHeight;
9483 };
9484 
9485 /** @private */
9486 gtk.Scroller.prototype.getMinWidthComposite = function(){
9487     return this._minWidth;
9488 };
9489 
9490 /** @private */
9491 gtk.Scroller.prototype.resizeWidthComposite = function(width){
9492 	var _width = width - this._padding*2;
9493 
9494 	var minWidthComposite = this.getMinWidthComposite();
9495 	var minWidth = _width > minWidthComposite ? _width : minWidthComposite;
9496 
9497 	this._resizeWidth(minWidth);
9498 
9499 	if(this._childResizable){
9500 	    var childMinWidth = this._child.getMinWidthComposite();
9501 	    if(minWidth > childMinWidth) this._child.resizeWidthComposite(minWidth);
9502 	    else this._child.resizeWidthComposite(childMinWidth);
9503 	}
9504 	if(this._child instanceof gtk.ListView) this._child.setParentWidth(minWidth);
9505 };
9506 
9507 /** @private */
9508 gtk.Scroller.prototype.resizeHeightComposite = function(height){
9509 	var _height = height - this._padding*2;
9510 
9511 	var minHeightComposite = this.getMinHeightComposite();
9512 	var minHeight = _height > minHeightComposite ? _height : minHeightComposite;
9513 
9514 	this._resizeHeight(minHeight);
9515 
9516     if(this._childResizable){
9517 	    var childMinHeight = this._child.getMinHeightComposite();
9518 	    if(minHeight > childMinHeight) this._child.resizeHeightComposite(minHeight);
9519 	    else this._child.resizeHeightComposite(childMinHeight);
9520 	}
9521 };
9522 
9523 gobject.signalNew("scrolled", gtk.Scroller, null, null, []);
9524 /**
9525  * VScroller is a class to create a vertical scroller. The vertical scroller has only vertical scrollbar
9526  * @base gtk.Scroller
9527  * @see gtk.Scroller
9528  * @constructor
9529  */
9530 gtk.VScroller = function() {
9531 	gtk.Scroller.apply(this);
9532 	this._scollerWidth = 18;
9533 	this.disableHScrolled();
9534 };
9535 
9536 gtk.VScroller.prototype = new gtk.Scroller();
9537 gtk.VScroller.prototype.constructor = gtk.VScroller;
9538 
9539 /**
9540  * A method to get width of the scroll window
9541  * @return {Integer} The minimum composite width of the scroll
9542  * @type Integer
9543  */
9544 gtk.VScroller.prototype.getMinWidthComposite = function(){
9545 	var childMinWidth = this._child.getMinWidthComposite();
9546 	return this._minWidth > childMinWidth ? this._minWidth : childMinWidth;
9547 };
9548 
9549 /**
9550  * A method to resize width of the scroll window
9551  * @param {Integer} width The composite width value in pixel to be set
9552  */
9553 gtk.VScroller.prototype.resizeWidthComposite = function(width){
9554 	var _width = width - this._padding*2;
9555 
9556 	var minWidth = this.getMinWidthComposite();
9557 	minWidth = _width > minWidth ? _width : minWidth;
9558 
9559 	this._resizeWidth(minWidth);
9560 
9561     this._child.resizeWidthComposite(minWidth - this._scollerWidth);
9562 
9563 	if(this._child instanceof gtk.ListView) this._child.setParentWidth(minWidth);
9564 };
9565 /**
9566  * Factory of all gtk.SmartEntry
9567  * @param {string} type of gtk.SmartEntry : gtk.SMART_ENTRY_DROPDOWN_FIXED_MODEL, gtk.SMART_ENTRY_DROPDOWN_DYNAMIC_MODEL
9568  * @constructor
9569  */
9570 gtk.SmartEntryFactory = function(type){
9571 	var smartEntry;
9572 	switch (type){
9573 		case gtk.SMART_ENTRY_DROPDOWN_FIXED_MODEL:
9574 			smartEntry = new gtk.SmartEntryDropDownFacade(new gtk.SmartEntryDropDownFixedModel());
9575 			break;
9576 		case gtk.SMART_ENTRY_DROPDOWN_DYNAMIC_MODEL:
9577 			smartEntry = new gtk.SmartEntryDropDownFacade(new gtk.SmartEntryDropDownDynamicModel());
9578 			break;
9579 	}
9580 	return smartEntry;
9581 };
9582 
9583 /**
9584  * SmartEntryDropDownFacade is an assistant class to create Smart Entry
9585  * @param {string} smartEntryDropDown The object of smart entry dropdown
9586  * @constructor
9587  * @base gtk.Object
9588  */
9589 gtk.SmartEntryDropDownFacade = function(smartEntryDropDown){
9590     gtk.Object.apply(this);
9591 
9592     var vscroller = new gtk.VScroller();
9593     vscroller.getNode().style.border = "1px solid #D5D5D5";
9594     vscroller.appendChild(smartEntryDropDown, true);
9595 
9596     vscroller.setModel       = function(model){smartEntryDropDown.setModel(model);};
9597     vscroller.showError      = function(isOnError){smartEntryDropDown.showError(isOnError);};
9598     vscroller.getValues      = function(){return smartEntryDropDown.getValues();}
9599     vscroller.getItems       = function(){return smartEntryDropDown.getItems()};
9600     vscroller.createFixedTag = function(obj){smartEntryDropDown.createFixedTag(obj);};
9601     vscroller.createTag      = function(obj){smartEntryDropDown.createTag(obj);};
9602     vscroller.setLabel       = function(text){smartEntryDropDown.setLabel(text);};
9603     vscroller.setFocus       = function(){smartEntryDropDown.setFocus();};
9604 
9605     smartEntryDropDown.connect("smartentrychanged", function(value){
9606         vscroller.emit("smartentrychanged", value);
9607     })
9608 
9609     return vscroller;
9610 };
9611 
9612 gobject.signalNew("smartentrychanged", gtk.Scroller, null, null, []);
9613 /**
9614  * A widget with an entry which is able to create many tags
9615  * @constructor
9616  * @base gtk.Widget
9617  */
9618 gtk.SmartEntryDropDown = function(){
9619     gtk.Widget.apply(this);
9620     /** 'smartentrychanged' signal */
9621 	this.SMARTENTRYDROPDOWN_SMARTENTRYCHANGED = "smartentrychanged";
9622 
9623     this._minWidth 		= this._width 	= 150;
9624     this._minHeight 		= this._height = 10;
9625     this._entryWidth 	= 100;
9626     this._textBoxError	= false;
9627     this._ismouseMoved  = false;
9628     this._isParentSignalHandled = false;
9629 
9630 	this._render = function(){
9631 	    this._domObj.className += " gtk_smart_entry_drop_down_widget";
9632 	    	this._holder = jsgtk.Dom.create({tag: "div", append: this._domObj, className: "gtk_smart_entry_drop_down_area"});
9633 	    		this._tagHolder = jsgtk.Dom.create({tag: "div", append: this._holder, className: "gtk_smart_entry_drop_down_tag_group"});
9634 
9635 			    this._entryHolder = jsgtk.Dom.create({tag: "div", append: this._holder, className: "gtk_smart_entry_drop_down_input_holder"});
9636 				    this._labelEntry = jsgtk.Dom.create({tag: "span", append: this._entryHolder, className: "gtk_smart_entry_drop_down_label"});
9637 				    this._entry = jsgtk.Dom.create({tag: "input", append: this._entryHolder, className: "gtk_smart_entry_drop_down_input"});
9638 
9639 		this.__dropDown = jsgtk.Dom.create({tag: "div", "append": document.body, className: "gtk_smart_entry_drop_down_widget_holder"});
9640 			jsgtk.Dom.hideElement(this.__dropDown);
9641 	};
9642 
9643 	this._render();
9644 };
9645 
9646 gtk.SmartEntryDropDown.prototype = new gtk.Widget();
9647 gtk.SmartEntryDropDown.prototype.constructor = gtk.SmartEntryDropDown;
9648 /**
9649  * Set mode to gtk.SmartEntryDropDown
9650  * @param {gtk.TreeStore} mode
9651  */
9652 gtk.SmartEntryDropDown.prototype.setModel = function(model){
9653 	this._controller.setModel(model);
9654 };
9655 /**
9656  * Show Error
9657  * @param {boolean} isOnError
9658  */
9659 gtk.SmartEntryDropDown.prototype.showError = function(isOnError){
9660 	 this._textBoxError = (typeof isOnError !== 'undefined' && typeof isOnError === 'boolean') ? isOnError : this._textBoxError;
9661 
9662     if(this._textBoxError) this._domObj.className += " gtk_smart_entry_onerror";
9663     else this._domObj.className = "gtk_widget gtk_smart_entry_drop_down_widget";
9664 };
9665 /** @private */
9666 gtk.SmartEntryDropDown.prototype._renderDropDown = function(children, parentNode){
9667 	var rowNodes = this._dropDownRendere._constructRowNodes(children, parentNode);
9668 	this._appendDropDown(rowNodes);
9669 };
9670 /** @private */
9671 gtk.SmartEntryDropDown.prototype._renderTag = function(){
9672 	var tag = this._tagRendere._createTag(null, this._dropDownRendere.getSelectedRowNode());
9673 	this._tagHolder.appendChild(tag);
9674 };
9675 /** @private */
9676 gtk.SmartEntryDropDown.prototype._resetEntry = function(){
9677 	this._entry.focus();
9678 	this._entry.value = "";
9679 	this._entry.style.width = this._entryWidth + 5 + "px";
9680 };
9681 /** @private */
9682 gtk.SmartEntryDropDown.prototype._clearDropDown = function(){
9683 	this.__dropDown.innerHTML = "";
9684 };
9685 /** @private */
9686 gtk.SmartEntryDropDown.prototype._handleRowNodeSelected = function(){
9687 	var selectedRowNode = this._dropDownRendere.getSelectedRowNode();
9688 	this._entry.value = selectedRowNode.firstChild.nodeValue;
9689 	this._renderTag();
9690 	this.__hideDropDown();
9691 	this._resetEntry();
9692 	this.__showLabel();
9693 };
9694 /** @private */
9695 gtk.SmartEntryDropDown.prototype._handleParentSignal = function(){
9696     var self = this;
9697     this._isParentSignalHandled = true;
9698     var parentWidget = this.getParent();
9699     parentWidget.connect("scrolled", function(){
9700         self.__hideDropDown();
9701     });
9702 };
9703 /** @private */
9704 gtk.SmartEntryDropDown.prototype._resetDropDownPosition = function(){
9705     var top = jsgtk.Util.pageY(this._domObj);
9706     var left = jsgtk.Util.pageX(this._domObj);
9707 
9708     var header = parseInt(this._holder.offsetHeight);
9709 
9710     var scrollY = this._getNearestScrollerY();
9711 
9712     this.__dropDown.style.top = top + header + 5 - scrollY + "px";
9713     this.__dropDown.style.left = left + 1 + "px";
9714 };
9715 /** @private */
9716 gtk.SmartEntryDropDown.prototype._getNearestScrollerY = function(){
9717     var scrollY = 0;
9718     var parentNode = this._domObj.parentNode;
9719     while(parentNode != null){
9720         if(/gtk_scroller_base/.test(parentNode.className)){
9721             scrollY = parentNode.scrollTop;
9722             this._addEventMouseWheel(parentNode);
9723             break;
9724         }
9725         parentNode = parentNode.parentNode;
9726     }
9727     return scrollY;
9728 };
9729 /** @private */
9730 gtk.SmartEntryDropDown.prototype._addEventMouseWheel = function(scrollObj){
9731     var self = this;
9732     jsgtk.Event.addDomListener(scrollObj, 'scroll', function(e){
9733 	    self.__hideDropDown();
9734 	}, false);
9735 };
9736 /** @private */
9737 gtk.SmartEntryDropDown.prototype._initEvent = function(){
9738 	var self = this;
9739 
9740 	jsgtk.Event.addDomListener(this._domObj, "click", function(e){
9741 		self.setFocus();
9742 		if(!self._isParentSignalHandled) self._handleParentSignal();
9743 		jsgtk.Event.stopBubble(e);
9744 	});
9745 	this.__bindInputEvent();
9746 
9747 	jsgtk.Event.addDomListener(this.__dropDown, "click", function(e){
9748 		var node = e.target;
9749 		if(jsgtk.Util.isMatched("gtk_smart_entry_drop_down_element", node.className))
9750 			self._handleRowNodeSelected();
9751 
9752 		jsgtk.Event.stopBubble(e);
9753 	});
9754 
9755 	jsgtk.Event.addDomListener(this.__dropDown, "mouseover", function(e){
9756 
9757 	    if(!self._ismouseMoved) return;
9758 
9759 		var node = e.target;
9760 		if(jsgtk.Util.isMatched("gtk_smart_entry_drop_down_element", node.className))
9761 			self._dropDownRendere.hilightRowNode(node);
9762 		self._ismouseMoved = false;
9763 	});
9764 
9765 	jsgtk.Event.addDomListener(this.__dropDown, "mousemove", function(e){
9766         self._ismouseMoved = true;
9767 	});
9768 
9769 	jsgtk.Event.addDomListener(document.body, "click", function(e){
9770 		self.__hideEntry();
9771 		self.__hideDropDown();
9772 	});
9773 };
9774 /** @private */
9775 gtk.SmartEntryDropDown.prototype._hilightRow = function(path){
9776 	this._dropDownRendere.hilightRowById(path);
9777 };
9778 /**
9779  * Set gtk.SmartEntryDropDown focus
9780  */
9781 gtk.SmartEntryDropDown.prototype.setFocus = function(){
9782 	this.__showEntry();
9783 
9784 	this._tagRendere.unSelectTags();
9785 	this._dropDownRendere._deHilightSelectedRow();
9786 
9787 	this._entry.focus();
9788 }
9789 /** @private */
9790 gtk.SmartEntryDropDown.prototype.__showEntry = function(){
9791 	this._entryHolder.style.display = "inline-block";
9792 	this._entry.parentNode.style.visibility = "visible";
9793 };
9794 /** @private */
9795 gtk.SmartEntryDropDown.prototype.__hideEntry = function(){
9796 	this._entry.parentNode.style.visibility = "hidden";
9797 };
9798 /** @private */
9799 gtk.SmartEntryDropDown.prototype._appendDropDown = function(dropDown){
9800 	this.__hideLoading();
9801 	this.__dropDown.appendChild(dropDown);
9802 };
9803 /** @private */
9804 gtk.SmartEntryDropDown.prototype.__showLoading = function(){
9805 	this.__dropDown.className += " gtk_smart_entry_drop_down_loading";
9806 };
9807 /** @private */
9808 gtk.SmartEntryDropDown.prototype.__hideLoading = function(){
9809 	this.__dropDown.className = "gtk_smart_entry_drop_down_widget_holder";
9810 };
9811 /** @private */
9812 gtk.SmartEntryDropDown.prototype._isCtrlAKeyPressed = function(e){
9813 	return (e.which == gtk.A_KEY || e.which == gtk.CAP_A_KEY) && e.ctrlKey;
9814 };
9815 /** @private */
9816 gtk.SmartEntryDropDown.prototype.__fireDownArrowKey = function(){
9817 	this._dropDownRendere.hilightNextRowNode();
9818 };
9819 /** @private */
9820 gtk.SmartEntryDropDown.prototype.__fireUpArrowKey = function(){
9821 	this._dropDownRendere.hilightPreviousRowNode();
9822 };
9823 /** @private */
9824 gtk.SmartEntryDropDown.prototype.__fireLeftArrowKey = function(){
9825 	if(!this._tagRendere.isTagExisted()) return;
9826 
9827 	var tag = this._tagRendere.isPreviousTagExisted();
9828 	if(!tag) return;
9829 
9830 	if(this._tagRendere.isFixedTag(tag)) return;
9831 
9832 	this._tagRendere.unSelectTag();
9833 	this._tagRendere.selectTag(tag || this._tagRendere.getSelectedTag());
9834 
9835 	this.__hideEntry();
9836     this.__hideDropDown();
9837 };
9838 /** @private */
9839 gtk.SmartEntryDropDown.prototype.__fireRightArrowKey = function(){
9840 	if(!this._tagRendere.isTagExisted() || !this._tagRendere.getSelectedTag()) return;
9841 
9842 	var nextTag = this._tagRendere.isNextTagExisted();
9843 
9844 	if(!nextTag){
9845 		this.__showEntry();
9846 		return;
9847 	}
9848 
9849 	this._tagRendere.unSelectTag();
9850 	this._tagRendere.selectTag(nextTag || this._tagRendere.getSelectedTag());
9851 };
9852 /** @private */
9853 gtk.SmartEntryDropDown.prototype.__fireEnterKey = function(){
9854 	if(this._dropDownRendere.getSelectedRowNode()){
9855 		this._handleRowNodeSelected();
9856 
9857 		this._dropDownRendere._deHilightSelectedRow();
9858 	}
9859 };
9860 /** @private */
9861 gtk.SmartEntryDropDown.prototype.__fireBackSpace = function(value){
9862     var tags = this._tagHolder.childNodes;
9863 
9864 	var entry = this._entry;
9865 	if(entry.value == "") this.__showLabel();
9866 
9867     var len = tags.length;
9868     if(len < 1) return;
9869 
9870     var tag = tags[len-1];
9871 
9872     if(len > 0 && value == "" && tag.childNodes[0].className != "gtk_smart_entry_drop_down_fixed_tag"){
9873 
9874         if(tag.selected){
9875 
9876             tag.parentNode.removeChild(tag);
9877 			this.__showEntry();
9878         	this._tagRendere.unSelectTags();
9879         }
9880         else{
9881     		this._tagRendere.unSelectTags();
9882             tag.selected = true;
9883             tag.className += " gtk_smart_entry_drop_down_tag_selected";
9884 			this.__hideEntry();
9885             this.__hideDropDown();
9886         }
9887     }
9888     return;
9889 };
9890 /** @private */
9891 gtk.SmartEntryDropDown.prototype.__fireDeleteKey = function(){
9892 	var tags = this._tagHolder.childNodes;
9893     var len = tags.length;
9894     var entry = this._entry;
9895 
9896     if(len > 0 && entry.value == ""){
9897         for(var i = len-1 ; i >= 0 ; i--){
9898         	var tag = tags[i];
9899             if(tag.selected){
9900 				this._tagHolder.removeChild(tag);
9901 			}
9902         }
9903 		this._tagRendere.unSelectTag();
9904         this.__showEntry();
9905         entry.focus();
9906     }
9907 };
9908 /** @private */
9909 gtk.SmartEntryDropDown.prototype._selectAllTags = function(){
9910 	this._tagRendere.selectTags();
9911 	this.__hideEntry();
9912 	this.__hideDropDown();
9913 };
9914 /** @private*/
9915 gtk.SmartEntryDropDown.prototype.__showDropDown = function(){
9916 	jsgtk.Dom.showElement(this.__dropDown);
9917 };
9918 /** @private*/
9919 gtk.SmartEntryDropDown.prototype.__hideDropDown = function(){
9920 	jsgtk.Dom.hideElement(this.__dropDown);
9921 };
9922 /** @private */
9923 gtk.SmartEntryDropDown.prototype.__hideLabel = function(){
9924 	this._labelEntry.style.visibility = "hidden";
9925 };
9926 /** @private */
9927 gtk.SmartEntryDropDown.prototype.__showLabel = function(){
9928 	this._labelEntry.style.visibility = "";
9929 };
9930 /** @private */
9931 gtk.SmartEntryDropDown.prototype.getValues = function(){
9932 	var children = this._holder.childNodes[0].childNodes,
9933 	len = children.length;
9934 	var values = [];
9935 	for(var i = 0; i < len; i++){
9936 		values.push(children[i].childNodes[0].innerHTML);
9937 	}
9938 	return values;
9939 };
9940 /** @private */
9941 gtk.SmartEntryDropDown.prototype.getItems = function(){
9942 	var children = this._holder.childNodes[0].childNodes,
9943 	len = children.length;
9944 	var values = [];
9945 	for(var i = 0; i < len; i++){
9946 		values.push(children[i]["valueObject"]);
9947 	}
9948 	return values;
9949 };
9950 /**
9951  * Method to create a smartEntry fixed tag
9952  * @param {String} fixedTag the value of fixed tag to be created
9953  */
9954 gtk.SmartEntryDropDown.prototype.createFixedTag = function(obj){
9955     var tagHolder = jsgtk.Dom.create({"tag": "div", "append": this._tagHolder, "className": "gtk_smart_entry_drop_down_tag_holder"});
9956     var tag  = jsgtk.Dom.create({"tag": "span", "append": tagHolder , "text": obj.value, "className": "gtk_smart_entry_drop_down_fixed_tag"});
9957 	tagHolder.object = obj;
9958 };
9959 /**
9960  * Create tag in smartEntry to a specific order
9961  * @param {integer} index The index of tag to be created
9962  * @param {String} value The value of tag to be created
9963  */
9964 gtk.SmartEntryDropDown.prototype.createTag = function(obj){
9965 	var tag = this._tagRendere._createTag(obj["display"]);
9966 	this._tagHolder.appendChild(tag);
9967     tag.valueObject = obj;
9968 };
9969 /**
9970  * Set text to be displayed inside entry
9971  * @param {string} label
9972  */
9973 gtk.SmartEntryDropDown.prototype.setLabel = function(label){
9974 	this._labelEntry.innerHTML = "";
9975 	this._labelEntry.appendChild(document.createTextNode(label));
9976 	this.__updateEntryWidth();
9977 };
9978 /** @private */
9979 gtk.SmartEntryDropDown.prototype.__updateEntryWidth = function(){
9980 	var tempSpan = this._labelEntry.cloneNode(true);
9981 	var width = jsgtk.Util.fullWidth(tempSpan);
9982 	if(width < 100) width = 100;
9983 	this._entryWidth = width;
9984 	this._entry.style.width = width + 10 + "px";
9985 	this._entry.parentNode.style.width = width + 10 + "px";
9986 };
9987 /** @private */
9988 gtk.SmartEntryDropDown.prototype.resizeWidthComposite = function(width){
9989 	this._width = width;
9990 	this._domObj.style.width = width + 'px';
9991 	this.__dropDown.style.width = width - 2 + "px";
9992 };
9993 /** @private */
9994 gtk.SmartEntryDropDown.prototype.resizeHeightComposite = function(height){
9995 	this._height = height;
9996 	this._domObj.style.height = height - 5 + 'px';
9997 };
9998 gobject.signalNew("_rendersubnodes", gtk.SmartEntryDropDown, null, null, []);
9999 gobject.signalNew("_setselectedvalues", gtk.SmartEntryDropDown, null, null, []);
10000 gobject.signalNew("_search", gtk.SmartEntryDropDown, null, null, []);
10001 gobject.signalNew("smartentrychanged", gtk.SmartEntryDropDown, null, null, []);
10002 /**
10003  * UploadButton is a class to create an upload button
10004  * @param {String} label The label or text display inside the upload button
10005  * @param {String} stock The stock value to be set
10006  * @base gtk.Button
10007  * @constructor
10008  */
10009 gtk.UploadButton = function(label){
10010     gtk.Button.apply(this, [label]);
10011 
10012     var self = this;
10013     this._imageShapeDom = null;
10014 
10015     /** A registered signal name '<b>filechanged</b>' when file is changed */
10016     this.UPLOADBUTTON_FILECHANGED 	= "";
10017     /** A registered signal name '<b>mouseover</b>' */
10018     this.UPLOADBUTTON_MOUSEOVER 	= "";
10019     /** A registered signal name '<b>mouseout</b>' */
10020     this.UPLOADBUTTON_MOUSEOUT 	= "";
10021 
10022     /** @private */
10023     this._render = function(){
10024 	    this._domObj.className += " gtk_upload_button";
10025 	    this._domObj.style.display = "";
10026 
10027 	    this._domImage = jsgtk.Dom.create({"tag": "div", "append": this._domObj, "className": "gtk_uploadbutton_image"});
10028 	    this._className = this._domObj.className;
10029 	    this._inputFile = jsgtk.Dom.create({"tag": "input", "type": "file", "append": this._domObj, "className": "gtk_upload_button_input_file"});
10030 	    this._inputFile.style.width = this._width + "px";
10031 	    this._inputFile.style.height = this._height + "px";
10032 	};
10033    this._render();
10034 
10035    jsgtk.Event.addDomListener(this._inputFile, "change", function(){
10036 		self.emit("filechanged", self._inputFile.value);
10037 	});
10038 
10039 	jsgtk.Event.addDomListener(this._domObj, "mouseover", function(){
10040 		self.emit("mouseover");
10041 	});
10042 
10043 	jsgtk.Event.addDomListener(this._domObj, "mouseout", function(){
10044 		self.emit("mouseout");
10045 	});
10046 };
10047 
10048 gtk.UploadButton.prototype = new gtk.Button();
10049 gtk.UploadButton.prototype.constructor = gtk.UploadButton;
10050 
10051 /**
10052  * A method to set the name of upload button
10053  * @param {String} name The name of upload button
10054  */
10055 gtk.UploadButton.prototype.setName = function(name){
10056     this._inputFile.setAttribute("name", name);
10057 };
10058 
10059 /**
10060  * A method to set the text of upload button
10061  * @param {String} strName The name of upload button
10062  */
10063 gtk.UploadButton.prototype.setText = function(strName){
10064     if(strName != null || typeof strName !== 'undefined') {
10065 		this.setTextLabel(strName);
10066 		this._inputFile.style.width = this._width - 2 + "px";
10067 	}
10068 };
10069 
10070 /**
10071  * A method to get an upload object as Dom
10072  * @return {Dom} The Dom object of upload button
10073  * @type Dom
10074  */
10075 gtk.UploadButton.prototype.getUploadNode = function(){
10076     console.log("gtk.UploadButton.getUploadNode() will be depricated, please use gtk.UploadButton.getChildNode()");
10077     return this.getChildNode();
10078 };
10079 
10080 /**
10081  * A method to get object of the upload input file
10082  * @return {Dom} The object of upload file
10083  * @type Dom
10084  */
10085 gtk.UploadButton.prototype.getChildNode = function(){
10086     return this._inputFile;
10087 };
10088 
10089 /**
10090  * A method to show loading image inside the button
10091  */
10092 gtk.UploadButton.prototype.showLoading = function(){
10093 	this._labelDom.style.display = "none";
10094 	this._imageDom.style.display = "none";
10095 	this._inputFile.style.display = "none";
10096 	if(!this._loading) this._loading = jsgtk.Dom.create({tag:"div", className: "gtk_button_loading", append: this._domObj});
10097 };
10098 
10099 /**
10100  * A method to transform or chagne upload button to image
10101  * @param {gtk.Image} imageObj The gtk.Image object to display to be set
10102  */
10103 gtk.UploadButton.prototype.setAsImage = function(imageObj){
10104 	if(this._imageShapeDom !== null) {
10105 		this._domImage.innerHTML = "";
10106 		this._imageShapeDom = null;
10107 	}
10108 	this._imageShapeDom = imageObj;
10109 	this._domObj.className += " gtk_button_with_image_shape";
10110 	this._gradient.style.display = "none";
10111 	this.setTextLabel("");
10112 	this._domImage.appendChild(imageObj.getNode());
10113 	imageObj.resetSize(imageObj._width, imageObj._height);
10114 
10115 	this._width	= this._minWidth	= imageObj._width;
10116 	this._height	= this._minHeight	= imageObj._height;
10117 
10118 	this.resizeWidthComposite(imageObj._width);
10119 	this.resizeHeightComposite(imageObj._height);
10120 };
10121 
10122 /** @private */
10123 gtk.UploadButton.prototype._getActualImageSize = function(imageObj){
10124 	var imageNode = imageObj.getChildNode();
10125 	var tmpImgObj = new Image();
10126 		 tmpImgObj.src = imageNode.src;
10127 	return [tmpImgObj.width, tmpImgObj.height];
10128 };
10129 
10130 /** @private */
10131 gtk.UploadButton.prototype._getPaddingAndBorderWidth = function(){
10132 	var attribute = this._attribute;
10133 	var paddingWidth 	= 0;
10134 	var borderWidth	= 0;
10135 	for(var el in attribute){
10136 		if(el == "padding") paddingWidth = parseInt(attribute[el]) * 2;
10137 		if(el == "border") borderWidth = parseInt(attribute[el]) * 2;
10138 	}
10139 	return [paddingWidth, borderWidth];
10140 };
10141 
10142 /**
10143  * A method to set attributes and apply styles
10144  * @param {Object} attribute The object literal that contain JavaScript styles
10145  */
10146 gtk.UploadButton.prototype.setAttribute = function(attribute){
10147 	this._attribute 	= attribute;
10148 	var paddingWidth 	= 0;
10149 	var borderWidth	= 0;
10150 	for(var el in attribute){
10151 		this._domObj.style[el] = attribute[el];
10152 		if(el == "padding") paddingWidth = parseInt(attribute[el]);
10153 		if(el == "border") borderWidth = parseInt(attribute[el]);
10154 	}
10155 	this._domImage.style.top = paddingWidth + "px";
10156 	this._domImage.style.left = paddingWidth + "px";
10157 
10158 	this.resizeWidthComposite(this._width);
10159 	this.resizeHeightComposite(this._height);
10160 };
10161 
10162 /**
10163  * A method to disable the control of upload button
10164  */
10165 gtk.UploadButton.prototype.disable = function(){
10166 	this._inputFile.disabled = false;
10167 	if(this._domImage.childNodes.length > 0){
10168 			this._domObj.className += " gtk_button_disabled gtk_upload_button_disabled";
10169 			this._imageShapeDom.getChildNode().style.opacity = 0.50;
10170 	}
10171 	else this._domObj.className += " gtk_button_disabled";
10172 
10173 	this._gradient.className += " gradisable";
10174 	this._inputFile.style.display = "none";
10175 	if(this._widget1 !== null) this._widget1.setStyle({cursor: "default"});
10176 
10177 };
10178 
10179 /**
10180  * A method to set enabled to the button
10181  */
10182 gtk.UploadButton.prototype.enable = function(){
10183 	this._inputFile.disabled = false;
10184 	var uploadBtnClass = "gtk_widget gtk_container gtk_button gtk_upload_button";
10185 	if(this._domImage.childNodes.length > 0) {
10186 			uploadBtnClass = "gtk_widget gtk_container gtk_upload_button";
10187 			this._imageShapeDom.getChildNode().style.opacity = 1;
10188 	}
10189 	this._domObj.className = uploadBtnClass;
10190 	this._gradient.className = "gtk_button_gradient";
10191 	this._inputFile.style.display = "";
10192 	if(this._widget1 !== null) this._widget1.setStyle({cursor: "default"});
10193 
10194 };
10195 
10196 /**
10197  * A method to hide loading image of upload button
10198  */
10199 gtk.UploadButton.prototype.hideLoading = function(){
10200 	this._labelDom.style.display = "";
10201 	this._imageDom.style.display = "";
10202 	this._inputFile.style.display = "";
10203 	if(this._loading){
10204 		this._domObj.removeChild(this._loading);
10205 		this._loading = null;
10206 	}
10207 };
10208 
10209 /** @private */
10210 gtk.UploadButton.prototype._resizeHeight = function(height){
10211 	this._domObj.style.height = this._height + "px";
10212 	this._domObj.childNodes[0].style.height = this._height / 2 + "px";
10213 	this._height = height;
10214 };
10215 
10216 /** @private */
10217 gtk.UploadButton.prototype._resizeWidth = function(width){
10218 	this._domObj.style.width = width - this.borderWidth + "px";
10219 	if(typeof this._domImage !== 'undefined'){
10220 		if(this._domImage.childNodes.length > 0) {
10221 			this._domObj.style.width = width + "px";
10222 		}
10223 	}
10224 	this._width = width;
10225 };
10226 
10227 /**
10228  * A method to resize the width of the upload button
10229  * @param {Interger} width The length of width to be resized.
10230  */
10231 gtk.UploadButton.prototype.resizeWidthComposite = function(width){
10232 	this.setWidth(width);
10233 	this.resize(width, this._height);
10234 	this._inputFile.style.width = width + "px";
10235 	this._domObj.style.width = width + "px";
10236 
10237 	if(typeof this._domImage !== 'undefined'){
10238 		if(this._domImage.childNodes.length > 0) {
10239 			this._imageShapeDom.resetSize(width, this._height);
10240 			this._domObj.style.top = "0px";
10241 		}
10242 	}
10243 };
10244 
10245 /**
10246  * A method to resize the height of upload Button
10247  * @param {Interger} height The length of width to be resized.
10248  */
10249 gtk.UploadButton.prototype.resizeHeightComposite = function(height){
10250 	this.setHeight(height);
10251 	this.resize(this._width, height);
10252 	var inputFileStyle = this._inputFile.style;
10253 	inputFileStyle.height = height + "px";
10254 	inputFileStyle.fontSize = height + "px";
10255 
10256 	this._domObj.style.height = height + "px";
10257 
10258 	if(this._domImage.childNodes.length > 0) {
10259 		this._imageShapeDom.resetSize(this._width, height);
10260 		this._domObj.style.top = "0px";
10261 	}
10262 };
10263 
10264 gobject.signalNew("filechanged", gtk.UploadButton, null, null, []);
10265 gobject.signalNew("mouseover", gtk.UploadButton, null, null, []);
10266 gobject.signalNew("mouseout", gtk.UploadButton, null, null, []);
10267 /**
10268  * Frame is a class to create a frame box to display text or image
10269  * @param {String} label The label or text display as title of the frame
10270  * @base gtk.Widget
10271  * @constructor
10272  */
10273 gtk.Frame = function(label){
10274 	gtk.Widget.apply(this);
10275 
10276 	this._label = label || " ";
10277     this._labelXAlign = 0;
10278     this._labelYAlign = 0.5;
10279     this._child = null;
10280 
10281 	this._minWidth = this._minContainerWidth = this._width = 1;
10282 	this._minHeight = this._minContainerHeight = this._height = 1;
10283 	this._childOffsetWidth = 18;
10284 	this._childOffsetHeight = 39;
10285 	this._attribute;
10286 	/** @private */
10287 	this._render = function(){
10288 		var domObj = this._domObj;
10289 		domObj.className += ' gtk_frame';
10290 		    this._labelDom = jsgtk.Dom.create({'append': domObj, 'tag' : 'div'});
10291 		        this._label = new gtk.Label(label);
10292     		    this._label.setJustify(gtk.JUSTIFY_CENTER);
10293     		    this._labelDom.appendChild(this._label.getNode());
10294 
10295 		this._minWidth = this._minContainerWidth = this._width = this._label.getWidth() + 2;
10296 		this._minHeight = this._minContainerHeight = this._height = this._label.getHeight() + 24;
10297 
10298 		    this._frameArea = jsgtk.Dom.create({"append": domObj,"tag":"div", "className": "gtk_frame_area"});
10299 		    var frameStyle = this._frameArea.style;
10300 		    frameStyle.width = this._width - 2 + "px";
10301 		    frameStyle.height = this._height - 10 + "px";
10302 			    this._widgetContainer = jsgtk.Dom.create({"append": this._frameArea, 'tag': 'div', 'style': 'position: relative'});
10303 			    this._widgetContainer.style.left = "7px";
10304 
10305 		domObj.style.height = this._height + "px";
10306 		domObj.style.width = this._width + "px";
10307 		this.setLabelAlign(this._labelXAlign, 0.5);
10308 	};
10309 
10310 	this._render();
10311 };
10312 
10313 gtk.Frame.prototype = new gtk.Widget();
10314 gtk.Frame.prototype.constructor = gtk.Frame;
10315 
10316 /**
10317  * A method to add or append child inside its body
10318  * @param {Dom} widget The Dom widget to be set
10319  */
10320 gtk.Frame.prototype.appendChild = function(widget){
10321 	if(typeof widget != 'undefined'){
10322         if(this._child !== null){
10323             this._widgetContainer.removeChild(this._child.getNode());
10324         }
10325         this._child = widget;
10326         this._widgetContainer.appendChild(widget.getNode());
10327 
10328         var size = this._getSize();
10329         this.resize(size[0], size[1]);
10330     }
10331 };
10332 
10333 /**
10334  * A method to remove a child from its body
10335  * @param {Dom} widget The Dom widget to be remove
10336  */
10337 gtk.Frame.prototype.removeChild = function(widget){
10338         this._widgetContainer.removeChild(widget.getNode());
10339         this._child = gtk.NullObject;
10340 };
10341 
10342 /**
10343  * A method to add the child widget into Frame
10344  * @param {gtk.widget} widget A child widget to be displayed in frame
10345  */
10346 gtk.Frame.prototype.add = function(widget){
10347     this.appendChild(widget);
10348 	console.log("gtk.Frame.add() will be deprecated, please use appendChild()");
10349 };
10350 
10351 /**
10352  * A method to set the text of the label as specified by label. If label is None the current label is removed
10353  * @param {String} label A string to be used as the label text
10354  */
10355 
10356 gtk.Frame.prototype.setLabel = function(label){
10357     this._label.setText(label);
10358     this._resetMinWidthMinHeight(this._label);
10359     this.setLabelAlign(this._labelXAlign, this._labelYAlign);
10360 };
10361 
10362 /**
10363  * A method to return the text in the label widget
10364  * @return {String} The text in the label, or None if there is no label widget.
10365  * @type String
10366  */
10367 gtk.Frame.prototype.getLabel = function(){
10368     return this._label.getText();
10369 };
10370 
10371 /**
10372  * A method to set the label widget (usually to something other than a gtk.Label widget) for the frame
10373  * @param {gtk.Widget} widget The new label widget
10374  */
10375 gtk.Frame.prototype.setLabelWidget = function(widget){
10376     this.setLabel(widget.getText());
10377     this._labelWidget = widget;
10378 	this._domObj.style.width = 	this._labelWidget._minWidth + 2 + "px";
10379 	this._frameArea.style.width = this._labelWidget._minWidth + "px";
10380 };
10381 
10382 /**
10383  * A method to retrieve the label widget for the frame
10384  * @return {Dom} The label widget, or null if there is no label widget
10385  * @type Dom
10386  */
10387 gtk.Frame.prototype.getLabelWidget = function(){
10388     return this._labelWidget;
10389 };
10390 
10391 /**
10392  * A method to set the alignment of the frame's label widget and decoration (defaults are 0.0 and 0.5) as specified by xalign and yalign
10393  * @param {Double} xAlign The horizontal alignment of the label widget along the top edge of the frame (in the range of 0.0 to 1.0)
10394  * @param {Double} yAlign The vertical alignment of the decoration with respect to the label widget (in the range 0.0 to 1.0)
10395  */
10396 gtk.Frame.prototype.setLabelAlign = function(xAlign, yAlign){
10397     this._labelXAlign = xAlign;
10398     this._labelYAlign = yAlign;
10399     var left = (this._width - this._label.getWidth()) * xAlign -1;
10400     if(left < 1) left = 1;
10401     this._labelDom.style.left = left + "px";
10402 };
10403 
10404 /**
10405  * A method to get or return an array containing the X and Y alignment of the frame's label widget and decoration
10406  * @return {Array} An Array containing the x and y alignments of the frame's label widget
10407  * @type Array
10408  */
10409 gtk.Frame.prototype.getLabelAlign = function(){
10410     return [this._labelXAlign, this._labelYAlign];
10411 };
10412 
10413 /** @private */
10414 gtk.Frame.prototype._getSize = function(){
10415     var width  = this._child.getMinWidthComposite();
10416     var height = this._child.getMinHeightComposite();
10417     width      = this._minContainerWidth  > width  ? this._minContainerWidth  : width;
10418     height     = this._minContainerHeight > height ? this._minContainerHeight : height;
10419     return [width + this._childOffsetWidth, height + this._childOffsetHeight];
10420 };
10421 
10422 /** @private */
10423 gtk.Frame.prototype._resetMinWidthMinHeight = function(label){
10424     if(this._minWidth < label.getWidth()) this._minWidth = label.getWidth();
10425     if(this._minHeight < label.getHeight()) this._minHeight = label.getHeight();
10426 };
10427 
10428 /** @private */
10429 gtk.Frame.prototype._setLabelXAlign = function(){
10430     this._labelXAlign = (this._width/2) - parseInt(this._labelDom.style.width)/2;
10431 };
10432 
10433 /** @private */
10434 gtk.Frame.prototype.resize = function(width, height){
10435     this._resizeWidth(width);
10436     this._resizeHeight(height);
10437     this._resizeChildren(width, height);
10438     this.setLabelAlign(this._labelXAlign, this._labelYAlign);
10439 };
10440 
10441 /** @private */
10442 gtk.Frame.prototype._resizeWidth = function(width){
10443     if(this._minWidth > width) return;
10444 
10445     if(this._width < width) this._width = width;
10446     else width = this._width;
10447 
10448     this._domObj.style.width = width - 2 + "px";
10449         this._frameArea.style.width = width - 4 + "px";
10450             this._widgetContainer.style.width = width - this._childOffsetWidth + 'px';
10451 };
10452 
10453 /** @private */
10454 gtk.Frame.prototype._resizeHeight = function(height){
10455     this._domObj.style.height = height - 2 + "px";
10456         this._frameArea.style.height = height - 12 + "px" ;
10457             this._widgetContainer.style.height = height - this._childOffsetHeight + 'px';
10458     this._height = height;
10459 };
10460 
10461 /** @private */
10462 gtk.Frame.prototype._resizeChildren = function(width, height){
10463     this._child.resizeWidthComposite(width - this._childOffsetWidth);
10464     this._child.resizeHeightComposite(height - this._childOffsetHeight);
10465 };
10466 
10467 /**
10468  * A method to get the minimum width of frame
10469  * @return {Integer} The minimum width of frame
10470  */
10471 gtk.Frame.prototype.getMinWidthComposite = function(){
10472 	var minWidth = this._child.getMinWidthComposite();
10473     if(this._minWidth < minWidth)
10474 		this._minWidth = minWidth;
10475 	return this._minWidth + this._childOffsetWidth;
10476 };
10477 
10478 /**
10479  * A method to get the minimum height of frame
10480  * @return {Integer} The minimum height of frame
10481  */
10482 gtk.Frame.prototype.getMinHeightComposite = function(){
10483 	var minHeight = this._child.getMinHeightComposite();
10484     if(this._minHeight < minHeight)
10485 		this._minHeight = minHeight;
10486 	return this._minHeight + this._childOffsetHeight;
10487 };
10488 
10489 /**
10490  * A method to resize the width of frame
10491  * @param {Interger} width The length of width to be resize.
10492  */
10493 gtk.Frame.prototype.resizeWidthComposite = function(width){
10494 	var minWidthComposite = this.getMinWidthComposite();
10495 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
10496 	this.setWidth(minWidth);
10497 	this.resize(minWidth, this._height);
10498 };
10499 
10500 /**
10501  * A method to resize the height of frame
10502  * @param {Interger} height The length of width to be resize.
10503  */
10504 gtk.Frame.prototype.resizeHeightComposite = function(height){
10505 	var minHeightComposite = this.getMinHeightComposite();
10506 	var minHeight = height > minHeightComposite? height : minHeightComposite;
10507 	this.resize(this._width, minHeight);
10508 };
10509 /**
10510  * A method to set and apply style given an object literal of an object
10511  * @param {Array} The array of attributes object styles
10512  */
10513 gtk.Frame.prototype.setAttribute = function(attribute){
10514 	this._attribute = attribute;
10515 	this._applyAttribute();
10516 };
10517 
10518 /** @private */
10519 gtk.Frame.prototype._applyAttribute = function(){
10520 	for(var el in this._attribute){
10521 	   if(el == "border"){
10522 	    this._frameArea.style.border = this._attribute[el];
10523 	   }else if(el == "backgroundColor"){
10524 	        this._domObj.style[el] = this._attribute[el];
10525 	   }
10526 	   else{
10527 	        this._label.getNode().childNodes[0].childNodes[0].childNodes[0].childNodes[0].style[el] = this._attribute[el];
10528 	   }
10529 	}
10530 };
10531 /**
10532  * Form is a class to create form widget
10533  * @param {Object} attributes The attributes of theform
10534  * @constructor
10535  * @base gtk.Widget
10536  */
10537 gtk.Form = function(attributes){
10538     gtk.Widget.apply(this);
10539 
10540     this._child = null;
10541 
10542     /** @private */
10543     this._render = function(){
10544         this._domObj.className += " gtk_form";
10545         this._form = jsgtk.Dom.create({"tag":"form", "append": this._domObj});
10546         this.setAttribute(attributes);
10547     };
10548 
10549     this._render();
10550 };
10551 
10552 gtk.Form.prototype = new gtk.Widget();
10553 gtk.Form.prototype.constructor = gtk.Form;
10554 
10555 /**
10556  * A method to set the attributes to form
10557  * @param {Object} attributes The attributes to be set as form's attributes
10558  */
10559 gtk.Form.prototype.setAttribute = function(attributes){
10560     var dom = this._form;
10561     for(var property in attributes){
10562         dom.setAttribute(property, attributes[property]);
10563     }
10564 };
10565 
10566 /**
10567  * A method to add a widget to Form
10568  * @param {Widget} widget A child widget to be added to Form
10569  */
10570 gtk.Form.prototype.add = function(widget){
10571 	if(!this._child){
10572 		this._child = widget;
10573 		if(widget._domObj) this._form.appendChild(widget.getNode());
10574 
10575 		var size = this._getChildSize(widget);
10576 		this.resize(size[0], size[1]);
10577 	}
10578 };
10579 
10580 /** @private */
10581 gtk.Form.prototype.resize = function(width, height){
10582     this._resizeWidth(width);
10583     this._resizeHeight(height);
10584 
10585     if(this._child){
10586         this._child.resizeWidthComposite(width);
10587         this._child.resizeHeightComposite(height);
10588     }
10589 };
10590 
10591 /** @private */
10592 gtk.Form.prototype._resizeWidth = function(width){
10593 	this._width = width;
10594 	this._domObj.style.width = this._width + 'px';
10595 };
10596 
10597 /** @private */
10598 gtk.Form.prototype._resizeHeight = function(height){
10599 	this._height = height;
10600 	this._domObj.style.height = this._height - 2 + 'px';
10601 };
10602 
10603 /** @private */
10604 gtk.Form.prototype._getChildSize = function(widget){
10605     var width    = widget.getWidth();
10606     var height   = widget.getHeight();
10607 
10608     return [width, height];
10609 };
10610 
10611 /**
10612  * A method to get the minimum width of Form
10613  * @return The minimum width of Form
10614  * @type Integer
10615  */
10616 gtk.Form.prototype.getMinWidthComposite = function(){
10617     this._minWidth = this._child ? this._child.getMinWidthComposite() : this._width;
10618 	return this._minWidth;
10619 };
10620 
10621 /**
10622  * A method to get the minimum height of Form
10623  * @return The minimum height of Form
10624  * @type Integer
10625  */
10626 gtk.Form.prototype.getMinHeightComposite = function(){
10627     this._minHeight = this._child ? this._child.getMinHeightComposite() : this._height;
10628 	return this._minHeight;
10629 };
10630 
10631 /**
10632  * A method to resize the width of Form
10633  * @param {Interger} width The length of width to be resize.
10634  */
10635 gtk.Form.prototype.resizeWidthComposite = function(width){
10636 	var minWidthComposite = this.getMinWidthComposite();
10637 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
10638 	this.resize(minWidth, this._height);
10639 };
10640 
10641 /**
10642  * A method to resize the height of Form
10643  * @param {Interger} height The length of width to be resize.
10644  */
10645 gtk.Form.prototype.resizeHeightComposite = function(height){
10646 	var minHeightComposite = this.getMinHeightComposite();
10647 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
10648 	this.resize(this._width, minHeight);
10649 };
10650 /**
10651  * UnorderList is a class to create an ordered or unordered list
10652  * @base gtk.Widget
10653  * @constructor
10654  */
10655 gtk.UnorderList = function(){
10656 	gtk.Widget.apply(this);
10657 	this._minWidth = this._width = 150;
10658 	this._minHeight = this._height = 16;
10659 
10660 	/** A registered signal name 'clicked' */
10661 	this.UNORDERLIST_CLICKED = '';
10662 
10663 	this._render = function(){
10664 	    this._domObj.className += " gtk_unorderlist";
10665 	        this.__ul = jsgtk.Dom.create({tag: "ul", append: this._domObj});
10666 	};
10667 
10668 	this._domObj.style.width = this._width + "px";
10669 	this._domObj.style.height = this._height + "px";
10670 
10671 	this._render();
10672 	this._initEvents();
10673 };
10674 
10675 gtk.UnorderList.prototype = new gtk.Widget();
10676 gtk.UnorderList.prototype.constructor = gtk.UnorderList;
10677 
10678 /**
10679  * A method to set modal data or reset modal data
10680  * @param {Object} model The model to be set as gtk.ListModel
10681  */
10682 gtk.UnorderList.prototype.setModel = function(model){
10683     this.__model = model;
10684     this.__constroller = new gtk.UnorderListController(this, model);
10685 };
10686 
10687 /** @private */
10688 gtk.UnorderList.prototype._renderList = function(model, parent){
10689     var docFragment = parent || document.createDocumentFragment();
10690     if(model.children != null){
10691         var children = model.children;
10692         var childLength = children.length;
10693     }else{
10694         var children = model;
10695         var childLength = children.length;;
10696     }
10697 
10698     for(var i = 0;i < childLength; i++){
10699         var child = children[i];
10700         if(child.children == null){
10701             var li = jsgtk.Dom.create({tag: "li", style: child.style, text: child.value, append: docFragment});
10702         }
10703         else{
10704             var li = jsgtk.Dom.create({tag: "li", style: child.style, text: child.value, append: docFragment});
10705             var ul = jsgtk.Dom.create({tag: "ul", style: child.style, append: li, style: "list-style-type: " + child.type});
10706             this._renderList(child.children, ul);
10707         }
10708     };
10709 
10710     return docFragment;
10711 };
10712 
10713 /** @private */
10714 gtk.UnorderList.prototype._initEvents = function(){
10715     var _self = this;
10716     jsgtk.Event.addDomListener(this.__ul, 'click', function(){
10717         _self.emit("clicked", _self._getItemsValue());
10718     });
10719 };
10720 
10721 /** @private */
10722 gtk.UnorderList.prototype._appendList = function(list){
10723     if(this.__ul.childNodes) this.__ul.innerHTML = "";
10724     this.__ul.appendChild(list);
10725 };
10726 
10727 /**
10728  * A method to set type orderedlist or unorderedlist
10729  * @param {String} type The type style of list
10730  */
10731 gtk.UnorderList.prototype.setListType = function(type){
10732     this.__ul.style.listStyleType = type;
10733 };
10734 
10735 /**
10736  * A method to set line height or spacing between each list
10737  * @param {Integer} height The line height of paragraph or sentence
10738  */
10739 gtk.UnorderList.prototype.setLineHeight = function(height){
10740     this.__ul.style.lineHeight = height + "px";
10741     this._calculateDomHeight();
10742     this._resize();
10743 };
10744 
10745 /** @private */
10746 gtk.UnorderList.prototype._getItemsValue = function(){
10747     var childObj = this.__ul.childNodes;
10748     var itemLength = childObj.length;
10749     var itemsValue = [];
10750     for(var i = 0; i< itemLength; i++){
10751         itemsValue.push(childObj[i].textContent);
10752     }
10753     return itemsValue;
10754 };
10755 
10756 /** @private */
10757 gtk.UnorderList.prototype._calculateDomHeight = function(){
10758     var temp = this._domObj.childNodes[0].cloneNode(true);
10759     temp.style.width = this._width - 14 + "px";
10760     this._height = this._minHeight = jsgtk.Util.fullHeight(temp);
10761     return this._height;
10762 };
10763 
10764 /**
10765  * A method to get minimum width of the list
10766  * @return {Integer} The minimum width of the list
10767  * @type Integer
10768  */
10769 gtk.UnorderList.prototype.getMinWidthComposite = function(){
10770     return this._minWidth;
10771 };
10772 
10773 /**
10774  * A method to get minimum height of the list
10775  * @return {Integer} The minimum height of the list
10776  * @type Integer
10777  */
10778 gtk.UnorderList.prototype.getMinHeightComposite = function(){
10779     return this._minHeight;
10780 };
10781 
10782 /** @private */
10783 gtk.UnorderList.prototype._resizeHeight = function(height){
10784     this._domObj.style.height = height + "px";
10785 };
10786 
10787 /** @private */
10788 gtk.UnorderList.prototype._resizeWidth = function(width){
10789     this._domObj.style.width = width + "px";
10790 };
10791 
10792 /** @private */
10793 gtk.UnorderList.prototype._resize = function(){
10794     this._resizeWidth(this._width);
10795     this._resizeHeight(this._height);
10796 };
10797 
10798 /**
10799  * A method to resize composite width of the list
10800  * @param {Integer} width The composite width to be set
10801  */
10802 gtk.UnorderList.prototype.resizeWidthComposite = function(width){
10803     this._width = this._minWidth = this._width > width ? this._width : width;
10804     this._calculateDomHeight();
10805     this._resize();
10806 };
10807 
10808 /**
10809  * A method to resize composite height of the list
10810  * @param {Integer} width The composite height to be set
10811  */
10812 gtk.UnorderList.prototype.resizeHeightComposite = function(height){
10813     this._height = this._minHeight = this._height > height ? this._height : height;
10814     this._resize();
10815 };
10816 
10817 /**
10818  * A method to set change to pointer or hand
10819  */
10820 gtk.UnorderList.prototype.setPointerCursor = function(){
10821     this.__ul.style.cursor = "pointer";
10822     this.__ul.style.cursor = "hand";
10823 };
10824 
10825 gobject.signalNew("clicked", gtk.UnorderList, null, null, []);
10826 /**
10827  * Accordion is a class to create an accordion widget
10828  * @param {Boolean} The boolean value true or false is to define whether all children have the same width or height
10829  * @base gtk.Widget
10830  * @constructor
10831  */
10832 gtk.Accordion = function(homogeneous){
10833     gtk.Widget.apply(this);
10834 
10835     this._minWidth  = this._width  = 200;
10836     this._minHeight = this._height = 30;
10837     this._accordionHeaderHeight = 22;
10838     this._children = [];
10839     this._homogeneous = homogeneous || true;
10840     this._activeIndex = null;
10841 
10842     /** A registered signal name 'activated' */
10843     this.ACCORDION_ACTIVATED = '';
10844     /** A registered signal name 'deactivated' */
10845     this.ACCORDION_DEACTIVATED = '';
10846 
10847     this._render = function(){
10848         this._domObj.className += " gtk_accordion";
10849     };
10850     this._render();
10851 };
10852 
10853 gtk.Accordion.prototype = new gtk.Widget();
10854 gtk.Accordion.prototype.constructor = gtk.Accordion;
10855 
10856 /**
10857  * Method to add or append content to to each tab of accordion
10858  * @param {String} title The title of the accordion tab
10859  * @param {Object} childWidget The DOM object of the child content
10860  */
10861 gtk.Accordion.prototype.appendChild = function(title, childWidget){
10862     childWidget.setParent(this);
10863 
10864     var childObject = this._createChildObject({"title": title, "childWidget": childWidget});
10865     this._children.push(childObject);
10866 
10867     this._appendAccordionNodeHolder(childObject["accordionNodeHolder"]);
10868 
10869     this.resizeWidthComposite(this._width);
10870     this.resizeHeightComposite(this._height);
10871 
10872     this.activate(0);
10873 };
10874 
10875 /**
10876  * Method to set deactivation unto any tab of accordion
10877  * @param {Integer} index The index value of the accordion tab
10878  */
10879 gtk.Accordion.prototype.deActivate = function(index){
10880     this._activeIndex = null;
10881     for(var i = 0, len = this._children.length; i < len; i++){
10882         if(i === index) {
10883             jsgtk.Dom.hideElement(this._children[index]["childNodeHolder"]);
10884             var imgNode = this._children[index]["headerNodeHolder"].childNodes[1];
10885             imgNode.className = "gtk_accordion_collapseimg";
10886         }
10887     }
10888 };
10889 
10890 /**
10891  * Method to set activation unto any tab of accordion
10892  * @param {Integer} The index value of the accordion tab
10893  */
10894 gtk.Accordion.prototype.activate = function(index){
10895     for(var i = 0, len = this._children.length; i < len; i++){
10896         if(i === index) {
10897             jsgtk.Dom.showElement(this._children[index]["childNodeHolder"]);
10898             var imgNode = this._children[index]["headerNodeHolder"].childNodes[1];
10899             imgNode.className = "gtk_accordion_expandimg";
10900             this._activeIndex = index;
10901         }
10902         else {
10903             jsgtk.Dom.hideElement(this._children[i]["childNodeHolder"]);
10904             var imgNode = this._children[i]["headerNodeHolder"].childNodes[1];
10905             imgNode.className = "gtk_accordion_collapseimg";
10906         }
10907     }
10908 };
10909 
10910 /** @private */
10911 gtk.Accordion.prototype._getAccordionIndex = function(headerNodeHolder){
10912     for(var i = 0, len = this._children.length; i < len; i++){
10913         if(this._children[i]["headerNodeHolder"] === headerNodeHolder) return i;
10914     }
10915 };
10916 
10917 /** @private */
10918 gtk.Accordion.prototype._createAccordionNodeHolder = function(headerNodeHolder, childNodeHolder){
10919     var accordionNodeHolder = jsgtk.Dom.create({"tag": "div", "className": "gtk_accordion_node_holder"});
10920     accordionNodeHolder.appendChild(headerNodeHolder);
10921     accordionNodeHolder.appendChild(childNodeHolder);
10922 
10923     return accordionNodeHolder;
10924 }
10925 
10926 /** @private */
10927 gtk.Accordion.prototype._createHeaderNodeHolder = function(title){
10928     var headerNode = jsgtk.Dom.create({"tag": "div", "className": "gtk_accordion_header"});
10929         var titleNode = jsgtk.Dom.create({"append": headerNode, "text": title,"tag": "div", "className": "gtk_accordion_title"});
10930         var imgNode = jsgtk.Dom.create({"append": headerNode, "tag": "span", "className": "gtk_accordion_collapseimg"});
10931 
10932     this._initEvent(headerNode);
10933 
10934     return headerNode;
10935 };
10936 
10937 /** @private */
10938 gtk.Accordion.prototype._createChildNodeHolder = function(childWidget){
10939     var childNodeHolder = jsgtk.Dom.create({"tag": "div", "className": "gtk_accordion_child_node_holder"});
10940     childNodeHolder.appendChild(childWidget.getNode());
10941 
10942     return childNodeHolder;
10943 };
10944 
10945 /** @private */
10946 gtk.Accordion.prototype._createChildObject = function(childProperties){
10947     var headerNodeHolder     = this._createHeaderNodeHolder(childProperties["title"]);
10948     var childNodeHolder     = this._createChildNodeHolder(childProperties["childWidget"]);
10949     var accordionNodeHolder = this._createAccordionNodeHolder(headerNodeHolder, childNodeHolder);
10950 
10951     var childObject = {
10952         "accordionNodeHolder": accordionNodeHolder,
10953         "headerNodeHolder": headerNodeHolder,
10954         "childNodeHolder": childNodeHolder,
10955         "childWidget": childProperties["childWidget"]
10956     };
10957 
10958     return childObject;
10959 };
10960 
10961 /** @private */
10962 gtk.Accordion.prototype._appendAccordionNodeHolder = function(accordionNodeHolder){
10963     this._domObj.appendChild(accordionNodeHolder);
10964 };
10965 
10966 /** @private */
10967 gtk.Accordion.prototype._getAccordionsHeaderHeight = function(){
10968     return this._children.length * this._accordionHeaderHeight;
10969 };
10970 
10971 /** @private */
10972 gtk.Accordion.prototype._resizeChildrenNodeWidth = function(minWidth){
10973     for(var i = this._children.length; i--;)
10974         this._children[i]["childWidget"].resizeWidthComposite(minWidth);
10975 };
10976 
10977 /** @private */
10978 gtk.Accordion.prototype._resizeChildrenNodeHeight = function(minHeight){
10979     for(var i = this._children.length; i--;)
10980         this._children[i]["childWidget"].resizeHeightComposite(minHeight);
10981 };
10982 
10983 /**
10984  * Method to get minimum height of childNodeHolder
10985  * @return {Integer} The minimum height of it
10986  * @type Integer
10987  */
10988 gtk.Accordion.prototype.getMinHeightComposite = function(){
10989     var minHeight = 0
10990     for(var i = this._children.length; i--;){
10991         var childWidgetMinHeight = this._children[i]["childWidget"].getMinHeightComposite()
10992         minHeight = minHeight < childWidgetMinHeight ? childWidgetMinHeight : minHeight;
10993     }
10994 
10995     minHeight += this._children.length * this._accordionHeaderHeight;
10996 
10997     this._minHeight = this._minHeight < minHeight ? minHeight : this._minHeight;
10998     return this._minHeight;
10999 };
11000 
11001 /**
11002  * Method to get minimum width of childNodeHolder
11003  * @return {Integer} The minimum width of it
11004  * @type Integer
11005  */
11006 gtk.Accordion.prototype.getMinWidthComposite = function(){
11007     for(var i = this._children.length; i--;){
11008         var childWidgetMinWidth = this._children[i]["childWidget"].getMinWidthComposite();
11009         this._minWidth = this._minWidth < childWidgetMinWidth ? childWidgetMinWidth : this._minWidth;
11010     }
11011     return this._minWidth;
11012 };
11013 
11014 /**
11015  * Method to resize width composite of it
11016  * @param {Integer} width The new width needs setting to the widget
11017  */
11018 gtk.Accordion.prototype.resizeWidthComposite = function(width){
11019     var minWidth = this.getMinWidthComposite();
11020     minWidth = minWidth < width ? width : minWidth;
11021     this._resizeWidth(minWidth);
11022     this._resizeChildrenNodeWidth(minWidth);
11023 };
11024 
11025 /**
11026  * Method to resize height composite of it
11027  * @param {Integer} height The new height needs setting to the widget
11028  */
11029 gtk.Accordion.prototype.resizeHeightComposite = function(height){
11030     var minHeight = this.getMinHeightComposite();
11031     minHeight = minHeight < height ? height : minHeight;
11032     this._resizeHeight(minHeight);
11033     this._resizeChildrenNodeHeight(minHeight - this._getAccordionsHeaderHeight());
11034 };
11035 
11036 /** @private */
11037 gtk.Accordion.prototype._initEvent = function(headerNode){
11038     var self = this;
11039     jsgtk.Event.addDomListener(headerNode, "click", function(e){
11040         var index = self._getAccordionIndex(headerNode);
11041 
11042         if(index === self._activeIndex) {
11043         	self.deActivate(index);
11044         	self.emit("deactivated", index);
11045         }
11046         else {
11047         	self.activate(index);
11048         	self.emit("activated", index);
11049         }
11050 
11051     }, false);
11052 };
11053 
11054 gobject.signalNew("activated", gtk.Accordion, null, null, []);
11055 gobject.signalNew("deactivated", gtk.Accordion, null, null, []);
11056 /**
11057  * Blank is a class to create a blank widget
11058  * @base gtk.Widget
11059  * @constructor
11060  */
11061 gtk.Blank = function(){
11062 	gtk.Widget.apply(this);
11063 	this.type = gtk.BLANK_WIDGET;
11064 	this._render = function(){
11065 		this._domObj.className += " gtk_blank";
11066 	};
11067 
11068 	this._render();
11069 	this.showLoading();
11070 };
11071 
11072 gtk.Blank.prototype = new gtk.Widget();
11073 gtk.Blank.prototype.constructor = gtk.Blank;
11074 /**
11075  * Bubble is a class to create Bubble or Tooltip
11076  * @param {Object} dom DOM object of its child content
11077  * @param {Object} callerId DOM object of parent to show/display bubble or tooltip
11078  * @param {String} title The title of the Bubble
11079  * @param {Integer} tailDistance An integer value for tail of bubble
11080  * @param {Boolean} isVertical The boolean value true or false to define if it is horizontal or vertical
11081  * @param {Integer} tailLength An integer value of tail length
11082  * @base gtk.Widget
11083  * @constructor
11084  */
11085 gtk.Bubble = function(dom, callerId, title, tailDistance, isVertical, tailLength){
11086     gtk.Widget.apply(this);
11087 
11088     this._domContent = dom;
11089 
11090     this._callerDom = (typeof callerId == "object") ? callerId : document.getElementById(callerId);
11091 
11092     this._isVertical = isVertical || false;
11093     this._tailDistance = tailDistance;
11094     this._title = title || "";
11095     this._closeButton = null;
11096     this._bubbleShape = null;
11097     this._contentWidth = 0;
11098     this._contentHeight = 0;
11099     this._minHeight = 25;
11100     this._minWidth = 100;
11101     this._titleHeight = 0;
11102     this._tailSide = "left";
11103     this._tailWidth = tailLength || 0;
11104     this._tailDistance = tailDistance || 30;
11105 
11106     /** A registered signal name 'closed' */
11107     this.BUBBLE_CLOSED = "";
11108 
11109     dom.className = "gtk_bubble_content";
11110     this._contentWidth = this._calculateDomWidth(dom);
11111     this._contentHeight = this._calculateDomHeight(dom);
11112 
11113 	this._render = function(dom, callerId, title, tailDistance, isVertical, tailLength){
11114 	    var bubbleDom = this._domObj;
11115 	    bubbleDom.className += " gtk_bubble";
11116 	    bubbleDom.setAttribute("id", "gtk_bubble");
11117 	    bubbleDom.style.position = "absolute";
11118 
11119         this._closeButton = jsgtk.Dom.create({"tag": "p", "append": bubbleDom, "className": "gtk_bubble_close_button"});
11120         this._closeButton.innerHTML = " ";
11121 
11122         this._spanTitle = this._createTitle(bubbleDom);
11123 
11124         var callerDomProperties = this._getDomProperties(this._callerDom);
11125 
11126         this._tailSide = callerDomProperties.tailSide;
11127 
11128 		this._positionBubbleTail(callerDomProperties);
11129 
11130         this._bubbleShape = new mylabs.Shape("bubble", 0, 0, this._contentWidth, this._getBubbleHeight(), this._tailSide, this._tailDistance);
11131 
11132         var domObjStyle = bubbleDom.style;
11133         domObjStyle.height = this._contentHeight + "px";
11134         domObjStyle.width = this._contentWidth + "px";
11135 
11136 		document.body.appendChild(bubbleDom);
11137         this._setContent(this._domContent);
11138 
11139         bubbleDom.insertBefore(this._bubbleShape.getNode(), bubbleDom.firstChild);
11140     };
11141 
11142 	this._render(dom, callerId, title, tailDistance, isVertical, tailLength);
11143 
11144 	this._initEvents();
11145 };
11146 
11147 gtk.Bubble.prototype = new gtk.Widget();
11148 gtk.Bubble.prototype.constructor = gtk.Bubble;
11149 
11150 /** @private */
11151 gtk.Bubble.prototype._initEvents = function(){
11152     var _self = this;
11153     jsgtk.Event.addDomListener(this._closeButton, 'click', function(e){
11154         _self.close();
11155         e.cancelBubble = true;
11156     });
11157 };
11158 
11159 /** @private */
11160 gtk.Bubble.prototype._setContent = function(content){
11161     if(content){
11162         this._domContent.className = "gtk_bubble_content";
11163         this._domObj.appendChild(content);
11164     }
11165 };
11166 
11167 /** @private */
11168 gtk.Bubble.prototype._setContentWidth = function(width){
11169     this._contentWidth = width > this._minWidth ?  width : this._minWidth;
11170 };
11171 
11172 /** @private */
11173 gtk.Bubble.prototype._getContentWidth = function(){
11174     return this._contentWidth;
11175 };
11176 
11177 /** @private */
11178 gtk.Bubble.prototype._setContentHeight = function(height){
11179     this._contentHeight = height;
11180 };
11181 
11182 /** @private */
11183 gtk.Bubble.prototype._getContentHeight = function(){
11184     return this._contentHeight;
11185 };
11186 
11187 /** @private */
11188 gtk.Bubble.prototype._getBubbleHeight = function(){
11189     var bubbleHeight = this._domContent ? this._getContentHeight() + this._titleHeight : this._titleHeight + 10;
11190 
11191     if(bubbleHeight > this._minHeight){
11192         this._setContentHeight(bubbleHeight);
11193     }else{
11194         this._setContentHeight(this._minHeight);
11195         bubbleHeight = this._getContentHeight();
11196     }
11197     return bubbleHeight;
11198 };
11199 
11200 /** @private */
11201 gtk.Bubble.prototype._createTitle = function(domBubble){
11202     if(this._title){
11203         this._updateTailWidth();
11204         var spanTitle = jsgtk.Dom.create({"append": domBubble, 'tag': "span", "className": "gtk_bubble_title"});
11205         spanTitle.innerHTML = this._title;
11206         spanTitle.style.width = this._getContentWidth() + "px";
11207         this._titleHeight = this._calculateDomHeight(domBubble.childNodes[1]);
11208 
11209         return spanTitle;
11210     }
11211 };
11212 
11213 /** @private */
11214 gtk.Bubble.prototype._updateTailWidth = function(){
11215     var height = this._titleHeight? this._titleHeight : 0;
11216 
11217     this._tailWidth = this._getContentHeight() + height < 70 ? 10 : 20;
11218 };
11219 
11220 /**
11221  * Method to set position of bubble or tooltip
11222  * @param {Object} caller The DOM object of caller or parent
11223  */
11224 gtk.Bubble.prototype.setPosition = function(caller){
11225 	this._callerDom = (typeof caller == "object") ? caller : document.getElementById(caller);
11226 	var callerDomProperties = this._getDomProperties(this._callerDom);
11227 	this._positionBubbleTail(callerDomProperties);
11228 	this._resize();
11229 };
11230 
11231 /**
11232  * Method to set position of bubble or tooltip by mouse position
11233  * @param {Event} e The event to be passed
11234  */
11235 gtk.Bubble.prototype.setPositionByMouse = function(e){
11236     this._domObj.style.left = e.clientX + 5 + "px";
11237     this._domObj.style.top = e.clientY - 12 + "px";
11238 };
11239 
11240 /** @private */
11241 gtk.Bubble.prototype._positionBubbleTail = function(callerDomProperties){
11242 	var domBubble = this._domObj;
11243     var domStyle = domBubble.style;
11244     this._updateTailWidth();
11245 
11246     if(callerDomProperties.tailSide == "right"){
11247         domStyle.left = callerDomProperties.left - (this._tailWidth) - this._getContentWidth() + "px";
11248         this._closeButton.style.left = this._getContentWidth() - this._tailWidth + 4  +"px";
11249         domStyle.top = callerDomProperties.top + parseInt(callerDomProperties.height / 2) - this._tailDistance - (this._tailWidth/2)+ "px";
11250     }
11251     else if(callerDomProperties.tailSide == "left"){
11252         domStyle.left = callerDomProperties.width + callerDomProperties.left + "px";
11253         domStyle.paddingLeft = this._tailWidth + "px";
11254         this._closeButton.style.left = this._getContentWidth() + this._tailWidth - 16 +"px";
11255         domStyle.top = callerDomProperties.top + parseInt(callerDomProperties.height / 2) - this._tailDistance - (this._tailWidth/2)+ "px";
11256     }
11257     else if(callerDomProperties.tailSide == "up"){
11258         domStyle.top = callerDomProperties.top + callerDomProperties.height  + "px";
11259         domStyle.left = callerDomProperties.width/2 + callerDomProperties.left - this._tailDistance - 8 + "px";
11260         this._spanTitle.style.top = this._tailWidth + "px";
11261         if(this._domContent) this._domContent.style.top = this._tailWidth + "px";
11262         this._closeButton.style.left = this._getContentWidth() - this._tailWidth + 4 + "px";
11263         this._closeButton.style.top = this._tailWidth - 4 + "px";
11264     }
11265     else{
11266         var contentHeight = this._getContentHeight();
11267         domStyle.top = callerDomProperties.top - this._titleHeight - this._tailWidth - contentHeight  + "px";
11268         domStyle.left = callerDomProperties.width/2 - this._tailDistance + callerDomProperties.left - 8 + "px";
11269         this._closeButton.style.left = this._getContentWidth() - this._tailWidth + 4 + "px";
11270         this._closeButton.style.top = -4 + "px";
11271     }
11272 };
11273 
11274 /** @private */
11275 gtk.Bubble.prototype._initEvents = function(){
11276     var self = this;
11277     jsgtk.Event.addDomListener(this._closeButton, 'click', function(e){
11278         self.close();
11279         e.cancelBubble = true;
11280     });
11281 };
11282 
11283 
11284 /**
11285  * Method to show the bubble after initiated
11286  */
11287 gtk.Bubble.prototype.show = function(){
11288     if(this._intervalID) { clearInterval(this._intervalID); }
11289     this.setPosition(this._callerDom);
11290     this._domObj.style.display = "";
11291 };
11292 
11293 /**
11294  * Method to set a newa title of the bubble
11295  * @param {String} title The string title is set to bubble
11296  */
11297 gtk.Bubble.prototype.setTitle = function(title){
11298     if(!this._spanTitle){
11299         this._spanTitle = jsgtk.Dom.create({"tag": "span", "className": "gtk_bubble_title"});
11300         this._spanTitle.className += this._tailSide == "left" ? " leftTailBubble": " rightTailBubble";
11301         var svgDom = document.getElementsByTagName("path")[0].parentNode;
11302         this._domObj.insertBefore(this._spanTitle, svgDom);
11303     }
11304 
11305     this._title = title;
11306     this._spanTitle.innerHTML = title;
11307     var titleHeight = this._calculateDomHeight(this._spanTitle);
11308     this._resize();
11309 };
11310 
11311 /**
11312  * Method to get or return the title of the bubble
11313  * @return {String} The title of of the bubble if applicable
11314  */
11315 gtk.Bubble.prototype.getTitle = function(){
11316     return this._title;
11317 };
11318 
11319 /**
11320  * Method to close or remove the bubble
11321  */
11322 gtk.Bubble.prototype.close = function(){
11323     if(this._showConfirm){
11324         var quit = window.confirm(this._message);
11325         if(quit){
11326             jsgtk.Event.trigger(this, "confirm");
11327         }
11328     }
11329 
11330     this._removeModal();
11331     if(this._domObj.parentNode !== null) this._domObj.parentNode.removeChild(this._domObj);
11332 
11333     this._showConfirm = false;
11334     this.emit("closed");
11335 };
11336 
11337 /** @private */
11338 gtk.Bubble.prototype._removeModal = function(){
11339     var modal = document.getElementById("gtk_bubble_modal");
11340     if(modal){ document.body.removeChild(modal); }
11341 };
11342 
11343 /**
11344  * Method to add Dom object into the bubble
11345  * @param {Dom} content The Dom object to be passed
11346  */
11347 gtk.Bubble.prototype.addContent = function(content){
11348     this.removeContent();
11349     content.className = "gtk_bubble_content";
11350     this._domContent = content;
11351     this._contentWidth = this._calculateDomWidth(content);
11352     this._contentHeight = this._calculateDomHeight(content);
11353     this._domObj.style.width = this._contentWidth + "px";
11354     this._domObj.style.height = this._contentHeight + "px";
11355     this._domObj.appendChild(content);
11356     this._resize();
11357 };
11358 
11359 /**
11360  * Method to remove all of its contents
11361  */
11362 gtk.Bubble.prototype.removeContent = function(){
11363     var childNodes = this._domObj.childNodes;
11364     var count = childNodes.length;
11365     var content ;
11366     for(var i = 0; i <count; i++){
11367         if(childNodes[i].className == "gtk_bubble_content"){
11368             content = childNodes[i];
11369         }
11370     }
11371 
11372     if(content){
11373         this._domObj.removeChild(content);
11374     }
11375 };
11376 
11377  /**
11378  * Method to set content as tooltip
11379  * @param {DOm} domContent The DOM content value
11380  */
11381 gtk.Bubble.prototype.setTooltip = function(domContent){
11382     if(domContent){
11383         this.addContent(domContent);
11384     }
11385     if(this._title) this.removeTitle();
11386     this._closeButton.style.display = "none";
11387 };
11388 
11389 /** @private */
11390 gtk.Bubble.prototype._resize = function(){
11391     var nodeStyle = this._domObj.style;
11392     nodeStyle.height = "";
11393     nodeStyle.width = this._contentWidth + "px";
11394     var bubbleHeight = this._calculateDomHeight(this._domObj);
11395     nodeStyle.height = bubbleHeight + "px";
11396 
11397     callerTop = jsgtk.Util.pageY(this._callerDom);
11398     callerHeight = this._callerDom.clientHeight;
11399     this._contentHeight = this._calculateDomHeight(this._domContent);
11400 
11401     if(this._spanTitle){
11402     	this._titleHeight = this._calculateDomHeight(this._spanTitle);
11403     	this._spanTitle.style.width = this._contentWidth + "px";
11404     }
11405 
11406 
11407     var callerProperties = this._getDomProperties(this._callerDom);
11408     this._tailSide = callerProperties.tailSide;
11409 
11410     this._bubbleShape.remove();
11411 
11412     this._bubbleShape = new mylabs.Shape("bubble", 0, 0, this._contentWidth , bubbleHeight, this._tailSide, this._tailDistance);
11413 
11414     this._domObj.insertBefore(this._bubbleShape.getNode(), this._domObj.firstChild);
11415 
11416     if(this._tailSide == "right"){
11417         nodeStyle.left = callerProperties.left - (this._tailWidth + 6) - this._getContentWidth() + "px";
11418         nodeStyle.paddingLeft = "";
11419         this._closeButton.style.left = this._contentWidth - this._tailWidth + 6 + "px";
11420     }
11421     else if(this._tailSide == "up"){
11422         this._domContent.style.top = this._tailWidth + "px";
11423         nodeStyle.paddingLeft = "0px";
11424         this._closeButton.style.left = this._contentWidth - 16 + "px";
11425         this._closeButton.style.top = this._tailWidth - 6 + "px";
11426         this._spanTitle.style.top = this._tailWidth + "px";
11427     }
11428     else if(this._tailSide == "down"){
11429         this._domObj.style.top = callerTop - bubbleHeight - callerHeight + "px";
11430         this._closeButton.style.left = this._contentWidth - 16 + "px";
11431         this._closeButton.style.top = "0px";
11432         this._spanTitle.style.top = "0px";
11433         nodeStyle.paddingLeft = "0px";
11434     }
11435     else{
11436         this._closeButton.style.left = this._contentWidth + this._tailWidth - 16 + "px";
11437     }
11438 };
11439 
11440  /**
11441   * Method to get the content from server then append to bubble
11442   * @param {String} url The URL of resource site
11443   * @param {Function} callback The method which will be executed after get response from server. Callback function should return a dom content
11444   */
11445 gtk.Bubble.prototype.loadContent = function(url, callback){
11446 
11447     this._divLoader = jsgtk.Dom.create({"tag": "div", "className": "gtk_bubble_table"});
11448     var divLoaderStyle = this._divLoader.style;
11449     divLoaderStyle.height = MylabsSvgVml.type == "SVG" ? "70px" : "120px";
11450     divLoaderStyle.width = "300px";
11451 
11452     this._progressBarContainer = jsgtk.Dom.create({"append": this._divLoader, "tag": "span", "className": "gtk_bubble_progress_bar_container"});
11453         this._progressBar = jsgtk.Dom.create({"append": this._progressBarContainer, "tag": "div"});
11454 
11455     this.addContent(this._divLoader);
11456 
11457     this._updateTailWidth();
11458     if(this._tailSide == "right"){
11459         this._domObj.style.paddingLeft = "0px";
11460     }
11461     else if(this._tailSide == "down"){
11462         this._domObj.style.paddingLeft = "0px";
11463     }
11464     else if(this._tailSide == "up"){
11465         var top = this._tailWidth + "px";
11466         this._divLoader.style.top = top;
11467         this._closeButton.style.top = top;
11468         this._spanTitle.style.top = top;
11469     }
11470     else{
11471         this._domObj.style.paddingLeft = this._tailWidth + "px";
11472     }
11473 
11474     this._ajax(url, callback);
11475 
11476 };
11477 
11478  /** @private */
11479 gtk.Bubble.prototype._updateProgressBar = function(state){
11480     var self = this;
11481     this._barWidth = 0;
11482     var bar = this._progressBar;
11483     var x = window.setInterval(
11484         function(){
11485             self._barWidth += 10;
11486             bar.style.width = self._barWidth + "px";
11487             if( self._barWidth== 180) { clearInterval(x); }
11488         },
11489         40
11490     );
11491 };
11492 
11493 /** @private */
11494 gtk.Bubble.prototype._appendContent = function(callback){
11495     var self = this;
11496     var time = 0, count = 50;
11497     var error = false;
11498     var y = window.setInterval(
11499         function(){
11500 
11501             time += count;
11502             if(self._barWidth == 180){
11503                 if(parseFloat(self._progressBar.style.width) < 195) self._progressBar.style.width = (parseFloat(self._progressBar.style.width) + 0.035) + "px";
11504                 if(self._response.state == 4){
11505                     clearInterval(y);
11506                     self._progressBar.style.width = "100%";
11507                     self._domObj.removeChild(self._divLoader);
11508 
11509                     var domContent = callback(eval( "(" + self._response.text + ")" ));
11510                     self.addContent(domContent);
11511                 }
11512             }
11513 
11514             if(time > 15000 && !error){
11515                 error = true;
11516                 var errorSpan = jsgtk.Dom.create({"tag":"span"});
11517                 errorSpan.innerHTML = "<i>This is taking longer than usual. </i><br/> Try again";
11518                 self._divLoader.appendChild(errorSpan);
11519 
11520                 self._divLoader.style.textAlign = "center";
11521             }
11522         },
11523         count
11524     );
11525 };
11526 
11527 /** @private */
11528 gtk.Bubble.prototype._updateContent = function(content){
11529     var container = jsgtk.Dom.create({tag: "div"});
11530     container.innerHTML = content;
11531     this._domObj.removeChild(this._divLoader);
11532     this.addContent(container);
11533 };
11534 
11535 /** @private */
11536 gtk.Bubble.prototype._ajax = function(url, callback){
11537 	var method = "GET";
11538 	var request;
11539 	var self = this;
11540 
11541 	if(window.XMLHttpRequest){
11542 	    request = new XMLHttpRequest();
11543 	}
11544 	else if (window.ActiveXObject){
11545 	    request = new ActiveXObject("Msxml2.XMLHTTP");
11546 	    if (!request){
11547 		    request = new ActiveXObject("Microsoft.XMLHTTP");
11548 	    }
11549 	}
11550 	this._updateProgressBar();
11551 	this._appendContent(callback);
11552 	this._response = {};
11553 	/** @private */
11554 	request.onreadystatechange = function() {
11555 		if (request.readyState == 4){
11556 	        self._response = {
11557 			    state: 4,
11558 			    text: request.responseText
11559 			};
11560 		}
11561 	};
11562 
11563 	request.open(method, url, true);
11564 	request.send(null);
11565 };
11566 
11567 /**
11568  * Method to remove title from bubble
11569  */
11570 gtk.Bubble.prototype.removeTitle = function(){
11571     this._title = "";
11572     this._domObj.removeChild(this._spanTitle);
11573     this._titleHeight = 0;
11574     this._resize();
11575     this._spanTitle = null;
11576 };
11577 
11578 /** @private */
11579 gtk.Bubble.prototype._getDomProperties = function(callerDom){
11580     var callerTemp = callerDom.cloneNode(true);
11581     var side, windowSize,
11582         widthFromLeft = jsgtk.Util.pageX(callerDom),
11583         heightFromTop = jsgtk.Util.pageY(callerDom),
11584         callerX = jsgtk.Util.fullWidth(callerTemp),
11585         callerY = jsgtk.Util.fullHeight(callerTemp);
11586 
11587     if(this._isVertical){
11588         windowSize = jsgtk.Util.windowHeight();
11589         side = (windowSize - heightFromTop - callerY > this._contentHeight + this._titleHeight + this._tailWidth) ? "up" : "down";
11590     }
11591     else{
11592         windowSize = document.body.clientWidth;
11593         side = (windowSize - (widthFromLeft + callerX + this._tailWidth) <  this._contentWidth) ? "right" : "left";
11594     }
11595 
11596     return {
11597         tailSide: side,
11598         left: widthFromLeft,
11599         top: heightFromTop,
11600         windowSize: windowSize,
11601         width: callerX,
11602         height: callerY
11603     };
11604 };
11605 
11606 /**
11607  * Method to show the modal modal window cover on top of page
11608  * @param {Function} callback The callback method
11609  * @param {String} msg The confirm message display in the confirmation popup box
11610  */
11611 gtk.Bubble.prototype.confirmClose = function(callback, msg){
11612     var self = this;
11613     this._showConfirm = true;
11614     this._message = msg || "Are you sure you want to quit?";
11615 
11616     jsgtk.Event.addListener(this, "confirm", callback);
11617     document.onkeypress = function(e){
11618         e = (e)?e:((event)?event:null);
11619         if(e.keyCode == 27){
11620             self.close();
11621         }
11622     };
11623 };
11624 
11625 /**
11626  * Method to show the modal modal window cover on top of page
11627  */
11628 gtk.Bubble.prototype.showModal = function(){
11629     this.show();
11630 
11631     var modal = jsgtk.Dom.create({"append": document.body, "tag": 'div', "id": "gtk_bubble_modal"});
11632     var pageSize = jsgtk.Util.getPageSize();
11633     modal.style.width = pageSize[0] + "px";
11634     modal.style.height = pageSize[1] + "px";
11635     this._domObj.style.display = "";
11636 };
11637 
11638 /** @private */
11639 gtk.Bubble.prototype._calculateDomHeight = function(dom){
11640     if(dom){
11641         var tempDom = dom.cloneNode(true);
11642         tempDom.style.visibility = "hidden";
11643         tempDom.style.position = "absolute";
11644         var marginTop = parseInt(jsgtk.Util.getStyle(tempDom, "marginTop")) || 0;
11645         var marginBottom = parseInt(jsgtk.Util.getStyle(tempDom, "marginBottom")) || 0;
11646         var height = jsgtk.Util.fullHeight(tempDom) + marginTop + marginBottom;
11647         height = this._minHeight > height ? this._minHeight : height;
11648         return height;
11649     }
11650     return 0;
11651 };
11652 
11653 /** @private */
11654 gtk.Bubble.prototype._calculateDomWidth = function(dom){
11655     if(dom){
11656         var tempDom = dom.cloneNode(true);
11657         tempDom.style.visibility = "hidden";
11658         tempDom.style.position = "absolute";
11659         var marginLeft = parseInt(jsgtk.Util.getStyle(tempDom, "marginLeft")) || 0;
11660         var marginRight = parseInt(jsgtk.Util.getStyle(tempDom, "marginRight")) || 0;
11661         var width = jsgtk.Util.fullWidth(tempDom) + marginLeft + marginRight;
11662         return width;
11663     }
11664     return 0;
11665 };
11666 
11667 /**
11668  * Method to hide the bubble with in an interval of time. When the user mouseover the bubble, it won't hide. When User mouseout the bubble, the bubble will be hide
11669  * @param {Integer} time The time interval which set to hide bubble. The default interval is 500.
11670  */
11671 gtk.Bubble.prototype.hide = function(time){
11672     var self = this;
11673     if(!this._autoHide){
11674 		this._domObj.style.display = "none";
11675 		return;
11676 	};
11677     this._intervalID = null;
11678     var timeout = time || 500;
11679     var modal = document.getElementById("gtk_bubble_modal");
11680     if(modal){
11681          return;
11682     }else{
11683         jsgtk.Event.addDomListener(this._domObj, "mouseover", function(){
11684             self._domObj.style.display = "";
11685             clearInterval(self._intervalID);
11686             jsgtk.Event.addDomListener(self._domObj, "mouseout", function(){
11687 
11688                 if(!document.getElementById("gtk_bubble_modal")){ self._domObj.style.display = "none"; }
11689             });
11690         });
11691 
11692         var displayNone = function(){
11693             self._domObj.style.display = "none";
11694             clearInterval(self._intervalID);
11695         };
11696 
11697         this._intervalID = setInterval(displayNone, timeout);
11698     }
11699 };
11700 
11701 /** Method to set display auto hideElement
11702  *  @param {Boolean} The boolean true or false for auto display or hide
11703  */
11704 gtk.Bubble.prototype.setAutoHide = function(autoHide){
11705 	this._autoHide = autoHide;
11706 };
11707 
11708 /**
11709  * Method to set fixed position
11710  */
11711 gtk.Bubble.prototype.setFixedPosition = function(){
11712 	this._domObj.style.position = "fixed";
11713 };
11714 
11715 gobject.signalNew("closed", gtk.Bubble, null, null, []);
11716 /**
11717 * Factory class for gtk.Table
11718 * @constructor
11719 * @param {integer} rows number of row of table
11720 * @param {integer} columns number of column of table
11721 * @param {boolean} homogeneous
11722 * <br> - homogeneous = true will return gtk.TableHomogenoues
11723 * <br> - homogeneous = false will return gtk.TableNoneHomogenoues
11724 * @param {boolean} resizeable
11725 * <br> - resizeable = true will make all children expand to fill table
11726 * <bt> - resizeable = false all children will be packed to the most top and most left of table
11727 * @param {integer} spacing between each child
11728 */
11729 gtk.TableFactory = function(rows, columns, homogeneous, resizeable, spacing) {
11730 	return homogeneous ?
11731 	       new gtk.TableHomogenoues(rows, columns, resizeable, spacing) :
11732 	       new gtk.TableNoneHomogenoues(rows, columns, resizeable, spacing);
11733 };
11734 /**
11735 * @constructor
11736 * @param {integer} rows number of row of table
11737 * @param {integer} columns number of column of table
11738 * @param {boolean} resizeable
11739 * <br> - resizeable = true will make all children expand to fill table
11740 * <bt> - resizeable = false all children will be packed to the most top and most left of table
11741 * @param {integer} spacing between each child
11742 */
11743 gtk.TableHomogenoues = function(rows, columns, resizeable, spacing) {
11744 	gtk.TableBase.call(this, rows, columns, resizeable, spacing);
11745 
11746 	this._render = function(){
11747 	    var domObj            = this._domObj;
11748 		domObj.className     += " gtk_table_homogenouse";
11749         this._children        = this._initChildren(this._rows, this._columns);
11750 
11751 		this._initWidthsHeights();
11752 	};
11753 
11754 	this._render();
11755 };
11756 
11757 gtk.TableHomogenoues.prototype = new gtk.TableBase();
11758 gtk.TableHomogenoues.prototype.constructor = gtk.TableHomogenoues;
11759 
11760 /**
11761  * Attach each gtk.Widget to gtk.Table
11762  * @param {gtk.Widget} child
11763  * @param {intger} left x1
11764  * @param {integer} right x2
11765  * @param {integer} top y1
11766  * @param {integer} bottom y2
11767  * @param {object} xoptions {align: gtk.JUSTIFY_LEFT || gtk.JUSTIFY_RIGHT, fill: false || true}
11768  * @param {object} yoptions {align: gtk.JUSTIFY_TOP || gtk.JUSTIFY_BOTTOM, fill: false || true}
11769  * @param {integer} xpadding
11770  * @param {integer} ypadding
11771  */
11772 gtk.TableHomogenoues.prototype.attach = function(child, left, right, top, bottom, xoptions, yoptions, xpadding, ypadding){
11773 
11774     var xcells = 1;
11775 
11776     for(var i = left + 1; i < right; i++){
11777         this._children[i][top].minWidth   = child.getMinWidthComposite();
11778         this._children[i][top].minHeight  = child.getMinHeightComposite();
11779         xcells += 1;
11780     }
11781     if(left + 1 < right){
11782         for(var i = left; i < right; i++){
11783             var ycells = 1;
11784             for(var j = top + 1; j < bottom; j++){
11785                 this._children[i][j].minWidth   = child.getMinWidthComposite();
11786                 this._children[i][j].minHeight  = child.getMinHeightComposite();
11787                 ycells += 1;
11788             }
11789         }
11790     }else{
11791 
11792         var ycells = 1;
11793         for(var i = top + 1; i < bottom; i++){
11794             this._children[left][i].minWidth   = child.getMinWidthComposite();
11795             this._children[left][i].minHeight  = child.getMinHeightComposite();
11796             ycells += 1;
11797         }
11798     }
11799 
11800     var targetChild = this._children[left][top];
11801     targetChild.widget   = child;
11802     targetChild.xoptions = xoptions;
11803     targetChild.yoptions = yoptions;
11804     targetChild.xpadding = xpadding;
11805     targetChild.ypadding = ypadding;
11806     targetChild.xcells   = xcells;
11807     targetChild.ycells   = ycells;
11808     targetChild.left     = left;
11809     targetChild.right    = right;
11810     targetChild.top      = top;
11811     targetChild.bottom   = bottom;
11812     targetChild.minWidth = child.getMinWidthComposite();
11813     targetChild.minHeight= child.getMinHeightComposite();
11814 
11815     this._setMaxChildWidthHeightHomo(targetChild);
11816     this._placeChildrenHomo(this._maxChildWidth, this._maxChildHeight);
11817     this.resize(this._maxChildWidth * this._columns, this._maxChildHeight * this._rows);
11818 };
11819 /** @private */
11820 gtk.TableHomogenoues.prototype._placeChildrenNoneHomo = function(){
11821     var child;
11822     this._domObj.innerHTML = "";
11823     var docFragment = document.createDocumentFragment();
11824     for(var i = 0; i < this._rows; i++){
11825         for(var j = 0; j < this._columns; j++){
11826             child = this._children[j][i];
11827             var width = 0;
11828             var height = 0;
11829             if(child.widget){
11830                 var childWrapper = jsgtk.Dom.create({"append": docFragment, "tag": "div", "style": "position: absolute;"});
11831 
11832                 for(var k = child.left; k < child.right; k++){
11833                     width += this._widths[k]["width"];
11834                 }
11835                 var left = 0; //how far from the left has to place the wrapper
11836                 for(var k = 0; k < child.left; k++){
11837                     left += this._widths[k]["width"];
11838                 }
11839 
11840                 for(var k = child.top; k < child.bottom; k++){
11841                     height += this._heights[k]["height"];
11842                 }
11843                 var top = 0;//how far from the top has to place the wrapper
11844                 for(var k = 0; k < child.top; k++){
11845                     top += this._heights[k]["height"];
11846                 }
11847 
11848                 childWrapper.style.width  = width + "px";
11849                 childWrapper.style.height  = height + "px";
11850                 childWrapper.style.left = left + "px";
11851                 childWrapper.style.top = top + "px";
11852 
11853                 childWrapper.appendChild(child.widget._domObj);
11854 
11855                 this._positionWidgetByXoptionsNoneHomo(child, width);
11856                 this._positionWidgetByYoptionsNoneHomo(child, height);
11857             }
11858         }
11859     }
11860     this._domObj.appendChild(docFragment);
11861 };
11862 /** @private */
11863 gtk.TableHomogenoues.prototype._positionWidgetByXoptionsNoneHomo = function(child, width){
11864     var xpadding = child.xpadding;
11865     var spacing = child.right === this._columns ? 0 : this._spacing;
11866     if(child.xoptions.fill){
11867         child.widget._domObj.style.left = xpadding + "px";
11868         child.widget.resizeWidthComposite(width - xpadding * 2 - spacing);
11869     }else{
11870         var left;
11871         switch(child.xoptions.align){
11872             case gtk.JUSTIFY_LEFT :
11873                 child.widget._domObj.style.left = child.xpadding + "px";
11874                 break;
11875             case gtk.JUSTIFY_RIGHT :
11876                 left = width - (child.minWidth + child.xpadding) - spacing;
11877                 child.widget._domObj.style.left = left + "px";
11878                 break;
11879             case gtk.JUSTIFY_CENTER :
11880                 left = ( (width-spacing) / 2) - (child.minWidth / 2);
11881                 child.widget._domObj.style.left = left + 'px';
11882                 break;
11883         }
11884         child.widget.resizeWidthComposite(child.minWidth);
11885     }
11886 };
11887 /** @private */
11888 gtk.TableHomogenoues.prototype._positionWidgetByYoptionsNoneHomo = function(child, height){
11889     var ypadding = child.ypadding;
11890      var spacing = child.bottom === this._rows ? 0 : this._spacing;
11891     if(child.yoptions.fill){
11892         child.widget._domObj.style.top = ypadding + "px";
11893         child.widget.resizeHeightComposite(height - ypadding * 2 - spacing);
11894     }else{
11895         var top;
11896         switch(child.yoptions.align){
11897             case gtk.JUSTIFY_TOP :
11898                 child.widget._domObj.style.top = child.ypadding + "px";
11899                 break;
11900             case gtk.JUSTIFY_BOTTOM :
11901                 top = height - (child.minHeight + child.ypadding) - spacing;
11902                 child.widget._domObj.style.top = top + "px";
11903                 break;
11904             case gtk.JUSTIFY_CENTER :
11905                 top = ( (height-spacing) / 2) - (child.minHeight / 2);
11906                 child.widget._domObj.style.top = top + 'px';
11907                 break;
11908         }
11909         child.widget.resizeHeightComposite(child.minHeight);
11910     }
11911 };
11912 /** @private */
11913 gtk.TableHomogenoues.prototype._placeChildrenHomo = function(childWidth, childHeight){
11914     var children = this._children;
11915     this._domObj.innerHTML = "";
11916     var docFragment = document.createDocumentFragment();
11917     for(var i = 0; i < this._columns; i++){
11918         for(var j = 0; j < this._rows; j++){
11919             var child = children[i][j];
11920             if(child.widget){
11921                 var childWrapper = jsgtk.Dom.create({'append': docFragment, 'tag': 'div', 'style': 'position: absolute;'});
11922                 childWrapper.style.width  = childWidth  * child.xcells + 'px';
11923                 childWrapper.style.height = childHeight * child.ycells + 'px';
11924                 childWrapper.style.top    = child.top * childHeight + 'px';
11925                 childWrapper.style.left   = child.left * childWidth + 'px';
11926                 childWrapper.appendChild(child.widget._domObj);
11927 
11928                 var width  = this._positionWidgetByXoptionsHomo(child, childWidth);
11929                 var height =this._positionWidgetByYoptionsHomo(child, childHeight);
11930 
11931                 child.widget.resizeWidthComposite(width - 2);
11932                 child.widget.resizeHeightComposite(height - 2);
11933             }
11934         }
11935     }
11936     this._domObj.appendChild(docFragment);
11937 };
11938 /** @private */
11939 gtk.TableHomogenoues.prototype._positionWidgetByYoptionsHomo = function(child, childHeight){
11940     var height;
11941     var spacing = child.bottom === this._rows ? 0 : this._spacing;
11942     if(child.yoptions.fill){
11943         child.widget._domObj.style.top = child.ypadding + 'px';
11944         height  = childHeight  * child.ycells - child.ypadding * 2 - spacing;
11945     }else{
11946         var top;
11947         height  = child.widget.getMinHeightComposite();
11948         switch(child.yoptions.align){
11949             case gtk.JUSTIFY_TOP :
11950                 child.widget._domObj.style.top = child.ypadding + "px";
11951                 break;
11952             case gtk.JUSTIFY_BOTTOM :
11953                 top = (childHeight * child.ycells) - (height + child.ypadding);
11954                 child.widget._domObj.style.top = top + "px";
11955                 break;
11956             case gtk.JUSTIFY_CENTER :
11957                 top = ( (childHeight * child.ycells) / 2) - (height / 2);
11958                 child.widget._domObj.style.top = top + "px";
11959                 break;
11960         }
11961     }
11962     return height;
11963 };
11964 /** @private */
11965 gtk.TableHomogenoues.prototype._positionWidgetByXoptionsHomo = function(child, childWidth){
11966     var width;
11967     var spacing = child.right === this._columns ? 0 : this._spacing;
11968     if(child.xoptions.fill){
11969         child.widget._domObj.style.left = child.xpadding + 'px';
11970         width  = childWidth * child.xcells - child.xpadding * 2 - spacing;
11971     }else{
11972         var left;
11973         width  = child.widget.getMinWidthComposite();
11974         switch(child.xoptions.align){
11975             case gtk.JUSTIFY_LEFT :
11976                 child.widget._domObj.style.left = child.xpadding + "px";
11977                 break;
11978             case gtk.JUSTIFY_RIGHT :
11979                 left = (childWidth * child.xcells) - (width + child.xpadding);
11980                 child.widget._domObj.style.left = left + "px";
11981                 break;
11982             case gtk.JUSTIFY_CENTER :
11983                 left = ( (childWidth * child.xcells) / 2) - (width / 2);
11984                 child.widget._domObj.style.left = left + 'px';
11985                 break;
11986         }
11987     }
11988     return width;
11989 };
11990 /** @private */
11991 gtk.TableHomogenoues.prototype.resize = function(width, height){
11992     this._resizeWidth(width);
11993     this._resizeHeight(height);
11994 };
11995 /** @private */
11996 gtk.TableHomogenoues.prototype._getWidths = function(){
11997     var width = 0;
11998     for(var i = 0; i < this._columns; i++){
11999         width += this._widths[i]["width"];
12000     }
12001     return width;
12002 };
12003 
12004 /** @private */
12005 gtk.TableHomogenoues.prototype._getHeights = function(){
12006     var height = 0;
12007     for(var i = 0; i < this._rows; i++){
12008         height += this._heights[i]["height"];
12009     }
12010     return height;
12011 };
12012 /** @private */
12013 gtk.TableHomogenoues.prototype._getResizeableColumns = function(){
12014     var columns = 0;
12015     for(var i = this._widths.length; i--;){
12016         if(this._widths[i]["resizeable"]) columns += 1;
12017     }
12018     return columns;
12019 };
12020 /** @private */
12021 gtk.TableHomogenoues.prototype.getMinWidthComposite = function(){
12022     return this._maxChildWidth * this._columns;
12023 };
12024 /** @private */
12025 gtk.TableHomogenoues.prototype.getMinHeightComposite = function(){
12026     return this._maxChildHeight * this._rows;
12027 };
12028 /** @private */
12029 gtk.TableHomogenoues.prototype.resizeWidthComposite = function(width){
12030     var widthComposite = this.getMinWidthComposite();
12031    	widthComposite     = width > widthComposite ? width : widthComposite;
12032 
12033     width = width > widthComposite ? width : widthComposite;
12034     var maxChildWidth  = (width / this._columns) + this._spacing;
12035     var maxChildHeight = this._height / this._rows;
12036     if(this._resizeable) this._placeChildrenHomo(maxChildWidth, maxChildHeight);
12037     this.resize(maxChildWidth * this._columns, maxChildHeight * this._rows);
12038 };
12039 /** @private */
12040 gtk.TableHomogenoues.prototype.resizeHeightComposite = function(height){
12041    	var heightComposite = this.getMinHeightComposite();
12042    	heightComposite     = height > heightComposite ? height : heightComposite;
12043 
12044 	height = height > heightComposite ? height : heightComposite;
12045     var maxChildHeight = height / this._rows + this._spacing;
12046     var maxChildWidth  = this._width / this._columns;
12047 	if(this._resizeable) this._placeChildrenHomo(maxChildWidth, maxChildHeight);
12048     this.resize(maxChildWidth * this._columns, maxChildHeight * this._rows);
12049 };
12050 /**
12051 * @constructor
12052 * @param {integer} rows number of row of table
12053 * @param {integer} columns number of column of table
12054 * @param {boolean} resizeable
12055 * <br> - resizeable resolve to true will make all children expand to fill table
12056 * <br> - resizeable resolbe to false all children will be packed to the most top and most left of table
12057 * @param {integer} spacing between each child
12058 */
12059 gtk.TableNoneHomogenoues = function(rows, columns, resizeable, spacing) {
12060 	gtk.TableBase.call(this, rows, columns, resizeable, spacing);
12061 
12062 	this._render = function(){
12063 	    var domObj            = this._domObj;
12064 		domObj.className     += " gtk_table_none_homogenouse";
12065         this._children        = this._initChildren(this._rows, this._columns);
12066 
12067 		this._initWidthsHeights();
12068 	};
12069 
12070 	this._render();
12071 };
12072 
12073 gtk.TableNoneHomogenoues.prototype = new gtk.TableBase();
12074 gtk.TableNoneHomogenoues.prototype.constructor = gtk.TableNoneHomogenoues;
12075 
12076 /**
12077  * Attach each gtk.Widget to gtk.Table
12078  * @param {gtk.Widget} child
12079  * @param {intger} left x1
12080  * @param {integer} right x2
12081  * @param {integer} top y1
12082  * @param {integer} bottom y2
12083  * @param {object} xoptions {align: gtk.JUSTIFY_LEFT || gtk.JUSTIFY_RIGHT, fill: false || true}
12084  * @param {object} yoptions {align: gtk.JUSTIFY_TOP || gtk.JUSTIFY_BOTTOM, fill: false || true}
12085  * @param {integer} xpadding
12086  * @param {integer} ypadding
12087  */
12088 gtk.TableNoneHomogenoues.prototype.attach = function(child, left, right, top, bottom, xoptions, yoptions, xpadding, ypadding){
12089 
12090     var xcells = 1;
12091 
12092     for(var i = left + 1; i < right; i++){
12093         this._children[i][top].minWidth   = child.getMinWidthComposite();
12094         this._children[i][top].minHeight  = child.getMinHeightComposite();
12095         xcells += 1;
12096     }
12097     if(left + 1 < right){
12098         for(var i = left; i < right; i++){
12099             var ycells = 1;
12100             for(var j = top + 1; j < bottom; j++){
12101                 this._children[i][j].minWidth   = child.getMinWidthComposite();
12102                 this._children[i][j].minHeight  = child.getMinHeightComposite();
12103                 ycells += 1;
12104             }
12105         }
12106     }else{
12107 
12108         var ycells = 1;
12109         for(var i = top + 1; i < bottom; i++){
12110             this._children[left][i].minWidth   = child.getMinWidthComposite();
12111             this._children[left][i].minHeight  = child.getMinHeightComposite();
12112             ycells += 1;
12113         }
12114     }
12115 
12116     var targetChild = this._children[left][top];
12117     targetChild.widget   = child;
12118     targetChild.xoptions = xoptions;
12119     targetChild.yoptions = yoptions;
12120     targetChild.xpadding = xpadding;
12121     targetChild.ypadding = ypadding;
12122     targetChild.xcells   = xcells;
12123     targetChild.ycells   = ycells;
12124     targetChild.left     = left;
12125     targetChild.right    = right;
12126     targetChild.top      = top;
12127     targetChild.bottom   = bottom;
12128     targetChild.minWidth = child.getMinWidthComposite();
12129     targetChild.minHeight= child.getMinHeightComposite();
12130 
12131     this._resetWidths(child, left, right, xoptions);
12132     this._resetHeights(child, top, bottom, yoptions);
12133 
12134     this._placeChildrenNoneHomo();
12135 
12136     var maxWidth  = this._getWidths();
12137     var maxHeight = this._getHeights();
12138 
12139     this.resize(maxWidth, maxHeight);
12140     this._minWidth = maxWidth;
12141     this._minHeight= maxHeight;
12142 };
12143 
12144 /** @private */
12145 gtk.TableNoneHomogenoues.prototype._placeChildrenNoneHomo = function(){
12146     var child;
12147     this._domObj.innerHTML = "";
12148     var docFragment = document.createDocumentFragment();
12149     for(var i = 0; i < this._rows; i++){
12150         for(var j = 0; j < this._columns; j++){
12151             child = this._children[j][i];
12152             var width = 0;
12153             var height = 0;
12154             if(child.widget){
12155                 var childWrapper = jsgtk.Dom.create({"append": docFragment, "tag": "div", "style": "position: absolute;"});
12156 
12157                 for(var k = child.left; k < child.right; k++){
12158                     width += this._widths[k]["width"];
12159                 }
12160                 var left = 0; //how far from the left has to place the wrapper
12161                 for(var k = 0; k < child.left; k++){
12162                     left += this._widths[k]["width"];
12163                 }
12164 
12165                 for(var k = child.top; k < child.bottom; k++){
12166                     height += this._heights[k]["height"];
12167                 }
12168                 var top = 0;//how far from the top has to place the wrapper
12169                 for(var k = 0; k < child.top; k++){
12170                     top += this._heights[k]["height"];
12171                 }
12172 
12173                 childWrapper.style.width  = width + "px";
12174                 childWrapper.style.height  = height + "px";
12175                 childWrapper.style.left = left + "px";
12176                 childWrapper.style.top = top + "px";
12177 
12178                 childWrapper.appendChild(child.widget._domObj);
12179 
12180                 this._positionWidgetByXoptionsNoneHomo(child, width);
12181                 this._positionWidgetByYoptionsNoneHomo(child, height);
12182             }
12183         }
12184     }
12185     this._domObj.appendChild(docFragment);
12186 };
12187 /** @private */
12188 gtk.TableNoneHomogenoues.prototype._positionWidgetByXoptionsNoneHomo = function(child, width){
12189     var xpadding = child.xpadding;
12190     var spacing = child.right === this._columns ? 0 : this._spacing;
12191     if(child.xoptions.fill){
12192         child.widget._domObj.style.left = xpadding + "px";
12193         child.widget.resizeWidthComposite(width - xpadding * 2 - spacing);
12194     }else{
12195         var left;
12196         switch(child.xoptions.align){
12197             case gtk.JUSTIFY_LEFT :
12198                 child.widget._domObj.style.left = child.xpadding + "px";
12199                 break;
12200             case gtk.JUSTIFY_RIGHT :
12201                 left = width - (child.minWidth + child.xpadding) - spacing;
12202                 child.widget._domObj.style.left = left + "px";
12203                 break;
12204             case gtk.JUSTIFY_CENTER :
12205                 left = ( (width-spacing) / 2) - (child.minWidth / 2);
12206                 child.widget._domObj.style.left = left + 'px';
12207                 break;
12208         }
12209         child.widget.resizeWidthComposite(child.minWidth);
12210     }
12211 };
12212 /** @private */
12213 gtk.TableNoneHomogenoues.prototype._positionWidgetByYoptionsNoneHomo = function(child, height){
12214     var ypadding = child.ypadding;
12215      var spacing = child.bottom === this._rows ? 0 : this._spacing;
12216     if(child.yoptions.fill){
12217         child.widget._domObj.style.top = ypadding + "px";
12218         child.widget.resizeHeightComposite(height - ypadding * 2 - spacing);
12219     }else{
12220         var top;
12221         switch(child.yoptions.align){
12222             case gtk.JUSTIFY_TOP :
12223                 child.widget._domObj.style.top = child.ypadding + "px";
12224                 break;
12225             case gtk.JUSTIFY_BOTTOM :
12226                 top = height - (child.minHeight + child.ypadding) - spacing;
12227                 child.widget._domObj.style.top = top + "px";
12228                 break;
12229             case gtk.JUSTIFY_CENTER :
12230                 top = ( (height-spacing) / 2) - (child.minHeight / 2);
12231                 child.widget._domObj.style.top = top + 'px';
12232                 break;
12233         }
12234         child.widget.resizeHeightComposite(child.minHeight);
12235     }
12236 };
12237 /** @private */
12238 gtk.TableNoneHomogenoues.prototype._placeChildrenHomo = function(childWidth, childHeight){
12239     var children = this._children;
12240     this._domObj.innerHTML = "";
12241     var docFragment = document.createDocumentFragment();
12242     for(var i = 0; i < this._columns; i++){
12243         for(var j = 0; j < this._rows; j++){
12244             var child = children[i][j];
12245             if(child.widget){
12246                 var childWrapper = jsgtk.Dom.create({'append': docFragment, 'tag': 'div', 'style': 'position: absolute;'});
12247                 childWrapper.style.width  = childWidth  * child.xcells + 'px';
12248                 childWrapper.style.height = childHeight * child.ycells + 'px';
12249                 childWrapper.style.top    = child.top * childHeight + 'px';
12250                 childWrapper.style.left   = child.left * childWidth + 'px';
12251                 childWrapper.appendChild(child.widget._domObj);
12252 
12253                 var width  = this._positionWidgetByXoptionsHomo(child, childWidth);
12254                 var height =this._positionWidgetByYoptionsHomo(child, childHeight);
12255 
12256                 child.widget.resizeWidthComposite(width - 2);
12257                 child.widget.resizeHeightComposite(height - 2);
12258             }
12259         }
12260     }
12261     this._domObj.appendChild(docFragment);
12262 };
12263 /** @private */
12264 gtk.TableNoneHomogenoues.prototype._positionWidgetByYoptionsHomo = function(child, childHeight){
12265     var height;
12266     var spacing = child.bottom === this._rows ? 0 : this._spacing;
12267     if(child.yoptions.fill){
12268         child.widget._domObj.style.top = child.ypadding + 'px';
12269         height  = childHeight  * child.ycells - child.ypadding * 2 - spacing;
12270     }else{
12271         var top;
12272         height  = child.widget.getMinHeightComposite();
12273         switch(child.yoptions.align){
12274             case gtk.JUSTIFY_TOP :
12275                 child.widget._domObj.style.top = child.ypadding + "px";
12276                 break;
12277             case gtk.JUSTIFY_BOTTOM :
12278                 top = (childHeight * child.ycells) - (height + child.ypadding);
12279                 child.widget._domObj.style.top = top + "px";
12280                 break;
12281             case gtk.JUSTIFY_CENTER :
12282                 top = ( (childHeight * child.ycells) / 2) - (height / 2);
12283                 child.widget._domObj.style.top = top + "px";
12284                 break;
12285         }
12286     }
12287     return height;
12288 };
12289 /** @private */
12290 gtk.TableNoneHomogenoues.prototype._positionWidgetByXoptionsHomo = function(child, childWidth){
12291     var width;
12292     var spacing = child.right === this._columns ? 0 : this._spacing;
12293     if(child.xoptions.fill){
12294         child.widget._domObj.style.left = child.xpadding + 'px';
12295         width  = childWidth * child.xcells - child.xpadding * 2 - spacing;
12296     }else{
12297         var left;
12298         width  = child.widget.getMinWidthComposite();
12299         switch(child.xoptions.align){
12300             case gtk.JUSTIFY_LEFT :
12301                 child.widget._domObj.style.left = child.xpadding + "px";
12302                 break;
12303             case gtk.JUSTIFY_RIGHT :
12304                 left = (childWidth * child.xcells) - (width + child.xpadding);
12305                 child.widget._domObj.style.left = left + "px";
12306                 break;
12307             case gtk.JUSTIFY_CENTER :
12308                 left = ( (childWidth * child.xcells) / 2) - (width / 2);
12309                 child.widget._domObj.style.left = left + 'px';
12310                 break;
12311         }
12312     }
12313     return width;
12314 };
12315 /** @private */
12316 gtk.TableNoneHomogenoues.prototype.getMinWidthComposite = function(){
12317     return this._minWidth;
12318 };
12319 /** @private */
12320 gtk.TableNoneHomogenoues.prototype.getMinHeightComposite = function(){
12321     return this._minHeight;
12322 };
12323 /** @private */
12324 gtk.TableNoneHomogenoues.prototype.resizeWidthComposite = function(width){
12325     var widthComposite = this.getMinWidthComposite();
12326    	widthComposite     = width > widthComposite ? width : widthComposite;
12327 
12328     var columns = this._getResizeableColumns();
12329     var offsetWidth = (widthComposite - this._getWidths()) / columns;
12330     for(var i = 0; i < this._columns; i++){
12331         if(this._widths[i]["resizeable"]) this._widths[i]["width"] += offsetWidth;
12332     }
12333     if(this._resizeable) this._placeChildrenNoneHomo();
12334     this.resize(widthComposite, this._height);
12335 };
12336 /** @private */
12337 gtk.TableNoneHomogenoues.prototype.resizeHeightComposite = function(height){
12338    	var heightComposite = this.getMinHeightComposite();
12339    	heightComposite     = height > heightComposite ? height : heightComposite;
12340 
12341     var rows = this._getResizeableRows();
12342     var offsetHeight = (heightComposite - this._getHeights()) / rows;
12343     for(var i = 0; i < this._rows; i++){
12344         if(this._heights[i]["resizeable"]) this._heights[i]["height"] += offsetHeight;
12345     }
12346     if(this._resizeable) this._placeChildrenNoneHomo();
12347     this.resize(this._width, heightComposite);
12348 };
12349 /**
12350  * A widget that displays the contents of a gtk.TextBuffer. A class inherit from gtk.Container
12351  * @constructor
12352  */
12353 gtk.TextView = function(){
12354 	gtk.Widget.apply(this);
12355 	/** 'focused' signal */
12356 	this.TEXTVIEW_FOCUSED = "focused";
12357 	/** 'blurred' signal */
12358 	this.TEXTVIEW_BLURRED = "blurred"
12359 	/** 'enterkeypressed' signal */
12360 	this.TEXTVIEW_ENTERKEYPRESSED = "enterkeypressed";
12361 
12362 	this._editable 		= true;
12363 	this._justification = "left";
12364 	this._focus 		= false;
12365 	this._showError		= true;
12366 
12367 	this._minWidth 		= this._width 	= 100;
12368 	this._minHeight 	= this._height 	= 50;
12369 
12370 	/** @ private */
12371 	this._render = function(){
12372 	    var className = this._domObj.className;
12373 		this._domObj = jsgtk.Dom.create({"tag": "textarea"});
12374 		this._domObj.className = className + ' gtk_text_view';
12375 	};
12376 
12377 	this._render();
12378 
12379 	this._initEvent();
12380 };
12381 
12382 gtk.TextView.prototype = new gtk.Widget();
12383 gtk.TextView.prototype.constructor = gtk.TextView;
12384 /** @private */
12385 gtk.TextView.prototype._initEvent = function(){
12386 	var self = this;
12387 	var jsgtkEvent = jsgtk.Event;
12388 	jsgtkEvent.addDomListener(this._domObj, "focus", function(){
12389 	    self._focus = true;
12390 	    self.emit("focused", self._focus);
12391 	});
12392 
12393 	jsgtkEvent.addDomListener(this._domObj, "blur", function(){
12394 	    self._focus = false;
12395 	    self.emit("blurred", self._focus);
12396 	});
12397 };
12398 /**
12399  * Sets the "editable" property to the value of setting. If setting is True the text in textview is editable by default
12400  * @param {boolean} setting If True the text is editable by default
12401  */
12402 gtk.TextView.prototype.setEditable = function(setting){
12403     this._editable = setting;
12404 
12405     setting? this._domObj.removeAttribute("readonly"):this._domObj.setAttribute("readonly", "readonly");
12406 };
12407 /**
12408  * Show error
12409  * @param {boolean} isOnError
12410  */
12411 gtk.TextView.prototype.showError = function(isOnError){
12412 	this._showError = (typeof isOnError !== 'undefined' && typeof isOnError === 'boolean') ? isOnError : true;
12413 
12414     if(this._showError) this._domObj.className += " gtk_text_view_onerror";
12415     else this._domObj.className = "gtk_widget gtk_container gtk_text_view";
12416 };
12417 /**
12418  * Returns the value of the "editable" property
12419  * @return True if text is editable by default
12420  */
12421 gtk.TextView.prototype.getEditable = function(){
12422     return  this._editable;
12423 };
12424 /**
12425  * Sets the "justification" property to the value of justification. The value of justification must be one of: gtk.JUSTIFY_LEFT, gtk.JUSTIFY_RIGHT, gtk.JUSTIFY_CENTER or gtk.JUSTIFY_FILL
12426  * @param {String} the text justification
12427  */
12428 gtk.TextView.prototype.setJustification = function(justification){
12429     this._justification = justification;
12430     this._domObj.style.textAlign = justification;
12431 };
12432 /**
12433  * Returns the value of the "justification" property. the default justification of paragraphs in text_view. The value of "justification" must be one of: gtk.JUSTIFY_LEFT, gtk.JUSTIFY_RIGHT, gtk.JUSTIFY_CENTER or gtk.JUSTIFY_FILL.
12434  * @return The default justification
12435  */
12436 gtk.TextView.prototype.getJustification = function(){
12437     return this._justification;
12438 };
12439 /**
12440  * Retrieve the value inside TextView
12441  * @return The value of TextView
12442  */
12443 gtk.TextView.prototype.getValue = function(){
12444     return this._domObj.value;
12445 };
12446 /**
12447  * Set the default value inside TextView
12448  * @param {String} value The value to be set into TextView
12449  */
12450 gtk.TextView.prototype.setValue = function(value){
12451     this._domObj.value = value;
12452 };
12453 /** @private */
12454 gtk.TextView.prototype.resize = function(width, height){
12455     this._resizeWidth(width);
12456     this._resizeHeight(height);
12457 };
12458 /**
12459  * Allow user to create custom event when enterkey is pressed
12460  */
12461 gtk.TextView.prototype.allowEnterKey = function(){
12462     var self = this;
12463     jsgtk.Event.addDomListener(this._domObj, "keypress", function(e){
12464 	    if(e.keyCode == gtk.ENTER_KEY){
12465 	        self.emit("enterkeypressed", self._domObj.value);
12466 	        jsgtk.Event.stopDefault(e);
12467 	    }
12468 	});
12469 };
12470 /**
12471  * Focus the cursor on the textview
12472  */
12473 gtk.TextView.prototype.focus = function(){
12474     this._domObj.focus();
12475 };
12476 /** @private */
12477 gtk.TextView.prototype._resizeWidth = function(width){
12478     this._domObj.style.width = width - 3 + 'px';
12479     this._width = width;
12480 };
12481 /** @private */
12482 gtk.TextView.prototype._resizeHeight = function(height){
12483     this._domObj.style.height = height - 4 + 'px';
12484     this._height = height;
12485 };
12486 /** @private */
12487 gtk.TextView.prototype.resizeWidthComposite = function(width){
12488     this.setWidth(width);
12489     this.resize(this._width, this._height);
12490 };
12491 /** @private */
12492 gtk.TextView.prototype.resizeHeightComposite = function(height){
12493     this.setHeight(height);
12494     this.resize(this._width, this._height);
12495 };
12496 gobject.signalNew("focused", gtk.TextView, null, null, []);
12497 gobject.signalNew("blurred", gtk.TextView, null, null, []);
12498 gobject.signalNew("enterkeypressed", gtk.TextView, null, null, []);
12499 /**
12500  * Dom is a class to create a text or an HTML container. It can contain any HTML string value.
12501  * @param {Integer} width The integer width value in pixel to be set
12502  * @param {Integer} height The integer height value in pixel to be set
12503  * @constructor
12504  * @base gtk.Widget
12505  */
12506 gtk.Dom = function(width, height) {
12507 	gtk.Widget.apply(this);
12508 
12509 	/** 'clicked' signal */
12510 	this.DOM_CLICKED = "clicked";
12511 	/** 'doubleclicked' signal */
12512 	this.DOM_DOUBLECLICKED = "doubleclicked";
12513 	/** 'mouseover' signal */
12514 	this.DOM_MOUSEOVER = "mouseover";
12515 	/** 'mouseup' signal */
12516 	this.DOM_MOUSEUP = "mouseup";
12517 	/** 'mouseout' signal */
12518 	this.DOM_MOUSEOUT = "mouseout";
12519 
12520 	this._attribute = null;
12521 
12522 	this._width  = this._minWidth  = this._initWidth	= width  || 16;
12523 	this._height = this._minHeight = this._initHeight	= height || 16;
12524 
12525 	this._dom = null;
12526 
12527 	this._render = function(){
12528 	    var domObj = this._domObj;
12529 		domObj.className   += " gtk_dom";
12530 	};
12531 
12532     this._render();
12533     this._initEvent();
12534 };
12535 
12536 gtk.Dom.prototype = new gtk.Widget();
12537 gtk.Dom.prototype.constructor = gtk.Dom;
12538 
12539 /**
12540 * Append the child widget to gtk.Dom
12541 * @param {gtk.Widget} dom The Dom object to be added
12542 */
12543 gtk.Dom.prototype.appendChild = function(dom){
12544     if(this._dom) this._domObj.replaceChild(dom, this._dom);
12545     else this._domObj.appendChild(dom);
12546 
12547     this._dom = dom;
12548 
12549     this._resetSize();
12550 };
12551 
12552 /**
12553  * Accept any HTML string
12554  * @param {String} value The HTML value to be set
12555  */
12556 gtk.Dom.prototype.setInnerHTML = function(value){
12557 	var newDom = jsgtk.Dom.create({'tag': 'div'});
12558 	newDom.innerHTML = value;
12559 	this.appendChild(newDom);
12560 };
12561 
12562 /**
12563  * Return HTML string
12564  * @return {String} The HTML string value inside the Dom
12565  * @type String
12566  */
12567 gtk.Dom.prototype.getValue = function(){
12568     return this._dom.innerHTML;
12569 };
12570 
12571 /** @private */
12572 gtk.Dom.prototype._resetSize = function(){
12573 	var size = this._getChildSize();
12574 	this._minWidth  = size[0];
12575 	this._minHeight = size[1];
12576 	this.resize(size[0], size[1]);
12577 };
12578 
12579 /** @private */
12580 gtk.Dom.prototype._initEvent = function(){
12581     var self = this;
12582     var jsgtkEvent = jsgtk.Event;
12583 
12584     jsgtkEvent.addDomListener(this._domObj, "click", function(e){
12585 		self.emit("clicked", self.getValue());
12586 	}, false);
12587 
12588 	jsgtkEvent.addDomListener(this._domObj, "dblclick", function(e){
12589 		self.emit("doubleclicked", self.getValue());
12590 	}, false);
12591 
12592 	jsgtkEvent.addDomListener(this._domObj, "mouseover", function(e){
12593 		self.emit("mouseover", self.getValue());
12594 	}, false);
12595 
12596 	jsgtkEvent.addDomListener(this._domObj, "mouseout", function(e){
12597 		self.emit("mouseout", self.getValue());
12598 	}, false);
12599 
12600 	jsgtkEvent.addDomListener(this._domObj, "mouseup", function(e){
12601 		self.emit("mouseup", self.getValue());
12602 	}, false);
12603 };
12604 
12605 /** @private */
12606 gtk.Dom.prototype.resize = function(width, height){
12607     this._resizeWidth(width);
12608     this._resizeHeight(height);
12609 };
12610 
12611 /** @private */
12612 gtk.Dom.prototype._resizeWidth = function(width){
12613 	this._width = width;
12614 	this._domObj.style.width = width + 'px';
12615 	this._dom.style.width = width + 'px';
12616 };
12617 
12618 /** @private */
12619 gtk.Dom.prototype._resizeHeight = function(height){
12620 	this._height = height;
12621 	this._domObj.style.height = height + 'px';
12622 	this._dom.style.height = height + "px";
12623 };
12624 
12625 /**
12626  * Set style or apply attribute
12627  * @param {Object} attribute A collection of object literal of styles
12628  */
12629 gtk.Dom.prototype.setAttribute = function(attribute){
12630 	this._attribute = attribute;
12631 	this._applyAttribute();
12632 };
12633 
12634 /** @private */
12635 gtk.Dom.prototype._applyAttribute = function(){
12636 	for(var el in this._attribute){
12637 	    this._domObj.style[el] = this._attribute[el];
12638 	}
12639 };
12640 
12641 /** @private */
12642 gtk.Dom.prototype._getChildSize = function(){
12643 	var jsgtkUtil = jsgtk.Util;
12644 	var tmpNode = this._dom.cloneNode(true);
12645 	tmpNode.style.width = this._width + "px";
12646 	var height   = jsgtkUtil.fullHeight(tmpNode) ? jsgtkUtil.fullHeight(tmpNode) : this._height;
12647 	return [this._width, height];
12648 };
12649 
12650 /** @private */
12651 gtk.Dom.prototype.resizeWidthComposite = function(width){
12652 	var minWidthComposite = this.getMinWidthComposite();
12653 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
12654 	this._resizeWidth(minWidth);
12655 };
12656 
12657 /** @private */
12658 gtk.Dom.prototype.resizeHeightComposite = function(height){
12659 	var minHeightComposite = this.getMinHeightComposite();
12660 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
12661 	this._resizeHeight(minHeight);
12662 };
12663 
12664 gobject.signalNew("clicked", gtk.Dom, null, null, []);
12665 gobject.signalNew("doubleclicked", gtk.Dom, null, null, []);
12666 gobject.signalNew("mouseover", gtk.Dom, null, null, []);
12667 gobject.signalNew("mouseup", gtk.Dom, null, null, []);
12668 gobject.signalNew("mouseout", gtk.Dom, null, null, []);
12669 /**
12670  * Contents is a class to create contents for NoteBook
12671  * @param {Integer} width The width of the widget to be set
12672  * @param {Integer} height The height of the widget
12673  * @constructor
12674  * @base gtk.Widget
12675  */
12676 gtk.Contents = function(width, height) {
12677 	gtk.Widget.apply(this);
12678 
12679 	this._width = width;
12680 	this._height = height;
12681 	this._children = [];
12682 	this._activeContent = null;
12683 	this._render = function(){
12684 		this._domObj.className += " gtk_contents";
12685 		this._domObj.style.width = this._width + 'px';
12686 		this._domObj.style.height = this._height + 'px';
12687 	};
12688 
12689 	this._render();
12690 };
12691 
12692 gtk.Contents.prototype = new gtk.Widget();
12693 gtk.Contents.prototype.constructor = gtk.Contents;
12694 
12695 /**
12696  * Method to hide border of widget
12697  */
12698 gtk.Contents.prototype.hideBorder = function(){
12699     this._domObj.style.border = "0px";
12700 };
12701 
12702 /**
12703  * Method to show border of widget
12704  */
12705 gtk.Contents.prototype.showBorder = function(){
12706     var domStyle = this._domObj.style;
12707     domStyle.borderBottom = "1px solid #EFC169";
12708     domStyle.borderLeft   = "1px solid #EFC169";
12709     domStyle.borderRight  = "1px solid #EFC169";
12710 };
12711 
12712 /**
12713  * Method to set activated as default
12714  */
12715 gtk.Contents.prototype.activateDefault = function(){
12716 	this._activeContent = this._children[0]["content"];
12717 	this._domObj.appendChild(this._activeContent.getNode());
12718 };
12719 
12720 /**
12721  * Method to set activated by index value
12722  * @param {Integer} index The index value to be set
12723  */
12724 gtk.Contents.prototype.activate = function(index){
12725 	var content = this._children[index]["content"];
12726 	this._domObj.innerHTML = "";
12727 	this._domObj.appendChild(content.getNode());
12728 	this._activeContent = content;
12729 	return content;
12730 };
12731 
12732 /**
12733  * Method to set activated by object value
12734  * @param {Object} content The object value to be passed
12735  */
12736 gtk.Contents.prototype.activateByObject = function(content){
12737     for(var i = 0, len = this._children.length; i < len; i++){
12738         if(this._children[i]["content"] === content) break;
12739     }
12740     this.activate(i);
12741 };
12742 
12743 /**
12744  * Method to set activated its content
12745  * @param {Integer} id The id value as integer
12746  */
12747 gtk.Contents.prototype.activateContent = function(id){
12748 	var content;
12749 	for(var i = 0, len = this._children.length; i < len; i++){
12750 		content = this._children[i]["content"];
12751 		if(id === this._children[i]["id"]) break;
12752 	}
12753 	this._domObj.innerHTML = "";
12754 	this._domObj.appendChild(content._domObj);
12755 	this._activeContent = content;
12756 	return content;
12757 };
12758 
12759 /**
12760  * Method to get/return active content
12761  * @return {Object} The active object value
12762  * @type Object
12763  */
12764 gtk.Contents.prototype.getActiveContent = function(){
12765     return this._activeContent;
12766 };
12767 
12768 /**
12769  * Method to update its content
12770  * @param {Object} content The object value of the content
12771  * @param {Integer} index The integer value of the content tab index
12772  */
12773 gtk.Contents.prototype.updateContent = function(content, index){
12774     this._children[index]["content"] = content;
12775     content.setParent(this);
12776 };
12777 
12778 /**
12779  * Method to add child object into its body
12780  * @param {Object} contentObj The object value of the content
12781  */
12782 gtk.Contents.prototype.addChild = function(contentObj){
12783     contentObj["padding"] = contentObj["padding"] === undefined || contentObj["padding"] === null ? 1 : contentObj["padding"];
12784     contentObj["content"].setParent(this);
12785 	this._children.push(contentObj);
12786 };
12787 
12788 /**
12789  * Method to insert an object value at a specific position
12790  * @param {Object} contentObj The object value of the content
12791  * @param {Integer} index The index value of the content tab
12792  */
12793 gtk.Contents.prototype.insertAt = function(contentObj, index){
12794 	this._children.splice(index, 0, contentObj);
12795 };
12796 
12797 /**
12798  * Method to remove child from it body given an index value
12799  * @param {Integer} index The index value to be set
12800  */
12801 gtk.Contents.prototype.removeChild = function(index){
12802     jsgtk.Util.removeArrayElements(this._children, index);
12803     this._domObj.removeChild(this._domObj.childNodes[0]);
12804 };
12805 
12806 /**
12807  * Method to get or return all children
12808  * @return {Object} The array objects of its contents or children
12809  * @type Object
12810  */
12811 gtk.Contents.prototype.getChildren = function(){
12812     return this._children;
12813 };
12814 
12815 /** @private */
12816 gtk.Contents.prototype._resizeChildrenHeight = function(height){
12817 
12818     for(var i = 0, len = this._children.length; i < len; i++){
12819         var childWiget = this._children[i]["content"];
12820         var padding    = this._children[i]["padding"];
12821         var childHeight = height - padding * 2;
12822         childWiget.resizeHeightComposite(childHeight);
12823         childWiget.getNode().style.top = padding + "px";
12824     }
12825 };
12826 
12827 /** @private */
12828 gtk.Contents.prototype._resizeChildrenWidthComposite = function(width){
12829     for(var i = this._children.length; i--;){
12830         var childWiget = this._children[i]["content"];
12831         var padding    = this._children[i]["padding"];
12832         var childWidth = width - padding * 2;
12833         childWiget.resizeWidthComposite(childWidth);
12834         childWiget.getNode().style.left = padding + "px";
12835     }
12836 };
12837 
12838 /**
12839  * Method to get/return minimum composite width
12840  * @return {Integer} The minimum composite width of the content
12841  * @type Integer
12842  */
12843 gtk.Contents.prototype.getMinWidthComposiste = function(){
12844 	var children = this._children;
12845 	var minWidth = this._minWidth;
12846 
12847 	for(var i = children.length; i--;){
12848 		var width = children[i]["content"].getMinWidthComposite() + children[i]["padding"] * 2;
12849 		if( width > minWidth & width != undefined ) minWidth = width;
12850 	}
12851 
12852 	this._minWidth = minWidth;
12853 	return this._minWidth;
12854 };
12855 
12856 /**
12857  * Method to get or return minimum composite height
12858  * @return {Integer} The minimum composite height of the content
12859  * @type Integer
12860  */
12861 gtk.Contents.prototype.getMinHeightComposite = function(){
12862 	var children = this._children;
12863 	var minHeight = this._minHeight;
12864 	for(var i = children.length; i--;){
12865 		var height = children[i]["content"].getMinHeightComposite() + children[i]["padding"] * 2;
12866 		if( height > minHeight & height != undefined ) minHeight = height;
12867 	}
12868 
12869 	this._minHeight = minHeight;
12870 	return this._minHeight;
12871 };
12872 
12873 /**
12874  * Method to resize width
12875  * @param {Integer} width The width to be passed
12876  */
12877 gtk.Contents.prototype.resizeWidthComposite = function(width){
12878 	var minWidthComposite = this.getMinWidthComposite();
12879 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
12880     this._resizeWidth(minWidth);
12881     this._resizeChildrenWidthComposite(minWidth);
12882 };
12883 
12884 /**
12885  * Method to resize height
12886  * @param {Integer} height The height to be passed
12887  */
12888 gtk.Contents.prototype.resizeHeightComposite = function(height){
12889 	var minHeightComposite = this.getMinHeightComposite();
12890 	var minHeight = height > minHeightComposite ? height : minHeightComposite;
12891 	this._resizeHeight(minHeight);
12892     this._resizeChildrenHeight(minHeight);
12893 };
12894 /**
12895  * Tabs is a class to create tab for NoteBook
12896  * @constructor
12897  * @param {Integer} width The width of the widget
12898  * @param {Integer} height The height of the widget
12899  * @param {Integer} vspaceWidth The vertical space
12900  * @base gtk.Widget
12901  * @see gtk.NoteBook
12902  * @see gtk.Contents
12903  */
12904 gtk.Tabs = function(width, height, vspaceWidth) {
12905 	gtk.Widget.apply(this);
12906 
12907 	this._children        = [];
12908 	this._width           = width;
12909 	this._height          = height;
12910 	this._vspaceWidth     = vspaceWidth;
12911 	this._activeTabDom    = null;
12912 	this._activeTab       = "";
12913 	this._border          = 2;
12914     this._loadingImgWidth = 16;
12915     this._tabs = [];
12916 	this._activeTabId 	  = null;
12917 
12918 	/** A registered signal name 'active' */
12919 	this.TABS_ACTIVE 	= "";
12920 
12921 	this._render = function(){
12922 		this._domObj.className   += " gtk_tabs";
12923 		this._domObj.style.width  = this._width + 'px';
12924 		this._domObj.style.height = this._height + 'px';
12925 	};
12926 
12927 	this._render();
12928 };
12929 
12930 gtk.Tabs.prototype = new gtk.Widget();
12931 gtk.Tabs.prototype.constructor = gtk.Tabs;
12932 
12933 /**
12934  * Method to show loading given tab object
12935  * @param {Object} tab The object value of the tab content
12936  */
12937 gtk.Tabs.prototype.showLoading = function(tab){
12938     var pageObj     = this._getPage(tab);
12939     var page        = tab.getNode().parentNode.parentNode;
12940     var loadingImg  = page.lastChild;
12941     var pageWrapper = page.firstChild;
12942 
12943     if(jsgtk.Dom.isShowed(loadingImg)) return;
12944 
12945     var extraWidth = this._loadingImgWidth > pageObj["padding"] / 2 ? this._loadingImgWidth : 0;
12946 
12947     var width = parseInt(page.style.width);
12948     page.style.width = width + extraWidth + "px";
12949     pageWrapper.style.width = width + extraWidth + "px";
12950 
12951     loadingImg.style.left = pageObj["padding"] / 2 + tab.getMinWidthComposite() + "px";
12952     jsgtk.Dom.showElement(loadingImg);
12953 };
12954 
12955 /**
12956  * Method to hide loading given tab object
12957  * @param {Object} tab The object value of the tab content
12958  */
12959 gtk.Tabs.prototype.hideLoading = function(tab){
12960     var pageObj     = this._getPage(tab);
12961     var page        = tab.getNode().parentNode.parentNode;
12962     var loadingImg  = page.lastChild;
12963     var pageWrapper = page.firstChild;
12964 
12965     if(!jsgtk.Dom.isShowed(loadingImg)) return;
12966 
12967     var extraWidth = this._loadingImgWidth > pageObj["padding"] / 2 ? this._loadingImgWidth : 0;
12968 
12969     var width = parseInt(page.style.width);
12970     page.style.width = width - extraWidth + "px";
12971     pageWrapper.style.width = width - extraWidth + "px";
12972 
12973     jsgtk.Dom.hideElement(loadingImg);
12974 };
12975 
12976 /**
12977  * Method to set activated as default
12978  */
12979 gtk.Tabs.prototype.activateDefault = function(){
12980     this.activate(0);
12981 };
12982 
12983 /** @private */
12984 gtk.Tabs.prototype._deactivateTab = function(){
12985     this._activeTabDom.className = "gtk_page";
12986     jsgtk.Dom.applyAttributes(this._activeTabDom.firstChild, {"borderBottom": "1px solid #D5D5D5"});
12987 };
12988 
12989 /** @private */
12990 gtk.Tabs.prototype._activeateTab = function(index){
12991     this._activeTabDom = this._children[index]["tab"]._domObj.parentNode.parentNode;
12992     this._activeTabDom.className = "tab_active";
12993     this._activeTab = this._children[index]["tab"];
12994     this._activeTabId = this._children[index]["id"];
12995     jsgtk.Dom.applyAttributes(this._activeTabDom.firstChild, {"borderBottom": "0px"});
12996 };
12997 
12998 /**
12999  * Method to set activated given an index value
13000  * @param {Integer} index The index value of the tab
13001  */
13002 gtk.Tabs.prototype.activate = function(index){
13003     if(this._activeTabDom) this._deactivateTab();
13004 	this._activeateTab(index);
13005 };
13006 
13007 /**
13008  * Method to set activated given an object value
13009  * @param {Object} label The object value
13010  */
13011 gtk.Tabs.prototype.activateByObject = function(label){
13012     for(var i = 0, len = this._children.length; i < len; i++){
13013         if(this._children[i]["tab"] === label) break;
13014     }
13015     this.activate(i);
13016 };
13017 
13018 /**
13019  * Method to get or return an index value
13020  * @return {Integer} tab The index value of the tab
13021  */
13022 gtk.Tabs.prototype.getIndex = function(tab){
13023     for(var i = 0, len = this._children.length; i < len; i++){
13024         if(this._children[i]["tab"] === tab) return i;
13025     }
13026 };
13027 
13028 /**
13029  * Method to add new tab given an object value
13030  * @param {Object} pageObj The object value
13031  */
13032 gtk.Tabs.prototype.addTab = function(pageObj){
13033     pageObj["padding"] = pageObj["padding"] || 0;
13034 	this._children.push(pageObj);
13035 	this._domObj.appendChild(this._createPage(pageObj));
13036 	this._domObj.appendChild(this._createVerticalSpace());
13037 };
13038 
13039 /**
13040  * Method to insert a tab in the specific value
13041  * @param {Object} pageObj The object value
13042  * @param {Integer} index The index value
13043  */
13044 gtk.Tabs.prototype.insertAt = function(pageObj, index){
13045 	this._children.splice(index, 0, pageObj);
13046     var domSibbling = this._domObj.childNodes[index * 2];
13047     var vspace = this._createVerticalSpace();
13048     this._domObj.insertBefore(vspace, domSibbling);
13049     this._domObj.insertBefore(this._createPage(pageObj), vspace);
13050 };
13051 
13052 /**
13053  * Method to remove tab from body given an index value
13054  * @param {Integer} index The index value to be removed
13055  */
13056 gtk.Tabs.prototype.removeTab = function(index){
13057     jsgtk.Util.removeArrayElements(this._children, index);
13058     var tabIndex = index * 2;
13059     this._domObj.removeChild(this._domObj.childNodes[tabIndex]);
13060     this._domObj.removeChild(this._domObj.childNodes[tabIndex]);
13061 };
13062 
13063 /** @private */
13064 gtk.Tabs.prototype._resizePage = function(pageObj, pageNode, wrapper){
13065 
13066 	var tabWidget = pageObj["tab"];
13067 	var size = tabWidget.getSize();
13068 
13069 	pageNode.style.width  = size[0] + this._border + pageObj["padding"] + 'px';
13070 	pageNode.style.height = size[1] + 12 + 'px';
13071 
13072     jsgtk.Util.detect.init();
13073     if(jsgtk.Util.detect.OS === "Windows") 	pageNode.style.top = 6 + 'px';
13074     else pageNode.style.top = 5 + 'px';
13075 
13076 		wrapper.style.width = size[0] + this._border + pageObj["padding"] + 'px';
13077 		wrapper.style.height = size[1] + 11 + 'px';
13078 
13079 		    var labelNode = tabWidget.getNode();
13080 		    labelNode.style.left = pageObj["padding"] / 2 + "px";
13081 }
13082 
13083 /** @private */
13084 gtk.Tabs.prototype._createPage = function(pageObj){
13085 	var pageNode = jsgtk.Dom.create({'tag': 'div', 'class': 'gtk_page','tabindex':this._tabindex});
13086 	    this._tabs.push(pageNode)
13087 		var wrapperNode = jsgtk.Dom.create({'append': pageNode, 'tag': 'div', 'class': 'gtk_tabs_wrapper'});
13088 	    wrapperNode.appendChild(pageObj["tab"].getNode());
13089 
13090 	    var loadingImg = jsgtk.Dom.create({'append': pageNode, 'tag': 'div', 'class': 'gtk_page_loading_img'});
13091         jsgtk.Dom.hideElement(loadingImg);
13092 
13093     this._resizePage(pageObj, pageNode, wrapperNode);
13094     this._tabindex++;
13095     this._initPageEvents(pageNode, pageObj);
13096 	return pageNode;
13097 };
13098 
13099 /** @private */
13100 gtk.Tabs.prototype._initPageEvents = function(page, pageObj){
13101     var self = this;
13102     jsgtk.Event.addDomListener(page, 'mousedown', function(e){
13103         if(self._activeTabDom === page) return;
13104 
13105 	    if(self._activeTabDom) self._deactivateTab();
13106 
13107 	    self._activeateTab(self.getIndex(pageObj["tab"]));
13108 
13109 		self.emit('active', pageObj["id"]);
13110 	});
13111 
13112 };
13113 
13114 /** @private */
13115 gtk.Tabs.prototype._setFocus = function(tab){
13116     tab.className +=" gtk_label_focus";
13117 };
13118 
13119 /** @private */
13120 gtk.Tabs.prototype._unFocus = function(tab){
13121     tab.className +="gtk_widget gtk_label";
13122 };
13123 
13124 /** @private */
13125 gtk.Tabs.prototype._createVerticalSpace = function(){
13126 	var vspace = jsgtk.Dom.create({'tag': 'div', 'class': 'gtk_vspace'});
13127 	vspace.style.width = this._vspaceWidth + "px";
13128 	vspace.style.height = "100%";
13129 	return vspace;
13130 };
13131 
13132 /**
13133  * Method to get or return the active tab
13134  * @return {Object} The active object value
13135  * @type Object
13136  */
13137 gtk.Tabs.prototype.getActiveTab = function(){
13138     return this._activeTab;
13139 };
13140 
13141 /**
13142  * Method to get/return the active tab
13143  * @return {Integer} The index value
13144  * @type Integer
13145  */
13146 gtk.Tabs.prototype.getActiveTabId = function(){
13147 	return this._activeTabId;
13148 }
13149 
13150 /**
13151  * Method to get/return all children belong to the class
13152  * @return {Object} The array of objects
13153  * @type Object
13154  */
13155 gtk.Tabs.prototype.getChildren = function(){
13156     return this._children;
13157 };
13158 
13159 /** @private */
13160 gtk.Tabs.prototype._getPage = function(tab){
13161     for(var i = 0, len = this._children.length; i < len; i++){
13162         if(this._children[i]["tab"] === tab) return this._children[i];
13163     }
13164 };
13165 
13166 /**
13167  * Method to resize width
13168  * @return {Integer} The width to be passed
13169  */
13170 gtk.Tabs.prototype.getMinWidthComposite = function(){
13171 	var tabs = this._children;
13172 	if(tabs.length > 0){
13173 		var minWidth = 0;
13174 		for(var i = tabs.length; i--;){
13175 			minWidth += tabs[i]["tab"].getMinWidthComposite() + this._border + tabs[i]["padding"];
13176 		}
13177 		var extraWidth = this._children.length * (this._border + this._vspaceWidth) ;
13178 		this._minWidth = minWidth + extraWidth;
13179 		return this._minWidth;
13180 	}
13181 };
13182 
13183 /**
13184  * Method to resize width
13185  * @param {Integer} The width to be passed
13186  */
13187 gtk.Tabs.prototype.resizeWidthComposite = function(width){
13188 	var minWidthComposite = this.getMinWidthComposite();
13189 	var minWidth = width > minWidthComposite ? width : minWidthComposite;
13190 
13191 	this._resizeWidth(minWidth);
13192 };
13193 
13194 gobject.signalNew('active', gtk.Tabs, [], null, null);
13195 /**
13196  * Menu is a class to create a list of menu items
13197  * @base gtk.Widget
13198  * @constructor
13199  * @see gtk.MenuItem
13200  */
13201 gtk.Menu = function() {
13202 	gtk.Widget.apply(this);
13203     var self = this;
13204 	this._menuItems        = [];
13205 	this._separatorDoms     = [];
13206 	this._minWidth         = 20;
13207 	this._minHeight        = 20;
13208 	this._menuItemActive   = false;
13209 	this._menuItemDeactive = true;
13210 	this._isActive         = false;
13211 	this._width            = this._minWidth;
13212 	this._height           = this._minHeight;
13213 	this._selectedItem     = null;
13214 	this._cellHeight       = 22;
13215 	this._zIndex           = 9000;
13216 	this._index            = -1;
13217 	this._currentHilighted = null;
13218 
13219 	/** A registered signal name 'menuselected' */
13220 	this.MENU_MENUSELECTED		= "";
13221 	/** A registered signal name 'menudeactivated' */
13222 	this.MENU_MENUDEACTIVATED	= "";
13223 	/** A registered signal name 'menuactivated' */
13224 	this.MENU_MENUACTIVATED		= "";
13225 
13226 	this._render = function(){
13227 		this._domObj.className += " gtk_menu_shell";
13228 		    this._hiddenEntry = jsgtk.Dom.create({"append": this._domObj, "tag": "input", "type": "text", "class": "gtk_menu_shell_hidden_textbox"});
13229 		this._domObj.style.width = this._width + 'px';
13230 		this._domObj.style.height = this._height + 'px';
13231 		this._domObj.style.zIndex = this._zIndex;
13232 		this._domObj.style.position = "absolute";
13233 		this.hide();
13234 	};
13235 
13236 	this._render();
13237 
13238 	jsgtk.Event.addDomListener(this._hiddenEntry, "keyup", function(e){
13239 	    var topIndex = self._menuItems.length - 1;
13240 
13241 	    if(e.keyCode === 13){
13242 	        var item = self._menuItems[self._index];
13243 	        if(!item.getSubMenu())item.activateItem(item.getText());
13244 	    }
13245 
13246         if(e.keyCode === 40){
13247             if(self._index === topIndex) self._index = -1;
13248             self._index++;
13249             self._hilightCell(self._index);
13250             return;
13251         }
13252 
13253         if(e.keyCode === 38){
13254             if(self._index <= 0) self._index = topIndex + 1;
13255             self._index--;
13256             self._hilightCell(self._index);
13257             return;
13258         }
13259 
13260         if(e.keyCode === 37 || e.keyCode === 39){
13261             var item = self._menuItems[self._index];
13262             if(item === undefined) return;
13263             if(!item.getSubMenu()){
13264                 self.emit("menudeactivated");
13265                 return;
13266             }
13267             item.showSubMenu();
13268         }
13269 
13270         jsgtk.Event.stopBubble(e);
13271 	});
13272 };
13273 
13274 gtk.Menu.prototype = new gtk.Widget();
13275 gtk.Menu.prototype.constructor = gtk.Menu;
13276 
13277 /**
13278  * A method to add or append a menu item
13279  * @param {Dom} menuItem The Dom object of the menu item to be set
13280  */
13281 gtk.Menu.prototype.append = function(menuItem){
13282 	var self = this;
13283 	var domItem = menuItem.getNode();
13284 	var separatorMargin = 0;
13285 	this._domObj.appendChild(domItem);
13286 
13287 	this._menuItems.push(menuItem);
13288 	this._minWidth  = this._getMaxChildWidth();
13289 
13290 	if(this._separatorDoms.length > 0){
13291 		separatorMargin = (3 * this._separatorDoms.length) ;
13292 	}
13293 
13294 	this._minHeight = (this._cellHeight * this._menuItems.length) + separatorMargin;
13295 
13296 	this.resize(this._minWidth, this._minHeight);
13297 
13298 	menuItem.connect("menumouseover", function(item){
13299         self._hideSubMenu(menuItem);
13300         self._index = self._getIndex(item);
13301         self._hilightCell(self._index);
13302         self._hiddenEntry.focus();
13303 	});
13304 
13305 	menuItem.connect("menuactivated", function(){
13306 	    self.show();
13307 	    self._hiddenEntry.focus();
13308 	});
13309 
13310 	menuItem.connect("menuselected", function(text){
13311 	    self.emit("menuselected", text);
13312 	    self._isActive = false;
13313 	    self.hideMenuComposite();
13314 	});
13315 };
13316 
13317 /** @private */
13318 gtk.Menu.prototype._hilightCell = function(index){
13319     if(this._currentHilighted) jsgtk.Dom.applyAttributes(this._currentHilighted, {"backgroundColor": ""});
13320     this._currentHilighted = this._menuItems[index].getNode();
13321     jsgtk.Dom.applyAttributes(this._currentHilighted, {"backgroundColor": "#FFDD00"});
13322 };
13323 
13324 /** @private */
13325 gtk.Menu.prototype._getIndex = function(item){
13326     for(var i = 0, len = this._menuItems.length; i < len; i++){
13327         if(this._menuItems[i] === item) return i;
13328     }
13329 };
13330 
13331 /**
13332  * A method to set selected on any menu item
13333  * @param {Dom} menuItem The Dom object of the menu item to be set
13334  */
13335 gtk.Menu.prototype.selectItem = function(menuItem){
13336 	for (var i = 0; i < this._menuItems.length; i++){
13337 			if(this._menuItems[i] === menuItem) this._index = i;
13338 	}
13339 	this._hilightCell(this._index);
13340 };
13341 
13342 /**
13343  * A method to hide or deactivate the menu
13344  */
13345 gtk.Menu.prototype.deactivate = function(){
13346 	this.hide();
13347 };
13348 
13349 /**
13350  * A method to add a separator amongst each menu items
13351  */
13352 gtk.Menu.prototype.addSeparator = function(){
13353 	var separator = jsgtk.Dom.create({'append':this._domObj, 'tag' : 'div'});
13354 	separator.className += ' separator';
13355 	this._separatorDoms.push(separator);
13356 };
13357 
13358 /** @private */
13359 gtk.Menu.prototype._getMaxChildWidth = function(){
13360 	var maxWidth = 0;
13361 	for(var i = this._menuItems.length; i--;){
13362 	    var itemWidth = this._menuItems[i].getMinWidthComposite();
13363 		if(itemWidth > maxWidth) maxWidth = itemWidth;
13364 	}
13365 	return maxWidth;
13366 };
13367 
13368 /** @private */
13369 gtk.Menu.prototype.resize = function(width,height){
13370 	this._resizeWidth(width);
13371     this._resizeHeight(height);
13372 
13373     for(var i = this._menuItems.length; i--;){
13374         var item = this._menuItems[i];
13375         item.resizeWidthComposite(width);
13376     }
13377 };
13378 
13379 /** @private */
13380 gtk.Menu.prototype._hideSubMenu = function(menuItem){
13381     var subMenu;
13382     for(var i = 0, len = this._menuItems.length; i < len; i++){
13383         var item = this._menuItems[i];
13384         if(item !== menuItem){
13385             subMenu = item.getSubMenu();
13386             if(subMenu) subMenu.hideMenuComposite();
13387         }
13388     }
13389 };
13390 
13391 /**
13392  * A method to hide the menu item
13393  */
13394 gtk.Menu.prototype.hideMenuComposite = function(){
13395     var subMenu;
13396     this.hide();
13397     for(var i = this._menuItems.length; i--;){
13398         var item = this._menuItems[i];
13399         subMenu = item.getSubMenu();
13400         if(subMenu) subMenu.hideMenuComposite();
13401     }
13402 };
13403 
13404 /**
13405  * A method to show menu item
13406  */
13407 gtk.Menu.prototype.showMenuComposite = function(){
13408     var subMenu;
13409     this.show();
13410     for(var i = this._menuItems.length; i--;){
13411         var item = this._menuItems[i];
13412         subMenu = item.getSubMenu();
13413         if(subMenu) subMenu.showMenuComposite();
13414     }
13415 };
13416 
13417 /**
13418  * A method to set anchor of the menu
13419  * @param {Integer} x The x-axis value
13420  * @param {Integer} y The y-axis value
13421  * @param {Integer} index The index value of the menu item
13422  */
13423 gtk.Menu.prototype.anchorTo = function(x, y, index){
13424     if(!this._isActive){
13425         this.show();
13426         this._hiddenEntry.focus();
13427 
13428         index = index || 0;
13429         this.show();
13430         var left,top;
13431 
13432         this._zIndex += index;
13433         this._domObj.style.zIndex = this._zIndex;
13434 
13435         var windowWidth = jsgtk.Util.getWindowWidth();
13436         var newX = windowWidth - x;
13437 
13438         if(this._width > newX) left = x - this._width;
13439         else left = x;
13440 
13441         var windowHeight = jsgtk.Util.getWindowHeight();
13442         var newY = windowHeight - y;
13443 
13444         if(this._height > newY) top = y - this._height;
13445         else top = y;
13446 
13447         this._domObj.style.top = top + "px";
13448         this._domObj.style.left = left + "px";
13449 
13450         this._isActive = true;
13451     }else{
13452         this.hideMenuComposite();
13453         this._isActive = false;
13454     }
13455 };
13456 
13457 /**
13458  * A method to resize its composite width
13459  * @param {Integer} width The integer width value to be set
13460  */
13461 gtk.Menu.prototype.resizeWidthComposite = function(width){
13462     var minWidth = this._minWidth < width ? width : this._minWidth;
13463     this.resize(minWidth, this._height);
13464 };
13465 
13466 /**
13467  * A method to resize its composite height
13468  * @param {Integer} height The integer height value to be set
13469  */
13470 gtk.Menu.prototype.resizeHeightComposite = function(height){
13471     var minHeight = this._minHeight < height ? height : this._minHeight;
13472     this.resize(this._width, minHeight);
13473 };
13474 
13475 gobject.signalNew("menuactivated", gtk.Menu, null, null, []);
13476 gobject.signalNew("menudeactivated", gtk.Menu, null, null, []);
13477 gobject.signalNew("menuselected", gtk.Menu, null, null, []);
13478 /**
13479  * MenuItem is a class to create a menu item
13480  * @param {gtk.Image} img The gtk.Image object to be set
13481  * @param {String} text The string text of the menu item
13482  * @base gtk.Item
13483  * @constructor
13484  * @see gtk.Menu
13485  */
13486 gtk.MenuItem = function(img, text){
13487 	gtk.Item.apply(this);
13488     var self = this;
13489     this._width            = this._minWidth  = 50;
13490     this._height           = this._minHeight = 22;
13491     this._imageWidgetWidth = 16;
13492 	this._imageWidget      = img || null;
13493     this._labelWidget      = new gtk.Label( text || "Item");
13494     this._labelWidget.show();
13495 
13496 	this._toggle           = false;
13497 	this._domMenuItemLabel = null;
13498 	this._isSubMenu        = false;
13499 	this._subMenu          = null;
13500 	this._callBack		   = function(){};
13501 	this._leftPadding      = 5;
13502 	this._rightPadding     = 10;
13503 	this._labelPadding     = 5;
13504 
13505 	/** A registered signal name 'menuselected' */
13506 	this.MENUITEM_MENUSELECTED	= "";
13507 	/** A registered signal name 'menumouseover' */
13508 	this.MENUITEM_MENUMOUSEOVER		= "";
13509 	/** A registered signal name 'menuactivated' */
13510 	this.MENUITEM_MENUACTIVATED		= "";
13511 
13512 	this._render = function(){
13513 		this._domObj.className += ' menu_item';
13514 		this._domObj.style.width = this._width + "px";
13515 		this._domObj.style.height = this._height + "px";
13516 
13517 		this._appendChildren();
13518 	};
13519 
13520 	this._render();
13521 
13522 	jsgtk.Event.addDomListener(this._domObj,'mouseover',function(e){
13523 	    self.emit("menumouseover", self);
13524 	    jsgtk.Event.stopBubble(e);
13525 	    if(self._subMenu){
13526 	        self._subMenu.show();
13527 			var position = self._getSubMenuPosition(this, self._subMenu);
13528 		    self._subMenu.anchorTo(position[0]-3, position[1]-3, 1);
13529 	    }
13530 	}, false);
13531 
13532 	jsgtk.Event.addDomListener(this._domObj, 'click', function(e){
13533 	    if(!self._subMenu) self.activateItem(self._labelWidget.getText());
13534 		jsgtk.Event.stopBubble(e);
13535 	}, false);
13536 };
13537 
13538 gtk.MenuItem.prototype = new gtk.Item();
13539 gtk.MenuItem.prototype.constructor = gtk.MenuItem;
13540 
13541 /**
13542  * A method to display the sub menu
13543  */
13544 gtk.MenuItem.prototype.showSubMenu = function(){
13545     if(this._subMenu){
13546         this._subMenu.show();
13547 		var position = this._getSubMenuPosition(this._domObj, this._subMenu);
13548 	    this._subMenu.anchorTo(position[0]-3, position[1]-3, 1);
13549     }
13550 };
13551 
13552 /** @private */
13553 gtk.MenuItem.prototype._getSubMenuPosition = function(dom, subMenu){
13554     var parentNode = dom.parentNode;
13555     var menuItems = parentNode.childNodes;
13556 
13557     var left = ( parseInt(parentNode.style.left) || 0) + parseInt(dom.style.width) + 6;
13558     var windowWidth = jsgtk.Util.getWindowWidth();
13559     var subMenuWidth = subMenu.getMinWidthComposite();
13560     var newLeft = windowWidth - left;
13561 	if(newLeft < subMenuWidth){
13562         left = (parseInt(parentNode.style.left) || 0) - subMenuWidth;
13563     }
13564 
13565     var height = 0;
13566     for(var i = 0; i < menuItems.length; i++){
13567         if(this._domObj === menuItems[i]){
13568             break;
13569         }
13570         height += parseInt(menuItems[i].style.height) ? parseInt(menuItems[i].style.height) : 0;
13571     }
13572     var parentTop  = parseInt(parentNode.style.top);
13573     var windowHeight = jsgtk.Util.getWindowHeight();
13574     var subMenuHeight = subMenu.getMinHeightComposite();
13575     var top = height + parentTop;
13576     var newTop = windowHeight - top;
13577 	if(newTop < subMenuHeight){
13578 		top = (windowHeight || 0) - subMenuHeight;
13579 	}
13580 
13581 	return [left, top];
13582 };
13583 
13584 /** @private */
13585 gtk.MenuItem.prototype._appendChildren = function(){
13586     var width = this._labelWidget.getMinWidthComposite() + this._imageWidgetWidth + this._leftPadding + this._rightPadding + this._labelPadding;
13587     this._minWidth = width > this._minWidth ? width : this._minWidth;
13588     this.resize(this._minWidth, this._minHeight);
13589 
13590     if(this._imageWidget) {
13591         var imageNode = this._imageWidget.getNode();
13592         imageNode.style.left = this._leftPadding + "px";
13593         imageNode.style.top  = "2px";
13594         this._domObj.appendChild(imageNode);
13595     }
13596 
13597     var labelNode = this._labelWidget.getNode();
13598     this._domObj.appendChild(labelNode);
13599     labelNode.style.position = "absolute";
13600     labelNode.style.left = this._leftPadding + this._imageWidgetWidth + this._labelPadding + "px";
13601     labelNode.style.top  = "1px";
13602 };
13603 
13604 /**
13605  * A method to set the menu as sub menu
13606  * @param {Dom} menu The Dom object to be set
13607  */
13608 gtk.MenuItem.prototype.setSubMenu = function(menu){
13609 	var self = this;
13610 	this._isSubMenu = true;
13611 	this._subMenu = menu;
13612 
13613 	this._subMenu.getNode().className += ' sub_menu';
13614 	document.body.appendChild(this._subMenu.getNode());
13615 
13616 	this._imageSubMenu = jsgtk.Dom.create({'append' : this._domObj, 'tag' : 'img', 'src' : '../../src/images/test/toSubmenu.png'});
13617 	this._imageSubMenu.className = 'image_sub_menu';
13618 	this._imageSubMenu.style.left = parseInt(this._domObj.style.width) - 10 + "px";
13619 
13620 	this._subMenu.connect("menudeactivated", function(){
13621         self.emit("menuactivated");
13622         self._subMenu.hide();
13623 	});
13624 
13625 	this._subMenu.connect("menuselected", function(text){
13626     	self.activateItem(text);
13627 	});
13628 };
13629 
13630 /** @private */
13631 gtk.MenuItem.prototype._setSubMenuImage = function(imagePath){
13632 	this._imageSubMenu.src = imagePath;
13633 };
13634 
13635 /**
13636  * A method to get or return menu text
13637  * @return {String} The string text of the menu item
13638  * @type String
13639  */
13640 gtk.MenuItem.prototype.getText = function(){
13641     return this._labelWidget.getText();
13642 };
13643 
13644 /**
13645  * A method to get or return the string text of sub menu
13646  * @return {String} The string text of the sub menu item
13647  * @type String
13648  */
13649 gtk.MenuItem.prototype.getSubMenu = function(){
13650     return this._subMenu;
13651 };
13652 
13653 /** @private */
13654 gtk.MenuItem.prototype.resize = function(width, height){
13655 	this._resizeWidth(width);
13656 	this._resizeHeight(height);
13657 };
13658 
13659 /** @private */
13660 gtk.MenuItem.prototype.removeSubMenu = function(){
13661 	document.body.removeChild(this._subMenu.getNode());
13662 	this._domObj.removeChild(this._imageSubMenu);
13663 	this._subMenu = null;
13664 };
13665 
13666 /** @private */
13667 gtk.MenuItem.prototype.activateItem = function(text){
13668     this.emit("menuselected", text);
13669 };
13670 
13671 /**
13672  * A method to resize width composite of the menu
13673  * @param {Integer} width The width composite of the menu
13674  */
13675 gtk.MenuItem.prototype.resizeWidthComposite = function(width){
13676     var minWidth = width > this._minWidth ? width : this._minWidth;
13677     this.resize(minWidth, this._height);
13678 };
13679 
13680 gobject.signalNew("menumouseover", gtk.MenuItem, null, null, []);
13681 gobject.signalNew("menuselected", gtk.MenuItem, null, null, []);
13682 gobject.signalNew("menuactivated", gtk.MenuItem, null, null, []);
13683 /**
13684  * Item is an assistant class to create menu item
13685  * @constructor
13686  * @base gtk.Widget
13687  * @see gtk.Menu
13688  * @see gtk.MenuItem
13689  */
13690 gtk.Item = function(){
13691 	gtk.Widget.apply(this);
13692 	var self = this;
13693 	this._toggle = false;
13694 
13695 	/** A registered signal name 'selected' */
13696 	this.ITEM_SELECTED 		= "";
13697 	/** A registered signal name 'deselected' */
13698 	this.ITEM_DESELECTED	= "";
13699 	/** A registered signal name 'toggled' */
13700 	this.ITEM_TOGGLED		= "";
13701 
13702 	this._render = function(){
13703 		this._domObj.className += ' item';
13704 	};
13705 
13706 	this._render();
13707 };
13708 
13709 gtk.Item.prototype = new gtk.Widget();
13710 gtk.Item.prototype.constructor = gtk.Item;
13711 
13712 /**
13713  * A method to set menu selected
13714  */
13715 gtk.Item.prototype.select = function(){
13716 	this.emit('selected');
13717 };
13718 
13719 /**
13720  * A method to set menu deselected
13721  */
13722 gtk.Item.prototype.deselect = function(){
13723 	this.emit('deselected');
13724 };
13725 
13726 /**
13727  * A method to set toggled of the menu
13728  */
13729 gtk.Item.prototype.toggle = function(){
13730 	this.emit('toggled');
13731 	if(this._toggle) this._toggle = false;
13732 	else this._toggle = true;
13733 };
13734 
13735 gobject.signalNew('selected', gtk.Button, null, null, []);
13736 gobject.signalNew('deselected', gtk.Button, null, null, []);
13737 gobject.signalNew('toggled', gtk.Button, null, null, []);
13738 
13739 /**
13740  * TreeStore is a helper or model or subordinate class used to create a model for other class applying in
13741  * MVC (Model View Controller) and MVP (Model View Presenter) as development concept.
13742  * @constructor
13743  */
13744 gtk.TreeStore = function(header){
13745  	gtk.Object.apply(this);
13746 
13747 	this._modelType = gtk.TREESTORE;
13748 	this._header = header || "Header";
13749  	this.children = [];
13750 };
13751 
13752 gtk.TreeStore.prototype = new gtk.Object();
13753 gtk.TreeStore.prototype.constructor = gtk.TreeStore;
13754 
13755 /**
13756  * Method to append a new row to the liststore
13757  * @param {Object} parent An object instantiated from gtk.TreeIter
13758  * @param {Object} row A tuple or list containing ordered column values to be set in the new row
13759  * @return {object} A gtk.TreeIter pointing to the new row
13760  * @type Object
13761  */
13762 gtk.TreeStore.prototype.append = function(parent, row){
13763 	if(parent){
13764 		var path = parent.getPath() + parent.getChildren().length.toString() + ':';
13765 		var iter = new gtk.TreeIter(path);
13766 		iter.setRow(row);
13767 		iter.hasNode = row["hasChild"] || false;
13768 		parent.add(iter);
13769 		parent.hasNode = true;
13770 	}else{
13771 		var iter = new gtk.TreeIter(this.children.length.toString() + ':');
13772 		iter.setRow(row);
13773 		iter.hasNode = row["hasChild"] || false;
13774 		this.add(iter);
13775 	}
13776 	return iter;
13777 };
13778 
13779 /**
13780  * Method to append a new node
13781  * @param {Object} parent An object instantiated from gtk.TreeIter
13782  * @param {Object} row A tuple or list containing ordered column values to be set in the new row
13783  * @return {Object} All children models
13784  * @type Object
13785  */
13786 gtk.TreeStore.prototype.appendNodes = function(parent, rows){
13787     if(rows.length === 0) return;
13788     var childrenModel = [];
13789     for(var i = 0, len = rows.length; i < len; i++){
13790         childrenModel.push(this.append(parent, rows[i]));
13791     }
13792     this.emit("nodesappended", parent);
13793     return childrenModel;
13794 };
13795 
13796 /**
13797  * Method to get a model type or name
13798  * @return {String} A type of model name
13799  * @type String
13800  */
13801 gtk.TreeStore.prototype.getModelType = function(){
13802 	return this._modelType;
13803 };
13804 
13805 /**
13806  * Method to get a child given its value member
13807  * @param {String} valueMember A name of its valued member
13808  * @param {String} value A value to be set
13809  * @return {Object} A model of the child
13810  * @type Object
13811  */
13812 gtk.TreeStore.prototype.getChldBy = function(valueMember, value){
13813 	for(var i = this.children.length; i--;){
13814 		var childModel = this.children[i].getChldBy(valueMember, value);
13815 		if(childModel) return childModel;
13816 	}
13817 };
13818 
13819 /**
13820  * Method to get a child given its index value
13821  * @param {Integer} index An index value to be passed
13822  * @return {Object} An object of a child
13823  * @type Object
13824  */
13825 gtk.TreeStore.prototype.getChildByIndex = function(index){
13826 	if(index < 0 || index > this.children.length) return null;
13827 	return this.children[index];
13828 };
13829 
13830 /**
13831  * Method to get a child given its path value
13832  * @param {String} path A path value to be looked for
13833  * @return {Object} An object of a child
13834  * @type Object
13835  */
13836 gtk.TreeStore.prototype.getChildByPath = function(path){
13837     var paths = path.split(":");
13838     var child = this._getChildByPath( parseInt(paths[0]) );
13839 
13840     paths.splice(0,1);
13841     if(paths.length === 1) return child;
13842 
13843     return child.getChildByPath(paths.join(":"));
13844 };
13845 
13846 /** @private */
13847 gtk.TreeStore.prototype._getChildByPath = function(path){
13848 	for(var i = this.children.length; i--;){
13849 		var childPath = this.children[i].path.split(":");
13850 		if(parseInt(childPath[0]) === path) return this.children[i];
13851 	}
13852 	return null;
13853 };
13854 
13855 /**
13856  * Method to get all children
13857  * @return {Array} An array of objects of a children
13858  * @type Array
13859  */
13860 gtk.TreeStore.prototype.getChildren = function(){
13861 	return this.children;
13862 };
13863 
13864 /**
13865  * Method to push or append a child to be the last child in an array
13866  * @param {Object} childModel The object of a child to be passed
13867  */
13868 gtk.TreeStore.prototype.add = function(child){
13869 	this.children.push(child);
13870 };
13871 
13872 /** @private */
13873 gtk.TreeStore.prototype._searchByValueMember = function(valueMember, value, children){
13874 	var child;
13875 
13876 	var children = children || this.children;
13877 	for(var i = 0, len = children.length; i < len; i++){
13878 		child = children[i];
13879 		if(child._value[valueMember] === value){
13880 			return child;
13881 		}
13882 	}
13883 
13884 	for(var i = 0, len = children.length; i < len; i++){
13885 		child = children[i];
13886 		if(child.hasNode) {
13887 			child = this._searchByValueMember(valueMember, value, child.getChildren());
13888 			if(child) return child;
13889 		}
13890 	}
13891 };
13892 
13893 /**
13894  * Method to search and filter child/children
13895  * @param {String} value The object of a child to be passed
13896  * @return {Object} A found object from all children
13897  * @type Object
13898  */
13899 gtk.TreeStore.prototype.filter = function(value){
13900     if(value.length === 0) return null;
13901 
13902     var matchedChildren = [];
13903     var re = new RegExp("^" + value.toLowerCase());
13904     for(var i = 0, len = this.children.length; i < len; i++){
13905     	var child = this.children[i];
13906     	result = child.getValue()["display"].toLowerCase().match(re);
13907     	if(result) matchedChildren.push(child);
13908     }
13909     return matchedChildren;
13910 };
13911 
13912 /**
13913  * Method to remove or delete a child from the list of children
13914  * @param {Object} child The object of a child to be removed
13915  */
13916 gtk.TreeStore.prototype.remove = function(child){
13917 	for(var i = 0, len = this.children.length; i < len; i++){
13918 		if(this.children[i] === child){
13919 			this.children.splice(i, 1);
13920 			break;
13921 		}
13922 	}
13923 };
13924 
13925 /**
13926  * Method to get a child given an index value
13927  * @param {Integer} index The integer value as an index of the to-be-wanted child
13928  * @return {Object} The object of the child to be returned
13929  * @type Object
13930  */
13931 gtk.TreeStore.prototype.getChild = function(index){
13932 	return this.children[index] || null;
13933 };
13934 
13935 /**
13936  * Method to search through all children given text and all children
13937  * @param {String} text The string value to be wanted to search for
13938  * @param {Array} children The array of children objects
13939  * @return {Object} The object of the found child
13940  * @type Object
13941  */
13942 gtk.TreeStore.prototype.search = function(text, children){
13943     var re = new RegExp("^" + text.toLowerCase());
13944     var children = children || this.children;
13945     var result = "";
13946 
13947     for(var i = 0, len = children.length; i < len; i++){
13948     	var child = children[i];
13949 		result = child._search(text);
13950 		if(result) return result;
13951     }
13952 };
13953 
13954 gobject.signalNew('nodesappended', gtk.TreeStore, [], null, null);
13955