1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

toolbar updates ()

- quit button removed, makes no sense with kivy/android version
- shuffle/autodrop button managed dynamically
- delayed execution on new and restart buttons, to prevent
  accicental activation while playing
This commit is contained in:
lufebe16 2023-09-19 15:03:31 +02:00
parent 187bae25cb
commit 158c3137fd
5 changed files with 194 additions and 85 deletions

View file

@ -430,6 +430,16 @@ class Application:
self.toolbar.config(
'shuffle',
self.opt.toolbar_vars['shuffle'] and self.game.canShuffle())
if TOOLKIT == 'kivy':
self.toolbar.config(
'undo',
self.opt.toolbar_vars['undo'] and self.game.canUndo())
self.toolbar.config(
'undo',
self.opt.toolbar_vars['redo'] and self.game.canRedo())
self.toolbar.config(
'autodrop',
self.opt.toolbar_vars['autodrop'] and not self.game.canShuffle()) # noqa
# delete intro progress bar
if self.intro.progress:
self.intro.progress.destroy()

View file

@ -44,6 +44,7 @@ from kivy.uix.actionbar import ActionPrevious
from kivy.uix.actionbar import ActionView
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image as KivyImage
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
@ -1814,7 +1815,9 @@ class LApp(App):
# Config.set('input', 'multitouchscreen1', 'tuio,0.0.0.0:3333')
self.baseWindow = FloatLayout() # needed e.g. for toasts
self.mainWindow = LMainWindow()
self.baseWindow.add_widget(self.mainWindow)
logging.info('top = %s' % str(self.mainWindow))
Cache.register('LAppCache', limit=10)
Cache.append('LAppCache', 'mainWindow', self.mainWindow, timeout=0)

68
pysollib/kivy/toast.py Normal file
View file

@ -0,0 +1,68 @@
# ================================================================
# flake8: noqa
# Toast implementation
# LB230919
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.uix.label import Label
from kivy.graphics import Color
from kivy.graphics.vertex_instructions import RoundedRectangle
# ================================================================
class Toast(Label):
def __init__(self, **kw):
super().__init__(opacity=0, **kw)
self.duration = 4.0
self.tsize = self.size
self.rsize = 20
with self.canvas.before:
Color(0.2, 0.2, 0.2, 0.8)
self.rect = RoundedRectangle()
self.bind(size=self._update_rect)
self.bind(texture_size=self.eval_size)
def eval_size(self,instance,size):
width, height = size
if width > self.parent.width:
instance.text_size = (self.parent.width, None)
instance.texture_update()
width, height = instance.texture_size
ads = height * 1.7
self.tsize = (width + ads, height + ads)
self.rsize = [(ads+height)/2.0,]
#print(self.tsize,self.rsize)
def _update_rect(self, instance, value):
self.rect.size = self.tsize
self.rect.pos = (instance.center_x-self.tsize[0]/2.0,instance.center_y-self.tsize[1]/2.0)
self.rect.radius = self.rsize
def stop(self, *args):
self.parent.remove_widget(self)
def hide(self, *args):
anim = Animation(opacity=0, duration=0.4)
anim.bind(on_complete=self.stop)
anim.start(self)
# Timed display with fadein/-out
def show(self, parent=None, duration=2.0):
if parent is None:
return
self.duration = duration
parent.add_widget(self)
anim = Animation(opacity=1, duration=0.4)
anim.start(self)
Clock.schedule_once(self.hide,self.duration)
# Popup display - use 'stop' to terminate.
def start(self,parent=None):
if parent is None:
return
self.opacity = 1
parent.add_widget(self)
# ================================================================

View file

