From 8d290f95368b54c5bf8ea189432faf8cb44de5ca Mon Sep 17 00:00:00 2001 From: Tariq Soliman Date: Fri, 3 Feb 2023 17:56:14 -0800 Subject: [PATCH] #324 Configurable Context Menu Actions (#325) * #324 Coordinates Config Tab Raw Variables * #324 Configurable context menu actions --- config/css/config.css | 3 + config/js/config.js | 42 ++++++++++++ .../Tabs/Coordinates/Coordinates_Tab.md | 27 ++++++++ src/essence/Ancillary/ContextMenu.css | 14 +++- src/essence/Ancillary/ContextMenu.js | 64 ++++++++++++++++--- src/essence/Ancillary/Coordinates.js | 4 +- src/essence/Basics/Globe_/Globe_.js | 8 ++- views/configure.pug | 20 ++++++ 8 files changed, 167 insertions(+), 15 deletions(-) diff --git a/config/css/config.css b/config/css/config.css index e120a054..bec1e1a4 100644 --- a/config/css/config.css +++ b/config/css/config.css @@ -301,6 +301,9 @@ textarea { margin: 0px 161px 0px 173px; border-bottom: 2px solid #1565c0 !important; } +.col > .CodeMirror { + margin: 0px; +} #missions { margin: 5px 0px; diff --git a/config/js/config.js b/config/js/config.js index f9de5eef..173b87fc 100644 --- a/config/js/config.js +++ b/config/js/config.js @@ -6,6 +6,7 @@ var missionPath = ""; var tData; var editors; var layerEditors; +var tabEditors; var usingCustomProjection; var availableKinds = []; @@ -132,6 +133,7 @@ function initialize() { editors = {}; layerEditors = {}; + tabEditors = {}; for (var i = 0; i < tData.length; i++) { // prettier-ignore @@ -199,6 +201,34 @@ function initialize() { } } + // Setup tabEditors + tabEditors["coordinatesVariables"] = CodeMirror.fromTextArea( + document.getElementById("coordinatesVariables"), + { + path: "js/codemirror/codemirror-5.19.0/", + mode: "javascript", + theme: "elegant", + viewportMargin: Infinity, + lineNumbers: true, + autoRefresh: true, + matchBrackets: true, + } + ); + $("#coordinatesVariables_example").html( + JSON.stringify( + { + rightClickMenuActions: [ + { + name: "The text for this menu entry when users right-click", + link: "https://domain?I={ll[0]}&will={ll[1]}&replace={ll[2]}&these={en[0]}&brackets={en[1]}&for={cproj[0]}&you={sproj[0]}&with={rxy[0]}&coordinates={site[2]}", + }, + ], + }, + null, + 4 + ) || "" + ); + //Make materialize initialize tabs $("ul.tabs#missions").tabs(); @@ -242,6 +272,10 @@ function initialize() { if (data.status == "success") { var cData = data.config; + for (var e in tabEditors) { + tabEditors[e].setValue(""); + } + //overall $("#overall_mission_name").text(mission); @@ -494,6 +528,11 @@ function initialize() { $( `.coordinates_coordMain[value="${cData.coordinates?.coordmain}"]` ).prop("checked", true); + tabEditors["coordinatesVariables"].setValue( + cData.coordinates?.variables + ? JSON.stringify(cData.coordinates?.variables, null, 4) + : "" + ); //look $("#tab_look #look_pagename").val("MMGIS"); @@ -2044,6 +2083,9 @@ function save() { ).val(); json.coordinates["coordmain"] = $(`.coordinates_coordMain:checked`).val() || "ll"; + json.coordinates["variables"] = JSON.parse( + tabEditors["coordinatesVariables"].getValue() || "{}" + ); //Look json.look["pagename"] = $("#tab_look #look_pagename").val(); diff --git a/docs/pages/Configure/Tabs/Coordinates/Coordinates_Tab.md b/docs/pages/Configure/Tabs/Coordinates/Coordinates_Tab.md index 97b31fe0..52de9324 100644 --- a/docs/pages/Configure/Tabs/Coordinates/Coordinates_Tab.md +++ b/docs/pages/Configure/Tabs/Coordinates/Coordinates_Tab.md @@ -37,3 +37,30 @@ Check to display Y, X, -Z coordinates to users relative to point features they h #### With Elevation Check to query for and append elevation values to the lower-right coordinates as users mouse around. DEM URL must be set. + +#### Raw Variables + +All raw variables are optional. + +Example: + +```javascript +{ + "rightClickMenuActions": [ + { + "name": "The text for this menu entry when users right-click", + "link": "https://domain?I={ll[0]}&will={ll[1]}&replace={ll[2]}&these={en[0]}&brackets={en[1]}&for={cproj[0]}&you={sproj[0]}&with={rxy[0]}&coordinates={site[2]}" + } + ] +} +``` + +- `rightClickMenuActions`: When right-clicking on the Map or Globe, a custom context-menu appears. By default it only offers "Copy Coordinates". By adding objects to the `rightClickMenuActions` array, entries can be added to the context-menu to send users to links with parameters populated with the current coordinates. + - `name`: The button text for this action in the right-click context-menu. + - `link`: A url template. Curly brackets are included. The available coordinate parameters (with array index in brackets and assuming they are enabled) are: + - `ll`: `[longitude, latitude, elevation]` - Longitude Latitude + - `en`: `[easting, northing, elevation]` - Easting Northing + - `cproj`: `[easting, northing, elevation]` - Projected + - `sproj`: `[easting, northing, elevation]` - Secondary Projected + - `rxy`: `[x, y, z]` - Relative + - `site`: `[y, x, -z]` - Local Level diff --git a/src/essence/Ancillary/ContextMenu.css b/src/essence/Ancillary/ContextMenu.css index 7dd2536e..37ff69f7 100644 --- a/src/essence/Ancillary/ContextMenu.css +++ b/src/essence/Ancillary/ContextMenu.css @@ -3,7 +3,8 @@ background: var(--color-a); box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.3); border: 1px solid var(--color-i); - border-radius: 3px; + border-radius: 1px; + font-size: 15px; z-index: 1; transition: opacity 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); } @@ -36,11 +37,20 @@ padding: 0; } .ContextMenuMap li { - padding: 4px 16px; + padding: 5px 8px 5px 16px; cursor: pointer; color: #aaa; + border-top: 1px solid var(--color-a1); + display: flex; transition: color 0.2s cubic-bezier(0.39, 0.575, 0.565, 1); } +.ContextMenuMap li:first-child { + border-top: none; +} +.ContextMenuMap li i { + padding: 0px 6px; +} .ContextMenuMap li:hover { color: white; + background: var(--color-a1); } diff --git a/src/essence/Ancillary/ContextMenu.js b/src/essence/Ancillary/ContextMenu.js index 202df8cb..9c2e439f 100644 --- a/src/essence/Ancillary/ContextMenu.js +++ b/src/essence/Ancillary/ContextMenu.js @@ -1,5 +1,6 @@ import $ from 'jquery' import * as d3 from 'd3' +import L_ from '../Basics/Layers_/Layers_' import F_ from '../Basics/Formulae_/Formulae_' import Map_ from '../Basics/Map_/Map_' import Coordinates from './Coordinates' @@ -10,29 +11,38 @@ var ContextMenu = { init: function () { this.remove() Map_.map.on('contextmenu', showContextMenuMap) + $('#_lithosphere_scene').on('contextmenu', showContextMenuMap) }, remove: function () { hideContextMenuMap() Map_.map.off('contextmenu', showContextMenuMap) + $('#_lithosphere_scene').off('contextmenu', showContextMenuMap) }, } function showContextMenuMap(e) { + const contextMenuActions = F_.getIn( + L_, + 'configData.coordinates.variables.rightClickMenuActions', + [] + ) + hideContextMenuMap(true) var x = e.originalEvent.clientX var y = e.originalEvent.clientY // prettier-ignore var markup = [ - "
", - "
", - "
", - "
", - "
", - "
", - "", - "" - ].join('\n'); + "
", + "
", + "
", + "
", + "
", + "", + "
" + ].join('\n'); $('body').append(markup) @@ -47,6 +57,40 @@ function showContextMenuMap(e) { $('#contextMenuMapCopyCoords').text('Copy Coordinates') }, 2000) }) + + contextMenuActions.forEach((a, idx) => { + $(`#contextMenuAction_${idx}`).on('click', function () { + if (a.link) { + let link = a.link + const lnglat = Coordinates.getLngLat() + + Object.keys(Coordinates.states).forEach((s) => { + if (link.indexOf(`{${s}[`) !== -1) { + const converted = Coordinates.convertLngLat( + lnglat[0], + lnglat[1], + s, + false, + true + ) + link = link.replace( + new RegExp(`{${s}\\[0\\]}`, 'gi'), + converted[0] + ) + link = link.replace( + new RegExp(`{${s}\\[1\\]}`, 'gi'), + converted[1] + ) + link = link.replace( + new RegExp(`{${s}\\[2\\]}`, 'gi'), + converted[2] + ) + } + }) + window.open(link, '_blank').focus() + } + }) + }) } function hideContextMenuMap(immediately) { diff --git a/src/essence/Ancillary/Coordinates.js b/src/essence/Ancillary/Coordinates.js index 3383c6ce..a1df95ef 100644 --- a/src/essence/Ancillary/Coordinates.js +++ b/src/essence/Ancillary/Coordinates.js @@ -319,7 +319,9 @@ const Coordinates = { }, getAllCoordinates: function () { return { - description: d3.select('#mouseDesc').html(), + description: d3 + .select('#changeCoordTypeDropdown .dropy__title > span') + .html(), coordinates: [ ...d3.select('#mouseLngLat').html().split(','), d3.select('#mouseElev').html(), diff --git a/src/essence/Basics/Globe_/Globe_.js b/src/essence/Basics/Globe_/Globe_.js index 94571d10..5d17f7e9 100644 --- a/src/essence/Basics/Globe_/Globe_.js +++ b/src/essence/Basics/Globe_/Globe_.js @@ -128,7 +128,10 @@ let Globe_ = { hideElement: true, onChange: (lng, lat, elev) => { if (lng == null || lat == null) { - $('#mouseLngLat').text(`Outer Space`) + L_.Coordinates.setCoords( + [null, null, null], + 'Outer Space' + ) } else { const converted = L_.Coordinates.convertLngLat( lng, @@ -136,7 +139,8 @@ let Globe_ = { L_.Coordinates.currentType, true ) - $('#mouseLngLat').text( + L_.Coordinates.setCoords( + [lng, lat, elev], `${converted[0]}, ${converted[1]}` ) } diff --git a/views/configure.pug b/views/configure.pug index 9cdec861..177c048d 100644 --- a/views/configure.pug +++ b/views/configure.pug @@ -325,6 +325,15 @@ script(type='text/javascript' src='config/pre/RefreshAuth.js') #coordinates_coordelevurlEl.input-field.col.s7.push-s1 input#coordinates_coordelevurl.validate(type='text' value='') label(for='coordinates_coordelevurl') DEM URL + li.row.title(style='margin-top: 45px;') + .col.s2.push-s1 Raw Variables + .col.s6.push-s3(style='text-align: center; background-color: rgba(0,0,0,0.06); position: relative; padding: 0;') + a.waves-effect.waves-light.modal-trigger(href='#coordinatesVariables_modal' style='color: #111; width: 100%;') Click for configuration documentation + i.mdi.mdi-information.mdi-18px(style='position: absolute; right: 2px; top: -2px; color: #444;') + + li.row(style='padding-bottom: 0px;') + #coordinates_variablseEl.input-field.col.s10.push-s1 + textarea#coordinatesVariables #tab_look.col.s12 a.helpFromDocs(href='docs/?page=Look_Tab' target='__blank' rel='noopener') @@ -521,6 +530,17 @@ script(type='text/javascript' src='config/pre/RefreshAuth.js') a#delete_mission_delete.modal-action.modal-close.btn-flat.waves-effect.waves-light.col.s12(style='border-radius: 0px; color: white;') | Delete Mission i.mdi.mdi-delete.mdi-24px(style='float: right; margin-top: 1px; padding-left: 5px;') + #coordinatesVariables_modal.modal + .modal-content(style='padding-bottom: 0;') + h4 Coordinates Raw Variables + #coordinatesVariables_info(style='margin-bottom: 0;') + #coordinatesVariables_title + hr + #coordinatesVariables_content + pre#coordinatesVariables_example + .modal-footer + a.modal-action.modal-close.waves-effect.waves-green.btn-flat(href='#!') Done + .row #info_modal.modal .modal-content(style='padding-bottom: 0;') h4 Modal Header