From 0637869318a295db22699226869d9748e9290655 Mon Sep 17 00:00:00 2001
From: default <mjbarrett@mcw.edu>
Date: Wed, 25 Sep 2024 17:52:35 +0000
Subject: [PATCH 1/6] improved mirroring

---
 src/viewers/viewer/controls/Mirror.js | 229 ++++++++++++--------------
 1 file changed, 105 insertions(+), 124 deletions(-)

diff --git a/src/viewers/viewer/controls/Mirror.js b/src/viewers/viewer/controls/Mirror.js
index c5d680861..c6b6a6e69 100644
--- a/src/viewers/viewer/controls/Mirror.js
+++ b/src/viewers/viewer/controls/Mirror.js
@@ -7,82 +7,54 @@ import { rotate } from 'ol/coordinate';
 export class Mirror extends Control {
     /**
      * @constructor
-     * @param {ol.control.MirrorOptions=} opt_options options. (className, target)
+     * @param {ol.control.MirrorOptions=} opt_options options. (className, target, flipX, flipY)
      */
-     constructor(opt_options) {
-        var options = opt_options ? opt_options : {};
+    constructor(opt_options) {
+        const options = opt_options || {};
 
-        var element = document.createElement('div');
+        const element = document.createElement('div');
         super({
             element: element,
             target: options.target
         });
 
-        /**
-        * @type {string}
-        * @private
-        */
-        this.class_name_ =
-            options.className === 'string' ? options.className : 'ol-flip';
-
-        /**
-         * @type {MapBrowserPointerEvent}
-         * @private
-         */
-        this.ref_ = null
-
-        /**
-         * @type {View}
-         */
-        this.view = null
-
-        /**
-         * @type {boolean}
-         * Sets default x inversion
-         */
-        this.flipX = 
-            typeof options.flipX == "boolean" ? options.flipX : false
-
-        /**
-         * @type {boolean}
-         * Sets default y inversion
-         */
-        this.flipY = 
-            typeof options.flipY == "boolean" ? options.flipY : false
-
-        var cssClasses =
-            this.class_name_ + ' ' + CLASS_UNSELECTABLE + ' ' +
-                CLASS_CONTROL;
-
-        // create button elements
+        this.class_name_ = typeof options.className === 'string' ? options.className : 'ol-flip';
+
+        this.ref_ = null;  // reference for handling events
+        
+        this.view = null;  // Map view reference
+        
+        this.initFlipX = typeof options.flipX === 'boolean' ? options.flipX : false;
+        this.initFlipY = typeof options.flipY === 'boolean' ? options.flipY : false;
+
+        const cssClasses = this.class_name_ + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
+
+        // Create button elements for flipping
         element.className = cssClasses;
-        var buttonGroup = document.createElement('div');
-        buttonGroup.className = "btn-group btn-group-sm ol-flip-buttons";
+        const buttonGroup = document.createElement('div');
+        buttonGroup.className = 'btn-group btn-group-sm ol-flip-buttons';
         buttonGroup.appendChild(this.addFlipButton(false));
         buttonGroup.appendChild(this.addFlipButton(true));
         element.appendChild(buttonGroup);
 
-        // need a map to finish intitialization
-        this.setMap_ = this.setMap
+        // Map setter override to initialize on map setup
+        this.setMap_ = this.setMap;
         this.setMap = (map) => {
-            this.setMap_(map)
-            if (map != null) this.init()
-        }
+            this.setMap_(map);
+            if (map != null) this.init();
+        };
     }
 
     /**
-     * Adds both, flip vertical and horizontal buttons
-     * @param {boolean} flip_vertical the vertical flip button is added if true, otherwise horizontal
+     * Adds a flip button for horizontal or vertical flip
+     * @param {boolean} flip_vertical Adds vertical flip if true, else horizontal
      * @private
      */
-     addFlipButton(flip_vertical) {
-        if (typeof flip_vertical !== 'boolean') flip_vertical = false;
-
-        var title = 'Flip ' + (flip_vertical ? 'vertical' : 'horizontal');
-        var element = document.createElement('button');
-        element.className =
-            this.class_name_ + (flip_vertical ? '-vertical glyphicon-resize-vertical' : '-horizontal glyphicon-resize-horizontal') +
-            " btn btn-default glyphicon ol-flip-button";
+    addFlipButton(flip_vertical) {
+        const title = `Flip ${flip_vertical ? 'vertical' : 'horizontal'}`;
+        const element = document.createElement('button');
+        element.className = this.class_name_ + (flip_vertical ? '-vertical glyphicon-resize-vertical' : '-horizontal glyphicon-resize-horizontal') +
+            ' btn btn-default glyphicon ol-flip-button';
         element.setAttribute('type', 'button');
         element.title = title;
 
@@ -91,82 +63,91 @@ export class Mirror extends Control {
         return element;
     }
 
-    init(){
-        this.view = this.getMap().getView()
-
-        this.getMap().getControls().getArray().forEach((control)=>{
-            if ('birds_eye_' in control){
-                this.birdseye = control
-                return
+    /**
+     * Initialization on map setup
+     */
+    init() {
+        const map = this.getMap()
+        this.view = map.getView();
+
+        map.getControls().getArray().forEach((control) => {
+            if ('birds_eye_' in control) {
+                this.birdseye = control;
+                return;
             }
-        })
-
-        this.view.constrainCenter_ = this.view.constrainCenter
-        this.view.constrainCenter = (center) => {
-            let curCenter = this.view.getCenter()
-            let rotation = this.view.getRotation()
-            // if there is rotation we need to undo it, mirror coords and then rerotate it
-            if (rotation != 0) {
-                rotate(center, Math.PI*2 - rotation)
-                rotate(curCenter, Math.PI*2 - rotation)
+        });
+        
+        map.getInteractions().getArray().forEach((interaction) => {
+            if (interaction.constructor.name == 'DragPan'){
+                interaction._mirror = this
+                interaction.updateTrackedPointers__ = interaction.updateTrackedPointers_
+                interaction.updateTrackedPointers_ = (mapBrowserEvent) => {
+                    if (this.view.get('flipX')) mapBrowserEvent.pointerEvent.clientX = mapBrowserEvent.pointerEvent.view.innerWidth - mapBrowserEvent.pointerEvent.clientX
+                    if (this.view.get('flipY')) mapBrowserEvent.pointerEvent.clientY = mapBrowserEvent.pointerEvent.view.innerHeight - mapBrowserEvent.pointerEvent.clientY
+                    return interaction.updateTrackedPointers__(mapBrowserEvent)
+                }
             }
-            if (this.view.values_.flipX) center[0] = curCenter[0]-(center[0]-curCenter[0])
-            if (this.view.values_.flipY) center[1] = curCenter[1]-(center[1]-curCenter[1])
-            if (rotation != 0) rotate(center, rotation)
-            return this.view.constrainCenter_(center)
-        }
-
-        // override getEventPixel to account for mirroring
-        this.map_.getEventPixel = function (evt) {
-            const viewportPosition = this.viewport_.getBoundingClientRect();
-            const eventPosition =
-                //FIXME Are we really calling this with a TouchEvent anywhere?
-                'changedTouches' in evt
-                ? /** @type {TouchEvent} */ (evt).changedTouches[0]
-                : /** @type {MouseEvent} */ (evt);
-
-            let x=eventPosition.clientX - viewportPosition.left
-            let y=eventPosition.clientY - viewportPosition.top
+        })
 
-            if (this.getView().flipX) x=viewportPosition.width-x
-            if (this.getView().flipY) y=viewportPosition.height-y
+        // Override getEventPixel to mirror the event based on flip state
+        map.getEventPixel = (evt) => {
+            const viewport = this.getMap().getViewport();
+            const viewportPosition = viewport.getBoundingClientRect();
+            const eventPosition = 'changedTouches' in evt ? evt.changedTouches[0] : evt;
+        
+            let x = eventPosition.clientX - viewportPosition.left;
+            let y = eventPosition.clientY - viewportPosition.top;
+        
+            // Apply flip transformations if necessary
+            if (this.view.get('flipX')) x = viewportPosition.width - x;
+            if (this.view.get('flipY')) y = viewportPosition.height - y;
+        
+            return [x, y];
+        };
 
-            return [x,y]
-        }
-        if (this.flipX) this.flip(1)
-        if (this.flipY) this.flip(0)
+        if (this.initFlipX) this.flip(1);
+        if (this.initFlipY) this.flip(0);
     }
 
-    // set desired transform and record in view
+    /**
+     * Apply or remove the flip transformation based on the axis
+     * @param {number} axis 0 for vertical flip (Y), 1 for horizontal flip (X)
+     */
     flip(axis) {
-        var viewport = this.getMap().getViewport().children[0] // (mirror just tiles)
-        let transform;
-        if (axis == 0) { 
-            transform="scaleY(-1)"
-            this.view.setProperties({flipY:!(this.view.values_.flipY)})
-        } else {
-            transform="scaleX(-1)"
-            this.view.setProperties({flipX:!(this.view.values_.flipX)})
+        const viewport = this.getMap().getViewport().children[0]; // Mirror only the tiles
+        const isY = (axis === 0);
+        const transformType = isY ? 'scaleY(-1)' : 'scaleX(-1)';
+        const viewProp = isY ? 'flipY' : 'flipX';
+
+        // Toggle the flip state in the view properties
+        const currentFlipState = this.view.get(viewProp);
+        this.view.set(viewProp, !currentFlipState);
+
+        // Update the viewport style transform
+        viewport.style.transform = currentFlipState ?
+            viewport.style.transform.replace(transformType, '') :
+            viewport.style.transform + ` ${transformType}`;
+
+        // Handle birds-eye control if present
+        if (this.birdseye && this.birdseye.controlDiv_) {
+            const birdseyeDiv = this.birdseye.controlDiv_;
+            birdseyeDiv.style.transform = currentFlipState ?
+                birdseyeDiv.style.transform.replace(transformType, '') :
+                birdseyeDiv.style.transform + ` ${transformType}`;
         }
-
-        // if it is already mirrored remove mirror, otherwise add mirror
-        viewport.style.transform = viewport.style.transform.includes(transform) ?
-            viewport.style.transform.replace(transform, "") : 
-            viewport.style.transform + transform
-        this.birdseye.controlDiv_.style.transform = this.birdseye.controlDiv_.style.transform.includes(transform) ?
-            this.birdseye.controlDiv_.style.transform.replace(transform, "") : 
-            this.birdseye.controlDiv_.style.transform + transform
     }
-  
+
+    /**
+     * Handle button click for flipping the map
+     * @param {Event} event Button click event
+     * @private
+     */
     handleClick_(event) {
-        // 0 axis if vertical ( flip y over x axis )
-        // 1 axis if hortizontal ( flip x over y axis )
         event.preventDefault();
-        var axis = event.target.className.indexOf("ol-flip-vertical") !== -1 ? 0 : 1;
-        
-        this.flip(axis)
-        return true
+        const axis = event.target.className.includes('ol-flip-vertical') ? 0 : 1;
+        this.flip(axis);
+        return true;
     }
-
 }
-export default Mirror
+
+export default Mirror;
\ No newline at end of file

From 71d3fde648fc3f6d00667fa8cb2cd6968df2f683 Mon Sep 17 00:00:00 2001
From: default <mjbarrett@mcw.edu>
Date: Thu, 3 Oct 2024 10:11:57 +0000
Subject: [PATCH 2/6] add flip indicator

---
 src/viewers/viewer/controls/Mirror.js | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/viewers/viewer/controls/Mirror.js b/src/viewers/viewer/controls/Mirror.js
index c6b6a6e69..3d7ee0daa 100644
--- a/src/viewers/viewer/controls/Mirror.js
+++ b/src/viewers/viewer/controls/Mirror.js
@@ -54,7 +54,7 @@ export class Mirror extends Control {
         const title = `Flip ${flip_vertical ? 'vertical' : 'horizontal'}`;
         const element = document.createElement('button');
         element.className = this.class_name_ + (flip_vertical ? '-vertical glyphicon-resize-vertical' : '-horizontal glyphicon-resize-horizontal') +
-            ' btn btn-default glyphicon ol-flip-button';
+            ' btn btn-default btn-primary glyphicon ol-flip-button';
         element.setAttribute('type', 'button');
         element.title = title;
 
@@ -144,7 +144,10 @@ export class Mirror extends Control {
      */
     handleClick_(event) {
         event.preventDefault();
-        const axis = event.target.className.includes('ol-flip-vertical') ? 0 : 1;
+        let classname = event.target.className
+        const axis = classname.includes('ol-flip-vertical') ? 0 : 1;
+        classname = classname.includes('active') ? classname.replace(' active', '') : classname += ' active'
+        event.target.className = classname
         this.flip(axis);
         return true;
     }

From 40edb27f97f84aa3f2b359bc510f6673a001f630 Mon Sep 17 00:00:00 2001
From: barrettMCW <mjbarrett@mcw.edu>
Date: Thu, 3 Oct 2024 13:52:15 +0000
Subject: [PATCH 3/6] fix dragpan bug in prod

---
 src/viewers/viewer/controls/Mirror.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/viewers/viewer/controls/Mirror.js b/src/viewers/viewer/controls/Mirror.js
index 3d7ee0daa..e868ad0bd 100644
--- a/src/viewers/viewer/controls/Mirror.js
+++ b/src/viewers/viewer/controls/Mirror.js
@@ -2,7 +2,7 @@ import {listen} from 'ol/events';
 import EventType from 'ol/events/EventType';
 import Control from 'ol/control/Control';
 import {CLASS_UNSELECTABLE, CLASS_CONTROL } from 'ol/css';
-import { rotate } from 'ol/coordinate';
+import DragPan from 'ol/interaction/DragPan';
 
 export class Mirror extends Control {
     /**
@@ -78,7 +78,7 @@ export class Mirror extends Control {
         });
         
         map.getInteractions().getArray().forEach((interaction) => {
-            if (interaction.constructor.name == 'DragPan'){
+            if (interaction instanceof DragPan){
                 interaction._mirror = this
                 interaction.updateTrackedPointers__ = interaction.updateTrackedPointers_
                 interaction.updateTrackedPointers_ = (mapBrowserEvent) => {

From 48f318c3dd6ff8c4f2a4c6b7d5b7daeca9d1358c Mon Sep 17 00:00:00 2001
From: barrettMCW <mjbarrett@mcw.edu>
Date: Thu, 3 Oct 2024 14:13:49 +0000
Subject: [PATCH 4/6] prettier flip indication

---
 src/viewers/viewer/controls/Mirror.js | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/viewers/viewer/controls/Mirror.js b/src/viewers/viewer/controls/Mirror.js
index e868ad0bd..2f77c87d8 100644
--- a/src/viewers/viewer/controls/Mirror.js
+++ b/src/viewers/viewer/controls/Mirror.js
@@ -144,11 +144,11 @@ export class Mirror extends Control {
      */
     handleClick_(event) {
         event.preventDefault();
-        let classname = event.target.className
-        const axis = classname.includes('ol-flip-vertical') ? 0 : 1;
-        classname = classname.includes('active') ? classname.replace(' active', '') : classname += ' active'
-        event.target.className = classname
+        event.target.style.backgroundColor = event.target.style.backgroundColor === 'silver' ? '' : 'silver'
+        
+        const axis = event.target.className.includes('ol-flip-vertical') ? 0 : 1;
         this.flip(axis);
+
         return true;
     }
 }

From 68b90aebf749c074bde218ba36d3ce662068cd05 Mon Sep 17 00:00:00 2001
From: barrettMCW <mjbarrett@mcw.edu>
Date: Fri, 4 Oct 2024 14:49:48 +0000
Subject: [PATCH 5/6] partial fix of DragSelect

---
 src/viewers/viewer/controls/Mirror.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/viewers/viewer/controls/Mirror.js b/src/viewers/viewer/controls/Mirror.js
index 2f77c87d8..425d8df1f 100644
--- a/src/viewers/viewer/controls/Mirror.js
+++ b/src/viewers/viewer/controls/Mirror.js
@@ -79,7 +79,6 @@ export class Mirror extends Control {
         
         map.getInteractions().getArray().forEach((interaction) => {
             if (interaction instanceof DragPan){
-                interaction._mirror = this
                 interaction.updateTrackedPointers__ = interaction.updateTrackedPointers_
                 interaction.updateTrackedPointers_ = (mapBrowserEvent) => {
                     if (this.view.get('flipX')) mapBrowserEvent.pointerEvent.clientX = mapBrowserEvent.pointerEvent.view.innerWidth - mapBrowserEvent.pointerEvent.clientX
@@ -115,6 +114,7 @@ export class Mirror extends Control {
      */
     flip(axis) {
         const viewport = this.getMap().getViewport().children[0]; // Mirror only the tiles
+        const selectionBox = this.getMap().getViewport().children[1]
         const isY = (axis === 0);
         const transformType = isY ? 'scaleY(-1)' : 'scaleX(-1)';
         const viewProp = isY ? 'flipY' : 'flipX';
@@ -128,6 +128,9 @@ export class Mirror extends Control {
             viewport.style.transform.replace(transformType, '') :
             viewport.style.transform + ` ${transformType}`;
 
+        selectionBox.style.transform = currentFlipState ?
+            selectionBox.style.transform.replace(transformType, '') :
+            selectionBox.style.transform + ` ${transformType}`;
         // Handle birds-eye control if present
         if (this.birdseye && this.birdseye.controlDiv_) {
             const birdseyeDiv = this.birdseye.controlDiv_;

From 233e0442b0f738b5aeffd80bd4c7549ea9d5cc81 Mon Sep 17 00:00:00 2001
From: barrettMCW <mjbarrett@mcw.edu>
Date: Wed, 16 Oct 2024 15:37:43 +0000
Subject: [PATCH 6/6] change selected button color

---
 src/viewers/viewer/controls/Mirror.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/viewers/viewer/controls/Mirror.js b/src/viewers/viewer/controls/Mirror.js
index 425d8df1f..0980a6d7c 100644
--- a/src/viewers/viewer/controls/Mirror.js
+++ b/src/viewers/viewer/controls/Mirror.js
@@ -147,7 +147,7 @@ export class Mirror extends Control {
      */
     handleClick_(event) {
         event.preventDefault();
-        event.target.style.backgroundColor = event.target.style.backgroundColor === 'silver' ? '' : 'silver'
+        event.target.style.backgroundColor = event.target.style.backgroundColor === 'dodgerblue' ? '' : 'dodgerblue'
         
         const axis = event.target.className.includes('ol-flip-vertical') ? 0 : 1;
         this.flip(axis);