kivyblocks/kivyblocks/baseWidget.py

364 lines
9.7 KiB
Python
Raw Normal View History

2019-12-19 11:13:47 +08:00
import sys
2020-04-24 18:35:30 +08:00
from traceback import print_exc
2020-07-12 08:55:36 +08:00
2020-12-10 23:47:30 +08:00
from kivy.properties import ObjectProperty, StringProperty
2020-04-24 18:35:30 +08:00
from kivy.app import App
2019-12-19 11:13:47 +08:00
from kivy.utils import platform
from kivy.uix.button import Button, ButtonBehavior
from kivy.uix.accordion import Accordion,AccordionItem
from kivy.uix.label import Label
2020-04-18 11:49:13 +08:00
from kivy.event import EventDispatcher
2020-07-12 08:54:13 +08:00
from kivy.metrics import dp
from kivy.core.window import Window
2021-01-16 10:12:16 +08:00
from kivy.clock import Clock
2019-12-19 11:13:47 +08:00
from kivy.uix.actionbar import ActionBar,ActionView,ActionPrevious,ActionItem,ActionButton
from kivy.uix.actionbar import ActionToggleButton, ActionCheck,ActionSeparator,ActionGroup
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.pagelayout import PageLayout
from kivy.uix.scatterlayout import ScatterLayout
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.checkbox import CheckBox
from kivy.uix.switch import Switch
from kivy.uix.textinput import TextInput
from kivy.uix.dropdown import DropDown
from kivy.uix.tabbedpanel import TabbedPanel,TabbedPanelContent,TabbedPanelHeader,TabbedPanelItem
from kivy.uix.treeview import TreeView
from kivy.uix.image import AsyncImage,Image
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.scrollview import ScrollView
from kivy.uix.splitter import Splitter
from kivy.uix.spinner import Spinner
from kivy.uix.slider import Slider
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.sandbox import Sandbox
from kivy.uix.progressbar import ProgressBar
from kivy.uix.popup import Popup
from kivy.uix.modalview import ModalView
from kivy.uix.filechooser import FileChooser
from kivy.uix.effectwidget import EffectWidget
from kivy.uix.colorpicker import ColorPicker
from kivy.uix.carousel import Carousel
from kivy.uix.bubble import Bubble
from kivy.uix.codeinput import CodeInput
from kivy.graphics import Color, Rectangle
from kivy.properties import ListProperty
from kivycalendar import DatePicker
2020-04-24 18:35:30 +08:00
from kivy.factory import Factory
2019-12-19 11:13:47 +08:00
from appPublic.dictObject import DictObject
2020-12-10 23:47:30 +08:00
from appPublic.jsonConfig import getConfig
2020-05-03 13:14:27 +08:00
from appPublic.folderUtils import listFile
2019-12-19 11:13:47 +08:00
from .widgetExt.scrollwidget import ScrollWidget
from .widgetExt.binstateimage import BinStateImage
from .widgetExt.jsoncodeinput import JsonCodeInput
from .widgetExt.inputext import FloatInput,IntegerInput, \
StrInput,SelectInput, BoolInput, AmountInput
from .widgetExt.messager import Messager
2020-03-06 11:22:53 +08:00
from .charts.bar import Bar
2020-04-02 13:18:10 +08:00
from .bgcolorbehavior import BGColorBehavior
2020-04-24 18:35:30 +08:00
from .utils import NeedLogin, InsufficientPrivilege, HTTPError
from .login import LoginForm
2020-07-24 14:32:32 +08:00
from .tab import TabsPanel
2020-07-28 21:37:23 +08:00
from .qrdata import QRCodeWidget
2020-11-20 19:43:05 +08:00
from .threadcall import HttpClient
2020-12-10 23:47:30 +08:00
from .i18n import I18n
2020-12-25 15:39:28 +08:00
from .utils import CSize
2020-07-28 21:37:23 +08:00
2019-12-19 11:13:47 +08:00
if platform == 'android':
from .widgetExt.phonebutton import PhoneButton
from .widgetExt.androidwebview import AWebView
2020-04-30 00:02:42 +08:00
class WrapText(Label):
def __init__(self, **kw):
Label.__init__(self, **kw)
self.bind(width=lambda *x: self.setter('text_size')(self, (self.width, None)),
texture_size=lambda *x: self.setter('height')(self, self.texture_size[1]))
2020-12-25 15:39:28 +08:00
class Box(BGColorBehavior, BoxLayout):
def __init__(self,color_level=-1,radius=[],**kw):
BoxLayout.__init__(self, **kw)
BGColorBehavior.__init__(self, color_level=color_level,
radius=radius)
def add_widget(self, w, *args, **kw):
super().add_widget(w, *args, **kw)
self.setWidgetTextColor(w)
def setWidgetTextColor(self,w):
if isinstance(w,Box):
return
if isinstance(w,Text):
if not w.bgcolor:
w.color = self.fgcolor
return
for c in w.children:
self.setWidgetTextColor(c)
def selected(self):
super().selected()
if self.fgcolor == self.selected_fgcolor:
return
for c in self.children:
self.setWidgetTextColor(c)
def unselected(self):
super().unselected()
if self.fgcolor == self.normal_fgcolor:
return
for c in self.children:
self.setWidgetTextColor(c)
class HBox(Box):
def __init__(self,**kw):
kw.update({'orientation':'horizontal'})
Box.__init__(self, **kw)
class VBox(Box):
def __init__(self,color_level=-1,radius=[],**kw):
kw.update({'orientation':'vertical'})
Box.__init__(self, **kw)
2020-08-07 07:39:38 +08:00
class Text(Label):
2020-12-10 23:47:30 +08:00
lang=StringProperty('')
otext = StringProperty('')
2020-12-25 15:39:28 +08:00
def __init__(self,i18n=False, texttype='text', wrap=False,
fgcolor=None, **kw):
fontsize={'font_size':CSize(1)}
offset={
'text':0,
'title1':CSize(0.6),
'title2':CSize(0.5),
'title3':CSize(0.4),
'title4':CSize(0.3),
'title5':CSize(0.2),
'title6':CSize(0.1),
}
fontsize = {'font_size': CSize(1) + offset.get(texttype,0)}
2020-12-10 23:47:30 +08:00
self._i18n = i18n
2021-01-23 03:38:52 +08:00
self.i18n = I18n()
2020-12-25 15:39:28 +08:00
self.bgcolor = fgcolor
2020-12-10 23:47:30 +08:00
kwargs = kw.copy()
config = getConfig()
2020-12-21 19:29:53 +08:00
self.wrap = wrap
2020-12-25 15:39:28 +08:00
kwargs.update(fontsize)
2020-12-10 23:47:30 +08:00
super().__init__(**kwargs)
if self._i18n:
self.i18n = I18n()
self.i18n.addI18nWidget(self)
self.otext = kw.get('text','')
2020-12-21 19:29:53 +08:00
if self.wrap:
font_size = self.font_size
self.text_size = self.width, None
2020-12-25 15:39:28 +08:00
if self.bgcolor:
self.color = self.bgcolor
2021-01-27 17:39:48 +08:00
def get_wraped_size(self):
if self.text:
self._label.refresh()
return self._label.size
return (None,None)
2020-12-21 19:29:53 +08:00
def on_size(self,o,size):
# super().on_size(o,size)
if self.wrap:
font_size = self.font_size
self.text_size = self.width, None
2020-12-10 23:47:30 +08:00
def on_otext(self,o,v=None):
if self._i18n:
self.text = self.i18n(v)
else:
self.text = v
def changeLang(self,lang):
self.lang = lang
def on_lang(self,o,lang):
self.text = self.i18n(self.otext)
2020-04-24 18:35:30 +08:00
2020-12-25 15:39:28 +08:00
class Title1(Text):
def __init__(self, **kw):
kw.update({'texttype':'title1','bold':True})
Text.__init__(self, **kw)
class Title2(Text):
def __init__(self, **kw):
kw.update({'texttype':'title2','bold':True})
Text.__init__(self, **kw)
class Title3(Text):
def __init__(self, **kw):
kw.update({'texttype':'title3','bold':True})
Text.__init__(self, **kw)
class Title4(Text):
def __init__(self, **kw):
kw.update({'texttype':'title4','bold':True})
Text.__init__(self, **kw)
class Title5(Text):
def __init__(self, **kw):
kw.update({'texttype':'title5','bold':True})
Text.__init__(self, **kw)
class Title6(Text):
def __init__(self, **kw):
kw.update({'texttype':'title6','bold':True})
Text.__init__(self, **kw)
class Modal(BGColorBehavior, ModalView):
def __init__(self, auto_open=False, color_level=-1, radius=[], **kw):
ModalView.__init__(self, **kw)
BGColorBehavior.__init__(self, color_level=color_level,
radius=radius)
self.auto_open = auto_open
2021-01-23 03:38:52 +08:00
def add_widget(self,w, *args, **kw):
super().add_widget(w, *args, **kw)
2020-12-25 15:39:28 +08:00
if self.auto_open:
self.open()
class TimedModal(Modal):
def __init__(self, show_time=5, **kw):
self.show_time = show_time
self.time_task = None
Modal.__init__(self, **kw)
def open(self, *args, **kw):
self.time_task = Clock.schedule_once(self.dismiss, self.show_time)
super().open(*args, **kw)
def dismiss(self, *args, **kw):
if self.time_task:
self.time_task.cancel()
self.time_task = None
super().dismiss(*args, **kw)
2020-04-24 18:35:30 +08:00
class PressableImage(ButtonBehavior,AsyncImage):
def on_press(self):
pass
2020-04-02 13:18:10 +08:00
class PressableLabel(ButtonBehavior, Text):
def on_press(self):
pass
2019-12-19 11:13:47 +08:00
2020-05-03 13:14:27 +08:00
class FILEDataHandler(EventDispatcher):
2020-05-07 18:12:15 +08:00
def __init__(self, url, suffixs=[],params={}):
2020-05-03 13:14:27 +08:00
self.url = url
self.subfixes=subfixes
self.params = params
self.page_rows = self.params.get('page_rows',60)
self.page = self.params.get('page',1)
if not url.startswith('file://'):
raise Exception('%s is not a file url' % url)
2020-05-07 18:12:15 +08:00
self.files = [i for i in listFile(url[7:],suffixs=suffixs, \
2020-05-03 13:14:27 +08:00
rescursive=self.params.get('rescursive',False)) ]
self.total_files = len(self.files)
x = 0 if self.total_files % self.page_rows == 0 else 1
self.total_pages = self.total_files / self.page_rows + x
self.register_event_type('on_success')
self.register_event_type('on_error')
def on_success(self,d):
return
def on_error(self,e):
return
def handle(self,params={}):
d = {}
d['total'] = self.total_files
d['rows'] = []
p = self.params.copy()
p.update(params)
page = p.get('page')
for i in range(self.page_rows):
try:
r = self.files[page * self.page_rows + i]
2020-06-03 11:23:34 +08:00
d['rows'].append({'filename':r,
'id':r,
'url':r
})
2020-05-03 13:14:27 +08:00
except:
break
self.dispatch('on_success',d)
2020-04-18 11:49:13 +08:00
class HTTPDataHandler(EventDispatcher):
2020-04-24 18:35:30 +08:00
def __init__(self, url,method='GET',params={},
headers={},
2020-04-26 15:16:31 +08:00
files={},
stream=False
2020-04-24 18:35:30 +08:00
):
EventDispatcher.__init__(self)
2020-04-18 11:49:13 +08:00
self.url = url
self.method = method
self.params = params
self.headers = headers
2020-04-24 18:35:30 +08:00
self.files=files
2020-04-26 15:16:31 +08:00
self.stream=stream
2020-04-24 18:35:30 +08:00
self.register_event_type('on_success')
2020-04-18 11:49:13 +08:00
self.register_event_type('on_error')
2020-04-24 18:35:30 +08:00
def on_success(self,v):
2020-11-20 19:43:05 +08:00
print('HTTPDataHandler():',self.url,'finished...')
2020-04-18 11:49:13 +08:00
pass
2020-04-24 18:35:30 +08:00
def on_error(self,e):
2020-04-18 11:49:13 +08:00
pass
def onSuccess(self,o,v):
2020-11-20 19:43:05 +08:00
print(self.url,'onSuccess() called')
2020-04-24 18:35:30 +08:00
self.dispatch('on_success',v)
2020-04-18 11:49:13 +08:00
def onError(self,o,e):
2020-11-20 19:43:05 +08:00
print(self.url,'onError():v=',e)
2020-04-18 11:49:13 +08:00
self.dispatch('on_error',e)
2020-04-24 18:35:30 +08:00
print_exc()
print('[****][*********] onError Called',e)
def redo(self,o,v=None):
self.handle()
2020-04-18 11:49:13 +08:00
def handle(self,params={},headers={}):
p = self.params
p.update(params)
h = self.headers
h.update(headers)
2020-11-20 19:43:05 +08:00
hc = HttpClient()
print('HTTPDataHandler():',self.url,'handling....')
hc(self.url,method=self.method,
2020-04-18 11:49:13 +08:00
params=p,
headers=h,
2020-04-26 15:16:31 +08:00
files=self.files,
stream=self.stream,
2020-04-18 11:49:13 +08:00
callback=self.onSuccess,
errback=self.onError)
2020-05-07 18:12:15 +08:00
def getDataHandler(url,**kwargs):
if url.startswith('file://'):
return FILEDataHandler(url,**kwargs)
2021-01-27 17:39:48 +08:00
return HTTPDataHandler(url, **kwargs)
2020-05-07 18:12:15 +08:00
2020-07-12 08:54:13 +08:00
def device_type():
if platform != "android" and platform != "ios":
return "desktop"
elif Window.width >= dp(600) and Window.height >= dp(600):
return "tablet"
else:
return "mobile"