This commit is contained in:
yumoqing 2020-03-08 17:39:01 +08:00
parent 8657c9764f
commit bf6b9144ad
8 changed files with 230 additions and 101 deletions

View File

@ -1,9 +1,9 @@
import os
from kivy import logger
__version_info__ = (0.5.0)
from kivy.logger import logging
__version_info__ = "0.5.0"
__version__ = '0.5.0'
path = os.path.dirname(__file__)
fonts_path = os.path.join(path,"ttf/")
images_path = os.path.join(path,'imgs/')
logger.info("kivyblocks:kivblocks version:{}".format(__version__)
logging.info("kivyblocks:kivblocks version:{}".format(__version__))

View File

@ -55,7 +55,6 @@ from .widgetExt.inputext import FloatInput,IntegerInput, \
StrInput,SelectInput, BoolInput, AmountInput
from .widgetExt.messager import Messager
from .charts.bar import Bar
from .tree import Tree, TextTree
if platform == 'android':
from .widgetExt.phonebutton import PhoneButton

View File

@ -30,6 +30,7 @@ from .serverImageViewer import ServerImageViewer
from .vplayer import VPlayer
from .form import InputBox, Form, StrSearchForm
from .boxViewer import BoxViewer
from .tree import Tree, TextTree
def showError(e):
print('error',e)

View File

@ -1,3 +1,5 @@
from kivy.logger import logging
colors = {
'Red': {
'200': 'ef9a9a',
@ -341,45 +343,6 @@ light_colors = {
'Light': ['White', 'MainBackground', 'DialogBackground']
}
level_bg_colors = [
'50',
'100',
'200',
'300',
]
level_selected_bg_colors = [
'400',
'500',
'600',
'700'
]
def getColors(style,level):
i = level % len(level_bg_colors)
text_color = text_colors[style][ level_bg_colors[i]]
bg_color = colors[style][ level_bg_colors[i]]
return color
def getSelectedColors(style,level):
i = level % len(level_selected_bg_colors)
text_color = text_colors[style][ level_bg_colors[i]]
bg_color = colors[style][ level_bg_colors[i]]
return text_color, bg_color
error_color_id = '900',
info_color_id = '800'
def getErrorColor(style):
text_color = text_colors[style][ error_color_id ]
bg_color = colors[style][ error_color_id ]
return text_color, bg_color
def getInfoColor(style):
text_color = text_colors[style][ info_color_id ]
bg_color = colors[style][ info_color_id ]
return text_color, bg_color
text_colors = {
'Red': {
'50': '000000',
@ -674,3 +637,43 @@ text_colors = {
'900': 'ffffff',
},
}
level_bg_colors = [
'900',
'800',
'700',
'600',
]
level_selected_bg_colors = [
'500',
'400',
'300',
'200'
]
def getColors(style,level=0):
i = level % len(level_bg_colors)
logging.info('TEST : style=%s,level=%d', style, level)
text_color = text_colors[style][ level_bg_colors[i]]
bg_color = colors[style][ level_bg_colors[i]]
return text_color,bg_color
def getSelectedColors(style,level=0):
i = level % len(level_selected_bg_colors)
text_color = text_colors[style][ level_selected_bg_colors[i]]
bg_color = colors[style][ level_selected_bg_colors[i]]
return text_color, bg_color
error_color_id = '100',
info_color_id = '50'
def getErrorColors(style):
text_color = text_colors[style][ error_color_id ]
bg_color = colors[style][ error_color_id ]
return text_color, bg_color
def getInfoColors(style):
text_color = text_colors[style][ info_color_id ]
bg_color = colors[style][ info_color_id ]
return text_color, bg_color

View File

@ -9,7 +9,7 @@ class GPS:
pass
def on_status(self,**kw):
pass
def __del__(self):
gps.stop()

View File

@ -0,0 +1,39 @@
from kivy.graphics import Color, Rectangle
from kivy.logger import logging
from kivyblocks.colorcalc import toArrayColor
from appPublic.jsonConfig import getConfig
from .color_definitions import getColors, getSelectedColors
from .color_definitions import getInfoColors, getErrorColors
class StyleBehavior(object):
def __init__(self,level=0):
config = getConfig()
style = config.style
self.style_level = level
self.selected_flag = False
logging.info('Tree : style=%s,level=%d',style, level)
c1, c2 = getColors(style,level)
self.text_color, self.bg_color = toArrayColor(c1),toArrayColor(c2)
c1, c2 = getSelectedColors(style,level)
self.s_text_color,self.s_bg_color = toArrayColor(c1), toArrayColor(c2)
self.bind(size=self.setBGColor,pos=self.setBGColor)
def setBGColor(self,o=None,v=None):
c = self.bg_color
if self.selected_flag:
c = self.s_bg_color
logging.info('selected=%s,color=%s',str(self.selected_flag),str(c))
with self.canvas.before:
Color(*c)
Rectangle(pos=self.pos,size=self.size)
def selected(self):
self.selected_flag = True
self.setBGColor()
def unselected(self):
self.selected_flag = False
self.setBGColor()

View File

@ -1,60 +1,72 @@
from kivy.app import App
from kivy.graphics import Color, Triangle
from kivy.logger import logging
from kivy.graphics import Color, Rectangle, Triangle
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.button import ButtonBehavior
from kivyblocks.widgetExt import ScrollWidget
from kivyblocks.blocksapp import BlocksApp
from kivyblocks.utils import CSize
from baseWidget import PressableLabel
from appPublic.dictObject import DictObject
from .baseWidget import PressableLabel
from .stylebehavior import StyleBehavior
class NodeTrigger(ButtonBehavior, Widget):
def __init__(self, open_status=False,color=[1,0,0,1]):
siz = CSize(1)
super().__init__(size_hint=(None,None),size=[siz,siz]) #CSize(1))
class EmptyBox(Label):
def __init__(self,size_cnt=1):
self.size_cnt = size_cnt
siz=CSize(self.size_cnt)
super().__init__(text=' ',font_size=siz,
text_size=(siz,siz),
halign='center',
size_hint=[None,None],size=[siz,siz])
def onSize(self,o=None,v=None):
return
class NodeTrigger(ButtonBehavior, EmptyBox):
def __init__(self, size_cnt=1,open_status=False,color=[1,0,0,1]):
super().__init__(size_cnt=size_cnt)
self.open_status = open_status
self.line_color = color
self.register_event_type('on_change')
self.open_points = [0,self.height, self.width,self.height,self.width/2,0]
self.close_points = [0,self.height, 0,0, self.width,self.height/2]
self.countPoints()
self.showOpenStatus()
self.bind(size=self.on_size)
self.bind(size=self.onSize,pos=self.onSize)
def on_change(self,status):
print('new_status=',status)
def countPoints(self):
self.open_points = [0,self.height,
self.width,self.height,
self.width/2,0]
self.close_points = [0,self.height,
0,0, self.width,
self.height/2]
def pointsShift(self,points):
x = [ p + self.pos[0] if i % 2 == 0 else p + self.pos[1] \
for i,p in enumerate(points) ]
return x
def on_size(self,o,v):
self.open_points = [0,self.height, self.width,self.height,self.width/2,0]
self.close_points = [0,self.height, 0,0, self.width,self.height/2]
def onSize(self,o=None,v=None):
self.countPoints()
self.showOpenStatus()
def on_press(self):
self.open_status = False if self.open_status else True
self.showOpenStatus()
self.dispatch('on_change',self.open_status)
def showOpenStatus(self):
points = self.close_points
if self.open_status:
points = self.open_points
self.canvas.clear()
points = self.pointsShift(points)
with self.canvas:
Color(*self.line_color)
Triangle(points=points)
class EmptyBox(Widget):
def __init__(self):
siz=CSize(1)
super().__init__(size_hint=[None,None],size=[siz,siz])
# print('pos=',self.pos,'size=',self.size)
class TreeNode(BoxLayout):
def __init__(self,tree:Tree=None,
parentNode:TreeNode=None,
data:dict):
def __init__(self,data,tree=None,
parentNode=None,
):
"""
base TreeNode
data:{
@ -74,17 +86,26 @@ class TreeNode(BoxLayout):
self.hasChildren_nodes = True if not n is None else False
self.children_nodes = n
self.children_loaded = False
self.hasChildren = data.get('hasChildren')
if hasChildren_nodes:
self.hasChildren_nodes = data.get('children')
if self.hasChildren_nodes:
self.trigger = NodeTrigger()
self.trigger.bind(on_change=self.toggleChildren)
self.trigger.bind(on_press=self.toggleChildren)
self.buildChildrenContainer()
else:
self.trigger = EmptyBox()
self.add_widget(self.node_box)
self.node_box.add_widget(self.trigger)
self.buildContent()
self.add_widget(self.node_box)
self.addContent()
self.setSize()
def setSize(self):
if self.children_open:
self.height = self.node_box.height + self.node_box1.height
else:
self.height = self.node_box.height
self.width = self.trigger.width + \
max(self.node_box.width,self.node_box1.width)
def buildChildrenContainer(self):
self.node_box1.add_widget(EmptyBox())
self.children_box = BoxLayout(orientation='vertical')
@ -105,43 +126,67 @@ class TreeNode(BoxLayout):
self.buildContent()
self.node_box.add_widget(self.content)
self.node_box.height = self.content.height + CSize(1)
self.node_box.width = self.trigger.width + self.content.width
self.node_box.width = self.trigger.width + \
self.content.width + CSize(1)
logging.info('Tree : content=(%d,%d),box=(%d,%d)', \
self.content.width,self.content.height,
self.node_box.width,self.node_box.height)
def buildChildren(self):
if self.data.children is None:
logging.info('Tree : is a leaf node')
return
if self.data.children == []:
self.treeObj.getUrlData(self.addChildren,self.data)
return
if len(self.subNodes) == 0:
logging.info('Tree : add subnodes')
self.addChildren(self.data.children)
else:
logging.info('Tree : not need add subnodes')
def childrenSizeChange(self,tn,v):
h = 0
w = 0
for n in self.subNodes:
h += n.height
w = max(w,n.width)
self.children_box.height = h
self.children_box.width = w
self.node_box1.height = self.children_box.height
self.node_box1.width = self.trigger.width + self.children_box.width
self.setSize()
def addChildren(self,children):
self.data.children = children
self.children_box.height = 0
self.children_box.width = 0
for c in children:
options = {}
options['tree'] = self.treeObj
options['parentNode'] = self
options['data'] = c
tn = self.teeeObj.NodeKlass(**options)
tn = self.treeObj.NodeKlass(**options)
tn.bind(size=self.childrenSizeChange)
self.subNodes.append(tn)
self.children_box.add_widget(tn)
self.children_box.height += tn.height
self.children_box.width = max(self.children_box.width,tn.width)
self.node_box1.height = self.children_box.height
self.node_box1.width = self.trigger.width + self.children_box.width
def toggleChildren(self,o,v):
if v:
def toggleChildren(self,o):
self.treeObj.unselected()
self.children_open = True if not self.children_open else False
if self.children_open:
self.buildChildren()
self.add_widget(self.node_box1)
self.children_open = True
self.height = self.node_box.height + self.node_box1.height
else:
self.remove_widget(self.node_box1)
self.height = self.node_box.height
self.children_open = False
self.setSize()
def on_size(self,o,v):
print('************treenode on_size', o, v)
self.node_box1.height = self.children_box.height
"""
tree options
{
@ -156,16 +201,31 @@ tree options
"data" # array of {children:{},...}
}
"""
class Tree(ScrollWidget):
class Tree(StyleBehavior,ScrollWidget):
def __init__(self,**options):
super().__init__() #orientation="vertical")
ScrollWidget.__init__(self)
level = options.get('level',0)
StyleBehavior.__init__(self,level=level)
self.options = DictObject(**options)
self.nodes = []
self.initflag = False
self.selected_node = None
self.bind(size=self.onSize,pos=self.onSize)
def select_row(self, node):
self.unselect_row()
self.selected_node = node
node.selected()
def unselect_row(self):
if self.selected_node:
logging.info('selected node unselected')
self.selected_node.unselected()
self.selected_node = None
def onSize(self,o,v=None):
if not self.initflag:
self.initflag = True
self.buildTree(self)
for n in self.nodes:
n.setMinWidth(self.width)
@ -190,8 +250,10 @@ class Tree(ScrollWidget):
if self.options.url:
return self.getUrlData(self.dataLoaded,kv)
data = self.options.data
logging.info("Tree : buildTree,data=%s",data)
self.dataLoaded(data)
def dataLoaded(self,d):
self.data = d
self.addNodes()
@ -201,39 +263,57 @@ class Tree(ScrollWidget):
options = {}
options['tree'] = self
options['parentNode'] = None
options['data'] = DictObject(c)
self.nodes.append(self.NodeKlass(**options))
for w in self.nodes:
options['data'] = DictObject(**c)
w = self.NodeKlass(**options)
self.nodes.append(w)
self.add_widget(w)
logging.info('Tree : node=%s',type(w))
class TextContent(StyleBehavior, PressableLabel):
def __init__(self,level=0,**options):
PressableLabel.__init__(self,**options)
StyleBehavior.__init__(self,level=level)
class TextTreeNode(TreeNode):
def buildContent(self):
txt = self.data.get(self.treeObj.options.textField,
self.data.get(self.treeObj.options.idField,'defaulttext'))
self.content = PressableLabel(text=txt,
self.content = TextContent(level=self.treeObj.style_level,
text=txt,
size_hint=(None,None),
font_size=CSize(1),
text_size=CSize(len(txt),1),
text_size=CSize(len(txt)-1,1),
halign='left',
height=CSize(2),width=CSize(len(txt)))
height=CSize(2),
width=CSize(len(txt)))
self.content.text_color = [0,0,0,1] #self.treeObj.text_color
self.content.bind(on_press=self.onPress)
return
def onPress(self,o,v=None):
if self.hasChildren_nodes:
v = True if not self.children_open else False
self.toggleChildren(self)
self.trigger.on_press()
return
logging.info('select the leaf node')
self.treeObj.select_row(self)
def selected(self):
pass
logging.info('content selected ........')
self.content.selected()
def unselected(self):
pass
logging.info('content unselected ........')
self.content.unselected()
class TextTree(Tree):
def __init__(self,**options):
self.NodeKlass = TextTReeNode
self.NodeKlass = TextTreeNode
super().__init__(**options)
self.register_event_type('on_press')
def onPress(self,o,v=None):
if self.selectNode:
self.selectNode.unselected()

View File

@ -16,7 +16,14 @@ email = "yumoqing@icloud.com"
packages=find_packages()
package_data = {
"kivyblocks":['imgs/*.png', 'imgs/*.gif','imgs/*.jpg','ttf/*.ttf', 'ui/*.uidesc' ],
"kivyblocks":[
'imgs/*.png',
'imgs/*.atlas',
'imgs/*.gif',
'imgs/*.jpg',
'ttf/*.ttf',
'ui/*.uidesc'
],
}
setup(