1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

+ 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
This commit is contained in:
skomoroh 2006-08-13 21:10:55 +00:00
parent 952125b5f8
commit 97537e05a2
35 changed files with 3070 additions and 216 deletions

View file

@ -58,7 +58,7 @@ from pysoltk import GameInfoDialog
from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE
from pysoltk import MfxMessageDialog, MfxSimpleEntry from pysoltk import MfxMessageDialog, MfxSimpleEntry
from pysoltk import MfxExceptionDialog from pysoltk import MfxExceptionDialog
from pysoltk import BooleanVar, IntVar, StringVar from pysoltk import MfxRadioMenuItem, MfxCheckMenuItem, StringVar
from pysoltk import PlayerOptionsDialog from pysoltk import PlayerOptionsDialog
from pysoltk import SoundOptionsDialog from pysoltk import SoundOptionsDialog
#from pysoltk import HintOptionsDialog #from pysoltk import HintOptionsDialog
@ -103,50 +103,50 @@ class PysolMenubarActions:
) )
# structure to convert menu-options to Toolkit variables # structure to convert menu-options to Toolkit variables
self.tkopt = Struct( self.tkopt = Struct(
gameid = IntVar(), gameid = MfxRadioMenuItem(self),
gameid_popular = IntVar(), gameid_popular = MfxRadioMenuItem(self),
comment = BooleanVar(), comment = MfxCheckMenuItem(self),
autofaceup = BooleanVar(), autofaceup = MfxCheckMenuItem(self),
autodrop = BooleanVar(), autodrop = MfxCheckMenuItem(self),
autodeal = BooleanVar(), autodeal = MfxCheckMenuItem(self),
quickplay = BooleanVar(), quickplay = MfxCheckMenuItem(self),
undo = BooleanVar(), undo = MfxCheckMenuItem(self),
bookmarks = BooleanVar(), bookmarks = MfxCheckMenuItem(self),
hint = BooleanVar(), hint = MfxCheckMenuItem(self),
highlight_piles = BooleanVar(), highlight_piles = MfxCheckMenuItem(self),
highlight_cards = BooleanVar(), highlight_cards = MfxCheckMenuItem(self),
highlight_samerank = BooleanVar(), highlight_samerank = MfxCheckMenuItem(self),
highlight_not_matching = BooleanVar(), highlight_not_matching = MfxCheckMenuItem(self),
mahjongg_show_removed = BooleanVar(), mahjongg_show_removed = MfxCheckMenuItem(self),
shisen_show_hint = BooleanVar(), shisen_show_hint = MfxCheckMenuItem(self),
sound = BooleanVar(), sound = MfxCheckMenuItem(self),
cardback = IntVar(), cardback = MfxRadioMenuItem(self),
tabletile = IntVar(), tabletile = MfxRadioMenuItem(self),
animations = IntVar(), animations = MfxRadioMenuItem(self),
shadow = BooleanVar(), shadow = MfxCheckMenuItem(self),
shade = BooleanVar(), shade = MfxCheckMenuItem(self),
shade_filled_stacks = BooleanVar(), shade_filled_stacks = MfxCheckMenuItem(self),
shrink_face_down = BooleanVar(), shrink_face_down = MfxCheckMenuItem(self),
toolbar = IntVar(), toolbar = MfxRadioMenuItem(self),
toolbar_style = StringVar(), toolbar_style = StringVar(),
toolbar_relief = StringVar(), toolbar_relief = StringVar(),
toolbar_compound = StringVar(), toolbar_compound = StringVar(),
toolbar_size = IntVar(), toolbar_size = MfxRadioMenuItem(self),
statusbar = BooleanVar(), statusbar = MfxCheckMenuItem(self),
num_cards = BooleanVar(), num_cards = MfxCheckMenuItem(self),
helpbar = BooleanVar(), helpbar = MfxCheckMenuItem(self),
save_games_geometry = BooleanVar(), save_games_geometry = MfxCheckMenuItem(self),
splashscreen = BooleanVar(), splashscreen = MfxCheckMenuItem(self),
demo_logo = BooleanVar(), demo_logo = MfxCheckMenuItem(self),
sticky_mouse = BooleanVar(), sticky_mouse = MfxCheckMenuItem(self),
mouse_undo = BooleanVar(), mouse_undo = MfxCheckMenuItem(self),
negative_bottom = BooleanVar(), negative_bottom = MfxCheckMenuItem(self),
pause = BooleanVar(), pause = MfxCheckMenuItem(self),
toolbar_vars = {}, toolbar_vars = {},
) )
for w in TOOLBAR_BUTTONS: for w in TOOLBAR_BUTTONS:
self.tkopt.toolbar_vars[w] = BooleanVar() self.tkopt.toolbar_vars[w] = MfxCheckMenuItem(self)
def connectGame(self, game): def connectGame(self, game):

