From 99dd6c911926588c2b554652bac9361d11b5429f Mon Sep 17 00:00:00 2001 From: skomoroh Date: Thu, 5 Apr 2007 21:22:01 +0000 Subject: [PATCH] + 1 new game - removed one duplicated game * tile: improved statistics dialog git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@156 efabe8c0-fbe8-4139-b769-b5e6d273206e --- pysollib/games/capricieuse.py | 3 +- pysollib/games/fortythieves.py | 6 +- pysollib/games/klondike.py | 22 --- pysollib/games/mahjongg/mahjongg2.py | 2 +- pysollib/games/pyramid.py | 102 ++++++++++- pysollib/tile/tkstats.py | 244 +++++++++++++++------------ 6 files changed, 242 insertions(+), 137 deletions(-) diff --git a/pysollib/games/capricieuse.py b/pysollib/games/capricieuse.py index c3635668..64060675 100644 --- a/pysollib/games/capricieuse.py +++ b/pysollib/games/capricieuse.py @@ -180,7 +180,8 @@ registerGame(GameInfo(293, Nationale, "Nationale", altnames=('Zigzag Course',) )) registerGame(GameInfo(606, Strata, "Strata", GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 2, 2, GI.SL_MOSTLY_SKILL, - ranks=(0, 6, 7, 8, 9, 10, 11, 12) )) + ranks=(0, 6, 7, 8, 9, 10, 11, 12), + altnames=('Persian Patience',) )) registerGame(GameInfo(673, Fifteen, "Fifteen", GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL)) diff --git a/pysollib/games/fortythieves.py b/pysollib/games/fortythieves.py index bfcf8299..6af9ee05 100644 --- a/pysollib/games/fortythieves.py +++ b/pysollib/games/fortythieves.py @@ -975,7 +975,7 @@ class DoubleGoldMine(Streets): # // Unlimited # // Breakwater # // Forty Nine -# // Alternations +# // Alternation # // Triple Interchange # ************************************************************************/ @@ -1030,7 +1030,7 @@ class FortyNine(Interchange): shallHighlightMatch = Game._shallHighlightMatch_AC -class Alternations(Interchange): +class Alternation(Interchange): RowStack_Class = AC_RowStack shallHighlightMatch = Game._shallHighlightMatch_AC @@ -1239,7 +1239,7 @@ registerGame(GameInfo(588, Roosevelt, "Roosevelt", GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(628, Crossroads, "Crossroads", GI.GT_FORTY_THIEVES, 4, 0, GI.SL_BALANCED)) -registerGame(GameInfo(631, Alternations, "Alternations", +registerGame(GameInfo(631, Alternation, "Alternation", GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(632, Floradora, "Floradora", GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_LUCK)) diff --git a/pysollib/games/klondike.py b/pysollib/games/klondike.py index 3cfe5426..0a7cd8b0 100644 --- a/pysollib/games/klondike.py +++ b/pysollib/games/klondike.py @@ -794,26 +794,6 @@ class Arizona(Phoenix): shallHighlightMatch = Game._shallHighlightMatch_RK -# /*********************************************************************** -# // Alternation -# ************************************************************************/ - -class Alternation(Klondike): - - Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0) - RowStack_Class = StackWrapper(AC_RowStack, base_rank=ANY_RANK) - - def createGame(self): - Klondike.createGame(self, max_rounds=1) - - def startGame(self): - for i in range(6): - self.s.talon.dealRow(rows=self.s.rows, flip=(i+1)%2, frames=0) - self.startDealSample() - self.s.talon.dealRow() - self.s.talon.dealCards() # deal first card to WasteStack - - # /*********************************************************************** # // Lanes # ************************************************************************/ @@ -1437,8 +1417,6 @@ registerGame(GameInfo(283, Jumbo, "Jumbo", GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED)) registerGame(GameInfo(333, OpenJumbo, "Open Jumbo", GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED)) -registerGame(GameInfo(297, Alternation, "Alternation", - GI.GT_KLONDIKE, 2, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(326, Lanes, "Lanes", GI.GT_KLONDIKE, 1, 1, GI.SL_BALANCED)) registerGame(GameInfo(327, ThirtySix, "Thirty Six", diff --git a/pysollib/games/mahjongg/mahjongg2.py b/pysollib/games/mahjongg/mahjongg2.py index 5c40adf9..8e08db59 100644 --- a/pysollib/games/mahjongg/mahjongg2.py +++ b/pysollib/games/mahjongg/mahjongg2.py @@ -50,7 +50,7 @@ r(5212, "Floating City", layout="0oagoaiocdocfochocjoclocphdahdchdmhdoaeboebaeda r(5215, "Hidden Words", layout="0haahachaehaghalabaabcobdabeabgabjablbbnabphcahcchceocghchhckhcqadgadmodohefheihemheoafgafjofjaflafnafphgfogghgkhgmhgohichiehikhinajaojaajcojdajeajghjhajjajlajnajphkbhkfokjhklhkpalaalghlialjalmombhmchmehmnanaancanebnganjanlannbnphochoiholhqchqfhqihqkaraarcarearjhschshhslhsnhspatgatjatlatnatphuchuhhunavaavcaveavjhvkhwdhwfhxihxmhxqayahybaycayeaygayjaylaynhyoayphzfhzkaAabAdaAghAhaAjaAmaAphBlhBnhBqaCahCbaCghCiaCjaCphDfhDp") r(5216, "Hovercraft", layout="0aadaafaahaajjbgdccdceacgdcidckjdgaedaefaehaejhfgagfpggaghhhgaigajajjgajmhkaakghkmalaolaalmolmhmavmaemghmmvmmanaonaCnaenceneenienkanmonmCnmhoavoaeoghomvomapaopaapmopmhqaaqghqmarajrgarmasghtgaufpugauhhvgawdawfawhawjjxgdycdyeaygdyidykjzgaAdaAfaAhaAj") r(5217, "Hurdles", layout="0aaaaacaaeaagaaiaakaamaaohbahbchbehbghbihbkhbmhboacaocaaccoccaceoceacgocgaciociackockacmocmacoocohdahdchdehdghdihdkhdmhdoaeaaecaeeaegaeiaekaemaeoagaagcageaggagiagkagmagohhahhchhehhghhihhkhhmhhoaiaoiaaicoicaieoieaigoigaiioiiaikoikaimoimaiooiohjahjchjehjghjihjkhjmhjoakaakcakeakgakiakkakmakoamaamcameamgamiamkammamohnahnchnehnghnihnkhnmhnoaoaooaaocoocaoeooeaogoogaoiooiaokookaomoomaooooohpahpchpehpghpihpkhpmhpoaqaaqcaqeaqgaqiaqkaqmaqo") -r(5218, "Hurricane", layout="0babaadaambaoabibegbekofdbfeoffafiofioflbfmofnbgchgibgoahaahiohiahqhibhiihipajbajeijfajgvjgajiojiajkvjkijlajmajphkbhkihkpalcalialohmchmoandineanfanianlinmannapbipdapevpeipfapgapkiplapmvpmipnappardirearfariarlirmarnhschsoatcatiatohubhuihupavbaveivfavgvvgavioviavkvvkivlavmavphwbhwihwpaxaaxioxiaxqbychyibyoozdbzeozfazioziozlbzmoznbAgbAkaDibEbaEdaEmbEo") +r(5218, "Tornado", layout="0babaadaambaoabibegbekofdbfeoffafiofioflbfmofnbgchgibgoahaahiohiahqhibhiihipajbajeijfajgvjgajiojiajkvjkijlajmajphkbhkihkpalcalialohmchmoandineanfanianlinmannapbipdapevpeipfapgapkiplapmvpmipnappardirearfariarlirmarnhschsoatcatiatohubhuihupavbaveivfavgvvgavioviavkvvkivlavmavphwbhwihwpaxaaxioxiaxqbychyibyoozdbzeozfazioziozlbzmoznbAgbAkaDibEbaEdaEmbEo") # r(5219, "IloveU", layout="0caddafcahdaldandapdcbcciceacejcgacgkdibcilckdckmcmecmndngdnpcoeconcqdcqmdsbcslcuacukcwacwjdybcyidzldzndzpcAddAfcAhdBpdDldDndDp") r(5220, "Inazuma", layout="0caaaaocaqcccacmccoacqceebeiaekcemaeoagacggcgkagmciaaicciibimakackcakeckkamccmeamgcmmaoecogaoicoocqaaqgdqiaqkcqqcscasicskasmcueaukcumauocwgawmcwoawqbyecyiayocyqaAecAgcAkaAqaCccCeaCgbCicCmaEacEcaEecEocGaaGccGq") diff --git a/pysollib/games/pyramid.py b/pysollib/games/pyramid.py index caaf64a2..52738de8 100644 --- a/pysollib/games/pyramid.py +++ b/pysollib/games/pyramid.py @@ -1237,6 +1237,105 @@ class UpAndDown(Pyramid): self.s.talon.dealCards() # deal first card to WasteStack +# /*********************************************************************** +# // Hurricane +# ************************************************************************/ + +class Hurricane_Hint(DefaultHint): + def step010(self, dropstacks, rows): + rows = rows + self.game.s.reserves + return DefaultHint.step010(self, dropstacks, rows) + + +class Hurricane_StackMethods(Pyramid_StackMethods): + + def acceptsCards(self, from_stack, cards): + if from_stack is self: + return False + if len(cards) != 1: + return False + if not self.cards: + return False + c1 = self.cards[-1] + c2 = cards[0] + return c1.face_up and c2.face_up and c1.rank + c2.rank == 12 + + def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): + if to_stack in self.game.s.rows or \ + to_stack in self.game.s.reserves: + self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow) + else: + self.game.moveMove(ncards, self, to_stack, + frames=frames, shadow=shadow) + self.fillStack() + +class Hurricane_RowStack(Hurricane_StackMethods, BasicRowStack): + pass + +class Hurricane_Reserve(Hurricane_StackMethods, OpenStack): + pass + + +class Hurricane(Pyramid): + Hint_Class = Hurricane_Hint + + def createGame(self): + # create layout + l, s = Layout(self), self.s + + # set window + ww = l.XS + max(2*l.XOFFSET, l.XS/2) + w = l.XM + 1.5*l.XS + 4*ww + h = l.YM + 3*l.YS + self.setSize(w, h) + + # create stacks + for xx, yy in ((0,0),(1,0),(2,0),(3,0), + (0,1), (3,1), + (0,2),(1,2),(2,2),(3,2), + ): + x, y = l.XM + 1.5*l.XS + ww*xx, l.YM + l.YS*yy + stack = Hurricane_Reserve(x, y, self, max_accept=1) + stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 + s.reserves.append(stack) + + d = 3*ww - 4*l.XS - 2*l.XOFFSET + x = l.XM + 1.5*l.XS + l.XS+2*l.XOFFSET + d/2 + y = l.YM+l.YS + for i in range(3): + stack = Hurricane_RowStack(x, y, self, max_accept=1) + s.rows.append(stack) + x += l.XS + + x, y = l.XM, l.YM + s.talon = TalonStack(x, y, self) + l.createText(s.talon, 'ne') + y += 2*l.YS + s.foundations.append(AbstractFoundationStack(x, y, self, + suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, + max_accept=0, max_move=0, max_cards=52)) + l.createText(s.foundations[0], 'ne') + + # define stack-groups + l.defaultStackGroups() + + + def startGame(self): + for i in range(2): + self.s.talon.dealRow(rows=self.s.reserves, frames=0) + self.startDealSample() + self.s.talon.dealRow(rows=self.s.reserves) + self.s.talon.dealRow() + + + def fillStack(self, stack): + if stack in self.s.rows and not stack.cards and self.s.talon.cards: + old_state = self.enterState(self.S_FILL) + self.s.talon.flipMove() + self.s.talon.moveMove(1, stack) + self.leaveState(old_state) + + # register the game registerGame(GameInfo(38, Pyramid, "Pyramid", @@ -1281,4 +1380,5 @@ registerGame(GameInfo(700, Triangle, "Triangle", GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(701, UpAndDown, "Up and Down", GI.GT_PAIRING_TYPE | GI.GT_ORIGINAL, 2, 2, GI.SL_MOSTLY_LUCK)) - +registerGame(GameInfo(735, Hurricane, "Hurricane", + GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) diff --git a/pysollib/tile/tkstats.py b/pysollib/tile/tkstats.py index 6642ccb2..27b24ce1 100644 --- a/pysollib/tile/tkstats.py +++ b/pysollib/tile/tkstats.py @@ -80,8 +80,8 @@ class StatsDialog(MfxDialog): self.tkfont = tkFont.Font(parent, self.font) self.font_metrics = self.tkfont.metrics() style = Tkinter.Style() - self.heading_font = style.lookup('Heading', 'font') # treeview heading - self.heading_tkfont = tkFont.Font(parent, self.heading_font) + heading_font = style.lookup('Heading', 'font') # treeview heading + self.heading_tkfont = tkFont.Font(parent, heading_font) self.selected_game = None @@ -122,8 +122,10 @@ class StatsDialog(MfxDialog): def initKw(self, kw): kw = KwStruct(kw, strings=((_("&Play this game"), 401), - "sep",_("&OK"), - (_("&Reset..."), 500)), default=0, + "sep", _("&OK"), + (_("&Reset..."), 500)), + default=0, + separatorwidth=0, ) return MfxDialog.initKw(self, kw) @@ -340,29 +342,36 @@ class TreeFormatter(PysolStatsFormatter): tw = 20*self.w ##tw = 160 self._tabs = [tw] - font = self.tkfont + measure = self.tkfont.measure for t in arg[1:]: - tw = font.measure(t)+8 + tw = measure(t)+8 self._tabs.append(tw) self._tabs.append(10) self.parent_window.tree_tabs = self._tabs - def writeStats(self, player, sort_by='name'): - header = self.getStatHeader() - if self._tabs is None: - self._calc_tabs(header) - t1, t2, t3, t4, t5, t6, t7 = header - for column, text, anchor, tab in ( - ('#0', t1, 'nw', self._tabs[0]), - ('played', t2, 'ne', self._tabs[1]), - ('won', t3, 'ne', self._tabs[2]), - ('lost', t4, 'ne', self._tabs[3]), - ('time', t5, 'ne', self._tabs[4]), - ('moves', t6, 'ne', self._tabs[5]), - ('percent', t7, 'ne', self._tabs[6]), ): + def createHeader(self, player, header): + i = 0 + for column in ('#0',) + self.parent_window.COLUMNS: + text = header[i] + anchor = i == 0 and 'nw' or 'ne' self.tree.heading(column, text=text, command=lambda par=self.parent_window, col=column: par.headerClick(col)) + self.tree.column(column, width=16) + i += 1 + + def resizeHeader(self, player, header): + if self._tabs is not None: + return + self._calc_tabs(header) + i = 0 + for column in ('#0',) + self.parent_window.COLUMNS: + tab = self._tabs[i] self.tree.column(column, width=tab) + i += 1 + + def writeStats(self, player, sort_by='name'): + header = self.getStatHeader() + self.resizeHeader(player, header) for result in self.getStatResults(player, sort_by): # result == [name, won+lost, won, lost, time, moves, perc, id] @@ -378,24 +387,9 @@ class TreeFormatter(PysolStatsFormatter): id = self.tree.insert(None, "end", text=text, values=(won+lost, won, lost, time, moves, perc)) self.parent_window.tree_items.append(id) - return 1 def writeLog(self, player, prev_games): - if self._tabs is None: - self._calc_tabs(('', '99999999999999999999', '9999-99-99 99:99', 'XXXXXXXXXXXX')) - header = self.getLogHeader() - t1, t2, t3, t4 = header - for column, text, anchor, tab in ( - ('#0', t1, 'nw', self._tabs[0]), - ('gamenumber', t2, 'ne', self._tabs[1]), - ('date', t3, 'ne', self._tabs[2]), - ('status', t4, 'ne', self._tabs[3]), ): - self.tree.heading(column, text=text, - command=lambda par=self.parent_window, col=column: par.headerClick(col)) - self.tree.column(column, width=tab) - ##if column in ('gamenumber', 'date', 'status'): - ## self.tree.column(column, anchor='center') if not player or not prev_games: return 0 num_rows = 0 @@ -451,7 +445,12 @@ class AllGamesFrame(Tkinter.Frame): sb.config(command=self.tree.yview) bind(self.tree, '<>', self.treeviewSelected) # - self.fillTreeview(player) + self.formatter = TreeFormatter(self.app, self.tree, self, + self.dialog.heading_tkfont, + self.CHAR_W, self.CHAR_H) + self.createHeader(player) + bind(self.tree, '', + lambda e, player=player: self.fillTreeview(player)) def getSelectedGame(self): sel = self.tree.selection() @@ -480,18 +479,15 @@ class AllGamesFrame(Tkinter.Frame): self.sort_by = sort_by self.fillTreeview(self.player) - # - # - # + def createHeader(self, player): + header = self.formatter.getStatHeader() + self.formatter.createHeader(player, header) def fillTreeview(self, player): if self.tree_items: self.tree.delete(tuple(self.tree_items)) self.tree_items = [] - formatter = TreeFormatter(self.app, self.tree, self, - self.dialog.heading_tkfont, - self.CHAR_W, self.CHAR_H) - formatter.writeStats(player, sort_by=self.sort_by) + self.formatter.writeStats(player, sort_by=self.sort_by) if self.dialog.buttons: run_button = self.dialog.buttons[0] run_button.config(state='disabled') @@ -508,6 +504,9 @@ class LogDialog(MfxDialog): self.font = app.getFont('default') self.tkfont = tkFont.Font(parent, self.font) + style = Tkinter.Style() + heading_font = style.lookup('Heading', 'font') # treeview heading + self.heading_tkfont = tkFont.Font(parent, heading_font) self.font_metrics = self.tkfont.metrics() self.CHAR_H = self.font_metrics['linespace'] @@ -545,8 +544,10 @@ class LogDialog(MfxDialog): def initKw(self, kw): kw = KwStruct(kw, strings=(_("&OK"), - (_("&Save to file"), 500)), default=0, + (_("&Save to file"), 500)), + default=0, width=76*self.CHAR_W, + separatorwidth=0, ) return MfxDialog.initKw(self, kw) @@ -566,18 +567,28 @@ class LogDialog(MfxDialog): FullLog_StatsDialog = SessionLog_StatsDialog = LogDialog +# /*********************************************************************** +# // +# ************************************************************************/ - -##class FullLog_StatsDialog(AllGames_StatsDialog): class FullLogFrame(AllGamesFrame): COLUMNS = ('gamenumber', 'date', 'status') + def __init__(self, dialog, parent, app, player, **kw): + AllGamesFrame.__init__(self, dialog, parent, app, player, **kw) + header = ('', '99999999999999999999', '9999-99-99 99:99', + 'XXXXXXXXXXXX') + self.formatter.resizeHeader(player, header) + + def createHeader(self, player): + header = self.formatter.getLogHeader() + self.formatter.createHeader(player, header) + def fillTreeview(self, player): - formatter = TreeFormatter(self.app, self.tree, self, - self.dialog.tkfont, - self.CHAR_W, self.CHAR_H) - formatter.writeFullLog(player) + if self.tree_items: + return + self.formatter.writeFullLog(player) def treeviewSelected(self, *args): pass @@ -585,13 +596,11 @@ class FullLogFrame(AllGamesFrame): pass -##class SessionLog_StatsDialog(FullLog_StatsDialog): class SessionLogFrame(FullLogFrame): def fillTreeview(self, player): - formatter = TreeFormatter(self.app, self.tree, self, - self.dialog.tkfont, - self.CHAR_W, self.CHAR_H) - formatter.writeSessionLog(player) + if self.tree_items: + return + self.formatter.writeSessionLog(player) # /*********************************************************************** @@ -640,6 +649,7 @@ class Status_StatsDialog(MfxMessageDialog): padx=20, ) + # /*********************************************************************** # // # ************************************************************************/ @@ -824,18 +834,17 @@ class TopFrame(Tkinter.Frame): # // # ************************************************************************/ -##class ProgressionDialog(MfxDialog): - class ProgressionFrame(Tkinter.Frame): def __init__(self, dialog, parent, app, player, gameid, **kw): Tkinter.Frame.__init__(self, parent) - self.text_height = dialog.font_metrics['linespace'] - measure = dialog.tkfont.measure - self.text_width_1 = measure('XX.XX') - self.text_width_2 = measure('XX.XX.XX') + self.mapped = False + self.dialog = dialog + self.app = app + self.player = player + self.gameid = gameid self.items = [] self.formatter = ProgressionFormatter(app, player, gameid) @@ -860,55 +869,6 @@ class ProgressionFrame(Tkinter.Frame): width=self.canvas_width, height=self.canvas_height) canvas.pack(side='left', padx=5) - # - dir = os.path.join('images', 'stats') - try: - fn = app.dataloader.findImage('progression', dir) - self.bg_image = loadImage(fn) - canvas.create_image(0, 0, image=self.bg_image, anchor='nw') - except: - pass - # - tw = max(measure(_('Games/day')), - measure(_('Games/week')), - measure(_('% won'))) - self.left_margin = self.xmargin+tw/2 - self.right_margin = self.xmargin+tw/2 - self.top_margin = 15+self.text_height - self.bottom_margin = 15+self.text_height+10+self.text_height - # - x0, y0 = self.left_margin, self.canvas_height-self.bottom_margin - x1, y1 = self.canvas_width-self.right_margin, self.top_margin - canvas.create_rectangle(x0, y0, x1, y1, fill='white') - # horizontal axis - canvas.create_line(x0, y0, x1, y0, width=3) - - # left vertical axis - canvas.create_line(x0, y0, x0, y1, width=3) - t = _('Games/day') - self.games_text_id = canvas.create_text(x0-4, y1-4, anchor='s', text=t) - - # right vertical axis - canvas.create_line(x1, y0, x1, y1, width=3) - canvas.create_text(x1+4, y1-4, anchor='s', text=_('% won')) - - # caption - d = self.text_height - x, y = self.xmargin, self.canvas_height-self.ymargin - id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', - fill=self.played_color) - x += d+5 - canvas.create_text(x, y, anchor='sw', text=_('Played')) - x += measure(_('Played'))+20 - id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', - fill=self.won_color) - x += d+5 - canvas.create_text(x, y, anchor='sw', text=_('Won')) - x += measure(_('Won'))+20 - id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', - fill=self.percent_color) - x += d+5 - canvas.create_text(x, y, anchor='sw', text=_('% won')) # right frame right_frame = Tkinter.Frame(frame) @@ -963,8 +923,74 @@ class ProgressionFrame(Tkinter.Frame): ) b.pack(fill='x', expand=True, padx=3, pady=1) + #self.createGraph() + bind(canvas, '', self.createGraph) + + + def createGraph(self, event): + if self.mapped: + return + self.mapped = True + + canvas = self.canvas + + self.text_height = self.dialog.font_metrics['linespace'] + measure = self.dialog.tkfont.measure + self.text_width_1 = measure('XX.XX') + self.text_width_2 = measure('XX.XX.XX') + + dir = os.path.join('images', 'stats') + try: + fn = self.app.dataloader.findImage('progression', dir) + self.bg_image = loadImage(fn) + canvas.create_image(0, 0, image=self.bg_image, anchor='nw') + except: + pass + # + tw = max(measure(_('Games/day')), + measure(_('Games/week')), + measure(_('% won'))) + self.left_margin = self.xmargin+tw/2 + self.right_margin = self.xmargin+tw/2 + self.top_margin = 15+self.text_height + self.bottom_margin = 15+self.text_height+10+self.text_height + # + x0, y0 = self.left_margin, self.canvas_height-self.bottom_margin + x1, y1 = self.canvas_width-self.right_margin, self.top_margin + canvas.create_rectangle(x0, y0, x1, y1, fill='white') + # horizontal axis + canvas.create_line(x0, y0, x1, y0, width=3) + + # left vertical axis + canvas.create_line(x0, y0, x0, y1, width=3) + t = _('Games/day') + self.games_text_id = canvas.create_text(x0-4, y1-4, anchor='s', text=t) + + # right vertical axis + canvas.create_line(x1, y0, x1, y1, width=3) + canvas.create_text(x1+4, y1-4, anchor='s', text=_('% won')) + + # caption + d = self.text_height + x, y = self.xmargin, self.canvas_height-self.ymargin + id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', + fill=self.played_color) + x += d+5 + canvas.create_text(x, y, anchor='sw', text=_('Played')) + x += measure(_('Played'))+20 + id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', + fill=self.won_color) + x += d+5 + canvas.create_text(x, y, anchor='sw', text=_('Won')) + x += measure(_('Won'))+20 + id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', + fill=self.percent_color) + x += d+5 + canvas.create_text(x, y, anchor='sw', text=_('% won')) + self.updateGraph() + def updateGraph(self, *args): interval = self.variable.get() canvas = self.canvas