#!/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.graphics import Color from kivy.graphics import Rectangle from kivy.uix.anchorlayout import AnchorLayout from kivy.uix.widget import Widget 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.LBase import LBase 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 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"): # 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.animation = None 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)/3.0 image.size = [cm*ed.getWidth(), cm*ed.getHeight()] 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): pass def tkraise(self, aboveThis=None): # print(self, ': tkraise, above =', aboveThis) abitm = None if aboveThis: if isinstance(aboveThis, MfxCanvasImage): abitm = aboveThis.widget if isinstance(aboveThis, LImageItem): abitm = aboveThis 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 not self.animation: image.pos, image.size = self.canvas.CoreToKivy(dpos, dsize) def makeAnimStart(self): def animStart(anim, widget): # print('MfxCanvasImage: animStart %s' % self) # nothing to do hiere pass return animStart def makeAnimEnd(self, dpos, dsize): def animEnd(anim, widget): # print('MfxCanvasImage: animEnd %s' % self) self.animation = False image = self.image image.pos, image.size = self.canvas.CoreToKivy(dpos, dsize) return animEnd def animatedMove(self, dx, dy, duration=0.2): # print ('MfxCanvasImage: animatedMove %s, %s' % (dx, dy)) 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.animation = True ssize = image.coreSize spos = (image.corePos[0], image.corePos[1]) spos, ssize = self.canvas.CoreToKivy(spos, ssize) LAnimationManager.create( spos, image, x=pos[0], y=pos[1], duration=duration, transition=transition, bindS=self.makeAnimStart(), bindE=self.makeAnimEnd(dpos, dsize)) 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) 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): print( 'MfxCanvasText: %s | %s, %s, %s | %s' % (canvas, x, y, preview, 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 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(Widget, LBase): def __str__(self): return f'' def __init__(self, wmain, *args, **kw): super(MfxCanvas, self).__init__() # 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): # print('MfxCanvas: update_widget size=(%s, %s)' % # (self.size[0], self.size[1])) # Update Skalierungsparameter oldscale = self.scale newscale = self.scalefactor() print('MfxCanvas: scale factor old= %s, new=%s' % (oldscale, 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. self.canvas.before.clear() texture = None if self._bg_img: texture = self._bg_img.texture # Color only: Nur eine Hintergrundfarbe wird installiert. if texture is None: kc = LColorToKivy(self._bg_color) self.canvas.before.add( Color(kc[0], kc[1], kc[2], kc[3])) self.canvas.before.add( Rectangle(pos=self.pos, size=self.size)) return # Image: Das Bild wird im Fenster expandiert. if self._stretch_bg_image: if self._save_aspect_bg_image == 0: self.canvas.before.add( Rectangle(texture=texture, pos=self.pos, size=self.size)) else: # save aspect aspect = texture.size[0]/texture.size[1] waspect = self.size[0]/self.size[1] print ('aspect: ', aspect) # noqa print ('waspect: ', waspect) # noqa # 'clamp_to_edge','repeat','mirrored_repeat' texture.wrap = 'repeat' print ('wrap: ',texture.wrap) # noqa # add new rectangle to canvas. r = Rectangle(texture=texture, pos=self.pos, size=self.size) self.canvas.before.add(r) # evaluate original texture coords. uu = r.tex_coords[0] vv = r.tex_coords[1] ww = r.tex_coords[2] - uu hh = r.tex_coords[5] - vv # in order to center the image in the window # modify texture coords if waspect < aspect: w = ww/aspect*waspect # noqa h = hh u = 0.5 - w/2.0 # noqa v = vv else: w = ww h = hh*aspect/waspect # noqa u = uu v = 0.5 - h/2.0 # noqa # and update them. tc = ( u, v, u + w, v, u + w, v + h, u, v + h ) # noqa r.tex_coords = tc print ('tex_coords (orig):',uu,vv,ww,hh) # noqa print ('tex_coords (mod): ',u,v,w,h) # noqa return else: # Tiles placement, reference point is bottom left. texture.wrap = 'repeat' r = Rectangle(texture=texture, pos=self.pos, size=self.size) self.canvas.before.add(r) # stsize = (texture.size[0] * self.scale, # texture.size[1] * self.scale) stsize = texture.size stepsy = self.size[1] / stsize[1] stepsx = self.size[0] / stsize[0] u = r.tex_coords[0] v = r.tex_coords[1] ww = r.tex_coords[2] - u hh = r.tex_coords[5] - v w = ww * stepsx h = hh * stepsy # move reference point to top left: v = stepsy - math.floor(stepsy) r.tex_coords = ( u, v, u + w, v, u + w, v + h, u, v + h ) # noqa # 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, itm=%s, aboveThis=%s' % (itm, abitm)) if (itm is not None): if (abitm is None): # print('MfxCanvas: tag_raise: to top') self.clear_widgets([itm]) self.add_widget(itm) else: # print('MfxCanvas: tag_raise: to specified position') ws = [] for c in reversed(self.children): # reversed! if c != itm and c != abitm: ws.append(c) if c == itm: continue if c == abitm: ws.append(abitm) ws.append(itm) self.clear_widgets() for w in ws: self.add_widget(w) def tag_lower(self, id, belowThis=None): print('MfxCanvas: tag_lower(%s, %s)' % (id, belowThis)) # y = self.yy # kommt das vor ? pass # # # def setInitialSize(self, width, height): print('MfxCanvas: setInitialSize request %s/%s' % (width, height)) print( 'MfxCanvas: setInitialSize actual %s/%s' % (self.size[0], self.size[1])) self.r_width = width self.r_height = height # ev. update anstossen self.update_widget(self.pos, self.size) # self.size[0] = width # self.size[1] = height 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 setTextColor(self, color): print('MfxCanvas: setTextColor1 %s' % color) if color is None: c = self.cget("bg") if not isinstance(c, str) or c[0] != "#" or len(c) != 7: return v = [] for i in (1, 3, 5): v.append(int(c[i:i + 2], 16)) luminance = (0.212671 * v[0] + 0.715160 * v[1] + 0.072169 * v[2]) / 255 # print c, ":", v, "luminance", luminance color = ("#000000", "#ffffff")[luminance < 0.3] print('MfxCanvas: setTextColor2 %s' % color) if self._text_color != color: self._text_color = color # falls wir das wollen in kivy: # -> text_color als property deklarieren, und a.a.O binden. # for item in self._text_items: # item.config(fill=self._text_color) def setTile(self, image, stretch=0, save_aspect=0): print('setTile: %s, %s' % (image, stretch)) if image: try: self._bg_img = LImage(source=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()