bugfix
This commit is contained in:
parent
4700ba32a3
commit
ba29b30fe9
0
kivyblocks/anz/__init__.py
Normal file
0
kivyblocks/anz/__init__.py
Normal file
46
kivyblocks/anz/bluetooth.py
Normal file
46
kivyblocks/anz/bluetooth.py
Normal file
@ -0,0 +1,46 @@
|
||||
from kivy.app import App
|
||||
|
||||
from jnius import autoclass
|
||||
import kivy
|
||||
from android.broadcast import BroadcastReceiver
|
||||
import sys
|
||||
|
||||
from kivyblocks.baseWidget import VBox
|
||||
|
||||
BluetoothManager = autoclass('android.bluetooth.BluetoothManager')
|
||||
BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
|
||||
BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice')
|
||||
|
||||
class BluetoothFinder(VBox):
|
||||
data = ListProperty([])
|
||||
def __init__(self, **kw):
|
||||
super().__init__(**kw)
|
||||
arg = context.getSystemService(context.BLUETOOTH_SERVICE)
|
||||
self.bt_manager = BluetoothManager(arg)
|
||||
self.bt_adapter = self.bt_manager.getAdaper()
|
||||
self.unpairedBT()
|
||||
|
||||
def get_paired_bt(self):
|
||||
return self.bt_adapter.getBondedDevice()
|
||||
|
||||
def __del__(self):
|
||||
self.adapter.cancelDiscovery()
|
||||
|
||||
def unpairedBT(self):
|
||||
self.adapter = BluetoothAdapter.getDefaultAdapter()
|
||||
# Search foir unpaired devices
|
||||
print("Unpaired devices")
|
||||
self.data=[{"text": "Unpaired Devices"}]
|
||||
myReceiver = BroadcastReceiver(self.onReceive, actions = [BluetoothDevice.ACTION_FOUND, BluetoothAdapter.ACTION_DISCOVERY_STARTED, BluetoothAdapter.ACTION_DISCOVERY_FINISHED])
|
||||
myReceiver.start()
|
||||
self.adapter.startDiscovery()
|
||||
|
||||
# Called by Broadcastreceiver
|
||||
def onReceive(self, context, intent):
|
||||
print(f"*BT* On receive context{context}", flush = True)
|
||||
print(f"*BT* On receive intent {intent}", flush = True)
|
||||
sys.stdout.flush()
|
||||
|
||||
self.myData.append({"text": f"Context {context}, intent {intent}"})
|
||||
self.layout.data = [item for item in self.myData]
|
||||
|
@ -67,7 +67,7 @@ from .widgetExt.inputext import FloatInput,IntegerInput, \
|
||||
StrInput,SelectInput, BoolInput, Password
|
||||
from .widgetExt.messager import Messager
|
||||
from .bgcolorbehavior import BGColorBehavior
|
||||
from .utils import NeedLogin, InsufficientPrivilege, HTTPError
|
||||
from .utils import NeedLogin, InsufficientPrivilege, HTTPError, blockImage
|
||||
from .login import LoginForm
|
||||
from .tab import TabsPanel
|
||||
from .threadcall import HttpClient
|
||||
@ -76,6 +76,7 @@ from .widget_css import WidgetCSS
|
||||
from .ready import WidgetReady
|
||||
from .utils import CSize, SUPER
|
||||
from .swipebehavior import SwipeBehavior
|
||||
from .widgetExt.inputext import MyDropDown
|
||||
|
||||
if platform == 'android':
|
||||
from .widgetExt.phonebutton import PhoneButton
|
||||
@ -171,7 +172,6 @@ class Text(Label):
|
||||
|
||||
SUPER(Text, self, kwargs)
|
||||
if self._i18n:
|
||||
self.i18n = I18n()
|
||||
self.i18n.addI18nWidget(self)
|
||||
if self.wrap:
|
||||
self.size_hint_y = None
|
||||
@ -220,6 +220,7 @@ class Text(Label):
|
||||
self.lang = lang
|
||||
|
||||
def on_lang(self,o,lang):
|
||||
if self._i18n and self.otext:
|
||||
self.text = self.i18n(self.otext)
|
||||
|
||||
class Title1(Text):
|
||||
@ -260,10 +261,11 @@ class Modal(VBox):
|
||||
position = OptionProperty('cc',options=['tl', 'tc', 'tr',
|
||||
'cl', 'cc', 'cr',
|
||||
'bl', 'bc', 'br'])
|
||||
|
||||
def __init__(self, **kw):
|
||||
self._target = None
|
||||
SUPER(Modal, self, kw)
|
||||
super(Modal, self).__init__(**kw)
|
||||
self.set_size_position()
|
||||
self._target.bind(size=self.set_size_position)
|
||||
self.register_event_type('on_open')
|
||||
self.register_event_type('on_pre_open')
|
||||
self.register_event_type('on_pre_dismiss')
|
||||
@ -285,7 +287,16 @@ class Modal(VBox):
|
||||
|
||||
return super().on_touch_down(touch)
|
||||
|
||||
def set_modal_position(self):
|
||||
def on_target(self):
|
||||
w = Window
|
||||
if self.target is not None:
|
||||
w = Factory.Blocks.getWidgetById(self.target)
|
||||
if w is None:
|
||||
w = Window
|
||||
if w != self._target:
|
||||
self._target = w
|
||||
|
||||
def set_target(self):
|
||||
if self._target is None:
|
||||
if self.target is None:
|
||||
w = Window
|
||||
@ -294,42 +305,56 @@ class Modal(VBox):
|
||||
if w is None:
|
||||
w = Window
|
||||
self._target = w
|
||||
|
||||
def set_size_position(self, *args):
|
||||
self.set_target()
|
||||
if self.size_hint_x:
|
||||
self.width = self.size_hint_x * self._target.width
|
||||
if self.size_hint_y:
|
||||
self.height = self.size_hint_y * self._target.height
|
||||
print(self.width, self.height,
|
||||
self.size_hint_x, self.size_hint_y,
|
||||
self._target.size
|
||||
)
|
||||
self.set_modal_position()
|
||||
|
||||
def set_modal_position(self):
|
||||
self.set_target()
|
||||
xn = self.position[1]
|
||||
yn = self.position[0]
|
||||
x, y = 0, 0
|
||||
if xn == 'c':
|
||||
x = (w.width - self.width) / 2
|
||||
x = (self._target.width - self.width) / 2
|
||||
elif xn == 'r':
|
||||
x = w.width - self.width
|
||||
x = self._target.width - self.width
|
||||
if x < 0:
|
||||
x = 0
|
||||
if yn == 'c':
|
||||
y = (w.height - self.height) / 2
|
||||
y = (self._target.height - self.height) / 2
|
||||
elif yn == 't':
|
||||
y = w.height - self.height
|
||||
y = self._target.height - self.height
|
||||
if y < 0:
|
||||
y = 0
|
||||
if w == Window:
|
||||
if self._target == Window:
|
||||
self.pos = x, y
|
||||
else:
|
||||
self.pos = w.pos[0] + x, w.pos[1] + y
|
||||
self.pos = self._target.pos[0] + x, self._target.pos[1] + y
|
||||
|
||||
def open(self, widget=None):
|
||||
def open(self):
|
||||
if self.parent:
|
||||
return
|
||||
self.parent.remove_widget(self)
|
||||
self.dispatch('on_pre_open')
|
||||
self.set_modal_position()
|
||||
Window.add_widget(self)
|
||||
self.dispatch('on_open')
|
||||
if self._target != Window:
|
||||
self._target.disable()
|
||||
self._target.disabled = True
|
||||
|
||||
def dismiss(self, *args):
|
||||
self.dispatch('on_pre_dismiss')
|
||||
self.dispatch('on_dismiss')
|
||||
Window.remove_widget(self)
|
||||
if self._target != Window:
|
||||
self._Target.enable()
|
||||
self._target.enabled = False
|
||||
|
||||
def on_open(self, *args):
|
||||
pass
|
||||
@ -369,6 +394,32 @@ class TimedModal(Modal):
|
||||
self.time_task = None
|
||||
super().dismiss()
|
||||
|
||||
class Running(AsyncImage):
|
||||
def __init__(self, widget, **kw):
|
||||
super().__init__(**kw)
|
||||
self.host_widget = widget
|
||||
self.source = blockImage('running.gif')
|
||||
self.host_widget.bind(size=self.set_size)
|
||||
self.set_size()
|
||||
self.open()
|
||||
|
||||
def open(self):
|
||||
if self.parent:
|
||||
self.parent.remove_widget(self)
|
||||
Window.add_widget(self)
|
||||
self.host_widget.disabled = True
|
||||
|
||||
def dismiss(self):
|
||||
if self.parent:
|
||||
self.parent.remove_widget(self)
|
||||
self.host_widget.disabled = False
|
||||
|
||||
def set_size(self, *args):
|
||||
self.size_hint = (None, None)
|
||||
self.width = CSize(2)
|
||||
self.height = CSize(2)
|
||||
self.center = self.host_widget.center
|
||||
|
||||
class PressableImage(ButtonBehavior,AsyncImage):
|
||||
def on_press(self):
|
||||
pass
|
||||
@ -377,6 +428,10 @@ class PressableLabel(ButtonBehavior, Text):
|
||||
def on_press(self):
|
||||
pass
|
||||
|
||||
class PressableText(ButtonBehavior, Text):
|
||||
def on_press(self):
|
||||
pass
|
||||
|
||||
class FILEDataHandler(EventDispatcher):
|
||||
def __init__(self, url, suffixs=[],params={}):
|
||||
self.url = url
|
||||
@ -577,3 +632,28 @@ class Slider(Carousel):
|
||||
w = bk.widgetBuild(desc)
|
||||
self.add_widget(w)
|
||||
|
||||
i18n = I18n()
|
||||
|
||||
class I18nWidget(PressableText):
|
||||
lang = StringProperty(None)
|
||||
def __init__(self, **kw):
|
||||
super().__init__(**kw)
|
||||
self.lang = i18n.lang
|
||||
|
||||
def on_lang(self, *args):
|
||||
self.otext = self.lang
|
||||
|
||||
def on_press(self, *args):
|
||||
langs = i18n.get_languages()
|
||||
data = [ {'lang':l} for l in langs ]
|
||||
mdd = MyDropDown(textField='lang', valueField='lang',
|
||||
value=self.lang,
|
||||
data=data)
|
||||
mdd.bind(on_select=self.selected_lang)
|
||||
mdd.showme(self)
|
||||
|
||||
def selected_lang(self, o, v):
|
||||
lang = v[0]
|
||||
self.lang = lang
|
||||
i18n.changeLang(self.lang)
|
||||
|
||||
|
@ -15,7 +15,6 @@ def get_cmd_desc(cmd_desc):
|
||||
desc['datamethod'] = v['datamethod']
|
||||
keys = v.keys()
|
||||
if 'url' in keys:
|
||||
Logger.info('get_cmd_desc():cmd_desc=%s', cmd_desc)
|
||||
desc['actiontype'] = 'urlwidget'
|
||||
desc['mode'] = 'replace'
|
||||
options = {
|
||||
@ -24,18 +23,22 @@ def get_cmd_desc(cmd_desc):
|
||||
}
|
||||
desc['options'] = options
|
||||
return desc
|
||||
|
||||
if 'rfname' in keys:
|
||||
desc['actiontype'] = 'registedfunction'
|
||||
desc['params'] = v.get('params',{})
|
||||
return desc
|
||||
|
||||
if 'script' in keys:
|
||||
desc['actiontype'] = 'script'
|
||||
desc['script'] = v.get('script')
|
||||
return desc
|
||||
|
||||
if 'method' in keys:
|
||||
desc['actiontype'] = 'method'
|
||||
desc['method'] = v.get('method')
|
||||
return desc
|
||||
|
||||
if 'actions' in keys:
|
||||
desc['actiontype'] = 'multiple'
|
||||
desc['actions'] = v.get('actions')
|
||||
@ -61,6 +64,6 @@ def cmd_action(cmd_desc, widget):
|
||||
})
|
||||
w.bind(on_conform=partial(blocks.uniaction, widget, desc))
|
||||
w.open()
|
||||
Logger.info('cmd_action():desc=%s, conform and action', desc)
|
||||
print('cmd_action():desc=', desc, ' conform and action', desc)
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ from appPublic.uniqueID import getID
|
||||
from appPublic.myTE import string_template_render
|
||||
|
||||
from .utils import *
|
||||
from .baseWidget import Text, HBox, VBox
|
||||
from .baseWidget import Text, HBox, VBox, Running
|
||||
from .scrollpanel import ScrollPanel
|
||||
from .paging import Paging, RelatedLoader
|
||||
from .ready import WidgetReady
|
||||
@ -64,7 +64,7 @@ class Cell(ButtonBehavior, WidgetCSS, BoxLayout):
|
||||
if self.row.header:
|
||||
self.csscls=self.row.part.datagrid.header_css
|
||||
if desc['header']:
|
||||
bl = Text(i18n=True, text=str(desc['value']),
|
||||
bl = Text(i18n=True, otext=str(desc['value']),
|
||||
font_size=CSize(1),wrap=True,
|
||||
halign='left', valign='middle'
|
||||
)
|
||||
@ -432,7 +432,7 @@ class DataGrid(VBox):
|
||||
desc = {
|
||||
"widgettype":"Text",
|
||||
"options":{
|
||||
"text":n,
|
||||
"otext":n,
|
||||
"i18n":True,
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ class I18n:
|
||||
def __init__(self):
|
||||
self.kvlang={}
|
||||
self.lang = locale.getdefaultlocale()[0]
|
||||
if self.lang is None:
|
||||
self.lang = 'en_US'
|
||||
self.languages = None
|
||||
self.loadI18n(self.lang)
|
||||
self.i18nWidgets = []
|
||||
|
||||
@ -21,8 +24,9 @@ class I18n:
|
||||
self.i18nWidgets.append(ref(w))
|
||||
|
||||
def loadI18nFromI18nFolder(self, lang):
|
||||
config = gtConfig()
|
||||
config = getConfig()
|
||||
fpath = os.path.join(config.i18n_folder,lang,'msg.txt')
|
||||
print('fpath=', fpath, type(fpath))
|
||||
with codecs.open(fpath,'r','utf-8') as f:
|
||||
line = f.readline()
|
||||
d = {}
|
||||
@ -32,15 +36,39 @@ class I18n:
|
||||
continue
|
||||
k,v = line.split(':',1)
|
||||
d.update({k:v})
|
||||
line = readline()
|
||||
line = f.readline()
|
||||
return d
|
||||
|
||||
def get_languages(self):
|
||||
if self.languages:
|
||||
return self.languages
|
||||
self.languages = self.getLanguages()
|
||||
return self.languages
|
||||
|
||||
def getLanguages(self):
|
||||
config = getConfig()
|
||||
if config.i18n_folder:
|
||||
langs = []
|
||||
for f in os.listdir(config.i18n_folder):
|
||||
p = os.path.join(config.i18n_folder, f)
|
||||
if os.path.isdir(p):
|
||||
langs.append(os.path.basename(f))
|
||||
return langs
|
||||
|
||||
if config.i18n_url:
|
||||
url = '%s%s' % (config.uihome, config.i18n_url)
|
||||
hc = HttpClient()
|
||||
d = hc.get(url)
|
||||
if isinstance(d, list):
|
||||
return d
|
||||
return []
|
||||
|
||||
def loadI18n(self,lang):
|
||||
app = App.get_running_app()
|
||||
config = getConfig()
|
||||
self.kvlang[lang] = {}
|
||||
if config.i18n_folder:
|
||||
self.kvlang[lang] = self.loadI18nFromFolder(lang)
|
||||
self.kvlang[lang] = self.loadI18nFromI18nFolder(lang)
|
||||
return
|
||||
|
||||
if config.i18n_url:
|
||||
@ -63,8 +91,8 @@ class I18n:
|
||||
if not d:
|
||||
self.loadI18n(lang)
|
||||
self.lang = lang
|
||||
ws = [ w for w in self.i18nWidgets if w is not None ]
|
||||
ws = [ w for w in self.i18nWidgets if w() is not None ]
|
||||
for w in ws:
|
||||
w().changeLang(lang)
|
||||
self.i18nWidgets = ws
|
||||
for w in self.i18nWidgets:
|
||||
w.changeLang(lang)
|
||||
|
||||
|
@ -5,7 +5,7 @@ from kivy.app import App
|
||||
from kivy.clock import Clock
|
||||
from kivy.factory import Factory
|
||||
from kivy.utils import platform
|
||||
from .baseWidget import VBox, HBox
|
||||
from .baseWidget import VBox, HBox, I18nWidget
|
||||
from .toggleitems import PressableBox
|
||||
from .utils import *
|
||||
from .swipebehavior import SwipeBehavior
|
||||
@ -61,6 +61,7 @@ PagePanel description file format
|
||||
"bar_autohide": true when page is idle
|
||||
"bar_size": bar size in CSize unit
|
||||
"bar_at": "top" or "bottom"
|
||||
"i18n": true of false
|
||||
"bar_css":
|
||||
"panel_css":
|
||||
"left_menu": if defined, it must be a widget instance or a dict
|
||||
@ -136,6 +137,7 @@ sub-widget's description file format
|
||||
"""
|
||||
def __init__(self, bar_size=2,
|
||||
bar_css='default',
|
||||
i18n=False,
|
||||
csscls='default',
|
||||
singlepage=False,
|
||||
fixed_before=None,
|
||||
@ -147,6 +149,7 @@ sub-widget's description file format
|
||||
self.bar_size = bar_size
|
||||
self.bar_autohide = bar_autohide
|
||||
self.bar_at = bar_at
|
||||
self.i18n = i18n
|
||||
self.singlepage = singlepage
|
||||
self.idle_status = False
|
||||
self.idle_threshold = 10
|
||||
@ -218,6 +221,10 @@ sub-widget's description file format
|
||||
})
|
||||
self.bar.add_widget(self.bar_left_menu)
|
||||
self.bar_left_menu.bind(on_press=self.show_left_menu)
|
||||
if self.i18n:
|
||||
self.i18n_w = I18nWidget(size_hint_x=None, width=CSize(5))
|
||||
self.bar.add_widget(self.i18n_w)
|
||||
|
||||
self.bar_title = HBox(csscls=bar_css)
|
||||
self.bar.add_widget(self.bar_title)
|
||||
self.bar_right_menu = VBox(size_hint=(None,None),size=CSize(bcsize,bcsize))
|
||||
|
@ -7,6 +7,7 @@ from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.button import Button
|
||||
from kivy.clock import Clock
|
||||
from kivy.app import App
|
||||
from kivy.properties import BooleanProperty
|
||||
from functools import partial
|
||||
from appPublic.dictObject import DictObject
|
||||
from appPublic.jsonConfig import getConfig
|
||||
@ -40,8 +41,8 @@ it fires two type of event
|
||||
"""
|
||||
|
||||
class PageLoader(EventDispatcher):
|
||||
loading = BooleanProperty(False)
|
||||
def __init__(self,target=None, **options):
|
||||
self.loading = False
|
||||
self.target = target
|
||||
self.options = options
|
||||
self.filter = None
|
||||
@ -72,6 +73,12 @@ class PageLoader(EventDispatcher):
|
||||
self.loader.bind(on_success=self.show_page)
|
||||
self.loader.bind(on_error=self.onerror)
|
||||
|
||||
def on_loading(self, *args):
|
||||
if self.loading:
|
||||
self.running = Running(self.target)
|
||||
else:
|
||||
self.running.dismiss()
|
||||
|
||||
def on_newbegin(self):
|
||||
pass
|
||||
|
||||
|
@ -1 +1 @@
|
||||
__version__ = '0.3.23'
|
||||
__version__ = '0.3.24'
|
||||
|
Loading…
Reference in New Issue
Block a user