View file

@ -55,7 +55,7 @@ from images import Images, SubsampledImages
from pysolrandom import PysolRandom from pysolrandom import PysolRandom
from game import Game from game import Game
from gamedb import GI, GAME_DB, loadGame from gamedb import GI, GAME_DB, loadGame
from settings import TOP_SIZE, TOP_TITLE from settings import TOP_SIZE, TOP_TITLE, TOOLKIT
# Toolkit imports # Toolkit imports
from pysoltk import tkname, tkversion, wm_withdraw, loadImage from pysoltk import tkname, tkversion, wm_withdraw, loadImage
@ -85,29 +85,29 @@ class Options:
self.saved = 0 self.saved = 0
# options menu: # options menu:
self.player = _("Unknown") self.player = _("Unknown")
self.confirm = 1 self.confirm = True
self.update_player_stats = 1 self.update_player_stats = True
self.autofaceup = 1 self.autofaceup = True
self.autodrop = 0 self.autodrop = False
self.autodeal = 1 self.autodeal = True
self.quickplay = 1 self.quickplay = True
self.undo = 1 self.undo = True
self.bookmarks = 1 self.bookmarks = True
self.hint = 1 self.hint = True
self.highlight_piles = 1 self.highlight_piles = True
self.highlight_cards = 1 self.highlight_cards = True
self.highlight_samerank = 1 self.highlight_samerank = True
self.highlight_not_matching = 1 self.highlight_not_matching = True
self.mahjongg_show_removed = False self.mahjongg_show_removed = False
self.mahjongg_create_solvable = True self.mahjongg_create_solvable = True
self.shisen_show_hint = True self.shisen_show_hint = True
self.animations = 2 # default to Timer based self.animations = 2 # default to Timer based
self.shadow = 1 self.shadow = True
self.shade = 1 self.shade = True
self.shrink_face_down = True self.shrink_face_down = True
self.shade_filled_stacks = True self.shade_filled_stacks = True
self.demo_logo = 1 self.demo_logo = True
self.toolbar = 1 self.toolbar = True
##self.toolbar_style = 'default' ##self.toolbar_style = 'default'
self.toolbar_style = 'crystal' self.toolbar_style = 'crystal'
if os.name == 'posix': if os.name == 'posix':
@ -118,11 +118,11 @@ class Options:
self.toolbar_vars = {} self.toolbar_vars = {}
for w in TOOLBAR_BUTTONS: for w in TOOLBAR_BUTTONS:
self.toolbar_vars[w] = True self.toolbar_vars[w] = True
self.statusbar = 1 self.statusbar = True
self.num_cards = 0 self.num_cards = False
self.helpbar = 0 self.helpbar = False
# sound # sound
self.sound = 1 self.sound = True
self.sound_mode = 1 self.sound_mode = 1
self.sound_sample_volume = 128 self.sound_sample_volume = 128
self.sound_music_volume = 128 self.sound_music_volume = 128
@ -234,8 +234,8 @@ class Options:
# not changeable options # not changeable options
def setConstants(self): def setConstants(self):
self.win_animation = 1 self.win_animation = True
self.dragcursor = 1 self.dragcursor = True
self.randomize_place = False self.randomize_place = False
def copy(self): def copy(self):
@ -661,14 +661,15 @@ class Application:
self.top.grid_rowconfigure(1, weight=1) self.top.grid_rowconfigure(1, weight=1)
self.setTile(self.tabletile_index, force=True) self.setTile(self.tabletile_index, force=True)
# create the toolbar # create the toolbar
dir = self.getToolbarImagesDir() if TOOLKIT == 'tk':
self.toolbar = PysolToolbar(self.top, dir=dir, dir = self.getToolbarImagesDir()
size=self.opt.toolbar_size, self.toolbar = PysolToolbar(self.top, dir=dir,
relief=self.opt.toolbar_relief, size=self.opt.toolbar_size,
compound=self.opt.toolbar_compound) relief=self.opt.toolbar_relief,
self.toolbar.show(self.opt.toolbar) compound=self.opt.toolbar_compound)
for w, v in self.opt.toolbar_vars.items(): self.toolbar.show(self.opt.toolbar)
self.toolbar.config(w, v) for w, v in self.opt.toolbar_vars.items():
self.toolbar.config(w, v)
# #
if self.intro.progress: self.intro.progress.update(step=1) if self.intro.progress: self.intro.progress.update(step=1)
# #
@ -754,7 +755,8 @@ class Application:
self.game.create(self) self.game.create(self)
# connect with game # connect with game
self.menubar.connectGame(self.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) self.game.updateStatus(player=self.opt.player)
# update "Recent games" menubar entry # update "Recent games" menubar entry
if id in self.opt.recent_gameid: if id in self.opt.recent_gameid:
@ -805,7 +807,8 @@ class Application:
# free game # free game
def freeGame(self): def freeGame(self):
# disconnect from game # disconnect from game
self.toolbar.connectGame(None, None) if self.toolbar: ##~
self.toolbar.connectGame(None, None)
self.menubar.connectGame(None) self.menubar.connectGame(None)
# clean up the canvas # clean up the canvas
self.canvas.deleteAllItems() self.canvas.deleteAllItems()

