Source: api/FloatingContainer.js

Retour à la documentation
define(["dojo/_base/declare","dijit/_WidgetBase", "dojo/dom-construct",
        "dojo/dom-style", "dijit/layout/ContentPane", "dijit/layout/AccordionContainer",
        "dojo/query", "dojo/on", "dojo/_base/lang", "dojo/dom-class"],
		function(declare, _WidgetBase, domConstruct, domStyle, ContentPane, Accordion,
				query, on, lang, domClass){
	
	return declare("spw.api.FloatingContainer", [_WidgetBase], /** @lends spw.api.FloatingContainer.prototype */{
		
		open:false,
		width:300,
		height: 300,
		minWidth:200,
		minHeight: 200,
		pinned: false,
		pinnable: true,
		unpinnedCloseTimeout: 2000,
		zone:"right",
		toggler: null,
		slideDuration: '0.5s',
		position: null,
		activateOnOpen: false,
		resizable: true,
		
		_toggler: null,
		
		content: null,
		containerTitle: null,
		
		_resizeActive: false,
		
        /**
         * @constructs
         * @param config
         */
		constructor: function (config) {
		},
		
		postMixInProperties: function (config) {
			this.inherited(arguments);
			
			var o = null;
			switch (this.zone){
			case 'right': o = { left: '-20px', top: '48%', borderWidth: '2px 0 2px 2px', borderRadius: '11px 0 0 11px', padding: '5px' }; break;
			case 'left': o = { right: '-20px', top: '48%', borderWidth: '2px 2px 2px 0', borderRadius: '0 11px 11px 0', padding: '5px' }; break;
			case 'top': o = { left: '48%', bottom: '-20px', borderWidth: '0px 2px 2px 2px', borderRadius: '0px 0px 11px 11px', padding: '0 10px' }; break;
			case 'bottom': o = { left: '48%', top: '-20px', borderWidth: '2px 2px 0px 2px', borderRadius: '11px 11px 0 0', padding: '0 10px' }; break;
			}
			lang.mixin(this._toggler = {}, o);
			lang.mixin(this._toggler, this.toggler);
			
			if(!this.position){
				this.position = {};
			}
		},
		
		_setPositionStyle: function() {
			domClass.add(this.domNode, 'floatingContainer');

			var pos = {};
			switch(this.zone){
			case 'left': lang.mixin(pos, {
					top: '25px',
					bottom: '25px',
					width: this.width + 'px',
					transition: 'left ' + this.slideDuration
				}, this.position, { left: this.open ? '0' : -this.width + 'px' }); break;
			case 'right': lang.mixin(pos, {
					top: '25px',
					bottom: '25px',
					width: this.width + 'px',
					transition: 'right ' + this.slideDuration
				}, this.position, { right: this.open ? '0' : -this.width + 'px' }); break;
			case 'top': lang.mixin(pos, {
					right: '25px',
					left: '25px',
					height: this.height + 'px',
					transition: 'top ' + this.slideDuration
				}, this.position, { top: this.open ? '0' : -this.height + 'px' }); break;
			case 'bottom': lang.mixin(pos, {
					right: '25px',
					left: '25px',
					height: this.height + 'px',
					transition: 'bottom ' + this.slideDuration
				}, this.position, { bottom: this.open ? '0' : -this.height + 'px' }); break;
			}
			domStyle.set(this.domNode, pos);
		},
		
		buildRendering: function (config) {
			this.inherited(arguments);

			this._setPositionStyle();

			this.acc = new Accordion({ style: "height: 100%; overflow-y: auto" }, domConstruct.create('div',{}, this.domNode));
			this.cPane = new ContentPane({content:this.content});
			this.acc.addChild(this.cPane);
			
			if(this.resizable){
				this._createResizer();
			}
			this._createToggler();

//			on(this.content.domNode, 'click', lang.hitch(this, function(){
//				query('.floatingContainerFocus').forEach(function(n){domClass.remove(n, 'floatingContainerFocus');});
//				domClass.add(this.domNode, 'floatingContainerFocus');
//			}));

			on(this.domNode, 'mouseenter', lang.hitch(this, function(){
				if(!this.pinned) {
					if(!this.open){
						this.set('open', true);
					} else if(this._closeTs){
						clearTimeout(this._closeTs);
					}
				}
			}));
			on(this.domNode, 'mouseleave', lang.hitch(this, function(){
				if(!this.pinned){
					this._closeTs = setTimeout(lang.hitch(this, function(){
						this.set('open', false);
					}), this.unpinnedCloseTimeout);
				}
			}));
		},
		
		_createResizer: function() {
			var style = '';
			switch (this.zone){
			case 'right': style = 'position: absolute;top: 0;bottom: 0;width: 5px;cursor:e-resize'; break;
			case 'left': style = 'position: absolute;right:0;top: 0;bottom: 0;width: 5px;cursor:e-resize'; break;
			case 'top': style = 'position: absolute;left: 0;right: 0;bottom:0;height: 5px;cursor:n-resize'; break;
			case 'bottom': style = 'position: absolute;left: 0;right: 0;top:0;height: 5px;cursor:n-resize'; break;
			}
			this._resizerDiv = domConstruct.create('div', {style:style}, this.domNode);
			on(document, 'mousedown', lang.hitch(this, function(e){
				if((e.target || e.srcElement) === this._resizerDiv) this.set('_resizeActive', true);
			}));
			on(document, 'mouseup', lang.hitch(this, function(e){
				this.set('_resizeActive', false);
			}));
			on(document, 'mousemove', lang.hitch(this, function(e){
				if(this._resizeActive){
					var newWidth = (!this.minWidth || this.minWidth < (screen.width - e.clientX)) ? (screen.width - e.clientX) : this.minWidth;
					domStyle.set(this.domNode, 'width', newWidth + 'px');
					this.width = newWidth;
					if (window.getSelection) {
					  if (window.getSelection().empty) {  // Chrome
					    window.getSelection().empty();
					  } else if (window.getSelection().removeAllRanges) {  // Firefox
					    window.getSelection().removeAllRanges();
					  }
					} else if (document.selection) {  // IE?
					  document.selection.empty();
					}
					this.resize();
				}
			}));
		},
		
		_createToggler: function() {
			var togglerContent = (this.open ? '>' : '<'), togglerStyle = { position: 'absolute', backgroundColor: 'white', borderStyle: 'solid', borderColor:'#759dc0', fontWeight: 'bolder', color: '#759DC8', fontSize: '1.7em', cursor: 'pointer' };
			if(this._toggler.label === true && this.content && this.content.widgetTitle){
				togglerContent = this.content.widgetTitle;
				//togglerStyle = {};
			} else if (this._toggler.label) {
				togglerContent = this._toggler.label;
				//togglerStyle = {};
			} else if(this._toggler.label === false){
				togglerContent = "&nbsp;";
				togglerStyle = {position: 'absolute', borderStyle: 'solid', borderColor:'#759dc0', cursor: 'pointer', backgroundRepeat: 'no-repeat', backgroundColor: 'white'};
				switch(this.zone){
				case 'right': lang.mixin(togglerStyle, {left:'-24px', width: '16px', height: '22px', backgroundPosition: '4px 9px'}); break;
				case 'left': lang.mixin(togglerStyle, {right:'-24px', width: '16px', height: '22px', backgroundPosition: '7px 9px'}); break;
				case 'top': lang.mixin(togglerStyle, {bottom:'-21px', height: '24px', width: '14px', backgroundPosition: '9px 7px'}); break;
				case 'bottom': lang.mixin(togglerStyle, {top:'-23px', height: '22px', width: '14px', backgroundPosition: '9px 4px'}); break;
				}
			}
			
			if(this._toggler.style){
				lang.mixin(togglerStyle, this._toggler.style);
			}
			
			this._togglerDiv = domConstruct.create('div', {innerHTML: togglerContent, className:"floatingToggler"}, this.domNode);
			var obj = {};
			switch(this.zone){
			case 'right': obj = { left: this._toggler.left, top: this._toggler.top, borderWidth: this._toggler.borderWidth, borderRadius: this._toggler.borderRadius, padding: this._toggler.padding }; break;
			case 'left': obj = { right: this._toggler.right, top: this._toggler.top, borderWidth: this._toggler.borderWidth, borderRadius: this._toggler.borderRadius, padding: this._toggler.padding }; break;
			case 'top': obj = { left: this._toggler.left, bottom: this._toggler.top, borderWidth: this._toggler.borderWidth, borderRadius: this._toggler.borderRadius, padding: this._toggler.padding }; break;
			case 'bottom': obj = { left: this._toggler.left, top: this._toggler.top, borderWidth: this._toggler.borderWidth, borderRadius: this._toggler.borderRadius, padding: this._toggler.padding }; break;
			}
			domStyle.set(this._togglerDiv, obj);

			if(this._toggler.iconClass === true && this.content && this.content.iconClass){
				domClass.add(this._togglerDiv, this.content.iconClass);
			} else if (this._toggler.iconClass){
				domClass.add(this._togglerDiv, this._toggler.iconClass);
			}
			
			if(this._toggler.iconStyle){
				domStyle.set(this._togglerDiv, this._toggler.iconStyle);
			}

			domStyle.set(this._togglerDiv, togglerStyle);
		},
		
		_setPinnedAttr: function(value) {
			this.pinned = value;
			if(this._pinBtn){
				domStyle.set(this._pinBtn, {
					backgroundImage: (value ? 'url(data:image/gif;base64,R0lGODlhEAAQAKEBAAAAAP///8zHuv///yH5BAEKAAMALAAAAAAQABAAAAIfnI+py80AoRtACOnqBVPj5nGZ9S3ROVHpIa7tCsdTAQA7)':'url(data:image/gif;base64,R0lGODlhEAAQAJEAAAAAAP///8zHuv///yH5BAEAAAMALAAAAAAQABAAAAIdnI+py+2PADygWsmA2BtHy3XNZY2kp6DTyrauUwAAOw==)')
				});
			}
		},
		
		postCreate: function() {
			this.inherited(arguments);
			this.acc.startup();
			query(".dijitAccordionChildWrapper", this.acc.domNode).forEach(function(node){
				switch(this.zone){
				case 'right': domStyle.set(node, {margin:'0 -1px 2px 2px'}); break;
				case 'left': domStyle.set(node, {margin:'0 2px 2px -1px'}); break;
				case 'top': domStyle.set(node, {margin:'0 2px 2px 2px'}); break;
				case 'bottom': domStyle.set(node, {margin:'0 2px -1px 2px'}); break;
				}
			});
			on(this._togglerDiv, 'click', lang.hitch(this, function(){
				if(!this.open || domClass.contains(this.domNode, 'floatingContainerFocus')){
					this.set('open', !this.open);
				} else if(this.open && !domClass.contains(this.domNode, 'floatingContainerFocus')){
					this.focusFloating(this);
				}
			}));
			
			if(this.cPane._buttonWidget){
				this._pinBtn = domConstruct.create('div', {innerHTML: '&nbsp;'}, this.cPane._buttonWidget.titleNode, 'last');
				domStyle.set(this._pinBtn, {
					'width':'16px',
					'height':'16px',
					'float':'right',
					'cursor':'pointer',
					'display': (this.pinnable ? 'block':'none')
				});
				
				on(this._pinBtn, 'click', lang.hitch(this, function(){
					this.set('pinned', !this.pinned);
				}));
			}
			
			this.set('pinned', this.pinned);
		},
		
		resize: function() {
			this.acc.resize();
		},
		
		_setOpenAttr: function(value){
			if(this._closeTs) clearTimeout(this._closeTs);
			if(this.activateOnOpen && this.content && this.content.onDeactivate && this.content.onActivate){
				if(value && this.content.activated !== true){
					this.content.onActivate();
				} else if (!value && this.content.activated !== false){
					this.content.onDeactivate();
				}
			}

			this.open = value;
			if(this._togglerDiv['data-originalZone'] && value){
				domStyle.set(this.domNode, {transitionDuration: "0s"});
				domStyle.set(this._togglerDiv, {transitionDuration: "0s"});
			} else {
				domStyle.set(this.domNode, {transitionDuration: this.slideDuration});
				domStyle.set(this._togglerDiv, {transitionDuration: this.slideDuration});
			}
			switch(this.zone){
			case 'right': domStyle.set(this.domNode, { right: (value ? '0' : (-this.width+10) + 'px') }); break;
			case 'left': domStyle.set(this.domNode, { left: (value ? '0' : (-this.width+10) + 'px') }); break;
			case 'top': domStyle.set(this.domNode, { top: (value ? '0' : (-this.height+10) + 'px') }); break;
			case 'bottom': domStyle.set(this.domNode, { bottom: (value ? '0' : (-this.height+10) + 'px') }); break;
			}
			if(this._togglerDiv.innerHTML == '>' || this._togglerDiv.innerHTML == '<'){
				this._togglerDiv.innerHTML = (value ? '>' : '<');
			}
			
			if(value){
				this.focusFloating(this);
			} else {
				this.unfocusFloating(this);
			}
		},
		
		focusFloating: function(_floating) {
			//this.resetTogglers();
			query('.floatingContainer').forEach(lang.hitch(_floating, function(n){
				var oFloat = dijit.byNode(n);
				if(oFloat && oFloat != this && oFloat.zone == this.zone && !oFloat.open){
					var orignalCssValue = this.getCssNumberValue(oFloat._togglerDiv, this.getInvertZone());
					oFloat._togglerDiv['data-originalZone'] = orignalCssValue;
					
					var s = {transitionDuration: this.slideDuration};
					s[this.getInvertZone()] = (orignalCssValue - this.width) +'px';
					domStyle.set(oFloat._togglerDiv, s);
				} else if (oFloat && oFloat != this && oFloat.zone == this.zone && oFloat.open) {
					oFloat.set('open', false);
				}
			}));
			domClass.add(_floating.domNode, 'floatingContainerFocus');
		},
		
		unfocusFloating: function(_floating) {
			domClass.remove(_floating.domNode, 'floatingContainerFocus');
			query('.floatingContainer').forEach(lang.hitch(_floating, function(n){
				var oFloat = dijit.byNode(n);
				if(oFloat && oFloat != this && oFloat.zone == this.zone && oFloat._togglerDiv['data-originalZone']){
					var s = {};
					s[this.getInvertZone()] = oFloat._togglerDiv['data-originalZone'] +'px';
					domStyle.set(oFloat._togglerDiv, s);
					delete oFloat._togglerDiv['data-originalZone'];
				}
			}));
			
			var focused = false;
			query('.floatingContainer').forEach(lang.hitch(_floating, function(n){
				var oFloat = dijit.byNode(n);
				if(oFloat && oFloat != this && oFloat.zone == this.zone && oFloat.open && !focused){
					focused = true;
					this.focusFloating(oFloat);
				}
			}));
		},
		
		resetTogglers: function(){
			query('.floatingContainer').forEach(lang.hitch(this, function(n){
				domClass.remove(n, 'floatingContainerFocus');
				var otherFloat = dijit.byNode(n);
				if(otherFloat && otherFloat._togglerDiv['data-originalZone']){
					var s = {}; s[this.getInvertZone()] = otherFloat._togglerDiv['data-originalZone']+'px';
					domStyle.set(otherFloat._togglerDiv, s);
					delete otherFloat._togglerDiv['data-originalZone'];
				}
			}));
		},
		
		_set_resizeActiveAttr: function(value) {
			this._resizeActive = value;
			domStyle.set(this._resizerDiv, {backgroundColor:value ? '#abd6ff':'transparent'});
		},
		
		getCssNumberValue: function(node, cssProp){
			var css = domStyle.get(node, cssProp);
			if(css && css.indexOf && css.indexOf('px') > 0){
				css = css.substring(0, css.indexOf('px'));
				css = parseInt(css);
			}
			return css;
		},
		
		getInvertZone: function(){
			return this.zone == 'left' || this.zone == 'right' ? (this.zone == 'left' ? 'right' : 'left') : (this.zone == 'top' ? 'bottom' : 'top');
		}
	});
});