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

* improved GTK bindings; menu and stats-dialog

git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@52 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
skomoroh 2006-08-19 22:45:59 +00:00
parent c124104d9a
commit b2ee652928
19 changed files with 586 additions and 183 deletions

1
data/pysolfc.glade Symbolic link
View file

@ -0,0 +1 @@
../../../pysolfc/pysolfc.glade

6
pysol
View file

@ -59,6 +59,12 @@ if os.name == 'nt':
##if locale_dir: locale_dir = os.path.normpath(locale_dir)
gettext.install('pysol', locale_dir, unicode=True)
## init toolkit
if '--gtk' in sys.argv:
import pysollib.settings
pysollib.settings.TOOLKIT = 'gtk'
sys.argv.remove('--gtk')
from pysollib.main import main
#import pychecker.checker

View file

@ -58,7 +58,7 @@ from gamedb import GI, GAME_DB, loadGame
from settings import TOP_SIZE, TOP_TITLE, TOOLKIT
# Toolkit imports
from pysoltk import tkname, tkversion, wm_withdraw, loadImage
from pysoltk import wm_withdraw, loadImage
from pysoltk import MfxMessageDialog, MfxExceptionDialog
from pysoltk import TclError, MfxRoot, MfxCanvas, MfxScrolledCanvas
from pysoltk import PysolMenubar
@ -107,7 +107,7 @@ class Options:
self.shrink_face_down = True
self.shade_filled_stacks = True
self.demo_logo = True
self.toolbar = True
self.toolbar = 1 # 0 == hide, 1,2,3,4 == top, bottom, lef, right
##self.toolbar_style = 'default'
self.toolbar_style = 'crystal'
if os.name == 'posix':

View file

@ -52,7 +52,7 @@ from resource import CSI
from pysolrandom import PysolRandom, LCRandom31
from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE
from pysoltk import CURSOR_WATCH, ANCHOR_SW, ANCHOR_SE
from pysoltk import tkname, bind, wm_map
from pysoltk import bind, wm_map
from pysoltk import after, after_idle, after_cancel
from pysoltk import MfxMessageDialog, MfxExceptionDialog
from pysoltk import MfxCanvasText, MfxCanvasImage
@ -393,8 +393,8 @@ class Game:
if self.canvas:
self.canvas.config(cursor=cursor)
##self.canvas.update_idletasks()
if self.app and self.app.toolbar:
self.app.toolbar.setCursor(cursor=cursor)
#if self.app and self.app.toolbar:
# self.app.toolbar.setCursor(cursor=cursor)
#
@ -529,7 +529,6 @@ class Game:
self.busy = old_busy
def resetGame(self):
##print '--- resetGame ---'
self.hints.list = None
self.s.talon.removeAllCards()
for stack in self.allstacks:
@ -560,7 +559,6 @@ class Game:
# with another game from there
def quitGame(self, id=0, random=None, loadedgame=None,
startdemo=0, bookmark=0, holdgame=0):
print 'quitGame'
self.updateTime()
if bookmark:
id, random = self.id, self.random

View file