View file

@ -1556,7 +1556,7 @@ for %d moves.
color = self.app.opt.highlight_not_matching_color color = self.app.opt.highlight_not_matching_color
width = 6 width = 6
x0, y0 = x+width/2-self.canvas.xmargin, y+width/2-self.canvas.ymargin 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, r = MfxCanvasRectangle(self.canvas, x0, y0, x1, y1,
width=width, fill=None, outline=color) width=width, fill=None, outline=color)
self.canvas.update_idletasks() self.canvas.update_idletasks()

View file

@ -142,19 +142,13 @@ class Pyramid_RowStack(Pyramid_StackMethods, OpenStack):
def __init__(self, x, y, game): def __init__(self, x, y, game):
OpenStack.__init__(self, x, y, game, max_accept=1, max_cards=2) OpenStack.__init__(self, x, y, game, max_accept=1, max_cards=2)
self.CARD_YOFFSET = 1 self.CARD_YOFFSET = 1
self.blockmap = []
STEP = (1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6)
def basicIsBlocked(self): def basicIsBlocked(self):
r, step = self.game.s.rows, self.STEP for r in self.blockmap:
i, n = self.id, 1 if r.cards:
while i < 21: return True
i = i + step[i] return False
n = n + 1
for j in range(i, i+n):
if r[j].cards:
return 1
return 0
def clickHandler(self, event): def clickHandler(self, event):
if self._dropKingClickHandler(event): if self._dropKingClickHandler(event):
@ -173,10 +167,33 @@ class Pyramid(Game):
RowStack_Class = Pyramid_RowStack RowStack_Class = Pyramid_RowStack
WasteStack_Class = Pyramid_Waste WasteStack_Class = Pyramid_Waste
PYRAMID_Y_FACTOR = 2
# #
# game layout # 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): def createGame(self, rows=4, reserves=0, waste=True, texts=True):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
@ -190,12 +207,8 @@ class Pyramid(Game):
self.setSize(w, h) self.setSize(w, h)
# create stacks # create stacks
for i in range(7): x, y = l.XM+l.XS, l.YM
x = l.XM + (8-i) * l.XS / 2 s.rows = self._createPyramid(l, x, y, 7)
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.YM x, y = l.XM, l.YM
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
@ -315,8 +328,8 @@ class Thirteen(Pyramid):
s.waste.CARD_XOFFSET = 14 s.waste.CARD_XOFFSET = 14
x, y = self.width - l.XS, l.YM x, y = self.width - l.XS, l.YM
s.foundations.append(Pyramid_Foundation(x, y, self, s.foundations.append(Pyramid_Foundation(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=UNLIMITED_CARDS)) max_move=0, max_cards=52))
# define stack-groups # define stack-groups
self.sg.talonstacks = [s.talon] + [s.waste] self.sg.talonstacks = [s.talon] + [s.waste]
@ -690,7 +703,6 @@ class TripleAlliance(Game):
# ************************************************************************/ # ************************************************************************/
class Pharaohs_RowStack(Pyramid_RowStack): class Pharaohs_RowStack(Pyramid_RowStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not self.basicAcceptsCards(from_stack, cards): if not self.basicAcceptsCards(from_stack, cards):
return False return False
@ -701,12 +713,6 @@ class Pharaohs_RowStack(Pyramid_RowStack):
return True return True
return r0 == r1 return r0 == r1
def basicIsBlocked(self):
for r in self.blockmap:
if r.cards:
return True
return False
class Pharaohs(Pyramid): class Pharaohs(Pyramid):
@ -715,28 +721,6 @@ class Pharaohs(Pyramid):
PYRAMID_Y_FACTOR = 3 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): def createGame(self):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
@ -867,28 +851,6 @@ class Apophis_RowStack(Pharaohs_RowStack):
return r0+r1 == 11 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): class Apophis(Pharaohs):
Hint_Class = Apophis_Hint Hint_Class = Apophis_Hint
RowStack_Class = Apophis_RowStack RowStack_Class = Apophis_RowStack
@ -909,7 +871,7 @@ class Apophis(Pharaohs):
s.rows = self._createPyramid(l, x, y, 7) s.rows = self._createPyramid(l, x, y, 7)
x, y = l.XM, l.YM 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') l.createText(s.talon, 'se')
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") tx, ty, ta, tf = l.getTextAttr(s.talon, "ne")
font = self.app.getFont("canvas_default") font = self.app.getFont("canvas_default")

