diff --git a/src/navigator.js b/src/navigator.js index 9e18d6ca..bfc4e4cf 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -83,7 +83,7 @@ $.Navigator = function( options ){ options.controlOptions.width = options.width; } } - + } else { this.element = document.getElementById( options.id ); options.controlOptions = { @@ -216,21 +216,48 @@ $.Navigator = function( options ){ unneededElement.parentNode.removeChild(unneededElement); } - if (options.navigatorRotate) - { + if (options.navigatorRotate) { options.viewer.addHandler("rotate", function (args) { _setTransformRotate(_this.displayRegionContainer, args.degrees); _setTransformRotate(_this.displayRegion, -args.degrees); _this.viewport.setRotation(args.degrees); }); - } + + this.addHandler("reset-size", function() { + if (_this.viewport) { + _this.viewport.goHome(true); + } + }); + + this.addHandler("reset-size", function() { + if (_this.viewport) { + _this.viewport.goHome(true); + } + }); + + viewer.world.addHandler("item-index-changed", function(event) { + var item = _this.world.getItemAt(event.previousIndex); + _this.world.setItemIndex(item, event.newIndex); + }); + + viewer.world.addHandler("remove-item", function(event) { + var count = _this.world.getItemCount(); + var item; + for (var i = 0; i < count; i++) { + item = _this.world.getItemAt(i); + if (item._originalForNavigator === event.item) { + _this.world.removeItem(item); + break; + } + } + }); }; $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /** @lends OpenSeadragon.Navigator.prototype */{ /** - * Used to notify the navigator when its size has changed. + * 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 */ @@ -313,7 +340,16 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* }, - open: function( source ) { + /** + * Overrides Viewer.open + * @private + */ + open: function(source, options) { + var _this = this; + + var original = options.originalTiledImage; + delete options.original; + this.updateSize(); var containerSize = this.viewer.viewport.containerSize.times( this.sizeRatio ); var ts = source.getTileSize(source.maxLevel); @@ -322,9 +358,31 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* } else { this.minPixelRatio = this.viewer.minPixelRatio; } - return $.Viewer.prototype.open.apply( this, [ source ] ); - } + this.addHandler('open', function openHandler() { + _this.removeHandler(openHandler); + _this.world.getItemAt(0)._originalForNavigator = original; + }); + + return $.Viewer.prototype.open.apply( this, [source, options] ); + }, + + /** + * Overrides Viewer.addTiledImage + * @private + */ + addTiledImage: function(options) { + var original = options.originalTiledImage; + delete options.original; + + var optionsClone = $.extend({}, options, { + success: function(item) { + item._originalForNavigator = original; + } + }); + + return $.Viewer.prototype.addTiledImage.apply(this, [optionsClone]); + } }); /** diff --git a/src/viewer.js b/src/viewer.js index 388d6b1e..340734c5 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -409,6 +409,26 @@ $.Viewer = function( options ) { this.bindStandardControls(); this.bindSequenceControls(); + this.world = new $.World({ + viewer: this + }); + + this.world.addHandler('add-item', function(event) { + if (_this.viewport) { + _this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor()); + } + + THIS[ _this.hash ].forceRedraw = true; + }); + + this.world.addHandler('remove-item', function(event) { + if (_this.viewport) { + _this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor()); + } + + THIS[ _this.hash ].forceRedraw = true; + }); + if ( initialTileSource ) { this.open( initialTileSource ); @@ -544,7 +564,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, this.source = null; this.drawer = null; - this.world = null; + + this.world.removeAll(); this.viewport = this.preserveViewport ? this.viewport : null; @@ -1046,6 +1067,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, * @param {Number} [options.y=0] The Y position for the image in world coordinates. * @param {Number} [options.width=1] The width for the image in world coordinates. * @param {Number} [options.height] The height for the image in world coordinates. + * @param {Function} [options.success] A function that gets called when the image is + * successfully added. It's passed a single parameter: the resulting TiledImage. * @fires OpenSeadragon.World.event:add-item * @fires OpenSeadragon.Viewer.event:add-item-failed */ @@ -1112,6 +1135,19 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, _this.world.addItem( tiledImage, { index: options.index }); + + if (_this.navigator) { + var optionsClone = $.extend({}, options, { + originalTiledImage: tiledImage, + tileSource: tileSource + }); + + _this.navigator.addTiledImage(optionsClone); + } + + if (options.success) { + options.success(tiledImage); + } }, function( event ) { event.options = options; raiseAddItemFailed(event); @@ -1888,20 +1924,6 @@ function openTileSource( viewer, source, options ) { maxImageCacheCount: _this.maxImageCacheCount }); - _this.world = new $.World({ - viewer: _this - }); - - _this.world.addHandler('add-item', function(event) { - _this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor()); - THIS[ _this.hash ].forceRedraw = true; - }); - - _this.world.addHandler('remove-item', function(event) { - _this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor()); - THIS[ _this.hash ].forceRedraw = true; - }); - _this.drawer = new $.Drawer({ viewer: _this, viewport: _this.viewport, @@ -1956,9 +1978,7 @@ function openTileSource( viewer, source, options ) { if ( _this.showNavigator && !_this.collectionMode ){ // Note: By passing the fully parsed source, the navigator doesn't // have to load it again. - if ( _this.navigator ) { - _this.navigator.open( source ); - } else { + if (!_this.navigator) { _this.navigator = new $.Navigator({ id: _this.navigatorId, position: _this.navigatorPosition, @@ -1969,13 +1989,18 @@ function openTileSource( viewer, source, options ) { width: _this.navigatorWidth, height: _this.navigatorHeight, autoResize: _this.navigatorAutoResize, - tileSources: source, tileHost: _this.tileHost, prefixUrl: _this.prefixUrl, viewer: _this, navigatorRotate: _this.navigatorRotate }); } + + var optionsClone = $.extend({}, options, { + originalTiledImage: tiledImage + }); + + _this.navigator.open(source, optionsClone); } //Instantiate a referencestrip if configured diff --git a/src/world.js b/src/world.js index a9299edb..66b25f3c 100644 --- a/src/world.js +++ b/src/world.js @@ -51,6 +51,7 @@ $.World = function( options ) { this.viewer = options.viewer; this._items = []; + this._needsUpdate = false; this._figureSizes(); }; @@ -74,6 +75,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W } this._figureSizes(); + this._needsUpdate = true; /** * Raised when an item is added to the World. @@ -139,6 +141,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W this._items.splice( oldIndex, 1 ); this._items.splice( index, 0, item ); + this._needsUpdate = true; /** * Raised when the order of the indexes has been changed. @@ -175,17 +178,24 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W this._items.splice( index, 1 ); this._figureSizes(); + this._needsUpdate = true; + this._raiseRemoveItem(item); + }, - /** - * Raised when a item is removed. - * @event remove-item - * @memberOf OpenSeadragon.World - * @type {object} - * @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event. - * @property {OpenSeadragon.TiledImage} item - The item's underlying item. - * @property {?Object} userData - Arbitrary subscriber-defined object. - */ - this.raiseEvent( 'remove-item', { item: item } ); + /** + * Remove all items. + * @function + * @fires OpenSeadragon.World.event:remove-item + */ + removeAll: function() { + var removedItems = this._items; + this._items = []; + this._figureSizes(); + this._needsUpdate = true; + + for (var i = 0; i < removedItems.length; i++) { + this._raiseRemoveItem(removedItems[i]); + } }, /** @@ -206,6 +216,8 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W for ( var i = 0; i < this._items.length; i++ ) { this._items[i].update(); } + + this._needsUpdate = false; }, /** @@ -218,7 +230,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W return true; } } - return false; + return this._needsUpdate; }, /** @@ -270,6 +282,23 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W this._homeBounds = new $.Rect( left, top, right - left, bottom - top ); this._contentSize = new $.Point(this._homeBounds.width * this._contentFactor, this._homeBounds.height * this._contentFactor); + }, + + /** + * @function + * @private + */ + _raiseRemoveItem: function(item) { + /** + * Raised when a item is removed. + * @event remove-item + * @memberOf OpenSeadragon.World + * @type {object} + * @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event. + * @property {OpenSeadragon.TiledImage} item - The item's underlying item. + * @property {?Object} userData - Arbitrary subscriber-defined object. + */ + this.raiseEvent( 'remove-item', { item: item } ); } }); diff --git a/test/demo/collections/main.js b/test/demo/collections/main.js index 9eeb757c..2fdce509 100644 --- a/test/demo/collections/main.js +++ b/test/demo/collections/main.js @@ -9,12 +9,12 @@ this.viewer = OpenSeadragon( { debugMode: true, zoomPerScroll: 1.02, - // showNavigator: true, + showNavigator: true, id: "contentDiv", prefixUrl: "../../../build/openseadragon/images/" } ); - this.gridTest(); + this.crossTest(); }, // ---------- @@ -87,6 +87,15 @@ y: 0, width: 1 }); + }, + + // ---------- + bigTest: function() { + this.viewer.open("../../data/testpattern.dzi", { + x: -2, + y: -2, + width: 6 + }); } };