mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
* improved support GTK (alpha)
git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@50 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
parent
06c287d6f1
commit
7478cfa2c7
14 changed files with 894 additions and 118 deletions
|
@ -6,7 +6,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PySol 0.0.1\n"
|
||||
"POT-Creation-Date: Fri Aug 11 02:15:03 2006\n"
|
||||
"PO-Revision-Date: 2006-08-09 23:52+0400\n"
|
||||
"PO-Revision-Date: 2006-08-17 20:14+0400\n"
|
||||
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -2729,7 +2729,7 @@ msgid "Pyramid 2"
|
|||
msgstr "Пирамида 2"
|
||||
|
||||
msgid "Pyramid Golf"
|
||||
msgstr "Пирамидальный Голф"
|
||||
msgstr "Пирамидальный Гольф"
|
||||
|
||||
msgid "Q.C."
|
||||
msgstr ""
|
||||
|
|
|
@ -46,8 +46,7 @@ from mfxutil import format_time
|
|||
from util import get_version_tuple, Timer
|
||||
from util import ACE, QUEEN, KING
|
||||
from version import VERSION, VERSION_TUPLE
|
||||
from settings import PACKAGE
|
||||
from settings import TOP_TITLE
|
||||
from settings import PACKAGE, TOOLKIT, TOP_TITLE
|
||||
from gamedb import GI
|
||||
from resource import CSI
|
||||
from pysolrandom import PysolRandom, LCRandom31
|
||||
|
@ -518,10 +517,15 @@ class Game:
|
|||
self.busy = old_busy
|
||||
|
||||
def resetGame(self):
|
||||
##print '--- resetGame ---'
|
||||
self.hints.list = None
|
||||
self.s.talon.removeAllCards()
|
||||
for stack in self.allstacks:
|
||||
##print stack
|
||||
stack.resetGame()
|
||||
if TOOLKIT == 'gtk':
|
||||
# FIXME (pyramid like games)
|
||||
stack.group.tkraise()
|
||||
if self.preview <= 1:
|
||||
for t in (self.texts.score, self.texts.base_rank,):
|
||||
if t:
|
||||
|
|
|
@ -39,6 +39,7 @@ from gtk import gdk
|
|||
# PySol imports
|
||||
from pysollib.gamedb import GI
|
||||
from pysollib.actions import PysolMenubarActions
|
||||
from pysollib.settings import PACKAGE
|
||||
|
||||
# toolkit imports
|
||||
from tkutil import setTransient
|
||||
|
@ -47,6 +48,14 @@ from selectcardset import SelectCardsetDialogWithPreview
|
|||
from selectcardset import SelectCardsetByTypeDialogWithPreview
|
||||
from selecttile import SelectTileDialogWithPreview
|
||||
|
||||
from selectgame import SelectGameDialogWithPreview
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
def ltk2gtk(s):
|
||||
return gettext(s).replace('&', '_')
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // - create menubar
|
||||
|
@ -78,71 +87,74 @@ class PysolMenubar(PysolMenubarActions):
|
|||
def createMenubar(self):
|
||||
|
||||
entries = (
|
||||
('new', gtk.STOCK_NEW, '_New', 'N', 'New game', self.mNewGame),
|
||||
('open', gtk.STOCK_OPEN, '_Open', '<control>O', 'Open a\nsaved game', self.mOpen),
|
||||
('restart', gtk.STOCK_REFRESH, '_Restart', '<control>G', 'Restart the\ncurrent game', self.mRestart),
|
||||
('save', gtk.STOCK_SAVE, '_Save', '<control>S', 'Save game', self.mSave),
|
||||
('undo', gtk.STOCK_UNDO, 'Undo', 'Z', 'Undo', self.mUndo),
|
||||
('redo', gtk.STOCK_REDO, 'Redo', 'R', 'Redo', self.mRedo),
|
||||
('autodrop',gtk.STOCK_JUMP_TO, '_Auto drop', 'A', 'Auto drop', self.mDrop),
|
||||
('stats', gtk.STOCK_HOME, 'Stats', None, 'Statistics', self.mStatus),
|
||||
('rules', gtk.STOCK_HELP, 'Rules', 'F1', 'Rules', self.mHelpRules),
|
||||
('quit', gtk.STOCK_QUIT, 'Quit', '<control>Q', 'Quit PySol', self.mQuit),
|
||||
('newgame', gtk.STOCK_NEW, ltk2gtk('&New game'), 'N', ltk2gtk('New game'), self.mNewGame),
|
||||
('open', gtk.STOCK_OPEN, ltk2gtk('&Open...'), '<control>O', ltk2gtk('Open a\nsaved game'), self.mOpen),
|
||||
('restart', gtk.STOCK_REFRESH, ltk2gtk('&Restart'), '<control>G', ltk2gtk('Restart the\ncurrent game'), self.mRestart),
|
||||
('save', gtk.STOCK_SAVE, ltk2gtk('&Save'), '<control>S', ltk2gtk('Save game'), self.mSave),
|
||||
('undo', gtk.STOCK_UNDO, ltk2gtk('&Undo'), 'Z', ltk2gtk('Undo'), self.mUndo),
|
||||
('redo', gtk.STOCK_REDO, ltk2gtk('&Redo'), 'R', ltk2gtk('Redo'), self.mRedo),
|
||||
('autodrop',gtk.STOCK_JUMP_TO, ltk2gtk('&Auto drop'), 'A', ltk2gtk('Auto drop'), self.mDrop),
|
||||
('stats', gtk.STOCK_HOME, ltk2gtk('Stats'), None, ltk2gtk('Statistics'), self.mStatus),
|
||||
('rules', gtk.STOCK_HELP, ltk2gtk('Rules'), 'F1', ltk2gtk('Rules'), self.mHelpRules),
|
||||
('quit', gtk.STOCK_QUIT, ltk2gtk('&Quit'), '<control>Q', ltk2gtk('Quit PySol'), self.mQuit),
|
||||
|
||||
('file', None, '_File' ),
|
||||
('selectgame', None, 'Select _game'),
|
||||
('edit', None, '_Edit'),
|
||||
('game', None, '_Game'),
|
||||
('assist', None, '_Assist'),
|
||||
('options', None, '_Options'),
|
||||
("automaticplay", None, "_Automatic play"),
|
||||
('file', None, ltk2gtk('&File')),
|
||||
('selectgame', None, ltk2gtk('Select &game')),
|
||||
('edit', None, ltk2gtk('&Edit')),
|
||||
('game', None, ltk2gtk('&Game')),
|
||||
('assist', None, ltk2gtk('&Assist')),
|
||||
('options', None, ltk2gtk('&Options')),
|
||||
("automaticplay", None, ltk2gtk("&Automatic play")),
|
||||
|
||||
('animations', None, '_Animations'),
|
||||
('help', None, '_Help'),
|
||||
('animations', None, ltk2gtk('A&nimations')),
|
||||
('help', None, ltk2gtk('&Help')),
|
||||
|
||||
('selectgamebynumber', None, 'Select game by number...', None, None, self.mSelectGameById),
|
||||
('saveas', None, 'Save _as...', None, None, self.m),
|
||||
('redoall', None, 'Redo _all', None, None, self.mRedoAll),
|
||||
('dealcards', None, '_Deal cards', 'D', None, self.mDeal),
|
||||
('status', None, 'S_tatus...', 'T', None, self.mStatus),
|
||||
('hint', None, '_Hint', 'H', None, self.mHint),
|
||||
('highlightpiles', None, 'Highlight _piles', None, None, self.mHighlightPiles),
|
||||
('demo', None,'_Demo', '<control>D',None,self.mDemo),
|
||||
('demoallgames', None,'Demo (all games)', None,None,self.mMixedDemo),
|
||||
('playeroptions',None,'_Player options...',None,None,self.mOptPlayerOptions),
|
||||
('tabletile', None,'Table t_ile...', None,None,self.mOptTableTile),
|
||||
('contents', None,'_Contents','<control>F1',None,self.mHelp),
|
||||
('aboutpysol', None,'_About PySol...', None,None,self.mHelpAbout),
|
||||
('playablepreview', None, ltk2gtk('Playable pre&view...'), 'V', None, self.mSelectGameDialogWithPreview),
|
||||
('selectgamebynumber', None, ltk2gtk('Select game by nu&mber...'), None, None, self.mSelectGameById),
|
||||
('saveas', None, ltk2gtk('Save &as...'), None, None, self.m),
|
||||
('redoall', None, ltk2gtk('Redo &all'), None, None, self.mRedoAll),
|
||||
('dealcards', None, ltk2gtk('&Deal cards'), 'D', None, self.mDeal),
|
||||
('status', None, ltk2gtk('S&tatus...'), 'T', None, self.mStatus),
|
||||
('hint', None, ltk2gtk('&Hint'), 'H', None, self.mHint),
|
||||
('highlightpiles', None, ltk2gtk('Highlight p&iles'), None, None, self.mHighlightPiles),
|
||||
('demo', None,ltk2gtk('&Demo'), '<control>D',None,self.mDemo),
|
||||
('demoallgames', None,ltk2gtk('Demo (&all games)'), None,None,self.mMixedDemo),
|
||||
('playeroptions',None,ltk2gtk('&Player options...'),None,None,self.mOptPlayerOptions),
|
||||
('tabletile', None,ltk2gtk('Table t&ile...'), None,None,self.mOptTableTile),
|
||||
('contents', None,ltk2gtk('&Contents'),'<control>F1',None,self.mHelp),
|
||||
('aboutpysol', None,ltk2gtk('&About ')+PACKAGE+'...', None,None,self.mHelpAbout),
|
||||
)
|
||||
|
||||
#
|
||||
toggle_entries = (
|
||||
('pause', gtk.STOCK_STOP, '_Pause', 'P', 'Pause game', self.mPause),
|
||||
('optautodrop', None, 'A_uto drop', None, None, self.mOptAutoDrop),
|
||||
('autofaceup', None, 'Auto _face up', None, None, self.mOptAutoFaceUp),
|
||||
("autodeal", None, "Auto _deal", None, None, self.mOptAutoDeal),
|
||||
("quickplay", None, '_Quick play', None, None, self.mOptQuickPlay),
|
||||
('pause', gtk.STOCK_STOP, ltk2gtk('&Pause'), 'P', ltk2gtk('Pause game'), self.mPause),
|
||||
('optautodrop', None, ltk2gtk('A&uto drop'), None, None, self.mOptAutoDrop),
|
||||
('autofaceup', None, ltk2gtk('Auto &face up'), None, None, self.mOptAutoFaceUp),
|
||||
("autodeal", None, ltk2gtk("Auto &deal"), None, None, self.mOptAutoDeal),
|
||||
("quickplay", None, ltk2gtk('&Quick play'), None, None, self.mOptQuickPlay),
|
||||
|
||||
('highlightmatchingcards', None, 'Highlight _matching cards', None, None, self.mOptEnableHighlightCards),
|
||||
('cardshadow', None, 'Card shadow', None, None, self.mOptShadow),
|
||||
('shadelegalmoves', None, 'Shade legal moves', None, None, self.mOptShade),
|
||||
('highlightmatchingcards', None, ltk2gtk('Highlight &matching cards'), None, None, self.mOptEnableHighlightCards),
|
||||
('cardshadow', None, ltk2gtk('Card shado&w'), None, None, self.mOptShadow),
|
||||
('shadelegalmoves', None, ltk2gtk('Shade &legal moves'), None, None, self.mOptShade),
|
||||
|
||||
)
|
||||
|
||||
#
|
||||
animations_entries = (
|
||||
('animationnone', None, '_None', None, None, 0),
|
||||
('animationfast', None, '_Fast', None, None, 1),
|
||||
('animationtimer', None, '_Timer based', None, None, 2),
|
||||
('animationslow', None, '_Slow', None, None, 3),
|
||||
('animationveryslow', None, '_Very slow', None, None, 4),
|
||||
('animationnone', None, ltk2gtk('&None'), None, None, 0),
|
||||
('animationfast', None, ltk2gtk('&Fast'), None, None, 1),
|
||||
('animationtimer', None, ltk2gtk('&Timer based'), None, None, 2),
|
||||
('animationslow', None, ltk2gtk('&Slow'), None, None, 3),
|
||||
('animationveryslow', None, ltk2gtk('&Very slow'), None, None, 4),
|
||||
)
|
||||
#
|
||||
ui_info = '''<ui>
|
||||
<menubar name='menubar'>
|
||||
|
||||
<menu action='file'>
|
||||
<menuitem action='newgame'/>
|
||||
<menuitem action='selectgamebynumber'/>
|
||||
<menuitem action='playablepreview'/>
|
||||
<menu action='selectgame'/>
|
||||
<separator/>
|
||||
<menuitem action='open'/>
|
||||
|
@ -179,7 +191,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
<menuitem action='playeroptions'/>
|
||||
<menu action='automaticplay'>
|
||||
<menuitem action='autofaceup'/>
|
||||
<menuitem action='autodrop'/>
|
||||
<menuitem action='optautodrop'/>
|
||||
<menuitem action='autodeal'/>
|
||||
<separator/>
|
||||
<menuitem action='quickplay'/>
|
||||
|
@ -245,6 +257,7 @@ class PysolMenubar(PysolMenubarActions):
|
|||
def _addSelectGameSubMenu(self, games, menu, command, group):
|
||||
for g in games:
|
||||
label = g.name
|
||||
label = gettext(label)
|
||||
menu_item = gtk.RadioMenuItem(group, label)
|
||||
group = menu_item
|
||||
menu.add(menu_item)
|
||||
|
@ -262,7 +275,9 @@ class PysolMenubar(PysolMenubarActions):
|
|||
if not games[n:n+d]:
|
||||
break
|
||||
m = min(n+d-1, len(games)-1)
|
||||
label = games[n].name[:3]+' - '+games[m].name[:3]
|
||||
n1, n2 = games[n].name, games[m].name
|
||||
n1, n2 = gettext(n1), gettext(n2)
|
||||
label = n1[:3]+' - '+n2[:3]
|
||||
submenu = self._createSubMenu(menu, label=label)
|
||||
group = self._addSelectGameSubMenu(games[n:n+d], submenu,
|
||||
command, group)
|
||||
|
@ -276,7 +291,10 @@ class PysolMenubar(PysolMenubarActions):
|
|||
## WARNING: setMenuState: not found: /menubar/file/holdandquit
|
||||
## WARNING: setMenuState: not found: /menubar/assist/findcard
|
||||
def setMenuState(self, state, path):
|
||||
path_map = {'help.rulesforthisgame': '/menubar/help/rules',}
|
||||
path_map = {
|
||||
'help.rulesforthisgame': '/menubar/help/rules',
|
||||
'options.automaticplay.autodrop': '/menubar/options/automaticplay/optautodrop'
|
||||
}
|
||||
if path_map.has_key(path):
|
||||
path = path_map[path]
|
||||
else:
|
||||
|
@ -302,11 +320,80 @@ class PysolMenubar(PysolMenubarActions):
|
|||
# menu actions
|
||||
#
|
||||
|
||||
def _createFileChooser(self, title, action, idir, ifile):
|
||||
d = gtk.FileChooserDialog(title, self.top, action,
|
||||
(gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT,
|
||||
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
|
||||
|
||||
d.set_current_folder(idir)
|
||||
if ifile:
|
||||
d.set_current_name(ifile)
|
||||
|
||||
filter = gtk.FileFilter()
|
||||
filter.set_name('PySol files')
|
||||
filter.add_pattern('*.pso')
|
||||
d.add_filter(filter)
|
||||
|
||||
filter = gtk.FileFilter()
|
||||
filter.set_name('All files')
|
||||
filter.add_pattern('*')
|
||||
d.add_filter(filter)
|
||||
|
||||
resp = d.run()
|
||||
if resp == gtk.RESPONSE_ACCEPT:
|
||||
filename = d.get_filename()
|
||||
else:
|
||||
filename = None
|
||||
d.destroy()
|
||||
return filename
|
||||
|
||||
|
||||
def mOpen(self, *args):
|
||||
pass
|
||||
if self._cancelDrag(break_pause=False): return
|
||||
filename = self.game.filename
|
||||
if filename:
|
||||
idir, ifile = os.path.split(os.path.normpath(filename))
|
||||
else:
|
||||
idir, ifile = "", ""
|
||||
if not idir:
|
||||
idir = self.app.dn.savegames
|
||||
filename = self._createFileChooser(_('Open Game'),
|
||||
gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
idir, '')
|
||||
if filename:
|
||||
##filename = os.path.normpath(filename)
|
||||
##filename = os.path.normcase(filename)
|
||||
if os.path.isfile(filename):
|
||||
self.game.loadGame(filename)
|
||||
|
||||
|
||||
def mSaveAs(self, *event):
|
||||
pass
|
||||
if self._cancelDrag(break_pause=False): return
|
||||
if not self.menustate.save_as:
|
||||
return
|
||||
filename = self.game.filename
|
||||
if not filename:
|
||||
filename = self.app.getGameSaveName(self.game.id)
|
||||
if os.name == "posix":
|
||||
filename = filename + "-" + self.game.getGameNumber(format=0)
|
||||
elif os.path.supports_unicode_filenames: # new in python 2.3
|
||||
filename = filename + "-" + self.game.getGameNumber(format=0)
|
||||
else:
|
||||
filename = filename + "-01"
|
||||
filename = filename + '.pso'
|
||||
idir, ifile = os.path.split(os.path.normpath(filename))
|
||||
if not idir:
|
||||
idir = self.app.dn.savegames
|
||||
##print self.game.filename, ifile
|
||||
filename = self._createFileChooser(_('Save Game'),
|
||||
gtk.FILE_CHOOSER_ACTION_SAVE,
|
||||
idir, ifile)
|
||||
if filename:
|
||||
##filename = os.path.normpath(filename)
|
||||
##filename = os.path.normcase(filename)
|
||||
self.game.saveGame(filename)
|
||||
self.updateMenus()
|
||||
|
||||
|
||||
def mOptCardset(self, *args):
|
||||
pass
|
||||
|
@ -353,3 +440,32 @@ class PysolMenubar(PysolMenubarActions):
|
|||
tile.color = color
|
||||
self.app.setTile(0)
|
||||
|
||||
|
||||
def mSelectGameDialogWithPreview(self, *event):
|
||||
if self._cancelDrag(break_pause=False): return
|
||||
## self.game.setCursor(cursor=CURSOR_WATCH)
|
||||
bookmark = None
|
||||
## if 0:
|
||||
## # use a bookmark for our preview game
|
||||
## if self.game.setBookmark(-2, confirm=0):
|
||||
## bookmark = self.game.gsaveinfo.bookmarks[-2][0]
|
||||
## del self.game.gsaveinfo.bookmarks[-2]
|
||||
##~ after_idle(self.top, self.__restoreCursor)
|
||||
d = SelectGameDialogWithPreview(self.top, title=_("Select game"),
|
||||
app=self.app, gameid=self.game.id,
|
||||
bookmark=bookmark)
|
||||
return self._mSelectGameDialog(d)
|
||||
|
||||
def _mSelectGameDialog(self, d):
|
||||
if d.status == 0 and d.button == 0 and d.gameid != self.game.id:
|
||||
##~ self.tkopt.gameid.set(d.gameid)
|
||||
##~ self.tkopt.gameid_popular.set(d.gameid)
|
||||
if 0:
|
||||
self._mSelectGame(d.gameid, random=d.random)
|
||||
else:
|
||||
# don't ask areYouSure()
|
||||
self._cancelDrag()
|
||||
self.game.endGame()
|
||||
self.game.quitGame(d.gameid, random=d.random)
|
||||
|
||||
|
||||
|
|
|
@ -93,7 +93,6 @@ class PlayerOptionsDialog(MfxDialog):
|
|||
strings=(_('&OK'), _('&Cancel'),),
|
||||
default=0,
|
||||
#resizable=1,
|
||||
#font=None,
|
||||
padx=10, pady=10,
|
||||
#width=600, height=400,
|
||||
##~ buttonpadx=10, buttonpady=5,
|
||||
|
|
|
@ -35,7 +35,6 @@ import os, sys
|
|||
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
TRUE, FALSE = True, False
|
||||
|
||||
# Toolkit imports
|
||||
from tkutil import makeToplevel, setTransient
|
||||
|
@ -55,8 +54,7 @@ class PysolProgressBar:
|
|||
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.set_resizable(False)
|
||||
self.top.connect("delete_event", self.wmDeleteWindow)
|
||||
|
||||
# hbox
|
||||
|
@ -67,21 +65,22 @@ class PysolProgressBar:
|
|||
0, 1, 0, 1,
|
||||
0, 0,
|
||||
0, 0)
|
||||
|
||||
# hbox-1: image
|
||||
if images and images[0]:
|
||||
im = gtk.Image()
|
||||
im.set_from_pixbuf(images[0].pixbuf)
|
||||
hbox.pack_start(im, expand=False, fill=False)
|
||||
im.show()
|
||||
im.set_property('xpad', 10)
|
||||
im.set_property('ypad', 5)
|
||||
# hbox-2:vbox
|
||||
vbox = gtk.VBox()
|
||||
vbox.show()
|
||||
hbox.pack_start(vbox, FALSE, FALSE)
|
||||
hbox.pack_start(vbox, False, False)
|
||||
# hbox-2:vbox:pbar
|
||||
self.pbar = gtk.ProgressBar()
|
||||
self.pbar.show()
|
||||
vbox.pack_start(self.pbar, TRUE, FALSE)
|
||||
vbox.pack_start(self.pbar, True, False)
|
||||
self.pbar.realize()
|
||||
##~ self.pbar.set_show_text(show_text)
|
||||
self.pbar.set_text(str(show_text)+'%')
|
||||
|
@ -99,6 +98,8 @@ class PysolProgressBar:
|
|||
im.set_from_pixbuf(images[1].pixbuf)
|
||||
hbox.pack_end(im, expand=False)
|
||||
im.show()
|
||||
im.set_property('xpad', 10)
|
||||
im.set_property('ypad', 5)
|
||||
# set icon
|
||||
if app:
|
||||
try:
|
||||
|
@ -130,15 +131,17 @@ class PysolProgressBar:
|
|||
percent = min(100, max(0, percent))
|
||||
self.pbar.set_fraction(percent / 100.0)
|
||||
self.pbar.set_text(str(percent)+'%')
|
||||
##~ self.pbar.update(self.percent / 100.0)
|
||||
self.update_idletasks()
|
||||
|
||||
def reset(self, percent=0):
|
||||
self.percent = percent
|
||||
|
||||
def update_idletasks(self):
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
|
||||
def wmDeleteWindow(self, *args):
|
||||
return TRUE
|
||||
return True
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -160,9 +163,9 @@ class TestProgressBar:
|
|||
if self.progress.percent >= 100:
|
||||
self.progress.destroy()
|
||||
mainquit()
|
||||
return FALSE
|
||||
return False
|
||||
self.progress.update(step=1)
|
||||
return TRUE
|
||||
return True
|
||||
|
||||
def progressbar_main(args):
|
||||
root = gtk.Window()
|
||||
|
|
605
pysollib/pysolgtk/selectgame.py
Normal file
605
pysollib/pysolgtk/selectgame.py
Normal file
|
@ -0,0 +1,605 @@
|
|||
## 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, re, sys, types
|
||||
import gtk, gobject
|
||||
|
||||
#from UserList import UserList
|
||||
|
||||
# PySol imports
|
||||
from pysollib.mfxutil import destruct, Struct, KwStruct
|
||||
from pysollib.mfxutil import kwdefault
|
||||
from pysollib.mfxutil import format_time
|
||||
from pysollib.gamedb import GI
|
||||
from pysollib.help import helpHTML
|
||||
from pysollib.resource import CSI
|
||||
|
||||
# Toolkit imports
|
||||
from tkutil import unbind_destroy
|
||||
from tkwidget import MfxDialog
|
||||
from tkcanvas import MfxCanvas, MfxCanvasText
|
||||
|
||||
gettext = _
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Dialog
|
||||
# ************************************************************************/
|
||||
|
||||
class SelectGameDialogWithPreview(MfxDialog):
|
||||
#Tree_Class = SelectGameTreeWithPreview
|
||||
game_store = None
|
||||
#
|
||||
_paned_position = 300
|
||||
_expanded_rows = []
|
||||
_geometry = None
|
||||
_selected_row = None
|
||||
_vadjustment_position = None
|
||||
|
||||
def __init__(self, parent, title, app, gameid, bookmark=None, **kw):
|
||||
kw = self.initKw(kw)
|
||||
MfxDialog.__init__(self, parent, title, **kw)
|
||||
#
|
||||
self.app = app
|
||||
self.gameid = gameid
|
||||
self.bookmark = bookmark
|
||||
self.random = None
|
||||
#
|
||||
if self.game_store is None:
|
||||
self.createGameStore()
|
||||
#
|
||||
top_box, bottom_box = self.createHBox()
|
||||
# paned
|
||||
hpaned = gtk.HPaned()
|
||||
self.hpaned = hpaned
|
||||
hpaned.show()
|
||||
top_box.pack_start(hpaned, expand=True, fill=True)
|
||||
# left
|
||||
sw = gtk.ScrolledWindow()
|
||||
sw.show()
|
||||
self.sw_vadjustment = sw.get_vadjustment()
|
||||
hpaned.pack1(sw, True, True)
|
||||
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
# tree
|
||||
treeview = gtk.TreeView(self.game_store)
|
||||
self.treeview = treeview
|
||||
treeview.show()
|
||||
sw.add(treeview)
|
||||
treeview.set_rules_hint(True)
|
||||
treeview.set_headers_visible(False)
|
||||
renderer = gtk.CellRendererText()
|
||||
renderer.set_property('xalign', 0.0)
|
||||
column = gtk.TreeViewColumn('Games', renderer, text=0)
|
||||
column.set_clickable(True)
|
||||
treeview.append_column(column)
|
||||
selection = treeview.get_selection()
|
||||
selection.connect('changed', self.showSelected)
|
||||
# right
|
||||
table = gtk.Table(2, 2, False)
|
||||
table.show()
|
||||
hpaned.pack2(table, True, True)
|
||||
# frames
|
||||
frame = gtk.Frame(label=_('About game'))
|
||||
frame.show()
|
||||
table.attach(frame,
|
||||
0, 1, 0, 1,
|
||||
gtk.FILL, gtk.FILL,
|
||||
0, 0)
|
||||
frame.set_border_width(4)
|
||||
info_frame = gtk.Table(2, 7, False)
|
||||
info_frame.show()
|
||||
frame.add(info_frame)
|
||||
info_frame.set_border_width(4)
|
||||
#
|
||||
frame = gtk.Frame(label=_('Statistics'))
|
||||
frame.show()
|
||||
table.attach(frame,
|
||||
1, 2, 0, 1,
|
||||
gtk.FILL, gtk.FILL,
|
||||
0, 0)
|
||||
frame.set_border_width(4)
|
||||
stats_frame = gtk.Table(2, 6, False)
|
||||
stats_frame.show()
|
||||
frame.add(stats_frame)
|
||||
stats_frame.set_border_width(4)
|
||||
# info
|
||||
self.info_labels = {}
|
||||
i = 0
|
||||
for n, t, f, row in (
|
||||
('name', _('Name:'), info_frame, 0),
|
||||
('altnames', _('Alternate names:'), info_frame, 1),
|
||||
('category', _('Category:'), info_frame, 2),
|
||||
('type', _('Type:'), info_frame, 3),
|
||||
('skill_level', _('Skill level:'), info_frame, 4),
|
||||
('decks', _('Decks:'), info_frame, 5),
|
||||
('redeals', _('Redeals:'), info_frame, 6),
|
||||
#
|
||||
('played', _('Played:'), stats_frame, 0),
|
||||
('won', _('Won:'), stats_frame, 1),
|
||||
('lost', _('Lost:'), stats_frame, 2),
|
||||
('time', _('Playing time:'), stats_frame, 3),
|
||||
('moves', _('Moves:'), stats_frame, 4),
|
||||
('percent', _('% won:'), stats_frame, 5),
|
||||
):
|
||||
title_label = gtk.Label()
|
||||
title_label.show()
|
||||
title_label.set_text(t)
|
||||
title_label.set_alignment(0., 0.)
|
||||
title_label.set_property('xpad', 2)
|
||||
title_label.set_property('ypad', 2)
|
||||
f.attach(title_label,
|
||||
0, 1, row, row+1,
|
||||
gtk.FILL, 0,
|
||||
0, 0)
|
||||
text_label = gtk.Label()
|
||||
text_label.show()
|
||||
text_label.set_alignment(0., 0.)
|
||||
text_label.set_property('xpad', 2)
|
||||
text_label.set_property('ypad', 2)
|
||||
f.attach(text_label,
|
||||
1, 2, row, row+1,
|
||||
gtk.FILL, 0,
|
||||
0, 0)
|
||||
self.info_labels[n] = (title_label, text_label)
|
||||
# canvas
|
||||
self.preview = MfxCanvas(self)
|
||||
self.preview.show()
|
||||
table.attach(self.preview,
|
||||
0, 2, 1, 2,
|
||||
gtk.EXPAND|gtk.FILL|gtk.SHRINK, gtk.EXPAND|gtk.FILL|gtk.SHRINK,
|
||||
0, 0)
|
||||
self.preview.set_border_width(4)
|
||||
self.preview.setTile(app, app.tabletile_index, force=True)
|
||||
|
||||
# set the scale factor
|
||||
self.preview.preview = 2
|
||||
# create a preview of the current game
|
||||
self.preview_key = -1
|
||||
self.preview_game = None
|
||||
self.preview_app = None
|
||||
##~ self.updatePreview(gameid, animations=0)
|
||||
##~ SelectGameTreeWithPreview.html_viewer = None
|
||||
|
||||
self.connect('unrealize', self._unrealizeEvent)
|
||||
|
||||
self.createButtons(bottom_box, kw)
|
||||
self._restoreSettings()
|
||||
self.show_all()
|
||||
gtk.main()
|
||||
|
||||
|
||||
def _addGamesFromData(self, data, store, root_iter, root_label, all_games):
|
||||
gl = []
|
||||
for label, selecter in data:
|
||||
games = self._selectGames(all_games, selecter)
|
||||
if games:
|
||||
gl.append((label, games))
|
||||
if not gl:
|
||||
return
|
||||
iter = store.append(root_iter)
|
||||
store.set(iter, 0, root_label, 1, -1)
|
||||
for label, games in gl:
|
||||
label = gettext(label)
|
||||
label = label.replace("&", "")
|
||||
self._addGames(store, iter, label, games)
|
||||
|
||||
|
||||
def _addGames(self, store, root_iter, root_label, games):
|
||||
if not games:
|
||||
return
|
||||
iter = store.append(root_iter)
|
||||
store.set(iter, 0, root_label, 1, -1)
|
||||
for id, name in games:
|
||||
child_iter = store.append(iter)
|
||||
name = gettext(name)
|
||||
store.set(child_iter, 0, name, 1, id)
|
||||
|
||||
#def _addNode(self, store, root_iter, root_label, games):
|
||||
|
||||
|
||||
def _selectGames(self, all_games, selecter):
|
||||
# return list of tuples (gameid, gamename)
|
||||
if selecter is None:
|
||||
return [(gi.id, gi.name) for gi in all_games]
|
||||
elif selecter == 'alt':
|
||||
return all_games
|
||||
return [(gi.id, gi.name) for gi in all_games if selecter(gi)]
|
||||
|
||||
|
||||
def createGameStore(self):
|
||||
store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_INT)
|
||||
app = self.app
|
||||
gdb = app.gdb
|
||||
|
||||
all_games = map(gdb.get, gdb.getGamesIdSortedByName())
|
||||
#
|
||||
alter_games = gdb.getGamesTuplesSortedByAlternateName()
|
||||
for label, games, selecter in (
|
||||
(_('All Games'), all_games, None),
|
||||
(_('Alternate Names'), alter_games, 'alt'),
|
||||
(_('Popular Games'), all_games, lambda gi: gi.si.game_flags & GI.GT_POPULAR),
|
||||
):
|
||||
games = self._selectGames(games, selecter)
|
||||
self._addGames(store, None, label, games)
|
||||
|
||||
# by type
|
||||
games = self._selectGames(all_games,
|
||||
lambda gi: gi.si.game_type == GI.GT_MAHJONGG)
|
||||
self._addGames(store, None, _("Mahjongg Games"), games)
|
||||
self._addGamesFromData(GI.SELECT_ORIENTAL_GAME_BY_TYPE, store,
|
||||
None, _("Oriental Games"), all_games)
|
||||
self._addGamesFromData(GI.SELECT_SPECIAL_GAME_BY_TYPE, store,
|
||||
None, _("Special Games"), all_games)
|
||||
self._addGamesFromData(GI.SELECT_GAME_BY_TYPE, store,
|
||||
None, _("French games"), all_games)
|
||||
# by skill level
|
||||
data = (
|
||||
(_('Luck only'), lambda gi: gi.skill_level == GI.SL_LUCK),
|
||||
(_('Mostly luck'), lambda gi: gi.skill_level == GI.SL_MOSTLY_LUCK),
|
||||
(_('Balanced'), lambda gi: gi.skill_level == GI.SL_BALANCED),
|
||||
(_('Mostly skill'), lambda gi: gi.skill_level == GI.SL_MOSTLY_SKILL),
|
||||
(_('Skill only'), lambda gi: gi.skill_level == GI.SL_SKILL),
|
||||
)
|
||||
self._addGamesFromData(data, store, None,
|
||||
_("by Skill Level"), all_games)
|
||||
|
||||
# by game feature
|
||||
root_iter = store.append(None)
|
||||
store.set(root_iter, 0, _('by Game Feature'), 1, -1)
|
||||
data = (
|
||||
(_("32 cards"), lambda gi: gi.si.ncards == 32),
|
||||
(_("48 cards"), lambda gi: gi.si.ncards == 48),
|
||||
(_("52 cards"), lambda gi: gi.si.ncards == 52),
|
||||
(_("64 cards"), lambda gi: gi.si.ncards == 64),
|
||||
(_("78 cards"), lambda gi: gi.si.ncards == 78),
|
||||
(_("104 cards"), lambda gi: gi.si.ncards == 104),
|
||||
(_("144 cards"), lambda gi: gi.si.ncards == 144),
|
||||
(_("Other number"), lambda gi: gi.si.ncards not in (32, 48, 52, 64, 78, 104, 144)),)
|
||||
self._addGamesFromData(data, store, root_iter,
|
||||
_("by Number of Cards"), all_games)
|
||||
data = (
|
||||
(_("1 deck games"), lambda gi: gi.si.decks == 1),
|
||||
(_("2 deck games"), lambda gi: gi.si.decks == 2),
|
||||
(_("3 deck games"), lambda gi: gi.si.decks == 3),
|
||||
(_("4 deck games"), lambda gi: gi.si.decks == 4),)
|
||||
self._addGamesFromData(data, store, root_iter,
|
||||
_("by Number of Decks"), all_games)
|
||||
data = (
|
||||
(_("No redeal"), lambda gi: gi.si.redeals == 0),
|
||||
(_("1 redeal"), lambda gi: gi.si.redeals == 1),
|
||||
(_("2 redeals"), lambda gi: gi.si.redeals == 2),
|
||||
(_("3 redeals"), lambda gi: gi.si.redeals == 3),
|
||||
(_("Unlimited redeals"), lambda gi: gi.si.redeals == -1),
|
||||
##(_("Variable redeals"), lambda gi: gi.si.redeals == -2),
|
||||
(_("Other number of redeals"), lambda gi: gi.si.redeals not in (-1, 0, 1, 2, 3)),)
|
||||
self._addGamesFromData(data, store, root_iter,
|
||||
_("by Number of Redeals"), all_games)
|
||||
|
||||
data = []
|
||||
for label, vg in GI.GAMES_BY_COMPATIBILITY:
|
||||
selecter = lambda gi, vg=vg: gi.id in vg
|
||||
label = gettext(label)
|
||||
data.append((label, selecter))
|
||||
self._addGamesFromData(data, store, root_iter,
|
||||
_("by Compatibility"), all_games)
|
||||
|
||||
# by PySol version
|
||||
data = []
|
||||
for version, vg in GI.GAMES_BY_PYSOL_VERSION:
|
||||
selecter = lambda gi, vg=vg: gi.id in vg
|
||||
label = _("New games in v. ") + version
|
||||
data.append((label, selecter))
|
||||
self._addGamesFromData(data, store, None,
|
||||
_("by PySol version"), all_games)
|
||||
|
||||
#
|
||||
data = (
|
||||
(_("Games for Children (very easy)"), lambda gi: gi.si.game_flags & GI.GT_CHILDREN),
|
||||
(_("Games with Scoring"), lambda gi: gi.si.game_flags & GI.GT_SCORE),
|
||||
(_("Games with Separate Decks"), lambda gi: gi.si.game_flags & GI.GT_SEPARATE_DECKS),
|
||||
(_("Open Games (all cards visible)"), lambda gi: gi.si.game_flags & GI.GT_OPEN),
|
||||
(_("Relaxed Variants"), lambda gi: gi.si.game_flags & GI.GT_RELAXED),)
|
||||
self._addGamesFromData(data, store, None,
|
||||
_("Other Categories"), all_games)
|
||||
|
||||
#
|
||||
self._addGamesFromData(GI.SELECT_ORIGINAL_GAME_BY_TYPE, store,
|
||||
None, _("Original Games"), all_games)
|
||||
##self._addGamesFromData(GI.SELECT_CONTRIB_GAME_BY_TYPE, store,
|
||||
## None, _("Contrib Game"), all_games)
|
||||
|
||||
SelectGameDialogWithPreview.game_store = store
|
||||
return
|
||||
|
||||
|
||||
def initKw(self, kw):
|
||||
kwdefault(kw,
|
||||
strings=(_("&Select"), _("&Rules"), _("&Cancel"),),
|
||||
default=0,
|
||||
##padx=10, pady=10,
|
||||
width=600, height=400,
|
||||
##~ buttonpadx=10, buttonpady=5,
|
||||
)
|
||||
return MfxDialog.initKw(self, kw)
|
||||
|
||||
|
||||
def _unrealizeEvent(self, w):
|
||||
self.deletePreview(destroy=1)
|
||||
#self.preview.unbind_all()
|
||||
self._saveSettings()
|
||||
|
||||
|
||||
def _saveSettings(self):
|
||||
SelectGameDialogWithPreview._geometry = self.get_size()
|
||||
self._saveExpandedRows()
|
||||
SelectGameDialogWithPreview._paned_position = self.hpaned.get_position()
|
||||
selection = self.treeview.get_selection()
|
||||
model, path = selection.get_selected_rows()
|
||||
if path:
|
||||
print 'save selected:', path
|
||||
SelectGameDialogWithPreview._selected_row = path[0]
|
||||
SelectGameDialogWithPreview._vadjustment_position = self.sw_vadjustment.get_value()
|
||||
|
||||
|
||||
def _restoreSettings(self):
|
||||
if self._geometry:
|
||||
self.resize(self._geometry[0], self._geometry[1])
|
||||
self._loadExpandedRows()
|
||||
self.hpaned.set_position(self._paned_position)
|
||||
if self._selected_row:
|
||||
selection = self.treeview.get_selection()
|
||||
##selection.select_path(self._selected_row)
|
||||
##selection.unselect_all()
|
||||
gtk.idle_add(selection.select_path, self._selected_row)
|
||||
if self._vadjustment_position is not None:
|
||||
##self.sw_vadjustment.set_value(self._vadjustment_position)
|
||||
gtk.idle_add(self.sw_vadjustment.set_value,
|
||||
self._vadjustment_position)
|
||||
|
||||
|
||||
def _getSelected(self):
|
||||
selection = self.treeview.get_selection()
|
||||
model, path = selection.get_selected_rows()
|
||||
if not path:
|
||||
return None
|
||||
iter = model.get_iter(path[0])
|
||||
index = model.get_value(iter, 1)
|
||||
if index < 0:
|
||||
return None
|
||||
return index
|
||||
|
||||
|
||||
def showSelected(self, w):
|
||||
id = self._getSelected()
|
||||
if id:
|
||||
self.updatePreview(id)
|
||||
##self.updateInfo(id)
|
||||
|
||||
|
||||
def deletePreview(self, destroy=0):
|
||||
self.preview_key = -1
|
||||
# clean up the canvas
|
||||
if self.preview:
|
||||
unbind_destroy(self.preview)
|
||||
self.preview.deleteAllItems()
|
||||
##~ if destroy:
|
||||
##~ self.preview.delete("all")
|
||||
#
|
||||
#for l in self.info_labels.values():
|
||||
# l.config(text='')
|
||||
# destruct the game
|
||||
if self.preview_game:
|
||||
self.preview_game.endGame()
|
||||
self.preview_game.destruct()
|
||||
destruct(self.preview_game)
|
||||
self.preview_game = None
|
||||
# destruct the app
|
||||
if destroy:
|
||||
if self.preview_app:
|
||||
destruct(self.preview_app)
|
||||
self.preview_app = None
|
||||
|
||||
def updatePreview(self, gameid, animations=5):
|
||||
if gameid == self.preview_key:
|
||||
return
|
||||
self.deletePreview()
|
||||
canvas = self.preview
|
||||
#
|
||||
gi = self.app.gdb.get(gameid)
|
||||
if not gi:
|
||||
self.preview_key = -1
|
||||
return
|
||||
#
|
||||
if self.preview_app is None:
|
||||
self.preview_app = Struct(
|
||||
# variables
|
||||
audio = self.app.audio,
|
||||
canvas = canvas,
|
||||
cardset = self.app.cardset.copy(),
|
||||
comments = self.app.comments.new(),
|
||||
debug = 0,
|
||||
gamerandom = self.app.gamerandom,
|
||||
gdb = self.app.gdb,
|
||||
gimages = self.app.gimages,
|
||||
images = self.app.subsampled_images,
|
||||
menubar = None,
|
||||
miscrandom = self.app.miscrandom,
|
||||
opt = self.app.opt.copy(),
|
||||
startup_opt = self.app.startup_opt,
|
||||
stats = self.app.stats.new(),
|
||||
top = None,
|
||||
top_cursor = self.app.top_cursor,
|
||||
toolbar = None,
|
||||
# methods
|
||||
constructGame = self.app.constructGame,
|
||||
getFont = self.app.getFont,
|
||||
)
|
||||
self.preview_app.opt.shadow = 0
|
||||
self.preview_app.opt.shade = 0
|
||||
#
|
||||
self.preview_app.audio = None # turn off audio for intial dealing
|
||||
if animations >= 0:
|
||||
self.preview_app.opt.animations = animations
|
||||
#
|
||||
if self.preview_game:
|
||||
self.preview_game.endGame()
|
||||
self.preview_game.destruct()
|
||||
##self.top.wm_title("Select Game - " + self.app.getGameTitleName(gameid))
|
||||
title = self.app.getGameTitleName(gameid)
|
||||
self.set_title(_("Playable Preview - ") + title)
|
||||
#
|
||||
self.preview_game = gi.gameclass(gi)
|
||||
self.preview_game.createPreview(self.preview_app)
|
||||
tx, ty = 0, 0
|
||||
gw, gh = self.preview_game.width, self.preview_game.height
|
||||
##~ canvas.config(scrollregion=(-tx, -ty, -tx, -ty))
|
||||
##~ canvas.xview_moveto(0)
|
||||
##~ canvas.yview_moveto(0)
|
||||
#
|
||||
random = None
|
||||
if gameid == self.gameid:
|
||||
random = self.app.game.random.copy()
|
||||
if gameid == self.gameid and self.bookmark:
|
||||
self.preview_game.restoreGameFromBookmark(self.bookmark)
|
||||
else:
|
||||
self.preview_game.newGame(random=random, autoplay=1)
|
||||
##~ canvas.config(scrollregion=(-tx, -ty, gw, gh))
|
||||
#
|
||||
self.preview_app.audio = self.app.audio
|
||||
if self.app.opt.animations:
|
||||
self.preview_app.opt.animations = 5
|
||||
else:
|
||||
self.preview_app.opt.animations = 0
|
||||
# save seed
|
||||
self.random = self.preview_game.random.copy()
|
||||
self.random.origin = self.random.ORIGIN_PREVIEW
|
||||
self.preview_key = gameid
|
||||
#
|
||||
self.updateInfo(gameid)
|
||||
#
|
||||
rules_button = self.buttons[1]
|
||||
if self.app.getGameRulesFilename(gameid):
|
||||
rules_button.set_sensitive(True)
|
||||
else:
|
||||
rules_button.set_sensitive(False)
|
||||
|
||||
def updateInfo(self, gameid):
|
||||
gi = self.app.gdb.get(gameid)
|
||||
# info
|
||||
name = gettext(gi.name)
|
||||
altnames = '\n'.join([gettext(n) for n in gi.altnames])
|
||||
category = gettext(CSI.TYPE[gi.category])
|
||||
type = ''
|
||||
if GI.TYPE_NAMES.has_key(gi.si.game_type):
|
||||
type = gettext(GI.TYPE_NAMES[gi.si.game_type])
|
||||
sl = {
|
||||
GI.SL_LUCK: _('Luck only'),
|
||||
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
||||
GI.SL_BALANCED: _('Balanced'),
|
||||
GI.SL_MOSTLY_SKILL: _('Mostly skill'),
|
||||
GI.SL_SKILL: _('Skill only'),
|
||||
}
|
||||
skill_level = sl.get(gi.skill_level)
|
||||
if gi.redeals == -2: redeals = _('variable')
|
||||
elif gi.redeals == -1: redeals = _('unlimited')
|
||||
else: redeals = str(gi.redeals)
|
||||
# stats
|
||||
won, lost, time, moves = self.app.stats.getFullStats(self.app.opt.player, gameid)
|
||||
if won+lost > 0: percent = "%.1f" % (100.0*won/(won+lost))
|
||||
else: percent = "0.0"
|
||||
time = format_time(time)
|
||||
moves = str(round(moves, 1))
|
||||
for n, t in (
|
||||
('name', name),
|
||||
('altnames', altnames),
|
||||
('category', category),
|
||||
('type', type),
|
||||
('skill_level', skill_level),
|
||||
('decks', gi.decks),
|
||||
('redeals', redeals),
|
||||
('played', won+lost),
|
||||
('won', won),
|
||||
('lost', lost),
|
||||
('time', time),
|
||||
('moves', moves),
|
||||
('percent', percent),
|
||||
):
|
||||
title_label, text_label = self.info_labels[n]
|
||||
if t == '':
|
||||
title_label.hide()
|
||||
text_label.hide()
|
||||
else:
|
||||
title_label.show()
|
||||
text_label.show()
|
||||
text_label.set_text(str(t))
|
||||
#self.info_labels[n].config(text=t)
|
||||
|
||||
def _saveExpandedRows(self):
|
||||
treeview = self.treeview
|
||||
SelectGameDialogWithPreview._expanded_rows = []
|
||||
treeview.map_expanded_rows(
|
||||
lambda tv, path, self=self:
|
||||
SelectGameDialogWithPreview._expanded_rows.append(path))
|
||||
print self._expanded_rows
|
||||
|
||||
def _loadExpandedRows(self):
|
||||
for path in self._expanded_rows:
|
||||
self.treeview.expand_to_path(path)
|
||||
|
||||
def done(self, button):
|
||||
button = button.get_data("user_data")
|
||||
print 'done', button
|
||||
if button == 0: # Ok or double click
|
||||
id = self._getSelected()
|
||||
if id:
|
||||
self.gameid = id
|
||||
##~ self.tree.n_expansions = 1 # save xyview in any case
|
||||
if button == 1: # Rules
|
||||
id = self._getSelected()
|
||||
if id:
|
||||
doc = self.app.getGameRulesFilename(id)
|
||||
if not doc:
|
||||
return
|
||||
dir = os.path.join("html", "rules")
|
||||
helpHTML(self.app, doc, dir, self)
|
||||
return
|
||||
|
||||
self.status = 0
|
||||
self.button = button
|
||||
self.quit()
|
||||
|
||||
|
|
@ -184,7 +184,6 @@ class SelectTileDialogWithPreview(MfxDialog):
|
|||
strings=(_('&OK'), _('&Solid color...'), _('&Cancel'),),
|
||||
default=0,
|
||||
resizable=1,
|
||||
font=None,
|
||||
padx=10, pady=10,
|
||||
width=600, height=400,
|
||||
##~ buttonpadx=10, buttonpady=5,
|
||||
|
|
|
@ -50,21 +50,25 @@ class BasicStatusbar:
|
|||
column, column+columnspan, row, row+1,
|
||||
gtk.EXPAND | gtk.FILL, 0,
|
||||
0, 0)
|
||||
self.createLabel('space', width=2)
|
||||
|
||||
|
||||
def createLabel(self, name, fill=False, expand=False, grip=False, width=0):
|
||||
def createLabel(self, name, fill=False, expand=False,
|
||||
tooltip=None, grip=False, width=0):
|
||||
label = gtk.Statusbar()
|
||||
self.hbox.pack_start(label, fill=fill, expand=expand)
|
||||
label.show()
|
||||
if not grip:
|
||||
label.set_has_resize_grip(False)
|
||||
setattr(self, name + "_label", label)
|
||||
label.set_size_request(width*8, -1)
|
||||
##lb = label.get_children()[0].get_children()[0]
|
||||
##lb.set_justify(gtk.JUSTIFY_CENTER)
|
||||
label.set_size_request(width*7, -1)
|
||||
lb = label.get_children()[0].get_children()[0]
|
||||
lb.set_alignment(0.5, 0.0)
|
||||
self._widgets.append(label)
|
||||
##label.push(0, '')
|
||||
## if tooltip:
|
||||
## tt = gtk.Tooltips()
|
||||
## tt.set_tip(label, tooltip, '')
|
||||
## tt.enable()
|
||||
|
||||
|
||||
def updateText(self, **kw):
|
||||
|
@ -75,8 +79,11 @@ class BasicStatusbar:
|
|||
|
||||
|
||||
def configLabel(self, name, **kw):
|
||||
print 'statusbar.configLabel', kw
|
||||
pass
|
||||
label = getattr(self, name + "_label")
|
||||
# FIXME kw['fg']
|
||||
label.pop(0)
|
||||
label.push(0, unicode(kw['text']))
|
||||
|
||||
|
||||
def show(self, show=True, resize=False):
|
||||
if show:
|
||||
|
@ -107,7 +114,7 @@ class PysolStatusbar(BasicStatusbar):
|
|||
("gamenumber", _("Game number"), 26),
|
||||
("stats", _("Games played: won/lost"), 12),
|
||||
):
|
||||
self.createLabel(n, width=w)
|
||||
self.createLabel(n, width=w, tooltip=t)
|
||||
#
|
||||
l = self.createLabel("info", fill=True, expand=True, grip=True)
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ TRUE, FALSE = True, False
|
|||
# toolkit imports
|
||||
from tkutil import anchor_tk2gtk, loadImage, bind
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // canvas items
|
||||
# //
|
||||
|
@ -75,17 +76,19 @@ class _CanvasItem:
|
|||
def __init__(self, canvas):
|
||||
self.canvas = canvas
|
||||
canvas._all_items.append(self)
|
||||
self._group = None
|
||||
|
||||
def addtag(self, group):
|
||||
##print self, 'addtag'
|
||||
##~ assert isinstance(group._item, CanvasGroup)
|
||||
self._item.reparent(group._item)
|
||||
self._group = group
|
||||
|
||||
def dtag(self, group):
|
||||
pass
|
||||
##print self, 'dtag'
|
||||
##~ assert isinstance(group._item, CanvasGroup)
|
||||
##self._item.reparent(self.canvas.root())
|
||||
self._group = None
|
||||
|
||||
def bind(self, sequence, func, add=None):
|
||||
bind(self._item, sequence, func, add)
|
||||
|
@ -100,23 +103,33 @@ class _CanvasItem:
|
|||
self._item = None
|
||||
|
||||
def lower(self, positions=None):
|
||||
##print "lower", self._item, positions
|
||||
print "lower", self._item, positions
|
||||
if positions is None:
|
||||
self._item.lower_to_bottom()
|
||||
if self._group:
|
||||
self._group._item.lower_to_bottom()
|
||||
##self._item.lower_to_bottom()
|
||||
else:
|
||||
self._item.lower_to_bottom()
|
||||
else:
|
||||
print self, 'lower', positions
|
||||
##~ assert type(positions) is types.IntType and positions > 0
|
||||
##~ self._item.lower(positions)
|
||||
pass
|
||||
self._item.lower(positions)
|
||||
|
||||
def tkraise(self, positions=None):
|
||||
##print "tkraise", self._item, positions
|
||||
##print "tkraise", self._group, self._item.get_property('parent') #self._item, positions
|
||||
if positions is None:
|
||||
self._item.raise_to_top()
|
||||
self._item.get_property('parent').raise_to_top()
|
||||
## if self._group:
|
||||
## self._group._item.raise_to_top()
|
||||
## ##self._item.raise_to_top()
|
||||
## else:
|
||||
## self._item.raise_to_top()
|
||||
else:
|
||||
print 'tkraise', positions
|
||||
print self, 'tkraise', positions
|
||||
##~ assert type(positions) is types.IntType and positions > 0
|
||||
##~ self._item.raise_(positions)
|
||||
self._item.raise_to_top()
|
||||
pass
|
||||
|
||||
def move(self, x, y):
|
||||
self._item.move(x, y)
|
||||
|
@ -141,7 +154,6 @@ class MfxCanvasGroup(_CanvasItem):
|
|||
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)
|
||||
|
@ -188,10 +200,10 @@ class MfxCanvasLine(_CanvasItem):
|
|||
class MfxCanvasRectangle(_CanvasItem):
|
||||
def __init__(self, canvas, x1, y1, x2, y2, width, fill, outline):
|
||||
_CanvasItem.__init__(self, canvas)
|
||||
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)
|
||||
kw = {'x1': x1, 'x2': x2, 'y1': y1, 'y2': y2, 'width_pixels': width}
|
||||
if fill: kw['fill_color'] = fill
|
||||
if outline: kw['outline_color'] = outline
|
||||
self._item = canvas.root().add(gnome.canvas.CanvasRect, **kw)
|
||||
|
||||
|
||||
class MfxCanvasText(_CanvasItem):
|
||||
|
@ -200,6 +212,7 @@ class MfxCanvasText(_CanvasItem):
|
|||
if preview < 0:
|
||||
preview = canvas.preview
|
||||
if preview > 1:
|
||||
self._item = None
|
||||
return
|
||||
anchor = anchor_tk2gtk(anchor)
|
||||
self._item = canvas.root().add(gnome.canvas.CanvasText,
|
||||
|
@ -240,7 +253,6 @@ class MfxCanvasText(_CanvasItem):
|
|||
|
||||
class MfxCanvas(gnome.canvas.Canvas):
|
||||
def __init__(self, top, bg=None, highlightthickness=0):
|
||||
print 'MfxCanvas', bg
|
||||
self.preview = 0
|
||||
# Tkinter compat
|
||||
self.items = {}
|
||||
|
@ -263,12 +275,12 @@ class MfxCanvas(gnome.canvas.Canvas):
|
|||
self.set_style(style)
|
||||
self.top_bg = top.style.bg[gtk.STATE_NORMAL]
|
||||
|
||||
|
||||
##
|
||||
self.top = top
|
||||
self.xmargin, self.ymargin = 0, 0
|
||||
|
||||
self.connect('size-allocate', self._sizeAllocate)
|
||||
self.connect('destroy', self.destroyEvent)
|
||||
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
|
@ -294,9 +306,27 @@ class MfxCanvas(gnome.canvas.Canvas):
|
|||
# FIXME
|
||||
return gdk.LEFT_PTR
|
||||
return self.get_window().get_cursor(v)
|
||||
elif attr == 'width':
|
||||
return self.get_size()[0]
|
||||
elif attr == 'height':
|
||||
return self.get_size()[1]
|
||||
print "TkCanvas cget:", attr
|
||||
raise AttributeError, attr
|
||||
|
||||
def xview(self):
|
||||
w, h = self.get_size()
|
||||
dx, dy = self.world_to_window(0, 0)
|
||||
return -float(dx)/w, 1.0
|
||||
def yview(self):
|
||||
w, h = self.get_size()
|
||||
dx, dy = self.world_to_window(0, 0)
|
||||
return -float(dy)/h, 1.0
|
||||
|
||||
def winfo_width(self):
|
||||
return self.get_size()[0]
|
||||
def winfo_height(self):
|
||||
return self.get_size()[1]
|
||||
|
||||
def configure(self, **kw):
|
||||
height, width = -1, -1
|
||||
for k, v in kw.items():
|
||||
|
@ -320,10 +350,6 @@ class MfxCanvas(gnome.canvas.Canvas):
|
|||
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
|
||||
|
||||
|
@ -335,7 +361,7 @@ class MfxCanvas(gnome.canvas.Canvas):
|
|||
i._item.destroy()
|
||||
##i._item = None
|
||||
self._all_items = []
|
||||
if self.__tileimage:
|
||||
if 0: #self.__tileimage:
|
||||
self.__tileimage.destroy()
|
||||
self.__tileimage = None
|
||||
|
||||
|
@ -457,7 +483,6 @@ class MfxCanvas(gnome.canvas.Canvas):
|
|||
self.__tileimage = w
|
||||
|
||||
|
||||
|
||||
def setTopImage(self, image, cw=0, ch=0):
|
||||
if self.__topimage:
|
||||
self.__topimage.destroy()
|
||||
|
@ -482,6 +507,7 @@ class MfxCanvas(gnome.canvas.Canvas):
|
|||
#gdk.window_process_all_updates()
|
||||
#self.show_now()
|
||||
self.update_now()
|
||||
pass
|
||||
|
||||
|
||||
def grid(self, *args, **kw):
|
||||
|
@ -492,19 +518,22 @@ class MfxCanvas(gnome.canvas.Canvas):
|
|||
self.show()
|
||||
|
||||
|
||||
def _resize(self):
|
||||
##print '_resize:', self._width, self._height
|
||||
#if self.window:
|
||||
self.set_size(self._width, self._height)
|
||||
self.window.resize(self._width, self._height)
|
||||
|
||||
def setInitialSize(self, width, height):
|
||||
##print 'setInitialSize:', width, height
|
||||
self._width, self._height = width, height
|
||||
self.set_size_request(width, height)
|
||||
#self.set_size(width, height)
|
||||
#self.queue_resize()
|
||||
#gobject.idle_add(self._resize, priority=gobject.PRIORITY_HIGH_IDLE)
|
||||
|
||||
|
||||
def destroyEvent(self, w):
|
||||
#print 'MfxCanvas.destroyEvent'
|
||||
self.hide()
|
||||
## self.deleteAllItems()
|
||||
## if self.__topimage:
|
||||
## self.__topimage.destroy()
|
||||
## self.__topimage = None
|
||||
|
||||
|
||||
|
||||
class MfxScrolledCanvas(MfxCanvas):
|
||||
|
|
|
@ -119,14 +119,20 @@ def color_gtk2tk(col):
|
|||
|
||||
|
||||
class _PysolPixmap:
|
||||
def __init__(self, file=None):
|
||||
def __init__(self, file=None, pixbuf=None, width=0, height=0,
|
||||
fill=None, outline=None):
|
||||
if file:
|
||||
self.pixbuf = gdk.pixbuf_new_from_file(file)
|
||||
elif pixbuf:
|
||||
self.pixbuf = pixbuf
|
||||
else:
|
||||
self.pixbuf = gdk.Pixbuf()
|
||||
self.pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB,
|
||||
True, 8, width, height)
|
||||
|
||||
def clone(self):
|
||||
return self.pixbuf.copy()
|
||||
pixbuf = self.pixbuf.copy()
|
||||
im = _PysolPixmap(pixbuf=pixbuf)
|
||||
return im
|
||||
|
||||
def width(self):
|
||||
return self.pixbuf.get_width()
|
||||
|
@ -134,19 +140,24 @@ class _PysolPixmap:
|
|||
def height(self):
|
||||
return self.pixbuf.get_height()
|
||||
|
||||
def subsample(self, x, y=None):
|
||||
## FIXME
|
||||
return None
|
||||
def subsample(self, r):
|
||||
w, h = self.pixbuf.get_width(), self.pixbuf.get_height()
|
||||
w, h = int(float(w)/r), int(float(h)/r)
|
||||
pixbuf = self.pixbuf.scale_simple(w, h, gdk.INTERP_BILINEAR)
|
||||
im = _PysolPixmap(pixbuf=pixbuf)
|
||||
return im
|
||||
|
||||
|
||||
def loadImage(file):
|
||||
return _PysolPixmap(file=file)
|
||||
|
||||
def copyImage(image, x, y, width, height):
|
||||
return image
|
||||
# FIXME
|
||||
return image.clone()
|
||||
|
||||
def createImage(width, height, fill, outline=None):
|
||||
return _PysolPixmap()
|
||||
# FIXME
|
||||
return _PysolPixmap(width=width, height=height, fill=fill, outline=outline)
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -74,8 +74,6 @@ class MfxDialog(_MyDialog):
|
|||
text='', justify='center',
|
||||
strings=("OK",), default=0,
|
||||
separatorwidth=0,
|
||||
font=None,
|
||||
buttonfont=None,
|
||||
padx=20, pady=20,
|
||||
bitmap=None, bitmap_side='left',
|
||||
bitmap_padx=20, bitmap_pady=20,
|
||||
|
@ -84,6 +82,7 @@ class MfxDialog(_MyDialog):
|
|||
_MyDialog.__init__(self)
|
||||
self.status = 1
|
||||
self.button = -1
|
||||
self.buttons = []
|
||||
|
||||
modal=True
|
||||
if modal:
|
||||
|
@ -121,7 +120,8 @@ class MfxDialog(_MyDialog):
|
|||
"question": gtk.STOCK_DIALOG_QUESTION} [kw['bitmap']]
|
||||
im = gtk.image_new_from_stock(stock, gtk.ICON_SIZE_DIALOG)
|
||||
box.pack_start(im)
|
||||
im.xpad, im.ypad = kw['bitmap_padx'], kw['bitmap_pady']
|
||||
im.set_property('xpad', kw['bitmap_padx'])
|
||||
im.set_property('ypad', kw['bitmap_pady'])
|
||||
im.show()
|
||||
elif kw['image']:
|
||||
im = gtk.Image()
|
||||
|
@ -130,7 +130,8 @@ class MfxDialog(_MyDialog):
|
|||
box.pack_start(im)
|
||||
else:
|
||||
box.pack_end(im)
|
||||
im.xpad, im.ypad = kw['image_padx'], kw['image_pady']
|
||||
im.set_property('xpad', kw['image_padx'])
|
||||
im.set_property('ypad', kw['image_pady'])
|
||||
im.show()
|
||||
|
||||
def createButtons(self, box, kw):
|
||||
|
@ -149,6 +150,7 @@ class MfxDialog(_MyDialog):
|
|||
b.connect("clicked", self.done)
|
||||
box.pack_start(b)
|
||||
b.show()
|
||||
self.buttons.append(b)
|
||||
|
||||
def initKw(self, kw):
|
||||
kwdefault(kw,
|
||||
|
|
|
@ -202,7 +202,6 @@ class _MfxToplevel(gtk.Window):
|
|||
|
||||
def wm_geometry(self, newGeometry=None):
|
||||
##print 'wm_geometry', newGeometry
|
||||
print 'allow_shrink:', self.allow_shrink
|
||||
if not newGeometry:
|
||||
pass
|
||||
##self.reshow_with_initial_size()
|
||||
|
|
|
@ -60,7 +60,7 @@ class PysolToolbar(PysolToolbarActions):
|
|||
ui_info = '''
|
||||
<ui>
|
||||
<toolbar name='toolbar'>
|
||||
<toolitem action='new'/>
|
||||
<toolitem action='newgame'/>
|
||||
<toolitem action='restart'/>
|
||||
<separator/>
|
||||
<toolitem action='open'/>
|
||||
|
|
|
@ -853,7 +853,8 @@ class PysolMenubar(PysolMenubarActions):
|
|||
if not idir:
|
||||
idir = self.app.dn.savegames
|
||||
d = tkFileDialog.Open()
|
||||
filename = d.show(filetypes=self.FILETYPES, defaultextension=self.DEFAULTEXTENSION,
|
||||
filename = d.show(filetypes=self.FILETYPES,
|
||||
defaultextension=self.DEFAULTEXTENSION,
|
||||
initialdir=idir, initialfile=ifile)
|
||||
if filename:
|
||||
filename = os.path.normpath(filename)
|
||||
|
@ -880,7 +881,8 @@ class PysolMenubar(PysolMenubarActions):
|
|||
idir = self.app.dn.savegames
|
||||
##print self.game.filename, ifile
|
||||
d = tkFileDialog.SaveAs()
|
||||
filename = d.show(filetypes=self.FILETYPES, defaultextension=self.DEFAULTEXTENSION,
|
||||
filename = d.show(filetypes=self.FILETYPES,
|
||||
defaultextension=self.DEFAULTEXTENSION,
|
||||
initialdir=idir, initialfile=ifile)
|
||||
if filename:
|
||||
filename = os.path.normpath(filename)
|
||||
|
|
Loading…
Add table
Reference in a new issue