bugfix
This commit is contained in:
parent
51033259b7
commit
5317227fbd
Binary file not shown.
@ -10,13 +10,14 @@ from kivy.properties import NumericProperty, DictProperty, \
|
||||
|
||||
from kivyblocks.ready import WidgetReady
|
||||
from kivyblocks.bgcolorbehavior import BGColorBehavior
|
||||
from kivyblocks.utils import CSize, SUPER
|
||||
from kivyblocks.utils import CSize, SUPER, blockImage
|
||||
from kivyblocks.baseWidget import Box, Text
|
||||
from kivyblocks.widget_css import WidgetCSS
|
||||
|
||||
class TinyText(Text):
|
||||
def __init__(self, **kw):
|
||||
SUPER(TinyText, self, kw)
|
||||
self.size_hint = (None, None)
|
||||
self.on_texture_size(self, (1,1))
|
||||
|
||||
def on_texture_size(self, o, ts):
|
||||
@ -28,6 +29,7 @@ class ClickableBox(TouchRippleButtonBehavior, Box):
|
||||
border_width=1,
|
||||
**kw):
|
||||
SUPER(ClickableBox, self, kw)
|
||||
self.size_hint = [None, None]
|
||||
self.border_width = border_width
|
||||
# self.bind(minimum_height=self.setter('height'))
|
||||
# self.bind(minimum_width=self.setter('width'))
|
||||
@ -49,7 +51,6 @@ class ClickableText(ClickableBox):
|
||||
text = StringProperty(' ')
|
||||
fontsize = NumericProperty(1)
|
||||
def __init__(self, **kw):
|
||||
print('ClickableText begin inited')
|
||||
self.txt_w = None
|
||||
SUPER(ClickableText, self, kw)
|
||||
self.txt_w = TinyText(otext=self.text,
|
||||
@ -72,7 +73,6 @@ class ClickableIconText(ClickableText):
|
||||
def __init__(self, **kw):
|
||||
self.img_w = None
|
||||
SUPER(ClickableIconText, self, kw)
|
||||
print('ClickableIconText inited')
|
||||
|
||||
def on_source(self, o, source):
|
||||
if self.img_w:
|
||||
@ -111,7 +111,6 @@ class ToggleText(ClickableText):
|
||||
|
||||
def on_select_state(self, o, f):
|
||||
self.csscls = self.css_on if f else self.css_off
|
||||
print(f'using {self.csscls}')
|
||||
|
||||
class ToggleIconText(ToggleText):
|
||||
"""
|
||||
@ -149,8 +148,6 @@ class ClickableImage(ClickableBox):
|
||||
def __init__(self, **kw):
|
||||
self.img_w = None
|
||||
SUPER(ClickableImage, self, kw)
|
||||
# self.img_w = AsyncImage(source=self.source, **self.img_kw)
|
||||
# self.add_widget(self.img_w)
|
||||
|
||||
def on_source(self, o, source):
|
||||
if self.source is None:
|
||||
@ -200,25 +197,69 @@ class ToggleImage(ClickableImage):
|
||||
else:
|
||||
self.source = self.source_off
|
||||
|
||||
class CheckBox(ToggleImage):
|
||||
class SingleCheckBox(ClickableBox):
|
||||
otext = StringProperty(None)
|
||||
select_state = BooleanProperty(False)
|
||||
def __init__(self, **kw):
|
||||
SUPER(CheckBox, self, kw)
|
||||
self.old_state = None
|
||||
self.register_event_type('on_changed')
|
||||
SUPER(SingleCheckBox, self, kw)
|
||||
self.source_on = blockImage('checkbox-on.png')
|
||||
self.source_off = blockImage('ceckbox-off.png')
|
||||
self.source_off = blockImage('checkbox-off.png')
|
||||
self.select(False)
|
||||
self.create_img_w()
|
||||
if self.otext:
|
||||
self.txt_w = TinyText(otext=self.otext, i18n=True)
|
||||
self.txt_w.bind(size=self.reset_size)
|
||||
self.add_widget(self.txt_w)
|
||||
self.reset_size(self, None)
|
||||
|
||||
def on_changed(self, o=None):
|
||||
pass
|
||||
|
||||
def on_press(self, o=None):
|
||||
self.toggle()
|
||||
|
||||
def select(self, f):
|
||||
self.select_state = f
|
||||
|
||||
def change_img_source(self):
|
||||
self.img_w.source = self.source_on if self.select_state else \
|
||||
self.source_off
|
||||
|
||||
def toggle(self):
|
||||
self.select_state = False if self.select_state else True
|
||||
|
||||
def state(self):
|
||||
return self.select_state
|
||||
|
||||
def on_select_state(self, o, f):
|
||||
self.change_img_source()
|
||||
self.dispatch('on_changed', self.select_state)
|
||||
|
||||
def getValue(self):
|
||||
return self.state()
|
||||
|
||||
def setValue(self, v):
|
||||
self.select_state = False if v else True
|
||||
self.select(True if v else False)
|
||||
|
||||
def create_img_w(self):
|
||||
if self.select_state:
|
||||
self.img_w = AsyncImage(source=self.source_on,
|
||||
size_hint=(None, None),
|
||||
size=CSize(1, 1)
|
||||
)
|
||||
else:
|
||||
self.img_w = AsyncImage(source=self.source_off,
|
||||
size_hint=(None, None),
|
||||
size=CSize(1, 1)
|
||||
)
|
||||
self.add_widget(self.img_w)
|
||||
self.img_w.bind(size=self.reset_size)
|
||||
|
||||
r = Factory.register
|
||||
r('TinyText', TinyText)
|
||||
r('CheckBox', CheckBox)
|
||||
r('SingleCheckBox', SingleCheckBox)
|
||||
r('ClickableBox', ClickableBox)
|
||||
r('ClickableText',ClickableText)
|
||||
r('ClickableIconText',ClickableIconText)
|
||||
|
@ -1,67 +1,149 @@
|
||||
from kivy.clock import Clock
|
||||
from kivy.factory import Factory
|
||||
from kivy.uix.stacklayout import StackLayout
|
||||
from kivy.properties import BooleanProperty, StringProperty,\
|
||||
ListProperty, DictProperty
|
||||
ListProperty, DictProperty, OptionProperty, \
|
||||
NumericProperty
|
||||
|
||||
from kivyblocks.baseWidget import VBox
|
||||
from kivyblocks.clickable import ToggleText, ToggleImage
|
||||
from kivyblocks.typewriterbox import TypeWriterBox
|
||||
from kivy.factory import Factory
|
||||
from kivyblocks.utils import SUPER, CSize
|
||||
from kivyblocks.widget_css import WidgetCSS
|
||||
from kivyblocks.ready import WidgetReady
|
||||
|
||||
class MultiSelect(TypeWriterBox):
|
||||
class MultiSelect(WidgetCSS, WidgetReady, StackLayout):
|
||||
"""
|
||||
{
|
||||
"widgettype":"MultiSelect",
|
||||
"options":{
|
||||
"valueField"
|
||||
"textField"
|
||||
"items"
|
||||
"item_css"
|
||||
"item_selected_css"
|
||||
"all_position"
|
||||
"need_others"
|
||||
"default_selected"
|
||||
}
|
||||
}
|
||||
"""
|
||||
valueField = StringProperty('value')
|
||||
textField = StringProperty('text')
|
||||
x_spacing_c = NumericProperty(1)
|
||||
y_spacing_c = NumericProperty(0.5)
|
||||
items = ListProperty([])
|
||||
item_css = DictProperty({})
|
||||
item_selected_css = DictProperty({})
|
||||
all_button_position = StringProperty(None)
|
||||
default_selected=StringProperty([])
|
||||
|
||||
item_css = StringProperty({})
|
||||
item_selected_css = StringProperty({})
|
||||
all_position = OptionProperty(None, \
|
||||
options=[None, 'begin', 'end'])
|
||||
need_others = BooleanProperty(False)
|
||||
default_selected=ListProperty([])
|
||||
result = ListProperty([])
|
||||
def __init__(self, **kw):
|
||||
super(MultiSelect, self).__init__(**kw)
|
||||
SUPER(MultiSelect, self, kw)
|
||||
self.spacing = CSize(self.x_spacing_c, self.y_spacing_c)
|
||||
self.orientation = 'lr-tb'
|
||||
self.build_all_items()
|
||||
self.old_result = []
|
||||
self.register_event_type('on_changed')
|
||||
self.button_dic = {}
|
||||
self.value_b = {}
|
||||
self.buildWidgets()
|
||||
|
||||
def buildItem(self, dic):
|
||||
def build_all_items(self):
|
||||
items = [i for i in self.items ]
|
||||
if self.need_others:
|
||||
dic = {
|
||||
self.valueField:'_other_',
|
||||
self.textField:'others'
|
||||
}
|
||||
items.append(dic)
|
||||
|
||||
if self.all_position is not None:
|
||||
dic = {
|
||||
self.textField:'all',
|
||||
self.valueField:'_all_',
|
||||
}
|
||||
if self.all_position == 'begin':
|
||||
items.insert(0, dic)
|
||||
else:
|
||||
items.append(dic)
|
||||
self.all_items = items
|
||||
|
||||
def on_changed(self, d):
|
||||
pass
|
||||
|
||||
def build_item_widget(self, dic):
|
||||
keys = dic.keys()
|
||||
ToggleText = Factory.ToggleText
|
||||
ToggleImage = Factory.ToggleImage
|
||||
if 'text' in keys and 'value' in keys:
|
||||
desc = dic.copy()
|
||||
desc['off_css'] = self.item_css
|
||||
desc['on_css'] = self.item_selected_css
|
||||
return ToggleText(**desc)
|
||||
if 'source' in keys and 'on_source' in keys:
|
||||
return ToggleImage(**dic)
|
||||
ToggleIconText = Factory.ToggleIconText
|
||||
if self.textField in keys and 'source_on' in keys and \
|
||||
'source_off' in keys:
|
||||
desc['text'] = dic[self.textField]
|
||||
desc['css_off'] = self.item_css
|
||||
desc['css_on'] = self.item_selected_css
|
||||
desc["source_on"] = dic['source_on'],
|
||||
desc["source_off"] = dic['source_off']
|
||||
print('ToggleIconText', desc)
|
||||
return ToggleIconText(**desc)
|
||||
|
||||
def on_items(self, o, items):
|
||||
self.clear_widgets()
|
||||
if all_button_position is not None:
|
||||
dic = {
|
||||
'text':'all',
|
||||
'value':'_all_',
|
||||
if self.textField in keys:
|
||||
desc = {}
|
||||
desc['text'] = dic[self.textField]
|
||||
desc['css_off'] = self.item_css
|
||||
desc['css_on'] = self.item_selected_css
|
||||
print('ToggleText', desc)
|
||||
return ToggleText(**desc)
|
||||
if 'source_on' in keys and 'source_off' in keys:
|
||||
desc = {
|
||||
"source_on":dic['source_on'],
|
||||
"source_off":dic['source_off']
|
||||
}
|
||||
if all_button_position == 'begin':
|
||||
items.insert(dic,0)
|
||||
else:
|
||||
items.append(dic)
|
||||
for item in items:
|
||||
b = self.buildItem(item)
|
||||
print('ToggleImage', desc)
|
||||
return ToggleImage(**desc)
|
||||
|
||||
def buildWidgets(self):
|
||||
self.clear_widgets()
|
||||
for item in self.all_items:
|
||||
b = self.build_item_widget(item)
|
||||
b.bind(on_press=self.button_pressed)
|
||||
self.button_dic.update({b:dic})
|
||||
self.value_b.update({dic['value']:b})
|
||||
self.button_dic.update({b:item})
|
||||
self.add_widget(b)
|
||||
|
||||
def button_pressed(self, o):
|
||||
o.toggle()
|
||||
if self.button_dic[o]['value'] == '_all_' and o.state():
|
||||
for b, dic in self.button_dic.copy().items():
|
||||
if self.button_dic[o][self.valueField] == '_all_' and o.state():
|
||||
for b, dic in self.button_dic.items():
|
||||
if b == o:
|
||||
continue
|
||||
b.select(False)
|
||||
if self.button_dic[o][self.valueField] == '_other_' and o.state():
|
||||
for b, dic in self.button_dic.items():
|
||||
if b == o:
|
||||
continue
|
||||
b.select(False)
|
||||
if self.button_dic[o][self.valueField] not in ['_all_', '_other_'] \
|
||||
and o.state():
|
||||
for b, dic in self.button_dic.items():
|
||||
if dic[self.valueField] in ['_all_', '_other_']:
|
||||
b.select(False)
|
||||
Clock.schedule_once(self.set_result, 0.1)
|
||||
|
||||
def set_result(self, t=None):
|
||||
self.result = [ d[self.valueField] for b, d in \
|
||||
self.button_dic.items() if b.state() ]
|
||||
if self.result != self.old_result:
|
||||
self.dispatch('on_changed', self.result)
|
||||
self.old_result = self.result
|
||||
|
||||
def getValue(self):
|
||||
selected_buttons = [ b for b in self.button_dic.item() \
|
||||
if b.state() ]
|
||||
r = [ dic['value'] for b, dic in self.button_dic.items() \
|
||||
if b in selected_buttons ]
|
||||
return r
|
||||
self.set_result()
|
||||
return self.result
|
||||
|
||||
def setValue(self, value):
|
||||
self.result = value
|
||||
self.old_result = value
|
||||
for v in value:
|
||||
b = self.value_b[v]
|
||||
b.select(True)
|
||||
|
@ -1,6 +1,8 @@
|
||||
|
||||
|
||||
from traceback import print_exc
|
||||
from contextlib import contextmanager
|
||||
from kivy.graphics import Fbo, Color, Rectangle
|
||||
from kivy.core.window import Window
|
||||
from kivy.clock import Clock
|
||||
from kivy.utils import platform
|
||||
|
@ -19,7 +19,7 @@ from appPublic.registerfunction import getRegisterFunctionByName
|
||||
from .baseWidget import PressableLabel, Text, HBox, VBox
|
||||
from .color_definitions import getColors
|
||||
from .widget_css import WidgetCSS
|
||||
from .utils import alert,absurl
|
||||
from .utils import alert,absurl, SUPER
|
||||
from .toggleitems import PressableBox
|
||||
from .threadcall import HttpClient
|
||||
|
||||
@ -38,12 +38,11 @@ class EmptyBox(Label):
|
||||
class NodeTrigger(ButtonBehavior, EmptyBox):
|
||||
open_status = BooleanProperty(False)
|
||||
color = ListProperty([1,0,0,1])
|
||||
def __init__(self, color=[1,0,0,1],**kw):
|
||||
# super(NodeTrigger, self).__init__(**kw)
|
||||
EmptyBox.__init__(self, **kw)
|
||||
ButtonBehavior.__init__(self)
|
||||
def __init__(self, **kw):
|
||||
self.open_points = None
|
||||
self.close_points = None
|
||||
SUPER(NodeTrigger, self, kw)
|
||||
self.countPoints()
|
||||
self.color = color
|
||||
self.bind(size=self.onSize,pos=self.onSize)
|
||||
|
||||
def countPoints(self):
|
||||
@ -65,7 +64,6 @@ class NodeTrigger(ButtonBehavior, EmptyBox):
|
||||
|
||||
def on_press(self, *args):
|
||||
self.open_status = False if self.open_status else True
|
||||
# self.showOpenStatus()
|
||||
|
||||
def on_open_status(self, *largs):
|
||||
self.showOpenStatus()
|
||||
@ -74,6 +72,8 @@ class NodeTrigger(ButtonBehavior, EmptyBox):
|
||||
self.showOpenStatus()
|
||||
|
||||
def showOpenStatus(self):
|
||||
if self.close_points is None:
|
||||
return
|
||||
points = self.close_points
|
||||
if self.open_status:
|
||||
points = self.open_points
|
||||
|
@ -1,50 +0,0 @@
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.factory import Factory
|
||||
from kivyblocks.widget_css import WidgetCSS
|
||||
from kivyblocks.ready import WidgetReady
|
||||
|
||||
class TypeWriterBox(WidgetCSS, WidgetReady, Widget):
|
||||
def __init__(self, **kw):
|
||||
super(TypeWriterBox, self).__init__(**kw)
|
||||
self.size_hint_y = None
|
||||
self.sub_widgets = []
|
||||
self.curbox = self.add_vertical_box()
|
||||
self.bind(minimum_height=self.setter('height'))
|
||||
|
||||
def on_width(self, o, size):
|
||||
self.relocate()
|
||||
|
||||
def add_widget(self, w, *args):
|
||||
width = 0
|
||||
for c in self.curbox.children:
|
||||
width += c.width
|
||||
if width + c.width > self.width:
|
||||
self.curbox = self.add_vertical_box()
|
||||
self.curbox.add_widget(w, *args)
|
||||
self.sub_widgets.append(w)
|
||||
|
||||
def del_widget(self, w):
|
||||
self.sub_widgets = [i for i in self.sub_widgets.copy() if i !=w ]
|
||||
self.relocate()
|
||||
|
||||
def add_veritcal_box(self):
|
||||
box = BoxLayout(orientation='vertical', size_hint_y=None)
|
||||
box.bind(minimum_height = box.setter('height'))
|
||||
super(TypeWriterBox, self).add_widget(box)
|
||||
return box
|
||||
|
||||
def relocate(self):
|
||||
with self.fboContext():
|
||||
for b in self.children:
|
||||
b.clear_widgets()
|
||||
width = 0
|
||||
self.clear_widgets()
|
||||
self.curbox = add_vertical_box()
|
||||
for w in self.sub_widgets:
|
||||
if width + w.width > self.width:
|
||||
self.curbox = self.add_vertical_box()
|
||||
width = 0
|
||||
self.curbox.add_widget(w)
|
||||
|
||||
Factory.register('TypeWriterBox', TypeWriterBox)
|
@ -1,5 +1,6 @@
|
||||
import os
|
||||
from traceback import print_exc
|
||||
from traceback import print_exc
|
||||
from kivy.app import App
|
||||
from appPublic.jsonConfig import getConfig
|
||||
from kivy.uix.popup import Popup
|
||||
@ -42,7 +43,12 @@ def SUPER(klass, obj, kw):
|
||||
dic = { k:kw.pop(k) for k in keys if hasattr(obj, k) }
|
||||
super(klass, obj).__init__(**kw)
|
||||
for k,v in dic.items():
|
||||
setattr(obj, k, v)
|
||||
try:
|
||||
setattr(obj, k, v)
|
||||
except Exception as e:
|
||||
print(f'obj={obj}, setattr(obj, "{k}","{v}") error')
|
||||
print_exc()
|
||||
raise e
|
||||
|
||||
def blockImage(name):
|
||||
p = os.path.dirname(os.path.abspath(__file__))
|
||||
|
@ -77,7 +77,6 @@ class StrInput(TextInput):
|
||||
|
||||
def checkChange(self,o,v=None):
|
||||
v = self.getValue()
|
||||
print('StrInput():v=', v)
|
||||
if v != self.old_value:
|
||||
self.old_value = v
|
||||
self.dispatch('on_changed',v)
|
||||
@ -89,6 +88,8 @@ class StrInput(TextInput):
|
||||
if v is None:
|
||||
v = ''
|
||||
self.text = str(v)
|
||||
self.old_value = self.text
|
||||
|
||||
|
||||
class Password(StrInput):
|
||||
def __init__(self, **kw):
|
||||
|
Loading…
Reference in New Issue
Block a user