mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Viewer: Add an option to display a scrollbar
This commit is contained in:
parent
42ae6dea61
commit
0ccedfdcc7
@ -12,8 +12,8 @@ from hashlib import sha256
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QApplication, QDockWidget, QEvent, QMimeData, QModelIndex, QPixmap, Qt, QUrl,
|
QApplication, QDockWidget, QEvent, QHBoxLayout, QMimeData, QModelIndex, QPixmap,
|
||||||
QVBoxLayout, QWidget, pyqtSignal
|
QScrollBar, Qt, QUrl, QVBoxLayout, QWidget, pyqtSignal
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import prints
|
from calibre import prints
|
||||||
@ -59,6 +59,61 @@ def path_key(path):
|
|||||||
return sha256(as_bytes(path)).hexdigest()
|
return sha256(as_bytes(path)).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
class ScrollBar(QScrollBar):
|
||||||
|
|
||||||
|
def paintEvent(self, ev):
|
||||||
|
if self.isEnabled():
|
||||||
|
return QScrollBar.paintEvent(self, ev)
|
||||||
|
|
||||||
|
|
||||||
|
class CentralWidget(QWidget):
|
||||||
|
|
||||||
|
def __init__(self, web_view, parent):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self.web_view = web_view
|
||||||
|
self.l = l = QHBoxLayout(self)
|
||||||
|
l.setContentsMargins(0, 0, 0, 0), l.setSpacing(0)
|
||||||
|
l.addWidget(web_view)
|
||||||
|
self.vertical_scrollbar = vs = ScrollBar(Qt.Vertical, self)
|
||||||
|
vs.sliderMoved[int].connect(self.slider_moved)
|
||||||
|
l.addWidget(vs)
|
||||||
|
self.current_book_length = None
|
||||||
|
web_view.notify_progress_frac.connect(self.update_scrollbar_positions)
|
||||||
|
web_view.scrollbar_visibility_changed.connect(self.apply_scrollbar_visibility)
|
||||||
|
web_view.overlay_visibility_changed.connect(self.overlay_visibility_changed)
|
||||||
|
self.apply_scrollbar_visibility()
|
||||||
|
|
||||||
|
def apply_scrollbar_visibility(self):
|
||||||
|
visible = get_session_pref('standalone_scrollbar', default=False, group=None)
|
||||||
|
self.vertical_scrollbar.setVisible(bool(visible))
|
||||||
|
|
||||||
|
def overlay_visibility_changed(self, visible):
|
||||||
|
self.vertical_scrollbar.setEnabled(not visible)
|
||||||
|
|
||||||
|
def set_scrollbar_value(self, frac):
|
||||||
|
val = int(self.vertical_scrollbar.maximum() * frac)
|
||||||
|
self.vertical_scrollbar.setValue(val)
|
||||||
|
|
||||||
|
def slider_moved(self, val):
|
||||||
|
frac = val / self.vertical_scrollbar.maximum()
|
||||||
|
self.web_view.goto_frac(frac)
|
||||||
|
|
||||||
|
def initialize_scrollbars(self, book_length):
|
||||||
|
self.current_book_length = book_length
|
||||||
|
maximum = book_length / 10
|
||||||
|
bar = self.vertical_scrollbar
|
||||||
|
bar.setMinimum(0)
|
||||||
|
bar.setMaximum(maximum)
|
||||||
|
bar.setSingleStep(10)
|
||||||
|
bar.setPageStep(100)
|
||||||
|
|
||||||
|
def update_scrollbar_positions(self, progress_frac, file_progress_frac, book_length):
|
||||||
|
if book_length != self.current_book_length:
|
||||||
|
self.initialize_scrollbars(book_length)
|
||||||
|
if not self.vertical_scrollbar.isSliderDown():
|
||||||
|
self.set_scrollbar_value(progress_frac)
|
||||||
|
|
||||||
|
|
||||||
class EbookViewer(MainWindow):
|
class EbookViewer(MainWindow):
|
||||||
|
|
||||||
msg_from_anotherinstance = pyqtSignal(object)
|
msg_from_anotherinstance = pyqtSignal(object)
|
||||||
@ -127,7 +182,8 @@ class EbookViewer(MainWindow):
|
|||||||
self.web_view.selection_changed.connect(self.lookup_widget.selected_text_changed, type=Qt.QueuedConnection)
|
self.web_view.selection_changed.connect(self.lookup_widget.selected_text_changed, type=Qt.QueuedConnection)
|
||||||
self.web_view.view_image.connect(self.view_image, type=Qt.QueuedConnection)
|
self.web_view.view_image.connect(self.view_image, type=Qt.QueuedConnection)
|
||||||
self.web_view.copy_image.connect(self.copy_image, type=Qt.QueuedConnection)
|
self.web_view.copy_image.connect(self.copy_image, type=Qt.QueuedConnection)
|
||||||
self.setCentralWidget(self.web_view)
|
self.central_widget = CentralWidget(self.web_view, self)
|
||||||
|
self.setCentralWidget(self.central_widget)
|
||||||
self.restore_state()
|
self.restore_state()
|
||||||
if continue_reading:
|
if continue_reading:
|
||||||
self.continue_reading()
|
self.continue_reading()
|
||||||
@ -288,6 +344,7 @@ class EbookViewer(MainWindow):
|
|||||||
self.web_view.show_home_page()
|
self.web_view.show_home_page()
|
||||||
return
|
return
|
||||||
set_book_path(data['base'], data['pathtoebook'])
|
set_book_path(data['base'], data['pathtoebook'])
|
||||||
|
self.central_widget.initialize_scrollbars(set_book_path.parsed_manifest['spine_length'])
|
||||||
self.current_book_data = data
|
self.current_book_data = data
|
||||||
self.current_book_data['annotations_map'] = defaultdict(list)
|
self.current_book_data['annotations_map'] = defaultdict(list)
|
||||||
self.current_book_data['annotations_path_key'] = path_key(data['pathtoebook']) + '.json'
|
self.current_book_data['annotations_path_key'] = path_key(data['pathtoebook']) + '.json'
|
||||||
|
@ -186,7 +186,7 @@ class UrlSchemeHandler(QWebEngineUrlSchemeHandler):
|
|||||||
|
|
||||||
def get_session_pref(name, default=None, group='standalone_misc_settings'):
|
def get_session_pref(name, default=None, group='standalone_misc_settings'):
|
||||||
sd = vprefs['session_data']
|
sd = vprefs['session_data']
|
||||||
g = sd.get(group, {})
|
g = sd.get(group, {}) if group else sd
|
||||||
return g.get(name, default)
|
return g.get(name, default)
|
||||||
|
|
||||||
|
|
||||||
@ -232,6 +232,8 @@ class ViewerBridge(Bridge):
|
|||||||
view_image = from_js(object)
|
view_image = from_js(object)
|
||||||
copy_image = from_js(object)
|
copy_image = from_js(object)
|
||||||
change_background_image = from_js(object)
|
change_background_image = from_js(object)
|
||||||
|
notify_progress_frac = from_js(object, object, object)
|
||||||
|
overlay_visibility_changed = from_js(object)
|
||||||
|
|
||||||
create_view = to_js()
|
create_view = to_js()
|
||||||
show_preparing_message = to_js()
|
show_preparing_message = to_js()
|
||||||
@ -242,6 +244,7 @@ class ViewerBridge(Bridge):
|
|||||||
get_current_cfi = to_js()
|
get_current_cfi = to_js()
|
||||||
show_home_page = to_js()
|
show_home_page = to_js()
|
||||||
background_image_changed = to_js()
|
background_image_changed = to_js()
|
||||||
|
goto_frac = to_js()
|
||||||
|
|
||||||
|
|
||||||
def apply_font_settings(page_or_view):
|
def apply_font_settings(page_or_view):
|
||||||
@ -373,6 +376,9 @@ class WebView(RestartingWebEngineView):
|
|||||||
selection_changed = pyqtSignal(object)
|
selection_changed = pyqtSignal(object)
|
||||||
view_image = pyqtSignal(object)
|
view_image = pyqtSignal(object)
|
||||||
copy_image = pyqtSignal(object)
|
copy_image = pyqtSignal(object)
|
||||||
|
scrollbar_visibility_changed = pyqtSignal()
|
||||||
|
notify_progress_frac = pyqtSignal(object, object, object)
|
||||||
|
overlay_visibility_changed = pyqtSignal(object)
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
self._host_widget = None
|
self._host_widget = None
|
||||||
@ -399,6 +405,8 @@ class WebView(RestartingWebEngineView):
|
|||||||
self.bridge.selection_changed.connect(self.selection_changed)
|
self.bridge.selection_changed.connect(self.selection_changed)
|
||||||
self.bridge.view_image.connect(self.view_image)
|
self.bridge.view_image.connect(self.view_image)
|
||||||
self.bridge.copy_image.connect(self.copy_image)
|
self.bridge.copy_image.connect(self.copy_image)
|
||||||
|
self.bridge.notify_progress_frac.connect(self.notify_progress_frac)
|
||||||
|
self.bridge.overlay_visibility_changed.connect(self.overlay_visibility_changed)
|
||||||
self.bridge.report_cfi.connect(self.call_callback)
|
self.bridge.report_cfi.connect(self.call_callback)
|
||||||
self.bridge.change_background_image.connect(self.change_background_image)
|
self.bridge.change_background_image.connect(self.change_background_image)
|
||||||
self.pending_bridge_ready_actions = {}
|
self.pending_bridge_ready_actions = {}
|
||||||
@ -499,6 +507,8 @@ class WebView(RestartingWebEngineView):
|
|||||||
vprefs['session_data'] = sd
|
vprefs['session_data'] = sd
|
||||||
if key in ('standalone_font_settings', 'base_font_size'):
|
if key in ('standalone_font_settings', 'base_font_size'):
|
||||||
apply_font_settings(self._page)
|
apply_font_settings(self._page)
|
||||||
|
elif key == 'standalone_scrollbar':
|
||||||
|
self.scrollbar_visibility_changed.emit()
|
||||||
|
|
||||||
def do_callback(self, func_name, callback):
|
def do_callback(self, func_name, callback):
|
||||||
cid = next(self.callback_id_counter)
|
cid = next(self.callback_id_counter)
|
||||||
@ -525,3 +535,6 @@ class WebView(RestartingWebEngineView):
|
|||||||
shutil.copyfileobj(src, dest)
|
shutil.copyfileobj(src, dest)
|
||||||
background_image.ans = None
|
background_image.ans = None
|
||||||
self.execute_when_ready('background_image_changed', img_id)
|
self.execute_when_ready('background_image_changed', img_id)
|
||||||
|
|
||||||
|
def goto_frac(self, frac):
|
||||||
|
self.execute_when_ready('goto_frac', frac)
|
||||||
|
@ -172,7 +172,7 @@ def get_length(root):
|
|||||||
if elem.tail:
|
if elem.tail:
|
||||||
num += len(strip_space.sub('', elem.tail))
|
num += len(strip_space.sub('', elem.tail))
|
||||||
if tname in 'img svg':
|
if tname in 'img svg':
|
||||||
num += 2000
|
num += 1000
|
||||||
return num
|
return num
|
||||||
|
|
||||||
for body in root.iterdescendants(XHTML('body')):
|
for body in root.iterdescendants(XHTML('body')):
|
||||||
|
@ -85,6 +85,7 @@ class IframeBoss:
|
|||||||
'initialize':self.initialize,
|
'initialize':self.initialize,
|
||||||
'display': self.display,
|
'display': self.display,
|
||||||
'scroll_to_anchor': self.on_scroll_to_anchor,
|
'scroll_to_anchor': self.on_scroll_to_anchor,
|
||||||
|
'scroll_to_frac': self.on_scroll_to_frac,
|
||||||
'next_screen': self.on_next_screen,
|
'next_screen': self.on_next_screen,
|
||||||
'change_font_size': self.change_font_size,
|
'change_font_size': self.change_font_size,
|
||||||
'change_color_scheme': self.change_color_scheme,
|
'change_color_scheme': self.change_color_scheme,
|
||||||
@ -105,6 +106,7 @@ class IframeBoss:
|
|||||||
scroll_viewport.update_window_size(data.width, data.height)
|
scroll_viewport.update_window_size(data.width, data.height)
|
||||||
window.onerror = self.onerror
|
window.onerror = self.onerror
|
||||||
window.addEventListener('scroll', debounce(self.onscroll, 1000))
|
window.addEventListener('scroll', debounce(self.onscroll, 1000))
|
||||||
|
window.addEventListener('scroll', self.no_latency_onscroll)
|
||||||
window.addEventListener('resize', debounce(self.onresize, 500))
|
window.addEventListener('resize', debounce(self.onresize, 500))
|
||||||
window.addEventListener('wheel', self.onwheel, {'passive': False})
|
window.addEventListener('wheel', self.onwheel, {'passive': False})
|
||||||
window.addEventListener('keydown', self.onkeydown, {'passive': False})
|
window.addEventListener('keydown', self.onkeydown, {'passive': False})
|
||||||
@ -171,6 +173,9 @@ class IframeBoss:
|
|||||||
root_data, self.mathjax, self.blob_url_map = finalize_resources(self.book, data.name, data.resource_data)
|
root_data, self.mathjax, self.blob_url_map = finalize_resources(self.book, data.name, data.resource_data)
|
||||||
self.resource_urls = unserialize_html(root_data, self.content_loaded)
|
self.resource_urls = unserialize_html(root_data, self.content_loaded)
|
||||||
|
|
||||||
|
def on_scroll_to_frac(self, data):
|
||||||
|
self.to_scroll_fraction(data.frac)
|
||||||
|
|
||||||
def handle_gesture(self, gesture):
|
def handle_gesture(self, gesture):
|
||||||
if gesture.type is 'show-chrome':
|
if gesture.type is 'show-chrome':
|
||||||
self.send_message('show_chrome')
|
self.send_message('show_chrome')
|
||||||
@ -280,13 +285,13 @@ class IframeBoss:
|
|||||||
if si:
|
if si:
|
||||||
self.length_before += files[si]?.length or 0
|
self.length_before += files[si]?.length or 0
|
||||||
self.onscroll()
|
self.onscroll()
|
||||||
self.send_message('content_loaded', progress_frac=self.get_progress_frac())
|
self.send_message('content_loaded', progress_frac=self.calculate_progress_frac(), file_progress_frac=progress_frac())
|
||||||
self.last_cfi = None
|
self.last_cfi = None
|
||||||
window.setTimeout(self.update_cfi, 0)
|
window.setTimeout(self.update_cfi, 0)
|
||||||
window.setTimeout(self.update_toc_position, 0)
|
window.setTimeout(self.update_toc_position, 0)
|
||||||
|
|
||||||
|
def calculate_progress_frac(self):
|
||||||
def calculate_progress_frac(self, current_name, spine_index):
|
current_name = current_spine_item().name
|
||||||
files = self.book.manifest.files
|
files = self.book.manifest.files
|
||||||
file_length = files[current_name]?.length or 0
|
file_length = files[current_name]?.length or 0
|
||||||
if self.length_before is None:
|
if self.length_before is None:
|
||||||
@ -295,14 +300,6 @@ class IframeBoss:
|
|||||||
ans = (self.length_before + (file_length * frac)) / self.book.manifest.spine_length
|
ans = (self.length_before + (file_length * frac)) / self.book.manifest.spine_length
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def get_progress_frac(self):
|
|
||||||
spine = self.book.manifest.spine
|
|
||||||
current_name = current_spine_item().name
|
|
||||||
index = spine.indexOf(current_name)
|
|
||||||
if index < 0:
|
|
||||||
return 0
|
|
||||||
return self.calculate_progress_frac(current_name, index)
|
|
||||||
|
|
||||||
def get_current_cfi(self, data):
|
def get_current_cfi(self, data):
|
||||||
cfi = at_current()
|
cfi = at_current()
|
||||||
selected_text = window.getSelection().toString()
|
selected_text = window.getSelection().toString()
|
||||||
@ -313,7 +310,7 @@ class IframeBoss:
|
|||||||
if index > -1:
|
if index > -1:
|
||||||
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
||||||
self.send_message(
|
self.send_message(
|
||||||
'report_cfi', cfi=cfi, progress_frac=self.calculate_progress_frac(current_name, index),
|
'report_cfi', cfi=cfi, progress_frac=self.calculate_progress_frac(),
|
||||||
file_progress_frac=progress_frac(), request_id=data.request_id, selected_text=selected_text)
|
file_progress_frac=progress_frac(), request_id=data.request_id, selected_text=selected_text)
|
||||||
return
|
return
|
||||||
self.send_message(
|
self.send_message(
|
||||||
@ -327,14 +324,18 @@ class IframeBoss:
|
|||||||
index = spine.indexOf(current_name)
|
index = spine.indexOf(current_name)
|
||||||
if index > -1:
|
if index > -1:
|
||||||
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
||||||
|
pf = self.calculate_progress_frac()
|
||||||
|
fpf = progress_frac()
|
||||||
if cfi is not self.last_cfi:
|
if cfi is not self.last_cfi:
|
||||||
self.last_cfi = cfi
|
self.last_cfi = cfi
|
||||||
selected_text = window.getSelection().toString()
|
selected_text = window.getSelection().toString()
|
||||||
self.send_message(
|
self.send_message(
|
||||||
'update_cfi', cfi=cfi, replace_history=self.replace_history_on_next_cfi_update,
|
'update_cfi', cfi=cfi, replace_history=self.replace_history_on_next_cfi_update,
|
||||||
progress_frac=self.calculate_progress_frac(current_name, index),
|
progress_frac=pf, file_progress_frac=fpf, selected_text=selected_text)
|
||||||
file_progress_frac=progress_frac(), selected_text=selected_text)
|
|
||||||
self.replace_history_on_next_cfi_update = True
|
self.replace_history_on_next_cfi_update = True
|
||||||
|
else:
|
||||||
|
self.send_message(
|
||||||
|
'update_progress_frac', progress_frac=pf, file_progress_frac=fpf)
|
||||||
|
|
||||||
def update_toc_position(self):
|
def update_toc_position(self):
|
||||||
visible_anchors = update_visible_toc_anchors(self.book.manifest.toc_anchor_map, self.anchor_funcs)
|
visible_anchors = update_visible_toc_anchors(self.book.manifest.toc_anchor_map, self.anchor_funcs)
|
||||||
@ -345,6 +346,12 @@ class IframeBoss:
|
|||||||
self.update_cfi()
|
self.update_cfi()
|
||||||
self.update_toc_position()
|
self.update_toc_position()
|
||||||
|
|
||||||
|
def no_latency_onscroll(self):
|
||||||
|
pf = self.calculate_progress_frac()
|
||||||
|
fpf = progress_frac()
|
||||||
|
self.send_message(
|
||||||
|
'update_progress_frac', progress_frac=pf, file_progress_frac=fpf)
|
||||||
|
|
||||||
def onresize(self):
|
def onresize(self):
|
||||||
self.send_message('request_size')
|
self.send_message('request_size')
|
||||||
if self.content_ready:
|
if self.content_ready:
|
||||||
|
@ -10,6 +10,8 @@ from dom import unique_id
|
|||||||
from widgets import create_button
|
from widgets import create_button
|
||||||
from session import defaults
|
from session import defaults
|
||||||
|
|
||||||
|
from read_book.globals import runtime
|
||||||
|
|
||||||
CONTAINER = unique_id('standalone-scrolling-settings')
|
CONTAINER = unique_id('standalone-scrolling-settings')
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +43,11 @@ def create_scrolling_panel(container):
|
|||||||
container.appendChild(cb(
|
container.appendChild(cb(
|
||||||
'paged_margin_clicks_scroll_by_screen', _('Clicking on the margins scrolls by screen fulls instead of pages')))
|
'paged_margin_clicks_scroll_by_screen', _('Clicking on the margins scrolls by screen fulls instead of pages')))
|
||||||
|
|
||||||
|
if runtime.is_standalone_viewer:
|
||||||
|
container.appendChild(E.div(style='margin-top:1ex; border-top: solid 1px', '\xa0'))
|
||||||
|
container.appendChild(cb(
|
||||||
|
'standalone_scrollbar', _('Show a scrollbar')))
|
||||||
|
|
||||||
container.appendChild(E.div(
|
container.appendChild(E.div(
|
||||||
style='margin-top: 1rem', create_button(_('Restore defaults'), action=restore_defaults)
|
style='margin-top: 1rem', create_button(_('Restore defaults'), action=restore_defaults)
|
||||||
))
|
))
|
||||||
|
@ -186,6 +186,7 @@ class View:
|
|||||||
'goto_doc_boundary': def(data): self.goto_doc_boundary(data.start);,
|
'goto_doc_boundary': def(data): self.goto_doc_boundary(data.start);,
|
||||||
'scroll_to_anchor': self.on_scroll_to_anchor,
|
'scroll_to_anchor': self.on_scroll_to_anchor,
|
||||||
'update_cfi': self.on_update_cfi,
|
'update_cfi': self.on_update_cfi,
|
||||||
|
'update_progress_frac': self.on_update_progress_frac,
|
||||||
'report_cfi': self.on_report_cfi,
|
'report_cfi': self.on_report_cfi,
|
||||||
'update_toc_position': self.on_update_toc_position,
|
'update_toc_position': self.on_update_toc_position,
|
||||||
'content_loaded': self.on_content_loaded,
|
'content_loaded': self.on_content_loaded,
|
||||||
@ -288,6 +289,8 @@ class View:
|
|||||||
def overlay_visibility_changed(self, visible):
|
def overlay_visibility_changed(self, visible):
|
||||||
if self.iframe_wrapper.send_message:
|
if self.iframe_wrapper.send_message:
|
||||||
self.iframe_wrapper.send_message('set_forward_keypresses', forward=v'!!visible')
|
self.iframe_wrapper.send_message('set_forward_keypresses', forward=v'!!visible')
|
||||||
|
if ui_operations.overlay_visibility_changed:
|
||||||
|
ui_operations.overlay_visibility_changed(visible)
|
||||||
|
|
||||||
def on_handle_shortcut(self, data):
|
def on_handle_shortcut(self, data):
|
||||||
if data.name is 'back':
|
if data.name is 'back':
|
||||||
@ -621,6 +624,34 @@ class View:
|
|||||||
name = self.book.manifest.spine[0 if start else self.book.manifest.spine.length - 1]
|
name = self.book.manifest.spine[0 if start else self.book.manifest.spine.length - 1]
|
||||||
self.show_name(name, initial_position={'type':'frac', 'frac':0 if start else 1, 'replace_history':False})
|
self.show_name(name, initial_position={'type':'frac', 'frac':0 if start else 1, 'replace_history':False})
|
||||||
|
|
||||||
|
def goto_frac(self, frac):
|
||||||
|
if not self.book or not self.book.manifest:
|
||||||
|
return
|
||||||
|
chapter_start_page = 0
|
||||||
|
total_length = self.book.manifest.spine_length
|
||||||
|
page = total_length * frac
|
||||||
|
chapter_frac = 0
|
||||||
|
chapter_name = None
|
||||||
|
for name in self.book.manifest.spine:
|
||||||
|
chapter_length = self.book.manifest.files[name]?.length or 0
|
||||||
|
chapter_end_page = chapter_start_page + chapter_length
|
||||||
|
if chapter_start_page <= page <= chapter_end_page:
|
||||||
|
num_pages = chapter_end_page - chapter_start_page - 1
|
||||||
|
if num_pages > 0:
|
||||||
|
chapter_frac = (page - chapter_start_page) / num_pages
|
||||||
|
else:
|
||||||
|
chapter_frac = 0
|
||||||
|
chapter_name = name
|
||||||
|
break
|
||||||
|
chapter_start_page = chapter_end_page
|
||||||
|
if not chapter_name:
|
||||||
|
chapter_name = self.book.manifest.spine[-1]
|
||||||
|
chapter_frac = max(0, min(chapter_frac, 1))
|
||||||
|
if self.currently_showing.name is chapter_name:
|
||||||
|
self.iframe_wrapper.send_message('scroll_to_frac', frac=chapter_frac)
|
||||||
|
else:
|
||||||
|
self.show_name(chapter_name, initial_position={'type':'frac', 'frac':chapter_frac, 'replace_history':True})
|
||||||
|
|
||||||
def on_scroll_to_anchor(self, data):
|
def on_scroll_to_anchor(self, data):
|
||||||
self.show_name(data.name, initial_position={'type':'anchor', 'anchor':data.frag, 'replace_history':False})
|
self.show_name(data.name, initial_position={'type':'anchor', 'anchor':data.frag, 'replace_history':False})
|
||||||
|
|
||||||
@ -698,8 +729,7 @@ class View:
|
|||||||
if not self.book.last_read_position:
|
if not self.book.last_read_position:
|
||||||
self.book.last_read_position = {}
|
self.book.last_read_position = {}
|
||||||
self.book.last_read_position[unkey] = data.cfi
|
self.book.last_read_position[unkey] = data.cfi
|
||||||
self.current_progress_frac = data.progress_frac
|
self.set_progress_frac(data.progress_frac, data.file_progress_frac)
|
||||||
self.current_file_progress_frac = data.file_progress_frac
|
|
||||||
self.update_header_footer()
|
self.update_header_footer()
|
||||||
if ui_operations.update_last_read_time:
|
if ui_operations.update_last_read_time:
|
||||||
ui_operations.update_last_read_time(self.book)
|
ui_operations.update_last_read_time(self.book)
|
||||||
@ -716,6 +746,10 @@ class View:
|
|||||||
})
|
})
|
||||||
v'delete self.report_cfi_callbacks[data.request_id]'
|
v'delete self.report_cfi_callbacks[data.request_id]'
|
||||||
|
|
||||||
|
def on_update_progress_frac(self, data):
|
||||||
|
self.set_progress_frac(data.progress_frac, data.file_progress_frac)
|
||||||
|
self.update_header_footer()
|
||||||
|
|
||||||
def on_update_cfi(self, data):
|
def on_update_cfi(self, data):
|
||||||
overlay_shown = not self.processing_spine_item_display and self.overlay.is_visible
|
overlay_shown = not self.processing_spine_item_display and self.overlay.is_visible
|
||||||
if overlay_shown or self.search_overlay.is_visible or self.content_popup_overlay.is_visible:
|
if overlay_shown or self.search_overlay.is_visible or self.content_popup_overlay.is_visible:
|
||||||
@ -741,7 +775,7 @@ class View:
|
|||||||
has_clock = False
|
has_clock = False
|
||||||
|
|
||||||
if self.book?.manifest:
|
if self.book?.manifest:
|
||||||
book_length = self.book.manifest.total_length or 0
|
book_length = self.book.manifest.spine_length or 0
|
||||||
name = self.currently_showing.name
|
name = self.currently_showing.name
|
||||||
chapter_length = self.book.manifest.files[name]?.length or 0
|
chapter_length = self.book.manifest.files[name]?.length or 0
|
||||||
else:
|
else:
|
||||||
@ -815,11 +849,19 @@ class View:
|
|||||||
def on_content_loaded(self, data):
|
def on_content_loaded(self, data):
|
||||||
self.processing_spine_item_display = False
|
self.processing_spine_item_display = False
|
||||||
self.hide_loading()
|
self.hide_loading()
|
||||||
frac = data.progress_frac or 0
|
self.set_progress_frac(data.progress_frac, data.file_progress_frac)
|
||||||
self.current_progress_frac = frac
|
|
||||||
self.update_header_footer()
|
self.update_header_footer()
|
||||||
window.scrollTo(0, 0) # ensure window is at 0 on mobile where the navbar causes issues
|
window.scrollTo(0, 0) # ensure window is at 0 on mobile where the navbar causes issues
|
||||||
|
|
||||||
|
def set_progress_frac(self, progress_frac, file_progress_frac):
|
||||||
|
self.current_progress_frac = progress_frac or 0
|
||||||
|
self.current_file_progress_frac = file_progress_frac or 0
|
||||||
|
if ui_operations.notify_progress_frac:
|
||||||
|
book_length = 0
|
||||||
|
if self.book?.manifest:
|
||||||
|
book_length = self.book.manifest.spine_length or 0
|
||||||
|
ui_operations.notify_progress_frac(self.current_progress_frac, self.current_file_progress_frac, book_length)
|
||||||
|
|
||||||
def update_font_size(self):
|
def update_font_size(self):
|
||||||
self.iframe_wrapper.send_message('change_font_size', base_font_size=get_session_data().get('base_font_size'))
|
self.iframe_wrapper.send_message('change_font_size', base_font_size=get_session_data().get('base_font_size'))
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ defaults = {
|
|||||||
'keyboard_shortcuts': {},
|
'keyboard_shortcuts': {},
|
||||||
'standalone_font_settings': {},
|
'standalone_font_settings': {},
|
||||||
'standalone_misc_settings': {},
|
'standalone_misc_settings': {},
|
||||||
|
'standalone_scrollbar': False,
|
||||||
'standalone_recently_opened': v'[]',
|
'standalone_recently_opened': v'[]',
|
||||||
'paged_wheel_scrolls_by_screen': False,
|
'paged_wheel_scrolls_by_screen': False,
|
||||||
'paged_margin_clicks_scroll_by_screen': True,
|
'paged_margin_clicks_scroll_by_screen': True,
|
||||||
@ -72,6 +73,7 @@ is_local_setting = {
|
|||||||
'standalone_font_settings': True,
|
'standalone_font_settings': True,
|
||||||
'standalone_misc_settings': True,
|
'standalone_misc_settings': True,
|
||||||
'standalone_recently_opened': True,
|
'standalone_recently_opened': True,
|
||||||
|
'standalone_scrollbar': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,6 +237,12 @@ def get_current_cfi(request_id):
|
|||||||
view.get_current_cfi(request_id, ui_operations.report_cfi)
|
view.get_current_cfi(request_id, ui_operations.report_cfi)
|
||||||
|
|
||||||
|
|
||||||
|
@from_python
|
||||||
|
def goto_frac(frac):
|
||||||
|
if view:
|
||||||
|
view.goto_frac(frac)
|
||||||
|
|
||||||
|
|
||||||
@from_python
|
@from_python
|
||||||
def background_image_changed(img_id):
|
def background_image_changed(img_id):
|
||||||
img = document.getElementById(img_id)
|
img = document.getElementById(img_id)
|
||||||
@ -306,8 +312,12 @@ if window is window.top:
|
|||||||
to_python.copy_image(name)
|
to_python.copy_image(name)
|
||||||
ui_operations.change_background_image = def(img_id):
|
ui_operations.change_background_image = def(img_id):
|
||||||
to_python.change_background_image(img_id)
|
to_python.change_background_image(img_id)
|
||||||
|
ui_operations.notify_progress_frac = def (pf, fpf, book_length):
|
||||||
|
to_python.notify_progress_frac(pf, fpf, book_length)
|
||||||
ui_operations.quit = def():
|
ui_operations.quit = def():
|
||||||
to_python.quit()
|
to_python.quit()
|
||||||
|
ui_operations.overlay_visibility_changed = def(visible):
|
||||||
|
to_python.overlay_visibility_changed(visible)
|
||||||
|
|
||||||
document.body.appendChild(E.div(id='view'))
|
document.body.appendChild(E.div(id='view'))
|
||||||
window.onerror = onerror
|
window.onerror = onerror
|
||||||
|
Loading…
x
Reference in New Issue
Block a user