View file

@ -905,6 +905,60 @@ class Adela(Game):
shallHighlightMatch = Game._shallHighlightMatch_SS 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 # register the game
registerGame(GameInfo(330, Sultan, "Sultan", 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)) GI.GT_1DECK_TYPE, 1, 1, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(646, Adela, "Adela", registerGame(GameInfo(646, Adela, "Adela",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK)) 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))

View file

@ -34,46 +34,27 @@ from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
# /*********************************************************************** # /***********************************************************************
# // # // Tournament
# ************************************************************************/ # ************************************************************************/
class Tournament_Talon(DealRowRedealTalonStack):
class Tournament_Talon(TalonStack):
def canDealCards(self):
if self.round == self.max_rounds and not self.cards:
return False
return not self.game.isGameWon()
def dealCards(self, sound=0): def dealCards(self, sound=0):
num_cards = 0
if sound and self.game.app.opt.animations:
self.game.startDealSample()
if len(self.cards) == 0: if len(self.cards) == 0:
self._redeal() num_cards = self._redeal(reverse=True, frames=0)
self.game.startDealSample() self.game.nextRoundMove(self)
n = 0
for r in self.game.s.rows: for r in self.game.s.rows:
for i in range(4): for i in range(4):
if not self.cards: if not self.cards:
break break
n += self.dealRow([r]) num_cards += self.dealRow([r], sound=0)
self.game.stopSamples() if sound:
return n self.game.stopSamples()
return num_cards
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
class Tournament(Game): class Tournament(Game):

View file

