More work on CS TB

This commit is contained in:
Kovid Goyal 2016-01-31 18:21:29 +05:30
parent a17faec811
commit 8f1ff1e3cf

View File

@ -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)