Add an auto-scroll button to the viewer controls

This commit is contained in:
Kovid Goyal 2019-12-28 20:49:37 +05:30
parent d94c2f21e7
commit 38736d9412
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 88 additions and 34 deletions

View File

@ -0,0 +1 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1395 864q0 13-10 23l-466 466q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23zm0-384q0 13-10 23l-466 466q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23z"/></svg>

After

Width:  |  Height:  |  Size: 414 B

View File

@ -141,6 +141,24 @@ def scroll_by_page(direction):
window.scrollBy(0, h * direction)
def is_auto_scroll_active():
return scroll_animator.auto and scroll_animator.is_running()
def start_autoscroll():
scroll_animator.start(DIRECTION.Down, True)
def toggle_autoscroll():
running = False
if is_auto_scroll_active():
cancel_scroll()
else:
start_autoscroll()
running = True
get_boss().send_message('autoscroll_state_changed', running=running)
def handle_shortcut(sc_name, evt):
if sc_name is 'down':
scroll_animator.start(DIRECTION.Down, False)
@ -173,10 +191,7 @@ def handle_shortcut(sc_name, evt):
scroll_by_page(1)
return True
if sc_name is 'toggle_autoscroll':
if scroll_animator.auto and scroll_animator.is_running():
cancel_scroll()
else:
scroll_animator.start(DIRECTION.Down, True)
toggle_autoscroll()
return True
if sc_name.startsWith('scrollspeed_'):
@ -190,7 +205,7 @@ def layout(is_single_page):
set_css(document.body, margin='0', border_width='0', padding='0')
def flow_auto_scroll_resume():
def auto_scroll_resume():
scroll_animator.wait = False
scroll_animator.sync()
@ -422,3 +437,17 @@ anchor_funcs = {
return (a[0] - b[0]) or (a[1] - b[1])
,
}
def auto_scroll_action(action):
if action is 'toggle':
toggle_autoscroll()
elif action is 'start':
if not is_auto_scroll_active():
toggle_autoscroll()
elif action is 'stop':
if is_auto_scroll_active():
toggle_autoscroll()
elif action is 'resume':
auto_scroll_resume()
return is_auto_scroll_active()

View File

