diff --git a/kivyblocks/blocksapp.py b/kivyblocks/blocksapp.py index cdb4a90..2f2243a 100644 --- a/kivyblocks/blocksapp.py +++ b/kivyblocks/blocksapp.py @@ -82,14 +82,68 @@ def getAuthHeader(): print('serverinfo authCode not found') return {} +kivyblocks_css_keys = [ + "height_nm", + "width_nm", + "height_cm", + "width_cm", + "bgcolor", + "fgcolor", + "radius", + "spacing", + "padding", + "border" +] + class BlocksApp(App): + def load_csses(self): + config = getConfig() + if not config.css: + return + + if config.css.css_filename: + with codecs.open(config.css.css_filename, 'r', 'utf-8') as f: + d = json.load(f) + self.buildCsses(d) + if config.css.css_url: + hc = HttpClient() + d = hc.get(self.realurl(config.css.css_url)) + self.buildCsses(d) + + def buildCsses(self, dic): + for k,v in dic.items(): + if isinstance(v,dict): + self.csses[k] = \ + {x:y for x,y in v.items() if x in kivyblocks_css_keys} + + def get_csses(self): + return self.csses + + def get_css(self, name): + return self.csses.get(name,self.csses.get('default',{})) + def build(self): config = getConfig() + self.csses = { + "default":{ + "bgcolor":[0.35,0.35,0.35,1], + "fgcolor":[0.85,0.85,0.85,1] + }, + "input":{ + "bgcolor":[0.35,0.35,0.35,1], + "fgcolor":[0.85,0.85,0.85,1] + }, + "input_focus":{ + "bgcolor":[1,0.35,0.35,1], + "fgcolor":[1,0.85,0.85,1] + } + } self.public_headers = {} Window.bind(on_request_close=self.on_close) Window.bind(size=self.device_info) self.workers = Workers(maxworkers=config.maxworkers or 80) self.workers.start() + self.load_csses() self.running = True if config.root: blocks = Blocks() diff --git a/kivyblocks/dg.py b/kivyblocks/dg.py index d4da7a4..8d02194 100644 --- a/kivyblocks/dg.py +++ b/kivyblocks/dg.py @@ -24,6 +24,7 @@ from .paging import Paging, RelatedLoader from .ready import WidgetReady from .toolbar import Toolbar from .bgcolorbehavior import BGColorBehavior +from .widget_css import WidgetCSS def field_widget(desc, rec): viewer = desc.get('viewer') @@ -67,6 +68,7 @@ class BLabel(ButtonBehavior, Text): def __init__(self, **kw): ButtonBehavior.__init__(self) Text.__init__(self,**kw) + self.csscls = 'dummy' class Cell(BoxLayout): def __init__(self,row,desc): @@ -129,6 +131,7 @@ class Row(GridLayout): self.linewidth = 1 self.rowdesc = rowdesc super().__init__(cols=len(self.rowdesc),spacing=self.linewidth) + self.spacing = 2 # Clock.schedule_once(self.init,0) self.init(0) @@ -156,12 +159,10 @@ class Row(GridLayout): self.part.datagrid.select_row = self self.part.datagrid.dispatch('on_selected',self) -class Header(WidgetReady, BGColorBehavior, ScrollWidget): +class Header(ScrollWidget, WidgetReady, WidgetCSS): def __init__(self,part,color_level=-1,**kw): self.part = part - ScrollWidget.__init__(self,**kw) - WidgetReady.__init__(self) - BGColorBehavior.__init__(self,color_level=color_level) + super(Header, self).__init__(**kw) self.init(1) self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop) if self.part.freeze_flag: @@ -176,10 +177,10 @@ class Header(WidgetReady, BGColorBehavior, ScrollWidget): self.add_widget(self.header) self.height = self.header.height -class Body(ScrollWidget): +class Body(ScrollWidget, WidgetReady, WidgetCSS): def __init__(self,part,**kw): self.part = part - ScrollWidget.__init__(self,**kw) + super(Body, self).__init__(**kw) self.idRow = {} self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop) if self.part.freeze_flag: diff --git a/kivyblocks/widgetExt/inputext.py b/kivyblocks/widgetExt/inputext.py index 777b614..9f4f0cc 100755 --- a/kivyblocks/widgetExt/inputext.py +++ b/kivyblocks/widgetExt/inputext.py @@ -13,6 +13,7 @@ from kivy.properties import BooleanProperty, ListProperty from ..threadcall import HttpClient from ..utils import CSize +from ..widget_css import WidgetCSS class BoolInput(Switch): def __init__(self,**kw): @@ -40,16 +41,7 @@ class BoolInput(Switch): def setValue(self,v): self.active = v -class StrInput(TextInput): - bgcolor = ListProperty(None) - fgcolor = ListProperty(None) - - def on_bgcolor(self, o, bgcolor): - self.background_color = bgcolor - - def on_fgcolor(self, o, fgcolor): - self.foreground_color = fgcolor - +class StrInput(WidgetCSS, TextInput): def __init__(self,**kv): if kv is None: kv = {} @@ -78,7 +70,7 @@ class StrInput(TextInput): a['font_size'] = CSize(kv.get('font_size',0.9)) Logger.info('TextInput:a=%s,kv=%s',a,kv) - super(StrInput,self).__init__(**a) + super(StrInput, self).__init__(**a) self.old_value = None self.register_event_type('on_changed') self.bind(focus=self.on_focus) @@ -95,8 +87,10 @@ class StrInput(TextInput): def on_focus(self,t,v): if v: self.old_value = self.getValue() + self.csscls = 'input_focus' else: self.checkChange(None) + self.csscls = 'input' def getValue(self): return self.text diff --git a/kivyblocks/widget_css.py b/kivyblocks/widget_css.py index 7773624..6262bdb 100644 --- a/kivyblocks/widget_css.py +++ b/kivyblocks/widget_css.py @@ -4,24 +4,7 @@ from kivy.uix.textinput import TextInput from kivy.uix.button import Button from kivy.uix.label import Label from kivyblocks.utils import CSize - -kivyblocks_css_keys = [ - "height_nm", - "width_nm", - "height_cm", - "width_cm", - "bgcolor", - "fgcolor", - "radius", - "spacing", - "padding", - "border" -] - -kivyblocks_csses = { - "default":{ - }, -} +from kivy.app import App class WidgetCSS(object): height_nm = NumericProperty(None) @@ -32,6 +15,8 @@ class WidgetCSS(object): fgcolor = ListProperty(None) csscls = StringProperty(None) radius = ListProperty(None) + background_rec = None + bg_func = Rectangle def on_height_nm(self, o, v): if not self.height_nm: @@ -53,16 +38,13 @@ class WidgetCSS(object): def on_csscls(self, o, csscls): if isinstance(self.csscls, str): - self.set_css(sef.csscls) - - def _get_css_dict_by_name(self, css_name): - dic = kivyblocks_csses.get(css_name,{}) - return dic + self.set_css(self.csscls) def set_css(self, css_str): css = {} + app = App.get_running_app() for css_name in css_str.split(' '): - css.update(self._get_css_dict_by_name(css_name)) + css.update(app.get_css(css_name)) for k,v in css.items(): setattr(self,k,v) @@ -82,9 +64,9 @@ class WidgetCSS(object): if not self.fgcolor: return if isinstance(self, TextInput): - self.foreground_color = fgcolor + self.foreground_color = self.fgcolor if isinstance(self, Label): - self.color = fgcolor + self.color = self.fgcolor return return @@ -92,17 +74,19 @@ class WidgetCSS(object): if not self.bgcolor: return if isinstance(self, TextInput): - self.background_color = bgcolor + self.background_color = self.bgcolor return if isinstance(self, Button): - self.background_color = bgcolor + self.background_color = self.bgcolor return self.set_background_color() def on_radius(self, o, r): if not radius: + self.bg_func = Rectangle return - self.set_background_color() + self.bg_func = RoundedRectangle + # self.set_background_color() def set_background_color(self, *args): if not self.bgcolor: @@ -112,11 +96,11 @@ class WidgetCSS(object): with self.canvas.before: Color(*self.bgcolor) - if self.radius and len(self.radius) == 4: - self.background_rect = RoundedRectangle(pos=self.pos, + if self.radius: + self.background_rect = self.bg_func(pos=self.pos, size=self.size, radius=self.radius) else: - self.background_rect = Rectangle(pos=self.pos, + self.background_rect = self.bg_func(pos=self.pos, size=self.size)