mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
More work on CS TB
This commit is contained in:
parent
a17faec811
commit
8f1ff1e3cf
@ -62,6 +62,7 @@ class SearchPanel:
|
|||||||
self.initial_load_started = False
|
self.initial_load_started = False
|
||||||
self.currently_loading = None
|
self.currently_loading = None
|
||||||
self.tag_browser_data = None
|
self.tag_browser_data = None
|
||||||
|
self.node_id_map = {}
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tb = self.container.querySelector('input[name="search-books"]')
|
tb = self.container.querySelector('input[name="search-books"]')
|
||||||
@ -87,11 +88,12 @@ class SearchPanel:
|
|||||||
self.currently_loading = None
|
self.currently_loading = None
|
||||||
if end_type == 'abort':
|
if end_type == 'abort':
|
||||||
return
|
return
|
||||||
|
|
||||||
parent = self.container.lastChild
|
parent = self.container.lastChild
|
||||||
if parent.lastChild.style.display == 'none':
|
if parent.lastChild.style.display == 'none':
|
||||||
parent.firstChild.style.display = 'none'
|
parent.firstChild.style.display = 'none'
|
||||||
parent.lastChild.style.display = 'block'
|
parent.lastChild.style.display = 'block'
|
||||||
container = parent.lastChild
|
container = self.tb_container
|
||||||
clear(container)
|
clear(container)
|
||||||
|
|
||||||
def show_error(error_html):
|
def show_error(error_html):
|
||||||
@ -99,48 +101,58 @@ class SearchPanel:
|
|||||||
container.appendChild(ediv)
|
container.appendChild(ediv)
|
||||||
ediv.innerHTML = '<h3>' + _('Failed to load tag browser data') + '</h3>' + error_html
|
ediv.innerHTML = '<h3>' + _('Failed to load tag browser data') + '</h3>' + error_html
|
||||||
|
|
||||||
|
def process_node(node):
|
||||||
|
self.node_id_map[node.id] = node
|
||||||
|
node.data = item_map[node.id]
|
||||||
|
for child in node.children:
|
||||||
|
child.parent = node
|
||||||
|
process_node(child)
|
||||||
|
|
||||||
if end_type == 'load':
|
if end_type == 'load':
|
||||||
try:
|
try:
|
||||||
self.tag_browser_data = JSON.parse(xhr.responseText)
|
tag_browser_data = JSON.parse(xhr.responseText)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
show_error(err + '')
|
show_error(err + '')
|
||||||
return
|
return
|
||||||
|
item_map = tag_browser_data['item_map']
|
||||||
|
self.tag_browser_data = tag_browser_data.root
|
||||||
|
process_node(self.tag_browser_data)
|
||||||
self.render_tag_browser(container, clear_path=True)
|
self.render_tag_browser(container, clear_path=True)
|
||||||
else:
|
else:
|
||||||
show_error(xhr.error_html)
|
show_error(xhr.error_html)
|
||||||
|
|
||||||
def render_tag_browser(self, container, clear_path=False):
|
def node_for_path(self, path):
|
||||||
|
path = path or self.tag_path
|
||||||
|
ans = self.tag_browser_data
|
||||||
|
for child_index in path:
|
||||||
|
ans = ans.children[child_index]
|
||||||
|
return ans
|
||||||
|
|
||||||
|
def render_tag_browser(self, container=None, clear_path=False):
|
||||||
if clear_path:
|
if clear_path:
|
||||||
self.tag_path = []
|
self.tag_path = []
|
||||||
|
container = container or self.tb_container
|
||||||
clear(container)
|
clear(container)
|
||||||
set_css(container, padding='1rem', display='flex', flex_wrap='wrap')
|
set_css(container, padding='1rem', display='flex', flex_wrap='wrap')
|
||||||
parent = self.tag_browser_data.root
|
self.render_children(container, self.node_for_path().children)
|
||||||
detailed_child = None
|
|
||||||
for child_index, state in self.tag_path:
|
|
||||||
q = parent.children and parent.children[child_index]
|
|
||||||
if not q:
|
|
||||||
break
|
|
||||||
parent, detailed_child = q, state
|
|
||||||
if detailed_child is not None and parent.children[detailed_child]:
|
|
||||||
self.render_child_menu(container, parent.children[detailed_child])
|
|
||||||
else:
|
|
||||||
self.render_children(container, parent.children)
|
|
||||||
|
|
||||||
def icon_for_node(self, node):
|
def icon_for_node(self, node):
|
||||||
ans = self.interface_data.icon_map[node.category] or 'column.png'
|
ans = self.interface_data.icon_map[node.data.category] or 'column.png'
|
||||||
return self.interface_data.icon_path + '/' + ans
|
return self.interface_data.icon_path + '/' + ans
|
||||||
|
|
||||||
def render_children(self, container, children):
|
def render_children(self, container, children):
|
||||||
item_map = self.tag_browser_data.item_map
|
|
||||||
|
|
||||||
for child in children:
|
def click_handler(func, i):
|
||||||
node = item_map[child.id]
|
return def():
|
||||||
|
func.call(self, i)
|
||||||
|
|
||||||
|
for i, node in enumerate(children):
|
||||||
div = E.div(
|
div = E.div(
|
||||||
style="display:flex; align-items: stretch",
|
style="display:flex; align-items: stretch",
|
||||||
E.div(class_='tag-name',
|
E.div(class_='tag-name',
|
||||||
style='border-right:solid 1px currentColor; padding: 1ex; display:block',
|
style='border-right:solid 1px currentColor; padding: 1ex; display:block',
|
||||||
E.img(src=self.icon_for_node(node), style='vertical-align:middle; display:inline-block; max-height:4ex'),
|
E.img(src=self.icon_for_node(node), style='vertical-align:middle; display:inline-block; max-height:4ex'),
|
||||||
'\xa0' + node.name
|
'\xa0' + node.data.name
|
||||||
),
|
),
|
||||||
E.div(class_='tag-menu',
|
E.div(class_='tag-menu',
|
||||||
style='padding: 1ex; display:flex; align-items:center',
|
style='padding: 1ex; display:flex; align-items:center',
|
||||||
@ -148,12 +160,32 @@ class SearchPanel:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
set_css(div, max_width='45vw', border='solid 1px currentColor', border_radius='20px', margin='0.5rem', cursor='pointer', overflow='hidden', user_select='none')
|
set_css(div, max_width='45vw', border='solid 1px currentColor', border_radius='20px', margin='0.5rem', cursor='pointer', overflow='hidden', user_select='none')
|
||||||
|
div.firstChild.addEventListener('click', click_handler(self.node_clicked, i))
|
||||||
container.appendChild(div)
|
container.appendChild(div)
|
||||||
|
|
||||||
|
def search_expression_for_item(self, node):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def node_clicked(self, i):
|
||||||
|
node = self.node_for_path().children[i]
|
||||||
|
if node.children and node.children.length:
|
||||||
|
self.tag_path.append(i)
|
||||||
|
self.render_tag_browser()
|
||||||
|
else:
|
||||||
|
self.execute_search(self.search_expression_for_item(node))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def container(self):
|
def container(self):
|
||||||
return document.getElementById(self.container_id)
|
return document.getElementById(self.container_id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tb_container(self):
|
||||||
|
return self.container.lastChild.lastChild
|
||||||
|
|
||||||
|
@property
|
||||||
|
def search_control(self):
|
||||||
|
return self.container.querySelector('input[name="search-books"]')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_visible(self):
|
def is_visible(self):
|
||||||
self.container.style.display == 'block'
|
self.container.style.display == 'block'
|
||||||
@ -162,6 +194,6 @@ class SearchPanel:
|
|||||||
def is_visible(self, val):
|
def is_visible(self, val):
|
||||||
self.container.style.display = 'block' if val else 'none'
|
self.container.style.display = 'block' if val else 'none'
|
||||||
|
|
||||||
def execute_search(self):
|
def execute_search(self, text=''):
|
||||||
text = self.container.querySelector('input[name="search-books"]').value or ''
|
text = text or self.search_control.value or ''
|
||||||
get_boss().ui.books_view.change_search(text)
|
get_boss().ui.books_view.change_search(text)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user