From 8e022911a366efc935687816c2159e08c7a9553b Mon Sep 17 00:00:00 2001 From: David Spriggs Date: Wed, 9 Jul 2014 22:22:11 -0500 Subject: [PATCH 1/5] Added stash folder to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 172d85a22..0d8a38c47 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Folders to ignore dist node_modules +stash ################# ## Eclipse From 4a105c53fc958a52f5a534b106864929ecfc78da Mon Sep 17 00:00:00 2001 From: David Spriggs Date: Fri, 11 Jul 2014 01:40:48 -0500 Subject: [PATCH 2/5] Finished FloatingTitlePane.js class. --- viewer/css/main.css | 48 +++++----- viewer/index.html | 1 - viewer/js/config/viewer.js | 5 + viewer/js/gis/dijit/FloatingTitlePane.js | 94 +++++++++++++++++++ ...atingWidget.js => FloatingWidgetDialog.js} | 0 viewer/js/viewer/Controller.js | 34 ++++--- 6 files changed, 139 insertions(+), 43 deletions(-) create mode 100644 viewer/js/gis/dijit/FloatingTitlePane.js rename viewer/js/gis/dijit/{FloatingWidget.js => FloatingWidgetDialog.js} (100%) diff --git a/viewer/css/main.css b/viewer/css/main.css index 4e2ff08da..c4af8a70d 100644 --- a/viewer/css/main.css +++ b/viewer/css/main.css @@ -7,7 +7,6 @@ body, html { /*font-family: Tahoma;*/ font-size: 14px; } - .appHeader { background: url("../images/linen.jpg") repeat-x scroll left top transparent; height: 70px; @@ -15,14 +14,12 @@ body, html { padding: 0; width: 100%; } - .appHeader .headerLogo { float: left; left: 30px; position: relative; top: 8px; } - .appHeader .headerTitle { color: #FFFFFF; float: left; @@ -32,33 +29,28 @@ body, html { top: 15px; position: relative; } - .appHeader .subHeaderTitle { color: #CFCFCF; font-size: small; padding-left: 20px; } - .appHeader .search { float: left; left: 80px; position: relative; top: 18px; } - .appHeader .headerLinks { float: right; color: #FFFFFF; position: relative; top: 27px; right: 10px; - text-align:right; + text-align: right; } - .appHeader .headerLinks a { color: #FFFFFF; } - #borderContainer { position: absolute; top: 70px; @@ -67,7 +59,6 @@ body, html { right: 0; background-color: #FFFFFF } - #sidebar { width: 334px; padding: 4px; @@ -76,25 +67,20 @@ body, html { overflow-x: hidden; border-right: 1px solid #B5BCC7; } - #map { padding: 0; overflow: hidden; background: url("../images/noisy_grid.png") #fff; } - .HomeButton, .LocateButton { margin-bottom: 10px; } - .titlePaneBottomFix { margin-bottom: -1px; } - .titlePaneRightFix { margin-right: -1px; } - .sidebarCollapseButton { width: 16px; height: 25px; @@ -110,48 +96,56 @@ body, html { background-repeat: no-repeat; cursor: pointer; } - .sidebarCollapseButton.close { left: 342px; background-image: url("../images/close.png"); } - .sidebarCollapseButton.open { background-image: url("../images/open.png"); left: 0; } - .floatingWidget_underlay { - display:none + display: none } - #help_parent_underlay { - display:block; + display: block; +} +.floatingWidgetMove:before { + float: right; + margin-left: 10px; + content: "\f047"; + font-family: FontAwesome; +} +.floatingWidgetDock:before { + float: right; + content: "\f112"; + font-family: FontAwesome; } /* dbootstrap overrides*/ + .dbootstrap .dijitToolbar .dijitButtonContents { padding: 1px !important; } - .dbootstrap .dijitTitlePane { border: 1px solid #DDDDDD; margin-bottom: 2px; -webkit-border-radius: 4px; border-radius: 4px; } - .dbootstrap .dijitTitlePaneTitle { color: #666666 !important; border-bottom: none; padding: 8px 15px; background-color: #F5F5F5; } - -.dijitSliderBarContainerH{ - z-index: 0!important; +.dijitSliderBarContainerH { + z-index: 0 !important; } .dbootstrap .dijitTitlePaneContentInner { background-color: #FFFFFF; } -/* end dbootstrap overrides*/ \ No newline at end of file +.dbootstrap :focus { + outline: none !important; +} +/* end dbootstrap overrides*/ diff --git a/viewer/index.html b/viewer/index.html index 191f9b7a4..81e6a6524 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -3,7 +3,6 @@ Configurable Viewer - diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 2cc46e236..8013b2f40 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -205,6 +205,7 @@ define([ include: true, id: 'find', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Find', title: 'Find', open: false, @@ -215,6 +216,7 @@ define([ include: true, id: 'draw', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Draw', title: 'Draw', open: false, @@ -228,6 +230,7 @@ define([ include: true, id: 'measurement', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Measurement', title: 'Measurement', open: false, @@ -243,6 +246,7 @@ define([ include: true, id: 'print', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Print', title: 'Print', open: false, @@ -307,6 +311,7 @@ define([ include: true, id: 'streetview', type: 'titlePane', + canFloat: true, position: 9, path: 'gis/dijit/StreetView', title: 'Google Street View', diff --git a/viewer/js/gis/dijit/FloatingTitlePane.js b/viewer/js/gis/dijit/FloatingTitlePane.js new file mode 100644 index 000000000..a588570b4 --- /dev/null +++ b/viewer/js/gis/dijit/FloatingTitlePane.js @@ -0,0 +1,94 @@ +define([ + 'dojo/_base/declare', + 'dijit/TitlePane', + 'dijit/_Contained', + 'dojo/on', + 'dojo/_base/lang', + 'dojo/dnd/Moveable', + 'dojo/aspect', + 'dojo/_base/window', + 'dojo/window', + 'dojo/dom-geometry', + 'dojo/dom-style', + 'dojo/dom-construct', + 'dojo/dom-attr', + 'dojo/dom-class' +], function(declare, TitlePane, _Contained, on, lang, Moveable, aspect, win, winUtils, domGeom, domStyle, domConstruct, domAttr, domClass) { + return declare([TitlePane, _Contained], { + postCreate: function() { + if (this.canFloat) { + this.dockHandleNode = domConstruct.create('span', null, this.titleNode, 'after'); + domStyle.set(this.dockHandleNode, 'display', 'none'); + this.moveHandleNode = domConstruct.create('span', null, this.titleNode, 'after'); + domClass.add(this.dockHandleNode, 'floatingWidgetDock'); + domClass.add(this.moveHandleNode, 'floatingWidgetMove'); + on(this.moveHandleNode, 'click', function(evt) { + evt.stopImmediatePropagation(); + }); + on(this.dockHandleNode, 'click', lang.hitch(this, function(evt) { + this._dockWidget(); + evt.stopImmediatePropagation(); + })); + } + this.inherited(arguments); + }, + startup: function() { + this.index = this.getIndexInParent(); + if (this.titleBarNode && this.canFloat) { + this._moveable = new Moveable(this.domNode, { + handle: this.moveHandleNode + }); + aspect.after(this._moveable, 'onMoveStop', lang.hitch(this, '_endDrag'), true); + aspect.after(this._moveable, 'onFirstMove', lang.hitch(this, '_moveDom'), true); + } + this.inherited(arguments); + }, + _dockWidget: function() { + domAttr.remove(this.domNode, 'style'); + domStyle.set(this.dockHandleNode, 'display', 'none'); + this.placeAt(this.sidebar, this.index); + }, + _moveDom: function() { + domStyle.set(this.dockHandleNode, 'display', 'inline'); + var computedStyle = domStyle.getComputedStyle(this.containerNode); + var width = parseInt(domStyle.getComputedStyle(this.sidebar.containerNode).width, 10); + domGeom.setContentSize(this.containerNode, { + w: (width - 32) + }, computedStyle); + domGeom.setContentSize(this.titleBarNode, { + w: (width - 32) + }, computedStyle); + this.placeAt(win.body()); + }, + _endDrag: function() { + // summary: + // Called after dragging the Dialog. Saves the position of the dialog in the viewport, + // and also adjust position to be fully within the viewport, so user doesn't lose access to handle + var nodePosition = domGeom.position(this.domNode); + var viewport = winUtils.getBox(this.ownerDocument); + nodePosition.y = Math.min(Math.max(nodePosition.y, 0), (viewport.h - nodePosition.h)); + nodePosition.x = Math.min(Math.max(nodePosition.x, 0), (viewport.w - nodePosition.w)); + this._relativePosition = nodePosition; + this._position(); + }, + _position: function() { + // summary: + // Position the dialog in the viewport. If no relative offset + // in the viewport has been determined (by dragging, for instance), + // center the dialog. Otherwise, use the Dialog's stored relative offset, + // adjusted by the viewport's scroll. + if (!domClass.contains(this.ownerDocumentBody, 'dojoMove')) { // don't do anything if called during auto-scroll + var node = this.domNode, + viewport = winUtils.getBox(this.ownerDocument), + p = this._relativePosition, + bb = p ? null : domGeom.position(node), + l = Math.floor(viewport.l + (p ? p.x : (viewport.w - bb.w) / 2)), + t = Math.floor(viewport.t + (p ? p.y : (viewport.h - bb.h) / 2)); + domStyle.set(node, { + left: l + 'px', + top: t + 'px' + }); + } + } + }); +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/FloatingWidget.js b/viewer/js/gis/dijit/FloatingWidgetDialog.js similarity index 100% rename from viewer/js/gis/dijit/FloatingWidget.js rename to viewer/js/gis/dijit/FloatingWidgetDialog.js diff --git a/viewer/js/viewer/Controller.js b/viewer/js/viewer/Controller.js index bd7adc80c..52c70aca6 100644 --- a/viewer/js/viewer/Controller.js +++ b/viewer/js/viewer/Controller.js @@ -1,4 +1,5 @@ define([ + 'dojo/_base/declare', 'esri/map', 'dojo/dom', 'dojo/dom-construct', @@ -8,14 +9,15 @@ define([ 'dojo/_base/array', 'dijit/layout/BorderContainer', 'dijit/layout/ContentPane', - 'dijit/TitlePane', + 'gis/dijit/FloatingTitlePane', + 'dijit/_Contained', 'dojo/_base/window', 'dojo/_base/lang', 'dojo/text!./templates/mapOverlay.html', 'config/viewer', 'esri/IdentityManager', - 'gis/dijit/FloatingWidget' -], function(Map, dom, domConstruct, domStyle, domClass, on, array, BorderContainer, ContentPane, TitlePane, win, lang, mapOverlay, config, IdentityManager, FloatingWidget) { + 'gis/dijit/FloatingWidgetDialog' +], function(declare, Map, dom, domConstruct, domStyle, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, _Contained, win, lang, mapOverlay, config, IdentityManager, FloatingWidgetDialog) { return { config: config, @@ -169,22 +171,24 @@ define([ this.outer.resize(); } }, - positionSideBarToggle: function () { + positionSideBarToggle: function() { var disp = domStyle.get(this.sidebar.domNode, 'display'); var rCls = (disp === 'none') ? 'close' : 'open'; var aCls = (disp === 'none') ? 'open' : 'close'; domClass.remove(this.sideBarToggle, rCls); domClass.add(this.sideBarToggle, aCls); }, - _createTitlePaneWidget: function(title, position, open, parentId) { + _createTitlePaneWidget: function(title, position, open, canFloat, parentId) { var options = { - title: title, - open: open + title: title || 'Widget', + open: open || false, + canFloat: canFloat || false, + sidebar: this.sidebar }; if (parentId) { options.id = parentId; } - var tp = new TitlePane(options).placeAt(this.sidebar, position); + var tp = new FloatingTitlePane(options).placeAt(this.sidebar, position); tp.startup(); return tp; }, @@ -195,7 +199,7 @@ define([ if (parentId) { options.id = parentId; } - var fw = new FloatingWidget(options); + var fw = new FloatingWidgetDialog(options); fw.startup(); return fw; }, @@ -203,9 +207,9 @@ define([ var parentId, pnl; // only proceed for valid widget types - var widgetTypes = ['titlePane','floating','domNode','invisible','map']; + var widgetTypes = ['titlePane', 'floating', 'domNode', 'invisible', 'map']; if (array.indexOf(widgetTypes, widgetConfig.type) < 0) { - console.log('Widget type ' + widgetConfig.type + ' (' + widgetConfig.title + ') at position ' + position + ' is not supported.'); + console.log('Widget type ' + widgetConfig.type + ' (' + widgetConfig.title + ') at position ' + position + ' is not supported.'); return; } @@ -213,7 +217,7 @@ define([ if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'floating') && (widgetConfig.id && widgetConfig.id.length > 0)) { parentId = widgetConfig.id + '_parent'; if (widgetConfig.type === 'titlePane') { - pnl = this._createTitlePaneWidget(widgetConfig.title, position, widgetConfig.open, parentId); + pnl = this._createTitlePaneWidget(widgetConfig.title, position, widgetConfig.open, widgetConfig.canFloat, parentId); } else if (widgetConfig.type === 'floating') { pnl = this._createFloatingWidget(widgetConfig.title, parentId); } @@ -222,12 +226,12 @@ define([ // 2 ways to use require to accomodate widgets that may have an optional separate configuration file if (typeof(widgetConfig.options) === 'string') { - require([widgetConfig.options, widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig)); + require([widgetConfig.options, widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig)); } else { - require([widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig, widgetConfig.options)); + require([widgetConfig.path], lang.hitch(this, 'createWidget', widgetConfig, widgetConfig.options)); } }, - createWidget: function (widgetConfig, options, WidgetClass) { + createWidget: function(widgetConfig, options, WidgetClass) { // set any additional options options.id = widgetConfig.id + '_widget'; options.parentWidget = widgetConfig.parentWidget; From 47f7ab549df1d7f3afe69710f00e19b0f616407d Mon Sep 17 00:00:00 2001 From: David Spriggs Date: Sat, 12 Jul 2014 13:16:02 -0500 Subject: [PATCH 3/5] Fixed docking order issue. --- viewer/js/gis/dijit/FloatingTitlePane.js | 27 ++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/viewer/js/gis/dijit/FloatingTitlePane.js b/viewer/js/gis/dijit/FloatingTitlePane.js index a588570b4..7131b951c 100644 --- a/viewer/js/gis/dijit/FloatingTitlePane.js +++ b/viewer/js/gis/dijit/FloatingTitlePane.js @@ -46,19 +46,24 @@ define([ _dockWidget: function() { domAttr.remove(this.domNode, 'style'); domStyle.set(this.dockHandleNode, 'display', 'none'); - this.placeAt(this.sidebar, this.index); + var dockedWidgets = this.sidebar.getChildren(); + this.placeAt(this.sidebar, dockedWidgets.length); + this.isFloating = false; }, _moveDom: function() { - domStyle.set(this.dockHandleNode, 'display', 'inline'); - var computedStyle = domStyle.getComputedStyle(this.containerNode); - var width = parseInt(domStyle.getComputedStyle(this.sidebar.containerNode).width, 10); - domGeom.setContentSize(this.containerNode, { - w: (width - 32) - }, computedStyle); - domGeom.setContentSize(this.titleBarNode, { - w: (width - 32) - }, computedStyle); - this.placeAt(win.body()); + if (!this.isFloating) { + domStyle.set(this.dockHandleNode, 'display', 'inline'); + var computedStyle = domStyle.getComputedStyle(this.containerNode); + var width = parseInt(domStyle.getComputedStyle(this.sidebar.containerNode).width, 10); + domGeom.setContentSize(this.containerNode, { + w: (width - 32) + }, computedStyle); + domGeom.setContentSize(this.titleBarNode, { + w: (width - 32) + }, computedStyle); + this.isFloating = true; + this.placeAt(win.body()); + } }, _endDrag: function() { // summary: From 5eda72366d15a369e9963010adb51ff65ac12338 Mon Sep 17 00:00:00 2001 From: David Spriggs Date: Mon, 14 Jul 2014 15:28:22 -0500 Subject: [PATCH 4/5] Fixed some issues with floating TitlePanes and brook out css. --- viewer/css/main.css | 11 ------- viewer/js/gis/dijit/FloatingTitlePane.js | 33 +++++++++++++++---- .../css/FloatingTitlePane.css | 16 +++++++++ 3 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css diff --git a/viewer/css/main.css b/viewer/css/main.css index c4af8a70d..a2f48b753 100644 --- a/viewer/css/main.css +++ b/viewer/css/main.css @@ -110,17 +110,6 @@ body, html { #help_parent_underlay { display: block; } -.floatingWidgetMove:before { - float: right; - margin-left: 10px; - content: "\f047"; - font-family: FontAwesome; -} -.floatingWidgetDock:before { - float: right; - content: "\f112"; - font-family: FontAwesome; -} /* dbootstrap overrides*/ diff --git a/viewer/js/gis/dijit/FloatingTitlePane.js b/viewer/js/gis/dijit/FloatingTitlePane.js index 7131b951c..62f46f21b 100644 --- a/viewer/js/gis/dijit/FloatingTitlePane.js +++ b/viewer/js/gis/dijit/FloatingTitlePane.js @@ -12,19 +12,27 @@ define([ 'dojo/dom-style', 'dojo/dom-construct', 'dojo/dom-attr', - 'dojo/dom-class' -], function(declare, TitlePane, _Contained, on, lang, Moveable, aspect, win, winUtils, domGeom, domStyle, domConstruct, domAttr, domClass) { + 'dojo/dom-class', + 'xstyle/css!./FloatingTitlePane/css/FloatingTitlePane.css' +], function(declare, TitlePane, _Contained, on, lang, Moveable, aspect, win, winUtils, domGeom, domStyle, domConstruct, domAttr, domClass, css) { return declare([TitlePane, _Contained], { postCreate: function() { if (this.canFloat) { - this.dockHandleNode = domConstruct.create('span', null, this.titleNode, 'after'); + this.dockHandleNode = domConstruct.create('span', { + title: 'Dock widget' + }, this.titleNode, 'after'); domStyle.set(this.dockHandleNode, 'display', 'none'); - this.moveHandleNode = domConstruct.create('span', null, this.titleNode, 'after'); domClass.add(this.dockHandleNode, 'floatingWidgetDock'); - domClass.add(this.moveHandleNode, 'floatingWidgetMove'); - on(this.moveHandleNode, 'click', function(evt) { + + this.moveHandleNode = domConstruct.create('span', { + title: 'Move widget' + }, this.titleNode, 'after'); + domClass.add(this.moveHandleNode, 'floatingWidgetPopout'); + + on(this.moveHandleNode, 'click', lang.hitch(this, function(evt) { + this._undockWidget(); evt.stopImmediatePropagation(); - }); + })); on(this.dockHandleNode, 'click', lang.hitch(this, function(evt) { this._dockWidget(); evt.stopImmediatePropagation(); @@ -43,16 +51,27 @@ define([ } this.inherited(arguments); }, + _undockWidget: function() { + if (!this.isFloating) { + domClass.add(this.moveHandleNode, 'floatingWidgetMove'); + domClass.remove(this.moveHandleNode, 'floatingWidgetPopout'); + } + }, _dockWidget: function() { domAttr.remove(this.domNode, 'style'); domStyle.set(this.dockHandleNode, 'display', 'none'); var dockedWidgets = this.sidebar.getChildren(); this.placeAt(this.sidebar, dockedWidgets.length); + domClass.remove(this.moveHandleNode, 'floatingWidgetMove'); + domClass.add(this.moveHandleNode, 'floatingWidgetPopout'); this.isFloating = false; }, _moveDom: function() { if (!this.isFloating) { domStyle.set(this.dockHandleNode, 'display', 'inline'); + domStyle.set(this.domNode, 'z-index', '40'); + domClass.add(this.moveHandleNode, 'floatingWidgetMove'); + domClass.remove(this.moveHandleNode, 'floatingWidgetPopout'); var computedStyle = domStyle.getComputedStyle(this.containerNode); var width = parseInt(domStyle.getComputedStyle(this.sidebar.containerNode).width, 10); domGeom.setContentSize(this.containerNode, { diff --git a/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css b/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css new file mode 100644 index 000000000..92a0e0fa4 --- /dev/null +++ b/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css @@ -0,0 +1,16 @@ +.floatingWidgetMove:before { + float: right; + margin-left: 10px; + content: "\f047"; + font-family: FontAwesome; +} +.floatingWidgetDock:before { + float: right; + content: "\f112"; + font-family: FontAwesome; +} +.floatingWidgetPopout:before { + float: right; + content: "\f064"; + font-family: FontAwesome; +} \ No newline at end of file From f43781bedf89a3065c234074a60fa06c607c0b60 Mon Sep 17 00:00:00 2001 From: David Spriggs Date: Mon, 14 Jul 2014 15:32:52 -0500 Subject: [PATCH 5/5] Removed unused class. --- viewer/js/viewer/Controller.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/viewer/js/viewer/Controller.js b/viewer/js/viewer/Controller.js index 567b9b20e..7f15a9c87 100644 --- a/viewer/js/viewer/Controller.js +++ b/viewer/js/viewer/Controller.js @@ -10,14 +10,13 @@ define([ 'dijit/layout/BorderContainer', 'dijit/layout/ContentPane', 'gis/dijit/FloatingTitlePane', - 'dijit/_Contained', 'dojo/_base/window', 'dojo/_base/lang', 'dojo/text!./templates/mapOverlay.html', 'config/viewer', 'esri/IdentityManager', 'gis/dijit/FloatingWidgetDialog' -], function(declare, Map, dom, domConstruct, domStyle, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, _Contained, win, lang, mapOverlay, config, IdentityManager, FloatingWidgetDialog) { +], function(declare, Map, dom, domConstruct, domStyle, domClass, on, array, BorderContainer, ContentPane, FloatingTitlePane, win, lang, mapOverlay, config, IdentityManager, FloatingWidgetDialog) { return { config: config,