@ -10,10 +10,10 @@ from iframe_comm import IframeClient
from read_book.cfi import scroll_to as scroll_to_cfi
from read_book.extract import get_elements
from read_book.flow_mode import (
anchor_funcs as flow_anchor_funcs, cancel_scroll as flow_cancel_auto_scroll,
flow_auto_scroll_resume, flow_onwheel, flow_to_scroll_fraction,
handle_gesture as flow_handle_gesture, handle_shortcut as flow_handle_shortcut,
layout as flow_layout, scroll_by_page as flow_scroll_by_page
anchor_funcs as flow_anchor_funcs, auto_scroll_action as flow_auto_scroll_action,
flow_onwheel, flow_to_scroll_fraction, handle_gesture as flow_handle_gesture,
handle_shortcut as flow_handle_shortcut, layout as flow_layout,
scroll_by_page as flow_scroll_by_page
)
from read_book.footnotes import is_footnote_link
from read_book.globals import (
@ -22,10 +22,11 @@ from read_book.globals import (
)
from read_book.mathjax import apply_mathjax
from read_book.paged_mode import (
anchor_funcs as paged_anchor_funcs, calc_columns_per_screen, current_cfi,
handle_gesture as paged_handle_gesture, handle_shortcut as paged_handle_shortcut,
jump_to_cfi as paged_jump_to_cfi, layout as paged_layout,
onwheel as paged_onwheel, paged_auto_scroll_resume,
anchor_funcs as paged_anchor_funcs,
auto_scroll_action as paged_auto_scroll_action, calc_columns_per_screen,
current_cfi, handle_gesture as paged_handle_gesture,
handle_shortcut as paged_handle_shortcut, jump_to_cfi as paged_jump_to_cfi,
layout as paged_layout, onwheel as paged_onwheel,
prepare_for_resize as paged_prepare_for_resize, progress_frac,
reset_paged_mode_globals, resize_done as paged_resize_done,
scroll_by_page as paged_scroll_by_page, scroll_to_elem,
@ -106,27 +107,32 @@ class IframeBoss:
'scroll_to_anchor': self.on_scroll_to_anchor,
'scroll_to_frac': self.on_scroll_to_frac,
'scroll_to_ref': self.on_scroll_to_ref,
'set_forward_keypresses': self.set_forward_keypresses,
'set_reference_mode': self.set_reference_mode,
'toggle_autoscroll': self.toggle_autoscroll,
'wheel_from_margin': self.wheel_from_margin,
'window_size': self.received_window_size,
'overlay_shown': self.on_overlay_shown,
'overlay_visibility_changed': self.on_overlay_visibility_changed,
}
self.comm = IframeClient(handlers)
self.last_window_ypos = 0
self.length_before = None
def on_overlay_shown(self):
if current_layout_mode() is 'flow':
flow_cancel_auto_scroll()
def on_overlay_visibility_changed(self, data):
if data.visible:
self.forward_keypresses = True
if self.auto_scroll_action:
self.auto_scroll_active_before_overlay = self.auto_scroll_action('is_active')
self.auto_scroll_action('stop')
else:
self.forward_keypresses = False
if self.auto_scroll_active_before_overlay:
self.auto_scroll_active_before_overlay = undefined
self.auto_scroll_action('start')
def modify_selection(self, data):
sel = window.getSelection()
sel.modify('extend', data.direction, data.granularity)
def set_forward_keypresses(self, data):
self.forward_keypresses = data.forward
def initialize(self, data):
scroll_viewport.update_window_size(data.width, data.height)
window.addEventListener('error', self.onerror)
@ -188,7 +194,7 @@ class IframeBoss:
self.to_scroll_fraction = flow_to_scroll_fraction
self.jump_to_cfi = scroll_to_cfi
self.anchor_funcs = flow_anchor_funcs
self.auto_scroll_resume = flow_auto_scroll_resume
self.auto_scroll_action = flow_auto_scroll_action
else:
self.do_layout = paged_layout
self.handle_wheel = paged_onwheel
@ -197,7 +203,7 @@ class IframeBoss:
self.jump_to_cfi = paged_jump_to_cfi
self._handle_gesture = paged_handle_gesture
self.anchor_funcs = paged_anchor_funcs
self.auto_scroll_resume = paged_auto_scroll_resume
self.auto_scroll_action = paged_auto_scroll_action
update_settings(data.settings)
self.keyboard_shortcut_map = create_shortcut_map(data.settings.keyboard_shortcuts)
set_current_spine_item({
@ -217,6 +223,9 @@ class IframeBoss:
def on_scroll_to_frac(self, data):
self.to_scroll_fraction(data.frac, False)
def toggle_autoscroll(self):
self.auto_scroll_action('toggle')
def handle_gesture(self, gesture):
if gesture.type is 'show-chrome':
self.send_message('show_chrome')
@ -317,7 +326,7 @@ class IframeBoss:
self.onscroll()
self.send_message('content_loaded', progress_frac=self.calculate_progress_frac(), file_progress_frac=progress_frac())
self.last_cfi = None
self.auto_scroll_resume()
self.auto_scroll_action('resume')
window.setTimeout(self.update_cfi, 0)
window.setTimeout(self.update_toc_position, 0)

View File

@ -6,6 +6,7 @@ from elementmaker import E
from gettext import gettext as _
from book_list.book_details import CLASS_NAME as BD_CLASS_NAME, render_metadata
from book_list.globals import get_session_data
from book_list.library_data import sync_library_books
from book_list.router import home
from book_list.theme import get_color
@ -230,6 +231,7 @@ class MainOverlay: # {{{
def show(self, container):
self.container_id = container.getAttribute('id')
icon_size = '3.5ex'
sd = get_session_data()
def ac(text, tooltip, action, icon, is_text_button):
if is_text_button:
@ -296,6 +298,14 @@ class MainOverlay: # {{{
full_screen_actions.push(
ac(text, _('Toggle full screen mode'), def(): self.overlay.hide(), ui_operations.toggle_full_screen();, 'full-screen')
)
if sd.get('read_mode') is 'flow':
asa = self.overlay.view.autoscroll_active
full_screen_actions.append(ac(
_('Stop auto scroll') if asa else _('Auto scroll'), _('Toggle auto-scrolling'), def():
self.overlay.hide()
window.setTimeout(self.overlay.view.toggle_autoscroll, 0)
, 'auto-scroll'))
if full_screen_actions.length:
actions_div.appendChild(E.ul(*full_screen_actions))
@ -510,7 +520,6 @@ class Overlay:
c.style.color = get_color('window-foreground')
if c.style.display is not 'block':
c.style.display = 'block'
self.view.overlay_visibility_changed(True)
return c
@property

View File

@ -563,10 +563,7 @@ def handle_shortcut(sc_name, evt):
scroll_by_page(False, True)
return True
if sc_name is 'toggle_autoscroll':
get_boss().send_message('error', title=_('No auto scroll in paged mode'), msg=_(
'Switch to flow mode (Viewer preferences->Page layout) to enable auto'
' scrolling')
)
auto_scroll_action('toggle')
return True
return False
@ -655,5 +652,10 @@ def resize_done():
resize_manager.end_resize()
def paged_auto_scroll_resume():
pass
def auto_scroll_action(action):
if action is 'toggle':
get_boss().send_message('error', title=_('No auto scroll in paged mode'), msg=_(
'Switch to flow mode (Viewer preferences->Page layout) to enable auto'
' scrolling')
)
return False

View File

@ -201,6 +201,9 @@ class View:
),
)
handlers = {
'autoscroll_state_changed': def(data):
self.autoscroll_active = v'!!data.running'
,
'bump_font_size': self.bump_font_size,
'content_loaded': self.on_content_loaded,
'error': self.on_iframe_error,
@ -339,9 +342,7 @@ class View:
def overlay_visibility_changed(self, visible):
if self.iframe_wrapper.send_message:
if visible:
self.iframe_wrapper.send_message('overlay_shown')
self.iframe_wrapper.send_message('set_forward_keypresses', forward=v'!!visible')
self.iframe_wrapper.send_message('overlay_visibility_changed', visible=visible)
if ui_operations.overlay_visibility_changed:
ui_operations.overlay_visibility_changed(visible)
@ -429,6 +430,9 @@ class View:
sd.set('read_mode', new_mode)
ui_operations.redisplay_book()
def toggle_autoscroll(self):
self.iframe_wrapper.send_message('toggle_autoscroll')
def toggle_toolbar(self):
sd = get_session_data()
misc = sd.get('standalone_misc_settings')