@ -41,9 +41,9 @@ import Tkinter
# PySol imports
from mfxutil import EnvError
from settings import PACKAGE, PACKAGE_URL
from settings import PACKAGE, PACKAGE_URL, TOOLKIT
from version import VERSION, FC_VERSION
from pysoltk import tkname, makeHelpToplevel, wm_map, wm_set_icon
from pysoltk import makeHelpToplevel, wm_map, wm_set_icon
from pysoltk import MfxMessageDialog
from pysoltk import tkHTMLViewer
from gamedb import GAME_DB
@ -95,10 +95,10 @@ def helpCredits(app, timeout=0, sound=1):
if sound:
app.audio.playSample("credits")
t = ""
if tkname == "tk": t = "Tcl/Tk, "
elif tkname == "gnome": t = "PyGTK, "
elif tkname == "kde": t = "pyKDE, "
elif tkname == "wx": t = "wxPython, "
if TOOLKIT == "tk": t = "Tcl/Tk, "
elif TOOLKIT == "gtk": t = "PyGTK, "
elif TOOLKIT == "kde": t = "pyKDE, "
elif TOOLKIT == "wx": t = "wxPython, "
d = MfxMessageDialog(app.top, title=_("Credits"), timeout=timeout,
text=PACKAGE+_(''' credits go to:

View file

@ -44,7 +44,7 @@ import gettext
from mfxutil import destruct, EnvError
from util import CARDSET, DataLoader
from version import VERSION
from settings import PACKAGE
from settings import PACKAGE, TOOLKIT
from resource import Tile
from gamedb import GI
from app import Application
@ -52,12 +52,11 @@ from pysolaudio import thread, pysolsoundserver
from pysolaudio import AbstractAudioClient, PysolSoundServerModuleClient, Win32AudioClient
# Toolkit imports
from pysoltk import tkname, tkversion, wm_withdraw, wm_set_icon, loadImage
from pysoltk import tkversion, wm_withdraw, wm_set_icon, loadImage
from pysoltk import MfxMessageDialog, MfxExceptionDialog
from pysoltk import TclError, MfxRoot
from pysoltk import PysolProgressBar
from tkFont import Font
# /***********************************************************************
# //
@ -327,20 +326,22 @@ def pysol_init(app, args):
font = top.option_get('font', '')
else:
font = None
try:
f = Font(top, font)
except:
print >> sys.stderr, "invalid font name:", font
pass
else:
if font:
fa = f.actual()
app.opt.fonts["default"] = (fa["family"],
fa["size"],
fa["slant"],
fa["weight"])
if TOOLKIT == 'tk':
from tkFont import Font
try:
f = Font(top, font)
except:
print >> sys.stderr, "invalid font name:", font
pass
else:
app.opt.fonts["default"] = None
if font:
fa = f.actual()
app.opt.fonts["default"] = (fa["family"],
fa["size"],
fa["slant"],
fa["weight"])
else:
app.opt.fonts["default"] = None
# check games
if len(app.gdb.getGamesIdSortedByName()) == 0:
@ -559,7 +560,7 @@ def main(args=None):
print "%s needs Python 1.5.2 or better (you have %s)" % (PACKAGE, sys.version)
return 1
assert len(tkversion) == 4
if tkname == "tk":
if TOOLKIT == "tk":
import Tkinter
if tkversion < (8, 0, 0, 0):
print "%s needs Tcl/Tk 8.0 or better (you have %s)" % (PACKAGE, str(tkversion))

View file

@ -53,6 +53,7 @@ gettext = _
def ltk2gtk(s):
# label tk to gtk
return gettext(s).replace('&', '_')
@ -69,7 +70,7 @@ class PysolMenubar(PysolMenubarActions):
# create menus
menubar = self.createMenubar()
self.top.table.attach(menubar,
0, 1, 0, 1,
0, 3, 0, 1,
gtk.EXPAND | gtk.FILL, 0,
0, 0);
menubar.show()
@ -119,7 +120,7 @@ class PysolMenubar(PysolMenubarActions):
('stats', gtk.STOCK_INDEX,
ltk2gtk('Stats'), None,
ltk2gtk('Statistics'),
self.mStatus),
lambda w, self=self: self.mPlayerStats(mode=101)),
('rules', gtk.STOCK_HELP,
ltk2gtk('Rules'), 'F1',
ltk2gtk('Rules'),
@ -136,9 +137,12 @@ class PysolMenubar(PysolMenubarActions):
('game', None, ltk2gtk('&Game')),
('assist', None, ltk2gtk('&Assist')),
('options', None, ltk2gtk('&Options')),
('assistlevel', None, ltk2gtk("Assist &level")),
("automaticplay", None, ltk2gtk("&Automatic play")),
('assistlevel', None, ltk2gtk('Assist &level')),
('automaticplay', None, ltk2gtk('&Automatic play')),
('animations', None, ltk2gtk('A&nimations')),
('cardview', None, ltk2gtk('Card &view')),
('toolbar', None, ltk2gtk('&Toolbar')),
('statusbar', None, ltk2gtk('Stat&usbar')),
('help', None, ltk2gtk('&Help')),
### menuitems
@ -150,7 +154,10 @@ class PysolMenubar(PysolMenubarActions):
None, self.mSelectGameById),
('saveas', None,
ltk2gtk('Save &as...'), None,
None, self.m),
None, self.mSaveAs),
('holdandquit', None,
ltk2gtk('&Hold and quit'), None,
None, self.mHoldAndQuit),
('redoall', None,
ltk2gtk('Redo &all'), None,
None, self.mRedoAll),
@ -195,34 +202,53 @@ class PysolMenubar(PysolMenubarActions):
#
toggle_entries = [
('pause', # name
gtk.STOCK_STOP, ltk2gtk('&Pause'), # stock, label
'P', ltk2gtk('Pause game'), # accelerator, tooltip
self.mPause, # callback
False, # initial value
), ]
for label, name, opt_name in (
('A&uto drop', 'optautodrop', 'autodrop'),
('Auto &face up', '', 'autofaceup'),
('Auto &deal', '', 'autodeal'),
('&Quick play', '', 'quickplay'),
('Enable &undo', '', 'undo'),
('Enable &bookmarks' , '', 'bookmarks'),
('Enable &hint', '', 'hint'),
('Enable highlight p&iles', '', 'highlight_piles'),
('Enable highlight &cards', '', 'highlight_cards'),
('Enable highlight same &rank', '', 'highlight_samerank'),
('Highlight &no matching', '', 'highlight_not_matching'),
('Card shado&w', '', 'shadow'),
('Shade &legal moves', '', 'shade'),
('pause', gtk.STOCK_STOP, # action, stock
ltk2gtk('&Pause'), 'P', # label, accelerator
ltk2gtk('Pause game'), # tooltip
self.mPause, # callback
False, # initial value
),
('negativecardsbottom', None,
ltk2gtk('&Negative cards bottom'), None, None,
self.mOptNegativeBottom,
self.app.opt.negative_bottom,
),
('showstatusbar', None,
ltk2gtk('Show &statusbar'), None, None,
self.mOptStatusbar,
self.app.opt.statusbar,
),
]
for label, action, opt_name, update_game in (
('A&uto drop', 'optautodrop', 'autodrop', False),
('Auto &face up', '', 'autofaceup', False),
('Auto &deal', '', 'autodeal', False),
('&Quick play', '', 'quickplay', False),
('Enable &undo', '', 'undo', False),
('Enable &bookmarks', '', 'bookmarks', False),
('Enable &hint', '', 'hint', False),
('Enable highlight p&iles', '', 'highlight_piles', False),
('Enable highlight &cards', '', 'highlight_cards', False),
('Enable highlight same &rank', '', 'highlight_samerank', False),
('Highlight &no matching', '', 'highlight_not_matching', False),
('Card shado&w', '', 'shadow', False),
('Shade &legal moves', '', 'shade', False),
('Shrink face-down cards', '', 'shrink_face_down', True),
('Shade &filled stacks', '', 'shade_filled_stacks', True),
('Stick&y mouse', '', 'sticky_mouse', False),
('Show &number of cards', '', 'num_cards', False),
('&Demo logo', '', 'demo_logo', False),
('Startup splash sc&reen', '', 'splashscreen', False),
('&Show removed tiles (in Mahjongg games)', '', 'mahjongg_show_removed', True),
('Show hint &arrow (in Shisen-Sho games)', '', 'shisen_show_hint', False),
):
if not name:
name = re.sub(r"[^0-9a-zA-Z]", "", label).lower()
if not action:
action = re.sub(r'[^0-9a-zA-Z]', '', label).lower()
toggle_entries.append(
(name,
(action,
None, ltk2gtk(label),
None, None,
lambda w, opt_name=opt_name: self.mOptToggle(w, opt_name),
lambda w, o=opt_name, u=update_game: self.mOptToggle(w, o, u),
getattr(self.app.opt, opt_name)))
#
@ -233,6 +259,14 @@ class PysolMenubar(PysolMenubarActions):
('animationslow', None, ltk2gtk('&Slow'), None, None, 3),
('animationveryslow', None, ltk2gtk('&Very slow'), None, None, 4),
)
toolbar_side_entries = (
('toolbarhide', None, ltk2gtk('Hide'), None, None, 0),
('toolbartop', None, ltk2gtk('Top'), None, None, 1),
('toolbarbottom', None, ltk2gtk('Bottom'), None, None, 2),
('toolbarleft', None, ltk2gtk('Left'), None, None, 3),
('toolbarright', None, ltk2gtk('Right'), None, None, 4),
)
#
ui_info = '''<ui>
<menubar name='menubar'>
@ -247,6 +281,7 @@ class PysolMenubar(PysolMenubarActions):
<menuitem action='save'/>
<menuitem action='saveas'/>
<separator/>
<menuitem action='holdandquit'/>
<menuitem action='quit'/>
</menu>
@ -256,8 +291,10 @@ class PysolMenubar(PysolMenubarActions):
<menuitem action='redoall'/>
<separator/>
<menuitem action='restart'/>
<!--
<separator/>
<menuitem action='updateall'/>
-->
</menu>
<menu action='game'>
@ -266,6 +303,7 @@ class PysolMenubar(PysolMenubarActions):
<menuitem action='pause'/>
<separator/>
<menuitem action='status'/>
<menuitem action='stats'/>
</menu>
<menu action='assist'>
@ -292,6 +330,9 @@ class PysolMenubar(PysolMenubarActions):
<menuitem action='enablehighlightcards'/>
<menuitem action='enablehighlightsamerank'/>
<menuitem action='highlightnomatching'/>
<separator/>
<menuitem action='showremovedtilesinmahjongggames'/>
<menuitem action='showhintarrowinshisenshogames'/>
</menu>
<separator/>
<menuitem action='tabletile'/>
@ -303,8 +344,28 @@ class PysolMenubar(PysolMenubarActions):
<menuitem action='animationslow'/>
<menuitem action='animationveryslow'/>
</menu>
<menuitem action='cardshadow'/>
<menuitem action='shadelegalmoves'/>
<menu action='cardview'>
<menuitem action='cardshadow'/>
<menuitem action='shadelegalmoves'/>
<menuitem action='negativecardsbottom'/>
<menuitem action='shrinkfacedowncards'/>
<menuitem action='shadefilledstacks'/>
</menu>
<menuitem action='stickymouse'/>
<separator/>
<menuitem action='demologo'/>
<menuitem action='startupsplashscreen'/>
<menu action='toolbar'>
<menuitem action='toolbarhide'/>
<menuitem action='toolbartop'/>
<menuitem action='toolbarbottom'/>
<menuitem action='toolbarleft'/>
<menuitem action='toolbarright'/>
</menu>
<menu action='statusbar'>
<menuitem action='showstatusbar'/>
<menuitem action='shownumberofcards'/>
</menu>
</menu>
<menu action='help'>
@ -326,6 +387,9 @@ class PysolMenubar(PysolMenubarActions):
action_group.add_radio_actions(animations_entries,
self.app.opt.animations,
self.mOptAnimations)
action_group.add_radio_actions(toolbar_side_entries,
self.app.opt.toolbar,
self.mOptToolbar)
ui_manager.insert_action_group(action_group, 0)
self.top.add_accel_group(ui_manager.get_accel_group())
@ -421,7 +485,6 @@ class PysolMenubar(PysolMenubarActions):
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)
@ -451,7 +514,7 @@ class PysolMenubar(PysolMenubarActions):
if filename:
idir, ifile = os.path.split(os.path.normpath(filename))
else:
idir, ifile = "", ""
idir, ifile = '', ''
if not idir:
idir = self.app.dn.savegames
filename = self._createFileChooser(_('Open Game'),
@ -471,12 +534,12 @@ class PysolMenubar(PysolMenubarActions):
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)
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)
filename = filename + '-' + self.game.getGameNumber(format=0)
else:
filename = filename + "-01"
filename = filename + '-01'
filename = filename + '.pso'
idir, ifile = os.path.split(os.path.normpath(filename))
if not idir:
@ -493,49 +556,14 @@ class PysolMenubar(PysolMenubarActions):
def mOptTableTile(self, *args):
if self._cancelDrag(break_pause=False): return
key = self.app.tabletile_index
if key <= 0:
key = self.app.opt.table_color.lower()
d = SelectTileDialogWithPreview(self.top, app=self.app,
title=_('Select table background'),
manager=self.app.tabletile_manager,
key=key)
if d.status == 0 and d.button in (0, 1):
if type(d.key) is str:
self._mOptTableColor(d.key)
elif d.key > 0 and d.key != self.app.tabletile_index:
self._mOptTableTile(d.key)
def mOptHintOptions(self, *args):
pass
def mOptDemoOptions(self, *args):
pass
def updateFavoriteGamesMenu(self, *args):
pass
def mSelectGame(self, menu_item, game_id):
if menu_item.get_active():
self._mSelectGame(game_id)
def mOptAnimations(self, a1, a2):
##print a1.get_current_value(), a2.get_current_value()
self.app.opt.animations = a1.get_current_value()
def _mOptTableTile(self, i):
self.app.setTile(i)
def _mOptTableColor(self, color):
tile = self.app.tabletile_manager.get(0)
tile.color = color
self.app.setTile(0)
def mSelectGameDialogWithPreview(self, *event):
if self._cancelDrag(break_pause=False): return
## self.game.setCursor(cursor=CURSOR_WATCH)
@ -546,12 +574,9 @@ class PysolMenubar(PysolMenubarActions):
## 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"),
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)
@ -564,10 +589,28 @@ class PysolMenubar(PysolMenubarActions):
self.game.quitGame(d.gameid, random=d.random)
def mOptTableTile(self, *args):
if self._cancelDrag(break_pause=False): return
key = self.app.tabletile_index
if key <= 0:
key = self.app.opt.table_color.lower()
d = SelectTileDialogWithPreview(self.top, app=self.app,
title=_('Select table background'),
manager=self.app.tabletile_manager,
key=key)
if d.status == 0 and d.button in (0, 1):
if type(d.key) is str:
tile = self.app.tabletile_manager.get(0)
tile.color = color
self.app.setTile(0)
elif d.key > 0 and d.key != self.app.tabletile_index:
self.app.setTile(i)
def mSelectCardsetDialog(self, *event):
if self._cancelDrag(break_pause=False): return
key = self.app.nextgame.cardset.index
d = SelectCardsetDialogWithPreview(self.top, title=_("Select cardset"),
d = SelectCardsetDialogWithPreview(self.top, title=_('Select cardset'),
app=self.app, manager=self.app.cardset_manager, key=key)
cs = self.app.cardset_manager.get(d.key)
if cs is None or d.key == self.app.cardset.index:
@ -581,10 +624,42 @@ class PysolMenubar(PysolMenubarActions):
self.app.opt.games_geometry = {} # clear saved games geometry
def mOptToggle(self, w, opt):
def mOptToggle(self, w, opt_name, update_game):
##print 'mOptToggle:', opt, w.get_active()
if self._cancelDrag(break_pause=False): return
self.app.opt.__dict__[opt] = w.get_active()
self.app.opt.__dict__[opt_name] = w.get_active()
if update_game:
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptNegativeBottom(self, w):
if self._cancelDrag(): return
self.app.opt.negative_bottom = w.get_active()
self.app.updateCardset()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptAnimations(self, w1, w2):
self.app.opt.animations = w1.get_current_value()
def mOptToolbar(self, w1, w2):
if self._cancelDrag(break_pause=False): return
side = w1.get_current_value()
self.app.opt.toolbar = side
if self.app.toolbar.show(side, resize=1):
self.top.update_idletasks()
def mOptStatusbar(self, w):
if self._cancelDrag(break_pause=False): return
if not self.app.statusbar: return
side = w.get_active()
self.app.opt.statusbar = side
resize = not self.app.opt.save_games_geometry
if self.app.statusbar.show(side, resize=resize):
self.top.update_idletasks()
def updateAll(self, *event):

View file

@ -86,12 +86,6 @@ class PysolProgressBar:
self.pbar.set_text(str(show_text)+'%')
w, h = self.pbar.size_request()
self.pbar.set_size_request(max(w, 300), max(h, height))
# set color
##~ c = self.pbar.get_colormap().alloc_color(color)
##~ self.pbar.style.bg[gtk.STATE_PRELIGHT] = c
##~ style = self.pbar.get_style().copy()
##~ style.bg[gtk.STATE_PRELIGHT] = c
##~ self.pbar.set_style(style)
# hbox-3:image
if images and images[1]:
im = gtk.Image()

View file

@ -76,6 +76,7 @@ class _CanvasItem:
def __init__(self, canvas):
self.canvas = canvas
canvas._all_items.append(self)
self._is_hidden = False
def addtag(self, group):
##print self, 'addtag'
@ -126,9 +127,11 @@ class _CanvasItem:
def show(self):
if self._item:
self._item.show()
self._is_hidden = False
def hide(self):
if self._item:
self._item.hide()
self._is_hidden = True
def connect(self, signal, func, args):
##print signal
@ -251,6 +254,7 @@ class MfxCanvas(gnome.canvas.Canvas):
self.items = {}
self._all_items = []
self._text_items = []
self._hidden_items = []
self._width, self._height = -1, -1
self._tile = None
# private
@ -327,13 +331,10 @@ class MfxCanvas(gnome.canvas.Canvas):
##print 'configure: bg:', v
c = self.get_colormap().alloc_color(v)
self.style.bg[gtk.STATE_NORMAL] = c
##~ self.set_style(self.style)
##~ self.queue_draw()
elif k == "cursor":
##~ w = self.window
##~ if w:
##~ w.set_cursor(cursor_new(v))
pass
if not self.window:
self.realize()
self.window.set_cursor(gdk.Cursor(v))
elif k == "height":
height = v
elif k == "width":
@ -359,12 +360,16 @@ class MfxCanvas(gnome.canvas.Canvas):
self.__tileimage = None
def hideAllItems(self):
self._hidden_items = []
for i in self._all_items:
i.hide()
if not i._is_hidden:
i.hide()
self._hidden_items.append(i)
def showAllItems(self):
for i in self._all_items:
for i in self._hidden_items:
i.show()
self._hidden_items = []
# PySol extension
def findCard(self, stack, event):
@ -440,8 +445,9 @@ class MfxCanvas(gnome.canvas.Canvas):
gtk.idle_add(self.setBackgroundImage, filename, stretch)
def setBackgroundImage(self, filename, stretch=False):
print 'setBackgroundImage', filename
##print 'setBackgroundImage', filename
if filename is None:
if self.__tileimage:
self.__tileimage.destroy()
@ -504,6 +510,9 @@ class MfxCanvas(gnome.canvas.Canvas):
##print 'MfxCanvas.update_idletasks'
#gdk.window_process_all_updates()
#self.show_now()
# FIXME
##if self.__topimage:
## self.__topimage.raise_to_top()
self.update_now()
pass
@ -523,7 +532,7 @@ class MfxCanvas(gnome.canvas.Canvas):
def grid(self, *args, **kw):
self.top.table.attach(self,
0, 1, 2, 3,
1, 2, 2, 3,
gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL | gtk.SHRINK,
0, 0)
self.show()

View file

@ -42,7 +42,6 @@ from gtk import ANCHOR_NW, ANCHOR_SW, ANCHOR_NE, ANCHOR_SE
# // constants
# ************************************************************************/
tkname = "gnome"
# (major version, minor version, micro version, patchlevel)
tkversion = (0, 0, 0, 0)

View file

@ -31,21 +31,275 @@
# imports
import os, sys
import gtk
import os, sys, time
import gtk, gobject, pango
import gtk.glade
# PySol imports
from pysollib.mfxutil import format_time
from pysollib.settings import TOP_TITLE
from pysollib.stats import PysolStatsFormatter
# Toolkit imports
from tkwidget import MfxDialog
from tkwidget import MfxDialog, MfxMessageDialog
glade_file = os.path.join(sys.path[0], 'data', 'pysolfc.glade')
open(glade_file)
# /***********************************************************************
# //
# ************************************************************************/
class SingleGame_StatsDialog(MfxDialog):
pass
class StatsWriter(PysolStatsFormatter.StringWriter):
def __init__(self, store):
self.store = store
def p(self, s):
pass
def pheader(self, s):
pass
def pstats(self, *args, **kwargs):
gameid=kwargs.get('gameid', None)
if gameid is None:
# header
return
iter = self.store.append(None)
self.store.set(iter,
0, args[0],
1, args[1],
2, args[2],
3, args[3],
4, args[4],
5, args[5],
6, args[6],
7, gameid)
class FullLogWriter(PysolStatsFormatter.StringWriter):
def __init__(self, store):
self.store = store
def p(self, s):
pass
def pheader(self, s):
pass
def plog(self, gamename, gamenumber, date, status, gameid=-1, won=-1):
if gameid < 0:
# header
return
iter = self.store.append(None)
self.store.set(iter,
0, gamename,
1, gamenumber,
2, date,
3, status,
4, gameid)
class Game_StatsDialog:
def __init__(self, parent, header, app, player, gameid):
#
self.app = app
formatter = PysolStatsFormatter(self.app)
#
self.widgets_tree = gtk.glade.XML(glade_file)
#game_name_combo = self.widgets_tree.get_widget('game_name_combo')
#model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
#game_name_combo.set_model(model)
#game_name_combo.set_text_column(0)
stats_dialog = self.widgets_tree.get_widget('stats_dialog')
stats_dialog.set_title('Game Statistics')
stats_dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
# total
won, lost = app.stats.getStats(player, gameid)
self._createText('total', won, lost)
drawing = self.widgets_tree.get_widget('total_drawingarea')
drawing.connect('expose_event', self._createChart, won, lost)
# current session
won, lost = app.stats.getSessionStats(player, gameid)
self._createText('current', won, lost)
drawing = self.widgets_tree.get_widget('session_drawingarea')
drawing.connect('expose_event', self._createChart, won, lost)
#
store = self._createStatsList()
writer = StatsWriter(store)
formatter.writeStats(writer, player, header, sort_by='name')
#
store = self._createLogList('full_log_treeview')
writer = FullLogWriter(store)
formatter.writeFullLog(writer, player, header)
#
store = self._createLogList('session_log_treeview')
writer = FullLogWriter(store)
formatter.writeSessionLog(writer, player, header)
#
stats_dialog.set_transient_for(parent)
stats_dialog.resize(400, 300)
stats_dialog.run()
self.status = -1
stats_dialog.destroy()
def _createText(self, name, won, lost):
pwon, plost = self._getPwon(won, lost)
label = self.widgets_tree.get_widget(name+'_num_won_label')
label.set_text(str(won))
label = self.widgets_tree.get_widget(name+'_num_lost_label')
label.set_text(str(lost))
label = self.widgets_tree.get_widget(name+'_percent_won_label')
label.set_text(str(int(round(pwon*100)))+'%')
label = self.widgets_tree.get_widget(name+'_percent_lost_label')
label.set_text(str(int(round(plost*100)))+'%')
label = self.widgets_tree.get_widget(name+'_num_total_label')
label.set_text(str(won+lost))
def _createChart(self, drawing, e, won, lost):
pwon, plost = self._getPwon(won, lost)
s, ewon, elost = 0, int(360.0*pwon), int(360.0*plost)
win = drawing.window
colormap = drawing.get_colormap()
gc = win.new_gc()
gc.set_colormap(colormap)
alloc = drawing.allocation
width, height = alloc.width, alloc.height
w, h = 90, 50
##x, y = 10, 10
x, y = (width-w)/2, (height-h)/2
dy = 9
y = y-dy/2
if won+lost > 0:
gc.set_rgb_fg_color(colormap.alloc_color('#007f00'))
win.draw_arc(gc, True, x, y+dy, w, h, s*64, ewon*64)
gc.set_rgb_fg_color(colormap.alloc_color('#7f0000'))
win.draw_arc(gc, True, x, y+dy, w, h, (s+ewon)*64, elost*64)
gc.set_rgb_fg_color(colormap.alloc_color('#00ff00'))
win.draw_arc(gc, True, x, y, w, h, s*64, ewon*64)
gc.set_rgb_fg_color(colormap.alloc_color('#ff0000'))
win.draw_arc(gc, True, x, y, w, h, (s+ewon)*64, elost*64)
else:
gc.set_rgb_fg_color(colormap.alloc_color('#7f7f7f'))
win.draw_arc(gc, True, x, y+dy, w, h, 0, 360*64)
gc.set_rgb_fg_color(colormap.alloc_color('#f0f0f0'))
win.draw_arc(gc, True, x, y, w, h, 0, 360*64)
gc.set_rgb_fg_color(colormap.alloc_color('#bfbfbf'))
pangolayout = drawing.create_pango_layout('No games')
ext = pangolayout.get_extents()
tw, th = ext[1][2]/pango.SCALE, ext[1][3]/pango.SCALE
win.draw_layout(
gc,
x+w/2-tw/2, y+h/2-th/2,
pangolayout)
def _createStatsList(self):
treeview = self.widgets_tree.get_widget('all_games_treeview')
n = 0
for label in (
'',
_('Played'),
_('Won'),
_('Lost'),
_('Playing time'),
_('Moves'),
_('% won'),
):
column = gtk.TreeViewColumn(label, gtk.CellRendererText(),
text=n)
column.set_resizable(True)
column.set_sort_column_id(n)
treeview.append_column(column)
n += 1
#
store = gtk.ListStore(gobject.TYPE_STRING, # name
gobject.TYPE_INT, # played
gobject.TYPE_INT, # won
gobject.TYPE_INT, # lost
gobject.TYPE_STRING, # playing time
gobject.TYPE_STRING, # moves
gobject.TYPE_STRING, # % won
gobject.TYPE_INT, # gameid
)
sortable = gtk.TreeModelSort(store)
treeview.set_model(sortable)
sortable.set_sort_func(4, self._cmpPlayingTime)
sortable.set_sort_func(5, self._cmpMoves)
sortable.set_sort_func(6, self._cmpPercent)
return store
def _createLogList(self, name):
#
treeview = self.widgets_tree.get_widget(name)
n = 0
for label in (
_('Game'),
_('Game number'),
_('Started at'),
_('Status'),
):
column = gtk.TreeViewColumn(label, gtk.CellRendererText(),
text=n)
column.set_resizable(True)
column.set_sort_column_id(n)
treeview.append_column(column)
n += 1
#
store = gtk.ListStore(gobject.TYPE_STRING, # game name
gobject.TYPE_STRING, # game number
gobject.TYPE_STRING, # started at
gobject.TYPE_STRING, # status
gobject.TYPE_INT, # gameid
)
treeview.set_model(store)
return store
def _getPwon(self, won, lost):
pwon, plost = 0.0, 0.0
if won + lost > 0:
pwon = float(won) / (won + lost)
pwon = min(max(pwon, 0.00001), 0.99999)
plost = 1.0 - pwon
return pwon, plost
def _cmpPlayingTime(self, store, iter1, iter2):
val1 = store.get_value(iter1, 4)
val2 = store.get_value(iter2, 4)
t1 = map(int, val1.split(':'))
t2 = map(int, val2.split(':'))
return cmp(len(t1), len(t2)) or cmp(t1, t2)
def _cmpMoves(self, store, iter1, iter2):
val1 = store.get_value(iter1, 5)
val2 = store.get_value(iter2, 5)
return cmp(float(val1), float(val2))
def _cmpPercent(self, store, iter1, iter2):
val1 = store.get_value(iter1, 6)
val2 = store.get_value(iter2, 6)
return cmp(float(val1), float(val2))
# /***********************************************************************
# //
# ************************************************************************/
SingleGame_StatsDialog = Game_StatsDialog
class AllGames_StatsDialog(MfxDialog):
pass
@ -56,8 +310,54 @@ class FullLog_StatsDialog(AllGames_StatsDialog):
class SessionLog_StatsDialog(FullLog_StatsDialog):
pass
class Status_StatsDialog(MfxDialog):
pass
# /***********************************************************************
# //
# ************************************************************************/
class Status_StatsDialog(MfxMessageDialog): #MfxDialog
def __init__(self, parent, game):
stats, gstats = game.stats, game.gstats
w1 = w2 = ''
n = 0
for s in game.s.foundations:
n = n + len(s.cards)
w1 = (_('Highlight piles: ') + str(stats.highlight_piles) + '\n' +
_('Highlight cards: ') + str(stats.highlight_cards) + '\n' +
_('Highlight same rank: ') + str(stats.highlight_samerank) + '\n')
if game.s.talon:
if game.gameinfo.redeals != 0:
w2 = w2 + _('\nRedeals: ') + str(game.s.talon.round - 1)
w2 = w2 + _('\nCards in Talon: ') + str(len(game.s.talon.cards))
if game.s.waste and game.s.waste not in game.s.foundations:
w2 = w2 + _('\nCards in Waste: ') + str(len(game.s.waste.cards))
if game.s.foundations:
w2 = w2 + _('\nCards in Foundations: ') + str(n)
#
date = time.strftime('%Y-%m-%d %H:%M', time.localtime(game.gstats.start_time))
MfxMessageDialog.__init__(self, parent, title=_('Game status'),
text=game.getTitleName() + '\n' +
game.getGameNumber(format=1) + '\n' +
_('Playing time: ') + game.getTime() + '\n' +
_('Started at: ') + date + '\n\n'+
_('Moves: ') + str(game.moves.index) + '\n' +
_('Undo moves: ') + str(stats.undo_moves) + '\n' +
_('Bookmark moves: ') + str(gstats.goto_bookmark_moves) + '\n' +
_('Demo moves: ') + str(stats.demo_moves) + '\n' +
_('Total player moves: ') + str(stats.player_moves) + '\n' +
_('Total moves in this game: ') + str(stats.total_moves) + '\n' +
_('Hints: ') + str(stats.hints) + '\n' +
'\n' +
w1 + w2,
strings=(_('&OK'),
(_('&Statistics...'), 101),
(TOP_TITLE+'...', 105), ),
image=game.app.gimages.logos[3],
image_side='left', image_padx=20,
padx=20,
)
class Top_StatsDialog(MfxDialog):
pass

View file

@ -58,8 +58,6 @@ def wm_set_icon(window, icon):
def makeToplevel(parent, title=None, class_=None, gtkclass=gtk.Window):
window = gtkclass()
##~ window.style = window.get_style().copy()
##~ window.set_style(window.style)
if not hasattr(window, 'table'):
window.table = gtk.Table(1, 4, False)
window.table.show()

View file

@ -51,8 +51,6 @@ from pysollib.mfxutil import kwdefault, KwStruct
class _MyDialog(gtk.Dialog):
def __init__(self):
gtk.Dialog.__init__(self)
##~ style = self.get_style().copy()
##~ self.set_style(style)
self.connect("destroy", self.quit)
self.connect("delete_event", self.quit)
@ -110,6 +108,7 @@ class MfxDialog(_MyDialog):
return self.createBox(widget_class=gtk.VBox)
def createTable(self):
# FIXME
return self.createBox(widget_class=gtk.Table)
def createBitmaps(self, box, kw):
@ -140,13 +139,17 @@ class MfxDialog(_MyDialog):
text = strings[i]
if not text:
continue
if isinstance(text, (list, tuple)):
text, index = text
else: # str
index = i
text = text.replace('&', '_')
b = gtk.Button(text)
b.set_property('can-default', True)
if i == default:
if index == default:
b.grab_focus()
#b.grab_default()
b.set_data("user_data", i)
b.set_data("user_data", index)
b.connect("clicked", self.done)
box.pack_start(b)
b.show()

View file

@ -109,12 +109,10 @@ class StringVar:
class _MfxToplevel(gtk.Window):
def __init__(self, *args, **kw):
gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL)
##~ self.style = self.get_style().copy()
##~ self.set_style(self.style)
#self.vbox = gtk.VBox()
#self.vbox.show()
#self.add(self.vbox)
self.table = gtk.Table(3, 5, False)
self.table = gtk.Table(3, 6, False)
self.add(self.table)
self.table.show()
self.realize()
@ -137,10 +135,6 @@ class _MfxToplevel(gtk.Window):
for k, v in kw.items():
if k in ("background", "bg"):
##print "Toplevel configure: bg"
##~ c = self.get_colormap().alloc_color(v)
##~ self.style.bg[gtk.STATE_NORMAL] = c
##~ self.set_style(self.style)
##~ self.queue_draw()
pass
elif k == "cursor":
self.setCursor(v)
@ -256,7 +250,9 @@ class _MfxToplevel(gtk.Window):
pass
def option_get(self, *args):
##print self, 'option_get'
if args and args[0] == 'font':
return self.get_style().font_desc.to_string()
print '_MfxToplevel: option_get', args
return None
def grid_columnconfigure(self, *args, **kw):

