mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
Kivy Version card placement revised, fixes:
- Mahjongg tile overlapping (3d simulation) implemented - Animation is now synchronised (so as the tk version does)- This prevents some stacking order corruptions reported earlier.
This commit is contained in:
parent
48f8a70989
commit
5c51f927eb
5 changed files with 126 additions and 36 deletions
|
@ -1450,6 +1450,23 @@ class Game(object):
|
||||||
# 10 - used internally in game preview
|
# 10 - used internally in game preview
|
||||||
if self.app.opt.animations == 0 or frames == 0:
|
if self.app.opt.animations == 0 or frames == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if TOOLKIT == 'kivy':
|
||||||
|
from kivy.base import EventLoop
|
||||||
|
if tkraise:
|
||||||
|
for card in cards:
|
||||||
|
card.tkraise()
|
||||||
|
c0 = cards[0]
|
||||||
|
dx, dy = (x - c0.x), (y - c0.y)
|
||||||
|
for card in cards:
|
||||||
|
base = float(self.app.opt.animations)
|
||||||
|
duration = base*0.1
|
||||||
|
card.animatedMove(dx, dy, duration)
|
||||||
|
for card in cards:
|
||||||
|
while card.animationIsRunning():
|
||||||
|
EventLoop.idle()
|
||||||
|
return
|
||||||
|
|
||||||
# init timer - need a high resolution for this to work
|
# init timer - need a high resolution for this to work
|
||||||
clock, delay, skip = None, 1, 1
|
clock, delay, skip = None, 1, 1
|
||||||
if self.app.opt.animations >= 2:
|
if self.app.opt.animations >= 2:
|
||||||
|
@ -1476,16 +1493,8 @@ class Game(object):
|
||||||
if shadow < 0:
|
if shadow < 0:
|
||||||
shadow = self.app.opt.shadow
|
shadow = self.app.opt.shadow
|
||||||
shadows = ()
|
shadows = ()
|
||||||
# start animation
|
|
||||||
if TOOLKIT == 'kivy':
|
|
||||||
c0 = cards[0]
|
|
||||||
dx, dy = (x - c0.x), (y - c0.y)
|
|
||||||
for card in cards:
|
|
||||||
base = float(self.app.opt.animations)
|
|
||||||
duration = base*0.1
|
|
||||||
card.animatedMove(dx, dy, duration)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
# start animation
|
||||||
if tkraise:
|
if tkraise:
|
||||||
for card in cards:
|
for card in cards:
|
||||||
card.tkraise()
|
card.tkraise()
|
||||||
|
|
|
@ -211,11 +211,11 @@ class Mahjongg_RowStack(OpenStack):
|
||||||
elif TOOLKIT == 'kivy':
|
elif TOOLKIT == 'kivy':
|
||||||
rows = [s for s in self.game.s.rows[:self.id] if s.cards]
|
rows = [s for s in self.game.s.rows[:self.id] if s.cards]
|
||||||
if rows:
|
if rows:
|
||||||
# self.group.tkraise(rows[-1].group)
|
self.group.tkraise(rows[-1].group)
|
||||||
return
|
return
|
||||||
rows = [s for s in self.game.s.rows[self.id+1:] if s.cards]
|
rows = [s for s in self.game.s.rows[self.id+1:] if s.cards]
|
||||||
if rows:
|
if rows:
|
||||||
# self.group.lower(rows[0].group)
|
self.group.lower(rows[0].group)
|
||||||
return
|
return
|
||||||
elif TOOLKIT == 'gtk':
|
elif TOOLKIT == 'gtk':
|
||||||
# FIXME (this is very slow)
|
# FIXME (this is very slow)
|
||||||
|
|
|
@ -765,6 +765,9 @@ class LImageItem(BoxLayout, LBase):
|
||||||
# ev. noch globales cache für stacks->game und cards->stack
|
# ev. noch globales cache für stacks->game und cards->stack
|
||||||
# einrichten. Aber: stacks hängt vom jeweiligen spiel ab.
|
# einrichten. Aber: stacks hängt vom jeweiligen spiel ab.
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'<LImageItem @ {hex(id(self))}>'
|
||||||
|
|
||||||
def send_event_pressed_n(self, event, n):
|
def send_event_pressed_n(self, event, n):
|
||||||
if self.group and n in self.group.bindings:
|
if self.group and n in self.group.bindings:
|
||||||
self.group.bindings[n](event)
|
self.group.bindings[n](event)
|
||||||
|
|
|
@ -125,6 +125,9 @@ class _OneImageCard(_HideableCard):
|
||||||
def animatedMove(self, dx, dy, duration=0.2):
|
def animatedMove(self, dx, dy, duration=0.2):
|
||||||
self.item.animatedMove(dx, dy, duration)
|
self.item.animatedMove(dx, dy, duration)
|
||||||
|
|
||||||
|
def animationIsRunning(self):
|
||||||
|
return self.item.animation
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
# * New idea since 3.00
|
# * New idea since 3.00
|
||||||
# *
|
# *
|
||||||
|
|
|
@ -129,14 +129,80 @@ def subAnchorOffset(pos, anchor, size):
|
||||||
|
|
||||||
class MfxCanvasGroup():
|
class MfxCanvasGroup():
|
||||||
def __init__(self, canvas, tag=None):
|
def __init__(self, canvas, tag=None):
|
||||||
# logging.info('MfxCanvasGroup: __init__() %s - %s' %
|
# print(self, '__init__(', canvas, tag, ')')
|
||||||
# (str(canvas), str(tag)))
|
|
||||||
self.canvas = canvas
|
self.canvas = canvas
|
||||||
self.bindings = {}
|
self.bindings = {}
|
||||||
self.stack = None
|
self.stack = None
|
||||||
|
|
||||||
def tkraise(self):
|
def __str__(self):
|
||||||
pass
|
return f'<MfxCanvasGroup @ {hex(id(self))}>'
|
||||||
|
|
||||||
|
def _imglist(self, group):
|
||||||
|
ilst = []
|
||||||
|
for w in reversed(group.canvas.children):
|
||||||
|
if isinstance(w, LImageItem):
|
||||||
|
if w.group == group:
|
||||||
|
ilst.append(w)
|
||||||
|
# damit is 0 das unterste image und -1 das oberste.
|
||||||
|
return ilst
|
||||||
|
|
||||||
|
def tkraise(self, position=None):
|
||||||
|
# print(self, ' tkraise(', position, ')')
|
||||||
|
# Das wird bei Mahjongg extensiv aufgerufen, wenn der Move
|
||||||
|
# abeschlossen ist. Wird aber auch bei andern games benutzt.
|
||||||
|
|
||||||
|
imgs = self._imglist(self)
|
||||||
|
if position is not None:
|
||||||
|
# In self.canvas suchen: das oberste image, welches zu position
|
||||||
|
# gehört und liste der images oberhalb einfüllen u.a.a.O weglassen.
|
||||||
|
|
||||||
|
pimgs = self._imglist(position)
|
||||||
|
ws = []
|
||||||
|
for c in reversed(self.canvas.children):
|
||||||
|
if c not in imgs:
|
||||||
|
ws.append(c)
|
||||||
|
if c == pimgs[-1]:
|
||||||
|
ws.extend(imgs)
|
||||||
|
self.canvas.clear_widgets()
|
||||||
|
for w in ws:
|
||||||
|
self.canvas.add_widget(w)
|
||||||
|
else:
|
||||||
|
# alle images in dieser gruppe ganz nach oben
|
||||||
|
ws = []
|
||||||
|
for c in reversed(self.canvas.children):
|
||||||
|
if c not in imgs:
|
||||||
|
ws.append(c)
|
||||||
|
ws.extend(imgs)
|
||||||
|
self.canvas.clear_widgets()
|
||||||
|
for w in ws:
|
||||||
|
self.canvas.add_widget(w)
|
||||||
|
|
||||||
|
def lower(self, position=None):
|
||||||
|
# print(self, ' lower(', position, ')')
|
||||||
|
# dasselbe wi tkraise aber vorher statt nachher einfügen.
|
||||||
|
|
||||||
|
imgs = self._imglist(self)
|
||||||
|
if position is not None:
|
||||||
|
pimgs = self._imglist(position)
|
||||||
|
ws = []
|
||||||
|
for c in reversed(self.canvas.children):
|
||||||
|
if c == pimgs[0]:
|
||||||
|
ws.extend(imgs)
|
||||||
|
if c not in imgs:
|
||||||
|
ws.append(c)
|
||||||
|
self.canvas.clear_widgets()
|
||||||
|
for w in ws:
|
||||||
|
self.canvas.add_widget(w)
|
||||||
|
else:
|
||||||
|
# alle images in dieser gruppe ganz nach unten ???
|
||||||
|
ws = imgs
|
||||||
|
for c in reversed(self.canvas.children):
|
||||||
|
if c not in imgs:
|
||||||
|
ws.append(c)
|
||||||
|
self.canvas.clear_widgets()
|
||||||
|
for w in ws:
|
||||||
|
self.canvas.add_widget(w)
|
||||||
|
|
||||||
def addtag(self, tag, option="withtag"):
|
def addtag(self, tag, option="withtag"):
|
||||||
# logging.info('MfxCanvasGroup: addtag(%s, %s)' % (tag, option))
|
# logging.info('MfxCanvasGroup: addtag(%s, %s)' % (tag, option))
|
||||||
|
@ -170,6 +236,7 @@ class MfxCanvasImage(object):
|
||||||
|
|
||||||
# print ('MfxCanvasImage: %s | %s | %s' % (canvas, args, kwargs))
|
# print ('MfxCanvasImage: %s | %s | %s' % (canvas, args, kwargs))
|
||||||
|
|
||||||
|
self.group = None
|
||||||
group = None
|
group = None
|
||||||
if 'group' in kwargs:
|
if 'group' in kwargs:
|
||||||
group = kwargs['group']
|
group = kwargs['group']
|
||||||
|
@ -184,6 +251,11 @@ class MfxCanvasImage(object):
|
||||||
if 'hint' in kwargs:
|
if 'hint' in kwargs:
|
||||||
self.hint = kwargs['hint']
|
self.hint = kwargs['hint']
|
||||||
|
|
||||||
|
# print ('MfxCanvasImage: group = %s ' % (group))
|
||||||
|
# wir kommen üblicherweise aus Card.__init__(). und da ist keine
|
||||||
|
# group (group wird über addtag gesetzt, sobald das image
|
||||||
|
# in einem stack ist.)
|
||||||
|
|
||||||
super(MfxCanvasImage, self).__init__()
|
super(MfxCanvasImage, self).__init__()
|
||||||
self.canvas = canvas
|
self.canvas = canvas
|
||||||
self.animation = None
|
self.animation = None
|
||||||
|
@ -223,27 +295,31 @@ class MfxCanvasImage(object):
|
||||||
print('MfxCanvasImage: __del__(%s)' % self.image)
|
print('MfxCanvasImage: __del__(%s)' % self.image)
|
||||||
self.canvas.clear_widgets([self.image])
|
self.canvas.clear_widgets([self.image])
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'<MfxCanvasImage @ {hex(id(self))}>'
|
||||||
|
|
||||||
def config(self, **kw):
|
def config(self, **kw):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def tkraise(self, aboveThis=None):
|
def tkraise(self, aboveThis=None):
|
||||||
# print('MfxCanvasImage: tkraise')
|
print(self, ': tkraise, above =', aboveThis)
|
||||||
|
|
||||||
abitm = None
|
abitm = None
|
||||||
if aboveThis:
|
if aboveThis:
|
||||||
abitm = aboveThis.widget
|
if isinstance(aboveThis, MfxCanvasImage):
|
||||||
if not self.animation:
|
abitm = aboveThis.widget
|
||||||
self.canvas.tag_raise(self.image, abitm)
|
if isinstance(aboveThis, LImageItem):
|
||||||
pass
|
abitm = aboveThis
|
||||||
|
self.canvas.tag_raise(self.image, abitm)
|
||||||
|
|
||||||
def addtag(self, tag):
|
def addtag(self, tag):
|
||||||
# print('MfxCanvasImage: addtag %s' % tag)
|
print('MfxCanvasImage: addtag %s' % tag.stack)
|
||||||
self.group = tag
|
self.group = tag
|
||||||
if (self.image):
|
if (self.image):
|
||||||
self.image.group = tag
|
self.image.group = tag
|
||||||
pass
|
|
||||||
|
|
||||||
def dtag(self, tag):
|
def dtag(self, tag):
|
||||||
# print('MfxCanvasImage: remtag %s' % tag)
|
print('MfxCanvasImage: remtag %s' % tag.stack)
|
||||||
self.group = None
|
self.group = None
|
||||||
if (self.image):
|
if (self.image):
|
||||||
self.image.group = None
|
self.image.group = None
|
||||||
|
@ -254,7 +330,7 @@ class MfxCanvasImage(object):
|
||||||
self.canvas.clear_widgets([self.image])
|
self.canvas.clear_widgets([self.image])
|
||||||
|
|
||||||
def move(self, dx, dy):
|
def move(self, dx, dy):
|
||||||
# print ('MfxCanvasImage: move %s, %s' % (dx, dy))
|
print('MfxCanvasImage: move %s, %s' % (dx, dy))
|
||||||
image = self.image
|
image = self.image
|
||||||
dsize = image.coreSize
|
dsize = image.coreSize
|
||||||
dpos = (image.corePos[0] + dx, image.corePos[1] + dy)
|
dpos = (image.corePos[0] + dx, image.corePos[1] + dy)
|
||||||
|
@ -264,19 +340,17 @@ class MfxCanvasImage(object):
|
||||||
|
|
||||||
def makeAnimStart(self):
|
def makeAnimStart(self):
|
||||||
def animStart(anim, widget):
|
def animStart(anim, widget):
|
||||||
# print('MfxCanvasImage: animStart')
|
print('MfxCanvasImage: animStart %s' % self)
|
||||||
image = self.image
|
# nothing to do hiere
|
||||||
self.canvas.tag_raise(image, None)
|
|
||||||
pass
|
pass
|
||||||
return animStart
|
return animStart
|
||||||
|
|
||||||
def makeAnimEnd(self, dpos, dsize):
|
def makeAnimEnd(self, dpos, dsize):
|
||||||
def animEnd(anim, widget):
|
def animEnd(anim, widget):
|
||||||
# print('MfxCanvasImage: animEnd %s' % self)
|
print('MfxCanvasImage: animEnd %s' % self)
|
||||||
self.animation = False
|
self.animation = False
|
||||||
image = self.image
|
image = self.image
|
||||||
image.pos, image.size = self.canvas.CoreToKivy(dpos, dsize)
|
image.pos, image.size = self.canvas.CoreToKivy(dpos, dsize)
|
||||||
pass
|
|
||||||
return animEnd
|
return animEnd
|
||||||
|
|
||||||
def animatedMove(self, dx, dy, duration=0.2):
|
def animatedMove(self, dx, dy, duration=0.2):
|
||||||
|
@ -310,10 +384,6 @@ class MfxCanvasImage(object):
|
||||||
bindS=self.makeAnimStart(),
|
bindS=self.makeAnimStart(),
|
||||||
bindE=self.makeAnimEnd(dpos, dsize))
|
bindE=self.makeAnimEnd(dpos, dsize))
|
||||||
|
|
||||||
# def moveTo(self, x, y):
|
|
||||||
# c = self.coords()
|
|
||||||
# self.move(x - int(c[0]), y - int(c[1]))
|
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
self.config(state='normal')
|
self.config(state='normal')
|
||||||
|
|
||||||
|
@ -444,6 +514,9 @@ class MfxCanvasText(object):
|
||||||
|
|
||||||
class MfxCanvas(Widget):
|
class MfxCanvas(Widget):
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'<MfxCanvas @ {hex(id(self))}>'
|
||||||
|
|
||||||
def __init__(self, wmain, *args, **kw):
|
def __init__(self, wmain, *args, **kw):
|
||||||
# super(MfxCanvas, self).__init__(**kw)
|
# super(MfxCanvas, self).__init__(**kw)
|
||||||
super(MfxCanvas, self).__init__()
|
super(MfxCanvas, self).__init__()
|
||||||
|
@ -707,23 +780,25 @@ class MfxCanvas(Widget):
|
||||||
#
|
#
|
||||||
# top-image support
|
# top-image support
|
||||||
#
|
#
|
||||||
|
|
||||||
def tag_raise(self, itm, abitm=None):
|
def tag_raise(self, itm, abitm=None):
|
||||||
# print('MfxCanvas: tag_raise, itm=%s, aboveThis=%s' % (itm, abitm))
|
# print('MfxCanvas: tag_raise, itm=%s, aboveThis=%s' % (itm, abitm))
|
||||||
|
|
||||||
if (itm is not None):
|
if (itm is not None):
|
||||||
if (abitm is None):
|
if (abitm is None):
|
||||||
# print('MfxCanvas: tag_raise: to top')
|
# print('MfxCanvas: tag_raise: to top')
|
||||||
self.clear_widgets([itm])
|
self.clear_widgets([itm])
|
||||||
self.add_widget(itm)
|
self.add_widget(itm)
|
||||||
else:
|
else:
|
||||||
print('MfxCanvas: tag_raise: to specified position')
|
# print('MfxCanvas: tag_raise: to specified position')
|
||||||
ws = []
|
ws = []
|
||||||
for c in reversed(self.children): # reversed!
|
for c in reversed(self.children): # reversed!
|
||||||
if c != itm and c != abitm:
|
if c != itm and c != abitm:
|
||||||
ws.append(c)
|
ws.append(c)
|
||||||
if c == itm:
|
if c == itm:
|
||||||
|
continue
|
||||||
|
if c == abitm:
|
||||||
ws.append(abitm)
|
ws.append(abitm)
|
||||||
ws.append(itm) # (~shadow image!)
|
ws.append(itm)
|
||||||
self.clear_widgets()
|
self.clear_widgets()
|
||||||
for w in ws:
|
for w in ws:
|
||||||
self.add_widget(w)
|
self.add_widget(w)
|
||||||
|
|
Loading…
Add table
Reference in a new issue