source: main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js@ 33088

Last change on this file since 33088 was 33088, checked in by wy59, 5 years ago

Fixed the bug described in the previous commit (but it had been wrongly described in reverse).

File size: 27.6 KB
Line 
1
2
3function MapEditor(id) {
4 // TODO: investigate const, see https://www.w3schools.com/js/js_const.asp and check it will work on older browsers,
5 // https://stackoverflow.com/questions/4271566/how-do-i-know-which-version-of-javascript-im-using
6 this.MAX_THICKNESS = 5.0;
7 this.MIN_THICKNESS = 0.0;
8 this.MAX_OPACITY = 100.00;
9 this.MIN_OPACITY = 0.00;
10
11 // WORK-IN-PROGRESS FEATURE: label on Map (to be changed to a label associated with each shape later)
12 // Also uncomment import of label-overlay-class.js in document.xsl
13 //this.labelOverlay = null;
14
15
16 this.id = id;
17 this.shiftKeyPressed = false;
18 this.beingDragged = false;
19 this.allowDeselect = true;
20 this.colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
21 this.selectedColor;
22 this.colorButtons = {};
23 this.thicknessValue = 1;
24 this.opacityValue = 40;
25 this.overlays = [];
26 this.selectedShapes = [];
27 this.listenersArray = [];
28 this.mapsArray = [];
29 this.drawingManager;
30 this.selectedShape;
31 this.savedOverlays = null;
32 this.map = null;
33 this.counter = 0;
34 this.branchNum = 1;
35 this.mouseState = "up";
36 this.thicknessRangeListener = this.thicknessValue; // ????
37 this.resizable = false;
38 this.dontResize = false;
39
40 this.shapeOptions = {
41 suppressUndo: true,
42 fillColor: '#CA4A2F',
43 strokeWeight: this.thicknessValue,
44 fillOpacity: this.opacityValue / 100,
45 editable: true,
46 geodesic: false,
47 draggable: true,
48 description: ""
49 };
50 this.mapEditorHistory = new MapEditorHistory(this);
51}
52
53//draggable checkbox control
54MapEditor.prototype.initMapEditorControls = function () {
55 var that = this;
56
57 var draggableCB = document.getElementById("draggableCB-"+ this.id);
58 draggableCB.addEventListener('change', function () {
59 if (this.checked) {
60 for (var i = 0; i < that.overlays.length; i++) {
61 that.overlays[i].draggable = false;
62 that.shapeOptions.draggable = false;
63 }
64 } else {
65 for (var i = 0; i < that.overlays.length; i++) {
66 that.overlays[i].draggable = true;
67 that.shapeOptions.draggable = true;
68 }
69 }
70 });
71
72
73 //Update thickness
74 var thicknessSliderOutput = document.getElementById("thicknessRangeVal" + "-" + this.id);
75 var thicknessSlider = document.getElementById("thicknessRange" + "-" + this.id);
76 var thicknessValue = ((thicknessSlider.value / 20) * 100) / 100;
77 thicknessSliderOutput.value = thicknessValue.toFixed(2);
78
79 thicknessSlider.oninput = function () {
80 that.shapeSpecsChangeMD();
81 var thicknessVal = ((this.value / 20) * 100) / 100;
82 thicknessSliderOutput.value = thicknessVal.toFixed(2);
83 that.thicknessValue = this.value / 20;
84 that.shapeOptions.strokeWeight = that.thicknessValue;
85 that.setSelectedThickness(that.thicknessValue);
86 }
87
88 thicknessSliderOutput.oninput = function () {
89 that.shapeSpecsChangeMD(); // TODO: DO WE NEED THIS LINE? (LINE COPIED & PASTED FROM ABOVE)
90 if(this.value > that.MAX_THICKNESS) this.value = that.MAX_THICKNESS;
91 if(this.value < that.MIN_THICKNESS) this.value = that.MIN_THICKNESS;
92 var thicknessVal = this.value * 20;
93 thicknessSlider.value = thicknessVal.toFixed(2);
94 that.thicknessValue = this.value;
95 that.shapeOptions.strokeWeight = that.thicknessValue;
96 that.setSelectedThickness(that.thicknessValue);
97 }
98 //Update opacity
99 // TODO: https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
100 var opacitySlider = document.getElementById("colourOpacity" + "-" + this.id);
101 var opacitySliderOutput = document.getElementById("opacityRangeVal" + "-" + this.id);
102
103 opacitySlider.oninput = function () {
104 that.shapeSpecsChangeMD();
105 opacitySliderOutput.value = this.value;
106 that.opacityValue = this.value / 100;
107 that.shapeOptions.fillOpacity = that.opacityValue;
108 that.setSelectedOpacity(that.opacityValue);
109 }
110 opacitySliderOutput.oninput = function () {
111 that.shapeSpecsChangeOnInput();
112 if(this.value > that.MAX_OPACITY) this.value = that.MAX_OPACITY;
113 if(this.value < that.MIN_OPACITY) this.value = that.MIN_OPACITY;
114 opacitySlider.value = this.value;
115 that.opacityValue = this.value / 100;
116 that.shapeOptions.fillOpacity = that.opacityValue;
117 that.setSelectedOpacity(that.opacityValue);
118 }
119
120 var descriptionInput = document.getElementById("description" + "-" + this.id);
121 descriptionInput.oninput = function () {
122 that.shapeSpecsChangeOnInput(); // takes care of history (undo/redo)
123 var description = this.value;
124 that.shapeOptions.description = description;
125 that.setSelectedDescription(that.shapeOptions.description);
126 }
127
128 // TODO: Do we need these listeners, when we already have onInput methods above? Test.
129 document.getElementById("color-palette1" + "-" + this.id).addEventListener("mousedown", function() { that.shapeSpecsChangeMD() });
130 document.getElementById("thicknessRange" + "-" + this.id).addEventListener("mouseup", function () { that.shapeSpecsChangeMU() });
131 document.getElementById("colourOpacity" + "-" + this.id).addEventListener("mouseup", function () { that.shapeSpecsChangeMU() });
132 //document.getElementById("description" + "-" + this.id).addEventListener("keypress", function () { that.shapeSpecsChangeOnInput() });
133
134 document.onmousedown = function (ev) {
135 that.mouseState = "down";
136 // console.log('Down State you can now start dragging');
137 //do not write any code here in this function
138 }
139
140 document.onmouseup = function (ev) {
141 that.mouseState = "up";
142 // console.log('up state you cannot drag now because you are not holding your mouse')
143 //do not write any code here in this function
144 }
145
146
147 //prompts the user to save the changes before reloading/leaving the page
148 window.onbeforeunload = function (e) {
149 var currentOverlays = JSON.stringify(ShapesUtil.overlayToJSON(that.overlays));
150 var enableMessage = currentOverlays !== that.savedOverlays;
151 var message = "Changes are not saved. Are you sure you want to leave?";
152
153
154 // Comment out following section in entirety -- from "e = e || window.event" to end of "if(e)" -- if
155 // you don't want to see the popup about changes that haven't been saved yet
156 e = e || window.event;
157 // For IE and Firefox
158 if (e) {
159
160 if(enableMessage){
161 if(currentOverlays !== "[]") {
162 alert(message);
163 e.returnValue = message;
164
165 // For Safari
166 return message;
167 }
168 }
169 }
170
171 }
172}
173
174MapEditor.prototype.settingThePath = function () {
175 var that = this;
176 this.listenersArray = []
177 this.counter = 0;
178 this.branchNum = 1;
179
180 for (var i = 0; i < this.selectedShapes.length * 2; i++) {
181 for (var j = 1; j < 6; j++) {
182 var path = "//*[@id='map-" + this.id + "']/div/div/div[1]/div[3]/div/div[3]/div[" + this.branchNum + "]/div[" + j + "]/div";
183 this.listenersArray[this.counter] = this.getElementByXpath(path);
184 if (this.listenersArray[this.counter] !== (undefined || null)) {
185 this.listenersArray[this.counter].addEventListener("mousemove", function () {
186 that.resizable = true;
187 that.shapeResize();
188 });
189 this.listenersArray[this.counter].addEventListener("mouseout", function () {
190 if (this.mouseDown) {
191 that.resizable = true;
192 that.shapeResize();
193
194 }
195 });
196 }
197 this.counter++;
198 }
199 this.branchNum++;
200 }
201}
202
203MapEditor.prototype.shapeResize = function () {
204 if (this.mouseState == "down") {
205 if (this.selectedShapes.length > 0) {
206 if (this.resizable) {
207 if (this.dontResize == false) {
208 this.mapEditorHistory.historyOverlayPush();
209 }
210
211 }
212 }
213 }
214}
215
216MapEditor.prototype.shapeSpecsChangeMD = function () {
217 if (this.selectedShapes.length > 0) {
218 this.mapEditorHistory.historyOverlayPush();
219 }
220}
221
222MapEditor.prototype.shapeSpecsChangeMU = function () {
223 if (this.selectedShapes.length > 0) {
224 this.mapEditorHistory.presentOverlayPush();
225 }
226}
227
228MapEditor.prototype.shapeSpecsChangeOnInput = function () {
229 if (this.selectedShapes.length > 0) {
230 this.mapEditorHistory.presentOverlayPush();
231 }
232}
233
234MapEditor.prototype.makeColorButton = function (color) {
235 var that = this;
236
237 var button = document.createElement('span');
238 button.className = 'color-buttons1';
239 button.style.backgroundColor = color;
240 google.maps.event.addDomListener(button, 'click', function () {
241 that.selectColor(color);
242 that.setSelectedShapeColor(color);
243 that.shapeSpecsChangeMU();
244 });
245 return button;
246}
247
248MapEditor.prototype.buildColorPalette = function () {
249 var colorPalette = document.getElementById("color-palette1" + "-" + this.id);
250 for (var i = 0; i < this.colors.length; ++i) {
251 var currColor = this.colors[i];
252 var colorButton = this.makeColorButton(currColor);
253 colorPalette.appendChild(colorButton);
254 this.colorButtons[currColor] = colorButton;
255 }
256 this.selectColor(this.colors[0]);
257};
258
259MapEditor.prototype.selectColor = function (color) {
260 this.selectedColor = color;
261 for (var i = 0; i < this.colors.length; ++i) {
262 var currColor = this.colors[i];
263 this.colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
264 }
265
266 // Retrieves the current options from the drawing manager and replaces the
267 // stroke or fill color as appropriate.
268 var polylineOptions = this.drawingManager.get('polylineOptions');
269 polylineOptions.strokeColor = color;
270 this.drawingManager.set('polylineOptions', polylineOptions);
271
272 var rectangleOptions = this.drawingManager.get('rectangleOptions');
273 rectangleOptions.fillColor = color;
274 this.drawingManager.set('rectangleOptions', rectangleOptions);
275
276 var circleOptions = this.drawingManager.get('circleOptions');
277 circleOptions.fillColor = color;
278 this.drawingManager.set('circleOptions', circleOptions);
279
280 var polygonOptions = this.drawingManager.get('polygonOptions');
281 polygonOptions.fillColor = color;
282 this.drawingManager.set('polygonOptions', polygonOptions);
283}
284
285MapEditor.prototype.initMapEditor = function () {
286 var that = this;
287
288 this.map = new google.maps.Map(document.getElementById("map-" + this.id), {
289 center: {
290 lat: -37.7891,
291 lng: 175.3180
292 },
293 zoom: 14,
294 mapId: this.id,
295 });
296
297 // WORK-IN-PROGRESS FEATURE: label on Map (to be changed to a label associated with each shape later)
298 // let's associate a label with the map (for now, later associate labels for each shape)
299 //this.labelOverlay = new LabelOverlay(this.map);
300
301 this.mapsArray.push(this.map);
302 // Add a style-selector control to the map.
303 var styleControl = document.getElementById('style-selector-control' + "-" + this.id);
304 this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(styleControl);
305
306 /*
307 // Set the map's style to the initial value of the selector.
308 var styleSelector = document.getElementById('style-selector' + "-" + this.id);
309 //console.log(styleSelector);
310 //map = google.maps.Map(document.getElementById('map' +"-"+ this.id));
311 this.map.setOptions({
312 styles: styles[styleSelector.value]
313
314 });
315
316 // Apply new JSON when the user selects a different style.
317 styleSelector.addEventListener('change', function () {
318 that.map.setOptions({
319 styles: styles[styleSelector.value]
320 });
321 });
322 */
323
324 this.drawingManager = new google.maps.drawing.DrawingManager({
325 //drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
326 drawingControl: true,
327 drawingControlOptions: {
328 position: google.maps.ControlPosition.TOP_CENTER,
329 drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
330 },
331 markerOptions: {
332 draggable: true
333 },
334 circleOptions: this.shapeOptions,
335 polylineOptions: this.shapeOptions,
336 polygonOptions: this.shapeOptions,
337 rectangleOptions: this.shapeOptions,
338 });
339
340 this.drawingManager.setMap(this.map);
341
342 google.maps.event.addListener(this.drawingManager, "drawingmode_changed", function () {
343 if (that.shiftKeyPressed != true && that.drawingManager.drawingMode !== null) {
344 that.deselectAll();
345 }
346 that.settingThePath();
347
348 })
349
350 // store reference to added overlay
351 google.maps.event.addListener(this.drawingManager, 'overlaycomplete', function (e) {
352 that.allowDeselect = true;
353 that.mapEditorHistory.historyOverlayPush();
354 that.overlays.push(e.overlay); // store reference to added overlay
355 var newShape = e.overlay;
356 newShape.type = e.type;
357 that.mapEditorHistory.presentOverlayPush();
358
359 if (e.type !== google.maps.drawing.OverlayType.MARKER) {
360 that.addShapeListeners(newShape, e);
361 that.setSelection(newShape, e);
362 } else {
363 that.addMarkerListeners(newShape, e);
364 that.setSelection(newShape, e);
365 }
366 });
367
368 //Clears selection if clicked on the map when shift is not presseed
369 google.maps.event.addListener(this.map, 'click', function (e) {
370 var c = document.body.childNodes;
371 if (e.target && e.target.matches("a.classA")) {
372 console.log("Anchor element clicked!");
373 }
374 if (that.shiftKeyPressed == false) {
375 that.clearSelection();
376 that.selectedShape = null;
377 }
378 });
379
380 google.maps.event.addListener(this.map, 'mousedown', function (e) {
381 that.dontResize = true;
382 });
383
384 google.maps.event.addListener(this.map, 'mouseup', function (e) {
385 that.dontResize = false;
386 });
387
388 //Keyboard shortcuts
389 var mapAndControls = document.getElementById("map-and-controls-" + this.id);
390 var thicknessField = document.getElementById ("thicknessRangeVal-" + this.id);
391 var opacityField = document.getElementById ("opacityRangeVal-" + this.id);
392 var openMapFunction = function() {
393 //Sets shift as unpressed
394 mapAndControls.addEventListener('keyup', function (event) {
395 if (event.keyCode == '16') {
396 that.shiftKeyPressed = false;
397 }
398 });
399
400 mapAndControls.addEventListener('keydown', function (event) {
401
402 // https://stackoverflow.com/questions/2220196/how-to-decode-character-pressed-from-jquerys-keydowns-event-handler
403 var keyCode = String.fromCharCode(event.which);
404 //console.log("Key pressed: " + keyCode);
405
406 //disable keyboard shortcut within the number input field
407 var activeElement = $(document.activeElement);
408 if(activeElement.attr('type') == 'number' || activeElement.attr('type') == 'text'){
409 //console.log('number detected')
410 return;
411 }
412 //Sets shift as pressed
413 if (event.keyCode == '16') {
414 that.shiftKeyPressed = true;
415 }
416 else if (keyCode == 'Y' && (event.ctrlKey || event.metaKey)) {
417 that.mapEditorHistory.redo();
418 }
419 else if (keyCode == 'Z' && (event.ctrlKey || event.metaKey) ) {
420 if (that.shiftKeyPressed == false) {
421 that.mapEditorHistory.undo();
422 }
423 }
424 else if (keyCode == 'A' && (event.ctrlKey || event.metaKey)) {
425 event.preventDefault();
426 that.drawingManager.setDrawingMode(null);
427 that.selectAll();
428 }
429 else if (keyCode == 'D' && (event.ctrlKey || event.metaKey)) {
430 event.preventDefault();
431 that.deselectAll();
432 }
433
434 else if (keyCode == '0' || keyCode == 'À' || (keyCode == 'G'&& (event.ctrlKey || event.metaKey))) {
435 event.preventDefault();
436 that.drawingManager.setDrawingMode(null);
437 } else if (keyCode == '1') {
438 that.drawingManager.setDrawingMode('marker');
439 } else if (keyCode == '2') {
440 that.drawingManager.setDrawingMode('circle');
441 } else if (keyCode == '3') {
442 that.drawingManager.setDrawingMode('polygon');
443 } else if (keyCode == '4') {
444 that.drawingManager.setDrawingMode('polyline');
445 } else if (keyCode == '5') {
446 that.drawingManager.setDrawingMode('rectangle');
447 }
448
449 //else if (keyCode == 'S') {
450 // that.saveToArchives();
451 //}
452 else if (keyCode == 'Q') { // for debugging information, press Q (easy to hit key)
453 that.printHistory();
454 }
455 else if (keyCode == '.') {
456 that.deleteSelectedShapes();
457 }
458 // console.log(keyCode);
459 });
460 };
461
462 openMapFunction();
463
464 this.buildColorPalette();
465
466
467 var collection = gs.cgiParams.c;
468 var site_name = gs.xsltParams.site_name;
469 var nodeID = this.id; // documentID, hopefully contains section ID too
470 var metaname = gps_metadata_name;
471
472 // collection, site, documentID, metadataName, metadataPosition, responseFunction
473 gs.functions.getArchivesMetadata(collection, site_name, nodeID, metaname, 0, function(responseText){
474 // responseText is of type GSMetadata
475
476 // called when data has been retrieved from archives
477 var JSONString = responseText.getValue();
478 if(JSONString !== "")
479 {
480 that.LOAD(JSONString, nodeID);
481 that.savedOverlays = JSONString;
482 }
483 }
484 ); // TODO: responseFunction in setMeta call
485}
486
487//Deletes a vertex if clicked on it
488MapEditor.prototype.vertexAndPolyDel = function (e, newShape) {
489 var vertex = e.vertex;
490 if (e.vertex !== undefined) {
491 if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
492 var path = newShape.getPaths().getAt(e.path);
493 path.removeAt(e.vertex);
494 if (path.length < 3) {
495 newShape.setMap(null);
496 }
497 }
498 if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
499 var path = newShape.getPath();
500 path.removeAt(e.vertex);
501 if (path.length < 2) {
502 newShape.setMap(null);
503 }
504 }
505 }
506}
507
508MapEditor.prototype.addMarkerListeners = function (newShape, e) {
509 var that = this;
510 //Click event if a marker is created
511 google.maps.event.addListener(newShape, 'click', function (e) {
512 if(that.shiftKeyPressed){
513
514 } else {
515 that.mapEditorHistory.historyOverlayPush();
516 newShape.setMap(null);
517 that.mapEditorHistory.presentOverlayPush();
518 }
519
520 });
521
522 google.maps.event.addListener(newShape, 'dragstart', function (e) {
523 that.beingDragged = true;
524 that.mapEditorHistory.historyOverlayPush();
525
526 });
527
528 google.maps.event.addListener(newShape, 'dragend', function () {
529 that.beingDragged = false;
530 that.mapEditorHistory.presentOverlayPush();
531 that.allowDeselect = false;
532 });
533}
534
535MapEditor.prototype.addShapeListeners = function (newShape, e) {
536 var that = this;
537 // Add an event listener that selects the newly-drawn shape when the user
538 // mouses down on it.
539 google.maps.event.addListener(newShape, 'click', function (e) {
540 that.vertexAndPolyDel(e, newShape);
541 });
542
543 google.maps.event.addListener(newShape, 'dragstart', function (e) {
544 that.allowDeselect = false;
545 that.mapEditorHistory.historyOverlayPush();
546 });
547
548 google.maps.event.addListener(newShape, 'dragend', function () {
549 that.beingDragged = false;
550 that.mapEditorHistory.presentOverlayPush();
551 that.settingThePath();
552
553 that.allowDeselect = false;
554 that.setSelection(newShape, e);
555 });
556
557 //Store information after the event ends
558 google.maps.event.addListener(newShape, 'bounds_changed', function (e) {
559 if (that.beingDragged == false) {
560 that.mapEditorHistory.presentOverlayPush();
561 }
562 });
563
564 //Add an event listener to select a shape if the mouse hovers over it
565 google.maps.event.addListener(newShape, 'mousedown', function (e) {
566 if (e.target && e.target.matches("a.classA")) {
567 console.log("Anchor element clicked!");
568 }
569 if (e.vertex !== undefined || e.edge !== undefined) {
570 that.mapEditorHistory.historyOverlayPush()
571 }
572 if (that.drawingManager.drawingMode == null) {
573 that.setSelection(newShape, e);
574 }
575 });
576
577 google.maps.event.addListener(newShape, 'mouseup', function (e) {
578 if (e.vertex !== undefined || e.edge !== undefined) {
579 that.mapEditorHistory.presentOverlayPush()
580 } else {
581 //that.setSelection(newShape, e);
582 }
583
584 });
585}
586MapEditor.prototype.clearSelection = function () {
587 if (this.selectedShape) {
588 if (this.shiftKeyPressed == false) {
589 for (var i = 0; i < this.selectedShapes.length; i++) {
590 if(this.selectedShapes[i].type !== 'marker') {
591 this.selectedShapes[i].setEditable(false);
592 }
593 }
594 this.selectedShapes = [];
595 }
596 this.selectedShape = null;
597 }
598}
599
600//Set selection for the selected overlay
601MapEditor.prototype.setSelection = function (shape, e) {
602 //var that = this;
603 if (shape.type !== 'marker') {
604 if (this.shiftKeyPressed == false) {
605 if (e !== null) {
606 if (e.vertex == undefined) {
607 if (e.edge == undefined) {
608 this.clearSelection();
609 shape.setEditable(true);
610 }
611 }
612 }
613 }
614 if (this.selectedShapes.includes(shape)) {
615 if (e !== null) {
616 if (e.vertex == undefined) {
617 if (e.edge == undefined) {
618 this.allowDeselect = true;
619 this.removeFromSelectedShapes(shape);
620 }
621 }
622 }
623 } else {
624 this.allowDeselect = false;
625 shape.setEditable(true);
626 this.selectedShapes.push(shape);
627 }
628
629 //Send the values to be updated
630 var thi = shape.strokeWeight;
631 var opa = shape.fillOpacity;
632 var fCol = shape.fillColor;
633 var sCol = shape.strokeColor;
634 var description = shape.description;
635 this.updateMenuValues(thi, opa, fCol, sCol, description);
636
637 } else if (shape.type == 'marker') {
638 this.allowDeselect = false;
639 this.selectedShapes.push(shape);
640 }
641 this.selectedShape = shape;
642 this.settingThePath();
643}
644
645MapEditor.prototype.removeFromSelectedShapes = function (shape) {
646 if (this.selectedShapes.includes(shape)) {
647 if (this.allowDeselect) {
648 const index = this.selectedShapes.indexOf(shape);
649 this.selectedShapes.splice(index, 1);
650 shape.setEditable(false);
651 }
652 this.allowDeselect = true;
653 }
654}
655
656//Set selected label
657MapEditor.prototype.setSelectedDescription = function (label) {
658 if (this.selectedShapes.length > 0) {
659 for (var i = 0; i < this.selectedShapes.length; i++) {
660 this.selectedShapes[i].set('description', label); //SAME: this.selectedShapes[i].description = label;
661 }
662 }
663}
664
665//Set selected thickness
666MapEditor.prototype.setSelectedThickness = function (sWeight) {
667 if (this.selectedShapes.length > 0) {
668 for (var i = 0; i < this.selectedShapes.length; i++) {
669 this.selectedShapes[i].set('strokeWeight', sWeight);
670 }
671 }
672}
673
674//Set selected opacity
675MapEditor.prototype.setSelectedOpacity = function (fOpacity) {
676
677 if (this.selectedShapes.length > 0) {
678 for (var i = 0; i < this.selectedShapes.length; i++) {
679 this.selectedShapes[i].set('fillOpacity', fOpacity);
680 }
681 }
682}
683
684//set selected fill colour
685MapEditor.prototype.setSelectedShapeColor = function (color) {
686 if (this.selectedShapes.length > 0) {
687 for (var i = 0; i < this.selectedShapes.length; i++) {
688 this.selectedShapes[i].set('fillColor', color);
689 this.selectedShapes[i].set('strokeColor', color);
690 }
691 }
692}
693
694MapEditor.prototype.getElementByXpath = function (path) {
695 return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
696}
697
698MapEditor.prototype.updateMenuValues = function (thi, opa, fCol, sCol, description) {
699 //Update thickness slider and value on the settings menu
700 var thicknessSliderOutput = document.getElementById("thicknessRangeVal" + "-" + this.id);
701 // update the thickness innerHTML's value to always have 2 decimal places, https://www.w3schools.com/js/js_number_methods.asp
702 thi = parseFloat(thi); //Ensure the thi is a number
703 thicknessSliderOutput.value = thi.toFixed(2);
704 document.getElementById("thicknessRange" + "-" + this.id).value = Math.round((thi * 20) * 100) / 100;
705
706 //Update the opacity slider and value on the settings menu
707 var opacitySliderOutput = document.getElementById("opacityRangeVal" + "-" + this.id);
708 opacitySliderOutput.value = opa * 100;
709 document.getElementById("colourOpacity" + "-" + this.id).value = opa * 100;
710
711 // Show the description in the description field
712 var descriptionInput = document.getElementById("description" + "-" + this.id);
713 descriptionInput.value = description;
714
715 if (this.drawingManager.drawingMode == null) {
716 this.selectColor(fCol);
717 }
718}
719MapEditor.prototype.selectAll = function () {
720 this.shiftKeyPressed = true;
721 var e = new Object();
722 e.vertex = undefined;
723 this.selectedShapes = [];
724 for (var i = 0; i < this.overlays.length; i++) {
725 this.setSelection(this.overlays[i], e);
726 }
727 this.shiftKeyPressed = false;
728}
729MapEditor.prototype.deselectAll = function () {
730 for (var i = 0; i < this.selectedShapes.length; i++) {
731 if (this.selectedShapes[i].type !== google.maps.drawing.OverlayType.MARKER) {
732 this.selectedShapes[i].setEditable(false);
733 }
734
735 }
736 this.selectedShapes = [];
737}
738
739// event handler for s being pressed *when map editor has the focus*
740// For saving and rebuilding, see map_scripts
741MapEditor.prototype.saveToArchives = function () {
742 var that = this;
743 console.log("Save pressed");
744
745 var json_overlays = JSON.stringify(ShapesUtil.overlayToJSON(this.overlays));
746 that.savedOverlays = json_overlays; // save the old version to compare with future changes
747 var collection = gs.cgiParams.c;
748 var site_name = gs.xsltParams.site_name;
749 var nodeID = this.id; // documentID, hopefully contains section ID too
750 var metaname = "GPS.mapOverlay";
751
752 // collection, site, documentID, metadataName, metadataPosition, metadataValue, prevMetadataValue, metamode, responseFunction
753 gs.functions.setArchivesMetadata(collection, site_name, nodeID, metaname, 0, json_overlays, null, "override", function(){
754 console.log("SAVED");
755 }
756 );
757}
758
759// TODO: When finished testing, can remove this debug function that just prints to console
760MapEditor.prototype.printHistory = function () {
761 console.log("prev", this.mapEditorHistory.prevOverlays);
762 console.log("present ", this.mapEditorHistory.presentOverlays);
763 console.log("undone ", this.mapEditorHistory.undoneOverlays);
764 console.log("@@@@ allShapes: ", this.overlays);
765 console.log("@@@@ selectedShapes: ", this.selectedShapes);
766}
767
768// to be called after reading back in stored JSON from archives meta
769MapEditor.prototype.LOAD = function (json_str, nodeID) {
770 this.mapEditorHistory.historyOverlayPush();
771
772
773 // This seems to convert the map_store object into an array and forces array index access, instead of convenient property access using nodeID
774 //Object.values(gsmap_store)[0]; // Always gets top level section's map-editor, not what we want.
775
776 // Get the map editor for the nodeID, as we're asked to load that editor
777 var map_editor = gsmap_store["map-"+nodeID];
778
779 var new_overlays = ShapesUtil.JSONToOverlays(json_str);
780 for (var i=0; i<map_editor.overlays.length; i++) {
781 map_editor.overlays[i].setMap(null);
782 }
783
784 map_editor.overlays = new_overlays;
785
786 for (var i=0; i<map_editor.overlays.length; i++) {
787 var shape = map_editor.overlays[i];
788 // make the shapes selectable on load:
789 if (ShapesUtil.overlayItemIsShape(shape)) {
790 map_editor.addShapeListeners(shape, null); // don't have an overlay event!
791 } else {
792 map_editor.addMarkerListeners(shape, null); // don't have an overlay event!
793 }
794 shape.setMap(map_editor.map);
795 }
796
797 this.mapEditorHistory.presentOverlayPush();
798}
799
800MapEditor.prototype.deleteSelectedShapes = function () {
801 if(this.selectedShapes.length !== 0) {
802 this.mapEditorHistory.historyOverlayPush();
803 for (var i = 0; i < this.selectedShapes.length; i++) {
804 this.selectedShapes[i].setMap(null);
805
806 if (this.overlays.includes(this.selectedShapes[i])) {
807 const index = this.overlays.indexOf(this.selectedShapes[i]);
808 this.overlays.splice(index, 1);
809// this.selectedShapes[i].setEditable(false);
810 }
811 }
812 this.selectedShapes = [];
813 this.mapEditorHistory.presentOverlayPush();
814 }
815}
816
817MapEditor.prototype.draggableState = function () {
818
819 var draggableCB = document.querySelector("input[name=draggableCB]");
820 draggableCB.addEventListener('change', function () {
821 if (this.checked) {
822 this.overlays.draggable = false;
823 } else {
824 this.overlays.draggable = false;
825 }
826 });
827}
828
829MapEditor.prototype.deleteAllShapes = function () {
830 if(this.overlays.length !== 0) {
831 //console.log("deleteAllShape() this.id = " + this.id);
832 this.mapEditorHistory.historyOverlayPush();
833 for (var i = 0; i < this.overlays.length; i++) {
834 this.overlays[i].setMap(null);
835 }
836 this.overlays = [];
837 this.mapEditorHistory.presentOverlayPush();
838 }
839}
Note: See TracBrowser for help on using the repository browser.