137
pysollib/pysolgtk/card.py Normal file
View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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
## <markus@oberhumer.com>
## http://www.oberhumer.com/pysol
##
##---------------------------------------------------------------------------##
__all__ = ['EditTextDialog']
# imports
## import os, sys, Tkinter
# PySol imports
# Toolkit imports
from tkwidget import MfxDialog
# /***********************************************************************
# //
# ************************************************************************/
class EditTextDialog(MfxDialog):
pass

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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('<main>')
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, "<Branch>"),
("/File/<tearoff>", None, None, 0, "<Tearoff>"),
("/File/_New Game", "<control>N", self.mNewGame, 0, ""),
("/File/Select _game", None, None, 0, "<Branch>"),
)
#
# /File/Select game
#
mi, radio = [], "<RadioItem>"
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, '<Branch>'))
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, '<Branch>'))
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/<sep>", None, None, 0, "<Separator>"),
("/File/_Open", "<control>O", self.m, 0, ""),
("/File/_Save", "<control>S", self.mSave, 0, ""),
("/File/Save _as...", None, self.m, 0, ""),
("/File/<sep>", None, None, 0, "<Separator>"),
("/File/_Quit", "<control>Q", self.mQuit, 0, ""),
("/_Edit", None, None, 0, "<Branch>"),
("/Edit/<tearoff>", None, None, 0, "<Tearoff>"),
("/Edit/_Undo", "Z", self.mUndo, 0, ""),
("/Edit/_Redo", "R", self.mRedo, 0, ""),
("/Edit/Redo _all", None, self.mRedoAll, 0, ""),
("/Edit/<sep>", None, None, 0, "<Separator>"),
("/Edit/Restart _game", "<control>G", self.mRestart, 0, ""),
("/_Game", None, None, 0, "<Branch>"),
("/Game/<tearoff>", None, None, 0, "<Tearoff>"),
("/Game/_Deal cards", "D", self.mDeal, 0, ""),
("/Game/_Auto drop", "A", self.mDrop, 0, ""),
("/Game/<sep>", None, None, 0, "<Separator>"),
("/Game/S_tatus...", "T", self.mStatus, 0, ""),
("/_Assist", None, None, 0, "<Branch>"),
("/Assist/<tearoff>", None, None, 0, "<Tearoff>"),
("/Assist/_Hint", "H", self.mHint, 0, ""),
("/Assist/Highlight _piles", "Shift", self.mHighlightPiles, 0, ""),
("/Assist/<sep>", None, None, 0, "<Separator>"),
("/Assist/_Demo", "<control>D", self.mDemo, 0, ""),
("/Assist/Demo (all games)", "", self.mMixedDemo, 0, ""),
("/_Options", None, None, 0, "<Branch>"),
("/Options/<tearoff>", None, None, 0, "<Tearoff>"),
("/Options/_Confirm", None, self.mOptConfirm, 0, "<ToggleItem>"),
("/Options/Auto_play", "P", self.mOptAutoDrop, 0, "<ToggleItem>"),
("/Options/_Automatic _face up", "F", self.mOptAutoFaceUp, 0, "<ToggleItem>"),
("/Options/Highlight _matching cards", None, self.mOptEnableHighlightCards, 0, "<ToggleItem>"),
("/Options/<sep>", None, None, 0, "<Separator>"),
)
mi, radio = [], "<RadioItem>"
path = "/Options/Cards_et"
mi.append((path, None, None, 0, "<Branch>"))
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 = [], "<RadioItem>"
path = "/Options/_Animations"
mi.append((path, None, None, 0, "<Branch>"))
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, "<ToggleItem>"),
("/Options/Shade legal moves", None, self.mOptShade, 0, "<ToggleItem>"),
("/Options/<sep>", None, None, 0, "<Separator>"),
("/Options/_Hint options...", None, self.mOptHintOptions, 0, ""),
("/Options/_Demo options...", None, self.mOptDemoOptions, 0, ""),
("/_Help", None, None, 0, "<LastBranch>"),
("/Help/<tearoff>", None, None, 0, "<Tearoff>"),
("/Help/_Contents", "F1", self.mHelp, 0, ""),
("/Help/_Rules", None, self.mHelpRules, 0, ""),
("/Help/<sep>", None, None, 0, "<Separator>"),
("/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, '<main>', 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)

View file

@ -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
## <markus@oberhumer.com>
## http://www.oberhumer.com/pysol
##
##---------------------------------------------------------------------------##
__all__ = ['PlayerOptionsDialog']
# imports
import gtk
# PySol imports
# Toolkit imports
from tkwidget import MfxDialog
# /***********************************************************************
# //
# ************************************************************************/
class PlayerOptionsDialog(MfxDialog):
pass

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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
## <markus@oberhumer.com>
## 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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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)

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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",
)

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

267
pysollib/pysolgtk/tkutil.py Normal file
View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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,
'<ButtonPress-1>': _wrap_b1_press,
'<2>': _wrap_b2_press,
'<ButtonPress-2>': _wrap_b2_press,
'<3>': _wrap_b3_press,
'<ButtonPress-3>': _wrap_b3_press,
'<Motion>': _wrap_b1_motion,
'<ButtonRelease-1>': _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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

294
pysollib/pysolgtk/tkwrap.py Normal file
View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -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
## <markus.oberhumer@jk.uni-linz.ac.at>
## 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

View file

