diff --git a/pysollib/kivy/LApp.py b/pysollib/kivy/LApp.py index b1c027e2..b9e08761 100644 --- a/pysollib/kivy/LApp.py +++ b/pysollib/kivy/LApp.py @@ -210,6 +210,22 @@ LAnimationManager = LAnimationMgr() # ============================================================================= + +def LAfterAnimation(task, delay=0.0): + def dotask(): # noqa + Clock.schedule_once(lambda dt: task()) + def mkcb(task): # noqa + def cb(dt): + if LAnimationManager.checkRunning(): + LAnimationManager.addEndCallback(dotask) + else: + dotask() + return cb + Clock.schedule_once(mkcb(task), delay) + +# ============================================================================= + + LSoundLoader = SoundLoader # ============================================================================= @@ -1629,16 +1645,13 @@ class LMainWindow(BoxLayout, LTkBase): print("touches cnt = ",len(self.touches)) ''' # multiclick detection - ''' + if touch.is_double_tap: # print('Touch is a double tap !') # print(' - interval is', touch.double_tap_time) # print(' - distance betw. previous is', touch.double_tap_distance) - # test the functions of Android back key - ret = self.processAndroidBack() - if (ret): - return ret - ''' + AndroidScreenRotation.unlock() + ''' if touch.is_triple_tap: print('Touch is a triple tap !') @@ -1736,8 +1749,8 @@ class LMainWindow(BoxLayout, LTkBase): self.workContainer.add_widget(w[1]) def rebuildContainer(self): - self.removeContainer() - self.buildContainer() + LAfterAnimation(self.removeContainer) + LAfterAnimation(self.buildContainer) def pushWork(self, key, widget): if (widget): diff --git a/pysollib/kivy/LImage.py b/pysollib/kivy/LImage.py index 24840969..846fa77b 100644 --- a/pysollib/kivy/LImage.py +++ b/pysollib/kivy/LImage.py @@ -13,11 +13,11 @@ import math # import inspect +from kivy.core.image import Image as CoreImage from kivy.graphics import Color from kivy.graphics import Rectangle from kivy.properties import ObjectProperty from kivy.properties import StringProperty -from kivy.uix.image import Image as KivyImage from kivy.uix.widget import Widget from pysollib.kivy.LBase import LBase @@ -144,7 +144,7 @@ class LImage(Widget, LBase): self.source = None if "source" in kwargs: self.source = kwargs["source"] - image = KivyImage(source=self.source) + image = CoreImage(self.source) self.texture = image.texture # update fit_num from fit_mode (needs self.fit_num defined) @@ -188,6 +188,8 @@ class LImage(Widget, LBase): self.fit_num = self.FILL if fit_mode == "cover": self.fit_num = self.COVER + if fit_mode == "scale-down": + self.fit_num = self.SCALE_DOWN if fit_mode == "scale_down": self.fit_num = self.SCALE_DOWN if fit_mode == "tiling": diff --git a/pysollib/kivy/menubar.py b/pysollib/kivy/menubar.py index 2168918c..f29adabc 100644 --- a/pysollib/kivy/menubar.py +++ b/pysollib/kivy/menubar.py @@ -28,6 +28,7 @@ import re from kivy.cache import Cache from kivy.clock import Clock +from kivy.core.window import Window from pysollib.gamedb import GI from pysollib.kivy.LApp import LMenu @@ -1153,24 +1154,24 @@ class LOptionsMenuGenerator(LTreeGenerator): self.addRadioNode(tv, rg, _('Hide'), self.menubar.tkopt.toolbar, 0, - self.menubar.mOptToolbar) + self.menubar.setToolbarPos) self.addRadioNode(tv, rg, _('Top'), self.menubar.tkopt.toolbar, 1, - self.menubar.mOptToolbar) + self.menubar.setToolbarPos) self.addRadioNode(tv, rg, _('Bottom'), self.menubar.tkopt.toolbar, 2, - self.menubar.mOptToolbar) + self.menubar.setToolbarPos) self.addRadioNode(tv, rg, _('Left'), self.menubar.tkopt.toolbar, 3, - self.menubar.mOptToolbar) + self.menubar.setToolbarPos) self.addRadioNode(tv, rg, _('Right'), self.menubar.tkopt.toolbar, 4, - self.menubar.mOptToolbar) + self.menubar.setToolbarPos) rg1 = tv.add_node( LTreeNode(text=_('Visible buttons')), rg) @@ -1406,24 +1407,20 @@ class DictObjMap(object): class PysolMenubarTk: def __init__(self, app, top, progress=None): print('PysolMenubarTk: __init__()') + self.top = top + self.app = app + self._createTkOpt() self._setOptions() - # init columnbreak -# self.__cb_max = int(self.top.winfo_screenheight()/23) + self.__cb_max = 8 -# sh = self.top.winfo_screenheight() -# self.__cb_max = 22 -# if sh >= 600: self.__cb_max = 27 -# if sh >= 768: self.__cb_max = 32 -# if sh >= 1024: self.__cb_max = 40 self.progress = progress + # create menus self.__menubar = None self.__menupath = {} self.__keybindings = {} self._createMenubar() - self.top = top - self.app = app if self.progress: self.progress.update(step=1) @@ -1506,6 +1503,8 @@ class PysolMenubarTk: flip_animation=LBoolWrap(opt, "flip_animation"), # toolbar toolbar=LNumWrap(opt, "toolbar"), + toolbar_land=LNumWrap(opt, "toolbar_land", self.mOptToolbar), + toolbar_port=LNumWrap(opt, "toolbar_port", self.mOptToolbar), toolbar_style=LStringWrap(opt, "toolbar_style"), toolbar_relief=LStringWrap(opt, "toolbar_relief"), toolbar_compound=LStringWrap(opt, "toolbar_compound"), @@ -1552,6 +1551,20 @@ class PysolMenubarTk: def _setOptions(self): # not supported self.tkopt.save_games_geometry.value = False + self.getToolbarPos(None, Window.size) + Window.bind(size=self.getToolbarPos) + + def getToolbarPos(self, obj, size): + if (size[0] > size[1]): + self.tkopt.toolbar.value = self.tkopt.toolbar_land.value + else: + self.tkopt.toolbar.value = self.tkopt.toolbar_port.value + + def setToolbarPos(self, *args): + if (Window.size[0] > Window.size[1]): + self.tkopt.toolbar_land.value = self.tkopt.toolbar.value + else: + self.tkopt.toolbar_port.value = self.tkopt.toolbar.value def connectGame(self, game): self.game = game @@ -2375,7 +2388,7 @@ the next time you restart the %(app)s""") % {'app': TITLE}) self._mOptCardback(self.app.cardset.backindex + 1) def mOptToolbar(self, *event): - self.setToolbarSide(self.tkopt.toolbar.value) + self.app.toolbar.show() def mOptToolbarStyle(self, *event): self.setToolbarStyle(self.tkopt.toolbar_style.value) @@ -2428,12 +2441,6 @@ the next time you restart the %(app)s""") % {'app': TITLE}) # toolbar support # - def setToolbarSide(self, side): - if self._cancelDrag(break_pause=False): - return - resize = not self.app.opt.save_games_geometry - self.app.toolbar.show(side, resize=resize) - def setToolbarSize(self, size): if self._cancelDrag(break_pause=False): return diff --git a/pysollib/kivy/tkutil.py b/pysollib/kivy/tkutil.py index 8c3f5b6a..da93a725 100644 --- a/pysollib/kivy/tkutil.py +++ b/pysollib/kivy/tkutil.py @@ -31,7 +31,6 @@ import logging import os from array import array -from kivy.clock import Clock from kivy.core.image import Image as CoreImage from kivy.core.text import Label as CoreLabel from kivy.graphics.texture import Texture @@ -179,22 +178,16 @@ def unbind_destroy(widget): # * timer wrapper - Tkinter doesn't properly delete all commands # ************************************************************************ + def after(widget, ms, func, *args): # print('tkutil: after(%s, %s, %s, %s)' % (widget, ms, func, args)) - if (ms == 'idle'): + if (ms == 'demo'): print('demo use') - def mkcb(func): - def cb(): - Clock.schedule_once(lambda dt: func(), 0.5) - return cb + from pysollib.kivy.LApp import LAfterAnimation + LAfterAnimation(func, 0.6) + return - from pysollib.kivy.LApp import LAnimationManager - if LAnimationManager.checkRunning(): - # run after animation terminated - LAnimationManager.addEndCallback(mkcb(func)) - else: - Clock.schedule_once(lambda dt: func(), 0.5) elif (isinstance(ms, int)): # print('ms: play timer (accounting)') # Clock.schedule_once(lambda dt: func(), float(ms)/1000.0) @@ -203,8 +196,9 @@ def after(widget, ms, func, *args): def after_idle(widget, func, *args): - # print('tkutil: after_idle()') - return after(widget, "idle", func, *args) + # NOTE: This is called from the core in demo mode only. + # 'func' executes the next step in the game. + return after(widget, "demo", func, *args) def after_cancel(t): diff --git a/pysollib/kivy/toolbar.py b/pysollib/kivy/toolbar.py index f8c4b6dd..36e423ee 100644 --- a/pysollib/kivy/toolbar.py +++ b/pysollib/kivy/toolbar.py @@ -23,11 +23,11 @@ import os from kivy.cache import Cache from kivy.clock import Clock +from kivy.core.image import Image as CoreImage from kivy.core.window import Window from kivy.properties import BooleanProperty from kivy.uix.behaviors import ButtonBehavior from kivy.uix.boxlayout import BoxLayout -from kivy.uix.image import Image as KivyImage # PySol kivy imports from pysollib.kivy.LBase import LBase @@ -39,10 +39,10 @@ from pysollib.mygettext import _, n_ # noqa from pysollib.util import IMAGE_EXTENSIONS from pysollib.winsystems import TkSettings - # ************************************************************************ -class MyButtonBase(ButtonBehavior, KivyImage, LBase): + +class MyButtonBase(ButtonBehavior, LImage, LBase): shown = BooleanProperty(True) enabled = BooleanProperty(True) config = BooleanProperty(True) @@ -58,8 +58,10 @@ class MyButtonBase(ButtonBehavior, KivyImage, LBase): self.name = "" if ('name' in kwargs): self.name = kwargs['name'] - self.source = self.src - self.allow_stretch = True + + image = CoreImage(self.src) + self.texture = image.texture + self.fit_mode = "contain" def set_enabled(self, instance, value): # print ('** set enabled (',self.name ,') called', value) @@ -75,10 +77,11 @@ class MyButton(MyButtonBase): super(MyButton, self).__init__(**kwargs) def on_press(self): - self.allow_stretch = False + self.fit_mode = "scale-down" + pass def on_release(self): - self.allow_stretch = True + self.fit_mode = "contain" if (self.command is not None): self.command() @@ -100,9 +103,9 @@ class MyCheckButton(MyButtonBase): def updateState(self, obj, val): if (val): - self.allow_stretch = False + self.fit_mode = "scale-down" else: - self.allow_stretch = True + self.fit_mode = "contain" def isChecked(self): return self.checked @@ -125,12 +128,12 @@ class MyCheckButton(MyButtonBase): # mb = self.win.app.menubar if game.pause: - self.allow_stretch = True + self.fit_mode = "contain" self.checked = False if (self.command is not None): self.command() else: - self.allow_stretch = False + self.fit_mode = "scale-down" self.checked = True if (self.command is not None): self.command() @@ -151,7 +154,7 @@ class MyToastButton(MyButtonBase): self.command() def on_press(self): - self.allow_stretch = False + self.fit_mode = "scale-down" text = "" if self.name == "new": text = _("New game") @@ -163,7 +166,7 @@ class MyToastButton(MyButtonBase): hook=self.exec_command) def on_release(self): - self.allow_stretch = True + self.fit_mode = "contain" class MyWaitButton(MyButtonBase): @@ -196,12 +199,12 @@ class MyWaitButton(MyButtonBase): Clock.schedule_once(self.okstart, 0.1) def on_press(self): - self.allow_stretch = False + self.fit_mode = "scale-down" self.eventId = Clock.schedule_once(self.holdend, self.timeout) self.make_toast(_("hold on ...")) def on_release(self): - self.allow_stretch = True + self.fit_mode = "contain" if self.eventId is not None: Clock.unschedule(self.eventId) self.clear_toast() @@ -299,22 +302,26 @@ class PysolToolbarTk(BoxLayout): def doResize(self, *args): self.show(True) - def show(self, on, **kw): - side = self.menubar.tkopt.toolbar.value + def show(self, on=0, **kw): + + landscape = Window.width/Window.height > 1.0 + if landscape: + side = self.menubar.tkopt.toolbar_land.value + else: + side = self.menubar.tkopt.toolbar_port.value + self.win.setTool(None, side) # size_hint dependent on screen orientation: - asp = Window.width/Window.height - if side in [1, 2]: self.orientation = "horizontal" - if asp > 1.0: + if landscape: self.size_hint = (1.0, 0.09) else: self.size_hint = (1.0, 0.06) else: self.orientation = "vertical" - if asp > 1.0: + if landscape: self.size_hint = (0.06, 1.0) else: self.size_hint = (0.09, 1.0) diff --git a/pysollib/options.py b/pysollib/options.py index b2aefc94..6881cde5 100644 --- a/pysollib/options.py +++ b/pysollib/options.py @@ -103,6 +103,8 @@ tree_icon_style = string tile_theme = string default_tile_theme = string toolbar = integer(0, 4) +toolbar_land = integer(0, 4) +toolbar_port = integer(0, 4) toolbar_style = string toolbar_relief = string toolbar_compound = string @@ -271,6 +273,8 @@ class Options: ('tile_theme', 'str'), ('default_tile_theme', 'str'), ('toolbar', 'int'), + ('toolbar_land', 'int'), + ('toolbar_port', 'int'), ('toolbar_style', 'str'), ('toolbar_relief', 'str'), ('toolbar_compound', 'str'), @@ -374,10 +378,13 @@ class Options: self.tree_icon_style = 'remix' self.tile_theme = 'default' self.default_tile_theme = 'default' - self.toolbar = 1 # 0 == hide, 1,2,3,4 == top, bottom, lef, right + self.toolbar = 1 # 0 == hide, 1,2,3,4 == top, bottom, left, right + # used with 'kivy' version in addition: + self.toolbar_land = 4 # (landscape) + self.toolbar_port = 2 # (portrait) + # 0 == hide, + # 1,2,3,4 == top, bottom, left, right # self.toolbar_style = 'default' - if TOOLKIT == 'kivy': - self.toolbar = 4 # 0 == hide, 1,2,3,4 == top, bottom, lef, right self.toolbar_style = 'remix' self.toolbar_relief = 'flat' self.toolbar_compound = 'none' # icons only diff --git a/setup.cfg b/setup.cfg index 8b77a7fe..1628f772 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,7 +7,7 @@ use_bzip2 = 1 [flake8] extend-ignore = H101,H104,H201,H237,H301,H306,H403,H404,H405, # remove some most ugly flakes (proposal) - # E231,E302,E741 + # E231,E302,E305,E741,W293 [sdist] force_manifest = 1