diff --git a/kivyblocks/block_test.py b/kivyblocks/block_test.py new file mode 100644 index 0000000..a0a98fe --- /dev/null +++ b/kivyblocks/block_test.py @@ -0,0 +1,60 @@ +from traceback import print_exc +import ujson as json +from kivy.properties import StringProperty +from kivy.factory import Factory +from .toolbar import Toolbar +from .baseWidget import VBox, StrInput +from .utils import SUPER, blockImage, CSize +from .clickable import ClickableText + +class BlockTest(VBox): + source_code = StringProperty(None) + def __init__(self, **kw): + SUPER(BlockTest, self, kw) + tb_desc = { + "img_size_c":2, + "toolbar_orient":"H", + "tool_orient":"horizontal", + "css_on":"default", + "css_off":"default", + "tools":[ + { + "name":"source", + "source_on":blockImage('source_on.png'), + "source_off":blockImage('source_off.png'), + "label":"source code" + }, + { + "name":"widget", + "source_on":blockImage('widget_on.png'), + "source_off":blockImage('widget_off.png'), + "label":"Result widget" + } + ] + } + self.toolbar = Toolbar(**tb_desc) + self.toolbar.bind(on_press=self.tool_pressed) + self.content = VBox() + self.source_w = StrInput(multiline=True) + self.content.add_widget(self.source_w) + if self.source_code: + self.source_w.text = self.source_code + self.add_widget(self.toolbar) + self.add_widget(self.content) + + def tool_pressed(self, o, v): + self.content.clear_widgets() + if v['name'] == 'source': + print('switch to source code') + self.content.add_widget(self.source_w) + else: + try: + dic = json.loads(self.source_w.text) + print(dic, type(dic)) + w = Factory.Blocks().widgetBuild(dic) + self.content.add_widget(w) + except Exception as e: + print_exc() + print('BlockTest:Exception:',e) + +Factory.register('BlockTest', BlockTest) diff --git a/kivyblocks/hirarchy.py b/kivyblocks/hirarchy.py new file mode 100644 index 0000000..426bc54 --- /dev/null +++ b/kivyblocks/hirarchy.py @@ -0,0 +1,97 @@ +import traceback + +from kivy.clock import Clock +from kivy.factory import Factory +from kivy.properties import ListProperty, BooleanProperty, \ + StringProperty, DictProperty +from kivy.uix.treeview import TreeView, TreeViewNode, TreeViewLabel +from kivy.uix.boxlayout import BoxLayout + +from .threadcall import HttpClient +from .scrollpanel import ScrollPanel +from .clickable import SingleCheckBox +from .baseWidget import Text + +class TreeViewComplexNode(BoxLayout, TreeViewLabel): + otext = StringProperty(None) + checkbox = BooleanProperty(False) + icon = StringProperty(None) + def __init__(self, **kw): + super(TreeViewComplexNode, self).__init__(**kw) + self.orientation = 'horizontal' + if self.checkbox: + cb = SingleCheckBox(size_hint=(None,None)) + cb.bind(on_press=self.set_checked) + self.add_widget(cb) + if self.icon: + img = AsyncImage(source=self.icon) + self.add_widget(img) + txt = Text(otext=self.otext, i18n=True) + txt.texture_update() + txt.size = txt.texture_size + self.add_widget(txt) + + def set_checked(self, o): + if o.state(): + self.data['checked'] = True + else: + self.data['checked'] = False + +class Hirarchy(ScrollPanel): + url = StringProperty(None) + params = DictProperty(None) + method = StringProperty('get') + idField = StringProperty(None) + textField = StringProperty(None) + data = ListProperty(None) + checkbox = BooleanProperty(False) + icon = StringProperty(None) + def __init__(self, **kw): + self.tree = TreeView(hide_root=True) + self.tree.size_hint_y = None + self.tree.bind(on_node_expand=self.check_load_subnodes) + super(Hirarchy, self).__init__(inner=self.tree, **kw) + if self.url: + self.data = self.get_remote_data() + + def check_load_subnodes(self, treeview, node): + if node.is_loaded: + return + data = self.get_remote_data(node) + for d in data: + self.create_new_node(d, node) + node.is_loaded = True + + def create_new_node(self, data, node=None): + n = TreeViewComplexNode(otext=data[self.textField], + checkbox=self.checkbox, + icon=self.icon + ) + n.data = data + if self.checkbox: + cb = SingleCheckBox() + n.add_widget(cb, index=len(n.children)) + if node: + self.tree.add_node(n, node) + else: + self.tree.add_node(n) + + def get_remote_data(self, node=None): + hc = HttpClient() + params = self.params.copy() if self.params else {} + if node: + params['id'] = node.data[self.idField] + d = hc(self.url, method=self.method, params=params) + if isinstance(d, list): + return d + if isinstance(d, dict): + return d['rows'] + return None + + def on_data(self, o, d=None): + if not self.data: + return + for d in self.data: + self.create_new_node(d) + +Factory.register('Hirarchy', Hirarchy) diff --git a/kivyblocks/register.py b/kivyblocks/register.py index 9ab9e81..37e321d 100644 --- a/kivyblocks/register.py +++ b/kivyblocks/register.py @@ -39,6 +39,8 @@ from .scrollpanel import ScrollPanel from .udp_widget import UdpWidget from .paging import PageLoader from .dateinput import DateInput +from .block_test import BlockTest +from .hirarchy import Hirarchy r = Factory.register if kivy.platform in ['win','linux', 'macosx']: diff --git a/kivyblocks/toolbar.py b/kivyblocks/toolbar.py index bb87824..58fe69b 100644 --- a/kivyblocks/toolbar.py +++ b/kivyblocks/toolbar.py @@ -132,7 +132,7 @@ class Toolbar(ScrollPanel): } ) - print(w, 'children=', len(w.children)) + w.widget_id = t['name'] if t.get('deletable', False): x = ClickableImage(source=blockImage('delete.png'), size_hint=(None,None), @@ -144,7 +144,8 @@ class Toolbar(ScrollPanel): if w: self.add_widget(w) - self.w_dic[w] = t + self.w_dic[w] = t.copy() + self.w_dic[w]['widget'] = w w.select(False) w.bind(size=self.on_children_size) w.bind(on_press=self.tool_press) diff --git a/kivyblocks/tree.py b/kivyblocks/tree.py index b20bbf3..c185943 100644 --- a/kivyblocks/tree.py +++ b/kivyblocks/tree.py @@ -356,18 +356,18 @@ class Tree(WidgetCSS, ScrollWidget): pass def select_row(self, node): - self.unselect_row() - self.selected_node = node - node.selected() - if not self.select_leaf_only or not node.hasChildren_nodes: - self.dispatch('on_press', node) - if node.hasChildren_nodes: + if node.hasChildren_nodes and self.select_leaf_only: node.toggleChildren(node) node.trigger.on_press() if node.children_open and self.single_expand: for n in node.sibling(): if n.hasChildren_nodes and n.children_open: n.collapse() + return + self.unselect_row() + self.selected_node = node + node.selected() + self.dispatch('on_press', node) def unselect_row(self): if self.selected_node: