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 }; } }); });