A simple TreeView widget

This commit is contained in:
Kovid Goyal 2016-06-10 07:47:31 +05:30
parent e7fe3f771f
commit c295219a28
4 changed files with 58 additions and 2 deletions

View File

@ -0,0 +1 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/></svg>

After

Width:  |  Height:  |  Size: 214 B

View File

@ -0,0 +1 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1152 896q0 26-19 45l-448 448q-19 19-45 19t-45-19-19-45v-896q0-26 19-45t45-19 45 19l448 448q19 19 19 45z"/></svg>

After

Width:  |  Height:  |  Size: 213 B

View File

@ -71,12 +71,19 @@ def create_keyframes(animation_name, *frames):
ans.push('}') ans.push('}')
return ans.join('\n') + '\n' return ans.join('\n') + '\n'
def change_icon_image(icon_element, new_name):
if new_name:
icon_element.firstChild.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#icon-' + new_name)
else:
icon_element.firstChild.removeAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href')
def svgicon(name, height, width): def svgicon(name, height, width):
ans = document.createElementNS('http://www.w3.org/2000/svg', 'svg') ans = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
ans.setAttribute('style', 'fill: currentColor; height: {}; width: {}; vertical-align: text-top'.format(height ? '2ex', width ? '2ex')) ans.setAttribute('style', 'fill: currentColor; height: {}; width: {}; vertical-align: text-top'.format(height ? '2ex', width ? '2ex'))
u = document.createElementNS('http://www.w3.org/2000/svg', 'use') u = document.createElementNS('http://www.w3.org/2000/svg', 'use')
u.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#icon-' + name)
ans.appendChild(u) ans.appendChild(u)
if name:
ans.firstChild.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#icon-' + name)
return ans return ans
def element(elem_id, child_selector): def element(elem_id, child_selector):

View File

@ -2,7 +2,7 @@
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from __python__ import hash_literals from __python__ import hash_literals
from dom import build_rule, clear, svgicon, create_keyframes, set_css from dom import build_rule, clear, svgicon, create_keyframes, set_css, change_icon_image
from elementmaker import E from elementmaker import E
from book_list.theme import get_color from book_list.theme import get_color
@ -94,6 +94,53 @@ class Breadcrumbs:
self.container.appendChild(li) self.container.appendChild(li)
return li return li
def create_tree(root, populate_data, onclick):
container = E.div()
set_css(container, overflow='auto')
def toggle_node(li):
if li.dataset.treeState is 'closed':
li.dataset.treeState = 'open'
li.lastChild.style.display = 'block'
change_icon_image(li.firstChild.firstChild, 'caret-down')
else:
li.dataset.treeState = 'closed'
li.lastChild.style.display = 'none'
change_icon_image(li.firstChild.firstChild, 'caret-right')
def process_node(node, parent_container, level):
if node.children?.length:
ul = E.div()
parent_container.appendChild(ul)
for child in node.children:
icon = 'caret-right' if child.children?.length else None
li = E.div(style='display:flex; flex-direction:column; margin: 1ex 1em; margin-left: {}em'.format(level+1),
E.div(style='display:flex; align-items: center',
svgicon(icon),
E.span('\xa0'),
E.a(
href='javascript: void(0)',
onclick=def (event):
if onclick:
onclick(event.currentTarget.parentNode.parentNode)
),
),
E.div(style='display:none'),
data_tree_state='closed',
)
ul.appendChild(li)
populate_data(child, li, li.firstChild.lastChild)
if icon:
set_css(li.firstChild.firstChild, cursor='pointer')
li.firstChild.firstChild.addEventListener('click', def(event):
toggle_node(event.currentTarget.parentNode.parentNode)
)
process_node(child, li.lastChild, level + 1)
if root:
process_node(root, container, 0)
return container
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