Merge pull request #341 from fs-webdev/rotate-buttons

Added Rotate Left/Right buttons to standard controls
This commit is contained in:
iangilman 2014-03-07 10:05:36 -08:00
commit 08568b5354
13 changed files with 179 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
images/rotateleft_hover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/rotateleft_rest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/rotateright_rest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -336,6 +336,11 @@
* image and if the 'next' button will wrap to the first image when viewing * image and if the 'next' button will wrap to the first image when viewing
* the last image. * the last image.
* *
* @property {Boolean} [showRotationControl=false]
* If true then the rotate left/right controls will be displayed as part of the
* standard controls. This is also subject to the browser support for rotate
* (e.g. viewer.drawer.canRotate()).
*
* @property {Boolean} [showSequenceControl=true] * @property {Boolean} [showSequenceControl=true]
* If the viewer has been configured with a sequence of tile sources, then * If the viewer has been configured with a sequence of tile sources, then
* provide buttons for navigating forward and backward through the images. * provide buttons for navigating forward and backward through the images.
@ -793,6 +798,18 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
HOVER: 'fullpage_hover.png', HOVER: 'fullpage_hover.png',
DOWN: 'fullpage_pressed.png' DOWN: 'fullpage_pressed.png'
}, },
rotateleft: {
REST: 'rotateleft_rest.png',
GROUP: 'rotateleft_grouphover.png',
HOVER: 'rotateleft_hover.png',
DOWN: 'rotateleft_pressed.png'
},
rotateright: {
REST: 'rotateright_rest.png',
GROUP: 'rotateright_grouphover.png',
HOVER: 'rotateright_hover.png',
DOWN: 'rotateright_pressed.png'
},
previous: { previous: {
REST: 'previous_rest.png', REST: 'previous_rest.png',
GROUP: 'previous_grouphover.png', GROUP: 'previous_grouphover.png',
@ -807,6 +824,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
} }
}, },
navPrevNextWrap: false, navPrevNextWrap: false,
showRotationControl: false,
//DEVELOPER SETTINGS //DEVELOPER SETTINGS
debugMode: false, debugMode: false,

View File

@ -55,7 +55,9 @@ var I18N = {
ZoomIn: "Zoom in", ZoomIn: "Zoom in",
ZoomOut: "Zoom out", ZoomOut: "Zoom out",
NextPage: "Next page", NextPage: "Next page",
PreviousPage: "Previous page" PreviousPage: "Previous page",
RotateLeft: "Rotate left",
RotateRight: "Rotate right"
} }
}; };

View File

