E-book viewer: Try to preserve page position when the window is resized

This commit is contained in:
Kovid Goyal 2012-03-22 13:12:51 +05:30
parent 91fb0462b1
commit 3fa649358b
2 changed files with 29 additions and 36 deletions

View File

@ -8,7 +8,7 @@ import os, math, re, glob, sys, zipfile
from base64 import b64encode
from functools import partial
from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer,
from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt,
QPainter, QPalette, QBrush, QFontDatabase, QDialog,
QColor, QPoint, QImage, QRegion, QVariant, QIcon,
QFont, pyqtSignature, QAction, QByteArray, QMenu,
@ -184,12 +184,10 @@ class Document(QWebPage): # {{{
self.misc_config()
self.after_load()
def __init__(self, shortcuts, parent=None, resize_callback=lambda: None,
debug_javascript=False):
def __init__(self, shortcuts, parent=None, debug_javascript=False):
QWebPage.__init__(self, parent)
self.setObjectName("py_bridge")
self.debug_javascript = debug_javascript
self.resize_callback = resize_callback
self.current_language = None
self.loaded_javascript = False
self.js_loader = JavaScriptLoader(
@ -259,12 +257,6 @@ class Document(QWebPage): # {{{
if self.loaded_javascript:
return
self.loaded_javascript = True
self.javascript(
'''
window.onresize = function(event) {
window.py_bridge.window_resized();
}
''')
self.loaded_lang = self.js_loader(self.mainFrame().evaluateJavaScript,
self.current_language, self.hyphenate_default_lang)
@ -310,10 +302,6 @@ class Document(QWebPage): # {{{
def debug(self, msg):
prints(msg)
@pyqtSignature('')
def window_resized(self):
self.resize_callback()
def reference_mode(self, enable):
self.javascript(('enter' if enable else 'leave')+'_reference_mode()')
@ -444,7 +432,7 @@ class Document(QWebPage): # {{{
def scroll_fraction(self):
def fget(self):
try:
return float(self.ypos)/(self.height-self.window_height)
return abs(float(self.ypos)/(self.height-self.window_height))
except ZeroDivisionError:
return 0.
def fset(self, val):
@ -516,7 +504,6 @@ class DocumentView(QWebView): # {{{
self.initial_pos = 0.0
self.to_bottom = False
self.document = Document(self.shortcuts, parent=self,
resize_callback=self.viewport_resized,
debug_javascript=debug_javascript)
self.setPage(self.document)
self.manager = None
@ -1035,13 +1022,9 @@ class DocumentView(QWebView): # {{{
return handled
def resizeEvent(self, event):
ret = QWebView.resizeEvent(self, event)
QTimer.singleShot(10, self.initialize_scrollbar)
return ret
def viewport_resized(self):
if self.manager is not None:
self.manager.viewport_resized(self.scroll_fraction)
self.manager.viewport_resize_started(event)
return QWebView.resizeEvent(self, event)
def event(self, ev):
if ev.type() == ev.Gesture:

View File

@ -224,6 +224,10 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.toc.setVisible(False)
self.action_quit = QAction(self)
self.addAction(self.action_quit)
self.view_resized_timer = QTimer(self)
self.view_resized_timer.timeout.connect(self.viewport_resize_finished)
self.view_resized_timer.setSingleShot(True)
self.resize_in_progress = False
qs = [Qt.CTRL+Qt.Key_Q]
if isosx:
qs += [Qt.CTRL+Qt.Key_W]
@ -301,8 +305,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
_('Press Esc to quit')),
self)
self.full_screen_label.setVisible(False)
self.window_mode_toggle_timer = QTimer(self)
self.window_mode_toggle_timer.timeout.connect(self.handle_window_mode_toggle)
self.full_screen_label.setStyleSheet('''
QLabel {
text-align: center;
@ -693,20 +695,28 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.open_progress_indicator(_('Laying out %s')%self.current_title)
self.view.load_path(path, pos=pos)
def viewport_resized(self, frac):
def viewport_resize_started(self, event):
if not self.resize_in_progress:
# First resize, so save the current page position
self.resize_in_progress = True
if not self.window_mode_changed:
# The special handling for window mode changed will already
# have saved page position, so only save it if this is not a
# mode change
self.view.document.page_position.save()
if self.resize_in_progress:
self.view_resized_timer.start(75)
def viewport_resize_finished(self):
# There hasn't been a resize event for some time
# restore the current page position.
self.resize_in_progress = False
if self.window_mode_changed:
# Soak up extra window resize events
self.window_mode_toggle_timer.start(15)
return
new_page = self.pos.value()
if self.current_page is not None:
try:
frac = float(new_page-self.current_page.start_page)/(self.current_page.pages-1)
except ZeroDivisionError:
frac = 0
self.view.scroll_to(frac, notify=False)
# This resize is part of a window mode change, special case it
self.handle_window_mode_toggle()
else:
self.set_page_number(frac)
self.view.document.page_position.restore()
def close_progress_indicator(self):
self.pi.stop()