From 97537e05a25476db7d9312ef203ff356936a07e9 Mon Sep 17 00:00:00 2001 From: skomoroh Date: Sun, 13 Aug 2006 21:10:55 +0000 Subject: [PATCH] + 1 new game + new stacks: DealRowRedealTalonStack and DealReserveRedealTalonStack ++ support GTK started git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@46 39dd0a4e-7c14-0410-91b3-c4f2d318f732 --- pysollib/actions.py | 76 ++--- pysollib/app.py | 71 ++--- pysollib/game.py | 2 +- pysollib/games/pyramid.py | 104 ++----- pysollib/games/sultan.py | 56 ++++ pysollib/games/tournament.py | 43 +-- pysollib/pysolgtk/__init__.py | 0 pysollib/pysolgtk/card.py | 137 +++++++++ pysollib/pysolgtk/colorsdialog.py | 45 +++ pysollib/pysolgtk/demooptionsdialog.py | 56 ++++ pysollib/pysolgtk/edittextdialog.py | 52 ++++ pysollib/pysolgtk/findcarddialog.py | 55 ++++ pysollib/pysolgtk/fontsdialog.py | 48 +++ pysollib/pysolgtk/gameinfodialog.py | 42 +++ pysollib/pysolgtk/menubar.py | 295 ++++++++++++++++++ pysollib/pysolgtk/playeroptionsdialog.py | 52 ++++ pysollib/pysolgtk/progressbar.py | 173 +++++++++++ pysollib/pysolgtk/selectcardset.py | 50 +++ pysollib/pysolgtk/selecttile.py | 50 +++ pysollib/pysolgtk/soundoptionsdialog.py | 50 +++ pysollib/pysolgtk/statusbar.py | 75 +++++ pysollib/pysolgtk/timeoutsdialog.py | 42 +++ pysollib/pysolgtk/tkcanvas.py | 370 +++++++++++++++++++++++ pysollib/pysolgtk/tkconst.py | 66 ++++ pysollib/pysolgtk/tkhtml.py | 56 ++++ pysollib/pysolgtk/tkstats.py | 65 ++++ pysollib/pysolgtk/tkutil.py | 267 ++++++++++++++++ pysollib/pysolgtk/tkwidget.py | 222 ++++++++++++++ pysollib/pysolgtk/tkwrap.py | 294 ++++++++++++++++++ pysollib/pysolgtk/toolbar.py | 177 +++++++++++ pysollib/pysoltk.py | 71 +++-- pysollib/settings.py | 3 + pysollib/stack.py | 82 ++++- pysollib/tk/menubar.py | 12 +- pysollib/tk/tkwrap.py | 27 +- 35 files changed, 3070 insertions(+), 216 deletions(-) create mode 100644 pysollib/pysolgtk/__init__.py create mode 100644 pysollib/pysolgtk/card.py create mode 100644 pysollib/pysolgtk/colorsdialog.py create mode 100644 pysollib/pysolgtk/demooptionsdialog.py create mode 100644 pysollib/pysolgtk/edittextdialog.py create mode 100644 pysollib/pysolgtk/findcarddialog.py create mode 100644 pysollib/pysolgtk/fontsdialog.py create mode 100644 pysollib/pysolgtk/gameinfodialog.py create mode 100644 pysollib/pysolgtk/menubar.py create mode 100644 pysollib/pysolgtk/playeroptionsdialog.py create mode 100644 pysollib/pysolgtk/progressbar.py create mode 100644 pysollib/pysolgtk/selectcardset.py create mode 100644 pysollib/pysolgtk/selecttile.py create mode 100644 pysollib/pysolgtk/soundoptionsdialog.py create mode 100644 pysollib/pysolgtk/statusbar.py create mode 100644 pysollib/pysolgtk/timeoutsdialog.py create mode 100644 pysollib/pysolgtk/tkcanvas.py create mode 100644 pysollib/pysolgtk/tkconst.py create mode 100644 pysollib/pysolgtk/tkhtml.py create mode 100644 pysollib/pysolgtk/tkstats.py create mode 100644 pysollib/pysolgtk/tkutil.py create mode 100644 pysollib/pysolgtk/tkwidget.py create mode 100644 pysollib/pysolgtk/tkwrap.py create mode 100644 pysollib/pysolgtk/toolbar.py diff --git a/pysollib/actions.py b/pysollib/actions.py index fbdd1635..5967a3c2 100644 --- a/pysollib/actions.py +++ b/pysollib/actions.py @@ -58,7 +58,7 @@ from pysoltk import GameInfoDialog from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE from pysoltk import MfxMessageDialog, MfxSimpleEntry from pysoltk import MfxExceptionDialog -from pysoltk import BooleanVar, IntVar, StringVar +from pysoltk import MfxRadioMenuItem, MfxCheckMenuItem, StringVar from pysoltk import PlayerOptionsDialog from pysoltk import SoundOptionsDialog #from pysoltk import HintOptionsDialog @@ -103,50 +103,50 @@ class PysolMenubarActions: ) # structure to convert menu-options to Toolkit variables self.tkopt = Struct( - gameid = IntVar(), - gameid_popular = IntVar(), - comment = BooleanVar(), - autofaceup = BooleanVar(), - autodrop = BooleanVar(), - autodeal = BooleanVar(), - quickplay = BooleanVar(), - undo = BooleanVar(), - bookmarks = BooleanVar(), - hint = BooleanVar(), - highlight_piles = BooleanVar(), - highlight_cards = BooleanVar(), - highlight_samerank = BooleanVar(), - highlight_not_matching = BooleanVar(), - mahjongg_show_removed = BooleanVar(), - shisen_show_hint = BooleanVar(), - sound = BooleanVar(), - cardback = IntVar(), - tabletile = IntVar(), - animations = IntVar(), - shadow = BooleanVar(), - shade = BooleanVar(), - shade_filled_stacks = BooleanVar(), - shrink_face_down = BooleanVar(), - toolbar = IntVar(), + gameid = MfxRadioMenuItem(self), + gameid_popular = MfxRadioMenuItem(self), + comment = MfxCheckMenuItem(self), + autofaceup = MfxCheckMenuItem(self), + autodrop = MfxCheckMenuItem(self), + autodeal = MfxCheckMenuItem(self), + quickplay = MfxCheckMenuItem(self), + undo = MfxCheckMenuItem(self), + bookmarks = MfxCheckMenuItem(self), + hint = MfxCheckMenuItem(self), + highlight_piles = MfxCheckMenuItem(self), + highlight_cards = MfxCheckMenuItem(self), + highlight_samerank = MfxCheckMenuItem(self), + highlight_not_matching = MfxCheckMenuItem(self), + mahjongg_show_removed = MfxCheckMenuItem(self), + shisen_show_hint = MfxCheckMenuItem(self), + sound = MfxCheckMenuItem(self), + cardback = MfxRadioMenuItem(self), + tabletile = MfxRadioMenuItem(self), + animations = MfxRadioMenuItem(self), + shadow = MfxCheckMenuItem(self), + shade = MfxCheckMenuItem(self), + shade_filled_stacks = MfxCheckMenuItem(self), + shrink_face_down = MfxCheckMenuItem(self), + toolbar = MfxRadioMenuItem(self), toolbar_style = StringVar(), toolbar_relief = StringVar(), toolbar_compound = StringVar(), - toolbar_size = IntVar(), - statusbar = BooleanVar(), - num_cards = BooleanVar(), - helpbar = BooleanVar(), - save_games_geometry = BooleanVar(), - splashscreen = BooleanVar(), - demo_logo = BooleanVar(), - sticky_mouse = BooleanVar(), - mouse_undo = BooleanVar(), - negative_bottom = BooleanVar(), - pause = BooleanVar(), + toolbar_size = MfxRadioMenuItem(self), + statusbar = MfxCheckMenuItem(self), + num_cards = MfxCheckMenuItem(self), + helpbar = MfxCheckMenuItem(self), + save_games_geometry = MfxCheckMenuItem(self), + splashscreen = MfxCheckMenuItem(self), + demo_logo = MfxCheckMenuItem(self), + sticky_mouse = MfxCheckMenuItem(self), + mouse_undo = MfxCheckMenuItem(self), + negative_bottom = MfxCheckMenuItem(self), + pause = MfxCheckMenuItem(self), toolbar_vars = {}, ) for w in TOOLBAR_BUTTONS: - self.tkopt.toolbar_vars[w] = BooleanVar() + self.tkopt.toolbar_vars[w] = MfxCheckMenuItem(self) def connectGame(self, game): diff --git a/pysollib/app.py b/pysollib/app.py index 7ec92c6a..cd06d797 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -55,7 +55,7 @@ from images import Images, SubsampledImages from pysolrandom import PysolRandom from game import Game from gamedb import GI, GAME_DB, loadGame -from settings import TOP_SIZE, TOP_TITLE +from settings import TOP_SIZE, TOP_TITLE, TOOLKIT # Toolkit imports from pysoltk import tkname, tkversion, wm_withdraw, loadImage @@ -85,29 +85,29 @@ class Options: self.saved = 0 # options menu: self.player = _("Unknown") - self.confirm = 1 - self.update_player_stats = 1 - self.autofaceup = 1 - self.autodrop = 0 - self.autodeal = 1 - self.quickplay = 1 - self.undo = 1 - self.bookmarks = 1 - self.hint = 1 - self.highlight_piles = 1 - self.highlight_cards = 1 - self.highlight_samerank = 1 - self.highlight_not_matching = 1 + self.confirm = True + self.update_player_stats = True + self.autofaceup = True + self.autodrop = False + self.autodeal = True + self.quickplay = True + self.undo = True + self.bookmarks = True + self.hint = True + self.highlight_piles = True + self.highlight_cards = True + self.highlight_samerank = True + self.highlight_not_matching = True self.mahjongg_show_removed = False self.mahjongg_create_solvable = True self.shisen_show_hint = True self.animations = 2 # default to Timer based - self.shadow = 1 - self.shade = 1 + self.shadow = True + self.shade = True self.shrink_face_down = True self.shade_filled_stacks = True - self.demo_logo = 1 - self.toolbar = 1 + self.demo_logo = True + self.toolbar = True ##self.toolbar_style = 'default' self.toolbar_style = 'crystal' if os.name == 'posix': @@ -118,11 +118,11 @@ class Options: self.toolbar_vars = {} for w in TOOLBAR_BUTTONS: self.toolbar_vars[w] = True - self.statusbar = 1 - self.num_cards = 0 - self.helpbar = 0 + self.statusbar = True + self.num_cards = False + self.helpbar = False # sound - self.sound = 1 + self.sound = True self.sound_mode = 1 self.sound_sample_volume = 128 self.sound_music_volume = 128 @@ -234,8 +234,8 @@ class Options: # not changeable options def setConstants(self): - self.win_animation = 1 - self.dragcursor = 1 + self.win_animation = True + self.dragcursor = True self.randomize_place = False def copy(self): @@ -661,14 +661,15 @@ class Application: self.top.grid_rowconfigure(1, weight=1) self.setTile(self.tabletile_index, force=True) # create the toolbar - dir = self.getToolbarImagesDir() - self.toolbar = PysolToolbar(self.top, dir=dir, - size=self.opt.toolbar_size, - relief=self.opt.toolbar_relief, - compound=self.opt.toolbar_compound) - self.toolbar.show(self.opt.toolbar) - for w, v in self.opt.toolbar_vars.items(): - self.toolbar.config(w, v) + if TOOLKIT == 'tk': + dir = self.getToolbarImagesDir() + self.toolbar = PysolToolbar(self.top, dir=dir, + size=self.opt.toolbar_size, + relief=self.opt.toolbar_relief, + compound=self.opt.toolbar_compound) + self.toolbar.show(self.opt.toolbar) + for w, v in self.opt.toolbar_vars.items(): + self.toolbar.config(w, v) # if self.intro.progress: self.intro.progress.update(step=1) # @@ -754,7 +755,8 @@ class Application: self.game.create(self) # connect with game self.menubar.connectGame(self.game) - self.toolbar.connectGame(self.game, self.menubar) + if self.toolbar: ##~ + self.toolbar.connectGame(self.game, self.menubar) self.game.updateStatus(player=self.opt.player) # update "Recent games" menubar entry if id in self.opt.recent_gameid: @@ -805,7 +807,8 @@ class Application: # free game def freeGame(self): # disconnect from game - self.toolbar.connectGame(None, None) + if self.toolbar: ##~ + self.toolbar.connectGame(None, None) self.menubar.connectGame(None) # clean up the canvas self.canvas.deleteAllItems() diff --git a/pysollib/game.py b/pysollib/game.py index de1f209d..975921ba 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -1556,7 +1556,7 @@ for %d moves. color = self.app.opt.highlight_not_matching_color width = 6 x0, y0 = x+width/2-self.canvas.xmargin, y+width/2-self.canvas.ymargin - x1, y1 = x+w-width/2-self.canvas.xmargin, y+h-width/2-self.canvas.ymargin + x1, y1 = x+w-width-self.canvas.xmargin, y+h-width-self.canvas.ymargin r = MfxCanvasRectangle(self.canvas, x0, y0, x1, y1, width=width, fill=None, outline=color) self.canvas.update_idletasks() diff --git a/pysollib/games/pyramid.py b/pysollib/games/pyramid.py index c180554a..f13e971d 100644 --- a/pysollib/games/pyramid.py +++ b/pysollib/games/pyramid.py @@ -142,19 +142,13 @@ class Pyramid_RowStack(Pyramid_StackMethods, OpenStack): def __init__(self, x, y, game): OpenStack.__init__(self, x, y, game, max_accept=1, max_cards=2) self.CARD_YOFFSET = 1 - - STEP = (1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6) + self.blockmap = [] def basicIsBlocked(self): - r, step = self.game.s.rows, self.STEP - i, n = self.id, 1 - while i < 21: - i = i + step[i] - n = n + 1 - for j in range(i, i+n): - if r[j].cards: - return 1 - return 0 + for r in self.blockmap: + if r.cards: + return True + return False def clickHandler(self, event): if self._dropKingClickHandler(event): @@ -173,10 +167,33 @@ class Pyramid(Game): RowStack_Class = Pyramid_RowStack WasteStack_Class = Pyramid_Waste + PYRAMID_Y_FACTOR = 2 + # # game layout # + def _createPyramid(self, l, x0, y0, size): + rows = [] + # create stacks + for i in range(size): + x = x0 + (size-1-i) * l.XS / 2 + y = y0 + i * l.YS / self.PYRAMID_Y_FACTOR + for j in range(i+1): + stack = self.RowStack_Class(x, y, self) + rows.append(stack) + x = x + l.XS + # compute blocking + n = 0 + lr = len(rows) + for i in range(size-1): + for j in range(i+1): + k = n+i+1 + rows[n].blockmap = [rows[k],rows[k+1]] + n += 1 + return rows + + def createGame(self, rows=4, reserves=0, waste=True, texts=True): # create layout l, s = Layout(self), self.s @@ -190,12 +207,8 @@ class Pyramid(Game): self.setSize(w, h) # create stacks - for i in range(7): - x = l.XM + (8-i) * l.XS / 2 - y = l.YM + i * l.YS / 2 - for j in range(i+1): - s.rows.append(self.RowStack_Class(x, y, self)) - x = x + l.XS + x, y = l.XM+l.XS, l.YM + s.rows = self._createPyramid(l, x, y, 7) x, y = l.XM, l.YM s.talon = self.Talon_Class(x, y, self) @@ -315,8 +328,8 @@ class Thirteen(Pyramid): s.waste.CARD_XOFFSET = 14 x, y = self.width - l.XS, l.YM s.foundations.append(Pyramid_Foundation(x, y, self, - suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, - max_move=0, max_cards=UNLIMITED_CARDS)) + suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, + max_move=0, max_cards=52)) # define stack-groups self.sg.talonstacks = [s.talon] + [s.waste] @@ -690,7 +703,6 @@ class TripleAlliance(Game): # ************************************************************************/ class Pharaohs_RowStack(Pyramid_RowStack): - def acceptsCards(self, from_stack, cards): if not self.basicAcceptsCards(from_stack, cards): return False @@ -701,12 +713,6 @@ class Pharaohs_RowStack(Pyramid_RowStack): return True return r0 == r1 - def basicIsBlocked(self): - for r in self.blockmap: - if r.cards: - return True - return False - class Pharaohs(Pyramid): @@ -715,28 +721,6 @@ class Pharaohs(Pyramid): PYRAMID_Y_FACTOR = 3 - def _createPyramid(self, l, x0, y0, size): - rows = [] - # create stacks - for i in range(size): - x = x0 + (size-1-i) * l.XS / 2 - y = y0 + i * l.YS / self.PYRAMID_Y_FACTOR - for j in range(i+1): - stack = self.RowStack_Class(x, y, self) - rows.append(stack) - stack.blockmap = [] - x = x + l.XS - # compute blocking - n = 0 - lr = len(rows) - for i in range(size-1): - for j in range(i+1): - k = n+i+1 - rows[n].blockmap = [rows[k],rows[k+1]] - n += 1 - return rows - - def createGame(self): # create layout l, s = Layout(self), self.s @@ -867,28 +851,6 @@ class Apophis_RowStack(Pharaohs_RowStack): return r0+r1 == 11 -class Apophis_Talon(RedealTalonStack): - def canDealCards(self): - r_cards = sum([len(r.cards) for r in self.game.s.reserves]) - if self.cards: - return True - elif r_cards and self.round != self.max_rounds: - return True - return False - - def dealCards(self, sound=0): - num_cards = 0 - if sound and self.game.app.opt.animations: - self.game.startDealSample() - if not self.cards: - num_cards = self._redeal(rows=self.game.s.reserves, frames=4) - self.game.nextRoundMove(self) - num_cards += self.dealRowAvail(rows=self.game.s.reserves, sound=0) - if sound: - self.game.stopSamples() - return num_cards - - class Apophis(Pharaohs): Hint_Class = Apophis_Hint RowStack_Class = Apophis_RowStack @@ -909,7 +871,7 @@ class Apophis(Pharaohs): s.rows = self._createPyramid(l, x, y, 7) x, y = l.XM, l.YM - s.talon = Apophis_Talon(x, y, self, max_rounds=3) + s.talon = DealReserveRedealTalonStack(x, y, self, max_rounds=3) l.createText(s.talon, 'se') tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") font = self.app.getFont("canvas_default") diff --git a/pysollib/games/sultan.py b/pysollib/games/sultan.py index 26ab7c0e..f1d3322e 100644 --- a/pysollib/games/sultan.py +++ b/pysollib/games/sultan.py @@ -905,6 +905,60 @@ class Adela(Game): shallHighlightMatch = Game._shallHighlightMatch_SS +# /*********************************************************************** +# // Toni +# ************************************************************************/ + +class Toni(Game): + + def createGame(self): + + l, s = Layout(self), self.s + self.setSize(l.XM+8.5*l.XS, l.YM+4*l.YS) + + y = l.YM + suit = 0 + for i in (0,1,3,4): + x = l.XM+(2+i)*l.XS + s.foundations.append(SS_FoundationStack(x, y, self, suit=suit)) + suit += 1 + + x, y = l.XM+4*l.XS, l.YM + for i in range(4): + s.foundations.append(SS_FoundationStack(x, y, self, suit=i, + base_rank=KING, dir=-1)) + y += l.YS + + for i, j in ((0,0),(1,0),(2,0),(5,0),(6,0),(7,0), + (0,1),(1,1),(2,1),(5,1),(6,1),(7,1), + ): + x, y = l.XM+(0.5+i)*l.XS, l.YM+(1.5+j)*l.YS + stack = BasicRowStack(x, y, self, max_accept=0) + s.rows.append(stack) + stack.CARD_YOFFSET = 0 + + x, y = l.XM, l.YM + s.talon = DealRowRedealTalonStack(x, y, self, max_rounds=3) + l.createText(s.talon, 'se') + tx, ty, ta, tf = l.getTextAttr(s.talon, 'ne') + font = self.app.getFont('canvas_default') + s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty, + anchor=ta, font=font) + + l.defaultStackGroups() + + + def _shuffleHook(self, cards): + return self._shuffleHookMoveToTop(cards, + lambda c: (c.rank in (ACE, KING) and c.deck == 0, (c.rank, c.suit))) + + + def startGame(self): + self.s.talon.dealRow(rows=self.s.foundations, frames=0) + self.startDealSample() + self.s.talon.dealRow() + + # register the game registerGame(GameInfo(330, Sultan, "Sultan", @@ -942,3 +996,5 @@ registerGame(GameInfo(635, CircleEight, "Circle Eight", GI.GT_1DECK_TYPE, 1, 1, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(646, Adela, "Adela", GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK)) +registerGame(GameInfo(660, Toni, "Toni", + GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_LUCK)) diff --git a/pysollib/games/tournament.py b/pysollib/games/tournament.py index a203343a..b3c40933 100644 --- a/pysollib/games/tournament.py +++ b/pysollib/games/tournament.py @@ -34,46 +34,27 @@ from pysollib.layout import Layout from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.pysoltk import MfxCanvasText + # /*********************************************************************** -# // +# // Tournament # ************************************************************************/ - -class Tournament_Talon(TalonStack): - - def canDealCards(self): - if self.round == self.max_rounds and not self.cards: - return False - return not self.game.isGameWon() - +class Tournament_Talon(DealRowRedealTalonStack): def dealCards(self, sound=0): + num_cards = 0 + if sound and self.game.app.opt.animations: + self.game.startDealSample() if len(self.cards) == 0: - self._redeal() - self.game.startDealSample() - n = 0 + num_cards = self._redeal(reverse=True, frames=0) + self.game.nextRoundMove(self) for r in self.game.s.rows: for i in range(4): if not self.cards: break - n += self.dealRow([r]) - self.game.stopSamples() - return n - - def _redeal(self): - # move all cards to the Talon - lr = len(self.game.s.rows) - num_cards = 0 - assert len(self.cards) == 0 - for r in self.game.s.rows[::-1]: - for i in range(len(r.cards)): - num_cards = num_cards + 1 - self.game.moveMove(1, r, self, frames=0) - self.game.flipMove(self) - assert len(self.cards) == num_cards - if num_cards == 0: # game already finished - return - self.game.nextRoundMove(self) - return + num_cards += self.dealRow([r], sound=0) + if sound: + self.game.stopSamples() + return num_cards class Tournament(Game): diff --git a/pysollib/pysolgtk/__init__.py b/pysollib/pysolgtk/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pysollib/pysolgtk/card.py b/pysollib/pysolgtk/card.py new file mode 100644 index 00000000..d89fca57 --- /dev/null +++ b/pysollib/pysolgtk/card.py @@ -0,0 +1,137 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import gtk + +# PySol imports +from pysollib.acard import AbstractCard + +# Toolkit imports +from tkcanvas import MfxCanvasGroup, MfxCanvasImage + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class _HideableCard(AbstractCard): + def hide(self, stack): + if stack is self.hide_stack: + return + self.item.hide() + self.hide_stack = stack + + def unhide(self): + if self.hide_stack is None: + return 0 + self.item.show() + self.hide_stack = None + return 1 + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class _OneImageCard(_HideableCard): + def __init__(self, id, deck, suit, rank, game, x=0, y=0): + _HideableCard.__init__(self, id, deck, suit, rank, game, x=x, y=y) + images = game.app.images + self.__face_image = images.getFace(deck, suit, rank) + self.__back_image = images.getBack(deck, suit, rank) + self.__image = MfxCanvasImage(game.canvas, self.x, self.y, + image=self.__back_image, + anchor=gtk.ANCHOR_NW) + if 0: + # using a group for a single image doesn't gain much + self.item = MfxCanvasGroup(game.canvas) + self.__image.addtag(self.item) + else: + self.item = self.__image + + def showFace(self, unhide=1): + if not self.face_up: + self.__image.config(image=self.__face_image) + self.tkraise(unhide) + self.face_up = 1 + + def showBack(self, unhide=1): + if self.face_up: + self.__image.config(image=self.__back_image) + self.tkraise(unhide) + self.face_up = 0 + + def updateCardBackground(self, image): + self.__back_image = image + if not self.face_up: + self.__image.config(image=image) + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class _TwoImageCard(_HideableCard): + def __init__(self, id, deck, suit, rank, game, x=0, y=0): + _HideableCard.__init__(self, id, deck, suit, rank, game, x=x, y=y) + images = game.app.images + self.item = MfxCanvasGroup(game.canvas) + self.__face = MfxCanvasImage(game.canvas, self.x, self.y, image=images.getFace(deck, suit, rank), anchor='nw') + self.__back = MfxCanvasImage(game.canvas, self.x, self.y, image=images.getBack(deck, suit, rank), anchor='nw') + self.__face.addtag(self.item) + self.__back.addtag(self.item) + self.__face.hide() + + def showFace(self, unhide=1): + if not self.face_up: + self.__back.hide() + self.__face.show() + self.tkraise(unhide) + self.face_up = 1 + + def showBack(self, unhide=1): + if self.face_up: + self.__face.hide() + self.__back.show() + self.tkraise(unhide) + self.face_up = 0 + + def updateCardBackground(self, image): + self.__back.config(image=image) + + + +# choose the implementation +Card = _TwoImageCard +Card = _OneImageCard + diff --git a/pysollib/pysolgtk/colorsdialog.py b/pysollib/pysolgtk/colorsdialog.py new file mode 100644 index 00000000..8c9ce661 --- /dev/null +++ b/pysollib/pysolgtk/colorsdialog.py @@ -0,0 +1,45 @@ +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +##---------------------------------------------------------------------------## + +__all__ = ['ColorsDialog'] + +## # imports +## import os, sys +## import Tkinter +## from tkColorChooser import askcolor + +## # PySol imports +## from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct + +## # Toolkit imports +## from tkconst import EVENT_HANDLED, EVENT_PROPAGATE + +from tkwidget import MfxDialog + +# /*********************************************************************** +# // +# ************************************************************************/ + +class ColorsDialog(MfxDialog): + pass + + + diff --git a/pysollib/pysolgtk/demooptionsdialog.py b/pysollib/pysolgtk/demooptionsdialog.py new file mode 100644 index 00000000..4af6b269 --- /dev/null +++ b/pysollib/pysolgtk/demooptionsdialog.py @@ -0,0 +1,56 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys +from gtk import * + +# PySol imports +from mfxutil import destruct, kwdefault, KwStruct, Struct + +# Toolkit imports +from tkwidget import MfxDialog + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class DemoOptionsDialog(MfxDialog): + def __init__(self, parent, title, app, **kw): + pass + + +class HintOptionsDialog(MfxDialog): + def __init__(self, parent, title, app, **kw): + pass + diff --git a/pysollib/pysolgtk/edittextdialog.py b/pysollib/pysolgtk/edittextdialog.py new file mode 100644 index 00000000..60fc06a5 --- /dev/null +++ b/pysollib/pysolgtk/edittextdialog.py @@ -0,0 +1,52 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## All Rights Reserved. +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://www.oberhumer.com/pysol +## +##---------------------------------------------------------------------------## + +__all__ = ['EditTextDialog'] + +# imports +## import os, sys, Tkinter + +# PySol imports + +# Toolkit imports +from tkwidget import MfxDialog + +# /*********************************************************************** +# // +# ************************************************************************/ + +class EditTextDialog(MfxDialog): + pass + diff --git a/pysollib/pysolgtk/findcarddialog.py b/pysollib/pysolgtk/findcarddialog.py new file mode 100644 index 00000000..ee358356 --- /dev/null +++ b/pysollib/pysolgtk/findcarddialog.py @@ -0,0 +1,55 @@ +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +##---------------------------------------------------------------------------## + +__all__ = ['create_find_card_dialog', + 'connect_game_find_card_dialog', + 'destroy_find_card_dialog', + ] + +# imports +## import os +## import Tkinter +## import traceback + +## # PySol imports + +## # Toolkit imports +## from tkutil import after, after_cancel +## from tkutil import bind, unbind_destroy, makeImage +## from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle + + +# /*********************************************************************** +# // +# ************************************************************************/ + +find_card_dialog = None + +def create_find_card_dialog(parent, game, dir): + pass + +def connect_game_find_card_dialog(game): + pass + +def destroy_find_card_dialog(): + pass + + diff --git a/pysollib/pysolgtk/fontsdialog.py b/pysollib/pysolgtk/fontsdialog.py new file mode 100644 index 00000000..d2cb80ab --- /dev/null +++ b/pysollib/pysolgtk/fontsdialog.py @@ -0,0 +1,48 @@ +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +##---------------------------------------------------------------------------## + +__all__ = ['FontsDialog'] + +## # imports +## import os, sys +## import types +## import Tkinter +## import tkFont + +## # PySol imports +## from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct + +## # Toolkit imports +## from tkconst import EVENT_HANDLED, EVENT_PROPAGATE +## from tkutil import bind + +from tkwidget import MfxDialog + +# /*********************************************************************** +# // +# ************************************************************************/ + +class FontsDialog(MfxDialog): + pass + + + + diff --git a/pysollib/pysolgtk/gameinfodialog.py b/pysollib/pysolgtk/gameinfodialog.py new file mode 100644 index 00000000..fba75120 --- /dev/null +++ b/pysollib/pysolgtk/gameinfodialog.py @@ -0,0 +1,42 @@ +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +##---------------------------------------------------------------------------## + + +__all__ = ['GameInfoDialog'] + +## # imports +## import os, sys +## import Tkinter + +## # PySol imports +## from pysollib.mfxutil import KwStruct +## from pysollib.gamedb import GI + +# Toolkit imports +from tkwidget import MfxDialog + +# /*********************************************************************** +# // +# ************************************************************************/ + +class GameInfoDialog(MfxDialog): + pass + diff --git a/pysollib/pysolgtk/menubar.py b/pysollib/pysolgtk/menubar.py new file mode 100644 index 00000000..77054ded --- /dev/null +++ b/pysollib/pysolgtk/menubar.py @@ -0,0 +1,295 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import math, os, re, string, sys + +import gtk +from gtk import gdk +TRUE, FALSE = True, False + +# PySol imports +from pysollib.gamedb import GI +from pysollib.actions import PysolMenubarActions + +# toolkit imports +from tkutil import setTransient +from tkutil import color_tk2gtk, color_gtk2tk +from selectcardset import SelectCardsetDialogWithPreview +from selectcardset import SelectCardsetByTypeDialogWithPreview + + +# /*********************************************************************** +# // - create menubar +# // - update menubar +# // - menu actions +# ************************************************************************/ + +class PysolMenubar(PysolMenubarActions): + def __init__(self, app, top, progress=None): + PysolMenubarActions.__init__(self, app, top) + self.menus = None + self.menu_items = None + # create menus + menubar, accel = self.createMenus() + # additional key bindings + ### FIXME + ###self.accel.add("Space", None, None, None, None) + # delete the old menubar + # set the menubar + ##~ accel.attach(self.top) + top.add_accel_group(accel) + w = menubar.get_widget('
') + self.top.vbox.pack_start(w, expand=FALSE, fill=FALSE) + self.top.vbox.reorder_child(w, 0) + self.__menubar = menubar + self.__accel = accel + self.menus = menubar + + + # + # create menubar + # + + def m(self, *args): + ##print args + pass + + def _initItemFactory(self): + self.menu_items = ( + ("/_File", None, None, 0, ""), + ("/File/", None, None, 0, ""), + ("/File/_New Game", "N", self.mNewGame, 0, ""), + ("/File/Select _game", None, None, 0, ""), + ) + + # + # /File/Select game + # + + mi, radio = [], "" + games = self.app.gdb.getGamesIdSortedByName() + i = 0 + path = "/File/Select game" + columnbreak = 25 + n = 0 + mm = [] + t1 = t2 = None + for id in games: + if t1 is None: + t1 = self.app.getGameMenuitemName(id)[:3] + if n == columnbreak: + t2 = self.app.getGameMenuitemName(id)[:3] + pp = '%s/%s-%s' % (path, t1, t2) + mi.append((pp, None, None, 0, '')) + for m in mm: + p = '%s/%s' % (pp, m[0]) + mi.append((p, None, self.mSelectGame, m[1], radio)) + if radio[0] == '<': + radio = re.sub('_', '', p) + n = 0 + mm = [] + t1 = t2 + + mm.append((self.app.getGameMenuitemName(id), id)) + n += 1 + + t2 = self.app.getGameMenuitemName(id)[:3] + pp = '%s/%s-%s' % (path, t1, t2) + mi.append((pp, None, None, 0, '')) + for m in mm: + p = '%s/%s' % (pp, m[0]) + mi.append((p, None, self.mSelectGame, m[1], radio)) + + self.menu_items = self.menu_items + tuple(mi) + self.tkopt.gameid.path = radio + + # + # + # + + self.menu_items = self.menu_items + ( + ("/File/Select game by number...", None, self.mSelectGameById, 0, ""), + ("/File/", None, None, 0, ""), + ("/File/_Open", "O", self.m, 0, ""), + ("/File/_Save", "S", self.mSave, 0, ""), + ("/File/Save _as...", None, self.m, 0, ""), + ("/File/", None, None, 0, ""), + ("/File/_Quit", "Q", self.mQuit, 0, ""), + ("/_Edit", None, None, 0, ""), + ("/Edit/", None, None, 0, ""), + ("/Edit/_Undo", "Z", self.mUndo, 0, ""), + ("/Edit/_Redo", "R", self.mRedo, 0, ""), + ("/Edit/Redo _all", None, self.mRedoAll, 0, ""), + ("/Edit/", None, None, 0, ""), + ("/Edit/Restart _game", "G", self.mRestart, 0, ""), + ("/_Game", None, None, 0, ""), + ("/Game/", None, None, 0, ""), + ("/Game/_Deal cards", "D", self.mDeal, 0, ""), + ("/Game/_Auto drop", "A", self.mDrop, 0, ""), + ("/Game/", None, None, 0, ""), + ("/Game/S_tatus...", "T", self.mStatus, 0, ""), + ("/_Assist", None, None, 0, ""), + ("/Assist/", None, None, 0, ""), + ("/Assist/_Hint", "H", self.mHint, 0, ""), + ("/Assist/Highlight _piles", "Shift", self.mHighlightPiles, 0, ""), + ("/Assist/", None, None, 0, ""), + ("/Assist/_Demo", "D", self.mDemo, 0, ""), + ("/Assist/Demo (all games)", "", self.mMixedDemo, 0, ""), + ("/_Options", None, None, 0, ""), + ("/Options/", None, None, 0, ""), + ("/Options/_Confirm", None, self.mOptConfirm, 0, ""), + ("/Options/Auto_play", "P", self.mOptAutoDrop, 0, ""), + ("/Options/_Automatic _face up", "F", self.mOptAutoFaceUp, 0, ""), + ("/Options/Highlight _matching cards", None, self.mOptEnableHighlightCards, 0, ""), + ("/Options/", None, None, 0, ""), + ) + + mi, radio = [], "" + path = "/Options/Cards_et" + mi.append((path, None, None, 0, "")) + for i in range(self.app.cardset_manager.len()): + columnbreak = i > 0 and (i % 25) == 0 + p = path + '/' + self.app.cardset_manager.get(i).name + mi.append((p, None, self.mOptCardset, i, radio)) + if radio[0] == '<': + radio = re.sub('_', '', p) + self.menu_items = self.menu_items + tuple(mi) +## self.tkopt.cardset.path = radio + + self.menu_items = self.menu_items + ( + ("/Options/Table color...", None, self.mOptTableColor, 0, ""), + ) + + mi, radio = [], "" + path = "/Options/_Animations" + mi.append((path, None, None, 0, "")) + i = 0 + for k in ("_None", "_Fast", "_Timer based"): + p = path + '/' + k + mi.append((p, None, self.mOptAnimations, i, radio)) + if radio[0] == '<': + radio = re.sub('_', '', p) + i = i + 1 + self.menu_items = self.menu_items + tuple(mi) + self.tkopt.animations.path = radio + + self.menu_items = self.menu_items + ( + ("/Options/Card shadow", None, self.mOptShadow, 0, ""), + ("/Options/Shade legal moves", None, self.mOptShade, 0, ""), + ("/Options/", None, None, 0, ""), + ("/Options/_Hint options...", None, self.mOptHintOptions, 0, ""), + ("/Options/_Demo options...", None, self.mOptDemoOptions, 0, ""), + ("/_Help", None, None, 0, ""), + ("/Help/", None, None, 0, ""), + ("/Help/_Contents", "F1", self.mHelp, 0, ""), + ("/Help/_Rules", None, self.mHelpRules, 0, ""), + ("/Help/", None, None, 0, ""), + ("/Help/_About PySol...", None, self.mHelpAbout, 0, ""), + ) + + + def createMenus(self): + if not self.menu_items: + self._initItemFactory() + accel = gtk.AccelGroup() + item_factory = gtk.ItemFactory(gtk.MenuBar, '
', accel) + item_factory.create_items(self.menu_items) + return item_factory, accel + + + # + # menu updates + # + + def setMenuState(self, state, path): + return + w = self.__menubar.get_widget(path) + w.set_sensitive(state) + + def setToolbarState(self, state, path): + ##~ w = getattr(self.app.toolbar, path + "_button") + ##~ w.set_sensitive(state) + pass + + + # + # menu actions + # + + def mOpen(self, *args): + pass + + def mSaveAs(self, *event): + pass + + def mOptCardset(self, *args): + pass + + def mOptTableColor(self, *args): + win = gtk.ColorSelectionDialog("Select table color") + win.help_button.destroy() + win.set_position(gtk.WIN_POS_MOUSE) + win.colorsel.set_current_color(gdk.color_parse(self.app.opt.table_color)) + + ##win.colorsel.set_update_policy(UPDATE_CONTINUOUS) + def delete_event(widget, *event): + widget.destroy() + def ok_button_clicked(_button, self=self, win=win): + c = win.colorsel.get_current_color() + c = '#%02x%02x%02x' % (c.red/256, c.green/256, c.blue/256) + win.destroy() + self.app.opt.table_color = c + self.game.canvas.config(bg=self.app.opt.table_color) + self.top.config(bg=self.app.opt.table_color) + win.connect("delete_event", delete_event) + win.ok_button.connect("clicked", ok_button_clicked) + win.cancel_button.connect("clicked", win.destroy) + setTransient(win, self.top) + win.show() + + def mOptConfirm(self, *args): + pass + + def mOptHintOptions(self, *args): + pass + + def mOptDemoOptions(self, *args): + pass + + def updateFavoriteGamesMenu(self, *args): + pass + +## def mSelectGame(self, gameid, menuitem): +## if menuitem.get_active(): +## self._mSelectGame(gameid) + diff --git a/pysollib/pysolgtk/playeroptionsdialog.py b/pysollib/pysolgtk/playeroptionsdialog.py new file mode 100644 index 00000000..32dd4982 --- /dev/null +++ b/pysollib/pysolgtk/playeroptionsdialog.py @@ -0,0 +1,52 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## All Rights Reserved. +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://www.oberhumer.com/pysol +## +##---------------------------------------------------------------------------## + +__all__ = ['PlayerOptionsDialog'] + +# imports +import gtk + +# PySol imports + +# Toolkit imports +from tkwidget import MfxDialog + +# /*********************************************************************** +# // +# ************************************************************************/ + +class PlayerOptionsDialog(MfxDialog): + pass + diff --git a/pysollib/pysolgtk/progressbar.py b/pysollib/pysolgtk/progressbar.py new file mode 100644 index 00000000..957c1d2e --- /dev/null +++ b/pysollib/pysolgtk/progressbar.py @@ -0,0 +1,173 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys + +import gtk +from gtk import gdk +TRUE, FALSE = True, False + +# Toolkit imports +from tkutil import makeToplevel, setTransient + + +# /*********************************************************************** +# // a simple progress bar +# ************************************************************************/ + +class PysolProgressBar: + def __init__(self, app, parent, title=None, images=None, + color='blue', bg='#c0c0c0', + height=25, show_text=1, norm=1): + self.parent = parent + self.percent = 0 + self.norm = norm + self.top = makeToplevel(parent, title=title) + self.top.set_position(gtk.WIN_POS_CENTER) + ##self.top.set_policy(FALSE, FALSE, FALSE) + self.top.set_resizable(FALSE) + self.top.connect("delete_event", self.wmDeleteWindow) + + # hbox + hbox = gtk.HBox(spacing=5) + hbox.set_border_width(10) + hbox.show() + self.top.vbox.pack_start(hbox, FALSE, FALSE) + # hbox-1: image +## if images and images[0]: +## im = images[0].clone() +## im.show() +## hbox.pack_start(im, FALSE, FALSE) + # hbox-2:vbox + vbox = gtk.VBox() + vbox.show() + hbox.pack_start(vbox, FALSE, FALSE) + # hbox-2:vbox:pbar + self.pbar = gtk.ProgressBar() + self.pbar.show() + vbox.pack_start(self.pbar, TRUE, FALSE) + self.pbar.realize() + ##~ self.pbar.set_show_text(show_text) + self.pbar.set_text(str(show_text)+'%') + w, h = self.pbar.size_request() + self.pbar.set_size_request(max(w, 300), max(h, height)) + # set color + c = self.pbar.get_colormap().alloc_color(color) + self.pbar.style.bg[gtk.STATE_PRELIGHT] = c + ##~ style = self.pbar.get_style().copy() + ##~ style.bg[gtk.STATE_PRELIGHT] = c + ##~ self.pbar.set_style(style) + # hbox-3:image +## if images and images[1]: +## im = images[1].clone() +## im.show() +## hbox.pack_start(im, FALSE, FALSE) + # set icon + if app: + try: + name = app.dataloader.findFile('pysol.xpm') + bg = self.top.get_style().bg[gtk.STATE_NORMAL] + pixmap, mask = create_pixmap_from_xpm(self.top, bg, name) + self.top.set_icon(pixmap, mask) + except: pass + ##~ self.top.get_window().set_cursor(cursor_new(gdk.WATCH)) + setTransient(self.top, parent) + self.top.show() + self.update(percent=0) + + def destroy(self): + self.top.destroy() + + def pack(self): + pass + + def update(self, percent=None, step=1): + if percent is None: + self.percent = self.percent + step + elif percent > self.percent: + self.percent = percent + self.percent = min(100, max(0, self.percent)) + self.pbar.set_fraction(self.percent / 100.0) + self.pbar.set_text(str(int(self.percent))+'%') + ##~ self.pbar.update(self.percent / 100.0) + self.update_idletasks() + + def update_idletasks(self): + while gtk.events_pending(): + gtk.mainiteration() + + def wmDeleteWindow(self, *args): + return TRUE + + +# /*********************************************************************** +# // +# ************************************************************************/ + +#%ifndef BUNDLE + +class TestProgressBar: + def __init__(self, parent, images=None): + self.parent = parent + self.progress = PysolProgressBar(None, parent, title="Progress", + images=images, color='#008200') + self.progress.pack() + self.func = [ self.update, 0 ] + self.func[1] = timeout_add(30, self.func[0]) + + def update(self, *args): + if self.progress.percent >= 100: + self.progress.destroy() + mainquit() + return FALSE + self.progress.update(step=1) + return TRUE + +def progressbar_main(args): + root = gtk.Window() + root.connect("destroy", mainquit) + root.connect("delete_event", mainquit) + images = None + if 1: + from tkwrap import loadImage + im = loadImage(os.path.join(os.pardir, os.pardir, 'data', 'images', 'jokers', 'joker07_40_774.gif')) + images = (im, im) + pb = TestProgressBar(root, images=images) + mainloop() + return 0 + +if __name__ == '__main__': + sys.exit(progressbar_main(sys.argv)) + +#%endif + diff --git a/pysollib/pysolgtk/selectcardset.py b/pysollib/pysolgtk/selectcardset.py new file mode 100644 index 00000000..6464647d --- /dev/null +++ b/pysollib/pysolgtk/selectcardset.py @@ -0,0 +1,50 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, re, sys, types +from gtk import * + +# Toolkit imports +from tkwidget import MfxDialog + + +# /*********************************************************************** +# // Dialog +# ************************************************************************/ + +class SelectCardsetDialogWithPreview(MfxDialog): + pass + +class SelectCardsetByTypeDialogWithPreview(SelectCardsetDialogWithPreview): + pass + diff --git a/pysollib/pysolgtk/selecttile.py b/pysollib/pysolgtk/selecttile.py new file mode 100644 index 00000000..09cee74e --- /dev/null +++ b/pysollib/pysolgtk/selecttile.py @@ -0,0 +1,50 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## All Rights Reserved. +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://www.oberhumer.com/pysol +## +##---------------------------------------------------------------------------## + + +## # imports +## import os, string, sys, types +## import Tkinter, tkColorChooser + +## # PySol imports +## from pysollib.mfxutil import destruct, Struct, KwStruct +## from pysollib.resource import CSI + +## # Toolkit imports +## from tkutil import loadImage +## from tkwidget import MfxDialog, MfxScrolledCanvas +## from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode +## from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas + diff --git a/pysollib/pysolgtk/soundoptionsdialog.py b/pysollib/pysolgtk/soundoptionsdialog.py new file mode 100644 index 00000000..572b6a20 --- /dev/null +++ b/pysollib/pysolgtk/soundoptionsdialog.py @@ -0,0 +1,50 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys +import gtk + +# PySol imports + +# Toolkit imports +from tkwidget import MfxDialog + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class SoundOptionsDialog(MfxDialog): + def __init__(self, parent, title, app, **kw): + pass + diff --git a/pysollib/pysolgtk/statusbar.py b/pysollib/pysolgtk/statusbar.py new file mode 100644 index 00000000..7783db5c --- /dev/null +++ b/pysollib/pysolgtk/statusbar.py @@ -0,0 +1,75 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys +import gtk +TRUE, FALSE = True, False + +# PySol imports + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class PysolStatusbar: + def __init__(self, top): + self.top = top + self.side = '#init#' + + def updateText(self, **kw): + pass + + def configLabel(self, name, **kw): + pass + + def show(self, side='bottom', resize=0): + return 0 + + def hide(self, resize=0): + self.show(None, resize) + + def getSide(self): + return self.side + + def destroy(self): + pass + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class HelpStatusbar(PysolStatusbar): + pass + diff --git a/pysollib/pysolgtk/timeoutsdialog.py b/pysollib/pysolgtk/timeoutsdialog.py new file mode 100644 index 00000000..13283977 --- /dev/null +++ b/pysollib/pysolgtk/timeoutsdialog.py @@ -0,0 +1,42 @@ +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +##---------------------------------------------------------------------------## + +__all__ = ['TimeoutsDialog'] + +## # imports +## import os, sys +## import Tkinter + +## # PySol imports +## from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct + +## # Toolkit imports +## from tkconst import EVENT_HANDLED, EVENT_PROPAGATE + +from tkwidget import MfxDialog + +# /*********************************************************************** +# // +# ************************************************************************/ + +class TimeoutsDialog(MfxDialog): + pass + diff --git a/pysollib/pysolgtk/tkcanvas.py b/pysollib/pysolgtk/tkcanvas.py new file mode 100644 index 00000000..c1c5b716 --- /dev/null +++ b/pysollib/pysolgtk/tkcanvas.py @@ -0,0 +1,370 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# +# This files tries to wrap a limited subset of the Tkinter canvas +# into GTK / Gnome. +# + +# +# Some background information: +# +# - Each card is a canvas group consisting of a background and foreground +# image. Turning a card raises the respective image within that group. +# +# - Each stack is a canvas group consisting of cards (i.e. a group of groups) +# +# - Cards change stacks, and are bound to the main canvas when dragging +# around. +# + + +# imports +import os, sys, types + +import gtk +from gtk import gdk +import gnome.canvas +TRUE, FALSE = True, False + +# toolkit imports +from tkutil import anchor_tk2gtk, loadImage, bind + +# /*********************************************************************** +# // canvas items +# // +# // My first (obvious) approach was to subclass the GnomeCanvas* +# // classes, but this didn't work at all... +# // +# // Now I've resorted to delegation, but what are the Gnome canvas item +# // classes for then ? +# ************************************************************************/ + +class _CanvasItem: + def __init__(self, canvas): + self.canvas = canvas + def addtag(self, group): + ##~ assert isinstance(group._item, CanvasGroup) + self._item.reparent(group._item) + def bind(self, sequence, func, add=None): + bind(self._item, sequence, func, add) + def bbox(self): + ## FIXME + return (0, 0, 0, 0) + def dtag(self, group): + ##~ assert isinstance(group._item, CanvasGroup) + self._item.reparent(self.canvas.root()) + def delete(self): + if self._item is not None: + self._item.destroy() + self._item = None + def hide(self): + self._item.hide() + def lower(self, positions=None): + ##print "lower", self._item, positions + if positions is None: + self._item.lower_to_bottom() + else: + ##~ assert type(positions) is types.IntType and positions > 0 + ##~ self._item.lower(positions) + pass + def move(self, x, y): + self._item.move(x, y) + def show(self): + self._item.show() + def tkraise(self, positions=None): + ##print "tkraise", self._item, positions + if positions is None: + self._item.raise_to_top() + else: + ##~ assert type(positions) is types.IntType and positions > 0 + ##~ self._item.raise_(positions) + pass + + +class MfxCanvasGroup(_CanvasItem): + def __init__(self, canvas): + _CanvasItem.__init__(self, canvas) + self._item = canvas.root().add(gnome.canvas.CanvasGroup, x=0, y=0) + + + +class MfxCanvasImage(_CanvasItem): + def __init__(self, canvas, x, y, image, anchor=gtk.ANCHOR_NW): + _CanvasItem.__init__(self, canvas) + anchor = anchor_tk2gtk(anchor) + self._item = canvas.root().add(gnome.canvas.CanvasPixbuf, + x=x, y=y, + pixbuf=image.pixbuf, + width=image.width(), + height=image.height(), + anchor=anchor) + + def config(self, image): + ##~ assert isinstance(image.im, GdkImlib.Image) + self._item.set(pixbuf=image.pixbuf) + + +class MfxCanvasLine(_CanvasItem): + def __init__(self, canvas, x1, y1, x2, y2, width, fill, arrow, arrowshape): + _CanvasItem.__init__(self, canvas) + # FIXME + self._item = None + + +class MfxCanvasRectangle(_CanvasItem): + def __init__(self, canvas, x1, y1, x2, y2, width, fill, outline): + self._item = canvas.root().add('rect', x1=x1, y1=y1, x2=x2, y2=y2, + width_pixels=width, outline_color=outline) + if fill is not None: + self._item.set(fill_color=fill) + + +class MfxCanvasText(_CanvasItem): + def __init__(self, canvas, x, y, anchor=gtk.ANCHOR_NW, preview=-1, **kw): + if preview < 0: + preview = canvas.preview + if preview > 1: + return + anchor = anchor_tk2gtk(anchor) + self._item = canvas.root().add(gnome.canvas.CanvasText, + x=x, y=y, anchor=anchor) + if not kw.has_key('fill'): + kw['fill'] = canvas._text_color + for k, v in kw.items(): + self[k] = v + self.text_format = None + canvas._text_items.append(self) + + def __setitem__(self, key, value): + if key == 'fill': + self._item.set(fill_color=value) + elif key == 'font': + self._item.set(font=value) + elif key == 'text': + self._item.set(text=value) + else: + raise AttributeError, key + + def config(self, **kw): + for k, v in kw.items(): + self[k] = v + + def __getitem__(self, key): + if key == 'text': + # FIXME + return "" + else: + raise AttributeError, key + cget = __getitem__ + + +# /*********************************************************************** +# // canvas +# ************************************************************************/ + +class MfxCanvas(gnome.canvas.Canvas): + def __init__(self, top, bg=None, highlightthickness=0): + self.preview = 0 + # Tkinter compat + self.items = {} + # private + self.__tileimage = None + self.__tiles = [] + # friend MfxCanvasText + self._text_color = '#000000' + self._text_items = [] + # + gnome.canvas.Canvas.__init__(self) + self.style = self.get_style().copy() + if bg is not None: + c = self.get_colormap().alloc(bg) + self.style.bg[gtk.STATE_NORMAL] = c + self.set_style(self.style) + self.set_scroll_region(0, 0, gdk.screen_width(), gdk.screen_height()) + top.vbox.pack_start(self) + ## + self.top = top + self.xmargin, self.ymargin = 0, 0 + + def __setattr__(self, name, value): + self.__dict__[name] = value + + def bind(self, sequence=None, func=None, add=None): + assert add is None + # FIXME + print "TkCanvas bind:", sequence + return + + def cget(self, attr): + if attr == 'cursor': + # FIXME + return gdk.LEFT_PTR + return self.get_window().get_cursor(v) + print "TkCanvas cget:", attr + raise AttributeError, attr + + def configure(self, **kw): + height, width = -1, -1 + for k, v in kw.items(): + if k == "background" or k == "bg": + print 'configure: bg:', v + c = self.get_colormap().alloc_color(v) + self.style.bg[gtk.STATE_NORMAL] = c + ##~ self.set_style(self.style) + self.queue_draw() + elif k == "cursor": + ##~ w = self.window + ##~ if w: + ##~ w.set_cursor(cursor_new(v)) + pass + elif k == "height": + height = v + elif k == "width": + width = v + else: + print "TkCanvas", k, v + raise AttributeError, k + if height > 0 and width > 0: + self.set_size_request(width, height) + #self.queue_draw() + #self.queue_resize() + #self.show() + #pass + + config = configure + + # PySol extension + # delete all CanvasItems, but keep the background and top tiles + def deleteAllItems(self): + ## FIXME + pass + + # PySol extension + def findCard(self, stack, event): + # FIXME + ##w = self.get_item_at(event.x, event.y) + ##print w + return stack._findCardXY(event.x, event.y) + + def pack(self, **kw): + self.show() + + # PySol extension + def setTextColor(self, color): + if self._text_color != color: + self._text_color = color + for item in self._text_items: + item.set(fill_color=_self.text_color) + + # PySol extension - set a tiled background image + def setTile(self, app, i, force=False): + ##print 'setTile' + tile = app.tabletile_manager.get(i) + if tile is None or tile.error: + return False + if i == 0: + assert tile.color + assert tile.filename is None + else: + assert tile.color is None + assert tile.filename + assert tile.basename + if not force: + if i == app.tabletile_index and tile.color == app.opt.table_color: + return False + # + if not self._setTile(tile.filename, tile.stretch): + tile.error = True + return False + + if i == 0: + self.configure(bg=tile.color) + ##app.top.config(bg=tile.color) + color = None + else: + self.configure(bg=app.top_bg) + ##app.top.config(bg=app.top_bg) + color = tile.text_color + + if app.opt.table_text_color: + self.setTextColor(app.opt.table_text_color_value) + else: + self.setTextColor(color) + + return True + + + ### FIXME: should use style.bg_pixmap ???? + def _setTile(self, image, stretch=False): + try: + if image and type(image) is types.StringType: + image = loadImage(image) + except: + return 0 + for item in self.__tiles: + item.destroy() + self.__tiles = [] + # must keep a reference to the image, otherwise Python will + # garbage collect it... + self.__tileimage = image + if image is None: + return 1 + iw, ih = image.width(), image.height() + sw = max(self.winfo_screenwidth(), 1024) + sh = max(self.winfo_screenheight(), 768) + for x in range(0, sw - 1, iw): + for y in range(0, sh - 1, ih): + item = self.root().add('image', x=x, y=y, width=iw, height=ih, + image=image.im._im, + anchor=gtk.ANCHOR_NW) + item.lower_to_bottom() + self.__tiles.append(item) + return 1 + + def setTopImage(self, image, cw=0, ch=0): + ## FIXME + pass + + def update_idletasks(self): + self.update_now() + + def grid(self, *args, **kw): + pass + + def setInitialSize(self, width, height): + self.set_size_request(width, height) + if self.window: + self.window.resize(width, height) + + + diff --git a/pysollib/pysolgtk/tkconst.py b/pysollib/pysolgtk/tkconst.py new file mode 100644 index 00000000..a6dae2b0 --- /dev/null +++ b/pysollib/pysolgtk/tkconst.py @@ -0,0 +1,66 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import sys +from gtk import gdk + + +# /*********************************************************************** +# // constants +# ************************************************************************/ + +tkname = "gnome" +# (major version, minor version, micro version, patchlevel) +tkversion = (0, 0, 0, 0) + +EVENT_HANDLED = 1 +EVENT_PROPAGATE = 0 + +CURSOR_DRAG = gdk.HAND1 +CURSOR_WATCH = gdk.WATCH + +TOOLBAR_BUTTONS = ( + "new", + "restart", + "open", + "save", + "undo", + "redo", + "autodrop", + "pause", + "statistics", + "rules", + "quit", + "player", + ) + diff --git a/pysollib/pysolgtk/tkhtml.py b/pysollib/pysolgtk/tkhtml.py new file mode 100644 index 00000000..be7d3ba6 --- /dev/null +++ b/pysollib/pysolgtk/tkhtml.py @@ -0,0 +1,56 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys + +# PySol imports + +# Toolkit imports +from tkwidget import MfxDialog + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class tkHTMLViewer: + symbols_fn = {} + + def __init__(self, parent): + self.parent = parent + self.parent.wm_deiconify() + + def display(self, url, add=1, relpath=1): + pass + + diff --git a/pysollib/pysolgtk/tkstats.py b/pysollib/pysolgtk/tkstats.py new file mode 100644 index 00000000..7d9c893c --- /dev/null +++ b/pysollib/pysolgtk/tkstats.py @@ -0,0 +1,65 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys +import gtk + +# PySol imports + +# Toolkit imports +from tkwidget import MfxDialog + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class SingleGame_StatsDialog(MfxDialog): + pass + +class AllGames_StatsDialog(MfxDialog): + pass + +class FullLog_StatsDialog(AllGames_StatsDialog): + pass + +class SessionLog_StatsDialog(FullLog_StatsDialog): + pass + +class Status_StatsDialog(MfxDialog): + pass + +class Top_StatsDialog(MfxDialog): + pass + + diff --git a/pysollib/pysolgtk/tkutil.py b/pysollib/pysolgtk/tkutil.py new file mode 100644 index 00000000..cc2325ee --- /dev/null +++ b/pysollib/pysolgtk/tkutil.py @@ -0,0 +1,267 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import sys, os, string, time, types + +import gtk +from gtk import gdk +TRUE, FALSE = True, False + + + +# /*********************************************************************** +# // window util +# ************************************************************************/ + +def wm_withdraw(window): + ##window.unmap() + pass + +def wm_deiconify(window): + window.show_all() + +def wm_map(window, maximized=None): + window.show_all() + +def wm_set_icon(window, icon): + pass + +def makeToplevel(parent, title=None, class_=None, gtkclass=gtk.Window): + window = gtkclass() + ##~ window.style = window.get_style().copy() + ##~ window.set_style(window.style) + if not hasattr(window, 'vbox'): + window.vbox = gtk.VBox() + window.vbox.show() + window.add(window.vbox) + window.realize() # needed for set_icon_name() + if title: + window.set_title(title) + ##~ window.set_icon_name(title) + if class_: + ## window.set_wmclass(???) ## FIXME + pass + return window + + +def setTransient(window, parent, relx=0.5, rely=0.3, expose=1): + window.realize() + ##~ grab_add(window) + if parent: + window.set_transient_for(parent) + if expose: + #window.unmap() # Become visible at the desired location + pass + + +# /*********************************************************************** +# // conversion util +# ************************************************************************/ + +def anchor_tk2gtk(anchor): + if type(anchor) is types.IntType: + assert 0 <= anchor <= 8 + return anchor + if type(anchor) is types.StringType: + a = ['center', 'n', 'nw', 'ne', 's', 'sw', 'se', 'w', 'e'] + return a.index(string.lower(anchor)) + assert 0 + + +def color_tk2gtk(col): + r = string.atoi(col[1:3], 16) / 255.0 + g = string.atoi(col[3:5], 16) / 255.0 + b = string.atoi(col[5:7], 16) / 255.0 + return (r, g, b, 1.0) + + +def color_gtk2tk(col): + r = int(round(col[0] * 255.0)) + g = int(round(col[1] * 255.0)) + b = int(round(col[2] * 255.0)) + return "#%02x%02x%02x" % (r, g, b) + + +# /*********************************************************************** +# // image util +# ************************************************************************/ + + + +class _PysolPixmap: + def __init__(self, file=None): + if file: + self.pixbuf = gdk.pixbuf_new_from_file(file) + else: + self.pixbuf = gdk.Pixbuf() + + def clone(self): + return self.pixbuf.copy() + + def width(self): + return self.pixbuf.get_width() + + def height(self): + return self.pixbuf.get_height() + + def subsample(self, x, y=None): + ## FIXME + return None + + +def loadImage(file): + return _PysolPixmap(file=file) + +def copyImage(image, x, y, width, height): + return image + +def createImage(width, height, fill, outline=None): + return _PysolPixmap() + + +# /*********************************************************************** +# // event wrapper +# // this really sucks, need something better... +# ************************************************************************/ + +def _wrap_b1_press(e): + return e.type == gdk.BUTTON_PRESS and e.button == 1 + +def _wrap_b2_press(e): + return e.type == gdk.BUTTON_PRESS and e.button == 2 + +def _wrap_b3_press(e): + return e.type == gdk.BUTTON_PRESS and e.button == 3 + +def _wrap_b1_motion(e): + return e.type == gdk.MOTION_NOTIFY and (e.state & gdk.BUTTON_PRESS_MASK) + +def _wrap_b1_release(e): + return e.type == gdk.BUTTON_RELEASE and e.button == 1 + +def _wrap_key_press(e, key): + return e.type == gdk.KEY_PRESS and e.key == key + + +_wrap_handlers = { + '<1>': _wrap_b1_press, + '': _wrap_b1_press, + '<2>': _wrap_b2_press, + '': _wrap_b2_press, + '<3>': _wrap_b3_press, + '': _wrap_b3_press, + '': _wrap_b1_motion, + '': _wrap_b1_release, +} +for c in " " + string.letters: + seq = "<" + c + ">" + if not _wrap_handlers.has_key(seq): + _wrap_handlers[seq] = lambda e, key=c: _wrap_key_press(e, key) +#print _wrap_handlers + + + +__bindings = {} + +def _wrap_event(widget, event, l): + for wrap, func in l: + if wrap(event): + #print "event:", wrap, func, event + return func(event) + return 0 + + +def bind(widget, sequence, func, add=None): + wrap = _wrap_handlers.get(sequence) + if not wrap: + ##print "NOT BOUND:", sequence + return + # HACK for MfxCanvasItem + if hasattr(widget, '_item'): + widget = widget._item + # + k = id(widget) + if __bindings.has_key(k): + __bindings[k].append((wrap, func)) + else: + l = [(wrap, func)] + widget.connect('event', _wrap_event, l) + __bindings[k] = l + + +def unbind_destroy(widget): + k = id(widget) + if __bindings.has_key(k): + ## FIXME + del __bindings[k] + + +# /*********************************************************************** +# // timer wrapper +# ************************************************************************/ + +def after(widget, ms, func, *args): + ## FIXME + return None + +def after_idle(widget, func, *args): + ## FIXME + return None + +def after_cancel(t): + if t is not None: + ## FIXME + pass + + +# /*********************************************************************** +# // font +# ************************************************************************/ + +getFont_cache = {} + +def getFont(name, cardw=0): + key = (name, cardw) + font = getFont_cache.get(key) + if font: + return font + # default + ### FIXME + font = "Helvetica-14" + font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" + getFont_cache[key] = font + return font + + +def getTextWidth(text, font=None, root=None): + return 10 diff --git a/pysollib/pysolgtk/tkwidget.py b/pysollib/pysolgtk/tkwidget.py new file mode 100644 index 00000000..8abaaf83 --- /dev/null +++ b/pysollib/pysolgtk/tkwidget.py @@ -0,0 +1,222 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys + +import gtk +TRUE, FALSE = True, False + +# PySol imports + +# Toolkit imports +from tkutil import makeToplevel, setTransient, wm_withdraw +from tkcanvas import MfxCanvas + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class _MyDialog(gtk.Dialog): + def __init__(self): + gtk.Dialog.__init__(self) + self.style = self.get_style().copy() + self.set_style(self.style) + self.connect("destroy", self.quit) + self.connect("delete_event", self.quit) + + def __setattr__(self, name, value): + self.__dict__[name] = value + + def quit(self, *args): + self.hide() + self.destroy() + gtk.mainquit() + + +class MfxDialog(_MyDialog): + def __init__(self, parent, title='', + timeout=0, + resizable=0, + text='', justify='center', + strings=("OK",), default=0, + width=0, separatorwidth=0, + font=None, + buttonfont=None, + padx='20', pady='20', + bitmap=None, bitmap_side='left', bitmap_padx=20, bitmap_pady=20, + image=None, image_side='left', image_padx=10, image_pady=20): + _MyDialog.__init__(self) + self.status = 1 + self.button = -1 + bitmap = None + self.init(parent, text, strings, default, bitmap, TRUE) + #font = "Times-14" + if font: + self.style.font = load_font(font) + self.set_style(self.style) + self.set_title(title) + self.show() + gtk.mainloop() + + def init(self, parent, message="", buttons=(), default=-1, + pixmap=None, modal=TRUE): + if modal: + setTransient(self, parent) + hbox = gtk.HBox(spacing=5) + hbox.set_border_width(5) + self.vbox.pack_start(hbox) + hbox.show() +## if pixmap: +## self.realize() +## pixmap = gtk.Pixmap(self, pixmap) +## hbox.pack_start(pixmap, expand=FALSE) +## pixmap.show() + label = gtk.Label(message) + hbox.pack_start(label) + label.show() + for i in range(len(buttons)): + text = buttons[i] + b = gtk.Button(text) + b.set_flags(gtk.CAN_DEFAULT) + if i == default: + b.grab_focus() + b.grab_default() + b.set_data("user_data", i) + b.connect("clicked", self.click) + self.action_area.pack_start(b) + b.show() + self.ret = None + + def click(self, button): + self.status = 0 + self.button = button.get_data("user_data") + self.quit() + + +MfxMessageDialog = MfxDialog + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class MfxExceptionDialog(MfxDialog): + def __init__(self, parent, ex, title="Error", **kw): + kw = KwStruct(kw, bitmap="error") + text = str(kw.get("text", "")) + if text and text[-1] != "\n": + text = text + "\n" + text = text + "\n" + if isinstance(ex, EnvironmentError) and ex.filename is not None: + t = '[Errno %s] %s:\n%s' % (ex.errno, ex.strerror, repr(ex.filename)) + else: + t = str(ex) + kw.text = text + t + apply(MfxDialog.__init__, (self, parent, title), kw.__dict__) + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class MfxSimpleSlider(_MyDialog): + def __init__(self, parent, title, + label, value, from_, to, resolution, + resizable=0): + self.button = 0 + self.status = 1 + self.value = value + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class MfxSimpleEntry(_MyDialog): + def __init__(self, parent, title, label, value, resizable=0, **kw): + _MyDialog.__init__(self) + self.button = 0 + self.status = 1 + self.value = value + self.init(parent, label, TRUE) + self.entry.set_text(str(value)) + self.set_title(title) + self.show() + gtk.mainloop() + + def init(self, parent, message="", modal=TRUE): + if modal: + setTransient(self, parent) + box = gtk.VBox(spacing=10) + box.set_border_width(10) + self.vbox.pack_start(box) + box.show() + if message: + label = gtk.Label(message) + box.pack_start(label) + label.show() + self.entry = gtk.Entry() + box.pack_start(self.entry) + self.entry.show() + self.entry.grab_focus() + button = gtk.Button("OK") + button.connect("clicked", self.click) + button.set_flags(CAN_DEFAULT) + self.action_area.pack_start(button) + button.show() + button.grab_default() + button = gtk.Button("Cancel") + button.connect("clicked", self.quit) + button.set_flags(CAN_DEFAULT) + self.action_area.pack_start(button) + button.show() + + def click(self, button): + self.status = 0 + self.value = self.entry.get_text() + self.quit() + + +class MfxScrolledCanvas(MfxCanvas): + def __init__(self, parent, hbar=2, vbar=2, **kw): + MfxCanvas.__init__(self, parent) + self.canvas = self + + + + + +class SelectDialogTreeData: + pass + diff --git a/pysollib/pysolgtk/tkwrap.py b/pysollib/pysolgtk/tkwrap.py new file mode 100644 index 00000000..e25d2f7a --- /dev/null +++ b/pysollib/pysolgtk/tkwrap.py @@ -0,0 +1,294 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, sys, time, types + +import gtk +from gtk import gdk +TRUE, FALSE = True, False + +# PySol imports +## from pysollib.images import Images + +# Toolkit imports +from tkutil import makeToplevel, loadImage + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class TclError: + pass + +def makeHelpToplevel(parent, title=None, class_=None): + return makeToplevel(parent, title=title, class_=class_, gtkclass=_MfxToplevel) + + +class MfxCheckMenuItem: + def __init__(self, menubar, path=None): + self.menubar = menubar + self.path = path + self.value = None + def get(self): + print 'MfxCheckMenuItem.get:', self.path + if self.path is None: return 0 + w = self.menubar.menus.get_widget(self.path) + return w.active + def set(self, value): + print 'MfxCheckMenuItem.set:', value, self.path + if self.path is None: return + if not value or value == 'false': value = 0 + assert type(value) is types.IntType and 0 <= value <= 1 + self.value = value + w = self.menubar.menus.get_widget(self.path) + w.set_active(value) + #print self.path, value, w, w.active + + +class MfxRadioMenuItem(MfxCheckMenuItem): + def get(self): + print 'MfxRadioMenuItem.get:', self.path, self.value + if self.path is None: return 0 + w = self.menubar.menus.get_widget(self.path) + #from pprint import pprint + #pprint(dir(w)) + #print 'widget:', w + #print w.active + #print w.__dict__ + return self.value + def set(self, value): + print 'MfxRadioMenuItem.set:', value, self.path + if self.path is None: return + if not value or value == 'false': value = 0 + assert type(value) is types.IntType and 0 <= value + self.value = value + #w = self.menubar.menus.get_widget(self.path) + #w.set_active(value) + #print self.path, value #, w, w.active + + +class StringVar: + def set(self, v): + pass + + +# /*********************************************************************** +# // A toplevel window. +# ************************************************************************/ + +class _MfxToplevel(gtk.Window): + def __init__(self, *args, **kw): + gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL) + ##~ self.style = self.get_style().copy() + self.set_style(self.style) + self.vbox = gtk.VBox() + self.vbox.show() + self.add(self.vbox) + self.realize() + + def cget(self, attr): + if attr == 'cursor': + # FIXME + return gdk.LEFT_PTR + return self.get_window().get_cursor(v) + print "Toplevel cget:", attr + ##~ raise AttributeError, attr + + def configure(self, **kw): + height, width = -1, -1 + for k, v in kw.items(): + if k == "background" or k == "bg": + c = self.get_colormap().alloc_color(v) + self.style.bg[gtk.STATE_NORMAL] = c + ##~ self.set_style(self.style) + self.queue_draw() + elif k == "cursor": + self.setCursor(v) + elif k == "height": + height = v + elif k == "width": + width = v + else: + print "Toplevel configure:", k, v + raise AttributeError, k + if height > 0 and width > 0: + ## FIXME + #self.set_default_size(width, height) + self.set_size_request(width, height) + #self.set_geometry_hints(base_width=width, base_height=height) + + config = configure + + def mainloop(self): + gtk.mainloop() # the global function + + def mainquit(self): + gtk.mainquit() # the global function + + def screenshot(self, filename): + pass + + def setCursor(self, cursor): + self.get_window().set_cursor(cursor_new(v)) + + def tk_setPalette(self, *args): + # FIXME ? + pass + + def update(self): + self.update_idletasks() + + def update_idletasks(self): + while gtk.events_pending(): + gtk.mainiteration(TRUE) + + def winfo_ismapped(self): + # FIXME + return 1 + + def winfo_screenwidth(self): + return gdk.screen_width() + + def winfo_screenheight(self): + return gdk.screen_height() + + def winfo_screendepth(self): + ##print 'winfo_screendepth', self.window.get_geometry() + return self.window.get_geometry()[-1] + + def wm_command(self, *args): + # FIXME + pass + + def wm_deiconify(self): + self.show_all() + + def wm_geometry(self, newGeometry=None): + ##print 'wm_geometry', newGeometry + if newGeometry == '': + self.resize(1, 1) + else: + w, h = newGeometry + self.resize(w, h) + + + + def wm_group(self, pathName=None): + # FIXME + pass + + def wm_iconbitmap(self, name): + if name and name[0] == '@' and name[-4:] == '.xbm': + name = name[1:-4] + '.xpm' + bg = self.get_style().bg[gtk.STATE_NORMAL] + pixmap, mask = create_pixmap_from_xpm(self, bg, name) + self.set_icon(pixmap, mask) + + def wm_iconname(self, name): + pass + ##~ self.set_icon_name(name) + + def wm_minsize(self, width, height): + self.set_geometry_hints(min_width=width, min_height=height) + + def wm_protocol(self, name=None, func=None): + if name == 'WM_DELETE_WINDOW': + self.connect("delete_event", func) + else: + raise AttributeError, name + + def wm_title(self, title): + self.set_title(title) + + def option_add(self, *args): + print self, 'option_add' + pass + + def option_get(self, *args): + print self, 'option_get' + return None + + def grid_columnconfigure(self, *args, **kw): + print self, 'grid_columnconfigure' + pass + + def grid_rowconfigure(self, *args, **kw): + print self, 'grid_rowconfigure' + pass + + def interruptSleep(self, *args, **kw): + ##print self, 'interruptSleep' + pass + + def wm_state(self): + print self, 'wm_state' + pass + + + +# /*********************************************************************** +# // The root toplevel window of an application. +# ************************************************************************/ + +class MfxRoot(_MfxToplevel): + def __init__(self, **kw): + apply(_MfxToplevel.__init__, (self,), kw) + self.app = None + + def connectApp(self, app): + self.app = app + + # sometimes an update() is needed under Windows, whereas + # under Unix an update_idletask() would be enough... + def busyUpdate(self): + game = None + if self.app: game = self.app.game + if not game: + self.update() + elif not game.busy: + game.busy = 1 + self.update() + game.busy = 0 + + # FIXME - make sleep interruptible + def sleep(self, seconds): + time.sleep(seconds) + + def wmDeleteWindow(self, *args): + if self.app and self.app.menubar: + self.app.menubar.mQuit() + else: + ##self.after_idle(self.quit) + pass + return TRUE diff --git a/pysollib/pysolgtk/toolbar.py b/pysollib/pysolgtk/toolbar.py new file mode 100644 index 00000000..76f6c9e4 --- /dev/null +++ b/pysollib/pysolgtk/toolbar.py @@ -0,0 +1,177 @@ +## vim:ts=4:et:nowrap +## +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +## +## 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 2 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; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## Markus F.X.J. Oberhumer +## +## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html +## +##---------------------------------------------------------------------------## + + +# imports +import os, re, sys + +import gtk +TRUE, FALSE = True, False + +# PySol imports + +from pysollib.actions import PysolToolbarActions + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class PysolToolbar(PysolToolbarActions): + def __init__(self, top, dir, relief=0): + PysolToolbarActions.__init__(self) + self.top = top + self.dir = dir + self.side = -1 + + self.toolbar = gtk.Toolbar(ORIENTATION_HORIZONTAL, TOOLBAR_ICONS) + self.bg = top.get_style().bg[STATE_NORMAL] + + self._createButton('new', self.mNewGame, tooltip='New game') + self._createButton('open', self.mOpen , tooltip='Open a \nsaved game') + self._createSeparator() + self._createButton('restart', self.mRestart, tooltip='Restart the \ncurrent game') + self._createButton('save', self.mSave, tooltip='Save game') + self._createSeparator() + self._createButton('undo', self.mUndo, tooltip='Undo') + self._createButton('redo', self.mRedo, tooltip='Redo') + self._createButton('autodrop',self.mDrop, tooltip='Auto drop') + self._createSeparator() + self._createButton('stats', self.mStatus, tooltip='Statistics') + self._createButton('rules', self.mHelpRules, tooltip='Rules') + self._createSeparator() + self._createButton('quit', self.mQuit, tooltip='Quit PySol') + self._createSeparator() + # no longer needed + self.bg = None + # + top.vbox.pack_start(self.toolbar, FALSE, FALSE) + + + # util + def _createButton(self, name, command, padx=0, tooltip=None): +## file = os.path.join(self.dir, name+".gif") +## im = GdkImlib.Image(file) +## im.render() +## pixmap = im.make_pixmap() +## if tooltip: tooltip = re.sub(r'\n', '', tooltip) + +##append_item(text, tooltip_text, tooltip_private_text, icon, callback, user_data=None) + + button = self.toolbar.append_item(name, tooltip, "", None, command) + setattr(self, name + "_button", button) + + def _createLabel(self, name, padx=0, side='IGNORE', tooltip=None): + ## FIXME: append_widget + pass + + def _createSeparator(self): + self.toolbar.append_space() + + + # + # wrappers + # + + def _busy(self): + return not (self.side and self.game and not self.game.busy and self.menubar) + + def destroy(self): + self.toolbar.destroy() + + def getSide(self): + return self.side + + def hide(self, resize=1): + self.show(None, resize) + + def show(self, side=1, resize=1): + self.side = side + if side: + self.toolbar.show() + else: + self.toolbar.hide() + + + # + # public methods + # + + def setCursor(self, cursor): + if self.side: + # FIXME + pass + + def setRelief(self, relief): + # FIXME + pass + + def updateText(self, **kw): + # FIXME + pass + + +# /*********************************************************************** +# // +# ************************************************************************/ + +#%ifndef BUNDLE + +class TestToolbar(PysolToolbar): + def __init__(self, top, args): + from util import DataLoader + dir = "kde-large" + dir = "gnome-large" + if len(args) > 1: dir = args[1] + dir = os.path.join(os.pardir, os.pardir, "data", "toolbar", dir) + ##print dataloader.dir + PysolToolbar.__init__(self, top, dir) + # test some settings + self.updateText(player="Player\nPySol") + self.undo_button.set_state(STATE_INSENSITIVE) + def mQuit(self, *args): + mainquit() + +def toolbar_main(args): + from tkwrap import MfxRoot + root = MfxRoot() + root.connect("destroy", mainquit) + root.connect("delete_event", mainquit) + toolbar = TestToolbar(root, args) + root.show_all() + mainloop() + return 0 + +if __name__ == '__main__': + sys.exit(toolbar_main(sys.argv)) + +#%endif + diff --git a/pysollib/pysoltk.py b/pysollib/pysoltk.py index d94fca66..fe126af8 100644 --- a/pysollib/pysoltk.py +++ b/pysollib/pysoltk.py @@ -19,25 +19,52 @@ ## ##---------------------------------------------------------------------------## -from tk.tkconst import * -from tk.tkutil import * -from tk.tkcanvas import * -from tk.tkwrap import * -from tk.tkwidget import * -from tk.tkhtml import * -from tk.edittextdialog import * -from tk.tkstats import * -from tk.playeroptionsdialog import * -from tk.soundoptionsdialog import * -from tk.timeoutsdialog import * -from tk.colorsdialog import * -from tk.fontsdialog import * -from tk.findcarddialog import * -from tk.gameinfodialog import * -from tk.toolbar import * -from tk.statusbar import * -from tk.progressbar import * -from tk.menubar import * -from tk.card import * -from tk.selectcardset import * -from tk.selecttree import * +from settings import TOOLKIT + +if TOOLKIT == 'tk': + from tk.tkconst import * + from tk.tkutil import * + from tk.tkcanvas import * + from tk.tkwrap import * + from tk.tkwidget import * + from tk.tkhtml import * + from tk.edittextdialog import * + from tk.tkstats import * + from tk.playeroptionsdialog import * + from tk.soundoptionsdialog import * + from tk.timeoutsdialog import * + from tk.colorsdialog import * + from tk.fontsdialog import * + from tk.findcarddialog import * + from tk.gameinfodialog import * + from tk.toolbar import * + from tk.statusbar import * + from tk.progressbar import * + from tk.menubar import * + from tk.card import * + from tk.selectcardset import * + from tk.selecttree import * + +else: + from pysolgtk.tkconst import * + from pysolgtk.tkutil import * + from pysolgtk.tkcanvas import * + from pysolgtk.tkwrap import * + from pysolgtk.tkwidget import * + from pysolgtk.tkhtml import * + from pysolgtk.edittextdialog import * + from pysolgtk.tkstats import * + from pysolgtk.playeroptionsdialog import * + from pysolgtk.soundoptionsdialog import * + from pysolgtk.timeoutsdialog import * + from pysolgtk.colorsdialog import * + from pysolgtk.fontsdialog import * + from pysolgtk.findcarddialog import * + from pysolgtk.gameinfodialog import * + from pysolgtk.toolbar import * + from pysolgtk.statusbar import * + from pysolgtk.progressbar import * + from pysolgtk.menubar import * + from pysolgtk.card import * + from pysolgtk.selectcardset import * + diff --git a/pysollib/settings.py b/pysollib/settings.py index f1a1dc3f..70cb08f8 100644 --- a/pysollib/settings.py +++ b/pysollib/settings.py @@ -28,6 +28,9 @@ n_ = lambda x: x PACKAGE = "PySol" PACKAGE_URL = "http://sourceforge.net/projects/pysolfc/" +TOOLKIT = 'gtk' +TOOLKIT = 'tk' + # data dirs DATA_DIRS = [] # you can add your extra directories here diff --git a/pysollib/stack.py b/pysollib/stack.py index dabb02c6..389e92d4 100644 --- a/pysollib/stack.py +++ b/pysollib/stack.py @@ -50,6 +50,8 @@ __all__ = ['cardsFaceUp', 'DealRowTalonStack', 'InitialDealTalonStack', 'RedealTalonStack', + 'DealRowRedealTalonStack', + 'DealReserveRedealTalonStack', 'OpenStack', 'AbstractFoundationStack', 'SS_FoundationStack', @@ -104,6 +106,7 @@ from pysoltk import after, after_idle, after_cancel from pysoltk import MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle, MfxCanvasText from pysoltk import Card from pysoltk import getTextWidth +from settings import TOOLKIT # /*********************************************************************** @@ -977,7 +980,7 @@ class Stack: if self.game.demo: self.game.stopDemo(event) if self.game.busy: return EVENT_HANDLED - if not self.game.app.opt.sticky_mouse: + if not self.game.app.opt.sticky_mouse and TOOLKIT == 'tk': # use a timer to update the drag # this allows us to skip redraws on slow machines drag = self.game.drag @@ -1056,6 +1059,8 @@ class Stack: drag.noshade_stacks = [ self ] drag.cards = self.getDragCards(i) drag.index = i + if TOOLKIT == 'gtk': + drag.stack.group.tkraise() images = game.app.images drag.shadows = self.createShadows(drag.cards) ##sx, sy = 0, 0 @@ -1070,6 +1075,8 @@ class Stack: for s in drag.shadows: if dx > 0 or dy > 0: s.move(dx, dy) + if TOOLKIT == 'gtk': + s.addtag(drag.stack.group) s.tkraise() for card in drag.cards: card.tkraise() @@ -1149,8 +1156,13 @@ class Stack: image=img1, anchor=ANCHOR_SE) s2 = MfxCanvasImage(self.game.canvas, cx, cy, image=img0, anchor=ANCHOR_SE) - s1.lower(c.item) - s2.lower(c.item) + if TOOLKIT == 'tk': + s1.lower(c.item) + s2.lower(c.item) + elif TOOLKIT == 'gtk': + positions = 2 ## FIXME + s1.lower(positions) + s2.lower(positions) return (s1, s2) return () @@ -1213,10 +1225,15 @@ class Stack: img = MfxCanvasImage(game.canvas, sx, sy, image=img, anchor=ANCHOR_NW) drag.shade_img = img # raise/lower the shade image to the correct stacking order - if drag.shadows: - img.lower(drag.shadows[0]) - else: - img.lower(drag.cards[0].item) + if TOOLKIT == 'tk': + if drag.shadows: + img.lower(drag.shadows[0]) + else: + img.lower(drag.cards[0].item) + elif TOOLKIT == 'gtk': + img.tkraise() + drag.stack.group.tkraise() + # for closeStackMove def _shadeStack(self): @@ -1547,7 +1564,11 @@ class TalonStack(Stack, self.images.redeal = MfxCanvasImage(self.game.canvas, cx, cy, image=img, anchor="center") self.images.redeal_img = img - self.images.redeal.tkraise(self.top_bottom) + if TOOLKIT == 'tk': + self.images.redeal.tkraise(self.top_bottom) + elif TOOLKIT == 'gtk': + ### FIXME + pass self.images.redeal.addtag(self.group) self.top_bottom = self.images.redeal if images.CARDH >= 90: @@ -1563,7 +1584,11 @@ class TalonStack(Stack, self.texts.redeal = MfxCanvasText(self.game.canvas, cx, cy, anchor=ca, font=font) self.texts.redeal_str = "" - self.texts.redeal.tkraise(self.top_bottom) + if TOOLKIT == 'tk': + self.texts.redeal.tkraise(self.top_bottom) + elif TOOLKIT == 'gtk': + ### FIXME + pass self.texts.redeal.addtag(self.group) self.top_bottom = self.texts.redeal @@ -1612,6 +1637,45 @@ class RedealTalonStack(TalonStack, RedealCards_StackMethods): RedealCards_StackMethods.redealCards(self, sound=sound) +class DealRowRedealTalonStack(TalonStack, RedealCards_StackMethods): + + def canDealCards(self, rows=None): + if rows is None: + rows = self.game.s.rows + r_cards = sum([len(r.cards) for r in rows]) + if self.cards: + return True + elif r_cards and self.round != self.max_rounds: + return True + return False + + def dealCards(self, sound=0, rows=None): + num_cards = 0 + if rows is None: + rows = self.game.s.rows + if sound and self.game.app.opt.animations: + self.game.startDealSample() + if not self.cards: + # move all cards to talon + num_cards = self._redeal(rows=rows, frames=4) + self.game.nextRoundMove(self) + num_cards += self.dealRowAvail(rows=rows, sound=0) + if sound: + self.game.stopSamples() + return num_cards + + +class DealReserveRedealTalonStack(DealRowRedealTalonStack): + + def canDealCards(self, rows=None): + return DealRowRedealTalonStack.canDealCards(self, + rows=self.game.s.reserves) + + def dealCards(self, sound=0, rows=None): + return DealRowRedealTalonStack.dealCards(self, sound=sound, + rows=self.game.s.reserves) + + # /*********************************************************************** # // An OpenStack is a stack where cards can be placed and dragged # // (i.e. FoundationStack, RowStack, ReserveStack, ...) diff --git a/pysollib/tk/menubar.py b/pysollib/tk/menubar.py index a24c4e88..62ed3d0d 100644 --- a/pysollib/tk/menubar.py +++ b/pysollib/tk/menubar.py @@ -966,12 +966,12 @@ class PysolMenubar(PysolMenubarActions): elif d.key > 0 and d.key != self.app.tabletile_index: self._mOptTableTile(d.key) - def mOptTableColor(self, *event): - if self._cancelDrag(break_pause=False): return - c = tkColorChooser.askcolor(initialcolor=self.app.opt.table_color, - title=_("Select table color")) - if c and c[1]: - self._mOptTableColor(c[1]) +## def mOptTableColor(self, *event): +## if self._cancelDrag(break_pause=False): return +## c = tkColorChooser.askcolor(initialcolor=self.app.opt.table_color, +## title=_("Select table color")) +## if c and c[1]: +## self._mOptTableColor(c[1]) def mOptToolbar(self, *event): ##if self._cancelDrag(break_pause=False): return diff --git a/pysollib/tk/tkwrap.py b/pysollib/tk/tkwrap.py index dfb21889..74b26631 100644 --- a/pysollib/tk/tkwrap.py +++ b/pysollib/tk/tkwrap.py @@ -34,8 +34,8 @@ ##---------------------------------------------------------------------------## __all__ = ['TclError', - 'BooleanVar', - 'IntVar', + 'MfxCheckMenuItem', + 'MfxRadioMenuItem', 'StringVar', 'MfxRoot'] @@ -53,8 +53,27 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE # // menubar # ************************************************************************/ -BooleanVar = Tkinter.BooleanVar -IntVar = Tkinter.IntVar +class MfxCheckMenuItem(Tkinter.BooleanVar): + def __init__(self, menubar, path=None): + Tkinter.BooleanVar.__init__(self) + def set(self, value): + if not value or value == "false": value = 0 + ##print value, type(value) + ##assert type(value) is types.IntType and 0 <= value <= 1 + Tkinter.BooleanVar.set(self, value) + + +class MfxRadioMenuItem(Tkinter.IntVar): + def __init__(self, menubar, path=None): + Tkinter.IntVar.__init__(self) + def set(self, value): + ##assert type(value) is types.IntType and 0 <= value + Tkinter.IntVar.set(self, value) + + +## BooleanVar = Tkinter.BooleanVar +## IntVar = Tkinter.IntVar + StringVar = Tkinter.StringVar