///////////////////////////////////////////////////////////////////////////
|
// Copyright © 2014 - 2018 Esri. All Rights Reserved.
|
//
|
// Licensed under the Apache License Version 2.0 (the "License");
|
// you may not use this file except in compliance with the License.
|
// You may obtain a copy of the License at
|
//
|
// http://www.apache.org/licenses/LICENSE-2.0
|
//
|
// Unless required by applicable law or agreed to in writing, software
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// See the License for the specific language governing permissions and
|
// limitations under the License.
|
///////////////////////////////////////////////////////////////////////////
|
|
define(['dojo/_base/declare',
|
'dojo/_base/lang',
|
'dojo/_base/array',
|
'dijit/_WidgetBase',
|
'dojo/dom-geometry',
|
'dojo/dom-class',
|
'dojo/Evented',
|
'dojo/debounce'
|
],
|
function(declare, lang, array, _WidgetBase, domGeometry, domClass, Evented, debounce) {
|
var COMPONENT_NAME = 'jimu grid';
|
/**
|
* The structure of the this layout has one limitation:
|
* A stack only contains one component.
|
*/
|
return declare([_WidgetBase, Evented], {
|
'baseClass': 'jimu-dijit-gridlayout',
|
declaredClass: 'jimu.dijit.GridLayout',
|
|
container: null, // the container domNode of golden layout
|
layoutDefinition: null, // configuration of golden layout
|
components: null, // array of {id: string, dijit: dijit instance}
|
editable: false,
|
|
_layout: null, // instance of goldenLayout
|
_coordinates: null, // an object whose key is component id and value is component coordinate.
|
_isCreatingLayout: null,
|
|
postCreate: function(){
|
this.inherited(arguments);
|
this._isCreatingLayout = false;
|
this._createLayout(this.layoutDefinition);
|
},
|
|
restoreLayout: function(layoutDefinition) {
|
layoutDefinition = layoutDefinition || this.layoutDefinition;
|
this._createLayout(layoutDefinition);
|
},
|
|
destroy: function() {
|
array.forEach(this.components, function(component) {
|
component.dijit.destroy();
|
});
|
this._layout.destroy();
|
this.inherited(arguments);
|
},
|
|
getLayoutDefinition: function() {
|
var currentConfig = this._layout.toConfig();
|
return currentConfig.content;
|
},
|
|
resize: function() {
|
var box = domGeometry.getMarginBox(this.container);
|
this._layout.updateSize(box.w, box.h);
|
},
|
|
getComponentSize: function(componentId) {
|
var rootElem = this._layout.root.contentItems[0];
|
var contentItem = rootElem.getItemsById(componentId), container;
|
if (contentItem && contentItem.length > 0) {
|
container = contentItem[0].container;
|
return {
|
w: container.width,
|
h: container.height
|
};
|
}
|
return {
|
w: 0,
|
h: 0
|
};
|
},
|
|
getSize: function() {
|
return {
|
w: this._layout.width,
|
h: this._layout.height
|
};
|
},
|
|
/**
|
*
|
*/
|
setVisible: function(componentId, visible) {
|
var rootElem = this._layout.root.contentItems[0];
|
var contentItem = rootElem.getItemsById(componentId);
|
if (contentItem && contentItem.length > 0 && visible === false) {
|
this._hideComponent(contentItem[0]);
|
} else if ((!contentItem || contentItem.length === 0) && visible === true) {
|
this._showComponent(componentId);
|
}
|
},
|
|
highlightItem: function(componentId) {
|
var rootElem = this._layout.root.contentItems[0];
|
var contentItem = rootElem.getItemsById(componentId);
|
if (contentItem && contentItem.length > 0) {
|
contentItem[0].highlight();
|
}
|
},
|
|
unhighlightItem: function(componentId) {
|
var rootElem = this._layout.root.contentItems[0];
|
var contentItem = rootElem.getItemsById(componentId);
|
if (contentItem && contentItem.length > 0) {
|
contentItem[0].unhighlight();
|
}
|
},
|
|
_createLayout: function(layoutDefinition) {
|
if (this._isCreatingLayout) {
|
return;
|
}
|
this._coordinates = {};
|
this._isCreatingLayout = true;
|
var config = {
|
settings: {
|
hasHeaders: false,
|
resizeEnabled: this.editable,
|
reorderEnabled: this.editable,
|
selectionEnabled: this.editable,
|
highlightEnabled: this.editable
|
},
|
dimensions: {
|
borderWidth: 1,
|
dragProxyWidth: 0,
|
dragProxyHeight: 0
|
},
|
content: layoutDefinition
|
};
|
var oldLayout = this._layout;
|
|
require(['libs/goldenlayout/goldenlayout'], lang.hitch(this, function(GoldenLayout){
|
this._layout = new GoldenLayout(config, this.container);
|
this._layout.registerComponent(COMPONENT_NAME, lang.hitch(this, function(container, componentState){
|
var targetDijit;
|
container.parent.config.id = componentState.id;
|
array.some(this.components, function(item) {
|
if (item.id === componentState.id) {
|
targetDijit = item.dijit;
|
container.getElement().html(item.dijit.domNode);
|
return true;
|
}
|
}, this);
|
container.on('resize', debounce(lang.hitch(this, function() {
|
if (container.width > 0 && container.height > 0 && targetDijit &&
|
typeof targetDijit.resize === 'function') {
|
targetDijit.resize(container.width, container.height);
|
}
|
}), 200));
|
container.on('select', lang.hitch(this, function() {
|
if(this.editable) {
|
container.parent.select();
|
}
|
this.emit('mask-click', container.parent.config.id);
|
}));
|
}));
|
this._layout.on( 'initialised', lang.hitch(this, function(){
|
this._resetCoordinate();
|
this.emit("initialised");
|
this._isCreatingLayout = false;
|
if (oldLayout) {
|
oldLayout.destroy();
|
}
|
}));
|
this._layout.on('stateChanged', lang.hitch(this, function(){
|
this._resetCoordinate();
|
}));
|
this._layout.init();
|
|
if (!this.editable) {
|
domClass.add(this._layout.root.childElementContainer[0], 'viewonly');
|
}
|
domClass.add(this._layout.root.childElementContainer[0], 'jimu-dijit-gridlayout');
|
setTimeout(lang.hitch(this, this.resize), 100);
|
}));
|
},
|
|
_hideComponent: function(contentItem) {
|
if (contentItem.parent) {
|
// remove component but won't destroy it
|
contentItem.parent.removeChild(contentItem, true);
|
}
|
},
|
|
_showComponent: function(componentId) {
|
var component, coordinates, currentNode, config, rootItem, rootContentItem, actualIndex;
|
array.some(this.components, function(item) {
|
if (item.id === componentId) {
|
component = item;
|
return true;
|
}
|
}, this);
|
|
if (component) {
|
config = {
|
id: componentId,
|
type: 'component',
|
componentName: COMPONENT_NAME,
|
componentState: {
|
id: componentId
|
}
|
};
|
coordinates = this._coordinates[componentId];
|
rootItem = this._layout.root;
|
if (coordinates) {
|
// rootItem.type may be stack is there is only one component
|
if (coordinates[0].type !== rootItem.contentItems[0].type) {
|
rootContentItem = rootItem.contentItems[0];
|
rootItem.replaceChild(rootContentItem, {
|
type: coordinates[0].type,
|
content: []
|
});
|
rootItem.contentItems[0].addChild(rootContentItem);
|
}
|
|
currentNode = rootItem;
|
array.forEach(coordinates, function(pos) {
|
actualIndex = pos.index <= currentNode.contentItems.length ?
|
pos.index : currentNode.contentItems.length;
|
if (pos.type === 'component') {
|
currentNode.addChild(config, actualIndex);
|
} else { //stack, column or row
|
if (pos.type === 'stack' ||
|
currentNode.contentItems[pos.index].type !== pos.type) {
|
currentNode.addChild({
|
type: pos.type,
|
content: []
|
}, actualIndex);
|
}
|
currentNode = currentNode.contentItems[actualIndex];
|
}
|
}, this);
|
} else {
|
if (rootItem.contentItems[0].type === 'stack') {
|
rootContentItem = rootItem.contentItems[0];
|
rootItem.replaceChild(rootContentItem, {
|
type: 'column',
|
content: []
|
});
|
rootItem.contentItems[0].addChild(rootContentItem);
|
}
|
rootItem.contentItems[0].addChild(config);
|
}
|
}
|
},
|
|
/**
|
* Calculate the coordinate of each component
|
*/
|
_resetCoordinate: function() {
|
var components = this._layout.root.getItemsByType('component');
|
var next = function(item, coordinates) {
|
var parent = item.parent;
|
if (!parent) {
|
return;
|
}
|
// get the index of the item in the contentItems array of its parent
|
array.some(parent.contentItems, function(sibliingItem, index) {
|
if (sibliingItem === item) {
|
coordinates.push({
|
type: sibliingItem.type,
|
index: index
|
});
|
return true;
|
}
|
});
|
next(parent, coordinates);
|
};
|
array.forEach(components, function(component) {
|
var coordinates = [];
|
next(component, coordinates);
|
this._coordinates[component.config.id] = coordinates.reverse();
|
}, this);
|
}
|
});
|
});
|