diff --git a/pysollib/app.py b/pysollib/app.py index 993eae8c..a1022d71 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -633,7 +633,9 @@ class Application: # widgets # # create the menubar - self.menubar = PysolMenubar(self, self.top) + if self.intro.progress: self.intro.progress.update(step=1) + self.menubar = PysolMenubar(self, self.top, + progress=self.intro.progress) # create the statusbar(s) self.statusbar = PysolStatusbar(self.top) self.statusbar.show(self.opt.statusbar) diff --git a/pysollib/games/camelot.py b/pysollib/games/camelot.py index 8ddb419e..0e1ea5b8 100644 --- a/pysollib/games/camelot.py +++ b/pysollib/games/camelot.py @@ -22,7 +22,6 @@ __all__ = [] # imports -import sys # PySol imports from pysollib.gamedb import registerGame, GameInfo, GI @@ -31,6 +30,9 @@ from pysollib.stack import * from pysollib.game import Game from pysollib.layout import Layout from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint +from pysollib.pysoltk import MfxCanvasText + +from numerica import Numerica_Hint # /*********************************************************************** @@ -174,7 +176,6 @@ class Camelot(Game): def startGame(self): self.is_fill = False - self.nnn = 0 self.s.talon.fillStack() @@ -212,8 +213,129 @@ class Camelot(Game): return [self.is_fill] +# /*********************************************************************** +# // Sly Fox +# ************************************************************************/ + +class SlyFox_Foundation(SS_FoundationStack): + def acceptsCards(self, from_stack, cards): + if not SS_FoundationStack.acceptsCards(self, from_stack, cards): + return False + if from_stack in self.game.s.rows: + return self.game.num_dealled <= 0 + return True + + +class SlyFox_Talon(OpenTalonStack): + rightclickHandler = OpenStack.rightclickHandler + doubleclickHandler = OpenStack.doubleclickHandler + + def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): + old_state = self.game.enterState(self.game.S_FILL) + self.game.saveStateMove(2|16) # for undo + if old_state == self.game.S_PLAY and to_stack in self.game.s.rows: + n = self.game.num_dealled + if n < 0: n = 0 + self.game.num_dealled = (n+1)%20 + self.game.saveStateMove(1|16) # for redo + self.game.leaveState(old_state) + OpenTalonStack.moveMove(self, ncards, to_stack, frames, shadow) + + +class SlyFox_RowStack(ReserveStack): + def acceptsCards(self, from_stack, cards): + if not ReserveStack.acceptsCards(self, from_stack, cards): + return False + return from_stack is self.game.s.talon + + +class SlyFox(Game): + Hint_Class = Numerica_Hint + + num_dealled = -1 + + def createGame(self): + l, s = Layout(self), self.s + self.setSize(l.XM+9*l.XS, l.YM+4*l.YS) + + x, y = l.XM, l.YM + s.talon = SlyFox_Talon(x, y, self) + s.waste = s.talon + l.createText(s.talon, 'ne') + tx, ty, ta, tf = l.getTextAttr(s.talon, "ss") + font = self.app.getFont("canvas_default") + self.texts.misc = MfxCanvasText(self.canvas, tx, ty, + anchor=ta, font=font) + + y = l.YM + for i in range(4): + x = l.XM+1.5*l.XS + for j in range(5): + stack = SlyFox_RowStack(x, y, self, max_cards=UNLIMITED_CARDS) + stack.CARD_YOFFSET = 0 + s.rows.append(stack) + x += l.XS + y += l.YS + + x, y = self.width-2*l.XS, l.YM + for i in range(4): + s.foundations.append(SlyFox_Foundation(x, y, self, suit=i)) + s.foundations.append(SlyFox_Foundation(x+l.XS, y, self, suit=i, + base_rank=KING, dir=-1)) + y += l.YS + + l.defaultStackGroups() + + + def _shuffleHook(self, cards): + return self._shuffleHookMoveToTop(cards, + lambda c: (c.rank in (ACE, KING) and c.deck == 0, (c.suit, c.rank))) + + def startGame(self): + self.num_dealled = -1 + self.s.talon.dealRow(rows=self.s.foundations, frames=0) + self.startDealSample() + self.s.talon.dealRow() + self.s.talon.fillStack() + + def _restoreGameHook(self, game): + self.num_dealled = game.loadinfo.num_dealled + + def _loadGameHook(self, p): + self.loadinfo.addattr(num_dealled=p.load()) + + def _saveGameHook(self, p): + p.dump(self.num_dealled) + + def setState(self, state): + # restore saved vars (from undo/redo) + self.num_dealled = state[0] + + def getState(self): + # save vars (for undo/redo) + return [self.num_dealled] + + + def fillStack(self, stack): + if self.num_dealled == -1 and stack in self.s.rows and not stack.cards: + old_state = self.enterState(self.S_FILL) + self.s.talon.moveMove(1, stack) + self.leaveState(old_state) + + + def updateText(self): + if self.preview > 1: + return + n = self.num_dealled + if n < 0: n = 0 + text=str(n)+'/20' + self.texts.misc.config(text=text) + + # register the game registerGame(GameInfo(280, Camelot, "Camelot", GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED)) +registerGame(GameInfo(610, SlyFox, "Sly Fox", + GI.GT_NUMERICA, 2, 0, GI.SL_MOSTLY_SKILL)) diff --git a/pysollib/games/katzenschwanz.py b/pysollib/games/katzenschwanz.py index e67bb150..2c737756 100644 --- a/pysollib/games/katzenschwanz.py +++ b/pysollib/games/katzenschwanz.py @@ -266,7 +266,7 @@ class SalicLaw(DerKatzenschwanz): l, s = Layout(self), self.s # set size - self.setSize(l.XM + 10*l.XS, l.YM + 7*l.YS) + self.setSize(l.XM+10*l.XS, l.YM+(5+len(self.Foundation_Classes))*l.YS) # playcards = 4*l.YS / l.YOFFSET @@ -288,8 +288,8 @@ class SalicLaw(DerKatzenschwanz): x += l.XS y += l.YS - x, y = l.XM, l.YM+2*l.YS - self.setRegion(s.foundations[8:], (-999, -999, 999999, y - l.XM / 2)) + x, y = l.XM, l.YM+l.YS*len(self.Foundation_Classes) + self.setRegion(s.foundations[-8:], (-999, -999, 999999, y - l.XM / 2)) for i in range(8): stack = self.RowStack_Class(x, y, self, max_move=1) stack.CARD_XOFFSET = xoffset @@ -388,6 +388,66 @@ class LaggardLady(SalicLaw): return True +# /*********************************************************************** +# // Faerie Queen +# ************************************************************************/ + +class FaerieQueen_RowStack(RK_RowStack): + def acceptsCards(self, from_stack, cards): + if self.game.s.talon.cards: + return False + if len(self.cards) == 1: + return True + return RK_RowStack.acceptsCards(self, from_stack, cards) + + +class FaerieQueen(SalicLaw): + + Foundation_Classes = [ + StackWrapper(RK_FoundationStack, max_move=0, max_cards=12) + ] + RowStack_Class = StackWrapper(FaerieQueen_RowStack, min_cards=1, max_move=1) + + def isGameWon(self): + if self.s.talon.cards: + return False + for s in self.s.foundations: + if len(s.cards) != 12: + return False + return True + + def getQuickPlayScore(self, ncards, from_stack, to_stack): + return int(len(to_stack.cards) > 1) + + shallHighlightMatch = Game._shallHighlightMatch_RK + + +# /*********************************************************************** +# // Glencoe +# ************************************************************************/ + +class Glencoe_Foundation(RK_FoundationStack): + def acceptsCards(self, from_stack, cards): + if not RK_FoundationStack.acceptsCards(self, from_stack, cards): + return False + c = cards[0] + if c.rank in (4, 5): + i = list(self.game.s.foundations).index(self) % 8 + r = self.game.s.rows[i] + if not r.cards: + return False + return c.suit == r.cards[0].suit + return True + + +class Glencoe(LaggardLady): + + Foundation_Classes = [ + StackWrapper(Glencoe_Foundation, base_rank=5, max_cards=6), + StackWrapper(Glencoe_Foundation, base_rank=4, max_cards=6, dir=-1, mod=13), + ] + + # register the game registerGame(GameInfo(141, DerKatzenschwanz, "Cat's Tail", @@ -406,5 +466,9 @@ registerGame(GameInfo(442, Deep, "Deep", GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(523, LaggardLady, "Laggard Lady", GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(611, FaerieQueen, "Faerie Queen", + GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(612, Glencoe, "Glencoe", + GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) diff --git a/pysollib/games/klondike.py b/pysollib/games/klondike.py index fa295af8..6018d548 100644 --- a/pysollib/games/klondike.py +++ b/pysollib/games/klondike.py @@ -1204,6 +1204,24 @@ class LuckyPiles(LuckyThirteen): shallHighlightMatch = Game._shallHighlightMatch_SS +# /*********************************************************************** +# // Legion +# ************************************************************************/ + +class Legion(Klondike): + + def createGame(self): + Klondike.createGame(self, max_rounds=1, rows=8) + + def startGame(self): + self.startDealSample() + self.s.talon.dealRow() + for i in (1,2,3): + self.s.talon.dealRow(rows=self.s.rows[i:-i], flip=0) + self.s.talon.dealRow(rows=self.s.rows[i:-i]) + self.s.talon.dealCards() + + # register the game registerGame(GameInfo(2, Klondike, "Klondike", @@ -1330,4 +1348,6 @@ registerGame(GameInfo(601, AmericanCanister, "American Canister", GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(602, BritishCanister, "British Canister", GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) +registerGame(GameInfo(607, Legion, "Legion", + GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED)) diff --git a/pysollib/games/numerica.py b/pysollib/games/numerica.py index f59a515e..a53121af 100644 --- a/pysollib/games/numerica.py +++ b/pysollib/games/numerica.py @@ -319,6 +319,7 @@ class PussInTheCorner(Numerica): # /*********************************************************************** # // Frog # // Fly +# // Fanny # ************************************************************************/ class Frog(Game): @@ -399,6 +400,18 @@ class Fly(Frog): self.s.talon.dealCards() +class Fanny(Frog): + + Foundation_Class = RK_FoundationStack + + def startGame(self): + self.startDealSample() + for i in range(11): + self.s.talon.dealRow(self.s.reserves, flip=0) + self.s.talon.dealRow(self.s.reserves) + self.s.talon.dealCards() + + # /*********************************************************************** # // Gnat # ************************************************************************/ @@ -751,4 +764,6 @@ registerGame(GameInfo(599, Assembly, "Assembly", GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(600, AnnoDomini, "Anno Domini", GI.GT_NUMERICA, 1, 2, GI.SL_BALANCED)) +registerGame(GameInfo(613, Fanny, "Fanny", + GI.GT_NUMERICA, 2, 0, GI.SL_BALANCED)) diff --git a/pysollib/games/royalcotillion.py b/pysollib/games/royalcotillion.py index ffb2e5f1..606802a3 100644 --- a/pysollib/games/royalcotillion.py +++ b/pysollib/games/royalcotillion.py @@ -42,6 +42,9 @@ from pysollib.game import Game from pysollib.layout import Layout from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint +from unionsquare import UnionSquare_Foundation + + # /*********************************************************************** # // Royal Cotillion # ************************************************************************/ @@ -220,6 +223,7 @@ class Kingdom(RoyalCotillion): # /*********************************************************************** # // Alhambra # // Granada +# // Grant's Reinforcement # ************************************************************************/ @@ -267,12 +271,14 @@ class Alhambra_Talon(DealRowTalonStack): class Alhambra(Game): Hint_Class = Alhambra_Hint - def createGame(self, rows=1): + RowStack_Class = StackWrapper(Alhambra_RowStack, base_rank=ANY_RANK) + + def createGame(self, rows=1, reserves=8, playcards=3): # create layout l, s = Layout(self), self.s # set window - self.setSize(l.XM + 8*l.XS, l.YM + 4*l.YS) + self.setSize(l.XM+8*l.XS, l.YM+3.5*l.YS+playcards*l.YOFFSET) # create stacks x, y, = l.XM, l.YM @@ -284,22 +290,23 @@ class Alhambra(Game): s.foundations.append(SS_FoundationStack(x, y, self, suit=i, max_move=0, base_rank=KING, dir=-1)) x = x + l.XS - x, y, = l.XM, y + l.YS - for i in range(8): + x, y, = l.XM+(8-reserves)*l.XS/2, y+l.YS + for i in range(reserves): stack = OpenStack(x, y, self, max_accept=0) stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, l.YOFFSET s.reserves.append(stack) x = x + l.XS - x, y = l.XM+(8-1-rows)*l.XS/2, y+l.YS+5*l.YOFFSET + x, y = l.XM+(8-1-rows)*l.XS/2, self.height-l.YS s.talon = Alhambra_Talon(x, y, self, max_rounds=3) l.createText(s.talon, "sw") x += l.XS for i in range(rows): - stack = Alhambra_RowStack(x, y, self, mod=13, - max_accept=1, base_rank=ANY_RANK) + stack = self.RowStack_Class(x, y, self, mod=13, max_accept=1) stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0 s.rows.append(stack) x += l.XS + if rows == 1: + l.createText(stack, 'se') # define stack-groups (non default) l.defaultStackGroups() @@ -328,6 +335,31 @@ class Granada(Alhambra): Alhambra.createGame(self, rows=4) +class GrantsReinforcement(Alhambra): + RowStack_Class = StackWrapper(Alhambra_RowStack, base_rank=NO_RANK) + + def createGame(self): + Alhambra.createGame(self, reserves=4, playcards=11) + + def startGame(self): + self.s.talon.dealRow(rows=self.s.foundations, frames=0) + for i in range(11): + self.s.talon.dealRow(rows=self.s.reserves, frames=0) + self.startDealSample() + self.s.talon.dealRow(rows=self.s.reserves) + self.s.talon.dealCards() + + def fillStack(self, stack): + for r in self.s.reserves: + if r.cards: + continue + if self.s.talon.cards: + old_state = self.enterState(self.S_FILL) + self.s.talon.flipMove() + self.s.talon.moveMove(1, r) + self.leaveState(old_state) + + # /*********************************************************************** # // Carpet # ************************************************************************/ @@ -589,6 +621,105 @@ class ThreePirates(Game): shallHighlightMatch = Game._shallHighlightMatch_SS +# /*********************************************************************** +# // Frames +# ************************************************************************/ + +class Frames_Foundation(UnionSquare_Foundation): + def acceptsCards(self, from_stack, cards): + if not UnionSquare_Foundation.acceptsCards(self, from_stack, cards): + return False + return from_stack in self.game.s.rows + + +class Frames_RowStack(UD_SS_RowStack): + def acceptsCards(self, from_stack, cards): + if not UD_SS_RowStack.acceptsCards(self, from_stack, cards): + return False + if not (from_stack in self.game.s.reserves or + from_stack in self.game.s.rows): + return False + if len(self.cards) > 1: + cs = self.cards+cards + if not (isSameSuitSequence(cs, dir=1) or + isSameSuitSequence(cs, dir=-1)): + return False + if from_stack in self.game.s.reserves: + if (hasattr(self.cap, 'column') and + self.cap.column != from_stack.cap.column): + return False + if (hasattr(self.cap, 'row') and + self.cap.row != from_stack.cap.row): + return False + return True + + +class Frames(Game): + Hint_Class = CautiousDefaultHint + + def createGame(self): + l, s = Layout(self), self.s + + self.setSize(l.XM+8*l.XS, l.YM+5*l.YS) + + x0, y0 = l.XM+2*l.XS, l.YM + # foundations (corners) + suit = 0 + for i, j in ((0,0),(5,0),(0,4),(5,4)): + x, y = x0+i*l.XS, y0+j*l.YS + s.foundations.append(Frames_Foundation(x, y, self, + suit=suit, dir=0, max_cards=26)) + suit += 1 + # rows (frame) + for i in (1,2,3,4): + for j in (0,4): + x, y = x0+i*l.XS, y0+j*l.YS + stack = Frames_RowStack(x, y, self) + s.rows.append(stack) + stack.cap.addattr(column=i) + stack.CARD_YOFFSET = 0 + for i in (0,5): + for j in (1,2,3): + x, y = x0+i*l.XS, y0+j*l.YS + stack = Frames_RowStack(x, y, self) + s.rows.append(stack) + stack.cap.addattr(row=j) + stack.CARD_YOFFSET = 0 + # reserves (picture) + for j in (1,2,3): + for i in (1,2,3,4): + x, y = x0+i*l.XS, y0+j*l.YS + stack = OpenStack(x, y, self) + s.reserves.append(stack) + stack.cap.addattr(column=i) + stack.cap.addattr(row=j) + # talon & waste + x, y, = l.XM, l.YM + s.talon = WasteTalonStack(x, y, self, max_rounds=1) + l.createText(s.talon, 'ne') + y += l.YS + s.waste = WasteStack(x, y, self) + l.createText(s.waste, 'ne') + + l.defaultStackGroups() + + def startGame(self): + self.s.talon.dealRow(frames=0) + self.startDealSample() + self.s.talon.dealRow(rows=self.s.reserves) + self.s.talon.dealCards() + + def fillStack(self, stack): + if not stack.cards and stack in self.s.reserves: + if not self.s.waste.cards: + self.s.talon.dealCards() + if self.s.waste.cards: + old_state = self.enterState(self.S_FILL) + self.s.waste.moveMove(1, stack) + self.leaveState(old_state) + + shallHighlightMatch = Game._shallHighlightMatch_SS + # register the game registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion", @@ -615,4 +746,8 @@ registerGame(GameInfo(465, Granada, "Granada", GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED)) registerGame(GameInfo(579, ThreePirates, "Three Pirates", GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL)) +registerGame(GameInfo(608, Frames, "Frames", + GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL)) +registerGame(GameInfo(609, GrantsReinforcement, "Grant's Reinforcement", + GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_SKILL)) diff --git a/pysollib/main.py b/pysollib/main.py index 588f1867..04e9e9dc 100644 --- a/pysollib/main.py +++ b/pysollib/main.py @@ -431,7 +431,7 @@ Sounds and background music will be disabled.'''), if app.tabletile_index > 0: color = "#008200" app.intro.progress = PysolProgressBar(app, top, title=title, color=color, - images=app.progress_images) + images=app.progress_images, norm=1.32) # prepare other images app.loadImages2() diff --git a/pysollib/tk/menubar.py b/pysollib/tk/menubar.py index 5d1bfa10..7364dfec 100644 --- a/pysollib/tk/menubar.py +++ b/pysollib/tk/menubar.py @@ -196,7 +196,7 @@ class MfxMenu(MfxMenubar): # ************************************************************************/ class PysolMenubar(PysolMenubarActions): - def __init__(self, app, top): + def __init__(self, app, top, progress=None): PysolMenubarActions.__init__(self, app, top) # init columnbreak self.__cb_max = int(self.top.winfo_screenheight()/23) @@ -205,11 +205,15 @@ class PysolMenubar(PysolMenubarActions): ## if sh >= 600: self.__cb_max = 27 ## if sh >= 768: self.__cb_max = 32 ## if sh >= 1024: self.__cb_max = 40 + self.progress = progress # create menus self.__menubar = None self.__menupath = {} self.__keybindings = {} self._createMenubar() + + if self.progress: self.progress.update(step=1) + # set the menubar self.updateBackgroundImagesMenu() self.top.config(menu=self.__menubar) @@ -225,6 +229,9 @@ class PysolMenubar(PysolMenubarActions): return "normal" return "disabled" + def updateProgress(self): + if self.progress: self.progress.update(step=1) + # # create the menubar @@ -268,9 +275,13 @@ class PysolMenubar(PysolMenubarActions): menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit) menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q") + if self.progress: self.progress.update(step=1) + menu = MfxMenu(self.__menubar, label=n_("&Select")) self._addSelectGameMenu(menu) + if self.progress: self.progress.update(step=1) + menu = MfxMenu(self.__menubar, label=n_("&Edit")) menu.add_command(label=n_("&Undo"), command=self.mUndo, accelerator="Z") menu.add_command(label=n_("&Redo"), command=self.mRedo, accelerator="R") @@ -321,6 +332,9 @@ class PysolMenubar(PysolMenubarActions): menu.add_command(label=n_("Demo (&all games)"), command=self.mMixedDemo) menu.add_separator() menu.add_command(label=n_("Piles description"), command=self.mStackDesk, accelerator="F2") + + if self.progress: self.progress.update(step=1) + menu = MfxMenu(self.__menubar, label=n_("&Options")) menu.add_command(label=n_("&Player options..."), command=self.mOptPlayerOptions) submenu = MfxMenu(menu, label=n_("&Automatic play")) @@ -383,6 +397,8 @@ class PysolMenubar(PysolMenubarActions): ### menu.add_separator() ### menu.add_command(label="Save options", command=self.mOptSave) + if self.progress: self.progress.update(step=1) + menu = MfxMenu(self.__menubar, label=n_("&Help")) menu.add_command(label=n_("&Contents"), command=self.mHelp, accelerator=m+"F1") menu.add_command(label=n_("&How to play"), command=self.mHelpHowToPlay) @@ -511,6 +527,7 @@ class PysolMenubar(PysolMenubarActions): submenu = MfxMenu(menu, label=n_("&French games")) self._addSelectGameSubMenu(submenu, games, GI.SELECT_GAME_BY_TYPE, self.mSelectGame, self.tkopt.gameid) + if self.progress: self.progress.update(step=1) submenu = MfxMenu(menu, label=n_("&Mahjongg games")) self._addSelectMahjonggGameSubMenu(submenu, self.mSelectGame, self.tkopt.gameid) @@ -522,6 +539,7 @@ class PysolMenubar(PysolMenubarActions): self._addSelectGameSubMenu(submenu, games, GI.SELECT_SPECIAL_GAME_BY_TYPE, self.mSelectGame, self.tkopt.gameid) menu.add_separator() + if self.progress: self.progress.update(step=1) submenu = MfxMenu(menu, label=n_("All games by name")) self._addSelectAllGameSubMenu(submenu, games, self.mSelectGame, self.tkopt.gameid) @@ -620,6 +638,7 @@ class PysolMenubar(PysolMenubarActions): n, d = 0, self.__cb_max i = 0 while True: + if self.progress: self.progress.update(step=1) columnbreak = i > 0 and (i % d) == 0 i += 1 if not g[n:n+d]: diff --git a/pysollib/tk/progressbar.py b/pysollib/tk/progressbar.py index fc8df506..cbbc3b62 100644 --- a/pysollib/tk/progressbar.py +++ b/pysollib/tk/progressbar.py @@ -48,8 +48,8 @@ from tkutil import makeToplevel, setTransient, wm_set_icon # ************************************************************************/ class PysolProgressBar: - def __init__(self, app, parent, title=None, images=None, - color="blue", width=300, height=25, show_text=1): + def __init__(self, app, parent, title=None, images=None, color="blue", + width=300, height=25, show_text=1, norm=1): self.parent = parent self.percent = 0 self.top = makeToplevel(parent, title=title) @@ -84,6 +84,8 @@ class PysolProgressBar: setTransient(self.top, None, relx=0.5, rely=0.5) else: self.update(percent=0) + self.norm = norm + self.steps_sum = 0 def wmDeleteWindow(self): return EVENT_HANDLED @@ -104,6 +106,9 @@ class PysolProgressBar: self.percent = percent def update(self, percent=None, step=1): + self.steps_sum += step + ##print self.steps_sum + step = step/self.norm if self.top is None: # already destroyed return if percent is None: