diff --git a/viewer/css/main.css b/viewer/css/main.css index 4e2ff08da..a2f48b753 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,45 @@ 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; } /* 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 4d2a724a3..bd1a37e02 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -206,6 +206,7 @@ define([ include: true, id: 'find', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Find', title: 'Find', open: false, @@ -216,6 +217,7 @@ define([ include: true, id: 'draw', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Draw', title: 'Draw', open: false, @@ -229,6 +231,7 @@ define([ include: true, id: 'measurement', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Measurement', title: 'Measurement', open: false, @@ -244,6 +247,7 @@ define([ include: true, id: 'print', type: 'titlePane', + canFloat: true, path: 'gis/dijit/Print', title: 'Print', open: false, @@ -308,6 +312,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..62f46f21b --- /dev/null +++ b/viewer/js/gis/dijit/FloatingTitlePane.js @@ -0,0 +1,118 @@ +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', + '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', { + title: 'Dock widget' + }, this.titleNode, 'after'); + domStyle.set(this.dockHandleNode, 'display', 'none'); + domClass.add(this.dockHandleNode, 'floatingWidgetDock'); + + 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(); + })); + } + 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); + }, + _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, { + w: (width - 32) + }, computedStyle); + domGeom.setContentSize(this.titleBarNode, { + w: (width - 32) + }, computedStyle); + this.isFloating = true; + 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/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 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 445f9ad93..7f15a9c87 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,14 @@ define([ 'dojo/_base/array', 'dijit/layout/BorderContainer', 'dijit/layout/ContentPane', - 'dijit/TitlePane', + 'gis/dijit/FloatingTitlePane', '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, win, lang, mapOverlay, config, IdentityManager, FloatingWidgetDialog) { return { config: config, @@ -177,15 +178,17 @@ define([ 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; }, @@ -196,7 +199,7 @@ define([ if (parentId) { options.id = parentId; } - var fw = new FloatingWidget(options); + var fw = new FloatingWidgetDialog(options); fw.startup(); return fw; }, @@ -214,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); }