@ -20,10 +20,10 @@
# imports
import os
from time import time
# PySol imports
from pysollib.mygettext import _, n_
from pysollib.settings import TITLE
from pysollib.util import IMAGE_EXTENSIONS
from pysollib.winsystems import TkSettings
@ -31,64 +31,36 @@ from pysollib.winsystems import TkSettings
# *
# ************************************************************************
class AbstractToolbarButton:
def __init__(self, parent, toolbar, toolbar_name, position):
self.toolbar = toolbar
self.toolbar_name = toolbar_name
self.position = position
self.visible = False
def show(self, orient, force=False):
if self.visible and not force:
return
self.visible = True
padx, pady = 2, 2
if orient == 'horizontal':
self.grid(row=0,
column=self.position,
ipadx=padx, ipady=pady,
sticky='nsew')
else:
self.grid(row=self.position,
column=0,
ipadx=padx, ipady=pady,
sticky='nsew')
def hide(self):
if not self.visible:
return
self.visible = False
self.grid_forget()
from pysollib.kivy.LApp import LImage
from pysollib.kivy.LApp import LBase
from pysollib.kivy.toast import Toast
# from LApp import LMainWindow
from kivy.uix.boxlayout import BoxLayout
# from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
# from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.image import Image as KivyImage
# ************************************************************************
if True:
from pysollib.kivy.LApp import LImage
from pysollib.kivy.LApp import LBase
# from LApp import LMainWindow
from kivy.uix.boxlayout import BoxLayout
# from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
# from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.image import Image as KivyImage
# ************************************************************************
from kivy.cache import Cache
class MyButton(ButtonBehavior, KivyImage, LBase):
def __init__(self, **kwargs):
super(MyButton, self).__init__(**kwargs)
# super(MyButton, self).__init__()
self.src = None
if ('image' in kwargs):
self.src = kwargs['image'].source
self.command = None
if ('command' in kwargs):
self.command = kwargs['command']
self.name = ""
if ('name' in kwargs):
self.name = kwargs['name']
self.source = self.src
self.allow_stretch = True
self.shown = True
def on_press(self):
self.allow_stretch = False
@ -102,13 +74,15 @@ class MyButton(ButtonBehavior, KivyImage, LBase):
class MyCheckButton(ButtonBehavior, KivyImage, LBase):
def __init__(self, **kwargs):
super(MyCheckButton, self).__init__(**kwargs)
# super(MyCheckButton, self).__init__()
self.src = None
if ('image' in kwargs):
self.src = kwargs['image'].source
self.command = None
if ('command' in kwargs):
self.command = kwargs['command']
self.name = ""
if ('name' in kwargs):
self.name = kwargs['name']
self.variable = None
if ('variable' in kwargs):
self.variable = kwargs['variable']
@ -118,6 +92,7 @@ class MyCheckButton(ButtonBehavior, KivyImage, LBase):
self.source = self.src
self.allow_stretch = True
self.checked = False
self.shown = True
# self.variable = self.win.app.menubar.tkopt.pause
if self.variable:
@ -163,6 +138,44 @@ class MyCheckButton(ButtonBehavior, KivyImage, LBase):
def on_release(self):
pass
class MyToastButton(ButtonBehavior, KivyImage, LBase):
def __init__(self, **kwargs):
super(MyToastButton, self).__init__(**kwargs)
self.src = None
if ('image' in kwargs):
self.src = kwargs['image'].source
self.command = None
if ('command' in kwargs):
self.command = kwargs['command']
self.name = ""
if ('name' in kwargs):
self.name = kwargs['name']
self.timeout = 0.0
if ('timeout' in kwargs):
self.timeout = kwargs['timeout']
self.source = self.src
self.allow_stretch = True
self.shown = True
self.start_time = 0.0
def on_press(self):
self.allow_stretch = False
self.start_time = time()
def on_release(self):
self.allow_stretch = True
delta = time()-self.start_time
if (self.command is not None):
if delta > self.timeout:
self.command()
else:
mainApp = Cache.get('LAppCache', 'mainApp')
toast = Toast(text=_("button released too early"))
toast.show(parent=mainApp.baseWindow, duration=2.0)
# print('too early released')
# ************************************************************************
# * Note: Applications should call show/hide after constructor.
# ************************************************************************
@ -179,15 +192,31 @@ class PysolToolbarTk(BoxLayout):
compound='none'):
super(PysolToolbarTk, self).__init__(orientation='vertical')
self.size_hint = (0.05, 1.0)
self.size_hint = (0.06, 1.0)
# self.size_hint=(None, 1.0)
# self.width = 50
self.win = top
self.menubar = menubar
self.dir = dir
self.win.setTool(self, 3)
self.buttons = []
for label, f, t in (
# This is called only once after program start. Configurations
# have to take place elsewhere.
bl = []
bl.append((n_("New"), self.mNewGame, _("New game")))
bl.append((n_("Restart"), self.mRestart, _("Restart the\ncurrent game"))) # noqa
bl.append((n_("Undo"), self.mUndo, _("Undo last move"))) # noqa
bl.append((n_("Redo"), self.mRedo, _("Redo last move")))
bl.append((n_("Autodrop"), self.mDrop, _("Auto drop cards")))
bl.append((n_("Shuffle"), self.mShuffle, _("Shuffle tiles")))
bl.append((n_("Hint"), self.mHint, _("Hint")))
bl.append((n_("Pause"), self.mPause, _("Pause game")))
bl.append((n_("Rules"), self.mHelpRules, _("Rules for this game")))
'''
for label, f, t in [
(n_("New"), self.mNewGame, _("New game")),
(n_("Restart"), self.mRestart, _("Restart the\ncurrent game")),
(None, None, None),
@ -205,40 +234,27 @@ class PysolToolbarTk(BoxLayout):
(n_("Rules"), self.mHelpRules, _("Rules for this game")),
(None, None, None),
(n_("Quit"), self.mHoldAndQuit, _("Quit %s") % TITLE),
):
]:
'''
for label, f, t in bl:
if label is None:
# sep = self._createSeparator()
# sep.bind("<1>", self.clickHandler)
# sep.bind("<3>", self.rightclickHandler)
# We dont have separators in kivy version.
pass
elif label == 'Pause':
self._createButton(label, f, check=True, tooltip=t)
button = self._createButton(label, f, check=True, tooltip=t)
self.buttons.append(button)
elif label in ["New", "Restart"]:
button = self._createButton(label, f, check=False, tooltip=t, timeout=1.0) # noqa
self.buttons.append(button)
else:
self._createButton(label, f, tooltip=t)
# hier gibt es noch ein 'player label' mit contextmenu, wo
# der spielername gewählt und die spielstatistik etc.
# angezeigt werden könnte (TBD):
'''
sep = self._createFlatSeparator()
sep.bind("<1>", self.clickHandler)
sep.bind("<3>", self.rightclickHandler)
self._createLabel("player", label=n_('Player'),
tooltip=_("Player options"))
#
self.player_label.bind("<1>", self.mOptPlayerOptions)
# self.player_label.bind("<3>", self.mOptPlayerOptions)
self.popup = MfxMenu(master=None, label=n_('Toolbar'), tearoff=0)
createToolbarMenu(menubar, self.popup)
self.frame.bind("<1>", self.clickHandler)
self.frame.bind("<3>", self.rightclickHandler)
#
self.setCompound(compound, force=True)
'''
button = self._createButton(label, f, check=False, tooltip=t)
self.buttons.append(button)
def show(self, on, **kw):
side = self.menubar.tkopt.toolbar.get()
self.win.setTool(None, side)
print('******** toolbar show', on, side, kw)
return False
def mHoldAndQuit(self, *args):
@ -253,9 +269,23 @@ class PysolToolbarTk(BoxLayout):
pass
def config(self, w, v):
print('PysolToolbarTk: config %s, %s' % (w, v))
# y = self.yy
pass
print('********************* PysolToolbarTk: config %s, %s' % (w, v))
# This is the position, where the toolbar can be configured.
chgd = False
for b in self.buttons:
if b.name == w:
ov = b.shown
if v != ov:
b.shown = v
chgd = True
if chgd:
self.clear_widgets()
for b in self.buttons:
if b.shown:
self.add_widget(b)
# Lokale.
@ -267,11 +297,10 @@ class PysolToolbarTk(BoxLayout):
if os.path.isfile(file):
image = LImage(source=file)
# print('_loadImage: file=%s' % file)
# image = Tkinter.PhotoImage(file=file)
break
return image
def _createButton(self, label, command, check=False, tooltip=None):
def _createButton(self, label, command, check=False, tooltip=None, timeout=0.0): # noqa
name = label.lower()
image = self._loadImage(name)
# position = len(self._widgets)
@ -289,27 +318,26 @@ class PysolToolbarTk(BoxLayout):
'padx': padx,
'pady': pady,
'overrelief': 'raised',
'timeout': timeout
}
# print ('toolbar: print %s' % self.win)
# print ('toolbar: print %s' % self.win.app)
kw['win'] = self.win
if image:
kw['image'] = image
if name:
kw['name'] = name
if check:
kw['offrelief'] = button_relief
kw['indicatoron'] = False
kw['selectcolor'] = ''
button = MyCheckButton(**kw)
elif timeout > 0.0:
button = MyToastButton(**kw)
else:
button = MyButton(**kw)
# button.show(orient=self.orient)
setattr(self, name + "_image", image)
setattr(self, name + "_button", button)
# self._widgets.append(button)
self.add_widget(button)
# TBD: tooltip ev. auf basis einer statuszeile implementieren
# if tooltip:
# b = MfxTooltip(button)

View file

@ -431,11 +431,11 @@ if TOOLKIT == 'kivy':
logging.info("KivyApp: build")
self.app = app = Application()
app.top = self.mainWindow
app.top = self.baseWindow
self.startCode = pysol_init(app, self.args)
logging.info('Main: App Initialised - starting main loop')
return self.mainWindow
return self.baseWindow
def main(args=None):
logging.basicConfig(level=logging.INFO)