@ -19,25 +19,52 @@
## ##
##---------------------------------------------------------------------------## ##---------------------------------------------------------------------------##
from tk.tkconst import * from settings import TOOLKIT
from tk.tkutil import *
from tk.tkcanvas import * if TOOLKIT == 'tk':
from tk.tkwrap import * from tk.tkconst import *
from tk.tkwidget import * from tk.tkutil import *
from tk.tkhtml import * from tk.tkcanvas import *
from tk.edittextdialog import * from tk.tkwrap import *
from tk.tkstats import * from tk.tkwidget import *
from tk.playeroptionsdialog import * from tk.tkhtml import *
from tk.soundoptionsdialog import * from tk.edittextdialog import *
from tk.timeoutsdialog import * from tk.tkstats import *
from tk.colorsdialog import * from tk.playeroptionsdialog import *
from tk.fontsdialog import * from tk.soundoptionsdialog import *
from tk.findcarddialog import * from tk.timeoutsdialog import *
from tk.gameinfodialog import * from tk.colorsdialog import *
from tk.toolbar import * from tk.fontsdialog import *
from tk.statusbar import * from tk.findcarddialog import *
from tk.progressbar import * from tk.gameinfodialog import *
from tk.menubar import * from tk.toolbar import *
from tk.card import * from tk.statusbar import *
from tk.selectcardset import * from tk.progressbar import *
from tk.selecttree 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 *

View file

@ -28,6 +28,9 @@ n_ = lambda x: x
PACKAGE = "PySol" PACKAGE = "PySol"
PACKAGE_URL = "http://sourceforge.net/projects/pysolfc/" PACKAGE_URL = "http://sourceforge.net/projects/pysolfc/"
TOOLKIT = 'gtk'
TOOLKIT = 'tk'
# data dirs # data dirs
DATA_DIRS = [] DATA_DIRS = []
# you can add your extra directories here # you can add your extra directories here

View file

