diff options
Diffstat (limited to 'js/dojo/dojox/layout/GridContainer.js')
| -rw-r--r-- | js/dojo/dojox/layout/GridContainer.js | 630 |
1 files changed, 630 insertions, 0 deletions
diff --git a/js/dojo/dojox/layout/GridContainer.js b/js/dojo/dojox/layout/GridContainer.js new file mode 100644 index 0000000..cdb2d9e --- /dev/null +++ b/js/dojo/dojox/layout/GridContainer.js @@ -0,0 +1,630 @@ +//>>built +define("dojox/layout/GridContainer", [ + "dojo/_base/kernel", + "dojo/_base/array", + "dojo/_base/connect", + "dojo/_base/declare", + "dojo/_base/html", + "dojo/_base/lang", + "dojo/_base/window", + "dojo/ready", // dojo.ready + "dojox/layout/GridContainerLite" +],function(dojo){ + return dojo.declare( + "dojox.layout.GridContainer", + dojox.layout.GridContainerLite, + { + // summary: + // A grid containing any kind of objects and acting like web portals. + // + // description: + // This component inherits of all features of gridContainerLite plus : + // - Resize colums + // - Add / remove columns + // - Fix columns at left or at right. + // example: + // | <div dojoType="dojox.layout.GridContainer" nbZones="3" isAutoOrganized="true"> + // | <div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div> + // | <div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div> + // | <div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div> + // | </div> + // + // example: + // | dojo.ready(function(){ + // | var cpane1 = new dijit.layout.ContentPane({ title:"cpane1", content: "Content Pane 1 : Drag Me !" }), + // | cpane2 = new dijit.layout.ContentPane({ title:"cpane2", content: "Content Pane 2 : Drag Me !" }), + // | cpane3 = new dijit.layout.ContentPane({ title:"cpane3", content: "Content Pane 3 : Drag Me !" }); + // | + // | var widget = new dojox.layout.GridContainer({ + // | nbZones: 3, + // | isAutoOrganized: true + // | }, dojo.byId("idNode")); + // | widget.addChild(cpane1, 0, 0); + // | widget.addChild(cpane2, 1, 0); + // | widget.addChild(cpane3, 2, 1); + // | widget.startup(); + // | }); + + // hasResizableColumns: Boolean + // Allow or not resizing of columns by a grip handle. + hasResizableColumns: true, + + // liveResizeColumns: Boolean + // Specifies whether columns resize as you drag (true) or only upon mouseup (false) + liveResizeColumns : false, + + // minColWidth: Integer + // Minimum column width in percentage. + minColWidth: 20, + + // minChildWidth: Integer + // Minimum children width in pixel (only used for IE6 which doesn't handle min-width css property) + minChildWidth: 150, + + // mode: String + // Location to add/remove columns, must be set to 'left' or 'right' (default). + mode: "right", + + // isRightFixed: Boolean + // Define if the last right column is fixed. + // Used when you add or remove columns by calling setColumns method. + isRightFixed: false, + + // isLeftFixed: Boolean + // Define if the last left column is fixed. + // Used when you add or remove columns by calling setColumns method. + isLeftFixed: false, + + startup: function(){ + // summary: + // Call the startup of GridContainerLite and place grips + // if user has chosen the hasResizableColumns attribute to true. + + //console.log("dojox.layout.GridContainer ::: startup"); + this.inherited(arguments); + if(this.hasResizableColumns){ + for(var i = 0; i < this._grid.length - 1; i++){ + this._createGrip(i); + } + // If widget has a container parent, grips will be placed + // by method onShow. + if(!this.getParent()){ + // Fix IE7 : + // The CSS property height:100% for the grip + // doesn't work anytime. It's necessary to wait + // the end of loading before to place grips. + dojo.ready(dojo.hitch(this, "_placeGrips")); + } + } + }, + + resizeChildAfterDrop : function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){ + // summary: + // Call when a child is dropped. + // description: + // Allow to resize and put grips + // node: + // domNode of dropped widget. + // targetArea: + // AreaManager Object containing information of targetArea + // indexChild: + // Index where the dropped widget has been placed + + if(this.inherited(arguments)){ + this._placeGrips(); + } + }, + + onShow: function(){ + // summary: + // Place grips in the right place when the GridContainer becomes visible. + + //console.log("dojox.layout.GridContainer ::: onShow"); + this.inherited(arguments); + this._placeGrips(); + }, + + resize: function(){ + // summary: + // Resize the GridContainer widget and columns. + // Replace grips if it's necessary. + // tags: + // callback + + //console.log("dojox.layout.GridContainer ::: resize"); + this.inherited(arguments); + // Fix IE6 : + // IE6 calls method resize itself. + // If the GridContainer is not visible at this time, + // the method _placeGrips can return a negative value with + // contentBox method. (see method _placeGrip() with Fix Ie6 for the height) + if(this._isShown() && this.hasResizableColumns){ + this._placeGrips(); + } + }, + + _createGrip: function(/*Integer*/ index){ + // summary: + // Create a grip for a specific zone. + // index: + // index where the grip has to be created. + // tags: + // protected + + //console.log("dojox.layout.GridContainer ::: _createGrip"); + var dropZone = this._grid[index], + grip = dojo.create("div", { 'class': "gridContainerGrip" }, this.domNode); + dropZone.grip = grip; + dropZone.gripHandler = [ + this.connect(grip, "onmouseover", function(e){ + var gridContainerGripShow = false; + for(var i = 0; i < this._grid.length - 1; i++){ + if(dojo.hasClass(this._grid[i].grip, "gridContainerGripShow")){ + gridContainerGripShow = true; + break; + } + } + if(!gridContainerGripShow){ + dojo.removeClass(e.target, "gridContainerGrip"); + dojo.addClass(e.target, "gridContainerGripShow"); + } + })[0], + this.connect(grip, "onmouseout", function(e){ + if(!this._isResized){ + dojo.removeClass(e.target, "gridContainerGripShow"); + dojo.addClass(e.target, "gridContainerGrip"); + } + })[0], + this.connect(grip, "onmousedown", "_resizeColumnOn")[0], + this.connect(grip, "ondblclick", "_onGripDbClick")[0] + ]; + }, + + _placeGrips: function(){ + // summary: + // Define the position of a grip and place it on page. + // tags: + // protected + + //console.log("dojox.layout.GridContainer ::: _placeGrips"); + var gripWidth, height, left = 0, grip; + var scroll = this.domNode.style.overflowY; + + dojo.forEach(this._grid, function(dropZone){ + if(dropZone.grip){ + grip = dropZone.grip; + if(!gripWidth){ + gripWidth = grip.offsetWidth / 2; + } + + left += dojo.marginBox(dropZone.node).w; + + dojo.style(grip, "left", (left - gripWidth) + "px"); + //if(dojo.isIE == 6){ do it fot all navigators + if(!height){ + height = dojo.contentBox(this.gridNode).h; + } + if(height > 0){ + dojo.style(grip, "height", height + "px"); + } + //} + } + }, this); + }, + + _onGripDbClick: function(){ + // summary: + // Called when a double click is catch. Resize all columns with the same width. + // The method resize of children have to be called. + // tags: + // callback protected + + //console.log("dojox.layout.GridContainer ::: _onGripDbClick"); + this._updateColumnsWidth(this._dragManager); + this.resize(); + }, + + _resizeColumnOn: function(/*Event*/e){ + // summary: + // Connect events to listen the resize action. + // Change the type of width columns (% to px). + // Calculate the minwidth according to the children. + // tags: + // callback + + //console.log("dojox.layout.GridContainer ::: _resizeColumnOn", e); + this._activeGrip = e.target; + this._initX = e.pageX; + e.preventDefault(); + + dojo.body().style.cursor = "ew-resize"; + + this._isResized = true; + + var tabSize = []; + var grid; + var i; + + for(i = 0; i < this._grid.length; i++){ + tabSize[i] = dojo.contentBox(this._grid[i].node).w; + } + + this._oldTabSize = tabSize; + + for(i = 0; i < this._grid.length; i++){ + grid = this._grid[i]; + if(this._activeGrip == grid.grip){ + this._currentColumn = grid.node; + this._currentColumnWidth = tabSize[i]; + this._nextColumn = this._grid[i + 1].node; + this._nextColumnWidth = tabSize[i + 1]; + } + grid.node.style.width = tabSize[i] + "px"; + } + + // calculate the minWidh of all children for current and next column + var calculateChildMinWidth = function(childNodes, minChild){ + var width = 0; + var childMinWidth = 0; + + dojo.forEach(childNodes, function(child){ + if(child.nodeType == 1){ + var objectStyle = dojo.getComputedStyle(child); + var minWidth = (dojo.isIE) ? minChild : parseInt(objectStyle.minWidth); + + childMinWidth = minWidth + + parseInt(objectStyle.marginLeft) + + parseInt(objectStyle.marginRight); + + if(width < childMinWidth){ + width = childMinWidth; + } + } + }); + return width; + } + var currentColumnMinWidth = calculateChildMinWidth(this._currentColumn.childNodes, this.minChildWidth); + + var nextColumnMinWidth = calculateChildMinWidth(this._nextColumn.childNodes, this.minChildWidth); + + var minPix = Math.round((dojo.marginBox(this.gridContainerTable).w * this.minColWidth) / 100); + + this._currentMinCol = currentColumnMinWidth; + this._nextMinCol = nextColumnMinWidth; + + if(minPix > this._currentMinCol){ + this._currentMinCol = minPix; + } + if(minPix > this._nextMinCol){ + this._nextMinCol = minPix; + } + this._connectResizeColumnMove = dojo.connect(dojo.doc, "onmousemove", this, "_resizeColumnMove"); + this._connectOnGripMouseUp = dojo.connect(dojo.doc, "onmouseup", this, "_onGripMouseUp"); + }, + + _onGripMouseUp: function(){ + // summary: + // Call on the onMouseUp only if the reiszeColumnMove was not called. + // tags: + // callback + + //console.log(dojox.layout.GridContainer ::: _onGripMouseUp"); + dojo.body().style.cursor = "default"; + + dojo.disconnect(this._connectResizeColumnMove); + dojo.disconnect(this._connectOnGripMouseUp); + + this._connectOnGripMouseUp = this._connectResizeColumnMove = null; + + if(this._activeGrip){ + dojo.removeClass(this._activeGrip, "gridContainerGripShow"); + dojo.addClass(this._activeGrip, "gridContainerGrip"); + } + + this._isResized = false; + }, + + _resizeColumnMove: function(/*Event*/e){ + // summary: + // Change columns size. + // tags: + // callback + + //console.log("dojox.layout.GridContainer ::: _resizeColumnMove"); + e.preventDefault(); + if(!this._connectResizeColumnOff){ + dojo.disconnect(this._connectOnGripMouseUp); + this._connectOnGripMouseUp = null; + this._connectResizeColumnOff = dojo.connect(dojo.doc, "onmouseup", this, "_resizeColumnOff"); + } + + var d = e.pageX - this._initX; + if(d == 0){ return; } + + if(!(this._currentColumnWidth + d < this._currentMinCol || + this._nextColumnWidth - d < this._nextMinCol)){ + + this._currentColumnWidth += d; + this._nextColumnWidth -= d; + this._initX = e.pageX; + this._activeGrip.style.left = parseInt(this._activeGrip.style.left) + d + "px"; + + if(this.liveResizeColumns){ + this._currentColumn.style["width"] = this._currentColumnWidth + "px"; + this._nextColumn.style["width"] = this._nextColumnWidth + "px"; + this.resize(); + } + } + }, + + _resizeColumnOff: function(/*Event*/e){ + // summary: + // Disconnect resize events. + // Change the type of width columns (px to %). + // tags: + // callback + + //console.log("dojox.layout.GridContainer ::: _resizeColumnOff"); + dojo.body().style.cursor = "default"; + + dojo.disconnect(this._connectResizeColumnMove); + dojo.disconnect(this._connectResizeColumnOff); + + this._connectResizeColumnOff = this._connectResizeColumnMove = null; + + if(!this.liveResizeColumns){ + this._currentColumn.style["width"] = this._currentColumnWidth + "px"; + this._nextColumn.style["width"] = this._nextColumnWidth + "px"; + //this.resize(); + } + + var tabSize = [], + testSize = [], + tabWidth = this.gridContainerTable.clientWidth, + node, + update = false, + i; + + for(i = 0; i < this._grid.length; i++){ + node = this._grid[i].node; + if(dojo.isIE){ + tabSize[i] = dojo.marginBox(node).w; + testSize[i] = dojo.contentBox(node).w; + } + else{ + tabSize[i] = dojo.contentBox(node).w; + testSize = tabSize; + } + } + + for(i = 0; i < testSize.length; i++){ + if(testSize[i] != this._oldTabSize[i]){ + update = true; + break; + } + } + + if(update){ + var mul = dojo.isIE ? 100 : 10000; + for(i = 0; i < this._grid.length; i++){ + this._grid[i].node.style.width = Math.round((100 * mul * tabSize[i]) / tabWidth) / mul + "%"; + } + this.resize(); + } + + if(this._activeGrip){ + dojo.removeClass(this._activeGrip, "gridContainerGripShow"); + dojo.addClass(this._activeGrip, "gridContainerGrip"); + } + + this._isResized = false; + }, + + setColumns: function(/*Integer*/nbColumns){ + // summary: + // Set the number of columns. + // nbColumns: + // Number of columns + + //console.log("dojox.layout.GridContainer ::: setColumns"); + var z, j; + if(nbColumns > 0){ + var length = this._grid.length, + delta = length - nbColumns; + if(delta > 0){ + var count = [], zone, start, end, nbChildren; + // Check if right or left columns are fixed + // Columns are not taken in account and can't be deleted + if(this.mode == "right"){ + end = (this.isLeftFixed && length > 0) ? 1 : 0; + start = (this.isRightFixed) ? length - 2 : length - 1 + for(z = start; z >= end; z--){ + nbChildren = 0; + zone = this._grid[z].node; + for(j = 0; j < zone.childNodes.length; j++){ + if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){ + nbChildren++; + break; + } + } + if(nbChildren == 0){ count[count.length] = z; } + if(count.length >= delta){ + this._deleteColumn(count); + break; + } + } + if(count.length < delta){ + dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]); + } + } + else{ // mode = "left" + start = (this.isLeftFixed && length > 0) ? 1 : 0; + end = (this.isRightFixed) ? length - 1 : length; + for(z = start; z < end; z++){ + nbChildren = 0; + zone = this._grid[z].node; + for(j = 0; j < zone.childNodes.length; j++){ + if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){ + nbChildren++; + break; + } + } + if(nbChildren == 0){ count[count.length] = z; } + if(count.length >= delta){ + this._deleteColumn(count); + break; + } + } + if(count.length < delta){ + //Not enough empty columns + dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]); + } + } + } + else{ + if(delta < 0){ this._addColumn(Math.abs(delta)); } + } + if(this.hasResizableColumns){ this._placeGrips(); } + } + }, + + _addColumn: function(/*Integer*/nbColumns){ + // summary: + // Add some columns. + // nbColumns: + // Number of column to added + // tags: + // private + + //console.log("dojox.layout.GridContainer ::: _addColumn"); + var grid = this._grid, + dropZone, + node, + index, + length, + isRightMode = (this.mode == "right"), + accept = this.acceptTypes.join(","), + m = this._dragManager; + + //Add a grip to the last column + if(this.hasResizableColumns && ((!this.isRightFixed && isRightMode) + || (this.isLeftFixed && !isRightMode && this.nbZones == 1) )){ + this._createGrip(grid.length - 1); + } + + for(var i = 0; i < nbColumns; i++){ + // Fix CODEX defect #53025 : + // Apply acceptType attribute on each new column. + node = dojo.create("td", { + 'class': "gridContainerZone dojoxDndArea" , + 'accept': accept, + 'id': this.id + "_dz" + this.nbZones + }); + + length = grid.length; + + if(isRightMode){ + if(this.isRightFixed){ + index = length - 1; + grid.splice(index, 0, { + 'node': grid[index].node.parentNode.insertBefore(node, grid[index].node) + }); + } + else{ + index = length; + grid.push({ 'node': this.gridNode.appendChild(node) }); + } + } + else{ + if(this.isLeftFixed){ + index = (length == 1) ? 0 : 1; + this._grid.splice(1, 0, { + 'node': this._grid[index].node.parentNode.appendChild(node, this._grid[index].node) + }); + index = 1; + } + else{ + index = length - this.nbZones; + this._grid.splice(index, 0, { + 'node': grid[index].node.parentNode.insertBefore(node, grid[index].node) + }); + } + } + if(this.hasResizableColumns){ + //Add a grip to resize columns + if((!isRightMode && this.nbZones != 1) || + (!isRightMode && this.nbZones == 1 && !this.isLeftFixed) || + (isRightMode && i < nbColumns-1) || + (isRightMode && i == nbColumns-1 && this.isRightFixed)){ + this._createGrip(index); + } + } + // register tnbZoneshe new area into the areaManager + m.registerByNode(grid[index].node); + this.nbZones++; + } + this._updateColumnsWidth(m); + }, + + _deleteColumn: function(/*Array*/indices){ + // summary: + // Remove some columns with indices passed as an array. + // indices: + // Column index array + // tags: + // private + + //console.log("dojox.layout.GridContainer ::: _deleteColumn"); + var child, grid, index, + nbDelZones = 0, + length = indices.length, + m = this._dragManager; + for(var i = 0; i < length; i++){ + index = (this.mode == "right") ? indices[i] : indices[i] - nbDelZones; + grid = this._grid[index]; + + if(this.hasResizableColumns && grid.grip){ + dojo.forEach(grid.gripHandler, function(handler){ + dojo.disconnect(handler); + }); + dojo.destroy(this.domNode.removeChild(grid.grip)); + grid.grip = null; + } + + m.unregister(grid.node); + dojo.destroy(this.gridNode.removeChild(grid.node)); + this._grid.splice(index, 1); + this.nbZones--; + nbDelZones++; + } + + // last grip + var lastGrid = this._grid[this.nbZones-1]; + if(lastGrid.grip){ + dojo.forEach(lastGrid.gripHandler, dojo.disconnect); + dojo.destroy(this.domNode.removeChild(lastGrid.grip)); + lastGrid.grip = null; + } + + this._updateColumnsWidth(m); + }, + + _updateColumnsWidth: function(/*Object*/ manager){ + // summary: + // Update the columns width. + // manager: + // dojox.mdnd.AreaManager singleton + // tags: + // private + + //console.log("dojox.layout.GridContainer ::: _updateColumnsWidth"); + this.inherited(arguments); + manager._dropMode.updateAreas(manager._areaList); + }, + + destroy: function(){ + dojo.unsubscribe(this._dropHandler); + this.inherited(arguments); + } + }); +}); |
