bugfix
This commit is contained in:
parent
211fee42ec
commit
2490b46b46
@ -3,6 +3,7 @@ from kivy.utils import platform
|
|||||||
from kivy.uix.button import Button, ButtonBehavior
|
from kivy.uix.button import Button, ButtonBehavior
|
||||||
from kivy.uix.accordion import Accordion,AccordionItem
|
from kivy.uix.accordion import Accordion,AccordionItem
|
||||||
from kivy.uix.label import Label
|
from kivy.uix.label import Label
|
||||||
|
from kivy.event import EventDispatcher
|
||||||
|
|
||||||
from kivy.uix.actionbar import ActionBar,ActionView,ActionPrevious,ActionItem,ActionButton
|
from kivy.uix.actionbar import ActionBar,ActionView,ActionPrevious,ActionItem,ActionButton
|
||||||
from kivy.uix.actionbar import ActionToggleButton, ActionCheck,ActionSeparator,ActionGroup
|
from kivy.uix.actionbar import ActionToggleButton, ActionCheck,ActionSeparator,ActionGroup
|
||||||
@ -79,3 +80,38 @@ class PressableLabel(ButtonBehavior, Text):
|
|||||||
def on_press(self):
|
def on_press(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class HTTPDataHandler(EventDispatcher):
|
||||||
|
def __init__(self, url,method='GET',params={},headers={}):
|
||||||
|
EventDispatcher.__init__()
|
||||||
|
self.opts = opts
|
||||||
|
self.url = url
|
||||||
|
self.method = method
|
||||||
|
self.params = params
|
||||||
|
self.headers = headers
|
||||||
|
self.hc = App.get_running_app().hc
|
||||||
|
self.register_event_type('on_sucess')
|
||||||
|
self.register_event_type('on_error')
|
||||||
|
|
||||||
|
def on_success(self,o,v):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_error(self,o,e):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onSuccess(self,o,v):
|
||||||
|
self.dispatch('on_sucess',v)
|
||||||
|
|
||||||
|
def onError(self,o,e):
|
||||||
|
self.dispatch('on_error',e)
|
||||||
|
|
||||||
|
def handle(self,params={},headers={}):
|
||||||
|
p = self.params
|
||||||
|
p.update(params)
|
||||||
|
h = self.headers
|
||||||
|
h.update(headers)
|
||||||
|
self.hc(self.url,method=self.method,
|
||||||
|
params=p,
|
||||||
|
headers=h,
|
||||||
|
callback=self.onSuccess,
|
||||||
|
errback=self.onError)
|
||||||
|
|
||||||
|
@ -5,23 +5,23 @@ from kivy.properties import ListProperty
|
|||||||
_logcnt = 0
|
_logcnt = 0
|
||||||
class BGColorBehavior(object):
|
class BGColorBehavior(object):
|
||||||
bgcolor = ListProperty([])
|
bgcolor = ListProperty([])
|
||||||
def __init__(self, bgcolor=[1,0,0,1],**kwargs):
|
def __init__(self, bgcolor=[0,0,0,1],**kwargs):
|
||||||
self.bgcolor = bgcolor
|
self.bgcolor = bgcolor
|
||||||
self.bind(size=self.on_bgcolor,pos=self.on_bgcolor)
|
self.bind(size=self.onSize_bgcolor_behavior,
|
||||||
|
pos=self.onSize_bgcolor_behavior)
|
||||||
|
self.on_bgcolor()
|
||||||
|
|
||||||
|
def onSize_bgcolor_behavior(self,o,v=None):
|
||||||
|
if not hasattr(self,'rect'):
|
||||||
|
self.on_bgcolor()
|
||||||
|
else:
|
||||||
|
self.rect.pos = o.pos
|
||||||
|
self.rect.size = o.size
|
||||||
|
|
||||||
def on_bgcolor(self,o=None,v=None):
|
def on_bgcolor(self,o=None,v=None):
|
||||||
global _logcnt
|
|
||||||
Logger.info('bgcolorBehavior: on_bgcolor(),o=%s,v=%s,logcnt=%d',\
|
|
||||||
o.text if hasattr(o,'text') else o,v,_logcnt)
|
|
||||||
_logcnt += 1
|
|
||||||
x = abs(self.size[0] - 100.0)
|
|
||||||
y = abs(self.size[1] - 100.0)
|
|
||||||
if self.size[0] < 0.0001 or self.size[1] < 0.0001:
|
|
||||||
return
|
|
||||||
if x < 0.0001 and y < 0.0001:
|
|
||||||
return
|
|
||||||
if self.canvas:
|
if self.canvas:
|
||||||
with self.canvas.before:
|
with self.canvas.before:
|
||||||
Color(*self.bgcolor)
|
Color(*self.bgcolor)
|
||||||
Rectangle(pos=self.pos, size=self.size)
|
self.rect = Rectangle(pos=self.pos,
|
||||||
|
size=self.size)
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
import traceback
|
||||||
|
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
from kivy.logger import logging
|
from kivy.core.window import Window
|
||||||
|
from kivy.logger import Logger
|
||||||
from kivy.graphics import Color, Rectangle, Triangle
|
from kivy.graphics import Color, Rectangle, Triangle
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
from kivy.uix.label import Label
|
from kivy.uix.label import Label
|
||||||
@ -8,9 +11,11 @@ from kivy.uix.button import ButtonBehavior
|
|||||||
from kivyblocks.widgetExt import ScrollWidget
|
from kivyblocks.widgetExt import ScrollWidget
|
||||||
from kivyblocks.utils import CSize
|
from kivyblocks.utils import CSize
|
||||||
from appPublic.dictObject import DictObject
|
from appPublic.dictObject import DictObject
|
||||||
|
from appPublic.jsonConfig import getConfig
|
||||||
from .baseWidget import PressableLabel
|
from .baseWidget import PressableLabel
|
||||||
from .color_definitions import getColors
|
from .color_definitions import getColors
|
||||||
from .bgcolorbehavior import BGColorBehavior
|
from .bgcolorbehavior import BGColorBehavior
|
||||||
|
from .utils import alert,absurl
|
||||||
|
|
||||||
class EmptyBox(Label):
|
class EmptyBox(Label):
|
||||||
def __init__(self,size_cnt=1):
|
def __init__(self,size_cnt=1):
|
||||||
@ -80,8 +85,11 @@ class TreeNode(BoxLayout):
|
|||||||
self.data = data
|
self.data = data
|
||||||
self.content = None
|
self.content = None
|
||||||
self.children_open = False
|
self.children_open = False
|
||||||
self.subNodes = []
|
self.nodes = []
|
||||||
self.node_box = BoxLayout(orientation='horizontal',size_hint_y=None)
|
self.initChildren = False
|
||||||
|
self.node_box = BoxLayout(orientation='horizontal',
|
||||||
|
spacing=CSize(0.5),
|
||||||
|
size_hint_y=None)
|
||||||
self.node_box1 = BoxLayout(orientation='horizontal')
|
self.node_box1 = BoxLayout(orientation='horizontal')
|
||||||
n = data.get('children')
|
n = data.get('children')
|
||||||
self.hasChildren_nodes = True if not n is None else False
|
self.hasChildren_nodes = True if not n is None else False
|
||||||
@ -122,7 +130,7 @@ class TreeNode(BoxLayout):
|
|||||||
self.node_box.width = width
|
self.node_box.width = width
|
||||||
if self.node_box1.width < width:
|
if self.node_box1.width < width:
|
||||||
self.node_box1.width = width
|
self.node_box1.width = width
|
||||||
for n in self.subNodes:
|
for n in self.nodes:
|
||||||
n.setMinWidth(width)
|
n.setMinWidth(width)
|
||||||
|
|
||||||
def buildContent(self):
|
def buildContent(self):
|
||||||
@ -134,28 +142,32 @@ class TreeNode(BoxLayout):
|
|||||||
self.node_box.height = self.content.height
|
self.node_box.height = self.content.height
|
||||||
self.node_box.width = self.trigger.width + \
|
self.node_box.width = self.trigger.width + \
|
||||||
self.content.width
|
self.content.width
|
||||||
logging.info('Tree : content=(%d,%d),box=(%d,%d)', \
|
Logger.info('Tree : content=(%d,%d),box=(%d,%d)', \
|
||||||
self.content.width,self.content.height,
|
self.content.width,self.content.height,
|
||||||
self.node_box.width,self.node_box.height)
|
self.node_box.width,self.node_box.height)
|
||||||
|
|
||||||
def buildChildren(self):
|
def buildChildren(self):
|
||||||
|
if self.initChildren == True:
|
||||||
|
return
|
||||||
|
|
||||||
if self.data.children is None:
|
if self.data.children is None:
|
||||||
logging.info('Tree : is a leaf node')
|
Logger.info('Tree : is a leaf node')
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.data.children == []:
|
if self.data.children == []:
|
||||||
self.treeObj.getUrlData(self.addChildren,self.data)
|
self.treeObj.getUrlData(self.addChildren,self.data)
|
||||||
return
|
return
|
||||||
if len(self.subNodes) == 0:
|
if len(self.nodes) == 0:
|
||||||
logging.info('Tree : add subnodes')
|
Logger.info('Tree : add subnodes')
|
||||||
self.addChildren(self.data.children)
|
self.addChildren(self.data.children)
|
||||||
else:
|
else:
|
||||||
logging.info('Tree : not need add subnodes')
|
Logger.info('Tree : not need add subnodes')
|
||||||
|
self.initChildren = True
|
||||||
|
|
||||||
def childrenSizeChange(self,tn,v):
|
def childrenSizeChange(self,tn,v):
|
||||||
h = 0
|
h = 0
|
||||||
w = 0
|
w = 0
|
||||||
for n in self.subNodes:
|
for n in self.nodes:
|
||||||
h += n.height
|
h += n.height
|
||||||
w = max(w,n.width)
|
w = max(w,n.width)
|
||||||
|
|
||||||
@ -176,13 +188,72 @@ class TreeNode(BoxLayout):
|
|||||||
options['data'] = c
|
options['data'] = c
|
||||||
tn = self.treeObj.NodeKlass(**options)
|
tn = self.treeObj.NodeKlass(**options)
|
||||||
tn.bind(size=self.childrenSizeChange)
|
tn.bind(size=self.childrenSizeChange)
|
||||||
self.subNodes.append(tn)
|
self.nodes.append(tn)
|
||||||
self.children_box.add_widget(tn)
|
self.children_box.add_widget(tn)
|
||||||
self.children_box.height += tn.height
|
self.children_box.height += tn.height
|
||||||
self.children_box.width = max(self.children_box.width,tn.width)
|
self.children_box.width = max(self.children_box.width,tn.width)
|
||||||
self.node_box1.height = self.children_box.height
|
self.node_box1.height = self.children_box.height
|
||||||
self.node_box1.width = self.trigger.width + self.children_box.width
|
self.node_box1.width = self.trigger.width + self.children_box.width
|
||||||
|
|
||||||
|
def addNodeByData(self,data):
|
||||||
|
options = {}
|
||||||
|
options['tree'] = self.treeObj
|
||||||
|
options['parentNode'] = self
|
||||||
|
if isinstance(data,dict):
|
||||||
|
options['data'] = DictObject(**data)
|
||||||
|
else:
|
||||||
|
options['data'] = data
|
||||||
|
w = self.treeObj.NodeKlass(**options)
|
||||||
|
self.nodes.append(w)
|
||||||
|
self.children_box.add_widget(w)
|
||||||
|
self.childrenSizeChange(None,None)
|
||||||
|
|
||||||
|
def addNode(self,node):
|
||||||
|
node.parentNode = self
|
||||||
|
self.nodes.append(node)
|
||||||
|
self.children_box.add_widget(node)
|
||||||
|
self.childrenSizeChange(None,None)
|
||||||
|
|
||||||
|
def deleteNode(self,node):
|
||||||
|
self.children_box.remove_widget(node)
|
||||||
|
self.nodes = [ i for i in self.nodes if i != node ]
|
||||||
|
self.childrenSizeChange(None,None)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
parentNode = self.parentNode if self.parentNode else self.treeObj
|
||||||
|
parentNode.deleteNode(self)
|
||||||
|
|
||||||
|
def expand(self):
|
||||||
|
if self.children_open:
|
||||||
|
return
|
||||||
|
self.toggleChildren(None)
|
||||||
|
|
||||||
|
def collapse(self):
|
||||||
|
if not self.children_open:
|
||||||
|
return
|
||||||
|
self.toggleChildren(None)
|
||||||
|
|
||||||
|
def expandall(self):
|
||||||
|
if not self.children_open:
|
||||||
|
self.toggleChildren(None)
|
||||||
|
for n in self.nodes:
|
||||||
|
n.expandall()
|
||||||
|
|
||||||
|
def collapseall(self):
|
||||||
|
if self.children_open:
|
||||||
|
self.toggleChildren(None)
|
||||||
|
for n in self.nodes:
|
||||||
|
n.collapseall(None)
|
||||||
|
|
||||||
|
def moveNode(self,node,newParent=None):
|
||||||
|
old_parent = node.parent
|
||||||
|
if old_parent == None:
|
||||||
|
old_parent = node.treeObj
|
||||||
|
old_parent.deleteNode(node)
|
||||||
|
if newParent == None:
|
||||||
|
newParent = node.treeObj
|
||||||
|
newParent.addNode(node)
|
||||||
|
|
||||||
def toggleChildren(self,o):
|
def toggleChildren(self,o):
|
||||||
self.treeObj.unselect_row()
|
self.treeObj.unselect_row()
|
||||||
self.children_open = True if not self.children_open else False
|
self.children_open = True if not self.children_open else False
|
||||||
@ -195,16 +266,14 @@ class TreeNode(BoxLayout):
|
|||||||
# when a widget remove from its parent, the get_parent_window()
|
# when a widget remove from its parent, the get_parent_window()
|
||||||
# will return a None
|
# will return a None
|
||||||
# w1 = self.children_box.get_parent_window()
|
# w1 = self.children_box.get_parent_window()
|
||||||
# logging.info('Tree :get_parent_window() return=%s',str(type(w1)))
|
# Logger.info('Tree :get_parent_window() return=%s',str(type(w1)))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
tree options
|
tree options
|
||||||
{
|
{
|
||||||
"url":
|
"url":
|
||||||
"params",
|
"params",
|
||||||
"bg_color",
|
|
||||||
"color_level",
|
"color_level",
|
||||||
"color",
|
|
||||||
"checkbox",
|
"checkbox",
|
||||||
"multplecheck",
|
"multplecheck",
|
||||||
"idField",
|
"idField",
|
||||||
@ -230,14 +299,14 @@ class Tree(BGColorBehavior, ScrollWidget):
|
|||||||
|
|
||||||
def unselect_row(self):
|
def unselect_row(self):
|
||||||
if self.selected_node:
|
if self.selected_node:
|
||||||
logging.info('selected node unselected')
|
Logger.info('selected node unselected')
|
||||||
self.selected_node.unselected()
|
self.selected_node.unselected()
|
||||||
self.selected_node = None
|
self.selected_node = None
|
||||||
|
|
||||||
def onSize(self,o,v=None):
|
def onSize(self,o,v=None):
|
||||||
if not self.initflag:
|
if not self.initflag:
|
||||||
self.initflag = True
|
self.initflag = True
|
||||||
self.buildTree(self)
|
self.buildTree()
|
||||||
for n in self.nodes:
|
for n in self.nodes:
|
||||||
n.setMinWidth(self.width)
|
n.setMinWidth(self.width)
|
||||||
|
|
||||||
@ -246,13 +315,23 @@ class Tree(BGColorBehavior, ScrollWidget):
|
|||||||
|
|
||||||
def getUrlData(self,callback,kv=None):
|
def getUrlData(self,callback,kv=None):
|
||||||
hc = App.get_running_app().hc
|
hc = App.get_running_app().hc
|
||||||
params = self.options.get(params,{}).copy()
|
params = self.options.get('params',{}).copy()
|
||||||
if not data is None:
|
if not kv is None:
|
||||||
for k,v in kv:
|
for k,v in kv.items():
|
||||||
if k in params.keys():
|
if k in params.keys():
|
||||||
params[k] = v
|
params[k] = v
|
||||||
params['id'] = kv[self.options.idField]
|
params['id'] = kv[self.options.idField]
|
||||||
hc.get(self.url,params=params,callback=callback)
|
config = getConfig()
|
||||||
|
url = absurl(self.options.url,None)
|
||||||
|
Logger.info('Tree: getUrlData(),url=%s',url)
|
||||||
|
hc.get(url,params=params,
|
||||||
|
callback=callback,
|
||||||
|
errback=self.showError)
|
||||||
|
|
||||||
|
def showError(self,o,e):
|
||||||
|
traceback.print_exc()
|
||||||
|
Logger.info('Tree: showError() o=%s,e=%s',o,e)
|
||||||
|
alert(e,title='error')
|
||||||
|
|
||||||
def buildTree(self,kv=None):
|
def buildTree(self,kv=None):
|
||||||
if not hasattr(self,'NodeKlass'):
|
if not hasattr(self,'NodeKlass'):
|
||||||
@ -260,16 +339,18 @@ class Tree(BGColorBehavior, ScrollWidget):
|
|||||||
|
|
||||||
if self.options.url:
|
if self.options.url:
|
||||||
return self.getUrlData(self.dataLoaded,kv)
|
return self.getUrlData(self.dataLoaded,kv)
|
||||||
data = self.options.data
|
data = self.options.data or []
|
||||||
logging.info("Tree : buildTree,data=%s",data)
|
Logger.info("Tree : buildTree,data=%s",data)
|
||||||
self.dataLoaded(data)
|
self.dataLoaded(None,data)
|
||||||
self.color, self.bgcolor = getColors(self.color_level)
|
self.color, self.bgcolor = getColors(self.color_level)
|
||||||
|
|
||||||
def dataLoaded(self,d):
|
def dataLoaded(self,o,d):
|
||||||
|
Logger.info("Tree: dataLoaded,d=%s",d)
|
||||||
self.data = d
|
self.data = d
|
||||||
self.addNodes()
|
self.addNodes()
|
||||||
|
|
||||||
def addNodes(self):
|
def addNodes(self):
|
||||||
|
Logger.info("Tree: addNodes()")
|
||||||
for c in self.data:
|
for c in self.data:
|
||||||
options = {}
|
options = {}
|
||||||
options['tree'] = self
|
options['tree'] = self
|
||||||
@ -278,7 +359,22 @@ class Tree(BGColorBehavior, ScrollWidget):
|
|||||||
w = self.NodeKlass(**options)
|
w = self.NodeKlass(**options)
|
||||||
self.nodes.append(w)
|
self.nodes.append(w)
|
||||||
self.add_widget(w)
|
self.add_widget(w)
|
||||||
logging.info('Tree : node=%s',type(w))
|
Logger.info('Tree : node=%s',type(w))
|
||||||
|
|
||||||
|
def addNode(self,data,parentNode=None):
|
||||||
|
options = {}
|
||||||
|
options['tree'] = self
|
||||||
|
options['parentNode'] = None
|
||||||
|
options['data'] = DictObject(**data)
|
||||||
|
w = self.NodeKlass(**options)
|
||||||
|
self.nodes.append(w)
|
||||||
|
self.add_widget(w)
|
||||||
|
|
||||||
|
def deleteNode(self,node):
|
||||||
|
if self.selected_node == node:
|
||||||
|
self.selected_node = None
|
||||||
|
self.remove_widget(node)
|
||||||
|
self.nodes = [ i for i in self.nodes if i != node ]
|
||||||
|
|
||||||
class TextContent(PressableLabel):
|
class TextContent(PressableLabel):
|
||||||
def __init__(self,level=0,**options):
|
def __init__(self,level=0,**options):
|
||||||
@ -309,22 +405,21 @@ class TextTreeNode(TreeNode):
|
|||||||
|
|
||||||
def onPress(self,o,v=None):
|
def onPress(self,o,v=None):
|
||||||
if self.hasChildren_nodes:
|
if self.hasChildren_nodes:
|
||||||
v = True if not self.children_open else False
|
|
||||||
self.toggleChildren(self)
|
self.toggleChildren(self)
|
||||||
self.trigger.on_press()
|
self.trigger.on_press()
|
||||||
return
|
return
|
||||||
logging.info('select the leaf node')
|
Logger.info('select the leaf node')
|
||||||
self.treeObj.select_row(self)
|
self.treeObj.select_row(self)
|
||||||
|
|
||||||
def selected(self):
|
def selected(self):
|
||||||
logging.info('content selected ........')
|
Logger.info('content selected ........')
|
||||||
color, bgcolor = getColors(self.treeObj.color_level,
|
color, bgcolor = getColors(self.treeObj.color_level,
|
||||||
selected=True)
|
selected=True)
|
||||||
self.content.bgcolor = bgcolor
|
self.content.bgcolor = bgcolor
|
||||||
self.content.color = color
|
self.content.color = color
|
||||||
|
|
||||||
def unselected(self):
|
def unselected(self):
|
||||||
logging.info('content unselected ........')
|
Logger.info('content unselected ........')
|
||||||
color, bgcolor = getColors(self.treeObj.color_level,
|
color, bgcolor = getColors(self.treeObj.color_level,
|
||||||
selected=False)
|
selected=False)
|
||||||
self.content.bgcolor = bgcolor
|
self.content.bgcolor = bgcolor
|
||||||
@ -336,13 +431,45 @@ class TextTree(Tree):
|
|||||||
super().__init__(**options)
|
super().__init__(**options)
|
||||||
self.register_event_type('on_press')
|
self.register_event_type('on_press')
|
||||||
|
|
||||||
|
def select_row(self, node):
|
||||||
|
super().select_row(node)
|
||||||
|
self.dispatch('on_press',node.data)
|
||||||
|
|
||||||
def onPress(self,o,v=None):
|
def on_press(self,o,v=None):
|
||||||
if self.selectNode:
|
|
||||||
self.selectNode.unselected()
|
|
||||||
self.selectNode = o
|
|
||||||
o.selected()
|
|
||||||
self.dispatch(on_press,o,o.data)
|
|
||||||
|
|
||||||
def on_press(self,o,v):
|
|
||||||
print('TextTree():on_press(),o=',o,'v=',v)
|
print('TextTree():on_press(),o=',o,'v=',v)
|
||||||
|
|
||||||
|
class PopupMenu(BoxLayout):
|
||||||
|
def __init__(self,target,menudesc,**opts):
|
||||||
|
self.target = target
|
||||||
|
self.menudesc = menudesc
|
||||||
|
BoxLayout.__init__(self, size_hint=(0.5,0.5))
|
||||||
|
self.menu_tree = TextTree(**menudesc)
|
||||||
|
self.add_widget(self.menu_tree)
|
||||||
|
self.menu_tree.bind(on_press=self.onMenuItemTouch)
|
||||||
|
self.register_event_type('on_press')
|
||||||
|
|
||||||
|
def on_press(self,o,v=None):
|
||||||
|
Logger.info('PopupMenu: on_press fired')
|
||||||
|
|
||||||
|
def onMenuItemTouch(self,o,d=None,v=None):
|
||||||
|
Logger.info('MenuTree: on_press fired,o=%s,d=%s,v=%s',o,d,v)
|
||||||
|
data = {
|
||||||
|
'target':self.target,
|
||||||
|
'menudata':d
|
||||||
|
}
|
||||||
|
self.dispatch('on_press',data)
|
||||||
|
self.dismiss()
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
Window.add_widget(self)
|
||||||
|
self.center = Window.center
|
||||||
|
|
||||||
|
def dismiss(self):
|
||||||
|
Window.remove_widget(self)
|
||||||
|
|
||||||
|
def on_touch_down(self,touch):
|
||||||
|
if not self.collide_point(*touch.pos):
|
||||||
|
self.dismiss()
|
||||||
|
return False
|
||||||
|
super().on_touch_down(touch)
|
||||||
|
return True
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
|
from kivy.logger import Logger
|
||||||
from kivy.uix.image import Image
|
from kivy.uix.image import Image
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
from kivy.uix.textinput import TextInput
|
from kivy.uix.textinput import TextInput
|
||||||
@ -25,14 +26,14 @@ class BoolInput(Switch):
|
|||||||
a.active = kw.get('value')
|
a.active = kw.get('value')
|
||||||
|
|
||||||
super().__init__(**a)
|
super().__init__(**a)
|
||||||
|
self.register_event_type('on_changed')
|
||||||
self.bind(active=on_active)
|
self.bind(active=on_active)
|
||||||
self.bind(change=self.on_change)
|
|
||||||
|
|
||||||
def on_change(self,t,v):
|
def on_changed(self,v=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_active(self,t,v):
|
def on_active(self,t,v):
|
||||||
change = True
|
self.dispatch('on_changed',v)
|
||||||
|
|
||||||
def getValue(self):
|
def getValue(self):
|
||||||
return self.active
|
return self.active
|
||||||
@ -41,43 +42,53 @@ class BoolInput(Switch):
|
|||||||
self.active = v
|
self.active = v
|
||||||
|
|
||||||
class StrInput(TextInput):
|
class StrInput(TextInput):
|
||||||
change = BooleanProperty(False)
|
|
||||||
def __init__(self,**kv):
|
def __init__(self,**kv):
|
||||||
if kv is None:
|
if kv is None:
|
||||||
kv = {}
|
kv = {}
|
||||||
a = {
|
a = {
|
||||||
# "allow_copy":True,
|
"allow_copy":True,
|
||||||
"font_size":CSize(1),
|
"font_size":1,
|
||||||
"multiline":False,
|
"multiline":False,
|
||||||
"halign":"left",
|
"halign":"left",
|
||||||
"hint_text":"",
|
"hint_text":"",
|
||||||
"size_hint_y":None,
|
"size_hint_y":None,
|
||||||
"height":CSize(2)
|
"width":20,
|
||||||
|
"height":2.5
|
||||||
}
|
}
|
||||||
if kv.get('tip'):
|
if kv.get('tip'):
|
||||||
a['hint_text'] = kv['tip']
|
a['hint_text'] = kv['tip']
|
||||||
a.update(kv)
|
a.update(kv)
|
||||||
a['multiline'] = False
|
a['width'] = CSize(kv.get('width',20))
|
||||||
super(StrInput,self).__init__(**a)
|
a['height'] = CSize(kv.get('height',2.5))
|
||||||
self.bind(focus=self.on_focus)
|
a['font_size'] = CSize(kv.get('font_size',1))
|
||||||
self.bind(text=self.on_text)
|
|
||||||
self.bind(change=self.on_change)
|
|
||||||
|
|
||||||
def on_change(self,t,v):
|
super(StrInput,self).__init__(**a)
|
||||||
if v:
|
self.old_value = None
|
||||||
|
self.register_event_type('on_changed')
|
||||||
|
self.bind(focus=self.on_focus)
|
||||||
|
self.bind(on_text_validate=self.checkChange)
|
||||||
|
|
||||||
|
def on_changed(self,v=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_text(self,t,v):
|
def checkChange(self,o,v=None):
|
||||||
self.change = True
|
v = self.getValue()
|
||||||
|
if v != self.old_value:
|
||||||
|
self.dispatch('on_changed',v)
|
||||||
|
|
||||||
def on_focus(self,t,v):
|
def on_focus(self,t,v):
|
||||||
self.change = False
|
if v:
|
||||||
|
self.old_value = self.getValue()
|
||||||
|
else:
|
||||||
|
self.checkChange(None)
|
||||||
|
|
||||||
def getValue(self):
|
def getValue(self):
|
||||||
return self.text
|
return self.text
|
||||||
|
|
||||||
def setValue(self,v):
|
def setValue(self,v):
|
||||||
self.text = v
|
if v is None:
|
||||||
|
v = ''
|
||||||
|
self.text = str(v)
|
||||||
|
|
||||||
class Password(StrInput):
|
class Password(StrInput):
|
||||||
def __init__(self, **kw):
|
def __init__(self, **kw):
|
||||||
@ -97,6 +108,10 @@ class IntegerInput(StrInput):
|
|||||||
s = re.sub(pat, '', substring)
|
s = re.sub(pat, '', substring)
|
||||||
return StrInput.insert_text(self,s, from_undo=from_undo)
|
return StrInput.insert_text(self,s, from_undo=from_undo)
|
||||||
|
|
||||||
|
def on_focus(self,t,v):
|
||||||
|
super().on_focus(t,v)
|
||||||
|
self.cursor = (0,len(self.text))
|
||||||
|
|
||||||
class FloatInput(IntegerInput):
|
class FloatInput(IntegerInput):
|
||||||
pat = re.compile('[^0-9]')
|
pat = re.compile('[^0-9]')
|
||||||
def filter(self,substring):
|
def filter(self,substring):
|
||||||
@ -167,17 +182,16 @@ class MyDropDown(DropDown):
|
|||||||
for d in data:
|
for d in data:
|
||||||
dd = (d[self.valueField],d[self.textField])
|
dd = (d[self.valueField],d[self.textField])
|
||||||
b = Button(text=d[self.textField],font_size=CSize(1),
|
b = Button(text=d[self.textField],font_size=CSize(1),
|
||||||
size_hint_y=None,
|
size_hint=(None,None),
|
||||||
height=CSize(1.8))
|
width=CSize(10),
|
||||||
|
height=CSize(2.5))
|
||||||
setattr(b,'kw_data',dd)
|
setattr(b,'kw_data',dd)
|
||||||
b.bind(on_release=lambda btn: self.select(btn.kw_data))
|
b.bind(on_release=lambda btn: self.select(btn.kw_data))
|
||||||
self.add_widget(b)
|
self.add_widget(b)
|
||||||
#print(dd)
|
#print(dd)
|
||||||
|
|
||||||
def setDataByUrl(self,url,params={}):
|
def setDataByUrl(self,url,params={}):
|
||||||
def x(obj,resp):
|
def x(obj,d):
|
||||||
if resp.status_code == 200:
|
|
||||||
d = resp.json()
|
|
||||||
self.setData(d)
|
self.setData(d)
|
||||||
|
|
||||||
app = App.get_running_app()
|
app = App.get_running_app()
|
||||||
@ -191,8 +205,11 @@ class MyDropDown(DropDown):
|
|||||||
|
|
||||||
class SelectInput(BoxLayout):
|
class SelectInput(BoxLayout):
|
||||||
def __init__(self,**kw):
|
def __init__(self,**kw):
|
||||||
super(SelectInput,self).__init__(orientation='horizontal', size_hint_y=None,height=CSize(1.8))
|
super(SelectInput,self).__init__(orientation='horizontal',\
|
||||||
self.tinp = StrInput()
|
size_hint=(None,None),
|
||||||
|
width=CSize(kw.get('width',10)),
|
||||||
|
height=CSize(kw.get('height',2.5)))
|
||||||
|
self.tinp = StrInput(size_hint_y=None,height=kw.get('height',2.5))
|
||||||
self.tinp.readonly = True
|
self.tinp.readonly = True
|
||||||
newkw = {}
|
newkw = {}
|
||||||
newkw.update(kw)
|
newkw.update(kw)
|
||||||
@ -205,17 +222,26 @@ class SelectInput(BoxLayout):
|
|||||||
self.si_data = ''
|
self.si_data = ''
|
||||||
self.text = ''
|
self.text = ''
|
||||||
self.add_widget(self.tinp)
|
self.add_widget(self.tinp)
|
||||||
|
self.old_value = self.si_data
|
||||||
self.tinp.bind(focus=self.showDropdown)
|
self.tinp.bind(focus=self.showDropdown)
|
||||||
|
self.register_event_type('on_changed')
|
||||||
|
|
||||||
|
def on_changed(self,v=None):
|
||||||
|
pass
|
||||||
|
|
||||||
def showDropdown(self,instance,yn):
|
def showDropdown(self,instance,yn):
|
||||||
# if self.collide_point(*touch.pos):
|
# if self.collide_point(*touch.pos):
|
||||||
if yn:
|
if yn:
|
||||||
self.tinp.focus = False
|
self.tinp.focus = False
|
||||||
self.dropdown.showme(self)
|
self.dropdown.showme(self)
|
||||||
|
self.old_value = self.getValue()
|
||||||
|
|
||||||
def setData(self,d):
|
def setData(self,d):
|
||||||
self.tinp.si_data = d[0]
|
self.tinp.si_data = d[0]
|
||||||
self.tinp.text = d[1]
|
self.tinp.text = d[1]
|
||||||
|
v = self.getValue()
|
||||||
|
if v != self.old_value:
|
||||||
|
self.dispatch('on_changed',v)
|
||||||
|
|
||||||
def setValue(self,v):
|
def setValue(self,v):
|
||||||
self.tinp.si_value = v
|
self.tinp.si_value = v
|
||||||
|
Loading…
Reference in New Issue
Block a user