1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
PySolFC/pysollib/kivy/tkcanvas.py
lufebe16 2bfc6bdd3d Android/Kivy version
- Zoom: bug fixes and refactoring
2024-11-09 13:50:49 +01:00

1015 lines
31 KiB
Python

#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------#
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
# Copyright (C) 2005-2009 Skomoroh
# Copyright (C) 2017 LB
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------#
from __future__ import division
import logging
import math
from kivy.clock import Clock
from kivy.properties import StringProperty
from kivy.uix.anchorlayout import AnchorLayout
from pysollib.kivy.LApp import LAnimationManager
from pysollib.kivy.LApp import LColorToKivy
from pysollib.kivy.LApp import LImageItem
from pysollib.kivy.LApp import LLine
from pysollib.kivy.LApp import LRectangle
from pysollib.kivy.LApp import LText
from pysollib.kivy.LImage import LImage
# ************************************************************************
# * canvas items helpers
# ************************************************************************
def addAnchorOffset(pos, anchor, size):
# print ('MfxCanvas: anchor=%s' % (anchor))
x = pos[0]
y = pos[1]
xa = 0
ya = 0
if anchor == "n":
ya = -1
elif anchor == "w":
xa = -1
elif anchor == "s":
ya = 1
elif anchor == "e":
xa = 1
elif anchor == "ne":
ya = -1
xa = 1
elif anchor == "nw":
ya = -1
xa = -1
elif anchor == "se":
ya = 1
xa = 1
elif anchor == "sw":
ya = 1
xa = -1
if xa == 0:
x = x - size[0] / 2.0
elif xa == 1:
x = x - size[0]
if ya == 0:
y = y - size[1] / 2.0
elif ya == 1:
y = y - size[1]
return (x, y)
def subAnchorOffset(pos, anchor, size):
# print ('MfxCanvas: anchor=%s' % (anchor))
x = pos[0]
y = pos[1]
xa = 0
ya = 0
if anchor == "n":
ya = -1
elif anchor == "w":
xa = -1
elif anchor == "s":
ya = 1
elif anchor == "e":
xa = 1
elif anchor == "ne":
ya = -1
xa = 1
elif anchor == "nw":
ya = -1
xa = -1
elif anchor == "se":
ya = 1
xa = 1
elif anchor == "sw":
ya = 1
xa = -1
if xa == 0:
x = x + size[0] / 2.0
elif xa == 1:
x = x + size[0]
if ya == 0:
y = y + size[1] / 2.0
elif ya == 1:
y = y + size[1]
return (x, y)
# ************************************************************************
# * canvas items
# ************************************************************************
class MfxCanvasGroup():
def __init__(self, canvas, tag=None):
# print(self, '__init__(', canvas, tag, ')')
self.canvas = canvas
self.bindings = {}
self.stack = None
def __str__(self):
return f'<MfxCanvasGroup @ {hex(id(self))}>'
def _imglist(self, group):
ilst = []
for w in group.canvas.children:
if isinstance(w, LImageItem):
if w.group == group:
ilst.append(w)
return ilst
def makeDeferredRaise(self, pos):
def animCallback():
self.tkraise(position=pos)
return animCallback
def tkraise(self, position=None):
# print(self, ' tkraise(', position, ')')
# Mainly used by Mahjongg game after a move.
# import inspect
# print('stack[1] = ',inspect.stack()[1].frame)
# print('stack[2] = ',inspect.stack()[2].frame)
if LAnimationManager.checkRunning():
LAnimationManager.addEndCallback(
self.makeDeferredRaise(position))
return
imgs = self._imglist(self)
if len(imgs) == 0:
return
if position is not None:
# add all images above specified position
pimgs = self._imglist(position)
if len(pimgs) == 0:
return
self.canvas.clear_widgets(imgs)
k = self.canvas.children.index(pimgs[-1])
for i in imgs:
self.canvas.add_widget(i, index=k)
k += 1
else:
# add all images to top
self.canvas.clear_widgets(imgs)
k = 0
for i in imgs:
self.canvas.add_widget(i, index=k)
k += 1
def makeDeferredLower(self, pos):
def animCallback():
self.lower(position=pos)
return animCallback
def lower(self, position=None):
# print(self, ' lower(', position, ')')
# import inspect
# print('stack[1] = ',inspect.stack()[1].frame)
# print('stack[2] = ',inspect.stack()[2].frame)
if LAnimationManager.checkRunning():
LAnimationManager.addEndCallback(
self.makeDeferredLower(position))
return
imgs = self._imglist(self)
if len(imgs) == 0:
return
if position is not None:
# add below specified position
pimgs = self._imglist(position)
if len(pimgs) == 0:
return
self.canvas.clear_widgets(imgs)
k = self.canvas.children.index(pimgs[0]) # the spec. item
k += 1 # insert before
for i in imgs:
self.canvas.add_widget(i, index=k)
k += 1
else:
# add all to bottom
self.canvas.clear_widgets(imgs)
k = len(self.canvas.children)-1 # the last item
k += 1 # insert before
for i in imgs:
self.canvas.add_widget(i, index=k)
k += 1
def addtag(self, tag, option="withtag"):
# logging.info('MfxCanvasGroup: addtag(%s, %s)' % (tag, option))
# self.canvas.addtag(tag, option, self.id)
pass
def delete(self):
# logging.info('MfxCanvasGroup: delete()')
# del self.canvas.items[self.id]
pass
def gettags(self):
# logging.info('MfxCanvasGroup: gettags()')
# return self.canvas.tk.splitlist(self._do("gettags"))
return None
def cardmagnif(canvas, size):
def pyth(s):
return math.sqrt(s[0]*s[0]+s[1]*s[1])
cs = canvas.wmain.app.images.getSize()
csl = pyth(cs)
sl = pyth(size)
return csl/sl
class MfxCanvasImage(object):
def __init__(self, canvas, *args, **kwargs):
# print ('MfxCanvasImage: %s | %s | %s' % (canvas, args, kwargs))
self.group = None
group = None
if 'group' in kwargs:
group = kwargs['group']
del kwargs['group']
self._image = None
if 'image' in kwargs:
self._image = kwargs['image']
self._anchor = None
if 'anchor' in kwargs:
self._anchor = kwargs['anchor']
self.hint = None
if 'hint' in kwargs:
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__()
self.canvas = canvas
self.redeal = False
# animation mode support:
self.animation = 0
self.duration = 0.2
self.deferred_raises = []
self.animations = []
ed = kwargs['image']
size = ed.size
if type(ed) is LImageItem:
aimage = ed
else:
image = LImage(texture=ed.texture)
if self.hint == "redeal_image":
cm = cardmagnif(canvas, size)/1.9
image.size = [cm*ed.getWidth(), cm*ed.getHeight()]
self.redeal = True
aimage = LImageItem(
size=ed.size, group=group, image_type=self.hint)
else:
image.size = [ed.getWidth(), ed.getHeight()]
aimage = LImageItem(size=ed.size, group=group)
aimage.add_widget(image)
aimage.size = image.size
size = image.size
xy = addAnchorOffset(args, self._anchor, size)
aimage.coreSize = (aimage.size[0], aimage.size[1])
aimage.corePos = (xy[0], xy[1])
aimage.pos, aimage.size = canvas.CoreToKivy(xy, aimage.size)
self.canvas.add_widget(aimage)
self.image = aimage
self.widget = aimage
if group:
self.addtag(group)
def __del__(self):
# print('MfxCanvasImage: __del__(%s)' % self.image)
self.canvas.clear_widgets([self.image])
def __str__(self):
return f'<MfxCanvasImage @ {hex(id(self))}>'
def config(self, **kw):
# print('MfxCanvasImage conifg:',kw)
if "image" in kw:
# print('is redeal image:',self.redeal)
if self.redeal:
image = self.image.children[0]
image.texture = kw["image"].texture
# print('redeal texture:',image.texture)
pass
def makeDeferredRaise(self, pos):
def animCallback():
self.canvas.tag_raise(self.image, pos)
return animCallback
def tkraise(self, aboveThis=None):
abitm = None
if aboveThis:
abitm = aboveThis.widget
# import inspect
# print('stack[1] = ', inspect.stack()[1].frame)
# print('stack[2] = ', inspect.stack()[2].frame)
# print('stack[3] = ', inspect.stack()[3].frame)
if self.animation > 0:
# print('defer tkraise to animation', abitm)
if len(self.deferred_raises) < self.animation:
self.deferred_raises.append(self.makeDeferredRaise(abitm))
return
# print('direct tkraise', abitm)
self.canvas.tag_raise(self.image, abitm)
def addtag(self, tag):
# print('MfxCanvasImage: addtag %s' % tag.stack)
self.group = tag
if (self.image):
self.image.group = tag
def dtag(self, tag):
# print('MfxCanvasImage: remtag %s' % tag.stack)
self.group = None
if (self.image):
self.image.group = None
pass
def delete(self):
# print('MfxCanvasImage: delete()')
self.canvas.clear_widgets([self.image])
def move(self, dx, dy):
# print('MfxCanvasImage: move %s, %s' % (dx, dy))
image = self.image
dsize = image.coreSize
dpos = (image.corePos[0] + dx, image.corePos[1] + dy)
image.corePos = dpos
if self.animation == 0:
image.pos, image.size = self.canvas.CoreToKivy(dpos, dsize)
else:
pos, size = self.canvas.CoreToKivy(dpos, dsize)
self.animations[self.animation-1].updateDestPos(pos)
def makeAnimStart(self):
def animStart(anim, widget):
# print('MfxCanvasImage: animStart %s' % self)
# raise to top if reqested for this move
if self.deferred_raises:
self.deferred_raises[0]()
self.deferred_raises = self.deferred_raises[1:]
# update z-order (for some specials)
while 1:
from pysollib.games.grandfathersclock import Clock_RowStack
specials = [Clock_RowStack, ]
if self.group is None: break # noqa
stack = self.group.stack
if stack is None: break # noqa
if type(stack) not in specials: break; # noqa
cards = self.group.stack.cards
card = self.image.card
if card is None: break # noqa
if card == cards[-1]: break # noqa
i = cards.index(card) + 1
# print('stack =', self.group.stack)
# print('cards:', [c.__str__() for c in cards])
# print('card =', card)
# print('***** adjust z-reordering:',card,'before',cards[i])
def lower_z(dt):
self.canvas.tag_lower(card.item.image, cards[i].item.image)
Clock.schedule_once(lower_z, self.duration/2.0)
break
return animStart
def makeAnimEnd(self, dpos, dsize):
def animEnd(anim, widget):
# print('MfxCanvasImage: animEnd %s' % self)
if self.animation > 0:
self.animation -= 1
self.animations = self.animations[1:]
if self.animation == 0:
# just for the case, keep in sync:
self.deferred_raises = []
self.animations = []
# print('MfxCanvasImage: animEnd moved to %s, %s' % (dpos[0], dpos[1])) # noqa
return animEnd
def animatedMove(self, dx, dy, duration=0.2):
# print('MfxCanvasImage: animatedMove %s, %s' % (dx, dy))
# import inspect
# for insi in range(1,9):
# print('stack[insi] = ', inspect.stack()[insi].frame)
image = self.image
dsize = image.coreSize
dpos = (image.corePos[0] + dx, image.corePos[1] + dy)
pos, size = self.canvas.CoreToKivy(dpos, dsize)
transition1 = 'out_expo'
# transition2 = 'out_cubic'
# transition3 = 'out_quad'
# transition4 = 'out_quint'
# transition5 = 'out_sine'
transition6 = 'in_out_quad'
# transition7 = 'in_bounce'
# transition8 = 'in_elastic'
transition = transition6
if self.canvas.wmain.app.game.demo:
transition = transition1
self.duration = duration
ssize = image.coreSize
spos = (image.corePos[0], image.corePos[1])
spos, ssize = self.canvas.CoreToKivy(spos, ssize)
from pysollib.kivy.LApp import LAnimationTask
task = LAnimationTask(
spos,
image,
x=pos[0], y=pos[1],
duration=duration, transition=transition,
bindS=self.makeAnimStart(),
bindE=self.makeAnimEnd(dpos, dsize))
self.animations.append(task)
self.animation += 1
LAnimationManager.taskInsert(task)
def show(self):
self.config(state='normal')
def hide(self):
self.config(state='hidden')
class MfxCanvasLine(object):
def __init__(self, canvas, *args, **kwargs):
# print('MfxCanvasLine: %s %s' % (args, kwargs))
self.canvas = canvas
line = LLine(canvas, args, **kwargs)
line.pos, line.size = canvas.CoreToKivy(line.corePos, line.coreSize)
canvas.add_widget(line)
self.canvas = canvas
self.line = line
self.widget = line
def delete_deferred(self, seconds):
# print('MfxCanvasLine: delete_deferred(%s)' % seconds)
from kivy.animation import Animation
z = 0
t = 'in_expo'
anim = Animation(opacity=z, t=t, d=seconds/1.5)
anim.start(self.line)
Clock.schedule_once(lambda dt: self.delete(), seconds)
def delete(self):
# print('MfxCanvasLine: delete()')
self.canvas.clear_widgets([self.line])
class MfxCanvasRectangle(object):
def __init__(self, canvas, *args, **kwargs):
# logging.info('MfxCanvasRectangle: %s %s' % (args, kwargs))
rect = LRectangle(canvas, args, **kwargs)
rect.pos, rect.size = canvas.CoreToKivy(rect.corePos, rect.coreSize)
canvas.add_widget(rect)
self.canvas = canvas
self.rect = rect
self.widget = rect
def delete(self):
# print('MfxCanvasRectangle: delete()')
self.canvas.clear_widgets([self.rect])
def __del__(self):
# print('MfxCanvasRectangle: __del__()')
self.delete()
def delete_deferred_step(self, seconds):
# print ('MfxCanvasRectangle: delete_deferred_step(%s)' % seconds)
Clock.schedule_once(lambda dt: self.delete(), seconds)
def delete_deferred(self, seconds):
# self.canvas.canvas.ask_update()
# print ('MfxCanvasRectangle: delete_deferred(%s)' % seconds)
Clock.schedule_once(
lambda dt: self.delete_deferred_step(seconds), 0.05)
def addtag(self, tag):
logging.info('MfxCanvasRectangle: addtag(%s) - fake' % tag)
pass
def tkraise(self, aboveThis=None):
# logging.info('MfxCanvasRectangle: tkraise(%s) - fake' % item)
abitm = None
if aboveThis:
abitm = aboveThis.widget
self.canvas.tag_raise(self.rect, abitm)
pass
class MfxCanvasText(object):
def __init__(self, canvas, x, y, preview=-1, **kwargs):
if preview < 0:
preview = canvas.preview
if preview > 1:
return
if "fill" not in kwargs:
kwargs["fill"] = canvas._text_color
if 'group' in kwargs:
del kwargs['group']
super(MfxCanvasText, self).__init__()
label = LText(canvas, x, y, **kwargs)
label.pos, label.size = canvas.CoreToKivy(
label.corePos, label.coreSize)
canvas.add_widget(label)
self.canvas = canvas
self.label = label
self.widget = label
self.canvas.bind(_text_color=self.setColor)
def setColor(self, w, c):
self.label.label.color = LColorToKivy(c)
def config(self, **kw):
# print('MfxCanvasText: config %s' % kw)
if ('text' in kw):
self.label.text = kw['text']
def tkraise(self, aboveThis=None):
abitm = None
if aboveThis:
abitm = aboveThis.widget
self.canvas.tag_raise(self.label, abitm)
pass
def bbox(self):
# Dimensionen als 2x2 array zurückgeben.
# (aufruf z.B. bei games/special/poker.py und bei Memory!)
label = self.label
canvas = self.canvas
pos = label.pos
size = label.size
pos, size = canvas.KivyToCore(pos, size)
ret = [[pos[0], pos[1]], [pos[0] + size[0], pos[1] + size[1]]]
return ret
def addtag(self, tag):
pass
# ************************************************************************
# * canvas
# ************************************************************************
class MfxCanvas(LImage):
_text_color = StringProperty("#000000")
def __str__(self):
return f'<MfxCanvas @ {hex(id(self))}>'
def __init__(self, wmain, *args, **kw):
super(MfxCanvas, self).__init__(background=True)
# print('MfxCanvas: __init__()')
# self.tags = {} # bei basisklasse widget (ev. nur vorläufig)
self.wmain = wmain
# print('MfxCanvas: wmain = %s' % self.wmain)
# Tkinter.Canvas.__init__(self, *args, **kw)
self.preview = 0
self.busy = False
self._text_color = '#000000'
self._bg_color = '#00ffff'
self._stretch_bg_image = 0
self._save_aspect_bg_image = 0
#
self.xmargin, self.ymargin = 0.0, 0.0
self.topImage = None
# Skalierung
# self.lastsize = (self.size[0], self.size[1])
# self.lastpos = (self.pos[0], self.pos[1])
self.scale = 1.2
self.r_width = None
self.r_height = None
self.bindings = {}
self.bind(pos=self.pos_update_widget)
self.bind(size=self.size_update_widget)
def on_touch_down(self,touch):
ret = False
ret = super(MfxCanvas,self).on_touch_down(touch)
return ret
def on_touch_up(self,touch):
ret = False
ret = super(MfxCanvas,self).on_touch_up(touch)
return ret
def on_touch_move(self,touch):
ret = False
ret = super(MfxCanvas,self).on_touch_move(touch)
return ret
def KivyToCoreP(self, pos, size, scale):
cpos = pos
cpos = (cpos[0] - self.pos[0], self.pos[1] +
self.size[1] - cpos[1] - size[1])
cpos = (1.0 * cpos[0] / scale, 1.0 * cpos[1] / scale)
csize = (1.0 * size[0] / scale, 1.0 * size[1] / scale)
return cpos, csize
def CoreToKivyP(self, cpos, csize, scale):
size = (1.0 * csize[0] * scale, 1.0 * csize[1] * scale)
pos = (1.0 * cpos[0] * scale, 1.0 * cpos[1] * scale)
pos = (self.pos[0] + pos[0], self.pos[1] +
self.size[1] - pos[1] - size[1])
return pos, size
def KivyToCore(self, pos, size=(0.0, 0.0)):
return self.KivyToCoreP(pos, size, self.scale)
def CoreToKivy(self, cpos, csize=(0.0, 0.0)):
return self.CoreToKivyP(cpos, csize, self.scale)
def move(self, itm, dx, dy):
# print ('MfxCanvas: move %s %s %s' % (itm, dx, dy))
scale = self.scale
dx = scale * dx
dy = scale * dy
itm.pos = (itm.pos[0] + dx, itm.pos[1] - dy)
def scalefactor(self):
if self.r_width is None:
return self.scale
if self.r_height is None:
return self.scale
# TBD (idee).
# Hier ev. einen 2ten Modus zulassen, welche das Spielfeld
# knapp auf die vorhandenen Karten/Anzeigeelemente bemisst.
# Zur Optimierung der Sichtbarkeit auf kleinen Geräten.
# Könnte z.B. über Doppelklick umgeschaltet werden. (Die
# Skalierung müsste dann allerding nach jedem Zug dem ev.
# veränderten Feld angepasst werden.)
wid = self.size[0]
hei = self.size[1]
scfx = wid / self.r_width
scfy = hei / self.r_height
scf = scfx
if (scfx < scfy):
# print('scale factor by x = %s' % (scfx))
scf = scfx
else:
# print('scale factor by y = %s' % (scfy))
scf = scfy
return scf
def pos_update_widget(self, posorobj, size):
# print('MfxCanvas: pos_update_widget size=(%s, %s)' %
# (self.size[0], self.size[1]))
self.update_widget(posorobj, size)
def size_update_widget(self, posorobj, size):
# print('MfxCanvas: size_update_widget size=(%s, %s)' %
# (self.size[0], self.size[1]))
self.update_widget(posorobj, size)
def update_widget(self, posorobj, size):
def psize(s):
return "({:1.2f}, {:1.2f})".format(s[0], s[1])
# logging.info('MfxCanvas: update_widget to: '+psize(size))
# print('MfxCanvas: update_widget size=(%s, %s)' %
# (self.size[0], self.size[1]))
# Update Skalierungsparameter
# oldscale = self.scale
newscale = self.scalefactor()
# logging.info('MfxCanvas: scale factor: {:1.2f})'.format(newscale))
self.scale = newscale
# Anpassung Skalierung.
for c in self.children:
if not hasattr(c, 'corePos'):
continue
if not hasattr(c, 'coreSize'):
continue
bpos = c.corePos
bsiz = c.coreSize
if bpos and bsiz:
npos, nsiz = self.CoreToKivy(bpos, bsiz)
c.pos = npos
c.size = nsiz
# Hintergrund update.
kc = LColorToKivy(self._bg_color)
texture = None
if self._bg_img:
texture = self._bg_img.texture
self.texture = texture
if texture is None:
self.setColor(kc)
else:
self.setColor([1,1,1,1]) # noqa
if self._stretch_bg_image:
if self._save_aspect_bg_image == 0:
self.fit_mode = "fill"
else:
self.fit_mode = "cover"
else:
self.fit_mode = "tiling"
# Funktionen, welche vom Core aufgerufen werden.
def winfo_width(self):
# return self.r_width
cpos, csize = self.KivyToCoreP(self.pos, self.size, self.scale)
# print('MfxCanvas: winfo_width %s' % (csize[0]))
return csize[0]
def winfo_height(self):
# return self.r_height
cpos, csize = self.KivyToCoreP(self.pos, self.size, self.scale)
# print('MfxCanvas: winfo_height %s' % (csize[1]))
return csize[1]
def cget(self, f):
print('MfxCanvas: cget %s -> %s, %s' % (f, self.pos, self.size))
cpos, csize = self.KivyToCoreP(self.pos, self.size, self.scale)
if f == 'width':
print('MfxCanvas: cget %s -> x=%s' % (f, cpos[0]))
return cpos[0]
if f == 'height':
print('MfxCanvas: cget %s -> y=%s' % (f, cpos[1]))
return cpos[1]
# if f=='bg':
# return background-color
print('MfxCanvas: cget unsupported token')
return 1
def xview(self):
print('MfxCanvas: xview')
return [1, 1]
pass
def yview(self):
print('MfxCanvas: yview')
return [1, 1]
pass
#
# top-image support
#
def tag_raise(self, itm, abitm=None):
# print('MfxCanvas: tag_raise(%s, %s)' % (itm, abitm))
def findTop(itm):
t = type(itm)
for c in self.children:
if type(c) is t:
return self.children.index(c)
return 0
if (itm is not None):
if (abitm is None):
self.remove_widget(itm)
self.add_widget(itm, index=findTop(itm))
else:
self.remove_widget(itm)
k = self.children.index(abitm)
self.add_widget(itm, index=k)
def tag_lower(self, itm, belowThis=None):
# print('MfxCanvas: tag_lower(%s, %s)' % (itm, belowThis))
if (itm is not None):
if (belowThis is None):
self.remove_widget(itm)
k = len(self.children)
self.add_widget(itm, index=k)
else:
self.remove_widget(itm)
k = self.children.index(belowThis)
k += 1
self.add_widget(itm, index=k)
def setInitialSize(self, width, height):
self.r_width = width
self.r_height = height
self.update_widget(self.pos, self.size)
return
# delete all CanvasItems, but keep the background and top tiles
def deleteAllItems(self):
print('MfxCanvas: deleteAllItems')
self.clear_widgets()
pass
def findCard(self, stack, event):
print('MfxCanvas: findCard(%s, %s)' % (stack, event))
if (event.cardid > -1):
return event.cardid
print('MfxCanvas: findCard no cardid')
return -1
def findImagesByType(self, image_type):
images = []
for c in self.children:
if type(c) is LImageItem:
if c.get_image_type() == image_type:
images.append(c)
return images
def setTextColor(self, color):
# print('MfxCanvas: setTextColor')
# color is ignored: it sets a predefined (option settable)
# color. We do not support that. Instead of this wie examine
# the background and set the color accordingly.
if self._bg_img is not None:
from pysollib.kivy.LApp import LTextureToLuminance
lumi = LTextureToLuminance(self._bg_img.texture)
else:
from pysollib.kivy.LApp import LColorToLuminance
lumi = LColorToLuminance(self._bg_color)
self._text_color = ("#000000", "#ffffff")[lumi < 0.4]
# print('average luminance =', lumi)
def setTile(self, image, stretch=0, save_aspect=0):
# print('setTile: %s, %s, %s' % (image, stretch, save_aspect))
if image:
try:
from pysollib.kivy.tkutil import LImageInfo
self._bg_img = LImageInfo(image)
self._stretch_bg_image = stretch
self._save_aspect_bg_image = save_aspect
self.update_widget(self.pos, self.size)
except Exception:
return 0
else:
# print ('setTile: no image!')
self._bg_img = None
self.update_widget(self.pos, self.size)
return 1
def setTopImage(self, image, cw=0, ch=0):
print('MfxCanvas: setTopImage %s' % image)
if self.topImage:
self.clear_widgets([self.topImage])
self.topImage = None
if image:
tex = LImage(texture=image.texture)
tex.size_hint = (0.4, 0.4)
lay = AnchorLayout(anchor_y='bottom')
lay.size = self.size
lay.add_widget(tex)
self.topImage = lay
self.add_widget(self.topImage)
return 1
#
# Pause support
#
def hideAllItems(self):
print('MfxCanvas: hideAllItems')
# TBD
# Wir lassen das. Das TopImage deckt alles ab. Spielen ist
# nicht möglich.
pass
def showAllItems(self):
print('MfxCanvas: showAllItems')
# TBD
# Brauchts darum auch nicht.
pass
# Erweiterungen fuer Tk Canvas (prüfen was noch nötig!!).
def itemconfig(self, tagOrId, cnf=None, **kw):
"""Configure resources of an item TAGORID.
The values for resources are specified as keyword
arguments. To get an overview about
the allowed keyword arguments call the method without arguments.
"""
print(
'MfxCanvas: itemconfigure tagOrId=%s, cnf=%s, kw=%s'
% (tagOrId, cnf, kw))
if 'image' in cnf:
# tagOrId ist ein Image oder ein CardImage
# self.clear_widgets([cnf['image']])
# self.add_widget(cnf['image'])
# y = self.yy
pass
if 'text' in cnf:
# tagOrId ist das Label.
tagOrId.text = cnf['text']
pass
def config(self, cnf={}, **kw):
# print('MfxCanvas: config %s %s' % (cnf, kw))
if ('cursor' in kw):
pass
if ('width' in kw):
self.size[0] = kw['width']
if ('height' in kw):
self.size[1] = kw['height']
if ('bg' in kw):
self._bg_color = kw['bg']
self.update_widget(self.pos, self.size)
def dtag(self, tag, b=None):
# print ('Canvas: dtag %s %s' % (tag, b))
# if (tag in self.tags):
# if (self.tags[tag]==b):
# del self.tags[tag]
pass
def addtag(self, tag, b, c):
# print ('Canvas: addtag %s %s %s' % (tag, b, c))
# self.tags[c] = tag
# self.tags.append(tag)
pass
def delete(self, tag):
# print ('MfxCanvas: delete tag=%s' % tag)
# y = self.yy
pass
def update_idletasks(self):
print('MfxCanvas: update_idletasks')
self.wmain.update_idletasks()