From 1e9ea154f2afd7ebecfd893d7258421740a5f22e Mon Sep 17 00:00:00 2001
From: Mark Salsbery <msalsbery@hotmail.com>
Date: Sat, 14 Dec 2013 14:45:11 -0800
Subject: [PATCH] Added navigatorAutoResize option

Improved resizable navigator support.
---
 src/navigator.js     | 53 ++++++++++++++++++++++++++++++++++++++------
 src/openseadragon.js |  5 +++++
 src/viewer.js        |  1 +
 3 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/src/navigator.js b/src/navigator.js
index bfd51980..6461659a 100644
--- a/src/navigator.js
+++ b/src/navigator.js
@@ -105,7 +105,8 @@ $.Navigator = function( options ){
         showSequenceControl:    false,
         immediateRender:        true,
         blendTime:              0,
-        animationTime:          0
+        animationTime:          0,
+        autoResize:             options.autoResize
     });
 
     options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio;
@@ -193,6 +194,8 @@ $.Navigator = function( options ){
         }
     }
 
+    this.oldContainerSize = new $.Point( 0, 0 );
+
     $.Viewer.apply( this, [ options ] );
 
     this.element.getElementsByTagName('form')[0].appendChild( this.displayRegion );
@@ -206,9 +209,43 @@ $.Navigator = function( options ){
 $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /** @lends OpenSeadragon.Navigator.prototype */{
 
     /**
+     * Used to notify the navigator when its size has changed. 
+     * Especially useful when {@link OpenSeadragon.Options}.navigatorAutoResize is set to false and the navigator is resizable.
      * @function
      */
-    update: function( viewport ){
+    updateSize: function () {
+        if ( this.viewport ) {
+            var containerSize = new $.Point(
+                    (this.container.clientWidth === 0 ? 1 : this.container.clientWidth),
+                    (this.container.clientHeight === 0 ? 1 : this.container.clientHeight)
+                );
+            if ( !containerSize.equals( this.oldContainerSize ) ) {
+                var oldBounds = this.viewport.getBounds();
+                var oldCenter = this.viewport.getCenter();
+                this.viewport.resize( containerSize, true );
+                var imageHeight = 1 / this.source.aspectRatio;
+                var newWidth = oldBounds.width <= 1 ? oldBounds.width : 1;
+                var newHeight = oldBounds.height <= imageHeight ?
+                    oldBounds.height : imageHeight;
+                var newBounds = new $.Rect(
+                    oldCenter.x - ( newWidth / 2.0 ),
+                    oldCenter.y - ( newHeight / 2.0 ),
+                    newWidth,
+                    newHeight
+                    );
+                this.viewport.fitBounds( newBounds, true );
+                this.oldContainerSize = containerSize;
+                this.drawer.update();
+            }
+        }
+    },
+
+    /**
+     * Used to update the navigator minimap's viewport rectangle when a change in the viewer's viewport occurs.
+     * @function
+     * @param {OpenSeadragon.Viewport} The viewport this navigator is tracking.
+     */
+    update: function( viewport ) {
 
         var viewerSize,
             bounds,
@@ -217,17 +254,18 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
 
         if ( this.maintainSizeRatio ) {
             viewerSize = $.getElementSize( this.viewer.element );
-            if ( !viewerSize.equals ( this.oldViewerSize ) ) {
+            if ( !viewerSize.equals( this.oldViewerSize ) ) {
                 this.element.style.height = ( viewerSize.y * this.sizeRatio ) + 'px';
                 this.element.style.width  = ( viewerSize.x * this.sizeRatio ) + 'px';
                 this.oldViewerSize = viewerSize;
+                this.updateSize();
             }
         }
 
-        if( viewport && this.viewport ){
+        if( viewport && this.viewport ) {
             bounds      = viewport.getBounds( true );
-            topleft     = this.viewport.pixelFromPoint( bounds.getTopLeft());
-            bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight()).minus(this.totalBorderWidths);
+            topleft     = this.viewport.pixelFromPoint( bounds.getTopLeft(), false );
+            bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight(), false ).minus( this.totalBorderWidths );
 
             //update style for navigator-box
             (function(style) {
@@ -246,7 +284,8 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
 
     },
 
-    open: function( source ){
+    open: function( source ) {
+        this.updateSize();
         var containerSize = this.viewer.viewport.containerSize.times( this.sizeRatio );
         if( source.tileSize > containerSize.x ||
             source.tileSize > containerSize.y ){
diff --git a/src/openseadragon.js b/src/openseadragon.js
index 43ad51a9..9ee18112 100644
--- a/src/openseadragon.js
+++ b/src/openseadragon.js
@@ -300,6 +300,10 @@
   *     Specifies the size of the navigator minimap (see navigatorPosition).
   *     If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.
   *
+  * @property {Boolean} [navigatorAutoResize=true]
+  *     Set to false to prevent polling for navigator size changes. Useful for providing custom resize behavior.
+  *     Setting to false can also improve performance when the navigator is configured to a fixed size.
+  *
   * @property {Number} [controlsFadeDelay=2000]
   *     The number of milliseconds to wait once the user has stopped interacting
   *     with the interface before begining to fade the controls. Assumes
@@ -736,6 +740,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
             navigatorLeft:              null,
             navigatorHeight:            null,
             navigatorWidth:             null,
+            navigatorAutoResize:        true,
 
             // INITIAL ROTATION
             degrees:                0,
diff --git a/src/viewer.js b/src/viewer.js
index 06a8858f..2139678e 100644
--- a/src/viewer.js
+++ b/src/viewer.js
@@ -1484,6 +1484,7 @@ function openTileSource( viewer, source ) {
                 left:              _this.navigatorLeft,
                 width:             _this.navigatorWidth,
                 height:            _this.navigatorHeight,
+                autoResize:        _this.navigatorAutoResize,
                 tileSources:       source,
                 tileHost:          _this.tileHost,
                 prefixUrl:         _this.prefixUrl,