318 lines
8.2 KiB
Python
318 lines
8.2 KiB
Python
from kivy.logger import Logger
|
|
from kivy.graphics import Color, Rectangle
|
|
from kivy.uix.button import ButtonBehavior
|
|
from kivy.uix.image import AsyncImage
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
from kivy.uix.gridlayout import GridLayout
|
|
from kivy.uix.label import Label
|
|
from kivy.uix.widget import Widget
|
|
from kivy.app import App
|
|
from kivy.clock import Clock
|
|
from kivy.factory import Factory
|
|
from kivy.properties import StringProperty, DictProperty, \
|
|
OptionProperty, ListProperty, NumericProperty, \
|
|
BooleanProperty
|
|
|
|
from appPublic.dictObject import DictObject
|
|
from appPublic.registerfunction import RegisterFunction
|
|
|
|
from .widgetExt.scrollwidget import ScrollWidget
|
|
from .utils import *
|
|
from .ready import WidgetReady
|
|
from .color_definitions import getColors
|
|
from .baseWidget import Text, Box
|
|
from .scrollpanel import ScrollPanel
|
|
from .command_action import cmd_action
|
|
|
|
class Toolbar(ScrollPanel):
|
|
"""
|
|
tool has the follow attributes
|
|
{
|
|
"name",
|
|
"source_on,
|
|
"source_off,
|
|
# source_on, source_off, or "img_src",
|
|
"label",
|
|
"deletable"
|
|
"url",
|
|
"rfname",
|
|
}
|
|
toolbar has follow attributes
|
|
{
|
|
"img_size_c":image height in charecter size
|
|
"text_size_c":
|
|
"toolbar_orient":"H" or "V"
|
|
"tool_orient":"horizontal" or "vertical"
|
|
"css_on",
|
|
"css_off",
|
|
"tools":
|
|
}
|
|
"""
|
|
|
|
css_on = StringProperty('default')
|
|
css_off = StringProperty('default')
|
|
tools = ListProperty([])
|
|
tool_orient = OptionProperty('horizontal', \
|
|
options=['horizontal', 'vertical'])
|
|
toolbar_orient = OptionProperty('H', options=['H', 'V'])
|
|
img_size_c = NumericProperty(2)
|
|
text_size_c = NumericProperty(1)
|
|
target = StringProperty(None)
|
|
executable = BooleanProperty(False)
|
|
def __init__(self, **kw):
|
|
self.w_dic = {}
|
|
SUPER(Toolbar, self, kw)
|
|
self.buffer = {}
|
|
self.register_event_type('on_press')
|
|
self.register_event_type('on_delete_tool')
|
|
if self.toolbar_orient == 'H':
|
|
self._inner.orientation = 'horizontal'
|
|
else:
|
|
self._inner.orientation = 'vertical'
|
|
self.clear_widgets()
|
|
for t in self.tools:
|
|
self.add_tool(t)
|
|
|
|
self.bar_width = 0
|
|
if self.toolbar_orient == 'H':
|
|
self.do_scroll_y = False
|
|
else:
|
|
self.do_scroll_x = False
|
|
|
|
def on_children_size(self, o, size):
|
|
self.on_size(None, None)
|
|
|
|
def on_size(self, o, size):
|
|
if self.toolbar_orient == 'H':
|
|
self.size_hint_x = 1
|
|
self.size_hint_y = None
|
|
if len(self.w_dic.keys()) > 0:
|
|
self.height = max([w.height for w in self.w_dic.keys()])
|
|
else:
|
|
self.size_hint_x = None
|
|
self.size_hint_y = 1
|
|
if len(self.w_dic.keys()) > 0:
|
|
self.width = max([w.width for w in self.w_dic.keys() ])
|
|
|
|
def add_tool(self, t):
|
|
label = t.get('label', t.get('name', None))
|
|
source_on = t.get('source_on', t.get('img_src',None))
|
|
source_off = t.get('source_off', t.get('img_src', None))
|
|
ToggleIconText = Factory.ToggleIconText
|
|
ToggleText = Factory.ToggleText
|
|
ToggleImage = Factory.ToggleImage
|
|
ClickableImage = Factory.ClickableImage
|
|
if label and source_on:
|
|
w = ToggleIconText(css_on=self.css_on,
|
|
css_off=self.css_off,
|
|
text=label,
|
|
size_hint = (None, None),
|
|
fontsize=self.text_size_c,
|
|
source_on=source_on,
|
|
source_off=source_off,
|
|
orientation=self.tool_orient,
|
|
img_kw={
|
|
"size_hint":(None, None),
|
|
"height":CSize(self.img_size_c),
|
|
"width":CSize(self.img_size_c)
|
|
}
|
|
)
|
|
elif label:
|
|
w = ToggleText(css_on=self.css_on,
|
|
css_off=self.css_off,
|
|
size_hint = (None, None),
|
|
orientation=self.tool_orient,
|
|
fontsize=CSize(self.text_size_c),
|
|
text=label)
|
|
elif source_on:
|
|
w = ToggleImage( source_on=source_on,
|
|
source_off=source_off,
|
|
size_hint = (None, None),
|
|
orientation=self.tool_orient,
|
|
img_kw={
|
|
"size_hint":(None, None),
|
|
"height":CSize(self.img_size_c),
|
|
"width":CSize(self.img_size_c)
|
|
}
|
|
)
|
|
|
|
w.widget_id = t['name']
|
|
if t.get('deletable', False):
|
|
x = ClickableImage(source=blockImage('delete.png'),
|
|
size_hint=(None,None),
|
|
size=CSize(1,1)
|
|
)
|
|
x.data = (w, t)
|
|
x.bind(on_press=self.delete_tool)
|
|
w.add_widget(x)
|
|
|
|
if w:
|
|
self.add_widget(w)
|
|
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)
|
|
w.bind(minimum_width=w.setter('width'))
|
|
w.bind(minimum_height=w.setter('height'))
|
|
|
|
def delete_tool(self, o):
|
|
w, t = o.data
|
|
self.del_tool(w)
|
|
self.dispatch('on_delete_tool', o.data)
|
|
|
|
def on_delete_tool(self, o, d=None):
|
|
pass
|
|
|
|
def del_tool(self, w):
|
|
self.remove_widget(w)
|
|
self.w_dic = {k:v for k,v in self.w_dic.copy().items() \
|
|
if k != w }
|
|
|
|
def on_press(self, o):
|
|
pass
|
|
|
|
def select(self,name):
|
|
for w, v in self.w_dic.items():
|
|
if v['name'] == name:
|
|
w.select(True)
|
|
self.tool_press(w)
|
|
break
|
|
|
|
def tool_press(self, o):
|
|
for w,v in self.w_dic.items():
|
|
if w == o:
|
|
ret_v = v
|
|
w.select(True)
|
|
else:
|
|
w.select(False)
|
|
if not self.executable:
|
|
self.dispatch('on_press', ret_v)
|
|
return
|
|
|
|
desc = self.w_dic[o].copy()
|
|
if not desc.get('target'):
|
|
desc['target'] = self.target
|
|
|
|
cmd_action(desc, self)
|
|
|
|
class ToolPage(Box):
|
|
"""
|
|
ToolPage:
|
|
{
|
|
toolbar_size:
|
|
tool_at
|
|
toolbar
|
|
}
|
|
"""
|
|
toolbar_size = NumericProperty(2)
|
|
tool_at = OptionProperty('top', \
|
|
options=['top', 'bottom', 'left', 'right'])
|
|
toolbar = DictProperty({})
|
|
def __init__(self, **kw):
|
|
SUPER(ToolPage, self, kw)
|
|
if self.tool_at in [ 'top','bottom']:
|
|
self.orientation = 'vertical'
|
|
else:
|
|
self.orientation = 'horizontal'
|
|
if not self.toolbar_size:
|
|
self.toolbar_size = self.img_size + self.text_size + 0.3
|
|
self.content_widgets = {}
|
|
self.content_w = None
|
|
self.toolbar_w = None
|
|
self.init()
|
|
self.toolbar_w.bind(on_delete_tool=self.delete_content_widget)
|
|
name = self.toolbar['tools'][0]['name']
|
|
self.toolbar_w.select(name)
|
|
|
|
def get_subwidgets(self):
|
|
children = [ i for i in self.children]
|
|
x = [ i for i in self.content_widgets.values() ]
|
|
return children + x
|
|
|
|
def delete_content_widget(self, o, d):
|
|
w, dic = d
|
|
self.del_tool(dic['name'])
|
|
|
|
def add_tool(self, tool):
|
|
self.toolbar_w.add_tool(tool)
|
|
|
|
def del_tool(self, name):
|
|
g = self.content_widgets.copy()
|
|
self.content_widgets = {k:v for k,v in g.items() if k!=name}
|
|
|
|
def on_size(self,obj,size):
|
|
if self.content_w is None:
|
|
return
|
|
if self.tool_at in ['top','bottom']:
|
|
self.toolbar_w.size_hint_y = None
|
|
self.content_w.height = self.height - self.toolbar_w.height
|
|
else:
|
|
self.toolbar_w.size_hint_x = None
|
|
self.content_w.width = self.width - self.toolbar_w.width
|
|
|
|
def init(self):
|
|
self.content_w = BoxLayout()
|
|
self.content_w.widget_id = 'content'
|
|
self.toolbar_w = Toolbar(**self.toolbar)
|
|
if self.tool_at in ['top','left']:
|
|
self.add_widget(self.toolbar_w)
|
|
self.add_widget(self.content_w)
|
|
else:
|
|
self.add_widget(self.content_w)
|
|
self.add_widget(self.toolbar_w)
|
|
|
|
self.toolbar_w.bind(on_press=self.on_press_handle)
|
|
|
|
def build_widget(self, url):
|
|
desc = {
|
|
"widgettype":"urlwidget",
|
|
"options":{
|
|
"url":url
|
|
}
|
|
}
|
|
b = Factory.Blocks()
|
|
return b.widgetBuild(desc)
|
|
|
|
def print_all(self):
|
|
self.print_info(self)
|
|
self.print_info(self.toolbar_w)
|
|
for w in self.toolbar_w.w_dic.keys():
|
|
self.print_info(w)
|
|
for c in w.children:
|
|
self.print_info(c)
|
|
self.print_info(self.content_w)
|
|
for c in self.content_w.children:
|
|
self.print_info(c)
|
|
|
|
def print_info(self, o):
|
|
print('self.size_hint=', o.__class__, o.size_hint,
|
|
'self.x,y=', o.width, o.height)
|
|
|
|
def on_press_handle(self, o, v):
|
|
name = v.get('name')
|
|
refresh = v.get('refresh', False)
|
|
# self.print_all()
|
|
|
|
w = self.content_widgets.get(name)
|
|
self.content_w.clear_widgets()
|
|
if w and not refresh:
|
|
self.content_w.add_widget(w)
|
|
return
|
|
url = v.get('url')
|
|
if url:
|
|
w = self.build_widget(url)
|
|
if w:
|
|
self.content_widgets[name] = w
|
|
self.content_w.add_widget(w)
|
|
return
|
|
rfname = v.get('rfname')
|
|
if rfname:
|
|
rf = RegisterFunction()
|
|
f = rf.get(rfname)
|
|
if f:
|
|
r = f()
|
|
if isinstance(r,Widget):
|
|
self.content_w.add_widget(r)
|
|
|