Start work on Read aloud mode

This commit is contained in:
Kovid Goyal 2020-11-29 08:44:13 +05:30
parent a30291c1ae
commit 4fd521a88b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 86 additions and 0 deletions

View File

@ -0,0 +1,79 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
from __python__ import bound_methods, hash_literals
from elementmaker import E
from book_list.theme import get_color
from dom import clear, unique_id
from read_book.globals import runtime
HIDDEN = 0
PAUSED = 1
PLAYING = 2
class ReadAloud:
def __init__(self, view):
self.view = view
self.state = HIDDEN
self.bar_id = unique_id('bar')
container = self.container
container.setAttribute('tabindex', '0')
container.style.overflow = 'hidden'
container.appendChild(E.div(
id=self.bar_id,
style='position: fixed; border: solid 1px currentColor; border-radius: 5px;'
'right: 95vw; top: 0; display: flex; flex-direction: column;'
))
@property
def container(self):
return document.getElementById('book-read-aloud-overlay')
@property
def supports_css_min_max(self):
return not runtime.is_standalone_viewer or runtime.QT_VERSION >= 0x050f00
@property
def bar(self):
return document.getElementById(self.bar_id)
@property
def is_visible(self):
return self.container.style.display is not 'none'
def hide(self):
self.state = HIDDEN
self.container.style.display = 'none'
self.view.focus_iframe()
def show(self):
if self.state is HIDDEN:
self.container.style.display = 'block'
self.state = PAUSED
self.focus()
def focus(self):
self.container.focus()
def build_bar(self, annot_id):
bar_container = self.bar
clear(bar_container)
bar_container.style.maxWidth = 'min(50rem, 90vw)' if self.supports_css_min_max else '50rem'
bar_container.style.backgroundColor = get_color("window-background")
notes_container = E.div()
for x in [
E.div(style='height: 4ex; display: flex; align-items: center; padding: 5px; justify-content: center'),
E.hr(style='border-top: solid 1px; margin: 0; padding: 0; display: none'),
E.div(
style='display: none; padding: 5px;',
notes_container,
)
]:
bar_container.appendChild(x)
bar = bar_container.firstChild
bar

View File

@ -34,6 +34,7 @@ from read_book.resources import load_resources
from read_book.scrollbar import BookScrollbar from read_book.scrollbar import BookScrollbar
from read_book.search import SearchOverlay, find_in_spine from read_book.search import SearchOverlay, find_in_spine
from read_book.selection_bar import SelectionBar from read_book.selection_bar import SelectionBar
from read_book.read_aloud import ReadAloud
from read_book.shortcuts import create_shortcut_map from read_book.shortcuts import create_shortcut_map
from read_book.timers import Timers from read_book.timers import Timers
from read_book.toc import get_current_toc_nodes, update_visible_toc_nodes from read_book.toc import get_current_toc_nodes, update_visible_toc_nodes
@ -243,6 +244,7 @@ class View:
right_margin, right_margin,
self.book_scrollbar.create(), self.book_scrollbar.create(),
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none;', id='book-selection-bar-overlay'), # selection bar overlay E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none;', id='book-selection-bar-overlay'), # selection bar overlay
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none;', id='book-read-aloud-overlay'), # read aloud overlay
E.div(style='position: absolute; top:0; left:0; width: 100%; pointer-events:none; display:none', id='book-search-overlay'), # search overlay E.div(style='position: absolute; top:0; left:0; width: 100%; pointer-events:none; display:none', id='book-search-overlay'), # search overlay
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none', id='book-content-popup-overlay'), # content popup overlay E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none', id='book-content-popup-overlay'), # content popup overlay
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; overflow: auto; display:none', id='book-overlay'), # main overlay E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; overflow: auto; display:none', id='book-overlay'), # main overlay
@ -313,6 +315,7 @@ class View:
self.content_popup_overlay = ContentPopupOverlay(self) self.content_popup_overlay = ContentPopupOverlay(self)
self.overlay = Overlay(self) self.overlay = Overlay(self)
self.selection_bar = SelectionBar(self) self.selection_bar = SelectionBar(self)
self.read_aloud = ReadAloud(self)
self.processing_spine_item_display = False self.processing_spine_item_display = False
self.pending_load = None self.pending_load = None
self.currently_showing = {'selection': {'empty': True}} self.currently_showing = {'selection': {'empty': True}}
@ -444,6 +447,7 @@ class View:
ui_operations.overlay_visibility_changed(visible) ui_operations.overlay_visibility_changed(visible)
if visible: if visible:
self.selection_bar.hide() self.selection_bar.hide()
self.read_aloud.hide()
else: else:
self.selection_bar.update_position() self.selection_bar.update_position()
@ -659,6 +663,8 @@ class View:
def focus_iframe(self): def focus_iframe(self):
if self.selection_bar.is_visible: if self.selection_bar.is_visible:
self.selection_bar.focus() self.selection_bar.focus()
elif self.read_aloud.is_visible:
self.read_aloud.focus()
else: else:
self.iframe.contentWindow.focus() self.iframe.contentWindow.focus()
@ -1256,6 +1262,7 @@ class View:
def on_content_loaded(self, data): def on_content_loaded(self, data):
self.selection_bar.hide() self.selection_bar.hide()
self.read_aloud.hide()
self.processing_spine_item_display = False self.processing_spine_item_display = False
self.currently_showing.loading = False self.currently_showing.loading = False
self.hide_loading() self.hide_loading()