#!/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 . # # ---------------------------------------------------------------------------# 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'' 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'' 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'' 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 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()