mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
- new option: `save games geometry'
- 5 new games: `double russian solitaire', `zodiac', `spike', `phantom blockade', `moving left' - tkhtmlviewer: highlight visited urls git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@8 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
parent
314f1a54b6
commit
f9c7a04cc5
19 changed files with 386 additions and 139 deletions
|
@ -5,7 +5,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Sun Jun 11 00:30:03 2006\n"
|
"POT-Creation-Date: Sun Jun 11 10:16:06 2006\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"POT-Creation-Date: Sun Jun 11 00:29:57 2006\n"
|
"POT-Creation-Date: Sun Jun 11 10:16:01 2006\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -2142,7 +2142,7 @@ msgid "Show hint arrow (in Shisen-Sho games)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:341
|
#: pysollib/tk/menubar.py:341
|
||||||
msgid "&Sound"
|
msgid "&Sound..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:349
|
#: pysollib/tk/menubar.py:349
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Sun Jun 11 00:30:03 2006\n"
|
"POT-Creation-Date: Sun Jun 11 10:16:06 2006\n"
|
||||||
"PO-Revision-Date: 2006-06-10 11:07+0400\n"
|
"PO-Revision-Date: 2006-06-10 11:07+0400\n"
|
||||||
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
||||||
"Language-Team: Russian <ru@li.org>\n"
|
"Language-Team: Russian <ru@li.org>\n"
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Sun Jun 11 00:29:57 2006\n"
|
"POT-Creation-Date: Sun Jun 11 10:16:01 2006\n"
|
||||||
"PO-Revision-Date: 2006-06-11 00:32+0400\n"
|
"PO-Revision-Date: 2006-06-12 15:31+0400\n"
|
||||||
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
||||||
"Language-Team: Russian <ru@li.org>\n"
|
"Language-Team: Russian <ru@li.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
|
@ -2280,8 +2280,8 @@ msgid "Show hint arrow (in Shisen-Sho games)"
|
||||||
msgstr "Показывать стрелку (в Шисен-Сё)"
|
msgstr "Показывать стрелку (в Шисен-Сё)"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:341
|
#: pysollib/tk/menubar.py:341
|
||||||
msgid "&Sound"
|
msgid "&Sound..."
|
||||||
msgstr "&Звук"
|
msgstr "&Звук..."
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:349
|
#: pysollib/tk/menubar.py:349
|
||||||
msgid "Cards&et..."
|
msgid "Cards&et..."
|
||||||
|
@ -2289,7 +2289,7 @@ msgstr "Коло&да..."
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:350
|
#: pysollib/tk/menubar.py:350
|
||||||
msgid "Table t&ile..."
|
msgid "Table t&ile..."
|
||||||
msgstr "&Игровой стол..."
|
msgstr "Игровой &стол..."
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:352
|
#: pysollib/tk/menubar.py:352
|
||||||
msgid "Card &background"
|
msgid "Card &background"
|
||||||
|
@ -2313,7 +2313,7 @@ msgstr "&Негативные контуры карты"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:357
|
#: pysollib/tk/menubar.py:357
|
||||||
msgid "A&nimations"
|
msgid "A&nimations"
|
||||||
msgstr "&Анимация"
|
msgstr "Анимаци&я"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:358
|
#: pysollib/tk/menubar.py:358
|
||||||
msgid "&None"
|
msgid "&None"
|
||||||
|
@ -2353,11 +2353,11 @@ msgstr "Тайма&уты..."
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:369
|
#: pysollib/tk/menubar.py:369
|
||||||
msgid "&Toolbar"
|
msgid "&Toolbar"
|
||||||
msgstr "Панель &инструментов"
|
msgstr "Панель и&нструментов"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:371
|
#: pysollib/tk/menubar.py:371
|
||||||
msgid "Stat&usbar"
|
msgid "Stat&usbar"
|
||||||
msgstr "Панель состояния"
|
msgstr "Панель с&остояния"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:372
|
#: pysollib/tk/menubar.py:372
|
||||||
msgid "Show &statusbar"
|
msgid "Show &statusbar"
|
||||||
|
@ -2373,11 +2373,11 @@ msgstr "Показывать панель помощи"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:375
|
#: pysollib/tk/menubar.py:375
|
||||||
msgid "&Demo logo"
|
msgid "&Demo logo"
|
||||||
msgstr "&Демо лого"
|
msgstr "Д&емо лого"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:376
|
#: pysollib/tk/menubar.py:376
|
||||||
msgid "Startup splash sc&reen"
|
msgid "Startup splash sc&reen"
|
||||||
msgstr "Окно &запуска"
|
msgstr "О&кно запуска"
|
||||||
|
|
||||||
#: pysollib/tk/menubar.py:380
|
#: pysollib/tk/menubar.py:380
|
||||||
msgid "&Help"
|
msgid "&Help"
|
||||||
|
@ -2809,7 +2809,7 @@ msgstr "Все фоновые изображения"
|
||||||
|
|
||||||
#: pysollib/tk/selecttile.py:158
|
#: pysollib/tk/selecttile.py:158
|
||||||
msgid "&Solid color..."
|
msgid "&Solid color..."
|
||||||
msgstr "&Монотонный цвет..."
|
msgstr "М&онотонный цвет..."
|
||||||
|
|
||||||
#: pysollib/tk/soundoptionsdialog.py:111
|
#: pysollib/tk/soundoptionsdialog.py:111
|
||||||
msgid "Sound enabled"
|
msgid "Sound enabled"
|
||||||
|
@ -2837,7 +2837,7 @@ msgstr "&Применить"
|
||||||
|
|
||||||
#: pysollib/tk/soundoptionsdialog.py:169 pysollib/tk/soundoptionsdialog.py:171
|
#: pysollib/tk/soundoptionsdialog.py:169 pysollib/tk/soundoptionsdialog.py:171
|
||||||
msgid "&Mixer..."
|
msgid "&Mixer..."
|
||||||
msgstr "&Миксер..."
|
msgstr "Ми&ксер..."
|
||||||
|
|
||||||
#: pysollib/tk/soundoptionsdialog.py:220
|
#: pysollib/tk/soundoptionsdialog.py:220
|
||||||
msgid "Sound preferences info"
|
msgid "Sound preferences info"
|
||||||
|
|
|
@ -130,6 +130,7 @@ class PysolMenubarActions:
|
||||||
statusbar = BooleanVar(),
|
statusbar = BooleanVar(),
|
||||||
num_cards = BooleanVar(),
|
num_cards = BooleanVar(),
|
||||||
helpbar = BooleanVar(),
|
helpbar = BooleanVar(),
|
||||||
|
save_games_geometry = BooleanVar(),
|
||||||
splashscreen = BooleanVar(),
|
splashscreen = BooleanVar(),
|
||||||
demo_logo = BooleanVar(),
|
demo_logo = BooleanVar(),
|
||||||
sticky_mouse = BooleanVar(),
|
sticky_mouse = BooleanVar(),
|
||||||
|
@ -180,6 +181,7 @@ class PysolMenubarActions:
|
||||||
tkopt.statusbar.set(opt.statusbar)
|
tkopt.statusbar.set(opt.statusbar)
|
||||||
tkopt.num_cards.set(opt.num_cards)
|
tkopt.num_cards.set(opt.num_cards)
|
||||||
tkopt.helpbar.set(opt.helpbar)
|
tkopt.helpbar.set(opt.helpbar)
|
||||||
|
tkopt.save_games_geometry.set(opt.save_games_geometry)
|
||||||
tkopt.demo_logo.set(opt.demo_logo)
|
tkopt.demo_logo.set(opt.demo_logo)
|
||||||
tkopt.splashscreen.set(opt.splashscreen)
|
tkopt.splashscreen.set(opt.splashscreen)
|
||||||
tkopt.sticky_mouse.set(opt.sticky_mouse)
|
tkopt.sticky_mouse.set(opt.sticky_mouse)
|
||||||
|
@ -743,19 +745,19 @@ class PysolMenubarActions:
|
||||||
if self._cancelDrag(): return
|
if self._cancelDrag(): return
|
||||||
if self.app.opt.hint:
|
if self.app.opt.hint:
|
||||||
if self.game.showHint(0, self.app.opt.hint_sleep):
|
if self.game.showHint(0, self.app.opt.hint_sleep):
|
||||||
self.game.stats.hints = self.game.stats.hints + 1
|
self.game.stats.hints += 1
|
||||||
|
|
||||||
def mHint1(self, *args):
|
def mHint1(self, *args):
|
||||||
if self._cancelDrag(): return
|
if self._cancelDrag(): return
|
||||||
if self.app.opt.hint:
|
if self.app.opt.hint:
|
||||||
if self.game.showHint(1, self.app.opt.hint_sleep):
|
if self.game.showHint(1, self.app.opt.hint_sleep):
|
||||||
self.game.stats.hints = self.game.stats.hints + 1
|
self.game.stats.hints += 1
|
||||||
|
|
||||||
def mHighlightPiles(self, *args):
|
def mHighlightPiles(self, *args):
|
||||||
if self._cancelDrag(): return
|
if self._cancelDrag(): return
|
||||||
if self.app.opt.highlight_piles:
|
if self.app.opt.highlight_piles:
|
||||||
if self.game.highlightPiles(self.app.opt.highlight_piles_sleep):
|
if self.game.highlightPiles(self.app.opt.highlight_piles_sleep):
|
||||||
self.game.stats.highlight_piles = self.game.stats.highlight_piles + 1
|
self.game.stats.highlight_piles += 1
|
||||||
|
|
||||||
def mDemo(self, *args):
|
def mDemo(self, *args):
|
||||||
if self._cancelDrag(): return
|
if self._cancelDrag(): return
|
||||||
|
|
|
@ -129,14 +129,14 @@ class Options:
|
||||||
'autopilotlost' : True,
|
'autopilotlost' : True,
|
||||||
'autopilotwon' : True,
|
'autopilotwon' : True,
|
||||||
'deal' : True,
|
'deal' : True,
|
||||||
'deal01' : True,
|
#'deal01' : True,
|
||||||
'deal02' : True,
|
#'deal02' : True,
|
||||||
'deal04' : True,
|
#'deal04' : True,
|
||||||
'deal08' : True,
|
#'deal08' : True,
|
||||||
'dealwaste' : True,
|
'dealwaste' : True,
|
||||||
'droppair' : True,
|
'droppair' : True,
|
||||||
'drop' : True,
|
'drop' : True,
|
||||||
'extra' : True,
|
#'extra' : True,
|
||||||
'flip' : True,
|
'flip' : True,
|
||||||
'move' : True,
|
'move' : True,
|
||||||
'nomove' : True,
|
'nomove' : True,
|
||||||
|
@ -184,6 +184,7 @@ class Options:
|
||||||
self.highlight_cards_sleep = 1.0
|
self.highlight_cards_sleep = 1.0
|
||||||
self.highlight_samerank_sleep = 1.0
|
self.highlight_samerank_sleep = 1.0
|
||||||
# additional startup information
|
# additional startup information
|
||||||
|
self.num_recent_games = 15
|
||||||
self.recent_gameid = []
|
self.recent_gameid = []
|
||||||
self.favorite_gameid = []
|
self.favorite_gameid = []
|
||||||
self.last_gameid = 0 # last game played
|
self.last_gameid = 0 # last game played
|
||||||
|
@ -191,6 +192,8 @@ class Options:
|
||||||
#self.last_save_dir = None # last directory for load/save
|
#self.last_save_dir = None # last directory for load/save
|
||||||
self.game_holded = 0
|
self.game_holded = 0
|
||||||
self.wm_maximized = 0
|
self.wm_maximized = 0
|
||||||
|
self.save_games_geometry = False
|
||||||
|
self.games_geometry = {} # saved games geometry (gameid: (width, height))
|
||||||
#
|
#
|
||||||
self.splashscreen = True
|
self.splashscreen = True
|
||||||
self.sticky_mouse = False
|
self.sticky_mouse = False
|
||||||
|
@ -668,7 +671,13 @@ class Application:
|
||||||
self.game._saveGame(self.fn.holdgame)
|
self.game._saveGame(self.fn.holdgame)
|
||||||
self.opt.game_holded = self.game.id
|
self.opt.game_holded = self.game.id
|
||||||
except:
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
pass
|
pass
|
||||||
|
# save game geometry
|
||||||
|
self.wm_save_state()
|
||||||
|
if self.opt.save_games_geometry and not self.opt.wm_maximized:
|
||||||
|
geom = (self.canvas.winfo_width(), self.canvas.winfo_height())
|
||||||
|
self.opt.games_geometry[self.game.id] = geom
|
||||||
self.freeGame()
|
self.freeGame()
|
||||||
#
|
#
|
||||||
if self.nextgame.id <= 0:
|
if self.nextgame.id <= 0:
|
||||||
|
@ -681,35 +690,25 @@ class Application:
|
||||||
finally:
|
finally:
|
||||||
# update options
|
# update options
|
||||||
self.opt.last_gameid = id
|
self.opt.last_gameid = id
|
||||||
## if self.debug:
|
|
||||||
## self.wm_save_state()
|
|
||||||
## # save options
|
|
||||||
## self.saveOptions()
|
|
||||||
## # save statistics
|
|
||||||
## self.saveStatistics()
|
|
||||||
## # save comments
|
|
||||||
## self.saveComments()
|
|
||||||
## # shut down audio
|
|
||||||
## self.audio.destroy()
|
|
||||||
## else:
|
|
||||||
try: self.wm_save_state()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
# save options
|
# save options
|
||||||
try: self.saveOptions()
|
try: self.saveOptions()
|
||||||
except:
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
pass
|
pass
|
||||||
# save statistics
|
# save statistics
|
||||||
try: self.saveStatistics()
|
try: self.saveStatistics()
|
||||||
except:
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
pass
|
pass
|
||||||
# save comments
|
# save comments
|
||||||
try: self.saveComments()
|
try: self.saveComments()
|
||||||
except:
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
pass
|
pass
|
||||||
# shut down audio
|
# shut down audio
|
||||||
try: self.audio.destroy()
|
try: self.audio.destroy()
|
||||||
except:
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -741,7 +740,7 @@ class Application:
|
||||||
if id in self.opt.recent_gameid:
|
if id in self.opt.recent_gameid:
|
||||||
self.opt.recent_gameid.remove(id)
|
self.opt.recent_gameid.remove(id)
|
||||||
self.opt.recent_gameid.insert(0, id)
|
self.opt.recent_gameid.insert(0, id)
|
||||||
del self.opt.recent_gameid[15:]
|
del self.opt.recent_gameid[self.opt.num_recent_games:]
|
||||||
self.menubar.updateRecentGamesMenu(self.opt.recent_gameid)
|
self.menubar.updateRecentGamesMenu(self.opt.recent_gameid)
|
||||||
self.menubar.updateFavoriteGamesMenu()
|
self.menubar.updateFavoriteGamesMenu()
|
||||||
# delete intro progress bar
|
# delete intro progress bar
|
||||||
|
@ -789,7 +788,6 @@ class Application:
|
||||||
self.toolbar.connectGame(None, None)
|
self.toolbar.connectGame(None, None)
|
||||||
self.menubar.connectGame(None)
|
self.menubar.connectGame(None)
|
||||||
# clean up the canvas
|
# clean up the canvas
|
||||||
unbind_destroy(self.canvas)
|
|
||||||
self.canvas.deleteAllItems()
|
self.canvas.deleteAllItems()
|
||||||
self.canvas.update_idletasks()
|
self.canvas.update_idletasks()
|
||||||
# destruct the game
|
# destruct the game
|
||||||
|
@ -808,7 +806,7 @@ class Application:
|
||||||
if self.top:
|
if self.top:
|
||||||
s = self.top.wm_state()
|
s = self.top.wm_state()
|
||||||
##print "wm_save_state", s
|
##print "wm_save_state", s
|
||||||
if s == "zoomed":
|
if s == "zoomed": # Windows only
|
||||||
self.opt.wm_maximized = 1
|
self.opt.wm_maximized = 1
|
||||||
elif s == "normal":
|
elif s == "normal":
|
||||||
self.opt.wm_maximized = 0
|
self.opt.wm_maximized = 0
|
||||||
|
@ -842,7 +840,7 @@ class Application:
|
||||||
for f in ("demo01", "demo02", "demo03", "demo04", "demo05",):
|
for f in ("demo01", "demo02", "demo03", "demo04", "demo05",):
|
||||||
self.gimages.demo.append(self.dataloader.findImage(f, dir))
|
self.gimages.demo.append(self.dataloader.findImage(f, dir))
|
||||||
dir = os.path.join("images", "pause")
|
dir = os.path.join("images", "pause")
|
||||||
for f in ("pause01", "pause02",):
|
for f in ("pause01", "pause02", "pause03",):
|
||||||
self.gimages.pause.append(self.dataloader.findImage(f, dir))
|
self.gimages.pause.append(self.dataloader.findImage(f, dir))
|
||||||
##dir = os.path.join("images", "stats")
|
##dir = os.path.join("images", "stats")
|
||||||
##for f in ("barchart",):
|
##for f in ("barchart",):
|
||||||
|
@ -950,8 +948,7 @@ class Application:
|
||||||
self.opt.cardset[gi.category] = (cs.name, cs.backname)
|
self.opt.cardset[gi.category] = (cs.name, cs.backname)
|
||||||
if update & 8:
|
if update & 8:
|
||||||
self.opt.cardset[(1, gi.id)] = (cs.name, cs.backname)
|
self.opt.cardset[(1, gi.id)] = (cs.name, cs.backname)
|
||||||
#from pprint import pprint
|
#from pprint import pprint; pprint(self.opt.cardset)
|
||||||
#pprint(self.opt.cardset)
|
|
||||||
|
|
||||||
def loadCardset(self, cs, id=0, update=7, progress=None):
|
def loadCardset(self, cs, id=0, update=7, progress=None):
|
||||||
#print 'loadCardset', cs.ident
|
#print 'loadCardset', cs.ident
|
||||||
|
@ -1146,8 +1143,7 @@ Please select a %s type %s.
|
||||||
return
|
return
|
||||||
opt = unpickle(self.fn.opt)
|
opt = unpickle(self.fn.opt)
|
||||||
if opt:
|
if opt:
|
||||||
##import pprint
|
##import pprint; pprint.pprint(opt.__dict__)
|
||||||
##pprint.pprint(opt.__dict__)
|
|
||||||
#cardset = self.opt.cardset
|
#cardset = self.opt.cardset
|
||||||
#cardset.update(opt.cardset)
|
#cardset.update(opt.cardset)
|
||||||
self.opt.__dict__.update(opt.__dict__)
|
self.opt.__dict__.update(opt.__dict__)
|
||||||
|
|
|
@ -184,12 +184,18 @@ class Game:
|
||||||
if not self.cards:
|
if not self.cards:
|
||||||
self.cards = self.createCards(progress=self.app.intro.progress)
|
self.cards = self.createCards(progress=self.app.intro.progress)
|
||||||
self.initBindings()
|
self.initBindings()
|
||||||
self.top.bind('<ButtonPress>', self.top._sleepEvent)
|
##self.top.bind('<ButtonPress>', self.top._sleepEvent)
|
||||||
self.top.bind('<3>', self.top._sleepEvent)
|
##self.top.bind('<3>', self.top._sleepEvent)
|
||||||
##print timer
|
##print timer
|
||||||
# update display properties
|
# update display properties
|
||||||
self.top.wm_geometry("") # cancel user-specified geometry
|
self.top.wm_geometry("") # cancel user-specified geometry
|
||||||
self.canvas.setInitialSize(self.width, self.height)
|
self.canvas.setInitialSize(self.width, self.height)
|
||||||
|
# restore game geometry
|
||||||
|
if self.app.opt.save_games_geometry:
|
||||||
|
w, h = self.app.opt.games_geometry.get(self.id, (0, 0))
|
||||||
|
w, h = max(w, self.width), max(h, self.height)
|
||||||
|
self.canvas.config(width=w, height=h)
|
||||||
|
#
|
||||||
self.stats.update_time = time.time()
|
self.stats.update_time = time.time()
|
||||||
self.busy = old_busy
|
self.busy = old_busy
|
||||||
##print timer
|
##print timer
|
||||||
|
@ -784,7 +790,8 @@ class Game:
|
||||||
#
|
#
|
||||||
|
|
||||||
def playSample(self, name, priority=0, loop=0):
|
def playSample(self, name, priority=0, loop=0):
|
||||||
if not self.app.opt.sound_samples[name]:
|
if self.app.opt.sound_samples.has_key(name) and \
|
||||||
|
not self.app.opt.sound_samples[name]:
|
||||||
return 0
|
return 0
|
||||||
##print "playSample:", name, priority, loop
|
##print "playSample:", name, priority, loop
|
||||||
if self.app.audio:
|
if self.app.audio:
|
||||||
|
|
|
@ -57,3 +57,4 @@ import unionsquare
|
||||||
import wavemotion
|
import wavemotion
|
||||||
import windmill
|
import windmill
|
||||||
import yukon
|
import yukon
|
||||||
|
import zodiac
|
||||||
|
|
|
@ -187,22 +187,25 @@ class Dover_RowStack(RK_RowStack):
|
||||||
class Dover(Bristol):
|
class Dover(Bristol):
|
||||||
|
|
||||||
Talon_Class = Bristol_Talon
|
Talon_Class = Bristol_Talon
|
||||||
Foundation_Class = SS_FoundationStack
|
Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0)
|
||||||
RowStack_Class = Dover_RowStack
|
RowStack_Class = StackWrapper(Dover_RowStack, base_rank=NO_RANK, max_move=1)
|
||||||
ReserveStack_Class = StackWrapper(ReserveStack, max_accept=0, max_cards=UNLIMITED_CARDS)
|
ReserveStack_Class = StackWrapper(ReserveStack, max_accept=0, max_cards=UNLIMITED_CARDS)
|
||||||
|
|
||||||
def createGame(self, text=False):
|
def createGame(self, rows=8, text=False):
|
||||||
# create layout
|
# create layout
|
||||||
l, s = Layout(self), self.s
|
l, s = Layout(self), self.s
|
||||||
|
|
||||||
# set window
|
# set window
|
||||||
self.setSize(2*l.XM+9*l.XS, l.YM+20+5*l.YS)
|
max_rows = max(rows, self.gameinfo.decks*4)
|
||||||
|
w, h = 2*l.XM+l.XS+max_rows*l.XS, l.YM+20+5*l.YS
|
||||||
|
self.setSize(w, h)
|
||||||
|
|
||||||
# create stacks
|
# create stacks
|
||||||
x, y, = l.XM+l.XM+l.XS, l.YM
|
x, y, = 2*l.XM+l.XS+l.XS*(max_rows-self.gameinfo.decks*4), l.YM
|
||||||
for i in range(8):
|
for j in range(self.gameinfo.decks):
|
||||||
s.foundations.append(self.Foundation_Class(x, y, self, suit=i/2, max_move=0))
|
for i in range(4):
|
||||||
x += l.XS
|
s.foundations.append(self.Foundation_Class(x, y, self, suit=i))
|
||||||
|
x += l.XS
|
||||||
if text:
|
if text:
|
||||||
x, y = l.XM+8*l.XS, l.YM
|
x, y = l.XM+8*l.XS, l.YM
|
||||||
tx, ty, ta, tf = l.getTextAttr(None, "s")
|
tx, ty, ta, tf = l.getTextAttr(None, "s")
|
||||||
|
@ -210,12 +213,12 @@ class Dover(Bristol):
|
||||||
font = self.app.getFont("canvas_default")
|
font = self.app.getFont("canvas_default")
|
||||||
self.texts.info = MfxCanvasText(self.canvas, tx, ty, anchor=ta, font=font)
|
self.texts.info = MfxCanvasText(self.canvas, tx, ty, anchor=ta, font=font)
|
||||||
|
|
||||||
x, y = l.XM+l.XM, l.YM+l.YS
|
x, y = 2*l.XM+(max_rows-rows)*l.XS, l.YM+l.YS
|
||||||
if text:
|
if text:
|
||||||
y += 20
|
y += 20
|
||||||
for i in range(8):
|
for i in range(rows):
|
||||||
x += l.XS
|
x += l.XS
|
||||||
stack = self.RowStack_Class(x, y, self, base_rank=NO_RANK, max_move=1)
|
stack = self.RowStack_Class(x, y, self)
|
||||||
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, l.YOFFSET
|
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, l.YOFFSET
|
||||||
s.rows.append(stack)
|
s.rows.append(stack)
|
||||||
x, y, = l.XM, l.YM
|
x, y, = l.XM, l.YM
|
||||||
|
@ -262,9 +265,9 @@ class NewYork_RowStack(AC_RowStack):
|
||||||
|
|
||||||
class NewYork(Dover):
|
class NewYork(Dover):
|
||||||
|
|
||||||
Foundation_Class = StackWrapper(SS_FoundationStack, mod=13)
|
Foundation_Class = StackWrapper(SS_FoundationStack, mod=13, max_move=0)
|
||||||
Talon_Class = NewYork_Talon
|
Talon_Class = NewYork_Talon
|
||||||
RowStack_Class = StackWrapper(NewYork_RowStack, base_rank=ANY_RANK, mod=13)
|
RowStack_Class = StackWrapper(NewYork_RowStack, base_rank=ANY_RANK, mod=13, max_move=1)
|
||||||
ReserveStack_Class = StackWrapper(NewYork_ReserveStack, max_accept=1, max_cards=UNLIMITED_CARDS, mod=13)
|
ReserveStack_Class = StackWrapper(NewYork_ReserveStack, max_accept=1, max_cards=UNLIMITED_CARDS, mod=13)
|
||||||
|
|
||||||
def createGame(self):
|
def createGame(self):
|
||||||
|
@ -315,6 +318,30 @@ class NewYork(Dover):
|
||||||
p.dump(self.base_card.id)
|
p.dump(self.base_card.id)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Spike
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class Spike(Dover):
|
||||||
|
|
||||||
|
Foundation_Class = SS_FoundationStack
|
||||||
|
RowStack_Class = KingAC_RowStack
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
Dover.createGame(self, rows=7)
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
for i in range(1, 7):
|
||||||
|
self.s.talon.dealRow(rows=self.s.rows[i:], flip=0, frames=0)
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
|
return (card1.color != card2.color and
|
||||||
|
abs(card1.rank-card2.rank) == 1)
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(42, Bristol, "Bristol",
|
registerGame(GameInfo(42, Bristol, "Bristol",
|
||||||
GI.GT_FAN_TYPE, 1, 0))
|
GI.GT_FAN_TYPE, 1, 0))
|
||||||
|
@ -324,4 +351,6 @@ registerGame(GameInfo(266, Dover, "Dover",
|
||||||
GI.GT_FAN_TYPE, 2, 0))
|
GI.GT_FAN_TYPE, 2, 0))
|
||||||
registerGame(GameInfo(425, NewYork, "New York",
|
registerGame(GameInfo(425, NewYork, "New York",
|
||||||
GI.GT_FAN_TYPE, 2, 0))
|
GI.GT_FAN_TYPE, 2, 0))
|
||||||
|
registerGame(GameInfo(468, Spike, "Spike",
|
||||||
|
GI.GT_KLONDIKE, 1, 0))
|
||||||
|
|
||||||
|
|
|
@ -325,6 +325,8 @@ class LexingtonHarp(MilliganHarp):
|
||||||
GAME_VERSION = 2
|
GAME_VERSION = 2
|
||||||
RowStack_Class = Yukon_AC_RowStack
|
RowStack_Class = Yukon_AC_RowStack
|
||||||
Hint_Class = YukonType_Hint
|
Hint_Class = YukonType_Hint
|
||||||
|
def getHighlightPilesStacks(self):
|
||||||
|
return ()
|
||||||
|
|
||||||
|
|
||||||
class Brunswick(LexingtonHarp):
|
class Brunswick(LexingtonHarp):
|
||||||
|
@ -344,6 +346,7 @@ class Griffon(Mississippi):
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Blockade
|
# // Blockade
|
||||||
|
# // Phantom Blockade
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
class Blockade(Gypsy):
|
class Blockade(Gypsy):
|
||||||
|
@ -364,6 +367,24 @@ class Blockade(Gypsy):
|
||||||
self.s.talon.moveMove(1, stack)
|
self.s.talon.moveMove(1, stack)
|
||||||
self.leaveState(old_state)
|
self.leaveState(old_state)
|
||||||
|
|
||||||
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
|
return (card1.suit == card2.suit and
|
||||||
|
abs(card1.rank-card2.rank) == 1)
|
||||||
|
|
||||||
|
|
||||||
|
class PhantomBlockade(Gypsy):
|
||||||
|
Layout_Method = Layout.klondikeLayout
|
||||||
|
RowStack_Class = KingAC_RowStack
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
Gypsy.createGame(self, rows=13, playcards=24)
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
self.s.talon.dealRow(frames=0)
|
||||||
|
self.s.talon.dealRow(frames=0)
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Cone
|
# // Cone
|
||||||
|
@ -507,4 +528,6 @@ registerGame(GameInfo(412, Cone, "Cone",
|
||||||
GI.GT_GYPSY, 2, 0))
|
GI.GT_GYPSY, 2, 0))
|
||||||
registerGame(GameInfo(463, Surprise, "Surprise",
|
registerGame(GameInfo(463, Surprise, "Surprise",
|
||||||
GI.GT_GYPSY, 2, 0))
|
GI.GT_GYPSY, 2, 0))
|
||||||
|
registerGame(GameInfo(469, PhantomBlockade, "Phantom Blockade",
|
||||||
|
GI.GT_GYPSY, 2, 0))
|
||||||
|
|
||||||
|
|
|
@ -950,6 +950,27 @@ class SevenDevils(Klondike):
|
||||||
self.s.talon.dealRow(rows=self.s.reserves)
|
self.s.talon.dealRow(rows=self.s.reserves)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Moving Left
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class MovingLeft(Klondike):
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
Klondike.createGame(self, max_rounds=1, rows=10, playcards=24)
|
||||||
|
|
||||||
|
def fillStack(self, stack):
|
||||||
|
if not stack.cards:
|
||||||
|
old_state = self.enterState(self.S_FILL)
|
||||||
|
if stack in self.s.rows:
|
||||||
|
i = list(self.s.rows).index(stack)
|
||||||
|
if i < 9:
|
||||||
|
from_stack = self.s.rows[i+1]
|
||||||
|
pile = from_stack.getPile()
|
||||||
|
if pile:
|
||||||
|
from_stack.moveMove(len(pile), stack)
|
||||||
|
self.leaveState(old_state)
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(2, Klondike, "Klondike",
|
registerGame(GameInfo(2, Klondike, "Klondike",
|
||||||
|
@ -1042,4 +1063,6 @@ registerGame(GameInfo(452, DoubleEasthaven, "Double Easthaven",
|
||||||
GI.GT_GYPSY, 2, 0))
|
GI.GT_GYPSY, 2, 0))
|
||||||
registerGame(GameInfo(453, TripleEasthaven, "Triple Easthaven",
|
registerGame(GameInfo(453, TripleEasthaven, "Triple Easthaven",
|
||||||
GI.GT_GYPSY, 3, 0))
|
GI.GT_GYPSY, 3, 0))
|
||||||
|
registerGame(GameInfo(470, MovingLeft, "Moving Left",
|
||||||
|
GI.GT_KLONDIKE, 2, 0))
|
||||||
|
|
||||||
|
|
|
@ -640,6 +640,9 @@ class Chelicera(Game):
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
self.s.talon.dealRow(rows=self.s.rows[4:])
|
self.s.talon.dealRow(rows=self.s.rows[4:])
|
||||||
|
|
||||||
|
def getHighlightPilesStacks(self):
|
||||||
|
return ()
|
||||||
|
|
||||||
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
||||||
|
|
||||||
|
@ -793,6 +796,9 @@ class Applegate(Game):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def getHighlightPilesStacks(self):
|
||||||
|
return ()
|
||||||
|
|
||||||
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
return (card1.suit == card2.suit and
|
return (card1.suit == card2.suit and
|
||||||
((card1.rank + 1) % stack1.cap.mod == card2.rank or
|
((card1.rank + 1) % stack1.cap.mod == card2.rank or
|
||||||
|
|
|
@ -347,21 +347,31 @@ Diamond: 4 8 Q 3 7 J 2 6 T A 5 9 K'''))
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Double Yukon
|
# // Double Yukon
|
||||||
|
# // Double Russian Solitaire
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
class DoubleYukon(Yukon):
|
class DoubleYukon(Yukon):
|
||||||
def createGame(self):
|
def createGame(self):
|
||||||
Yukon.createGame(self, rows=10)
|
Yukon.createGame(self, rows=10)
|
||||||
def startGame(self):
|
def startGame(self):
|
||||||
for i in range(1, len(self.s.rows)):
|
for i in range(1, len(self.s.rows)-1):
|
||||||
self.s.talon.dealRow(rows=self.s.rows[i:], flip=0, frames=0)
|
self.s.talon.dealRow(rows=self.s.rows[i:], flip=0, frames=0)
|
||||||
|
#self.s.talon.dealRow(rows=self.s.rows, flip=0, frames=0)
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
self.s.talon.dealRow(rows=self.s.rows, flip=1, frames=0)
|
self.s.talon.dealRow(flip=1, frames=0)
|
||||||
self.startDealSample()
|
self.startDealSample()
|
||||||
self.s.talon.dealRow(rows=self.s.rows[:-1])
|
self.s.talon.dealRow()
|
||||||
assert len(self.s.talon.cards) == 0
|
assert len(self.s.talon.cards) == 0
|
||||||
|
|
||||||
|
|
||||||
|
class DoubleRussianSolitaire(DoubleYukon):
|
||||||
|
RowStack_Class = StackWrapper(Yukon_SS_RowStack, base_rank=KING)
|
||||||
|
|
||||||
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
|
return (card1.suit == card2.suit and
|
||||||
|
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Triple Yukon
|
# // Triple Yukon
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
@ -543,3 +553,5 @@ registerGame(GameInfo(450, RawPrawn, "Raw Prawn",
|
||||||
GI.GT_YUKON, 1, 0))
|
GI.GT_YUKON, 1, 0))
|
||||||
registerGame(GameInfo(456, BimBom, "Bim Bom",
|
registerGame(GameInfo(456, BimBom, "Bim Bom",
|
||||||
GI.GT_YUKON | GI.GT_ORIGINAL, 2, 0))
|
GI.GT_YUKON | GI.GT_ORIGINAL, 2, 0))
|
||||||
|
registerGame(GameInfo(466, DoubleRussianSolitaire, "Double Russian Solitaire",
|
||||||
|
GI.GT_YUKON | GI.GT_ORIGINAL, 2, 0))
|
||||||
|
|
126
pysollib/games/zodiac.py
Normal file
126
pysollib/games/zodiac.py
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
##---------------------------------------------------------------------------##
|
||||||
|
##
|
||||||
|
## 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__ = []
|
||||||
|
|
||||||
|
# imports
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# PySol imports
|
||||||
|
from pysollib.gamedb import registerGame, GameInfo, GI
|
||||||
|
from pysollib.util import *
|
||||||
|
from pysollib.mfxutil import kwdefault
|
||||||
|
from pysollib.stack import *
|
||||||
|
from pysollib.game import Game
|
||||||
|
from pysollib.layout import Layout
|
||||||
|
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Zodiac
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class Zodiac_Foundation(SS_FoundationStack):
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not SS_FoundationStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
if self.game.s.waste.cards or self.game.s.talon.cards:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class Zodiac_RowStack(UD_SS_RowStack):
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not UD_SS_RowStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
if from_stack in self.game.s.rows:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
class Zodiac_ReserveStack(ReserveStack):
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not ReserveStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
if from_stack in self.game.s.rows:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Zodiac(Game):
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
|
||||||
|
# create layout
|
||||||
|
l, s = Layout(self), self.s
|
||||||
|
|
||||||
|
# set window
|
||||||
|
w, h = l.XM+12*l.XS, l.YM+5*l.YS
|
||||||
|
self.setSize(w, h)
|
||||||
|
|
||||||
|
# create stacks
|
||||||
|
x = l.XM
|
||||||
|
for i in range(12):
|
||||||
|
for y in (l.YM, l.YM+4*l.YS):
|
||||||
|
stack = Zodiac_RowStack(x, y, self, base_rank=NO_RANK)
|
||||||
|
s.rows.append(stack)
|
||||||
|
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
x = l.XM+4*l.XS
|
||||||
|
for i in range(4):
|
||||||
|
y = l.YM+l.YS
|
||||||
|
s.foundations.append(Zodiac_Foundation(x, y, self, suit=i))
|
||||||
|
y += 2*l.YS
|
||||||
|
s.foundations.append(Zodiac_Foundation(x, y, self, suit=i,
|
||||||
|
base_rank=KING, dir=-1))
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
x, y = l.XM+2*l.XS, l.YM+2*l.YS
|
||||||
|
for i in range(8):
|
||||||
|
s.reserves.append(Zodiac_ReserveStack(x, y, self))
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
x, y = l.XM+l.XS, l.YM+l.YS
|
||||||
|
s.talon = WasteTalonStack(x, y, self,
|
||||||
|
max_rounds=UNLIMITED_REDEALS)
|
||||||
|
l.createText(s.talon, 'sw')
|
||||||
|
x += l.XS
|
||||||
|
s.waste = WasteStack(x, y, self)
|
||||||
|
l.createText(s.waste, 'se')
|
||||||
|
|
||||||
|
# define stack-groups
|
||||||
|
l.defaultStackGroups()
|
||||||
|
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow(rows=self.s.reserves)
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
|
||||||
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
|
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
||||||
|
|
||||||
|
|
||||||
|
# register the game
|
||||||
|
registerGame(GameInfo(467, Zodiac, "Zodiac",
|
||||||
|
GI.GT_2DECK_TYPE, 2, -1))
|
|
@ -338,7 +338,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
submenu.add_checkbutton(label=n_("Show removed tiles (in Mahjongg games)"), variable=self.tkopt.mahjongg_show_removed, command=self.mOptMahjonggShowRemoved)
|
submenu.add_checkbutton(label=n_("Show removed tiles (in Mahjongg games)"), variable=self.tkopt.mahjongg_show_removed, command=self.mOptMahjonggShowRemoved)
|
||||||
submenu.add_checkbutton(label=n_("Show hint arrow (in Shisen-Sho games)"), variable=self.tkopt.shisen_show_hint, command=self.mOptShisenShowHint)
|
submenu.add_checkbutton(label=n_("Show hint arrow (in Shisen-Sho games)"), variable=self.tkopt.shisen_show_hint, command=self.mOptShisenShowHint)
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
label = n_("&Sound")
|
label = n_("&Sound...")
|
||||||
if self.app.audio.audiodev is None:
|
if self.app.audio.audiodev is None:
|
||||||
menu.add_checkbutton(label=label, variable=self.tkopt.sound, command=self.mOptSoundDialog, state=Tkinter.DISABLED)
|
menu.add_checkbutton(label=label, variable=self.tkopt.sound, command=self.mOptSoundDialog, state=Tkinter.DISABLED)
|
||||||
else:
|
else:
|
||||||
|
@ -372,6 +372,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
submenu.add_checkbutton(label=n_("Show &statusbar"), variable=self.tkopt.statusbar, command=self.mOptStatusbar)
|
submenu.add_checkbutton(label=n_("Show &statusbar"), variable=self.tkopt.statusbar, command=self.mOptStatusbar)
|
||||||
submenu.add_checkbutton(label=n_("Show &number of cards"), variable=self.tkopt.num_cards, command=self.mOptNumCards)
|
submenu.add_checkbutton(label=n_("Show &number of cards"), variable=self.tkopt.num_cards, command=self.mOptNumCards)
|
||||||
submenu.add_checkbutton(label=n_("Show &help bar"), variable=self.tkopt.helpbar, command=self.mOptHelpbar)
|
submenu.add_checkbutton(label=n_("Show &help bar"), variable=self.tkopt.helpbar, command=self.mOptHelpbar)
|
||||||
|
menu.add_checkbutton(label=n_("Save games &geometry"), variable=self.tkopt.save_games_geometry, command=self.mOptSaveGamesGeometry)
|
||||||
menu.add_checkbutton(label=n_("&Demo logo"), variable=self.tkopt.demo_logo, command=self.mOptDemoLogo)
|
menu.add_checkbutton(label=n_("&Demo logo"), variable=self.tkopt.demo_logo, command=self.mOptDemoLogo)
|
||||||
menu.add_checkbutton(label=n_("Startup splash sc&reen"), variable=self.tkopt.splashscreen, command=self.mOptSplashscreen)
|
menu.add_checkbutton(label=n_("Startup splash sc&reen"), variable=self.tkopt.splashscreen, command=self.mOptSplashscreen)
|
||||||
### menu.add_separator()
|
### menu.add_separator()
|
||||||
|
@ -866,6 +867,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
self._cancelDrag()
|
self._cancelDrag()
|
||||||
self.game.endGame(bookmark=1)
|
self.game.endGame(bookmark=1)
|
||||||
self.game.quitGame(bookmark=1)
|
self.game.quitGame(bookmark=1)
|
||||||
|
self.app.opt.games_geometry = {} # clear saved games geometry
|
||||||
|
|
||||||
def _mOptCardback(self, index):
|
def _mOptCardback(self, index):
|
||||||
if self._cancelDrag(break_pause=False): return
|
if self._cancelDrag(break_pause=False): return
|
||||||
|
@ -958,7 +960,8 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if not self.app.statusbar: return
|
if not self.app.statusbar: return
|
||||||
side = self.tkopt.statusbar.get()
|
side = self.tkopt.statusbar.get()
|
||||||
self.app.opt.statusbar = side
|
self.app.opt.statusbar = side
|
||||||
if self.app.statusbar.show(side):
|
resize = not self.app.opt.save_games_geometry
|
||||||
|
if self.app.statusbar.show(side, resize=resize):
|
||||||
self.top.update_idletasks()
|
self.top.update_idletasks()
|
||||||
|
|
||||||
def mOptNumCards(self, *event):
|
def mOptNumCards(self, *event):
|
||||||
|
@ -970,9 +973,14 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if not self.app.helpbar: return
|
if not self.app.helpbar: return
|
||||||
show = self.tkopt.helpbar.get()
|
show = self.tkopt.helpbar.get()
|
||||||
self.app.opt.helpbar = show
|
self.app.opt.helpbar = show
|
||||||
if self.app.helpbar.show(show):
|
resize = not self.app.opt.save_games_geometry
|
||||||
|
if self.app.helpbar.show(show, resize=resize):
|
||||||
self.top.update_idletasks()
|
self.top.update_idletasks()
|
||||||
|
|
||||||
|
def mOptSaveGamesGeometry(self, *event):
|
||||||
|
if self._cancelDrag(break_pause=False): return
|
||||||
|
self.app.opt.save_games_geometry = self.tkopt.save_games_geometry.get()
|
||||||
|
|
||||||
def mOptDemoLogo(self, *event):
|
def mOptDemoLogo(self, *event):
|
||||||
if self._cancelDrag(break_pause=False): return
|
if self._cancelDrag(break_pause=False): return
|
||||||
self.app.opt.demo_logo = self.tkopt.demo_logo.get()
|
self.app.opt.demo_logo = self.tkopt.demo_logo.get()
|
||||||
|
@ -1002,7 +1010,8 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if self._cancelDrag(break_pause=False): return
|
if self._cancelDrag(break_pause=False): return
|
||||||
self.app.opt.toolbar = side
|
self.app.opt.toolbar = side
|
||||||
self.tkopt.toolbar.set(side) # update radiobutton
|
self.tkopt.toolbar.set(side) # update radiobutton
|
||||||
if self.app.toolbar.show(side):
|
resize = not self.app.opt.save_games_geometry
|
||||||
|
if self.app.toolbar.show(side, resize=resize):
|
||||||
self.top.update_idletasks()
|
self.top.update_idletasks()
|
||||||
|
|
||||||
def setToolbarSize(self, size):
|
def setToolbarSize(self, size):
|
||||||
|
|
|
@ -74,31 +74,33 @@ class SoundOptionsDialog(MfxDialog):
|
||||||
self.music_volume = IntVar()
|
self.music_volume = IntVar()
|
||||||
self.music_volume.set(app.opt.sound_music_volume)
|
self.music_volume.set(app.opt.sound_music_volume)
|
||||||
self.samples = [
|
self.samples = [
|
||||||
('areyousure', 'AreYouSure', BooleanVar()),
|
('areyousure', _('Are You Sure'), BooleanVar()),
|
||||||
('autodrop', 'AutoDrop', BooleanVar()),
|
|
||||||
('autoflip', 'AutoFlip', BooleanVar()),
|
('deal', _('Deal'), BooleanVar()),
|
||||||
('autopilotlost', 'AutopilotLost', BooleanVar()),
|
('dealwaste', _('Deal waste'), BooleanVar()),
|
||||||
('autopilotwon', 'AutopilotWon', BooleanVar()),
|
|
||||||
('deal', 'Deal', BooleanVar()),
|
('turnwaste', _('Turn waste'), BooleanVar()),
|
||||||
#('deal01', 'Deal01', BooleanVar()),
|
('startdrag', _('Start drag'), BooleanVar()),
|
||||||
#('deal02', 'Deal02', BooleanVar()),
|
|
||||||
#('deal04', 'Deal04', BooleanVar()),
|
('drop', _('Drop'), BooleanVar()),
|
||||||
#('deal08', 'Deal08', BooleanVar()),
|
('droppair', _('Drop pair'), BooleanVar()),
|
||||||
('dealwaste', 'DealWaste', BooleanVar()),
|
('autodrop', _('Auto drop'), BooleanVar()),
|
||||||
('droppair', 'DropPair', BooleanVar()),
|
|
||||||
('drop', 'Drop', BooleanVar()),
|
('flip', _('Flip'), BooleanVar()),
|
||||||
#('extra', 'Extra', BooleanVar()),
|
('autoflip', _('Auto flip'), BooleanVar()),
|
||||||
('flip', 'Flip', BooleanVar()),
|
('move', _('Move'), BooleanVar()),
|
||||||
('move', 'Move', BooleanVar()),
|
('nomove', _('No move'), BooleanVar()),
|
||||||
('nomove', 'NoMove', BooleanVar()),
|
|
||||||
('redo', 'Redo', BooleanVar()),
|
('undo', _('Undo'), BooleanVar()),
|
||||||
('startdrag', 'StartDrag', BooleanVar()),
|
('redo', _('Redo'), BooleanVar()),
|
||||||
('turnwaste', 'TurnWaste', BooleanVar()),
|
|
||||||
('undo', 'Undo', BooleanVar()),
|
('autopilotlost', _('Autopilot lost'), BooleanVar()),
|
||||||
('gamefinished', 'GameFinished', BooleanVar()),
|
('autopilotwon', _('Autopilot won'), BooleanVar()),
|
||||||
('gamelost', 'GameLost', BooleanVar()),
|
|
||||||
('gameperfect', 'GamePerfect', BooleanVar()),
|
('gamefinished', _('Game finished'), BooleanVar()),
|
||||||
('gamewon', 'GameWon', BooleanVar()),
|
('gamelost', _('Game lost'), BooleanVar()),
|
||||||
|
('gamewon', _('Game won'), BooleanVar()),
|
||||||
|
('gameperfect', _('Perfect game'), BooleanVar()),
|
||||||
]
|
]
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -125,15 +125,15 @@ class tkHTMLWriter(formatter.DumbWriter):
|
||||||
self.text.tag_bind(tag, "<1>", self.createCallback(url))
|
self.text.tag_bind(tag, "<1>", self.createCallback(url))
|
||||||
self.text.tag_bind(tag, "<Enter>", lambda e: self.anchor_enter(url))
|
self.text.tag_bind(tag, "<Enter>", lambda e: self.anchor_enter(url))
|
||||||
self.text.tag_bind(tag, "<Leave>", self.anchor_leave)
|
self.text.tag_bind(tag, "<Leave>", self.anchor_leave)
|
||||||
self.text.tag_config(tag, foreground="blue", underline=1)
|
fg = 'blue'
|
||||||
|
u = self.viewer.normurl(url, with_protocol=False)
|
||||||
|
if u in self.viewer.visited_urls:
|
||||||
|
fg = '#303080'
|
||||||
|
self.text.tag_config(tag, foreground=fg, underline=1)
|
||||||
self.anchor = None
|
self.anchor = None
|
||||||
|
|
||||||
def anchor_enter(self, url):
|
def anchor_enter(self, url):
|
||||||
for p in REMOTE_PROTOCOLS:
|
url = self.viewer.normurl(url)
|
||||||
if url.startswith(p):
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
url = 'file://'+self.viewer.basejoin(url)
|
|
||||||
self.viewer.statusbar.updateText(url=url)
|
self.viewer.statusbar.updateText(url=url)
|
||||||
self.text.config(cursor=self.viewer.handcursor)
|
self.text.config(cursor=self.viewer.handcursor)
|
||||||
|
|
||||||
|
@ -219,6 +219,7 @@ class tkHTMLViewer:
|
||||||
list = [],
|
list = [],
|
||||||
index = 0,
|
index = 0,
|
||||||
)
|
)
|
||||||
|
self.visited_urls = []
|
||||||
self.images = {} # need to keep a reference because of garbage collection
|
self.images = {} # need to keep a reference because of garbage collection
|
||||||
self.defcursor = parent["cursor"]
|
self.defcursor = parent["cursor"]
|
||||||
##self.defcursor = 'xterm'
|
##self.defcursor = 'xterm'
|
||||||
|
@ -247,7 +248,8 @@ class tkHTMLViewer:
|
||||||
text_frame = Tkinter.Frame(parent)
|
text_frame = Tkinter.Frame(parent)
|
||||||
text_frame.grid(row=1, column=0, columnspan=4, sticky='nsew')
|
text_frame.grid(row=1, column=0, columnspan=4, sticky='nsew')
|
||||||
self.text = Tkinter.Text(text_frame,
|
self.text = Tkinter.Text(text_frame,
|
||||||
fg='black', bg='white', bd=0,
|
fg='black', bg='white',
|
||||||
|
bd=1, relief='sunken',
|
||||||
cursor=self.defcursor,
|
cursor=self.defcursor,
|
||||||
wrap='word', padx=20, pady=20)
|
wrap='word', padx=20, pady=20)
|
||||||
self.text.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH, expand=1)
|
self.text.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH, expand=1)
|
||||||
|
@ -287,24 +289,22 @@ class tkHTMLViewer:
|
||||||
except: pass
|
except: pass
|
||||||
self.parent = None
|
self.parent = None
|
||||||
|
|
||||||
|
def _yview(self, *args):
|
||||||
|
apply(self.text.yview, args, {})
|
||||||
|
return 'break'
|
||||||
|
|
||||||
def page_up(self, *event):
|
def page_up(self, *event):
|
||||||
self.text.yview_scroll(-1, "page")
|
return self._yview('scroll', -1, 'page')
|
||||||
return "break"
|
|
||||||
def page_down(self, *event):
|
def page_down(self, *event):
|
||||||
self.text.yview_scroll(1, "page")
|
return self._yview('scroll', 1, 'page')
|
||||||
return "break"
|
|
||||||
def unit_up(self, *event):
|
def unit_up(self, *event):
|
||||||
self.text.yview_scroll(-1, "unit")
|
return self._yview('scroll', -1, 'unit')
|
||||||
return "break"
|
|
||||||
def unit_down(self, *event):
|
def unit_down(self, *event):
|
||||||
self.text.yview_scroll(1, "unit")
|
return self._yview('scroll', 1, 'unit')
|
||||||
return "break"
|
|
||||||
def scroll_top(self, *event):
|
def scroll_top(self, *event):
|
||||||
self.text.yview_moveto(0)
|
return self._yview('moveto', 0)
|
||||||
return "break"
|
|
||||||
def scroll_bottom(self, *event):
|
def scroll_bottom(self, *event):
|
||||||
self.text.yview_moveto(1)
|
return self._yview('moveto', 1)
|
||||||
return "break"
|
|
||||||
|
|
||||||
# locate a file relative to the current self.url
|
# locate a file relative to the current self.url
|
||||||
def basejoin(self, url, baseurl=None, relpath=1):
|
def basejoin(self, url, baseurl=None, relpath=1):
|
||||||
|
@ -325,6 +325,18 @@ class tkHTMLViewer:
|
||||||
url = os.path.normpath(url)
|
url = os.path.normpath(url)
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
def normurl(self, url, with_protocol=True):
|
||||||
|
for p in REMOTE_PROTOCOLS:
|
||||||
|
if url.startswith(p):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
url = self.basejoin(url)
|
||||||
|
if with_protocol:
|
||||||
|
if os.name == 'nt':
|
||||||
|
url = url.replace('\\', '/')
|
||||||
|
url = 'file://'+url
|
||||||
|
return url
|
||||||
|
|
||||||
def openfile(self, url):
|
def openfile(self, url):
|
||||||
if url[-1:] == "/" or os.path.isdir(url):
|
if url[-1:] == "/" or os.path.isdir(url):
|
||||||
url = os.path.join(url, "index.html")
|
url = os.path.join(url, "index.html")
|
||||||
|
@ -338,6 +350,7 @@ class tkHTMLViewer:
|
||||||
if self.app and self.app.game:
|
if self.app and self.app.game:
|
||||||
self.app.game.stopDemo()
|
self.app.game.stopDemo()
|
||||||
##self.app.game._cancelDrag()
|
##self.app.game._cancelDrag()
|
||||||
|
##pass
|
||||||
|
|
||||||
# ftp: and http: would work if we use urllib, but this widget is
|
# ftp: and http: would work if we use urllib, but this widget is
|
||||||
# far too limited to display anything but our documentation...
|
# far too limited to display anything but our documentation...
|
||||||
|
@ -418,6 +431,8 @@ to open the following URL:
|
||||||
##self.frame.config(cursor=self.defcursor)
|
##self.frame.config(cursor=self.defcursor)
|
||||||
|
|
||||||
def addHistory(self, url, xview=0, yview=0):
|
def addHistory(self, url, xview=0, yview=0):
|
||||||
|
if not url in self.visited_urls:
|
||||||
|
self.visited_urls.append(url)
|
||||||
if self.history.index > 0:
|
if self.history.index > 0:
|
||||||
u, xv, yv = self.history.list[self.history.index-1]
|
u, xv, yv = self.history.list[self.history.index-1]
|
||||||
if cmp(u, url) == 0:
|
if cmp(u, url) == 0:
|
||||||
|
|
|
@ -38,7 +38,7 @@ import os, string, types
|
||||||
import Tkinter
|
import Tkinter
|
||||||
|
|
||||||
# Toolkit imports
|
# Toolkit imports
|
||||||
from tkutil import bind, unbind_destroy
|
from tkutil import bind
|
||||||
from tkwidget import MfxScrolledCanvas
|
from tkwidget import MfxScrolledCanvas
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,6 +244,7 @@ class MfxTreeInCanvas(MfxScrolledCanvas):
|
||||||
|
|
||||||
def __init__(self, parent, rootnodes, **kw):
|
def __init__(self, parent, rootnodes, **kw):
|
||||||
bg = kw["bg"] = kw.get("bg") or parent.cget("bg")
|
bg = kw["bg"] = kw.get("bg") or parent.cget("bg")
|
||||||
|
kw['bd'] = 0
|
||||||
apply(MfxScrolledCanvas.__init__, (self, parent,), kw)
|
apply(MfxScrolledCanvas.__init__, (self, parent,), kw)
|
||||||
#
|
#
|
||||||
self.rootnodes = rootnodes
|
self.rootnodes = rootnodes
|
||||||
|
|
|
@ -420,7 +420,7 @@ class MfxTooltip:
|
||||||
class MfxScrolledCanvas:
|
class MfxScrolledCanvas:
|
||||||
def __init__(self, parent, hbar=2, vbar=2, **kw):
|
def __init__(self, parent, hbar=2, vbar=2, **kw):
|
||||||
bg = kw.get("bg", parent.cget("bg"))
|
bg = kw.get("bg", parent.cget("bg"))
|
||||||
kwdefault(kw, bg=bg, highlightthickness=0)
|
kwdefault(kw, bg=bg, highlightthickness=0, bd=1, relief='sunken')
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.createFrame(kw)
|
self.createFrame(kw)
|
||||||
self.canvas = None
|
self.canvas = None
|
||||||
|
@ -629,41 +629,36 @@ class MfxScrolledCanvas:
|
||||||
self.vbar_show = show
|
self.vbar_show = show
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def _xview(self, *args):
|
||||||
|
if self.hbar_show: apply(self.canvas.xview, args, {})
|
||||||
|
return 'break'
|
||||||
|
def _yview(self, *args):
|
||||||
|
if self.vbar_show: apply(self.canvas.yview, args, {})
|
||||||
|
return 'break'
|
||||||
|
|
||||||
def page_up(self, *event):
|
def page_up(self, *event):
|
||||||
self.canvas.yview_scroll(-1, "page")
|
return self._yview('scroll', -1, 'page')
|
||||||
return "break"
|
|
||||||
def page_down(self, *event):
|
def page_down(self, *event):
|
||||||
self.canvas.yview_scroll(1, "page")
|
return self._yview('scroll', 1, 'page')
|
||||||
return "break"
|
|
||||||
def unit_up(self, *event):
|
def unit_up(self, *event):
|
||||||
self.canvas.yview_scroll(-1, "unit")
|
return self._yview('scroll', -1, 'unit')
|
||||||
return "break"
|
|
||||||
def unit_down(self, *event):
|
def unit_down(self, *event):
|
||||||
self.canvas.yview_scroll(1, "unit")
|
return self._yview('scroll', 1, 'unit')
|
||||||
return "break"
|
|
||||||
def mouse_wheel_up(self, *event):
|
def mouse_wheel_up(self, *event):
|
||||||
self.canvas.yview_scroll(-5, "unit")
|
return self._yview('scroll', -5, 'unit')
|
||||||
return "break"
|
|
||||||
def mouse_wheel_down(self, *event):
|
def mouse_wheel_down(self, *event):
|
||||||
self.canvas.yview_scroll(5, "unit")
|
return self._yview('scroll', 5, 'unit')
|
||||||
return "break"
|
|
||||||
def page_left(self, *event):
|
def page_left(self, *event):
|
||||||
self.canvas.xview_scroll(-1, "page")
|
return self._xview('scroll', -1, 'page')
|
||||||
return "break"
|
|
||||||
def page_right(self, *event):
|
def page_right(self, *event):
|
||||||
self.canvas.xview_scroll(1, "page")
|
return self._xview('scroll', 1, 'page')
|
||||||
return "break"
|
|
||||||
def unit_left(self, *event):
|
def unit_left(self, *event):
|
||||||
self.canvas.xview_scroll(-1, "unit")
|
return self._xview('scroll', -1, 'unit')
|
||||||
return "break"
|
|
||||||
def unit_right(self, *event):
|
def unit_right(self, *event):
|
||||||
self.canvas.xview_scroll(1, "unit")
|
return self._xview('scroll', 1, 'unit')
|
||||||
return "break"
|
|
||||||
def scroll_top(self, *event):
|
def scroll_top(self, *event):
|
||||||
self.canvas.yview_moveto(0)
|
return self._yview('moveto', 0)
|
||||||
return "break"
|
|
||||||
def scroll_bottom(self, *event):
|
def scroll_bottom(self, *event):
|
||||||
self.canvas.yview_moveto(1)
|
return self._yview('moveto', 1)
|
||||||
return "break"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue