diff --git a/.travis.yml b/.travis.yml index 88a5a983b..1d8421df7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ language: node_js node_js: -- '5' +- 'node' sudo: false before_install: npm install -g grunt-cli before_script: grunt build --verbose deploy: provider: releases api_key: - secure: RH6f8GbwwkXZvoxOS88NhOhEAfFHL52wQ9cadmzPTCnqNNVeC5GhAvwoNvBTobZhB+Jt0W9oVQt2WTnAomxC9cqh07fSqLBk8I8UpuhRkmL+AZPwnquDxD9Bi6yNAgwd5IQfMqP251Qlzfwe7ffL42yAsjGfJOoliZRvfQyKQho= + secure: PbeHwM34muUp/D+g9gbpBj/ABYtKRmPkgRpvSMl8zxFw/slFEoepA25komkh4QO1VGV5xGtUiIz8F6Rg+uhgWiid0F+GAxDjVc9NAUAeK9ONzKpo9H5f7JJrESBnEp06R6CVR/hVPN5v2UlKUJd2MoRYHKTM/GlnCY8/L+0j0bU= file: dist/viewer.zip on: tags: true diff --git a/README.md b/README.md index 4e1417eb2..5ccfd054d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # CMV The Configurable Map Viewer -[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/cmv/cmv-app.svg?branch=master)](https://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.2-brightgreen.svg?style=flat)](https://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/cmv/cmv-app.svg?branch=master)](https://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) ## Introduction [CMV](https://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](https://developers.arcgis.com/javascript/jsapi/3/), [ArcGIS Server](https://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. @@ -47,7 +47,7 @@ A [resource proxy](https://github.com/Esri/resource-proxy) may be required to ac ## Documentation: Use the [documentation](https://docs.cmv.io/) for getting started and guidance on configuring your application. The initial documentation is sparse. Please help make it better by contributing over at the [cmv documentation repo](https://github.com/cmv/cmv-docs). -[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.2-brightgreen.svg?style=flat)](https://docs.cmv.io/) ## Community We have a [gitter.im chat room](https://gitter.im/cmv/cmv-app). Come on by if you have questions. The community is very active and helpful. diff --git a/package.json b/package.json index a83a5b61f..6a9a15cb3 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,31 @@ { "name": "ConfigurableMapViewerCMV", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "author": "cmv.io - https://github.com/cmv/", "license": "MIT", "year": "2017", "homepage": "https://cmv.io/", "repository": "https://github.com/cmv/cmv-app/", "dependencies": { - "babel-eslint": "~7.1.1", + "babel-eslint": "~7.2.0", "csslint": "1.0.x", - "eslint": "~3.17.0", + "eslint": "~3.19.0", "grunt": "1.0.x", - "grunt-contrib-clean": "1.0.x", + "grunt-contrib-clean": "~1.1.0", "grunt-contrib-compress": "~1.4.1", "grunt-contrib-connect": "1.0.x", "grunt-contrib-copy": "1.0.x", "grunt-contrib-csslint": "~2.0.x", - "grunt-contrib-cssmin": "~2.0.0", - "grunt-contrib-uglify": "~2.2.0", + "grunt-contrib-cssmin": "~2.2.0", + "grunt-contrib-uglify": "~3.0.0", "grunt-contrib-watch": "1.0.x", "grunt-eslint": "19.0.x", - "grunt-newer": "1.2.x", + "grunt-newer": "~1.3.0", "grunt-open": "0.2.x", "grunt-postcss": "0.8.x", "body-parser": "~1.17.0", "proxypage": "*" }, - "engine": "node >= 4", + "engine": "node >= 6", "dojoBuild": "package.js" } diff --git a/viewer/css/cmv-theme-overrides.css b/viewer/css/cmv-theme-overrides.css index 55219bc4a..00401a31e 100644 --- a/viewer/css/cmv-theme-overrides.css +++ b/viewer/css/cmv-theme-overrides.css @@ -3,13 +3,13 @@ } .cmv .dijitTitlePane { - margin-bottom: 2px; background-color: #FFF; + margin-bottom: 2px; } .cmv .dijitTitlePaneTitle { - color: #666; background-color: #F5F5F5; + color: #666; } .cmv .dijitTitlePaneTitleOpen { @@ -25,13 +25,6 @@ outline: none !important; } -/* icons for the sidebar */ -.cmv .dijitTitlePane .dijitTitlePaneTitle .titlePaneIcon { - margin: 0 0 0 8px; - padding-top: 2px; -} -/* end custom icons */ - /* esri popup window overrides */ .cmv .esriPopup .sizer { @@ -41,32 +34,38 @@ .cmv .esriPopup .esriPopupWrapper { background-color: #FFFFFF; } + .cmv .esriPopup .attachmentsSection div { font-weight: bold; } + .cmv .esriPopup .contentPane table.attrTable { - width: 100%; border-collapse: collapse; + width: 100%; } + .cmv .esriPopup .contentPane table.attrTable td { padding: 2px; } + .cmv .esriPopup .contentPane table.attrTable td.attrName { - text-align: right; - font-weight: bold; color: #333333; - width: 40%; + font-weight: bold; padding-right: 5px; + text-align: right; + width: 40%; } + .cmv .esriPopup .contentPane table.attrTable td.attrValue { width: 60%; } + .cmv .esriPopup .contentPane table.attrTable tr { - vertical-align: top; border-bottom: 1px solid rgb(221, 221, 221); + vertical-align: top; } .cmv .esriPopup .contentPane table.attrTable tr:nth-child(odd) { - background-color: none; + background-color: transparent; } .cmv .esriPopup .contentPane table.attrTable tr:nth-child(even) { background-color: rgb(238, 238, 238); @@ -79,24 +78,23 @@ .cmv .esriPopupMobile { z-index: 999; } -.cmv .esriMobileNavigationBar { - background-color: #666666; - background: url("../images/linen.jpg") repeat-x scroll left top transparent; - color: #FFFFFF; -} + +.cmv .esriMobileNavigationBar, .cmv .esriPopupMobile .titlePane { - background-color: #666666; background: url("../images/linen.jpg") repeat-x scroll left top transparent; + background-color: #666666; color: #FFFFFF; } + .cmv .esriPopupMobile .pointer.bottom{ - background:url("../images/pointertop.png"); -webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -o-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } + +.cmv .esriPopupMobile .pointer.bottom, .cmv .esriPopupMobile .pointer.top { background:url("../images/pointertop.png"); } @@ -117,11 +115,12 @@ background-repeat: repeat-x; border: 1px solid #BBB; border-bottom: 1px solid #A8A8A8; - padding: 0px 12px; color: #000; letter-spacing: 0; + padding: 0 12px; text-transform: none; } + .cmv .simpleDirections .esriStopsGetDirections:before { content: '\f277'; font-family: 'FontAwesome'; @@ -156,9 +155,9 @@ background-image: -ms-linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-image: linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-repeat: repeat-x; - box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); - border-top-color: #444; border-color: #666; + border-top-color: #444; + box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); } @@ -185,11 +184,11 @@ } .flat .dijitTabContainerTop-tabs .dijitTabChecked:before { - height: 3px; background-color: #666; - top: -1px; + height: 3px; left: -1px; right: -1px; + top: -1px; } .flat .dijitTitlePaneTitle { @@ -209,20 +208,56 @@ border-top: none; } +.flat .dijitButton .dijitButtonNode .dijitIcon.fa, +.flat .dijitDropDownButton .dijitButtonNode .dijitIcon.fa, +.flat .dijitComboButton .dijitButtonNode .dijitIcon.fa { + margin-top: 4px; +} + +.flat .dijitButton .dijitButtonNode, +.flat .dijitDropDownButton .dijitButtonNode, +.flat .dijitComboButton .dijitButtonNode, +.flat .dijitToggleButton .dijitButtonNode, +.flat .dijitComboBox .dijitButtonNode, +.flat .dijitSpinnerButtonContainer.dijitButtonNode, +.flat .dijitSelect .dijitButtonNode { + background-color: #E6E6E6; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #e6e6e6)); + background-image: -webkit-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -moz-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -ms-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-repeat: repeat-x; + border-bottom-color: #A8A8A8; + border-color: #BBB; + padding: 4px 12px; +} + +.flat .dijitComboBox .dijitArrowButton, +.flat .dijitSelect .dijitArrowButton { + padding: 4px; +} + +.flat .dijitSpinner .dijitSpinnerButtonContainer { + padding: 0; +} + .flat .dijitButtonHover .dijitButtonNode, .flat .dijitDropDownButtonHover .dijitButtonNode, .flat .dijitComboButton .dijitButtonNodeHover, .flat .dijitComboButton .dijitDownArrowButtonHover, .flat .dijitToggleButtonHover .dijitButtonNode, .flat .dijitDropDownButtonActive .dijitButtonNode { - background-position: 0 -15px; - text-decoration: none; - transition: background-position 0.1s linear; - -moz-transition: background-position 0.1s linear; - -ms-transition: background-position 0.1s linear; - -o-transition: background-position 0.1s linear; - -webkit-transition: background-position 0.1s linear; + background-position: 0 -15px; + text-decoration: none; + transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -ms-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + -webkit-transition: background-position 0.1s linear; } + .flat .dijitButtonActive .dijitButtonNode, .flat .dijitComboButton .dijitButtonNodeActive, .flat .dijitToggleButtonActive .dijitButtonNode, @@ -235,11 +270,12 @@ background-image: -ms-linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-image: linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-repeat: repeat-x; - box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); - border-top-color: #444; border-color: #666; + border-top-color: #444; -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); + box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); } + .flat .dijitButtonDisabled .dijitButtonNode, .flat .dijitDropDownButtonDisabled .dijitButtonNode, .flat .dijitComboButtonDisabled .dijitButtonNode, @@ -247,24 +283,25 @@ .flat .dijitComboBoxDisabled .dijitButtonNode, .flat .dijitSpinnerDisabled .dijitButtonNode, .flat .dijitSelectDisabled .dijitButtonNode { - background-image: none; - box-shadow: none; - cursor: not-allowed; - filter: alpha(opacity=65); - opacity: 0.65; - -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=65); - -webkit-box-shadow: none; + background-image: none; + -webkit-box-shadow:none; + box-shadow: none; + cursor: not-allowed; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=65); + filter: alpha(opacity=65); + opacity: 0.65; } .flat .success .dijitButtonNode { background: #409843; - color: #FFF; border-color: #39883c; + color: #FFF; } + .flat .danger .dijitButtonNode { background: #e32d29; - color: #FFF; border-color: #d4201b; + color: #FFF; } .flat .dijitTextBoxHover, @@ -283,4 +320,4 @@ background-color: #999; } -/* end flat theme */ +/* end flat theme */ \ No newline at end of file diff --git a/viewer/css/main.css b/viewer/css/main.css index abf36af1f..29ddbce38 100644 --- a/viewer/css/main.css +++ b/viewer/css/main.css @@ -97,6 +97,31 @@ body, html { overflow: hidden; background: url("../images/noisy_grid.png") #fff; } +.cmv-widget { + position:absolute; + z-index:40; +} +.cmv-widget-mapinfo { + bottom: 0; + left: 0; +} +.cmv-widget-basemaps { + right: 20px; + top: 20px; +} +.cmv-widget-growler { + right: 20px; + top: 60px; + width: 250px; +} +.cmv-widgets-left { + left: 19px; + top: 87px; +} +.cmv-widget-geocoder { + left: 64px; + top: 20px; +} .panetop { border-top: 1px solid #B5BCC7; } diff --git a/viewer/index.html b/viewer/index.html index 6dbebc88c..687153790 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -11,7 +11,7 @@ Configurable Map Viewer - + @@ -50,7 +50,7 @@ - + diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index f83155e22..87061e9bb 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -34,9 +34,12 @@ 'viewer/_ConfigMixin', // manage the Configuration 'viewer/_LayoutMixin', // build and manage the Page Layout and User Interface 'viewer/_MapMixin', // build and manage the Map - 'viewer/_WidgetsMixin' // build and manage the Widgets + 'viewer/_WidgetsMixin', // build and manage the Widgets // 'viewer/_WebMapMixin' // for WebMaps + + 'viewer/_SidebarMixin' // for mobile sidebar + //'config/_customMixin' ], function ( @@ -46,9 +49,11 @@ _ConfigMixin, _LayoutMixin, _MapMixin, - _WidgetsMixin + _WidgetsMixin, // _WebMapMixin + + _SidebarMixin //_MyCustomMixin ) { @@ -61,6 +66,10 @@ // for the most part they are interchangeable, except _ConfigMixin // and _ControllerBase // + + // Mixin for Mobile Sidebar + _SidebarMixin, + _LayoutMixin, _WidgetsMixin, // _WebMapMixin, diff --git a/viewer/js/config/identify.js b/viewer/js/config/identify.js index a85fb35b1..7a6e81185 100644 --- a/viewer/js/config/identify.js +++ b/viewer/js/config/identify.js @@ -1,7 +1,8 @@ define([ 'dojo/i18n!./nls/main', - 'dojo/_base/lang' -], function (i18n, lang) { + 'dojo/_base/lang', + 'dojo/number' +], function (i18n, lang, number) { var linkTemplate = '{text}'; function directionsFormatter (noValue, attributes) { @@ -10,6 +11,7 @@ define([ text: 'Get Directions' }); } + return { map: true, mapClickMode: true, @@ -34,6 +36,22 @@ define([ // for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html identifies: { + cities: { + 0: { + fieldInfos: [{ + visible: true, + fieldName: 'CITY_NAME', + label: 'Name' + }, { + visible: true, + fieldName: 'POP', + label: 'Population', + formatter: function (value) { + return number.format(value); + } + }] + } + }, louisvillePubSafety: { 2: { title: i18n.identify.louisvillePubSafety.policeStation, diff --git a/viewer/js/config/nls/es/main.js b/viewer/js/config/nls/es/main.js index 47acf6117..fee18694a 100644 --- a/viewer/js/config/nls/es/main.js +++ b/viewer/js/config/nls/es/main.js @@ -44,6 +44,7 @@ define({ legend: 'Leyenda', locale: 'Lugar', print: 'Imprimir', + search: 'Buscar', streetview: 'Google Street View' } } diff --git a/viewer/js/config/nls/fr/main.js b/viewer/js/config/nls/fr/main.js index dbf7b877d..b95757dba 100644 --- a/viewer/js/config/nls/fr/main.js +++ b/viewer/js/config/nls/fr/main.js @@ -44,6 +44,7 @@ define({ legend: 'Légende', locale: 'Lieu', print: 'Impression', + search: 'Rechercher', streetview: 'Google StreetView' } } diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index d4e18302b..a1ca815cd 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -22,6 +22,7 @@ define({ }, viewer: { operationalLayers: { + cities: 'World Cities', damageAssessment: 'Damage Assessment', louisvillePubSafety: 'Louisville Public Safety', restaurants: 'Restaurants', @@ -45,6 +46,7 @@ define({ legend: 'Legend', locale: 'Locale', print: 'Print', + search: 'Search', streetview: 'Google Street View' } } diff --git a/viewer/js/config/nls/pt-br/main.js b/viewer/js/config/nls/pt-br/main.js index 3bb82f665..818970576 100644 --- a/viewer/js/config/nls/pt-br/main.js +++ b/viewer/js/config/nls/pt-br/main.js @@ -44,6 +44,7 @@ define({ legend: 'Legendas', locale: 'Localidade', print: 'Imprimir', + search: 'Pesquisar', streetview: 'Google Street View' } } diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 3bb82f665..818970576 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -44,6 +44,7 @@ define({ legend: 'Legendas', locale: 'Localidade', print: 'Imprimir', + search: 'Pesquisar', streetview: 'Google Street View' } } diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index d11dc7490..f91d67098 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -7,8 +7,9 @@ define([ 'esri/layers/ImageParameters', 'gis/plugins/Google', 'dojo/i18n!./nls/main', - 'dojo/topic' -], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters, GoogleMapsLoader, i18n, topic) { + 'dojo/topic', + 'dojo/sniff' +], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters, GoogleMapsLoader, i18n, topic, has) { // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; @@ -120,6 +121,18 @@ define([ pageTitle: i18n.viewer.titles.pageTitle }, + layout: { + /* possible options for sidebar layout: + true - always use mobile sidebar, false - never use mobile sidebar, + 'mobile' - use sidebar for phones and tablets, 'phone' - use sidebar for phones, + 'touch' - use sidebar for all touch devices, 'tablet' - use sidebar for tablets only (not sure why you'd do this?), + other feature detection supported by dojo/sniff and dojo/has- http://dojotoolkit.org/reference-guide/1.10/dojo/sniff.html + + default value is 'phone' + */ + //sidebar: 'phone' + }, + // user-defined layer types /* layerTypes: { @@ -156,19 +169,23 @@ define([ layerInfo: { title: i18n.viewer.operationalLayers.restaurants } + }, + layerControlLayerInfos: { + layerGroup: 'Grouped Feature Layers' } }, { type: 'feature', - url: 'https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', + url: 'https://sampleserver6.arcgisonline.com/ArcGIS/rest/services/SF311/FeatureServer/0', title: i18n.viewer.operationalLayers.sf311Incidents, options: { id: 'sf311Incidents', opacity: 1.0, - visible: true, + visible: false, outFields: ['req_type', 'req_date', 'req_time', 'address', 'district'], mode: 0 }, layerControlLayerInfos: { + layerGroup: 'Grouped Feature Layers', menu: [{ topic: 'hello', label: 'Say Hello Custom', @@ -224,6 +241,14 @@ define([ iconClass: 'fa fa-smile-o' }] } + }, { + type: 'dynamic', + url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/SampleWorldCities/MapServer', + title: i18n.viewer.operationalLayers.cities, + options: { + id: 'cities', + visible: false + } /* //examples of vector tile layers (beta in v3.15) }, { @@ -294,15 +319,18 @@ define([ }, search: { include: true, - type: 'domNode', + type: has('phone') ? 'titlePane' : 'domNode', path: 'esri/dijit/Search', srcNodeRef: 'geocoderButton', + title: i18n.viewer.widgets.search, + iconClass: 'fa-search', + position: 0, options: { map: true, visible: true, enableInfoWindow: false, - enableButtonMode: true, - expanded: false + enableButtonMode: has('phone') ? false : true, + expanded: has('phone') ? true : false } }, basemaps: { @@ -321,6 +349,7 @@ define([ title: i18n.viewer.widgets.identify, iconClass: 'fa-info-circle', open: false, + preload: true, position: 3, options: 'config/identify' }, @@ -372,7 +401,7 @@ define([ } }, overviewMap: { - include: true, + include: has('phone') ? false : true, id: 'overviewMap', type: 'map', path: 'esri/dijit/OverviewMap', @@ -552,7 +581,7 @@ define([ } }, editor: { - include: true, + include: has('phone') ? false : true, id: 'editor', type: 'titlePane', path: 'gis/dijit/Editor', @@ -605,24 +634,30 @@ define([ }, locale: { include: true, + type: has('phone') ? 'titlePane' : 'domNode', id: 'locale', - //type: 'titlePane', - //position: 0, - //open: true, - type: 'domNode', + position: 0, srcNodeRef: 'geocodeDijit', path: 'gis/dijit/Locale', title: i18n.viewer.widgets.locale, + iconClass: 'fa-flag', options: { - style: 'margin-left: 30px;' + style: has('phone') ? null : 'margin-left: 30px;' } }, help: { - include: true, + include: has('phone') ? false : true, id: 'help', type: 'floating', path: 'gis/dijit/Help', title: i18n.viewer.widgets.help, + iconClass: 'fa-info-circle', + paneOptions: { + draggable: false, + html: 'link'.replace('link', i18n.viewer.widgets.help), + domTarget: 'helpDijit', + style: 'height:345px;width:450px;' + }, options: {} } diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index 72a9dbbce..11d24d62c 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -44,7 +44,7 @@ define([ widgetsInTemplate: true, i18n: i18n, title: i18n.title, - + baseClass: 'basemapWidget', basemaps: {}, currentBasemap: null, mapStartBasemap: null, @@ -174,4 +174,4 @@ define([ } } }); -}); \ No newline at end of file +}); diff --git a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css index d35d4ec8c..27e7c4134 100644 --- a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css +++ b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css @@ -1,14 +1,26 @@ -.selectedIcon:before { - font-family: FontAwesome; - content: "\f046"; +.basemapWidget .selectedIcon:before { + font-family: FontAwesome; + content: "\f046"; } -.emptyIcon:before { - font-family: FontAwesome; - content: "\f096"; +.basemapWidget .emptyIcon:before { + font-family: FontAwesome; + content: "\f096"; } -.basemapsIcon:before { - font-family: FontAwesome; - content: "\f009"; -} \ No newline at end of file +.basemapWidget .basemapsIcon:before { + font-family: FontAwesome; + content: "\f009"; +} + + +/* condense dropdown on small screens */ + +@media (max-width: 768px) { + .cmv .map .basemapWidget .dijitDropDownButton .dijitButtonNode { + padding: 4px 8px; + } + .cmv .map .basemapWidget .dijitButtonText { + display: none; + } +} diff --git a/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html b/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html index fa8b65db1..637bf5056 100644 --- a/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html +++ b/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html @@ -1,4 +1,4 @@ -
+
${title} diff --git a/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css b/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css index 149b45b6c..ed17fc8d1 100644 --- a/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css +++ b/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css @@ -1,10 +1,16 @@ -.floatingWidgetDock:before { - float: right; +.dijitTitlePane .dijitTitlePaneTitle .titlePaneIcon { + margin: 0 0 0 8px; + padding-top: 2px; +} + +.dijitTitlePane .dijitTitlePaneTitle .floatingWidgetDock:before { content: "\f112"; + float: right; font-family: FontAwesome; } -.floatingWidgetPopout:before { - float: right; + +.dijitTitlePane .dijitTitlePaneTitle .floatingWidgetPopout:before { content: "\f064"; + float: right; font-family: FontAwesome; } \ No newline at end of file diff --git a/viewer/js/gis/dijit/FloatingWidgetDialog.js b/viewer/js/gis/dijit/FloatingWidgetDialog.js index 42a0170fa..ee25613ca 100644 --- a/viewer/js/gis/dijit/FloatingWidgetDialog.js +++ b/viewer/js/gis/dijit/FloatingWidgetDialog.js @@ -1,13 +1,30 @@ define([ 'dojo/_base/declare', - 'dijit/Dialog' -], function (declare, Dialog) { + 'dijit/Dialog', + 'dojo/_base/lang', + 'dojo/on', + 'dojo/dom-construct', + + 'xstyle/css!./FloatingWidgetDialog/css/FloatingWidgetDialog.css' +], function (declare, Dialog, lang, on, domConstruct) { return declare([Dialog], { declaredClass: 'gis.dijit.FloatingWidget', title: 'Floating Widget', draggable: true, 'class': 'floatingWidget', + postCreate: function () { + if (this.iconClass) { + this.iconNode = domConstruct.create('span', { + 'class': 'titlePaneIcon fa fa-fw ' + this.iconClass + }, this.titleNode, 'before'); + } + if (this.html && this.domTarget) { + var link = domConstruct.place(this.html, this.domTarget); + this.own(on(link, 'click', lang.hitch(this, 'show'))); + } + this.inherited(arguments); + }, close: function () { this.hide(); }, diff --git a/viewer/js/gis/dijit/FloatingWidgetDialog/css/FloatingWidgetDialog.css b/viewer/js/gis/dijit/FloatingWidgetDialog/css/FloatingWidgetDialog.css new file mode 100644 index 000000000..0947a7266 --- /dev/null +++ b/viewer/js/gis/dijit/FloatingWidgetDialog/css/FloatingWidgetDialog.css @@ -0,0 +1,3 @@ +.dijitDialogTitleBar .titlePaneIcon { + margin: 0 4px 0 0; +} \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help.js b/viewer/js/gis/dijit/Help.js index 461a374d1..5375d3b03 100644 --- a/viewer/js/gis/dijit/Help.js +++ b/viewer/js/gis/dijit/Help.js @@ -4,8 +4,6 @@ define([ 'dijit/_TemplatedMixin', 'dijit/_WidgetsInTemplateMixin', 'gis/dijit/_FloatingWidgetMixin', - 'dojo/dom-construct', - 'dojo/on', 'dojo/_base/lang', 'dojo/aspect', 'dojo/text!./Help/templates/HelpDialog.html', @@ -14,26 +12,19 @@ define([ 'dijit/layout/TabContainer', 'dijit/layout/ContentPane', 'xstyle/css!./Help/css/Help.css' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, domConstruct, on, lang, aspect, template, i18n) { +], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, lang, aspect, template, i18n) { return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], { widgetsInTemplate: true, templateString: template, i18n: i18n, - html: 'link'.replace('link', i18n.link), - domTarget: 'helpDijit', - draggable: false, baseClass: 'helpDijit', postCreate: function () { this.inherited(arguments); - this.parentWidget.draggable = this.draggable; if (this.parentWidget.toggleable) { this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { this.containerNode.resize(); }))); - } else { - var help = domConstruct.place(this.html, this.domTarget); - on(help, 'click', lang.hitch(this.parentWidget, 'show')); } }, onOpen: function () { diff --git a/viewer/js/gis/dijit/Help/css/Help.css b/viewer/js/gis/dijit/Help/css/Help.css index 5900f2ba1..d153d3176 100644 --- a/viewer/js/gis/dijit/Help/css/Help.css +++ b/viewer/js/gis/dijit/Help/css/Help.css @@ -1,21 +1,21 @@ -.helpDijit .listdbootstrapFix{ +.helpDijit .listdbootstrapFix { padding: 0 0 0 25px; } .helpDijit .helpContainer { - padding: 0px; + padding: 0; } + .floatingWidget .helpDijit .helpContainer { padding: 5px; } + .helpDijit .helpNode { - width: 98%; - height: 325px; -} -.floatingWidget .helpDijit .helpNode { - width: 450px; + height:280px; + width: 100%; } + .helpDijit .helpTabContainer { - width: 100%; height: 100%; + width: 100%; } \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help/nls/es/resource.js b/viewer/js/gis/dijit/Help/nls/es/resource.js index 6c4cea412..3f80ea63d 100644 --- a/viewer/js/gis/dijit/Help/nls/es/resource.js +++ b/viewer/js/gis/dijit/Help/nls/es/resource.js @@ -1,5 +1,4 @@ define ({ - link: 'Ayuda', navigation: { title: 'Navegación', description: 'Mapa de navegación a través del ratón y el teclado:', diff --git a/viewer/js/gis/dijit/Help/nls/fr/resource.js b/viewer/js/gis/dijit/Help/nls/fr/resource.js index 6bda3e07f..719cc48f9 100644 --- a/viewer/js/gis/dijit/Help/nls/fr/resource.js +++ b/viewer/js/gis/dijit/Help/nls/fr/resource.js @@ -1,5 +1,4 @@ define ({ - link: 'Aide', navigation: { title: 'Navigation', description: 'Navigation dans la carte en utilisant la souris et le clavier:', diff --git a/viewer/js/gis/dijit/Help/nls/pt-br/resource.js b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js index 2793d85a8..8dc3218cd 100644 --- a/viewer/js/gis/dijit/Help/nls/pt-br/resource.js +++ b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js @@ -1,5 +1,4 @@ define({ - link: 'Ajuda', navigation: { title: 'Navegação', description: 'Navegação no mapa usando o rato e o teclado', diff --git a/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js index 2793d85a8..8dc3218cd 100644 --- a/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js @@ -1,5 +1,4 @@ define({ - link: 'Ajuda', navigation: { title: 'Navegação', description: 'Navegação no mapa usando o rato e o teclado', diff --git a/viewer/js/gis/dijit/Help/nls/resource.js b/viewer/js/gis/dijit/Help/nls/resource.js index 137c491ff..f7816fc9c 100644 --- a/viewer/js/gis/dijit/Help/nls/resource.js +++ b/viewer/js/gis/dijit/Help/nls/resource.js @@ -1,6 +1,5 @@ define({ root: { - link: 'Help', navigation: { title: 'Navigation', description: 'Map navigation using mouse and keyboard:', diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js index ccae23bc5..50efe59f5 100644 --- a/viewer/js/gis/dijit/Identify.js +++ b/viewer/js/gis/dijit/Identify.js @@ -397,7 +397,7 @@ define([ getInfoTemplate: function (layer, layerId, result) { var popup, config; if (result) { - layerId = result.layerId || layer.layerId; + layerId = typeof result.layerId === 'number' ? result.layerId : layer.layerId; } else if (layerId === null) { layerId = layer.layerId; } diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 4a8f14098..bce4c9fbf 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -33,14 +33,15 @@ define([ map: null, layerInfos: [], icons: { - expand: 'fa-caret-right', - collapse: 'fa-caret-down', - checked: 'fa-check-square-o', - unchecked: 'fa-square-o', - update: 'fa-refresh', - menu: 'fa-bars', - folder: 'fa-folder-o', - folderOpen: 'fa-folder-open-o' + expand: 'fa-caret-right fa-fw layerControlIcon-Expand', + collapse: 'fa-caret-down fa-fw layerControlIcon-Collapse', + checked: 'fa-check fa-fw fa-border layerControlIcon-Checked', + unchecked: 'fa-square fa-fw fa-border layerControlIcon-Unchecked', + indeterminate: 'fa-minus fa-fw fa-border layerControlIcon-Indeterminate', + update: 'fa-refresh layerControlIcon-Update', + menu: 'fa-bars layerControlIcon-Menu', + folder: 'fa-folder-o fa-fw layerControlIcon-Folder', + folderOpen: 'fa-folder-open-o fa-fw layerControlIcon-Folder layerControlIcon-FolderOpen' }, separated: false, overlayReorder: false, @@ -61,6 +62,7 @@ define([ _overlayContainer: null, _swiper: null, _swipeLayerToggleHandle: null, + _groupedLayerInfos: {}, _controls: { dynamic: './LayerControl/controls/Dynamic', feature: './LayerControl/controls/Feature', @@ -75,7 +77,10 @@ define([ webtiled: './LayerControl/controls/WebTiled', imagevector: './LayerControl/controls/ImageVector', raster: './LayerControl/controls/Raster', - stream: './LayerControl/controls/Stream' + stream: './LayerControl/controls/Stream', + grouped: './LayerControl/controls/Grouped', + graphics: './LayerControl/controls/Graphics', + osm: './LayerControl/controls/OpenStreetMap' }, constructor: function (options) { options = options || {}; @@ -137,11 +142,17 @@ define([ var modules = []; // push layer control mods array.forEach(layerInfos, function (layerInfo) { + layerInfo.controlOptions = layerInfo.controlOptions || {}; // check if control is excluded var controlOptions = layerInfo.controlOptions; - if (controlOptions && controlOptions.exclude === true) { + if (controlOptions.exclude === true) { return; } + // if layerGroups are used, disallow re-ordering + if (controlOptions.layerGroup) { + this.overlayReorder = false; + this.vectorReorder = false; + } var mod = this._controls[layerInfo.type]; if (mod) { modules.push(mod); @@ -157,7 +168,7 @@ define([ array.forEach(layerInfos, function (layerInfo) { // exclude from widget var controlOptions = layerInfo.controlOptions; - if (controlOptions && controlOptions.exclude === true) { + if (controlOptions.exclude === true) { return; } var control = this._controls[layerInfo.type]; @@ -165,6 +176,33 @@ define([ require([control], lang.hitch(this, '_addControl', layerInfo)); } }, this); + + for (var key in this._groupedLayerInfos) { + if (this._groupedLayerInfos.hasOwnProperty(key)) { + var layerDetails = this._groupedLayerInfos[key]; + if (layerDetails && layerDetails.length > 1) { + var control = this._controls.grouped; + var layerInfo = { + title: key, + type: 'grouped', + controlOptions: {}, + layer: { + id: key.replace(/\s/g, ''), + loaded: true, + getMap: lang.hitch(this, function () { + return this.map; + }), + minScale: 0, + maxScale: 0, + _params: {} + }, + layerDetails: layerDetails + }; + require([control], lang.hitch(this, '_addControl', layerInfo)); + } + } + } + this._checkReorder(); })); }, @@ -203,7 +241,7 @@ define([ // create layer control and add to appropriate _container _addControl: function (layerInfo, Control) { var layer = (typeof layerInfo.layer === 'string') ? this.map.getLayer(layerInfo.layer) : layerInfo.layer; - if (layerInfo.controlOptions && (layerInfo.type === 'dynamic' || layerInfo.type === 'feature')) { + if (layerInfo.type === 'dynamic' || layerInfo.type === 'feature') { if (layer.loaded) { this._applyLayerControlOptions(layerInfo.controlOptions, layer); } else { @@ -214,6 +252,7 @@ define([ controller: this, layer: layer, layerTitle: layerInfo.title, + layerDetails: layerInfo.layerDetails, controlOptions: lang.mixin({ noLegend: null, noZoom: null, @@ -221,14 +260,21 @@ define([ swipe: null, expanded: false, sublayers: true, + layerGroup: null, menu: this.menu[layerInfo.type], subLayerMenu: this.subLayerMenu[layerInfo.type] }, layerInfo.controlOptions) }); layerControl.startup(); var position = layerInfo.position || 0; + var layerType = layerControl._layerType; + if (layerType === 'grouped') { + if (layerControl.layerDetails && layerControl.layerDetails.length > 0) { + layerControl._layerType = layerControl.layerDetails[0].layerControl._layerType; + } + } if (this.separated) { - if (layerControl._layerType === 'overlay') { + if (layerType === 'overlay') { this._overlayContainer.addChild(layerControl, position); } else { this._vectorContainer.addChild(layerControl, position); @@ -236,6 +282,22 @@ define([ } else { this.addChild(layerControl, position); } + this._storeGroupedLayerInfo(layerInfo, layerControl); + }, + _storeGroupedLayerInfo: function (layerInfo, layerControl) { + if (!layerInfo.controlOptions.layerGroup) { + // Not a grouped layer + return; + } + var layerGroup = layerInfo.controlOptions.layerGroup; + if (!this._groupedLayerInfos.hasOwnProperty(layerGroup)) { + this._groupedLayerInfos[layerGroup] = []; + } + + this._groupedLayerInfos[layerGroup].push({ + layerInfo: layerInfo, + layerControl: layerControl + }); }, _applyLayerControlOptions: function (controlOptions, layer) { if (typeof controlOptions.includeUnspecifiedLayers === 'undefined' && typeof controlOptions.subLayerInfos === 'undefined' && typeof controlOptions.excludedLayers === 'undefined') { diff --git a/viewer/js/gis/dijit/LayerControl/controls/Graphics.js b/viewer/js/gis/dijit/LayerControl/controls/Graphics.js new file mode 100644 index 000000000..080049563 --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/Graphics.js @@ -0,0 +1,24 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control' // layer control base class +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control +) { + + var GraphicsControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + _layerType: 'vector', // constant + _esriLayerType: 'graphics', // constant + _layerTypeInit: function () { + this._expandRemove(); + // legend or no legend??? + } + }); + return GraphicsControl; +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/controls/Grouped.js b/viewer/js/gis/dijit/LayerControl/controls/Grouped.js new file mode 100644 index 000000000..707d1d480 --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/Grouped.js @@ -0,0 +1,158 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/_base/array', + 'dojo/on', + 'dojo/topic', + 'dojo/html', + 'dojo/dom-class', + 'dojo/dom-style', + 'dojo/dom-construct', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control' // layer control base class +], function ( + declare, + lang, + array, + on, + topic, + html, + domClass, + domStyle, + domConstruct, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control +) { + var GroupedControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + layerDetails: null, + _layerType: 'grouped', // constant + _esriLayerType: null, // constant + + // create and legend + _layerTypePreInit: function () { + array.forEach(this.layerDetails, lang.hitch(this, function (layerDetail) { + domConstruct.place(layerDetail.layerControl.domNode, this.expandNode, 'first'); + })); + }, + + _layerTypeInit: function () { + this._expandClick(); + }, + + hasAnyVisibleLayer: function () { + return array.some(this.layerDetails, function (layerDetail) { + return layerDetail.layerInfo.layer.visible; + }); + }, + + hasAnyInvisibleLayer: function () { + return array.some(this.layerDetails, function (layerDetail) { + return !layerDetail.layerInfo.layer.visible; + }); + }, + + _initialize: function () { + // an optional function in each control widget called before widget init + if (this._layerTypePreInit) { + this._layerTypePreInit(); + } + var layer = this.layer, + controlOptions = this.controlOptions, + layerDetails = this.layerDetails; + + // set checkbox + this._setLayerCheckbox(layer, this.checkNode); + + // wire up layer visibility + on(this.checkNode, 'click', lang.hitch(this, '_setLayerVisibility', layerDetails, this.checkNode)); + + // set title + html.set(this.labelNode, this.layerTitle); + + // create layer menu + domClass.remove(this.menuNode, 'fa, layerControlMenuIcon, ' + this.icons.menu); + domStyle.set(this.menuClickNode, 'cursor', 'default'); + + // if layer has scales set + if (layer.minScale !== 0 || layer.maxScale !== 0) { + this._checkboxScaleRange(); + this._scaleRangeHandler = layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); + } + + // a function in each control widget for layer type specifics like legends and such + this._layerTypeInit(); + + // show expandNode + // no harm if click handler wasn't created + if (controlOptions.expanded) { + this.expandClickNode.click(); + } + + topic.subscribe('layerControl/layerToggle', lang.hitch(this, function (options) { + if (options.params && !options.forced && options.id !== layer.id && options.params.groupID === this.layerTitle) { + var layerVisible = this.layer.visible; + if (layerVisible && !this.hasAnyVisibleLayer()) { + this.toggleVisibility(); + } else if (!layerVisible && !this.hasAnyInvisibleLayer()) { + this.toggleVisibility(); + } + } + this._setLayerCheckbox(); + })); + }, + + toggleVisibility: function () { + var layer = this.layer; + layer.visible = !layer.visible; + if (this.hasAnyVisibleLayer() && this.hasAnyInvisibleLayer()) { + layer.visible = true; + } + this._setLayerCheckbox(layer, this.checkNode); + topic.publish('layerControl/layerToggle', { + id: layer.id, + visible: layer.visible, + forced: true + }); + }, + + _setLayerVisibility: function (layerDetails, checkNode, event) { + this.toggleVisibility(); + + var _arguments = arguments; + // Calls _setLayerVisibility for each grouped layer + array.forEach(layerDetails, lang.hitch(this, function (layerDetail) { + if (this.layer.visible !== layerDetail.layerInfo.layer.visible) { + this.inherited(_arguments, [layerDetail.layerInfo.layer, layerDetail.layerControl.checkNode, event]); + } + })); + this._setLayerCheckbox(); + }, + + // overrides the method in _Control + _setLayerCheckbox: function () { + var checkNode = this.checkNode, + i = this.icons; + + domClass.remove(checkNode, i.checked); + domClass.remove(checkNode, i.unchecked); + domClass.remove(checkNode, i.indeterminate); + + var hasVisible = this.hasAnyVisibleLayer(); + var hasHidden = this.hasAnyInvisibleLayer(); + + // indeterminate - both visible and invisible layers in group + if (hasVisible && hasHidden) { + domClass.add(checkNode, i.indeterminate); + } else if (hasVisible) { + domClass.add(checkNode, i.checked); + } else { + domClass.add(checkNode, i.unchecked); + } + } + }); + return GroupedControl; +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/controls/OpenStreetMap.js b/viewer/js/gis/dijit/LayerControl/controls/OpenStreetMap.js new file mode 100644 index 000000000..6846f474d --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/OpenStreetMap.js @@ -0,0 +1,23 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control' // layer control base class +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control +) { + + var OpenStreetMapControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + _layerType: 'overlay', // constant + _esriLayerType: 'osm', // constant + _layerTypeInit: function () { + this._expandRemove(); + } + }); + return OpenStreetMapControl; +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js index 58e7f6179..229a5e33c 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js @@ -177,14 +177,16 @@ define([ layer.hide(); topic.publish('layerControl/layerToggle', { id: layer.id, - visible: layer.visible + visible: layer.visible, + params: layer._params }); } else { this._setLayerCheckbox(layer, checkNode); layer.show(); topic.publish('layerControl/layerToggle', { id: layer.id, - visible: layer.visible + visible: layer.visible, + params: layer._params }); } if (layer.minScale !== 0 || layer.maxScale !== 0) { diff --git a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css index c3fa09b4e..e50621c76 100644 --- a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css +++ b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css @@ -1,13 +1,8 @@ .layerControlDijit .vectorLayerContainer {} -.layerControlDijit .vectorLabelContainer { - font-size: 15px; - font-weight: 600; - padding-bottom: 4px; -} - .layerControlDijit .overlayLayerContainer {} +.layerControlDijit .vectorLabelContainer, .layerControlDijit .overlayLabelContainer { font-size: 15px; font-weight: 600; @@ -31,43 +26,32 @@ } .layerControlDijit .layerControlTable tr { - vertical-align: middle; + vertical-align: top; } .layerControlDijit .layerControlTable td { padding: 0; } -.layerControlDijit .layerControlTableExpand { +.layerControlDijit .layerControlTableExpand, +.layerControlDijit .layerControlTableCheck, +.layerControlDijit .layerControlTableMenu, +.layerControlDijit .layerControlTableLabel { cursor: pointer; - width: 18px; - height: 15px; - line-height: 15px; } -.layerControlDijit .layerControlTableCheck, .layerControlDijit .layerControlTableMenu { - cursor: pointer; - width: 19px; - height: 16px; - line-height: 16px; +.layerControlDijit .layerControlTableExpand, +.layerControlDijit .layerControlTableCheck, +.layerControlDijit .layerControlTableMenu, +.layerControlDijit .layerControlTableUpdate { + text-align: center; } .layerControlDijit .layerControlTableLabel { - cursor: pointer; font-size: 15px; - height: 16px; line-height: 16px; -} - -.layerControlDijit .layerControlTableMenu { - cursor: pointer; -} - -.layerControlDijit .layerControlTableUpdate { - width: 21px; - height: 16px; - line-height: 16px; - text-align: center; + padding-top: 2px; + width: 100%; } .layerControlDijit .layerControlHidden { @@ -79,27 +63,79 @@ } .layerControlDijit .layerControlIndent { - padding-left: 22px; + padding-left: 20px; } .layerControlDijit .layerControlIcon { - font-size: 17px; + font-size: 18px; + margin-right: 4px; +} + +.layerControlDijit .layerControlTableExpand .layerControlIcon { + margin-right: 0; + width: 1em; +} + +.layerControlDijit .layerControlIndent .layerControlTableExpand .layerControlIcon { + margin-right: 4px; +} + +.layerControlDijit .layerControlIndent .layerControlIndent .layerControlTableExpand .layerControlIcon, +.layerControlDijit .layerControlSublayer .layerControlTableExpand .layerControlIcon { + margin-left: 4px; + margin-right: 4px; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon { + font-size: 12px; + height: 13px; + width: 13px; +} + +.layerControlDijit .layer-folder { + color: #666; +} + +.layerControlDijit .layerControlTableCheck .fa-border { + border-color: #333; + border-radius: 3px; + padding: 0.15em 0.1875em 0.1125em; +} + + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Folder { + color: #333; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Checked { + color: #090; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Unchecked:before { + color: transparent; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Indeterminate { + color: #666; } .layerControlDijit .layerControlUpdateIcon { + color: #666; font-size: 12px; } .layerControlDijit .layerControlMenuIcon { font-size: 15px; color: #666; + margin-left: 4px; } .layerControlDijit .layerControlMenuIcon:hover { color: #111; } -.layerControlDijit .layerControlCheckIconOutScale { +.layerControlDijit .layerControlTableCheck .layerControlCheckIconOutScale { + border-color: #BBB; color: #BBB; } @@ -120,6 +156,10 @@ text-decoration: underline; } +.layerControlDijit .layerControlLegendTable { + margin: 4px 0; +} + .layerControlDijit .layerControlLegendTable tr { vertical-align: middle; } @@ -151,7 +191,7 @@ /* sublayer menu */ .layerControlDijit .layerControlSublayer .layerControlTable td.layerControlTableMenu { - padding-right: 20px; + padding-right: 16px; } .layerControlDijit .menuClickNode.hidden { diff --git a/viewer/js/gis/dijit/Print.js b/viewer/js/gis/dijit/Print.js index 7fa56891f..8f2262608 100644 --- a/viewer/js/gis/dijit/Print.js +++ b/viewer/js/gis/dijit/Print.js @@ -216,6 +216,7 @@ define([ template.format = form.format; template.layout = form.layout; template.preserveScale = eval(form.preserveScale); //turns a string 'true' into true + template.outScale = form.outScale; template.label = form.title; template.exportOptions = mapOnlyForm; template.layoutOptions = { diff --git a/viewer/js/gis/dijit/Print/templates/Print.html b/viewer/js/gis/dijit/Print/templates/Print.html index c8ed5cdab..453c6c9a1 100644 --- a/viewer/js/gis/dijit/Print/templates/Print.html +++ b/viewer/js/gis/dijit/Print/templates/Print.html @@ -52,6 +52,14 @@ ${i18n.mapExtent} + + + ${i18n.mapScale}: + + + + +
diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index a9dc90a0f..64650cdfc 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -73,6 +73,10 @@ define([ this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { this.onLayoutChange(this.parentWidget.open); }))); + + // trigger layout change since parentWidget might + // already be open + this.onLayoutChange(this.parentWidget.open); } this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); diff --git a/viewer/js/viewer/_LayoutMixin.js b/viewer/js/viewer/_LayoutMixin.js index 4940098d1..8d857c58e 100644 --- a/viewer/js/viewer/_LayoutMixin.js +++ b/viewer/js/viewer/_LayoutMixin.js @@ -63,6 +63,12 @@ define([ } }, collapseButtons: {}, + + loadConfig: function () { + this.detectTouchDevices(); + return this.inherited(arguments); + }, + postConfig: function () { this.layoutDeferred = new Deferred(); return this.inherited(arguments); @@ -73,7 +79,7 @@ define([ this.addTopics(); this.addTitles(); - this.detectTouchDevices(); + this.setPhoneInfoWindow(); this.initPanes(); this.mapDeferred.then(lang.hitch(this, 'createPanes')); @@ -321,7 +327,6 @@ define([ this.positionSideBarToggle(id); }, - // simple feature detection. kinda like dojox/mobile without the overhead detectTouchDevices: function () { if (has('touch') && (has('ios') || has('android') || has('bb'))) { has.add('mobile', true); @@ -330,11 +335,13 @@ define([ } else { has.add('tablet', true); } + } + }, - // use the mobile popup for phones - if (has('phone') && !this.config.mapOptions.infoWindow) { - this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); - } + setPhoneInfoWindow: function () { + // use the mobile popup for phones + if (has('phone') && !this.config.mapOptions.infoWindow) { + this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); } } diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index 71e658d0a..3d26795b4 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -109,10 +109,10 @@ define([ dynamic: 'esri/layers/ArcGISDynamicMapServiceLayer', feature: 'esri/layers/FeatureLayer', georss: 'esri/layers/GeoRSSLayer', + graphics: 'esri/layers/GraphicsLayer', image: 'esri/layers/ArcGISImageServiceLayer', imagevector: 'esri/layers/ArcGISImageServiceVectorLayer', kml: 'esri/layers/KMLLayer', - label: 'esri/layers/LabelLayer', //untested mapimage: 'esri/layers/MapImageLayer', //untested osm: 'esri/layers/OpenStreetMapLayer', raster: 'esri/layers/RasterLayer', diff --git a/viewer/js/viewer/_SidebarMixin.js b/viewer/js/viewer/_SidebarMixin.js new file mode 100644 index 000000000..056371458 --- /dev/null +++ b/viewer/js/viewer/_SidebarMixin.js @@ -0,0 +1,119 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/dom', + 'dojo/sniff', + 'dojo/Deferred', + 'module', + + 'put-selector' + +], function ( + declare, + lang, + dom, + has, + Deferred, + module, + + put, + + Sidebar +) { + + return declare(null, { + + postConfig: function () { + this.config.layout = this.config.layout || {}; + this._checkForSidebarLayout(); + + if (this.config.layout.sidebar) { + this.inherited(arguments); + this.config.panes = this.mixinDeep(this.config.panes || {}, { + left: { + collapsible: false, + style: 'display:none !important' + } + }); + var deferred = new Deferred(); + require([ + 'viewer/sidebar/Sidebar' + ], lang.hitch(this, function (sidebar) { + Sidebar = sidebar; + this.mapDeferred.then(lang.hitch(this, '_createSidebar')); + deferred.resolve(); + })); + return deferred; + } + return this.inherited(arguments); + }, + + _checkForSidebarLayout: function () { + var sidebar = this.config.layout.sidebar; + + switch (sidebar) { + // all devices + case true: + break; + + // no devices + case false: + break; + + // tablets and phones + case 'mobile': + if (has('mobile')) { + sidebar = true; + } + break; + + // phones + case 'phone': + if (has('phone')) { + sidebar = true; + } + break; + default: + // perhaps they've configured something we don't expect + if (typeof(sidebar) === 'string') { + if (has(sidebar)) { + sidebar = true; + } + // default is just for phones + } else if (has('phone')) { + sidebar = true; + } + break; + } + this.config.layout.sidebar = sidebar; + }, + + _createSidebar: function () { + var mapContainer = dom.byId(this.map.id); + //create controls div + var mapControlsNode = put(this.map.root, 'div.sidebar-map'); + //move the slider into the controls div + put(mapControlsNode, '>', this.map._slider); + //create sidebar + this.sidebar = new Sidebar({ + map: this.map, + mapContainer: mapContainer, + collapseSyncNode: mapControlsNode + }, put(this.map.root, 'div')); + this.sidebar.startup(); + + this._createTitlePaneWidget = this._createTabPaneWidget; + }, + + _createTabPaneWidget: function (parentId, widgetConfig) { + var tabOptions = widgetConfig.tabOptions || { + id: parentId, + title: widgetConfig.title, + iconClass: widgetConfig.iconClass + }; + + return this.sidebar.createTab(tabOptions); + } + + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index 8ab99d897..872f75af9 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -2,6 +2,7 @@ define([ 'dojo/_base/declare', 'dojo/_base/array', 'dojo/_base/lang', + 'dojo/aspect', 'dojo/promise/all', 'dojo/Deferred', @@ -17,6 +18,7 @@ define([ declare, array, lang, + aspect, promiseAll, Deferred, @@ -75,7 +77,7 @@ define([ widgetTypes = widgetTypes || this.widgetTypes; for (var key in this.config.widgets) { if (this.config.widgets.hasOwnProperty(key)) { - var widget = lang.clone(this.config.widgets[key]); + var widget = this.config.widgets[key]; widget.widgetKey = widget.widgetKey || widget.id || key; if (widget.include && (!this.widgets[widget.widgetKey]) && (array.indexOf(widgetTypes, widget.type) >= 0)) { widget.position = (typeof(widget.position) !== 'undefined') ? widget.position : 10000; @@ -145,33 +147,49 @@ define([ } // build a titlePane or floating widget as the parent + widgetConfig.watched = widgetConfig.watched || 'open'; if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating')) { parentId = widgetConfig.widgetKey + '_parent'; if (widgetConfig.type === 'titlePane') { pnl = this._createTitlePaneWidget(parentId, widgetConfig); } else if (widgetConfig.type === 'contentPane') { pnl = this._createContentPaneWidget(parentId, widgetConfig); + widgetConfig.preload = true; } else if (widgetConfig.type === 'floating') { pnl = this._createFloatingWidget(parentId, widgetConfig); } widgetConfig.parentWidget = pnl; + widgetConfig.preload = (widgetConfig.preload) || pnl.get(widgetConfig.watched) || (typeof(pnl.watch) !== 'function'); this._showWidgetLoader(pnl); } - // 2 ways to use require to accommodate widgets that may have an optional separate configuration file var deferred = new Deferred(); + widgetConfig.preload = (typeof(widgetConfig.preload) === 'undefined') ? true : widgetConfig.preload; + if (!widgetConfig.preload) { + widgetConfig.watchHandle = pnl.watch(widgetConfig.watched, lang.hitch(this, '_loadWidget', widgetConfig, deferred)); + } else { + this._loadWidget(widgetConfig, deferred); + } + return deferred; + }, + + _loadWidget: function (widgetConfig, deferred) { + // 2 ways to use require to accommodate widgets that may have an optional separate configuration file if (typeof(widgetConfig.options) === 'string') { require([widgetConfig.options, widgetConfig.path], lang.hitch(this, function (options, WidgetClass) { - deferred.resolve(); this.createWidget(widgetConfig, options, WidgetClass); + deferred.resolve(); })); } else { require([widgetConfig.path], lang.hitch(this, function (WidgetClass) { - deferred.resolve(); this.createWidget(widgetConfig, widgetConfig.options, WidgetClass); + deferred.resolve(); })); } - return deferred; + if (widgetConfig.watchHandle) { + widgetConfig.watchHandle.unwatch(); + widgetConfig.watchHandle.remove(); + } }, createWidget: function (widgetConfig, options, WidgetClass) { @@ -282,7 +300,8 @@ define([ _createFloatingWidget: function (parentId, widgetConfig) { var options = lang.mixin({ - title: widgetConfig.title + title: widgetConfig.title, + iconClass: widgetConfig.iconClass }, widgetConfig.paneOptions || {}); if (parentId) { options.id = parentId; diff --git a/viewer/js/viewer/sidebar/Sidebar.js b/viewer/js/viewer/sidebar/Sidebar.js new file mode 100644 index 000000000..ca0f37115 --- /dev/null +++ b/viewer/js/viewer/sidebar/Sidebar.js @@ -0,0 +1,173 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + + 'dojo/_base/lang', + 'dojo/_base/array', + 'dojo/query', + 'dojo/dom-class', + 'dojo/dom-geometry', + 'dojo/on', + 'dojo/aspect', + + 'dijit/registry', + + 'put-selector/put', + + 'viewer/sidebar/SidebarTab', + + 'dojo/text!./templates/Sidebar.html', + + 'xstyle/css!./css/Sidebar.css', + + 'dojo/NodeList-traverse' + +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + + lang, + array, + query, + domClass, + domGeom, + on, + aspect, + + registry, + + put, + + SidebarTab, + + template +) { + return declare([_WidgetBase, _TemplatedMixin], { + templateString: template, + baseClass: 'sidebar', + + viewPadding: { + top: 0, + left: 0, + right: 0, + bottom: 0 + }, + + showCloseIcon: true, + + collapseSyncNode: null, + + postCreate: function () { + this.inherited(arguments); + + this.tabs = []; + if (this.collapseSyncNode) { + if (domClass.contains(this.domNode, 'collapsed')) { + put(this.mapContainer, '.sidebar-collapsed'); + } + //wire up css transition callback covering all event name bases + on(this.collapseSyncNode, 'transitionend, oTransitionEnd, webkitTransitionEnd, animationend, webkitAnimationEnd', lang.hitch(this, '_setViewPadding')); + } + aspect.before(this.map, 'setExtent', lang.hitch(this, '_viewPaddingHandler')); + + // resize tab and any widgets within the tab when it is opened + on(this.domNode, 'transitionend, oTransitionEnd, webkitTransitionEnd, animationend, webkitAnimationEnd', lang.hitch(this, '_resizeActiveTab')); + + // resize tab and any widgets within the tab when the browser is resized + on(window, 'resize', lang.hitch(this, function () { + window.setTimeout(lang.hitch(this, '_resizeActiveTab'), 300); // 300ms to wait for the animation to complete + })); + + }, + + createTab: function (options) { + options = options || {}; + options.open = options.open || false; + options.baseClass = this.baseClass; + options.showCloseIcon = this.showCloseIcon; + options.tabsContainerNode = this.tabsContainerNode; + options.tabsButtonNode = this.tabsButtonNode; + + var tab = new SidebarTab(options); + tab.watch('open', lang.hitch(this, 'checkTabs', tab)); + if (options.open) { + tab.openTab(); + } + + this.tabs.push(tab); + return tab; + }, + + checkTabs: function (tab) { + array.forEach(this.tabs, function (childTab) { + if (childTab.get('id') !== tab.get('id')) { + childTab.closeTab(true); + } + }); + if (tab.get('open')) { + domClass.add(this.tabsButtonNode, 'active'); + domClass.remove(this.domNode, 'collapsed'); + domClass.remove(this.mapContainer, 'sidebar-collapsed'); + } else { + domClass.remove(this.tabsButtonNode, 'active'); + domClass.add(this.domNode, 'collapsed'); + domClass.add(this.mapContainer, 'sidebar-collapsed'); + } + }, + + _setViewPadding: function () { + var dims = domGeom.getContentBox(this.domNode); + this.viewPadding = { + top: 0, + left: dims.w + dims.l, + right: 0, + bottom: 0 + }; + this._viewPaddingHandler(this.map.extent); + }, + + _viewPaddingHandler: function (extent) { + var map = this.map, + vp = this.viewPadding, + w = map.width - vp.left - vp.right, + h = map.height - vp.top - vp.bottom, + res = Math.max(extent.getWidth() / w, extent.getHeight() / h), + center = extent.getCenter(), + result = map.extent.expand(res / (map.extent.getWidth() / map.width)); + result = result.centerAt({ + x: center.x - (vp.left - vp.right) * 0.5 * res, + y: center.y - (vp.top - vp.bottom) * 0.5 * res + }); + return [result]; + }, + + _resizeActiveTab: function () { + var childTabs = array.filter(this.tabs, function (tab) { + return domClass.contains(tab.contentNode, 'active'); + }); + if (childTabs && childTabs.length > 0) { + var contentNode = query(childTabs[0].contentNode); + this._resizeWidgetsInNodeList(contentNode); + var children = contentNode.children(); + this._resizeWidgetsInNodeList(children); + } + }, + + _resizeWidgetsInNodeList: function (nodes) { + array.forEach(nodes, function (node) { + // resize any widgets + var childWidgets = registry.findWidgets(node); + array.forEach(childWidgets, function (widget) { + if (widget.resize && typeof(widget.resize) === 'function') { + window.setTimeout(function () { + widget.resize(); + }, 50); + } + }); + + }); + } + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/sidebar/SidebarTab.js b/viewer/js/viewer/sidebar/SidebarTab.js new file mode 100644 index 000000000..db4945f77 --- /dev/null +++ b/viewer/js/viewer/sidebar/SidebarTab.js @@ -0,0 +1,87 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + + 'dojo/_base/lang', + 'dojo/on', + 'dojo/dom-class', + + 'put-selector/put' + +], function ( + declare, + _WidgetBase, + + lang, + on, + domClass, + + put + +) { + return declare([_WidgetBase], { + id: null, + title: 'Title', + iconClass: 'fa-bars', + open: false, + baseClass: null, + tabsButtonNode: null, + tabsContainerNode: null, + buttonNode: null, + contentNode: null, + titleNode: null, + closeBtnNode: null, + containerNode: null, + + postCreate: function () { + this.inherited(arguments); + + //create and place dom element for the tab button + this.buttonNode = put(this.tabsButtonNode, 'li a[role=tab] i.fa.' + this.iconClass + '<<'); + + //create and place dom elements for the tab pane + this.contentNode = put(this.tabsContainerNode, 'div.' + this.baseClass + '-pane'); + this.titleNode = put(this.contentNode, 'div.' + this.baseClass + '-pane-title $', this.title); + this.containerNode = put(this.contentNode, 'div.sidebar-widget div.sidebar-widget-content'); + if (this.showCloseIcon) { + this.closeBtnNode = put(this.titleNode, 'i.fa.fa-chevron-left.' + this.baseClass + '-closeIcon'); + // listen for the tab close button click + on(this.closeBtnNode, 'click', lang.hitch(this, 'tabClickHandler')); + } + + // listen for the tab button click + on(this.buttonNode, 'click', lang.hitch(this, 'tabClickHandler')); + + }, + + openTab: function (silent) { + domClass.add(this.buttonNode, 'active'); + domClass.add(this.containerNode, 'active'); + domClass.add(this.contentNode, 'active'); + if (silent) { + this.open = true; + return; + } + this.set('open', true); + }, + + closeTab: function (silent) { + domClass.remove(this.buttonNode, 'active'); + domClass.remove(this.containerNode, 'active'); + domClass.remove(this.contentNode, 'active'); + if (silent) { + this.open = false; + return; + } + this.set('open', false); + }, + + tabClickHandler: function () { + if (domClass.contains(this.buttonNode, 'active')) { + this.closeTab(); + } else { + this.openTab(); + } + } + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/sidebar/css/Sidebar.css b/viewer/js/viewer/sidebar/css/Sidebar.css new file mode 100644 index 000000000..c1ee89cea --- /dev/null +++ b/viewer/js/viewer/sidebar/css/Sidebar.css @@ -0,0 +1,308 @@ +.cmv .sidebar { + bottom: 0; + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5); + height: auto; + left: 0; + overflow: hidden; + position: absolute; + top: 0; + width: 100%; + z-index: 40; +} + +.cmv .sidebar.collapsed { + height: auto; + width: 40px; +} + +.cmv .sidebar-tabs { + background-color: #fff; + color: #444; + height: 100%; + margin: 0; + overflow-y: auto; + padding: 0; + position: absolute; + top: 0; + width: 40px; + z-index: 41; +} + +.cmv .sidebar-tabs.active { + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5); +} + +.cmv .sidebar-tabs > li { + cursor: pointer; + float: none; + font-size: 14pt; + height: 40px; + overflow: hidden; + transition: all 80ms; + width: 100%; +} + +.cmv .sidebar-tabs > li:hover { + background-color: #444; + color: #fff; +} + +.cmv .sidebar-tabs > li.active { + background-color: #444; + color: #fff; +} + +.cmv .sidebar-tabs > li > a { + color: inherit; + display: block; + height: 100%; + line-height: 40px; + text-align: center; + text-decoration: none; + width: 100%; +} + +.cmv .sidebar-content { + background-color: #fff; + bottom: 0; + left: 40px; + overflow-x: hidden; + overflow-y: auto; + position: absolute; + right: 0; + top: 0; +} + +.cmv .sidebar-pane { + display: none; + right: 0; + width: 100%; +} + +.cmv .sidebar-pane.active { + display: block; +} + +.cmv .sidebar-pane-title { + background-color: #eee; + color: #333; + border-bottom: 1px solid #333; + font-size: 16px; + font-weight: bold; + height: 28px; + left: 0; + padding: 12px 10px 0 10px; + position: absolute; + right: 0; + top: 0; +} + +.cmv .sidebar .sidebar-pane-title .sidebar-closeIcon { + cursor: pointer; + float: right; +} + +.cmv .sidebar-widget { + bottom: 0; + left: 0; + overflow-x: hidden; + overflow-y: auto; + padding: 10px; + position: absolute; + right: 0; + top: 40px; +} + +.cmv .sidebar-widget .sidebar-widget-content { + padding: 5px; + position: relative; +} + + +/* esri map widgets */ +.cmv .map .sidebar-map { + left: 40px; + position: absolute; + top: 0; +} + +.cmv .map .cmv-widget-geocoder { + top: 15px; +} + +.cmv .sidebar, +.cmv .map .sidebar-map, +.cmv .map .cmv-widget, +.cmv .map .scalebar_bottom-left { + transition: left 300ms; +} + +@media (max-width: 320px) { + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 100px; + } +} + +@media (min-width: 321px) and (max-width: 400px) { + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 140px; + } +} + +@media (min-width: 401px) and (max-width: 767px) { + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 160px; + } +} + +@media (max-width: 767px) { + .cmv .sidebar-widget .sidebar-widget-content { + zoom: 1.25; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .cmv .sidebar { + width: 300px; + } + .cmv .map .sidebar-map { + left: 300px; + } + .cmv .map .cmv-widget-mapinfo { + left: 300px; + } + .cmv .map .cmv-widgets-left { + left: 314px; + } + .cmv .map .scalebar_bottom-left { + left: 325px !important; + } + .cmv .map .cmv-widget-geocoder { + left: 360px; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 140px; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .cmv .sidebar { + width: 350px; + } + .cmv .map .sidebar-map { + left: 350px; + } + .cmv .map .cmv-widget-mapinfo { + left: 350px; + } + .cmv .map .cmv-widgets-left { + left: 364px; + } + .cmv .map .cmv-widget-geocoder { + left: 410px; + } + .cmv .map .scalebar_bottom-left { + left: 375px !important; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 190px; + } +} + +@media (min-width: 1200px) and (max-width: 1800px) { + .cmv .sidebar { + width: 400px; + } + .cmv .map .sidebar-map { + left: 400px; + } + .cmv .map .cmv-widget-mapinfo { + left: 400px; + } + .cmv .map .cmv-widgets-left { + left: 414px; + } + .cmv .map .cmv-widget-geocoder { + left: 460px; + } + .cmv .map .scalebar_bottom-left { + left: 425px !important; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 240px; + } +} + +@media (min-width: 1800px) { + .cmv .sidebar { + width: 450px; + } + .cmv .map .sidebar-map { + left: 450px; + } + .cmv .map .cmv-widget-mapinfo { + left: 450px; + } + .cmv .map .cmv-widgets-left { + left: 464px; + } + .cmv .map .cmv-widget-geocoder { + left: 510px; + } + .cmv .map .scalebar_bottom-left { + left: 475px !important; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 290px; + } +} + +.cmv .sidebar-collapsed .sidebar-map { + left: 40px; +} + +.cmv .sidebar-collapsed .cmv-widget-mapinfo { + left: 40px; +} + +.cmv .sidebar-collapsed .cmv-widgets-left { + left: 54px; +} + +.cmv .sidebar-collapsed .cmv-widget-geocoder { + left: 100px; +} + +.cmv .sidebar-collapsed .scalebar_bottom-left { + left: 65px !important; +} + +/* simple zoom slider: positioning */ +.cmv .map .esriSimpleSliderTL { + left: 15px; + top: 15px; +} + +.cmv .map .esriSimpleSliderTR { + right: 15px; + top: 15px; +} + +/* simple zoom slider: horizontal */ + +.cmv .map .esriSimpleSliderHorizontal { + top: 10px; +} + +.cmv .map .esriSimpleSliderHorizontal.esriSimpleSliderBL { + left: 10px; +} + +.cmv .map .esriSimpleSliderHorizontal.esriSimpleSliderBR { + right: 10px; +} + +.cmv .map .cmv-widget-basemaps { + right: 10px; + top: 10px; +} \ No newline at end of file diff --git a/viewer/js/viewer/sidebar/templates/Sidebar.html b/viewer/js/viewer/sidebar/templates/Sidebar.html new file mode 100644 index 000000000..025e27262 --- /dev/null +++ b/viewer/js/viewer/sidebar/templates/Sidebar.html @@ -0,0 +1,9 @@ + diff --git a/viewer/js/viewer/templates/mapOverlay.html b/viewer/js/viewer/templates/mapOverlay.html index 42dd41a40..80d25080b 100644 --- a/viewer/js/viewer/templates/mapOverlay.html +++ b/viewer/js/viewer/templates/mapOverlay.html @@ -1,22 +1,16 @@ -
-
-
+
+
-
-
-
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
-
-
-
+
+
\ No newline at end of file