mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement the basic item list panel
This commit is contained in:
parent
9c916a3679
commit
d7180443da
@ -1,7 +1,7 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from book_list.ui import BookList
|
||||
from book_list.ui import UI
|
||||
|
||||
class Boss:
|
||||
|
||||
@ -10,7 +10,7 @@ class Boss:
|
||||
self.current_library_id = interface_data['default_library']
|
||||
self.current_library_name = interface_data['library_map'][self.current_library_id]
|
||||
self.update_window_title()
|
||||
self.book_list = BookList(interface_data)
|
||||
self.ui = UI(interface_data)
|
||||
|
||||
def update_window_title(self):
|
||||
document.title = 'calibre :: ' + self.current_library_name
|
||||
|
78
src/pyj/book_list/item_list.pyj
Normal file
78
src/pyj/book_list/item_list.pyj
Normal file
@ -0,0 +1,78 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from dom import build_rule
|
||||
from elementmaker import E
|
||||
|
||||
from book_list.theme import get_font_size, get_color
|
||||
|
||||
iv_counter = 0
|
||||
|
||||
class ItemsView:
|
||||
|
||||
def __init__(self, interface_data):
|
||||
nonlocal iv_counter
|
||||
iv_counter += 1
|
||||
self.container_id = 'items-view-' + iv_counter
|
||||
style = ''
|
||||
cid = '#' + self.container_id
|
||||
style += build_rule(cid + ' li', padding='1em', border_bottom='solid 1px ' + get_color('window-foreground'), border_top='solid 1px ' + get_color('window-background'), cursor='pointer', list_style='none')
|
||||
style += build_rule(cid + ' .title', font_size=get_font_size('item-list-title'))
|
||||
style += build_rule(cid + ' .subtitle', font_size=get_font_size('item-list-subtitle'), font_style='italic')
|
||||
style += build_rule(cid + ' li:hover', color=get_color('bar-foreground'), background_color=get_color('bar-background'), border_top_color=get_color('bar-foreground'))
|
||||
style += build_rule(cid + ' li:active', color=get_color('bar-highlight'))
|
||||
self.base_style = style
|
||||
div = E.div(
|
||||
id=self.container_id, style='display:none',
|
||||
E.style(style, type='text/css')
|
||||
)
|
||||
document.body.appendChild(div)
|
||||
|
||||
@property
|
||||
def container(self):
|
||||
return document.getElementById(self.container_id)
|
||||
|
||||
@property
|
||||
def is_visible(self):
|
||||
self.container.style.display == 'block'
|
||||
|
||||
@is_visible.setter
|
||||
def is_visible(self, val):
|
||||
self.container.style.display = 'block' if val else 'none'
|
||||
|
||||
def clear(self):
|
||||
c = self.container
|
||||
while c.lastChild is not c.firstChild:
|
||||
c.removeChild(c.lastChild)
|
||||
return c
|
||||
|
||||
def init(self, data):
|
||||
items = getattr(data, 'items', data)
|
||||
subtitle = getattr(data, 'subtitle', None)
|
||||
c = self.clear()
|
||||
if subtitle:
|
||||
c.appendChild(E.p(subtitle))
|
||||
ul = E.ul()
|
||||
c.appendChild(ul)
|
||||
has_icons = has_subtitles = False
|
||||
for item in items:
|
||||
if item.icon_name:
|
||||
has_icons = True
|
||||
if item.subtitle:
|
||||
has_subtitles = True
|
||||
if has_icons and has_subtitles:
|
||||
break
|
||||
|
||||
for item in items:
|
||||
ul.appendChild(E.li(E.a(href='javascript:void(0)',
|
||||
E.div(item.title, class_='title')
|
||||
)))
|
||||
a = ul.lastChild.firstChild
|
||||
if item.subtitle:
|
||||
a.appendChild(E.div(item.subtitle, class_='subtitle'))
|
||||
if item.action:
|
||||
a.addEventListener('click', def(event): event.preventDefault(), item.action();)
|
||||
|
||||
|
||||
def create_item(title, action=None, subtitle=None, icon_name=None):
|
||||
return {'title':title, 'action':action, 'subtitle':subtitle, 'icon_name':icon_name}
|
@ -14,4 +14,6 @@ def get_color(name):
|
||||
def get_font_size(name):
|
||||
return {
|
||||
'title': '1.4rem',
|
||||
'item-list-title': '1.2rem',
|
||||
'item-list-subtitle': '0.8 rem',
|
||||
}[name]
|
||||
|
@ -81,7 +81,7 @@ class TopBar:
|
||||
href="javascript:void(0)", title=tooltip,
|
||||
E.i(class_='fa fa-' + icon_name)
|
||||
))
|
||||
a = right.firstChild
|
||||
a = right.lastChild
|
||||
if bar is self.bar:
|
||||
if action is not None:
|
||||
a.addEventListener('click', def(event): event.preventDefault(), action();)
|
||||
|
@ -1,9 +1,11 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from book_list.globals import get_boss
|
||||
from book_list.theme import get_color
|
||||
from book_list.top_bar import TopBar
|
||||
from book_list.views import BooksView
|
||||
from book_list.item_list import ItemsView, create_item
|
||||
from dom import set_css
|
||||
from gettext import gettext as _
|
||||
from utils import debounce
|
||||
@ -17,21 +19,94 @@ class BarState:
|
||||
def add_button(self, **kw):
|
||||
self.buttons.push(kw)
|
||||
|
||||
class BookList:
|
||||
class ClosePanelBar(BarState):
|
||||
|
||||
def __init__(self, title, tooltip=''):
|
||||
tooltip = tooltip or _('Close this panel')
|
||||
BarState.__init__(self, title=title, tooltip=tooltip, action=close_panel, icon_name='times')
|
||||
|
||||
class UIState:
|
||||
|
||||
def __init__(self, top_bar_state=None, main_panel=None, panel_data=None):
|
||||
self.top_bar_state = top_bar_state
|
||||
self.main_panel = main_panel or get_boss().ui.items_view
|
||||
self.panel_data = panel_data
|
||||
|
||||
def add_button(self, **kw):
|
||||
self.top_bar_state.add_button(**kw)
|
||||
|
||||
panels = {}
|
||||
|
||||
def panel(key):
|
||||
ans = panels[key]
|
||||
if not ans:
|
||||
ans = panels[key] = create_panel[key]()
|
||||
return ans
|
||||
|
||||
def close_panel():
|
||||
get_boss().ui.close_panel()
|
||||
|
||||
def replace_panel_action(replacement):
|
||||
return def():
|
||||
get_boss().ui.replace_panel(panel(replacement))
|
||||
|
||||
def show_panel_action(key):
|
||||
return def():
|
||||
get_boss().ui.show_panel(panel(key))
|
||||
|
||||
create_panel = {
|
||||
'more-actions-menu': def more_actions_menu():
|
||||
return UIState(ClosePanelBar(_('More actions')), panel_data=[
|
||||
create_item(_('Book List Mode'), replace_panel_action('booklist-mode-menu'), _('Change how the list of books is displayed')),
|
||||
])
|
||||
,
|
||||
|
||||
'booklist-mode-menu': def booklist_mode_menu():
|
||||
return UIState(ClosePanelBar(_('Book List Mode')), panel_data=[
|
||||
])
|
||||
,
|
||||
}
|
||||
|
||||
|
||||
class UI:
|
||||
|
||||
def __init__(self, interface_data):
|
||||
set_css(document.body, background_color=get_color('window-background'))
|
||||
self.states = []
|
||||
self.initial_bar_state = ibs = BarState(run_animation=True)
|
||||
self.states, self.panels = [], []
|
||||
self.top_bar = TopBar()
|
||||
self.books_view = BooksView(interface_data)
|
||||
self.items_view = ItemsView(interface_data)
|
||||
ibs = BarState(run_animation=True)
|
||||
ibs.add_button(icon_name='sort-alpha-asc', tooltip=_('Sort books'))
|
||||
ibs.add_button(icon_name='search', tooltip=_('Search for books'))
|
||||
ibs.add_button(icon_name='bars', tooltip=_('More actions'))
|
||||
self.states.append(ibs)
|
||||
self.top_bar = TopBar()
|
||||
self.top_bar.apply_state(ibs.left_state, ibs.buttons)
|
||||
self.books_view = BooksView(interface_data)
|
||||
ibs.add_button(icon_name='ellipsis-v', tooltip=_('More actions'), action=show_panel_action('more-actions-menu'))
|
||||
self.states.append(UIState(ibs, self.books_view))
|
||||
self.apply_state(self.states[0])
|
||||
ibs.left_state.run_animation = False
|
||||
window.addEventListener('resize', debounce(bind(self.on_resize, self), 250))
|
||||
self.panels = v'[self.books_view, self.items_view]'
|
||||
|
||||
def on_resize(self):
|
||||
self.books_view.on_resize()
|
||||
|
||||
def apply_state(self, state):
|
||||
self.top_bar.apply_state(state.top_bar_state.left_state, state.top_bar_state.buttons)
|
||||
for panel in self.panels:
|
||||
panel.is_visible = panel is state.main_panel
|
||||
if callable(state.main_panel.init):
|
||||
state.main_panel.init(state.panel_data)
|
||||
|
||||
def close_panel(self):
|
||||
if len(self.states) > 1:
|
||||
self.states.pop()
|
||||
self.apply_state(self.states[-1])
|
||||
|
||||
def replace_panel(self, state):
|
||||
if len(self.states) > 1:
|
||||
self.states.pop()
|
||||
self.states.append(state)
|
||||
self.apply_state(self.states[-1])
|
||||
|
||||
def show_panel(self, state):
|
||||
self.states.append(state)
|
||||
self.apply_state(self.states[-1])
|
||||
|
Loading…
x
Reference in New Issue
Block a user