define([
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/_base/array',
'dojo/_base/html',
'dojo/on',
'dojo/dom-construct',
'dojo/query',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'jimu/dijit/ViewStack',
'jimu/utils'
],
function(
declare, lang, array, html, on, domConstruct,
query, _WidgetBase, _TemplatedMixin, ViewStack, utils) {
/* global jimuConfig */
//label is not visible if node width is less than 80px, and icon should be scaled.
var NORMAL_MIN_WIDTH = 80,
NORMAL_WIDTH = 120, //node width should not be larger than this value.
MIN_MARGIN = 20, //minimux margin between this dom and the map box.
MIN_NODE_WIDTH = 10, //If node width is less than 10px, the node will not be visible.
MAX_ROWCOL = 4,
MIN_ROWCOL = 3;
//3*3 tile nodes, with a close button
return declare([_WidgetBase, _TemplatedMixin], {
baseClass: 'jimu-header-more-popup',
templateString: '
',
margin: 4,
postCreate: function() {
this.nodes = [];
this.pages = [];
this.createCloseBtn();
},
startup: function() {
this.viewStack = new ViewStack({
views: [],
viewType: 'dom'
}, this.pagesNode);
this.viewStack.startup();
// this.createPages();
// if (this.viewStack.views.length > 0) {
// this._selectPage(0);
// }
this.resize();
},
resize: function() {
var gridParam = this._calculateGridParam(), closeDiv;
if(gridParam !== null){
html.setStyle(this.domNode, utils.getPositionStyle(gridParam.position));
this.nodeWidth = gridParam.cellSize - this.margin;
if(!this.oldGridParam || this.oldGridParam.rows !== gridParam.rows ||
this.oldGridParam.cols !== gridParam.cols){
//grid changed, re-create the pages
this.clearPages();
this.createPages(gridParam);
}
this.nodes.forEach(lang.hitch(this, function(node, i) {
this.setItemNodePosition(node, i, gridParam);
}));
this.oldGridParam = gridParam;
closeDiv = query('div.close', this.domNode)[0];
html.setStyle(closeDiv, {
width: this.nodeWidth * 0.25 + 'px',
height: this.nodeWidth * 0.25 + 'px'
});
}else{
this.oldGridParam = null;
html.setStyle(this.domNode, utils.getPositionStyle({
left:0,
top:0,
width:0,
height:0,
zIndex: 111
}));
this.nodeWidth = 0;
}
},
setItemNodePosition: function(node, i, gridParam) {
var ml, mt, imgWidth = 48, fontSize = 16, imgNode, labelNode; //margin-left, margin-top
if (i % gridParam.cols === 0) {
ml = 0;
} else {
ml = this.margin / 2;
}
// If the node is in the first row of each page, margin-top is 0, else margin-top is 2
if ((i % (gridParam.rows * gridParam.cols)) < gridParam.cols) {
mt = 0;
} else {
mt = this.margin / 2;
}
var nodeStyle = {};
if (typeof this.nodeWidth === "number") {
nodeStyle.width = this.nodeWidth + 'px';
nodeStyle.height = this.nodeWidth + 'px';
}
if (typeof ml === 'number') {
if (window.isRTL){
nodeStyle.marginRight = ml + 'px';
}else {
nodeStyle.marginLeft = ml + 'px';
}
}
if (typeof mt === 'number') {
nodeStyle.marginTop = mt + 'px';
}
imgNode = query('img', node)[0];
if(imgNode){
if(gridParam.iconScaled){
imgWidth = imgWidth * (this.nodeWidth / NORMAL_WIDTH);
html.setStyle(imgNode, {
width: imgWidth + 'px',
height: imgWidth + 'px'
});
}else{
html.setStyle(imgNode, {
width: imgWidth + 'px',
height: imgWidth + 'px'
});
}
}
labelNode = query('div.node-label', node)[0];
if(labelNode){
if(gridParam.showLabel){
if(gridParam.iconScaled){
fontSize = fontSize * (this.nodeWidth / NORMAL_WIDTH);
html.setStyle(labelNode, {
'font-size': fontSize + 'px',
display: 'block'
});
}else{
html.setStyle(labelNode, {
'font-size': fontSize + 'px',
display: 'block'
});
}
}else{
html.setStyle(labelNode, {
'font-size': fontSize + 'px',
display: 'none'
});
}
}
html.setStyle(node, nodeStyle);
},
clearPages: function(){
array.forEach(this.pages, function(page){
this.viewStack.removeView(page.pageNode);
}, this);
domConstruct.empty(this.pointsNode);
this.pages = [];
this.nodes = [];
},
/**
* Create node pages based on the gridParam object.
* @param {object} gridParam include rows:number, cols:number, cellSize:number,
* iconScaled:boolean, showLabel:boolean,
* position:object(left, right, top, bottom, width, height)
*/
createPages: function(gridParam) {
var count, pages, p, pageNode, pointNode;
count = this.items.length;
pages = Math.ceil(count / (gridParam.rows * gridParam.cols));
for (p = 0; p < pages; p++) {
pageNode = domConstruct.create('div', {
'class': 'page'
});
this.createPageItems(p, pageNode, gridParam);
this.viewStack.addView(pageNode);
if (pages > 1) {
pointNode = domConstruct.create('div', {
'class': 'point'
}, this.pointsNode);
this.own(on(pointNode, 'click', lang.hitch(this, this._onPageNodeClick, p)));
}
this.pages.push({
pageNode: pageNode,
pointNode: pointNode
});
}
if (this.viewStack.views.length > 0) {
this._selectPage(0);
}
},
_onPageNodeClick: function(p) {
this._selectPage(p);
},
_selectPage: function(p) {
if (this.pages.length > 1) {
query('.point', this.domNode).removeClass('point-selected');
html.addClass(this.pages[p].pointNode, 'point-selected');
}
this.viewStack.switchView(this.pages[p].pageNode);
},
createPageItems: function(page, pageNode, gridParam) {
var count, pageSize, i, b, e, empty;
count = this.items.length;
pageSize = gridParam.rows * gridParam.cols;
b = page * pageSize;
e = (page + 1) * pageSize;
empty = e - count;
e = Math.min(e, count);
for (i = b; i < e; i++) {
this.createItemNode(i, pageNode);
}
for (i = count; i < count + empty; i++) {
this.createEmptyItemNode(pageNode);
}
},
createItemNode: function(i, pageNode) {
var node, item;
item = this.items[i];
node = domConstruct.create('div', {
'class': 'icon-node jimu-float-leading jimu-main-background',
title: item.label,
settingId: item.id,
'data-widget-name': item.name
}, pageNode);
var imgNode = domConstruct.create('img', {
'src': item.icon
}, node);
if(window.isRTL && item.mirrorIconForRTL){
html.addClass(imgNode, 'jimu-flipx');
}
domConstruct.create('div', {
'class': 'node-label',
'title': item.label,
'innerHTML': utils.stripHTML(item.label)
}, node);
node.config = item;
this.own(on(node, 'click', lang.hitch(this, function() {
this.onNodeClicked(node);
})));
this.nodes.push(node);
},
createEmptyItemNode: function(pageNode) {
var node;
node = domConstruct.create('div', {
'class': 'icon-node jimu-float-leading jimu-main-background'
}, pageNode);
this.nodes.push(node);
return node;
},
createCloseBtn: function() {
var node;
node = domConstruct.create('div', {
'class': 'close'
}, this.domNode);
domConstruct.create('div', {
'class': 'close-inner jimu-main-background'
}, node);
on(node, 'click', lang.hitch(this, function() {
this.hide();
}));
return node;
},
hide: function() {
html.setStyle(this.domNode, 'display', 'none');
},
show: function() {
html.setStyle(this.domNode, 'display', 'block');
},
onNodeClicked: function(node) {
/* jshint unused: false*/
this.hide();
},
_calculateGridParam: function(){
var mapBox, minLen, position, rows, cols, cellSize, iconScaled = false,
showLabel = true;
mapBox = html.getContentBox(jimuConfig.mapId);
minLen = Math.min(mapBox.w, mapBox.h) - MIN_MARGIN * 2;
//calculate node width
if(minLen >= NORMAL_WIDTH * MIN_ROWCOL){
cellSize = NORMAL_WIDTH;
}else{
cellSize = Math.floor(minLen / MIN_ROWCOL);
if(cellSize < MIN_NODE_WIDTH){
return null;
}
iconScaled = true;
if(cellSize < NORMAL_MIN_WIDTH){
showLabel = false;
}
}
//calculate rows and columns
rows = Math.floor((mapBox.h - MIN_MARGIN * 2) / cellSize);
cols = Math.floor((mapBox.w - MIN_MARGIN * 2) / cellSize);
rows = rows > MAX_ROWCOL ? MAX_ROWCOL : rows;
cols = cols > MAX_ROWCOL ? MAX_ROWCOL : cols;
rows = rows < MIN_ROWCOL ? MIN_ROWCOL : rows;
cols = rows < MIN_ROWCOL ? MIN_ROWCOL : cols;
//calculate position
position = {
top: (mapBox.h - cellSize * rows) / 2,
bottom: (mapBox.h - cellSize * rows) / 2,
left: (mapBox.w - cellSize * cols) / 2,
right: (mapBox.w - cellSize * cols) / 2,
width: cellSize * cols - this.margin * (cols - 1) / 2,
height: cellSize * rows - this.margin * (rows - 1) / 2,
zIndex: 111
};
return {
rows: rows,
cols: cols,
cellSize: cellSize,
iconScaled: iconScaled,
showLabel: showLabel,
position: position
};
}
});
});