Start work on ToC view

This commit is contained in:
Kovid Goyal 2016-06-10 09:40:31 +05:30
parent c295219a28
commit 18754ac18f
5 changed files with 73 additions and 3 deletions

View File

@ -39,6 +39,7 @@ class IframeBoss:
self.handlers = {
'initialize':self.initialize,
'display': self.display,
'scroll_to_anchor': self.on_scroll_to_anchor,
}
self.last_window_ypos = 0
@ -105,6 +106,13 @@ class IframeBoss:
root_data, self.mathjax = finalize_resources(self.book, data.name, data.resource_data)
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):
document.documentElement.style.overflow = 'hidden'
self.do_layout()

View File

@ -8,6 +8,7 @@ from book_list.theme import get_color
from book_list.globals import get_boss
from widgets import create_spinner, create_button
from gettext import gettext as _
from read_book.toc import create_toc_panel
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'),
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(_('Go to a specific location in the book')),
), 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:
def __init__(self, view):
@ -249,3 +267,8 @@ class Overlay:
self.hide_current_panel()
self.panels = [DeleteBook(self, _('Are you sure you want to reload this book?'), 'refresh', _('Reload book'), True)]
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
View 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)

View File

@ -205,6 +205,18 @@ class View:
def on_scroll_to_anchor(self, data):
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):
spine = self.book.manifest.spine
idx = spine.indexOf(self.currently_showing.name)

View File

@ -95,7 +95,7 @@ class Breadcrumbs:
return li
def create_tree(root, populate_data, onclick):
container = E.div()
container = E.div(class_='simple-tree')
set_css(container, overflow='auto')
def toggle_node(li):
@ -122,7 +122,7 @@ def create_tree(root, populate_data, onclick):
href='javascript: void(0)',
onclick=def (event):
if onclick:
onclick(event.currentTarget.parentNode.parentNode)
onclick(event, event.currentTarget.parentNode.parentNode)
),
),
E.div(style='display:none'),
@ -141,9 +141,15 @@ def create_tree(root, populate_data, onclick):
process_node(root, container, 0)
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():
ans = 'a, button:focus { outline: none }; a, button::-moz-focus-inner { border: 0 }\n'
ans += create_button.style
ans += create_spinner.style
ans += Breadcrumbs.STYLE_RULES
ans += create_tree.style
return ans