View file

@ -32,12 +32,10 @@
# imports
import os, re, sys
import gtk
TRUE, FALSE = True, False
from gtk import gdk
# PySol imports
from pysollib.actions import PysolToolbarActions
@ -54,9 +52,6 @@ class PysolToolbar(PysolToolbarActions):
self.dir = dir
self.side = -1
self.toolbar = gtk.Toolbar(gtk.ORIENTATION_HORIZONTAL,
gtk.TOOLBAR_ICONS)
ui_info = '''
<ui>
<toolbar name='toolbar'>
@ -82,15 +77,11 @@ class PysolToolbar(PysolToolbarActions):
ui_manager_id = ui_manager.add_ui_from_string(ui_info)
toolbar = ui_manager.get_widget("/toolbar")
self.toolbar = toolbar
toolbar.set_tooltips(True)
toolbar.set_style(gtk.TOOLBAR_ICONS)
toolbar.show()
top.table.attach(toolbar,
0, 1, 1, 2,
gtk.EXPAND | gtk.FILL, 0,
0, 0)
toolbar.show()
self._attached = False
#
@ -103,6 +94,11 @@ class PysolToolbar(PysolToolbarActions):
def destroy(self):
self.toolbar.destroy()
#
# public methods
#
def getSide(self):
return self.side
@ -110,24 +106,51 @@ class PysolToolbar(PysolToolbarActions):
return 0
def hide(self, resize=1):
self.show(None, resize)
self.show(0, resize)
def show(self, side=1, resize=1):
if self.side == side:
return 0
self.side = side
if side:
self.toolbar.show()
else:
if not side:
# hide
self.toolbar.hide()
return 1
# show
if side == 1:
# top
x, y = 1, 1
elif side == 2:
# bottom
x, y = 1, 3
elif side == 3:
# left
x, y = 0, 2
else:
# right
x, y = 2, 2
# set orient
if side in (1, 2):
orient = gtk.ORIENTATION_HORIZONTAL
else:
orient = gtk.ORIENTATION_VERTICAL
self.toolbar.set_orientation(orient)
if self._attached:
self.top.table.remove(self.toolbar)
row_span, column_span = 1, 1
self.top.table.attach(self.toolbar,
x, x+1, y, y+1,
gtk.FILL, gtk.FILL,
0, 0)
self.toolbar.show()
self._attached = True
return 1
#
# public methods
#
def setCursor(self, cursor):
if self.side:
# FIXME
pass
if self.toolbar.window:
self.toolbar.window.set_cursor(gdk.Cursor(v))
def setRelief(self, relief):
# FIXME

View file

@ -29,7 +29,7 @@ PACKAGE = "PySol"
PACKAGE_URL = "http://sourceforge.net/projects/pysolfc/"
TOOLKIT = 'gtk'
#TOOLKIT = 'tk'
TOOLKIT = 'tk'
# data dirs
DATA_DIRS = []

View file

@ -99,7 +99,7 @@ from util import Timer
from util import ACE, KING, SUITS
from util import ANY_SUIT, ANY_COLOR, ANY_RANK, NO_RANK
from util import NO_REDEAL, UNLIMITED_REDEALS, VARIABLE_REDEALS
from pysoltk import tkname, EVENT_HANDLED, EVENT_PROPAGATE
from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE
from pysoltk import CURSOR_DRAG, ANCHOR_NW, ANCHOR_SE
from pysoltk import bind, unbind_destroy
from pysoltk import after, after_idle, after_cancel
@ -887,7 +887,11 @@ class Stack:
self.cards[i].item.tkraise()
self.game.canvas.update_idletasks()
self.game.sleep(self.game.app.opt.raise_card_sleep)
self.cards[i].item.lower(self.cards[i+1].item)
if TOOLKIT == 'tk':
self.cards[i].item.lower(self.cards[i+1].item)
elif TOOLKIT == 'gtk':
for c in self.cards[i+1:]:
c.tkraise()
self.game.canvas.update_idletasks()
return 1
@ -1160,10 +1164,10 @@ class Stack:
if TOOLKIT == 'tk':
s1.lower(c.item)
s2.lower(c.item)
elif TOOLKIT == 'gtk':
positions = 2 ## FIXME
s1.lower(positions)
s2.lower(positions)
## elif TOOLKIT == 'gtk':
## positions = 2 ## FIXME
## s1.lower(positions)
## s2.lower(positions)
return (s1, s2)
return ()

View file

@ -1042,8 +1042,7 @@ class PysolMenubar(PysolMenubarActions):
def mOptNegativeBottom(self, *event):
if self._cancelDrag(): return
n = self.tkopt.negative_bottom.get()
self.app.opt.negative_bottom = n
self.app.opt.negative_bottom = self.tkopt.negative_bottom.get()
self.app.updateCardset()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)

View file

@ -33,8 +33,7 @@
##
##---------------------------------------------------------------------------##
__all__ = ['tkname',
'tkversion',
__all__ = ['tkversion',
'TK_DASH_PATCH',
'EVENT_HANDLED',
'EVENT_PROPAGATE',
@ -64,8 +63,6 @@ n_ = lambda x: x
# // constants
# ************************************************************************/
tkname = "tk"
# (major version, minor version, micro version, patchlevel)
tkversion = (8, 0, 0, 0)
try: