this.constModeThumb = 3;
// Zoom levels
+ // $$$ provide finer grained zooming
this.reductionFactors = [0.5, 1, 2, 4, 8, 16];
// Object to hold parameters related to 2up mode
}
$("#BookReader").empty();
+
this.initToolbar(this.mode, this.ui); // Build inside of toolbar div
$("#BookReader").append("<div id='BRcontainer'></div>");
$("#BRcontainer").append("<div id='BRpageview'></div>");
$("#BRcontainer").bind('scroll', this, function(e) {
e.data.loadLeafs();
});
-
+
this.setupKeyListeners();
this.startLocationPolling();
// $$$ refactor this so it's enough to set the first index and call preparePageView
// (get rid of mode-specific logic at this point)
if (1 == this.mode) {
- this.resizePageView();
this.firstIndex = startIndex;
+ this.prepareOnePageView();
this.jumpToIndex(startIndex);
} else if (3 == this.mode) {
this.firstIndex = startIndex;
}
-// setDragHandler()
+// bindGestures(jElement)
//______________________________________________________________________________
-BookReader.prototype.setDragHandler = function(div) {
- div.dragging = false;
-
- $(div).unbind('mousedown').bind('mousedown', function(e) {
- e.preventDefault();
-
- //console.log('mousedown at ' + e.pageY);
-
- this.dragging = true;
- this.prevMouseX = e.pageX;
- this.prevMouseY = e.pageY;
-
- var startX = e.pageX;
- var startY = e.pageY;
- var startTop = $('#BRcontainer').attr('scrollTop');
- var startLeft = $('#BRcontainer').attr('scrollLeft');
-
- });
-
- $(div).unbind('mousemove').bind('mousemove', function(ee) {
- ee.preventDefault();
-
- // console.log('mousemove ' + ee.pageX + ',' + ee.pageY);
-
- var offsetX = ee.pageX - this.prevMouseX;
- var offsetY = ee.pageY - this.prevMouseY;
-
- if (this.dragging) {
- $('#BRcontainer').attr('scrollTop', $('#BRcontainer').attr('scrollTop') - offsetY);
- $('#BRcontainer').attr('scrollLeft', $('#BRcontainer').attr('scrollLeft') - offsetX);
- }
-
- this.prevMouseX = ee.pageX;
- this.prevMouseY = ee.pageY;
-
- });
-
- $(div).unbind('mouseup').bind('mouseup', function(ee) {
- ee.preventDefault();
- //console.log('mouseup');
-
- this.dragging = false;
- });
-
- $(div).unbind('mouseleave').bind('mouseleave', function(e) {
- e.preventDefault();
- //console.log('mouseleave');
-
- this.dragging = false;
- });
-
- $(div).unbind('mouseenter').bind('mouseenter', function(e) {
- e.preventDefault();
- //console.log('mouseenter');
-
- this.dragging = false;
- });
-}
+BookReader.prototype.bindGestures = function(jElement) {
-// setDragHandler2UP()
-//______________________________________________________________________________
-BookReader.prototype.setDragHandler2UP = function(div) {
- div.dragging = false;
-
- $(div).unbind('mousedown').bind('mousedown', function(e) {
+ jElement.unbind('gesturechange').bind('gesturechange', function(e) {
e.preventDefault();
-
- //console.log('mousedown at ' + e.pageY);
-
- this.dragStart = {x: e.pageX, y: e.pageY };
- this.mouseDown = true;
- this.dragging = false; // wait until drag distance
- this.prevMouseX = e.pageX;
- this.prevMouseY = e.pageY;
-
- var startX = e.pageX;
- var startY = e.pageY;
- var startTop = $('#BRcontainer').attr('scrollTop');
- var startLeft = $('#BRcontainer').attr('scrollLeft');
-
- });
-
- $(div).unbind('mousemove').bind('mousemove', function(ee) {
- ee.preventDefault();
-
- // console.log('mousemove ' + ee.pageX + ',' + ee.pageY);
-
- var offsetX = ee.pageX - this.prevMouseX;
- var offsetY = ee.pageY - this.prevMouseY;
-
- var minDragDistance = 5; // $$$ constant
-
- var distance = Math.max(Math.abs(offsetX), Math.abs(offsetY));
-
- if (this.mouseDown && (distance > minDragDistance)) {
- //console.log('drag start!');
-
- this.dragging = true;
+ if (e.originalEvent.scale > 1.5) {
+ br.zoom(1);
+ } else if (e.originalEvent.scale < 0.6) {
+ br.zoom(-1);
}
-
- if (this.dragging) {
- $('#BRcontainer').attr('scrollTop', $('#BRcontainer').attr('scrollTop') - offsetY);
- $('#BRcontainer').attr('scrollLeft', $('#BRcontainer').attr('scrollLeft') - offsetX);
- this.prevMouseX = ee.pageX;
- this.prevMouseY = ee.pageY;
- }
-
-
- });
-
- /*
- $(div).unbind('mouseup').bind('mouseup', function(ee) {
- ee.preventDefault();
- //console.log('mouseup');
-
- this.dragging = false;
- this.mouseDown = false;
});
- */
-
-
- $(div).unbind('mouseleave').bind('mouseleave', function(e) {
- e.preventDefault();
- //console.log('mouseleave');
-
- this.dragging = false;
- this.mouseDown = false;
- });
-
- $(div).unbind('mouseenter').bind('mouseenter', function(e) {
- e.preventDefault();
- //console.log('mouseenter');
- this.dragging = false;
- this.mouseDown = false;
- });
}
BookReader.prototype.setClickHandler2UP = function( element, data, handler) {
//console.log('setting handler');
//console.log(element.tagName);
- $(element).unbind('click').bind('click', data, function(e) {
- e.preventDefault();
-
- //console.log('click!');
-
- if (this.mouseDown && (!this.dragging)) {
- //console.log('click not dragging!');
- handler(e);
- }
-
- this.dragging = false;
- this.mouseDown = false;
+ $(element).unbind('tap').bind('tap', data, function(e) {
+ handler(e);
});
}
$(div).css('height', height+'px');
//$(div).text('loading...');
- this.setDragHandler(div);
-
$('#BRpageview').append(div);
var img = document.createElement("img");
// drawLeafsThumbnail()
//______________________________________________________________________________
-BookReader.prototype.drawLeafsThumbnail = function() {
+// If seekIndex is defined, the view will be drawn with that page visible (without any
+// animated scrolling)
+BookReader.prototype.drawLeafsThumbnail = function( seekIndex ) {
//alert('drawing leafs!');
this.timer = null;
-
+
var viewWidth = $('#BRcontainer').attr('scrollWidth') - 20; // width minus buffer
//console.log('top=' + scrollTop + ' bottom='+scrollBottom);
var leafMap = [];
var self = this;
+
+ // Will be set to top of requested seek index, if set
+ var seekTop;
// Calculate the position of every thumbnail. $$$ cache instead of calculating on every draw
for (i=0; i<this.numLeafs; i++) {
rightPos += leafWidth + this.padding;
if (rightPos > maxRight) { maxRight = rightPos; }
leafIndex++;
+
+ if (i == seekIndex) {
+ seekTop = bottomPos - this.padding - leafMap[currentRow].height;
+ }
}
// reset the bottom position based on thumbnails
$('#BRpageview').height(bottomPos);
var pageViewBuffer = Math.floor(($('#BRcontainer').attr('scrollWidth') - maxRight) / 2) - 14;
+
+ // If seekTop is defined, seeking was requested and target found
+ if (typeof(seekTop) != 'undefined') {
+ $('#BRcontainer').scrollTop( seekTop );
+ }
+
var scrollTop = $('#BRcontainer').attr('scrollTop');
var scrollBottom = scrollTop + $('#BRcontainer').height();
// link to page in single page mode
link = document.createElement("a");
$(link).data('leaf', leaf);
- $(link).bind('click', function(event) {
+ $(link).bind('tap', function(event) {
self.firstIndex = $(this).data('leaf');
self.switchMode(self.constMode1up);
event.preventDefault();
// e.g. does not preserve position in thumbnail mode
// See http://bugs.launchpad.net/bookreader/+bug/552972
+ switch (this.mode) {
+ case this.constMode1up:
+ case this.constMode2up:
+ this.resizePageView1up();
+ break;
+ case this.constModeThumb:
+ this.prepareThumbnailView( this.currentIndex() );
+ break;
+ default:
+ alert('Resize not implemented for this mode');
+ }
+}
+
+BookReader.prototype.resizePageView1up = function() {
var i;
var viewHeight = 0;
//var viewWidth = $('#BRcontainer').width(); //includes scrollBar
if (width>viewWidth) viewWidth=width;
}
$('#BRpageview').height(viewHeight);
- $('#BRpageview').width(viewWidth);
+ $('#BRpageview').width(viewWidth);
var newCenterY = scrollRatio*viewHeight;
var newTop = Math.max(0, Math.floor( newCenterY - $('#BRcontainer').height()/2 ));
//this.centerPageView();
this.loadLeafs();
-
- // $$$ jump to index here? index is not preserved when resizing in thumb mode
-
- // Not really needed until there is 1up autofit
+
this.removeSearchHilites();
this.updateSearchHilites();
}
+
// centerX1up()
//______________________________________________________________________________
// Returns the current offset of the viewport center in scaled document coordinates.
if (this.thumbColumns != oldColumns) {
this.prepareThumbnailView();
- this.jumpToIndex(this.currentIndex());
}
}
leafIndex = 0;
}
- // $$$ leaf is not defined in this function -- leaking in from somewhere else
- leafHeight = parseInt((this.getPageHeight(leaf)*this.thumbWidth)/this.getPageWidth(leaf), 10);
+ leafHeight = parseInt((this.getPageHeight(leafIndex)*this.thumbWidth)/this.getPageWidth(leafIndex), 10);
if (leafHeight > rowHeight) { rowHeight = leafHeight; }
if (leafIndex==0) { leafTop = bottomPos; }
if (leafIndex==0) { bottomPos += this.padding + rowHeight; }
} else if (3 == mode) {
this.reduce = this.quantizeReduce(this.reduce);
this.prepareThumbnailView();
- this.jumpToIndex(this.currentIndex());
} else {
// $$$ why don't we save autofit?
this.twoPage.autofit = false; // Take zoom level from other mode
// var startLeaf = this.displayedIndices[0];
var startLeaf = this.currentIndex();
-
+
$('#BRcontainer').empty();
$('#BRcontainer').css({
overflowY: 'scroll',
overflowX: 'auto'
});
-
+
$("#BRcontainer").append("<div id='BRpageview'></div>");
+
+ // Attaches to first child - child must be present
+ $('#BRcontainer').dragscrollable();
+ this.bindGestures($('#BRcontainer'));
+
// $$$ keep select enabled for now since disabling it breaks keyboard
// nav in FF 3.6 (https://bugs.edge.launchpad.net/bookreader/+bug/544666)
// BookReader.util.disableSelect($('#BRpageview'));
- this.resizePageView();
+ this.resizePageView();
this.jumpToIndex(startLeaf);
this.displayedIndices = [];
overflowY: 'scroll',
overflowX: 'auto'
});
-
+
$("#BRcontainer").append("<div id='BRpageview'></div>");
+
+ $('#BRcontainer').dragscrollable();
+ this.bindGestures($('#BRcontainer'));
// $$$ keep select enabled for now since disabling it breaks keyboard
// nav in FF 3.6 (https://bugs.edge.launchpad.net/bookreader/+bug/544666)
// BookReader.util.disableSelect($('#BRpageview'));
- var startLeaf = this.currentIndex();
this.thumbWidth = this.getThumbnailWidth(this.thumbColumns);
this.reduce = this.getPageWidth(0)/this.thumbWidth;
- this.resizePageView();
-
this.displayedRows = [];
+
+ // Draw leafs with current index directly in view (no animating to the index)
+ this.drawLeafsThumbnail( this.currentIndex() );
- // $$$ resizePageView will do a delayed load -- this will make it happen faster
- this.drawLeafsThumbnail();
}
// prepareTwoPageView()
// Add the two page view
// $$$ Can we get everything set up and then append?
$('#BRcontainer').append('<div id="BRtwopageview"></div>');
+
+ // Attaches to first child, so must come after we add the page view
+ $('#BRcontainer').dragscrollable();
+ this.bindGestures($('#BRcontainer'));
// $$$ calculate first then set
$('#BRtwopageview').css( {
this.firstIndex = index;
}
-/*
-// Returns the current index if visible, or the logically current visible
-// thumbnail
-BookReader.prototype.currentIndexOrVisibleThumb = function() {
- // XXX finish implementation
- var index = this.currentIndex();
- if (!this.indexIsVisbleThumb(this.currentIndex()) {
- // XXX search for visible
- }
- return index;
-}
-
-// Returns true if the given index is visible
-BookReader.prototype.indexIsVisibleThumb = function(index, onlyCompletelyVisible = true) {
- // XXX implement
- // $$$ I'd prefer to go through a stored leaf map instead of DOM
-
-
-}
-*/
-
// right()
//______________________________________________________________________________
// setMouseHandlers2UP
//______________________________________________________________________________
BookReader.prototype.setMouseHandlers2UP = function() {
- /*
- $(this.prefetchedImgs[this.twoPage.currentIndexL]).bind('dblclick', function() {
- //self.prevPage();
- self.autoStop();
- self.left();
- });
- $(this.prefetchedImgs[this.twoPage.currentIndexR]).bind('dblclick', function() {
- //self.nextPage();'
- self.autoStop();
- self.right();
- });
- */
-
- this.setDragHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexL] );
this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexL],
{ self: this },
function(e) {
e.data.self.left();
+ e.preventDefault();
}
);
- this.setDragHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexR] );
this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexR],
{ self: this },
function(e) {
e.data.self.right();
+ e.preventDefault();
}
);
}
this.updateToolbarZoom(this.reduce); // Pretty format
- if (ui == "embed") {
+ if (ui == "embed" || ui == "touch") {
$("#BookReader a.logo").attr("target","_blank");
}