@ -50,6 +50,8 @@ __all__ = ['cardsFaceUp',
'DealRowTalonStack', 'DealRowTalonStack',
'InitialDealTalonStack', 'InitialDealTalonStack',
'RedealTalonStack', 'RedealTalonStack',
'DealRowRedealTalonStack',
'DealReserveRedealTalonStack',
'OpenStack', 'OpenStack',
'AbstractFoundationStack', 'AbstractFoundationStack',
'SS_FoundationStack', 'SS_FoundationStack',
@ -104,6 +106,7 @@ from pysoltk import after, after_idle, after_cancel
from pysoltk import MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle, MfxCanvasText from pysoltk import MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle, MfxCanvasText
from pysoltk import Card from pysoltk import Card
from pysoltk import getTextWidth from pysoltk import getTextWidth
from settings import TOOLKIT
# /*********************************************************************** # /***********************************************************************
@ -977,7 +980,7 @@ class Stack:
if self.game.demo: if self.game.demo:
self.game.stopDemo(event) self.game.stopDemo(event)
if self.game.busy: return EVENT_HANDLED 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 # use a timer to update the drag
# this allows us to skip redraws on slow machines # this allows us to skip redraws on slow machines
drag = self.game.drag drag = self.game.drag
@ -1056,6 +1059,8 @@ class Stack:
drag.noshade_stacks = [ self ] drag.noshade_stacks = [ self ]
drag.cards = self.getDragCards(i) drag.cards = self.getDragCards(i)
drag.index = i drag.index = i
if TOOLKIT == 'gtk':
drag.stack.group.tkraise()
images = game.app.images images = game.app.images
drag.shadows = self.createShadows(drag.cards) drag.shadows = self.createShadows(drag.cards)
##sx, sy = 0, 0 ##sx, sy = 0, 0
@ -1070,6 +1075,8 @@ class Stack:
for s in drag.shadows: for s in drag.shadows:
if dx > 0 or dy > 0: if dx > 0 or dy > 0:
s.move(dx, dy) s.move(dx, dy)
if TOOLKIT == 'gtk':
s.addtag(drag.stack.group)
s.tkraise() s.tkraise()
for card in drag.cards: for card in drag.cards:
card.tkraise() card.tkraise()
@ -1149,8 +1156,13 @@ class Stack:
image=img1, anchor=ANCHOR_SE) image=img1, anchor=ANCHOR_SE)
s2 = MfxCanvasImage(self.game.canvas, cx, cy, s2 = MfxCanvasImage(self.game.canvas, cx, cy,
image=img0, anchor=ANCHOR_SE) image=img0, anchor=ANCHOR_SE)
s1.lower(c.item) if TOOLKIT == 'tk':
s2.lower(c.item) s1.lower(c.item)
s2.lower(c.item)
elif TOOLKIT == 'gtk':
positions = 2 ## FIXME
s1.lower(positions)
s2.lower(positions)
return (s1, s2) return (s1, s2)
return () return ()
@ -1213,10 +1225,15 @@ class Stack:
img = MfxCanvasImage(game.canvas, sx, sy, image=img, anchor=ANCHOR_NW) img = MfxCanvasImage(game.canvas, sx, sy, image=img, anchor=ANCHOR_NW)
drag.shade_img = img drag.shade_img = img
# raise/lower the shade image to the correct stacking order # raise/lower the shade image to the correct stacking order
if drag.shadows: if TOOLKIT == 'tk':
img.lower(drag.shadows[0]) if drag.shadows:
else: img.lower(drag.shadows[0])
img.lower(drag.cards[0].item) else:
img.lower(drag.cards[0].item)
elif TOOLKIT == 'gtk':
img.tkraise()
drag.stack.group.tkraise()
# for closeStackMove # for closeStackMove
def _shadeStack(self): def _shadeStack(self):
@ -1547,7 +1564,11 @@ class TalonStack(Stack,
self.images.redeal = MfxCanvasImage(self.game.canvas, cx, cy, self.images.redeal = MfxCanvasImage(self.game.canvas, cx, cy,
image=img, anchor="center") image=img, anchor="center")
self.images.redeal_img = img 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.images.redeal.addtag(self.group)
self.top_bottom = self.images.redeal self.top_bottom = self.images.redeal
if images.CARDH >= 90: if images.CARDH >= 90:
@ -1563,7 +1584,11 @@ class TalonStack(Stack,
self.texts.redeal = MfxCanvasText(self.game.canvas, cx, cy, self.texts.redeal = MfxCanvasText(self.game.canvas, cx, cy,
anchor=ca, font=font) anchor=ca, font=font)
self.texts.redeal_str = "" 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.texts.redeal.addtag(self.group)
self.top_bottom = self.texts.redeal self.top_bottom = self.texts.redeal
@ -1612,6 +1637,45 @@ class RedealTalonStack(TalonStack, RedealCards_StackMethods):
RedealCards_StackMethods.redealCards(self, sound=sound) 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 # // An OpenStack is a stack where cards can be placed and dragged
# // (i.e. FoundationStack, RowStack, ReserveStack, ...) # // (i.e. FoundationStack, RowStack, ReserveStack, ...)

View file

@ -966,12 +966,12 @@ class PysolMenubar(PysolMenubarActions):
elif d.key > 0 and d.key != self.app.tabletile_index: elif d.key > 0 and d.key != self.app.tabletile_index:
self._mOptTableTile(d.key) self._mOptTableTile(d.key)
def mOptTableColor(self, *event): ## def mOptTableColor(self, *event):
if self._cancelDrag(break_pause=False): return ## if self._cancelDrag(break_pause=False): return
c = tkColorChooser.askcolor(initialcolor=self.app.opt.table_color, ## c = tkColorChooser.askcolor(initialcolor=self.app.opt.table_color,
title=_("Select table color")) ## title=_("Select table color"))
if c and c[1]: ## if c and c[1]:
self._mOptTableColor(c[1]) ## self._mOptTableColor(c[1])
def mOptToolbar(self, *event): def mOptToolbar(self, *event):
##if self._cancelDrag(break_pause=False): return ##if self._cancelDrag(break_pause=False): return

View file

@ -34,8 +34,8 @@
##---------------------------------------------------------------------------## ##---------------------------------------------------------------------------##
__all__ = ['TclError', __all__ = ['TclError',
'BooleanVar', 'MfxCheckMenuItem',
'IntVar', 'MfxRadioMenuItem',
'StringVar', 'StringVar',
'MfxRoot'] 'MfxRoot']
@ -53,8 +53,27 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
# // menubar # // menubar
# ************************************************************************/ # ************************************************************************/
BooleanVar = Tkinter.BooleanVar class MfxCheckMenuItem(Tkinter.BooleanVar):
IntVar = Tkinter.IntVar 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 StringVar = Tkinter.StringVar