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 base64 import b64encode
from functools import partial 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, QPainter, QPalette, QBrush, QFontDatabase, QDialog,
QColor, QPoint, QImage, QRegion, QVariant, QIcon, QColor, QPoint, QImage, QRegion, QVariant, QIcon,
QFont, pyqtSignature, QAction, QByteArray, QMenu, QFont, pyqtSignature, QAction, QByteArray, QMenu,
@ -184,12 +184,10 @@ class Document(QWebPage): # {{{
self.misc_config() self.misc_config()
self.after_load() self.after_load()
def __init__(self, shortcuts, parent=None, resize_callback=lambda: None, def __init__(self, shortcuts, parent=None, debug_javascript=False):
debug_javascript=False):
QWebPage.__init__(self, parent) QWebPage.__init__(self, parent)
self.setObjectName("py_bridge") self.setObjectName("py_bridge")
self.debug_javascript = debug_javascript self.debug_javascript = debug_javascript
self.resize_callback = resize_callback
self.current_language = None self.current_language = None
self.loaded_javascript = False self.loaded_javascript = False
self.js_loader = JavaScriptLoader( self.js_loader = JavaScriptLoader(
@ -259,12 +257,6 @@ class Document(QWebPage): # {{{
if self.loaded_javascript: if self.loaded_javascript:
return return
self.loaded_javascript = True 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.loaded_lang = self.js_loader(self.mainFrame().evaluateJavaScript,
self.current_language, self.hyphenate_default_lang) self.current_language, self.hyphenate_default_lang)
@ -310,10 +302,6 @@ class Document(QWebPage): # {{{
def debug(self, msg): def debug(self, msg):
prints(msg) prints(msg)
@pyqtSignature('')
def window_resized(self):
self.resize_callback()
def reference_mode(self, enable): def reference_mode(self, enable):
self.javascript(('enter' if enable else 'leave')+'_reference_mode()') self.javascript(('enter' if enable else 'leave')+'_reference_mode()')
@ -444,7 +432,7 @@ class Document(QWebPage): # {{{
def scroll_fraction(self): def scroll_fraction(self):
def fget(self): def fget(self):
try: try:
return float(self.ypos)/(self.height-self.window_height) return abs(float(self.ypos)/(self.height-self.window_height))
except ZeroDivisionError: except ZeroDivisionError:
return 0. return 0.
def fset(self, val): def fset(self, val):
@ -516,7 +504,6 @@ class DocumentView(QWebView): # {{{
self.initial_pos = 0.0 self.initial_pos = 0.0
self.to_bottom = False self.to_bottom = False
self.document = Document(self.shortcuts, parent=self, self.document = Document(self.shortcuts, parent=self,
resize_callback=self.viewport_resized,
debug_javascript=debug_javascript) debug_javascript=debug_javascript)
self.setPage(self.document) self.setPage(self.document)
self.manager = None self.manager = None
@ -1035,13 +1022,9 @@ class DocumentView(QWebView): # {{{
return handled return handled
def resizeEvent(self, event): 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: 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): def event(self, ev):
if ev.type() == ev.Gesture: if ev.type() == ev.Gesture:

View File

@ -224,6 +224,10 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.toc.setVisible(False) self.toc.setVisible(False)
self.action_quit = QAction(self) self.action_quit = QAction(self)
self.addAction(self.action_quit) 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] qs = [Qt.CTRL+Qt.Key_Q]
if isosx: if isosx:
qs += [Qt.CTRL+Qt.Key_W] qs += [Qt.CTRL+Qt.Key_W]
@ -301,8 +305,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
_('Press Esc to quit')), _('Press Esc to quit')),
self) self)
self.full_screen_label.setVisible(False) 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(''' self.full_screen_label.setStyleSheet('''
QLabel { QLabel {
text-align: center; text-align: center;
@ -693,20 +695,28 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.open_progress_indicator(_('Laying out %s')%self.current_title) self.open_progress_indicator(_('Laying out %s')%self.current_title)
self.view.load_path(path, pos=pos) 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: if self.window_mode_changed:
# Soak up extra window resize events # This resize is part of a window mode change, special case it
self.window_mode_toggle_timer.start(15) self.handle_window_mode_toggle()
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)
else: else:
self.set_page_number(frac) self.view.document.page_position.restore()
def close_progress_indicator(self): def close_progress_indicator(self):
self.pi.stop() self.pi.stop()