@ -1153,6 +1153,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
doSingleZoomOutHandler = $.delegate( this, doSingleZoomOut ), doSingleZoomOutHandler = $.delegate( this, doSingleZoomOut ),
onHomeHandler = $.delegate( this, onHome ), onHomeHandler = $.delegate( this, onHome ),
onFullScreenHandler = $.delegate( this, onFullScreen ), onFullScreenHandler = $.delegate( this, onFullScreen ),
onRotateLeftHandler = $.delegate( this, onRotateLeft ),
onRotateRightHandler = $.delegate( this, onRotateRight ),
onFocusHandler = $.delegate( this, onFocus ), onFocusHandler = $.delegate( this, onFocus ),
onBlurHandler = $.delegate( this, onBlur ), onBlurHandler = $.delegate( this, onBlur ),
navImages = this.navImages, navImages = this.navImages,
@ -1232,6 +1234,37 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
onBlur: onBlurHandler onBlur: onBlurHandler
})); }));
if (this.showRotationControl) {
buttons.push( this.rotateLeft = new $.Button({
element: this.rotateLeftButton ? $.getElement( this.rotateLeftButton ) : null,
clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold,
tooltip: $.getString( "Tooltips.RotateLeft" ),
srcRest: resolveUrl( this.prefixUrl, navImages.rotateleft.REST ),
srcGroup: resolveUrl( this.prefixUrl, navImages.rotateleft.GROUP ),
srcHover: resolveUrl( this.prefixUrl, navImages.rotateleft.HOVER ),
srcDown: resolveUrl( this.prefixUrl, navImages.rotateleft.DOWN ),
onRelease: onRotateLeftHandler,
onFocus: onFocusHandler,
onBlur: onBlurHandler
}));
buttons.push( this.rotateRight = new $.Button({
element: this.rotateRightButton ? $.getElement( this.rotateRightButton ) : null,
clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold,
tooltip: $.getString( "Tooltips.RotateRight" ),
srcRest: resolveUrl( this.prefixUrl, navImages.rotateright.REST ),
srcGroup: resolveUrl( this.prefixUrl, navImages.rotateright.GROUP ),
srcHover: resolveUrl( this.prefixUrl, navImages.rotateright.HOVER ),
srcDown: resolveUrl( this.prefixUrl, navImages.rotateright.DOWN ),
onRelease: onRotateRightHandler,
onFocus: onFocusHandler,
onBlur: onBlurHandler
}));
}
if( useGroup ){ if( useGroup ){
this.buttons = new $.ButtonGroup({ this.buttons = new $.ButtonGroup({
buttons: buttons, buttons: buttons,
@ -1470,6 +1503,21 @@ function openTileSource( viewer, source ) {
debugGridColor: _this.debugGridColor debugGridColor: _this.debugGridColor
}); });
// Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttons
if (!_this.drawer.canRotate()) {
// Disable/remove the rotate left/right buttons since they aren't supported
if (_this.rotateLeft) {
i = _this.buttons.buttons.indexOf(_this.rotateLeft);
_this.buttons.buttons.splice(i, 1);
_this.buttons.element.removeChild(_this.rotateLeft.element);
}
if (_this.rotateRight) {
i = _this.buttons.buttons.indexOf(_this.rotateRight);
_this.buttons.buttons.splice(i, 1);
_this.buttons.element.removeChild(_this.rotateRight.element);
}
}
//Instantiate a navigator if configured //Instantiate a navigator if configured
if ( _this.showNavigator && !_this.collectionMode ){ if ( _this.showNavigator && !_this.collectionMode ){
// Note: By passing the fully parsed source, the navigator doesn't // Note: By passing the fully parsed source, the navigator doesn't
@ -2116,6 +2164,38 @@ function onFullScreen() {
} }
} }
/**
* Note: The current rotation feature is limited to 90 degree turns.
*/
function onRotateLeft() {
if ( this.viewport ) {
var currRotation = this.viewport.getRotation();
if (currRotation === 0) {
currRotation = 270;
}
else {
currRotation -= 90;
}
this.viewport.setRotation(currRotation);
}
}
/**
* Note: The current rotation feature is limited to 90 degree turns.
*/
function onRotateRight() {
if ( this.viewport ) {
var currRotation = this.viewport.getRotation();
if (currRotation === 270) {
currRotation = 0;
}
else {
currRotation += 90;
}
this.viewport.setRotation(currRotation);
}
}
function onPrevious(){ function onPrevious(){
var previous = THIS[ this.hash ].sequence - 1; var previous = THIS[ this.hash ].sequence - 1;

77
test/rotate.js Normal file
View File

@ -0,0 +1,77 @@
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */
(function () {
var viewer;
module('Basic', {
setup: function () {
var example = $('<div id="rotateTests"></div>').appendTo("#qunit-fixture");
testLog.reset();
},
teardown: function () {
if (viewer && viewer.close) {
viewer.close();
}
viewer = null;
}
});
asyncTest('RotateControlOff', function () {
var openHandler = function (event) {
viewer.removeHandler('open', openHandler);
ok(true, 'Open event was sent');
ok(viewer.drawer, 'Drawer exists');
ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true');
ok(!viewer.showRotationControl, 'showRotationControl should be off');
ok(!viewer.rotateLeft, "rotateLeft button should be null");
ok(!viewer.rotateRight, "rotateRight button should be null");
start();
};
viewer = OpenSeadragon({
id: 'rotateTests',
prefixUrl: '/build/openseadragon/images/',
springStiffness: 100, // Faster animation = faster tests
showRotationControl: false
});
viewer.addHandler('open', openHandler);
viewer.open('/test/data/testpattern.dzi');
});
asyncTest('RotateControlOn', function () {
var openHandler = function (event) {
viewer.removeHandler('open', openHandler);
ok(true, 'Open event was sent');
ok(viewer.drawer, 'Drawer exists');
ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true');
ok(viewer.showRotationControl, 'showRotationControl should be true');
ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft should be found");
ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight should be found");
// Now simulate the left/right button clicks. Security prevents us from simulating a click,
// so we will call the 'onRelease' handler for the button
ok(viewer.viewport.degrees === 0, "Image should start at 0 degrees rotation");
viewer.rotateLeft.onRelease();
ok(viewer.viewport.degrees === 270, "Image should be 270 degrees rotation (left)");
viewer.rotateRight.onRelease();
ok(viewer.viewport.degrees === 0, "Image should be 270 degrees rotation (right)");
start();
};
viewer = OpenSeadragon({
id: 'rotateTests',
prefixUrl: '/build/openseadragon/images/',
springStiffness: 100, // Faster animation = faster tests
showRotationControl: true
});
viewer.addHandler('open', openHandler);
viewer.open('/test/data/testpattern.dzi');
});
})();

View File

@ -27,5 +27,6 @@
<script src="/test/utils.js"></script> <script src="/test/utils.js"></script>
<script src="/test/events.js"></script> <script src="/test/events.js"></script>
<script src="/test/units.js"></script> <script src="/test/units.js"></script>
<script src="/test/rotate.js"></script>
</body> </body>
</html> </html>