mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Wire up the hints overlay
This commit is contained in:
parent
99dedc4ac3
commit
b4731c552c
@ -3,6 +3,53 @@
|
||||
from __python__ import bound_methods, hash_literals
|
||||
|
||||
|
||||
class Hints:
|
||||
|
||||
def __init__(self, view):
|
||||
self.view = view
|
||||
container = self.container
|
||||
container.setAttribute('tabindex', '0')
|
||||
container.style.overflow = 'hidden'
|
||||
container.addEventListener('keydown', self.on_keydown, {'passive': False})
|
||||
container.addEventListener('click', self.container_clicked, {'passive': False})
|
||||
|
||||
@property
|
||||
def container(self):
|
||||
return document.getElementById('book-hints-overlay')
|
||||
|
||||
@property
|
||||
def is_visible(self):
|
||||
return self.container.style.display is not 'none'
|
||||
|
||||
def focus(self):
|
||||
self.container.focus()
|
||||
|
||||
def hide(self):
|
||||
if self.is_visible:
|
||||
self.container.style.display = 'none'
|
||||
self.send_message('hide')
|
||||
|
||||
def show(self):
|
||||
if not self.is_visible:
|
||||
self.container.style.display = 'block'
|
||||
self.focus()
|
||||
self.send_message('show')
|
||||
|
||||
def on_keydown(self, ev):
|
||||
ev.preventDefault(), ev.stopPropagation()
|
||||
|
||||
def container_clicked(self, ev):
|
||||
ev.stopPropagation(), ev.preventDefault()
|
||||
self.hide()
|
||||
|
||||
def send_message(self, type, **kw):
|
||||
self.view.iframe_wrapper.send_message('hints', type=type, **kw)
|
||||
|
||||
def handle_message(self, msg):
|
||||
if msg.type is 'shown':
|
||||
self.hints_map = msg.hints_map
|
||||
|
||||
|
||||
def is_visible(a):
|
||||
if not a.offsetParent:
|
||||
return False
|
||||
|
@ -11,6 +11,7 @@ from range_utils import (
|
||||
last_span_for_crw, reset_highlight_counter, select_crw, unwrap_all_crw,
|
||||
unwrap_crw, wrap_text_in_range
|
||||
)
|
||||
from read_book.hints import hint_visible_links, unhint_links
|
||||
from read_book.cfi import cfi_for_selection, range_from_cfi
|
||||
from read_book.extract import get_elements
|
||||
from read_book.find import (
|
||||
@ -148,6 +149,7 @@ class IframeBoss:
|
||||
'handle_navigation_shortcut': self.on_handle_navigation_shortcut,
|
||||
'annotations': self.annotations_msg_received,
|
||||
'tts': self.tts_msg_received,
|
||||
'hints': self.hints_msg_received,
|
||||
'copy_selection': self.copy_selection,
|
||||
'replace_highlights': self.replace_highlights,
|
||||
'clear_selection': def(): window.getSelection().removeAllRanges();,
|
||||
@ -228,6 +230,7 @@ class IframeBoss:
|
||||
set_toc_anchor_map()
|
||||
self.replace_history_on_next_cfi_update = True
|
||||
self.book = current_book.book = data.book
|
||||
self.link_attr = 'data-' + self.book.manifest.link_uid
|
||||
self.reference_mode_enabled = data.reference_mode_enabled
|
||||
self.is_titlepage = data.is_titlepage
|
||||
spine = self.book.manifest.spine
|
||||
@ -650,9 +653,9 @@ class IframeBoss:
|
||||
def send_message(self, action, **data):
|
||||
self.comm.send_message(action, data)
|
||||
|
||||
|
||||
def connect_links(self):
|
||||
link_attr = 'data-' + self.book.manifest.link_uid
|
||||
for a in document.body.querySelectorAll(f'a[{link_attr}]'):
|
||||
for a in document.body.querySelectorAll(f'a[{self.link_attr}]'):
|
||||
a.addEventListener('click', self.link_activated)
|
||||
if runtime.is_standalone_viewer:
|
||||
# links with a target get turned into requests to open a new window by Qt
|
||||
@ -669,11 +672,10 @@ class IframeBoss:
|
||||
self.send_message('view_image', calibre_src=img.dataset.calibreSrc)
|
||||
|
||||
def link_activated(self, evt):
|
||||
link_attr = 'data-' + self.book.manifest.link_uid
|
||||
try:
|
||||
data = JSON.parse(evt.currentTarget.getAttribute(link_attr))
|
||||
data = JSON.parse(evt.currentTarget.getAttribute(self.link_attr))
|
||||
except:
|
||||
print('WARNING: Failed to parse link data {}, ignoring'.format(evt.currentTarget?.getAttribute?(link_attr)))
|
||||
print('WARNING: Failed to parse link data {}, ignoring'.format(evt.currentTarget?.getAttribute?(self.link_attr)))
|
||||
return
|
||||
name, frag = data.name, data.frag
|
||||
if not name:
|
||||
@ -917,5 +919,15 @@ class IframeBoss:
|
||||
if select_tts_mark(occurrence_number):
|
||||
self.ensure_selection_visible()
|
||||
|
||||
def hints_msg_received(self, data):
|
||||
if data.type is 'show':
|
||||
# clear selection so that it does not confuse with the hints which use the same colors
|
||||
window.getSelection().removeAllRanges()
|
||||
hints_map = hint_visible_links(self.link_attr)
|
||||
self.send_message('hints', type='shown', hints_map=hints_map)
|
||||
elif data.type is 'hide':
|
||||
unhint_links(self.link_attr)
|
||||
|
||||
|
||||
def main():
|
||||
main.boss = IframeBoss()
|
||||
|
@ -194,6 +194,12 @@ def shortcuts_definition():
|
||||
_('Read aloud')
|
||||
),
|
||||
|
||||
'toggle_hints': desc(
|
||||
'Alt+f',
|
||||
'ui',
|
||||
_('Follow links with the keyboard')
|
||||
),
|
||||
|
||||
'copy_to_clipboard': desc(
|
||||
v"['Ctrl+c', 'Meta+c']",
|
||||
'ui',
|
||||
|
@ -35,6 +35,7 @@ from read_book.scrollbar import BookScrollbar
|
||||
from read_book.search import SearchOverlay, find_in_spine
|
||||
from read_book.selection_bar import SelectionBar
|
||||
from read_book.read_aloud import ReadAloud
|
||||
from read_book.hints import Hints
|
||||
from read_book.shortcuts import create_shortcut_map
|
||||
from read_book.timers import Timers
|
||||
from read_book.toc import get_current_toc_nodes, update_visible_toc_nodes
|
||||
@ -245,6 +246,7 @@ class View:
|
||||
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-read-aloud-overlay'), # read aloud overlay
|
||||
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none;', id='book-hints-overlay'), # hints 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%; overflow: auto; display:none', id='book-overlay'), # main overlay
|
||||
@ -317,6 +319,7 @@ class View:
|
||||
self.overlay = Overlay(self)
|
||||
self.selection_bar = SelectionBar(self)
|
||||
self.read_aloud = ReadAloud(self)
|
||||
self.hints = Hints(self)
|
||||
self.processing_spine_item_display = False
|
||||
self.pending_load = None
|
||||
self.currently_showing = {'selection': {'empty': True}}
|
||||
@ -349,6 +352,9 @@ class View:
|
||||
def on_tts_message(self, data):
|
||||
self.read_aloud.handle_message(data)
|
||||
|
||||
def on_hints_message(self, data):
|
||||
self.hints.handle_message(data)
|
||||
|
||||
def left_margin_clicked(self, event):
|
||||
if event.button is 0:
|
||||
event.preventDefault(), event.stopPropagation()
|
||||
@ -452,6 +458,7 @@ class View:
|
||||
if visible:
|
||||
self.selection_bar.hide()
|
||||
self.read_aloud.hide()
|
||||
self.hints.hide()
|
||||
else:
|
||||
self.selection_bar.update_position()
|
||||
|
||||
@ -507,6 +514,8 @@ class View:
|
||||
self.toggle_reference_mode()
|
||||
elif data.name is 'read_aloud':
|
||||
self.start_read_aloud()
|
||||
elif data.name is 'toggle_hints':
|
||||
self.toggle_hints()
|
||||
elif data.name is 'toggle_read_aloud':
|
||||
self.toggle_read_aloud()
|
||||
elif data.name is 'reload_book':
|
||||
@ -673,11 +682,14 @@ class View:
|
||||
self.selection_bar.focus()
|
||||
elif self.read_aloud.is_visible:
|
||||
self.read_aloud.focus()
|
||||
elif self.hints.is_visible:
|
||||
self.hints.focus()
|
||||
else:
|
||||
self.iframe.contentWindow.focus()
|
||||
|
||||
def start_read_aloud(self, dont_start_talking):
|
||||
self.selection_bar.hide()
|
||||
self.hints.hide()
|
||||
self.read_aloud.show()
|
||||
if not dont_start_talking:
|
||||
self.read_aloud.play()
|
||||
@ -688,6 +700,14 @@ class View:
|
||||
else:
|
||||
self.start_read_aloud()
|
||||
|
||||
def toggle_hints(self):
|
||||
if self.hints.is_visible:
|
||||
self.hints.hide()
|
||||
else:
|
||||
self.selection_bar.hide()
|
||||
self.read_aloud.hide()
|
||||
self.hints.show()
|
||||
|
||||
def show_chrome(self, data):
|
||||
elements = {}
|
||||
if data and data.elements:
|
||||
|
Loading…
x
Reference in New Issue
Block a user