diff --git a/pysollib/game.py b/pysollib/game.py index f2edfccf..3a2e5cad 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -262,11 +262,12 @@ class Game: def initBindings(self): # note: a Game is only allowed to bind self.canvas and not to self.top - bind(self.canvas, "<2>", self.dropHandler) ##bind(self.canvas, "", self.undoHandler) bind(self.canvas, "<1>", self.undoHandler) + bind(self.canvas, "<2>", self.dropHandler) bind(self.canvas, "<3>", self.redoHandler) bind(self.canvas, '', self._unmapHandler) + bind(self.canvas, '', self.configureHandler, add=True) def __createCommon(self, app): self.busy = 1 @@ -535,6 +536,9 @@ class Game: self.stats.update_time = time.time() self.busy = old_busy # + ##self.configureHandler() # reallocateCards + after(self.top, 200, self.configureHandler) # wait for canvas is mapped + # if TOOLKIT == 'gtk': ## FIXME if self.top: @@ -973,6 +977,11 @@ class Game: if self.app and not self.pause: self.app.menubar.mPause() + def configureHandler(self, event=None): + if not self.canvas: + return + for stack in self.allstacks: + stack.updatePositions() # # sound support diff --git a/pysollib/games/bristol.py b/pysollib/games/bristol.py index 375f8de7..9fc6e4f8 100644 --- a/pysollib/games/bristol.py +++ b/pysollib/games/bristol.py @@ -444,8 +444,9 @@ class Interment(Game): x += l.XS x, y = l.XM, l.YM+l.YS for i in range(3): - s.xwastes.append(Interment_Waste(x, y, self, - max_cards=UNLIMITED_CARDS)) + stack = Interment_Waste(x, y, self, max_cards=UNLIMITED_CARDS) + l.createText(stack, 'ne') + s.xwastes.append(stack) y += l.YS x, y = l.XM+1.5*l.XS, l.YM+l.YS for i in range(8): diff --git a/pysollib/move.py b/pysollib/move.py index c1513bf6..1bcb1e0e 100644 --- a/pysollib/move.py +++ b/pysollib/move.py @@ -96,6 +96,8 @@ class AMoveMove(AtomicMove): from_stack.removeCard() for c in cards: to_stack.addCard(c) + from_stack.updatePositions() + to_stack.updatePositions() def redo(self, game): self._doMove(game, self.ncards, game.allstacks[self.from_stack_id], diff --git a/pysollib/options.py b/pysollib/options.py index c5dc7f6c..db7ab1d5 100644 --- a/pysollib/options.py +++ b/pysollib/options.py @@ -61,6 +61,7 @@ animations = integer(0, 5) redeal_animation = boolean win_animation = boolean flip_animation = boolean +squeeze_stacks = boolean shadow = boolean shade = boolean shrink_face_down = boolean @@ -187,6 +188,7 @@ class Options: ('redeal_animation', 'bool'), ('win_animation', 'bool'), ('flip_animation', 'bool'), + ('squeeze_stacks', 'bool'), ('shadow', 'bool'), ('shade', 'bool'), ('shrink_face_down', 'bool'), @@ -255,6 +257,7 @@ class Options: self.redeal_animation = True self.win_animation = True self.flip_animation = True + self.squeeze_stacks = True self.shadow = True self.shade = True self.shrink_face_down = True diff --git a/pysollib/stack.py b/pysollib/stack.py index baa3597e..628f21f3 100644 --- a/pysollib/stack.py +++ b/pysollib/stack.py @@ -408,6 +408,7 @@ class Stack: # bottom image if self.is_visible: self.prepareBottom() + self.INIT_CARD_YOFFSET = self.CARD_YOFFSET # for reallocateCards # stack bottom image def prepareBottom(self): @@ -859,6 +860,57 @@ class Stack: ## t = t + " (%d)" % visible self.texts.ncards.config(text=t) + def updatePositions(self): + # squeeze the stack if a cards is off-screen + if self.reallocateCards(): + for c in self.cards: + self._position(c) + + def reallocateCards(self): + # change CARD_YOFFSET if a cards is off-screen + if not self.game.app.opt.squeeze_stacks: + return False + if TOOLKIT != 'tk': + return False + if self.CARD_XOFFSET != (0,): + return False + if len(self.CARD_YOFFSET) != 1: + return False + if self.CARD_YOFFSET[0] <= 0: + return False + if len(self.cards) <= 1: + return False + if not self.canvas.winfo_ismapped(): + return False + yoffset = self.CARD_YOFFSET[0] + cardh = self.game.app.images.CARDH / 2 # 1/2 of a card is visible + num_face_up = len([c for c in self.cards if c.face_up]) + num_face_down = len(self.cards) - num_face_up + stack_height = int(self.y + + num_face_down * yoffset / self.shrink_face_down + + num_face_up * yoffset + + cardh) + visible_height = self.canvas.winfo_height() + game_height = self.game.height + 2*self.canvas.ymargin + height = max(visible_height, game_height) + if stack_height > height: + # squeeze stack + n = num_face_down / self.shrink_face_down + num_face_up + dy = float(height - self.y - cardh) / n + if dy < yoffset: + self.CARD_YOFFSET = (dy,) + return True + elif stack_height < height: + # expande stack + if self.CARD_YOFFSET == self.INIT_CARD_YOFFSET: + return False + n = num_face_down / self.shrink_face_down + num_face_up + dy = float(height - self.y - cardh) / n + dy = min(dy, self.INIT_CARD_YOFFSET[0]) + self.CARD_YOFFSET = (dy,) + return True + return False + def basicShallHighlightSameRank(self, card): # by default all open stacks are available for highlighting assert card in self.cards