mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Start work on ToC view
This commit is contained in:
parent
c295219a28
commit
18754ac18f
@ -39,6 +39,7 @@ class IframeBoss:
|
|||||||
self.handlers = {
|
self.handlers = {
|
||||||
'initialize':self.initialize,
|
'initialize':self.initialize,
|
||||||
'display': self.display,
|
'display': self.display,
|
||||||
|
'scroll_to_anchor': self.on_scroll_to_anchor,
|
||||||
}
|
}
|
||||||
self.last_window_ypos = 0
|
self.last_window_ypos = 0
|
||||||
|
|
||||||
@ -105,6 +106,13 @@ class IframeBoss:
|
|||||||
root_data, self.mathjax = finalize_resources(self.book, data.name, data.resource_data)
|
root_data, self.mathjax = finalize_resources(self.book, data.name, data.resource_data)
|
||||||
unserialize_html(root_data, self.content_loaded)
|
unserialize_html(root_data, self.content_loaded)
|
||||||
|
|
||||||
|
def on_scroll_to_anchor(self, data):
|
||||||
|
frag = data.frag
|
||||||
|
if frag:
|
||||||
|
self.scroll_to_anchor(frag)
|
||||||
|
else:
|
||||||
|
self.to_scroll_fraction(0.0)
|
||||||
|
|
||||||
def content_loaded(self):
|
def content_loaded(self):
|
||||||
document.documentElement.style.overflow = 'hidden'
|
document.documentElement.style.overflow = 'hidden'
|
||||||
self.do_layout()
|
self.do_layout()
|
||||||
|
@ -8,6 +8,7 @@ from book_list.theme import get_color
|
|||||||
from book_list.globals import get_boss
|
from book_list.globals import get_boss
|
||||||
from widgets import create_spinner, create_button
|
from widgets import create_spinner, create_button
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
|
from read_book.toc import create_toc_panel
|
||||||
|
|
||||||
class LoadingMessage: # {{{
|
class LoadingMessage: # {{{
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ class MainOverlay: # {{{
|
|||||||
), display='flex', align_items='center', flex_wrap='wrap', padding='0 0.5rem', border_bottom='solid 1px currentColor'),
|
), display='flex', align_items='center', flex_wrap='wrap', padding='0 0.5rem', border_bottom='solid 1px currentColor'),
|
||||||
|
|
||||||
set_css(E.ul(class_='item-list', # list of items
|
set_css(E.ul(class_='item-list', # list of items
|
||||||
E.li(_('Table of Contents')),
|
E.li(_('Table of Contents'), onclick=self.overlay.show_toc),
|
||||||
E.li(_('Bookmarks')),
|
E.li(_('Bookmarks')),
|
||||||
E.li(_('Go to a specific location in the book')),
|
E.li(_('Go to a specific location in the book')),
|
||||||
), list_style_type='none'),
|
), list_style_type='none'),
|
||||||
@ -183,6 +184,23 @@ class MainOverlay: # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
class TOCOverlay: # {{{
|
||||||
|
|
||||||
|
def __init__(self, overlay):
|
||||||
|
self.overlay = overlay
|
||||||
|
|
||||||
|
def on_container_click(self, evt):
|
||||||
|
pass # Dont allow panel to be closed by a click
|
||||||
|
|
||||||
|
def show(self, container):
|
||||||
|
container.style.backgroundColor = get_color('window-background')
|
||||||
|
create_toc_panel(self.overlay.view.book, container, self.handle_activate)
|
||||||
|
|
||||||
|
def handle_activate(self, dest, frag):
|
||||||
|
self.overlay.hide()
|
||||||
|
self.overlay.view.goto_named_destination(dest, frag)
|
||||||
|
# }}}
|
||||||
|
|
||||||
class Overlay:
|
class Overlay:
|
||||||
|
|
||||||
def __init__(self, view):
|
def __init__(self, view):
|
||||||
@ -249,3 +267,8 @@ class Overlay:
|
|||||||
self.hide_current_panel()
|
self.hide_current_panel()
|
||||||
self.panels = [DeleteBook(self, _('Are you sure you want to reload this book?'), 'refresh', _('Reload book'), True)]
|
self.panels = [DeleteBook(self, _('Are you sure you want to reload this book?'), 'refresh', _('Reload book'), True)]
|
||||||
self.show_current_panel()
|
self.show_current_panel()
|
||||||
|
|
||||||
|
def show_toc(self):
|
||||||
|
self.hide_current_panel()
|
||||||
|
self.panels.push(TOCOverlay(self))
|
||||||
|
self.show_current_panel()
|
||||||
|
21
src/pyj/read_book/toc.pyj
Normal file
21
src/pyj/read_book/toc.pyj
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
from __python__ import hash_literals
|
||||||
|
|
||||||
|
from widgets import create_tree
|
||||||
|
|
||||||
|
def create_toc_tree(toc, onclick):
|
||||||
|
|
||||||
|
def populate_data(node, li, a):
|
||||||
|
li.dataset.tocDest = node.dest or ''
|
||||||
|
li.dataset.tocFrag = node.frag or ''
|
||||||
|
a.textContent = node.title or ''
|
||||||
|
|
||||||
|
return create_tree(toc, populate_data, onclick)
|
||||||
|
|
||||||
|
def create_toc_panel(book, container, onclick):
|
||||||
|
def handle_click(event, li):
|
||||||
|
if event.button is 0:
|
||||||
|
onclick(li.dataset.tocDest, li.dataset.tocFrag)
|
||||||
|
toc_panel = create_toc_tree(book.manifest.toc, handle_click)
|
||||||
|
container.appendChild(toc_panel)
|
@ -205,6 +205,18 @@ class View:
|
|||||||
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})
|
||||||
|
|
||||||
|
def goto_named_destination(self, name, frag):
|
||||||
|
if self.currently_showing.name is name:
|
||||||
|
self.send_message('scroll_to_anchor', frag=frag)
|
||||||
|
else:
|
||||||
|
spine = self.book.manifest.spine
|
||||||
|
idx = spine.indexOf(name)
|
||||||
|
if idx is -1:
|
||||||
|
self.ui.show_error(_('Destination does not exist'), _(
|
||||||
|
'The file {} does not exist in this book').format(name))
|
||||||
|
return
|
||||||
|
self.show_name(name, initial_position={'type':'anchor', 'anchor':frag, 'replace_history':False})
|
||||||
|
|
||||||
def on_next_spine_item(self, data):
|
def on_next_spine_item(self, data):
|
||||||
spine = self.book.manifest.spine
|
spine = self.book.manifest.spine
|
||||||
idx = spine.indexOf(self.currently_showing.name)
|
idx = spine.indexOf(self.currently_showing.name)
|
||||||
|
@ -95,7 +95,7 @@ class Breadcrumbs:
|
|||||||
return li
|
return li
|
||||||
|
|
||||||
def create_tree(root, populate_data, onclick):
|
def create_tree(root, populate_data, onclick):
|
||||||
container = E.div()
|
container = E.div(class_='simple-tree')
|
||||||
set_css(container, overflow='auto')
|
set_css(container, overflow='auto')
|
||||||
|
|
||||||
def toggle_node(li):
|
def toggle_node(li):
|
||||||
@ -122,7 +122,7 @@ def create_tree(root, populate_data, onclick):
|
|||||||
href='javascript: void(0)',
|
href='javascript: void(0)',
|
||||||
onclick=def (event):
|
onclick=def (event):
|
||||||
if onclick:
|
if onclick:
|
||||||
onclick(event.currentTarget.parentNode.parentNode)
|
onclick(event, event.currentTarget.parentNode.parentNode)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
E.div(style='display:none'),
|
E.div(style='display:none'),
|
||||||
@ -141,9 +141,15 @@ def create_tree(root, populate_data, onclick):
|
|||||||
process_node(root, container, 0)
|
process_node(root, container, 0)
|
||||||
return container
|
return container
|
||||||
|
|
||||||
|
create_tree.style = '''
|
||||||
|
div.simple-tree a:hover { color: red; }
|
||||||
|
div.simple-tree a:active { transform: scale(1.5); }
|
||||||
|
'''
|
||||||
|
|
||||||
def get_widget_css():
|
def get_widget_css():
|
||||||
ans = 'a, button:focus { outline: none }; a, button::-moz-focus-inner { border: 0 }\n'
|
ans = 'a, button:focus { outline: none }; a, button::-moz-focus-inner { border: 0 }\n'
|
||||||
ans += create_button.style
|
ans += create_button.style
|
||||||
ans += create_spinner.style
|
ans += create_spinner.style
|
||||||
ans += Breadcrumbs.STYLE_RULES
|
ans += Breadcrumbs.STYLE_RULES
|
||||||
|
ans += create_tree.style
|
||||||
return ans
|
return ans
|
||||||
|
Loading…
x
Reference in New Issue
Block a user