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