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, stats-dialog, colors-dialog, timeouts-dialog

git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@53 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
skomoroh 2006-08-21 21:17:19 +00:00
parent 7b0e4d33f9
commit dc038c8dc9
23 changed files with 1066 additions and 489 deletions

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PySol 0.0.1\n"
"POT-Creation-Date: Fri Aug 11 02:14:56 2006\n"
"PO-Revision-Date: 2006-08-11 02:13+0400\n"
"PO-Revision-Date: 2006-08-20 17:42+0400\n"
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
@ -2386,7 +2386,7 @@ msgstr "Разрешить показывать карты &одного дос
#: pysollib/tk/menubar.py:353
msgid "Highlight &no matching"
msgstr "Подсветка отсутствия &совпадения:"
msgstr "Подсветка отсутствия &совпадения"
#: pysollib/tk/menubar.py:355
msgid "&Show removed tiles (in Mahjongg games)"

View file

@ -378,12 +378,6 @@ class PysolMenubarActions:
self.game.endGame()
self.game.quitGame(id, random=random)
def mSelectGame(self, *args):
self._mSelectGame(self.tkopt.gameid.get())
def mSelectGamePopular(self, *args):
self._mSelectGame(self.tkopt.gameid_popular.get())
def _mNewGameBySeed(self, seed, origin):
try:
random = constructRandom(seed)
@ -762,19 +756,19 @@ class PysolMenubarActions:
def mHint(self, *args):
if self._cancelDrag(): return
if self.app.opt.hint:
if self.game.showHint(0, self.app.opt.hint_sleep):
if self.game.showHint(0, self.app.opt.timeouts['hint']):
self.game.stats.hints += 1
def mHint1(self, *args):
if self._cancelDrag(): return
if self.app.opt.hint:
if self.game.showHint(1, self.app.opt.hint_sleep):
if self.game.showHint(1, self.app.opt.timeouts['hint']):
self.game.stats.hints += 1
def mHighlightPiles(self, *args):
if self._cancelDrag(): return
if self.app.opt.highlight_piles:
if self.game.highlightPiles(self.app.opt.highlight_piles_sleep):
if self.game.highlightPiles(self.app.opt.timeouts['highlight_piles']):
self.game.stats.highlight_piles += 1
def mDemo(self, *args):
@ -787,7 +781,6 @@ class PysolMenubarActions:
self._mDemo(mixed=1)
def _mDemo(self, mixed):
if self._cancelDrag(): return
if self.changed():
# only ask if there have been no demo moves or hints yet
if self.game.stats.demo_moves == 0 and self.game.stats.hints == 0:
@ -814,134 +807,36 @@ class PysolMenubarActions:
self.game.updateStatus(player=self.app.opt.player)
self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id))
def mOptAutoFaceUp(self, *args):
if self._cancelDrag(): return
self.app.opt.autofaceup = self.tkopt.autofaceup.get()
if self.app.opt.autofaceup:
self.game.autoPlay()
def mOptAutoDrop(self, *args):
if self._cancelDrag(): return
self.app.opt.autodrop = self.tkopt.autodrop.get()
if self.app.opt.autodrop:
self.game.autoPlay()
def mOptAutoDeal(self, *args):
if self._cancelDrag(): return
self.app.opt.autodeal = self.tkopt.autodeal.get()
if self.app.opt.autodeal:
self.game.autoPlay()
def mOptQuickPlay(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.quickplay = self.tkopt.quickplay.get()
def mOptEnableUndo(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.undo = self.tkopt.undo.get()
self.game.updateMenus()
def mOptEnableBookmarks(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.bookmarks = self.tkopt.bookmarks.get()
self.game.updateMenus()
def mOptEnableHint(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.hint = self.tkopt.hint.get()
self.game.updateMenus()
def mOptEnableHighlightPiles(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_piles = self.tkopt.highlight_piles.get()
self.game.updateMenus()
def mOptEnableHighlightCards(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_cards = self.tkopt.highlight_cards.get()
self.game.updateMenus()
def mOptEnableHighlightSameRank(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_samerank = self.tkopt.highlight_samerank.get()
##self.game.updateMenus()
def mOptEnableHighlightNotMatching(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_not_matching = self.tkopt.highlight_not_matching.get()
##self.game.updateMenus()
def mOptShrinkFaceDown(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shrink_face_down = self.tkopt.shrink_face_down.get()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptShadeFilledStacks(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shade_filled_stacks = self.tkopt.shade_filled_stacks.get()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptMahjonggShowRemoved(self, *args):
if self._cancelDrag(): return
self.app.opt.mahjongg_show_removed = self.tkopt.mahjongg_show_removed.get()
##self.game.updateMenus()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptShisenShowHint(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shisen_show_hint = self.tkopt.shisen_show_hint.get()
##self.game.updateMenus()
## def mOptSound(self, *args):
## if self._cancelDrag(break_pause=False): return
## self.app.opt.sound = self.tkopt.sound.get()
## if not self.app.opt.sound:
## self.app.audio.stopAll()
def mOptSoundDialog(self, *args):
if self._cancelDrag(break_pause=False): return
d = SoundOptionsDialog(self.top, _("Sound settings"), self.app)
self.tkopt.sound.set(self.app.opt.sound)
def mOptAnimations(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.animations = self.tkopt.animations.get()
def mOptShadow(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shadow = self.tkopt.shadow.get()
def mOptShade(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shade = self.tkopt.shade.get()
## def mOptIrregularPiles(self, *args):
## if self._cancelDrag(): return
## self.app.opt.irregular_piles = self.tkopt.irregular_piles.get()
def mOptColorsOptions(self, *args):
def mOptColors(self, *args):
if self._cancelDrag(break_pause=False): return
d = ColorsDialog(self.top, _("Set colors"), self.app)
table_text_color = self.app.opt.table_text_color
table_text_color_value = self.app.opt.table_text_color_value
text_color = self.app.opt.colors['text']
use_default_text_color = self.app.opt.use_default_text_color
if d.status == 0 and d.button == 0:
self.app.opt.table_text_color = d.table_text_color
self.app.opt.table_text_color_value = d.table_text_color_value
##self.app.opt.table_color = d.table_color
self.app.opt.highlight_piles_colors = d.highlight_piles_colors
self.app.opt.highlight_cards_colors = d.highlight_cards_colors
self.app.opt.highlight_samerank_colors = d.highlight_samerank_colors
self.app.opt.hintarrow_color = d.hintarrow_color
self.app.opt.highlight_not_matching_color = d.highlight_not_matching_color
self.app.opt.use_default_text_color = d.use_default_color
self.app.opt.colors['text'] = d.text_color
self.app.opt.colors['piles'] = d.piles_color
self.app.opt.colors['cards_1'] = d.cards_1_color
self.app.opt.colors['cards_2'] = d.cards_2_color
self.app.opt.colors['samerank_1'] = d.samerank_1_color
self.app.opt.colors['samerank_2'] = d.samerank_2_color
self.app.opt.colors['hintarrow'] = d.hintarrow_color
self.app.opt.colors['not_matching'] = d.not_matching_color
#
if table_text_color != self.app.opt.table_text_color \
or table_text_color_value != self.app.opt.table_text_color_value:
if (text_color != self.app.opt.colors['text'] or
use_default_text_color != self.app.opt.use_default_text_color):
self.app.setTile(self.tkopt.tabletile.get(), 1)
def mOptFontsOptions(self, *args):
def mOptFonts(self, *args):
if self._cancelDrag(break_pause=False): return
d = FontsDialog(self.top, _("Set fonts"), self.app)
if d.status == 0 and d.button == 0:
@ -950,16 +845,16 @@ class PysolMenubarActions:
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptTimeoutsOptions(self, *args):
def mOptTimeouts(self, *args):
if self._cancelDrag(break_pause=False): return
d = TimeoutsDialog(self.top, _("Set timeouts"), self.app)
if d.status == 0 and d.button == 0:
self.app.opt.demo_sleep = d.demo_sleep
self.app.opt.hint_sleep = d.hint_sleep
self.app.opt.raise_card_sleep = d.raise_card_sleep
self.app.opt.highlight_piles_sleep = d.highlight_piles_sleep
self.app.opt.highlight_cards_sleep = d.highlight_cards_sleep
self.app.opt.highlight_samerank_sleep = d.highlight_samerank_sleep
self.app.opt.timeouts['demo'] = d.demo_timeout
self.app.opt.timeouts['hint'] = d.hint_timeout
self.app.opt.timeouts['raise_card'] = d.raise_card_timeout
self.app.opt.timeouts['highlight_piles'] = d.highlight_piles_timeout
self.app.opt.timeouts['highlight_cards'] = d.highlight_cards_timeout
self.app.opt.timeouts['highlight_samerank'] = d.highlight_samerank_timeout
## def mOptSave(self, *args):
## if self._cancelDrag(break_pause=False): return

View file

@ -167,21 +167,27 @@ class Options:
self.fonts["sans"] = ("times new roman", 12)
self.fonts["fixed"] = ("courier new", 10)
# colors
self.table_color = "#008200"
self.highlight_piles_colors = (None, "#ffc000")
self.highlight_cards_colors = (None, "#ffc000", None, "#0000ff")
self.highlight_samerank_colors = (None, "#ffc000", None, "#0000ff")
self.hintarrow_color = "#303030"
self.highlight_not_matching_color = '#ff0000'
self.table_text_color = False # `False' is mean use default
self.table_text_color_value = '#ffffff'
self.colors = {
'table': '#008200',
'text': '#ffffff',
'piles': '#ffc000',
'cards_1': '#ffc000',
'cards_2': '#0000ff',
'samerank_1': '#ffc000',
'samerank_2': '#0000ff',
'hintarrow': '#303030',
'not_matching': '#ff0000',
}
self.use_default_text_color = True
# delays
self.hint_sleep = 1.0
self.demo_sleep = 1.0
self.raise_card_sleep = 1.0
self.highlight_piles_sleep = 1.0
self.highlight_cards_sleep = 1.0
self.highlight_samerank_sleep = 1.0
self.timeouts = {
'hint': 1.0,
'demo': 1.0,
'raise_card': 1.0,
'highlight_piles': 1.0,
'highlight_cards': 1.0,
'highlight_samerank': 1.0,
}
# additional startup information
self.num_recent_games = 15
self.recent_gameid = []
@ -935,7 +941,7 @@ class Application:
if self.scrolled_canvas.setTile(self, i, force):
tile = self.tabletile_manager.get(i)
if i == 0:
self.opt.table_color = tile.color
self.opt.colors['table'] = tile.color
self.opt.tabletile_name = None
else:
self.opt.tabletile_name = tile.basename
@ -1005,7 +1011,7 @@ class Application:
self.wm_save_state()
self.wm_withdraw()
title = _("Loading %s %s...") % (CARDSET, cs.name)
color = self.opt.table_color
color = self.opt.colors['table']
if self.tabletile_index > 0:
color = "#008200"
progress = PysolProgressBar(self, self.top, title=title,

View file

@ -1470,7 +1470,7 @@ for %d moves.
def highlightCard(self, suit, rank):
if not self.app:
return None
col = self.app.opt.highlight_samerank_colors[1]
col = self.app.opt.colors['samerank_1']
info = []
for s in self.allstacks:
for c in s.cards:
@ -1546,10 +1546,19 @@ for %d moves.
y2 = y2 + self.app.images.CARDH
tkraise = True
##print c1, c2, x1, y1, x2, y2
r = MfxCanvasRectangle(self.canvas, x1-1, y1-1, x2+1, y2+1,
width=4, fill=None, outline=color)
if tkraise:
r.tkraise(c2.item)
if TOOLKIT == 'tk':
r = MfxCanvasRectangle(self.canvas, x1-1, y1-1, x2+1, y2+1,
width=4, fill=None, outline=color)
if tkraise:
r.tkraise(c2.item)
elif TOOLKIT == 'gtk':
r = MfxCanvasRectangle(self.canvas, x1-1, y1-1, x2+1, y2+1,
width=4, fill=None, outline=color,
group=s.group)
if tkraise:
i = s.cards.index(c2)
for c in s.cards[i+1:]:
c.tkraise(1)
items.append(r)
if not items:
return 0
@ -1575,14 +1584,14 @@ for %d moves.
y = int(int(self.canvas.cget('height'))*(self.canvas.yview()[0]))
w, h = self.canvas.winfo_width(), self.canvas.winfo_height()
#
color = self.app.opt.highlight_not_matching_color
color = self.app.opt.colors['not_matching']
width = 6
x0, y0 = x+width/2-self.canvas.xmargin, y+width/2-self.canvas.ymargin
x1, y1 = x+w-width-self.canvas.xmargin, y+h-width-self.canvas.ymargin
r = MfxCanvasRectangle(self.canvas, x0, y0, x1, y1,
width=width, fill=None, outline=color)
self.canvas.update_idletasks()
self.sleep(self.app.opt.highlight_cards_sleep)
self.sleep(self.app.opt.timeouts['highlight_cards'])
r.delete()
self.canvas.update_idletasks()
@ -1591,7 +1600,7 @@ for %d moves.
if not stackinfo:
self.highlightNotMatching()
return 0
col = self.app.opt.highlight_piles_colors
col = self.app.opt.colors['piles']
hi = []
for si in stackinfo:
for s in si[0]:
@ -1771,7 +1780,7 @@ for %d moves.
y2 = y2 + images.CARDH / 2
# draw the hint
arrow = MfxCanvasLine(self.canvas, x1, y1, x2, y2, width=7,
fill=self.app.opt.hintarrow_color,
fill=self.app.opt.colors['hintarrow'],
arrow="last", arrowshape=(30,30,10))
self.canvas.update_idletasks()
# wait
@ -1794,7 +1803,7 @@ for %d moves.
self.demo = Struct(
level = level,
mixed = mixed,
sleep = self.app.opt.demo_sleep,
sleep = self.app.opt.timeouts['demo'],
last_deal = [],
hint = None,
keypress = None,
@ -1979,8 +1988,9 @@ for %d moves.
ta = self.getDemoInfoTextAttr(tinfo)
if ta:
font = self.app.getFont("canvas_large")
self.demo.info_text = MfxCanvasText(self.canvas, ta[1], ta[2], anchor=ta[0],
font=font, text=self.getDemoInfoText())
self.demo.info_text = MfxCanvasText(self.canvas, ta[1], ta[2],
anchor=ta[0], font=font,
text=self.getDemoInfoText())
def getDemoInfoText(self):
return self.gameinfo.short_name

View file

@ -228,7 +228,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
game.updateStackMove(game.s.talon, 2|16) # for undo
if not game.demo:
if game.app.opt.shisen_show_hint:
self.drawArrow(other_stack, game.app.opt.hint_sleep)
self.drawArrow(other_stack, game.app.opt.timeouts['hint'])
game.playSample("droppair", priority=200)
#
game.moveMove(n, self, f, frames=frames, shadow=shadow)
@ -275,7 +275,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
arrow = MfxCanvasLine(game.canvas,
coords,
{'width': w,
'fill': game.app.opt.hintarrow_color,
'fill': game.app.opt.colors['hintarrow'],
##'arrow': 'last',
##'arrowshape': (s1, s1, s2)
}

View file

@ -374,7 +374,7 @@ Please check your %s installation.
# init tiles
manager = app.tabletile_manager
tile = Tile()
tile.color = app.opt.table_color
tile.color = app.opt.colors['table']
tile.name = "None"
tile.filename = None
manager.register(tile)
@ -449,7 +449,7 @@ Sounds and background music will be disabled.'''),
# create the progress bar
title = _("Welcome to ") + PACKAGE
color = app.opt.table_color
color = app.opt.colors['table']
if app.tabletile_index > 0:
color = "#008200"
app.intro.progress = PysolProgressBar(app, top, title=title, color=color,

View file

@ -21,25 +21,115 @@
__all__ = ['ColorsDialog']
## # imports
# imports
## import os, sys
## import Tkinter
## from tkColorChooser import askcolor
import gtk, gobject, pango
import gtk.glade
from gtk import gdk
## # PySol imports
## from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct
# PySol imports
## # Toolkit imports
## from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
# Toolkit imports
from tkwidget import MfxDialog
gettext = _
# /***********************************************************************
# //
# ************************************************************************/
class ColorsDialog(MfxDialog):
pass
class ColorsDialog:
## self.app.opt.table_text_color = d.table_text_color
## self.app.opt.table_text_color_value = d.table_text_color_value
## ##self.app.opt.table_color = d.table_color
## self.app.opt.highlight_piles_colors = d.highlight_piles_colors
## self.app.opt.highlight_cards_colors = d.highlight_cards_colors
## self.app.opt.highlight_samerank_colors = d.highlight_samerank_colors
## self.app.opt.hintarrow_color = d.hintarrow_color
## self.app.opt.highlight_not_matching_color = d.highlight_not_matching_color
def __init__(self, parent, title, app, **kw):
glade_file = app.dataloader.findFile('pysolfc.glade')
self.widgets_tree = gtk.glade.XML(glade_file)
keys = (
'text',
'piles',
'cards_1',
'cards_2',
'samerank_1',
'samerank_2',
'hintarrow',
'not_matching',
)
for n in keys:
label = self.widgets_tree.get_widget(n+'_label')
self._setColor(label, app.opt.colors[n])
button = self.widgets_tree.get_widget(n+'_button')
button.connect('clicked', self._changeColor, n, label)
checkbutton = self.widgets_tree.get_widget('use_default_checkbutton')
checkbutton.set_active(not app.opt.use_default_text_color)
self._translateLabels()
dialog = self.widgets_tree.get_widget('colors_dialog')
self.dialog = dialog
dialog.set_title(title)
dialog.set_transient_for(parent)
dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.status = -1
self.button = -1
response = dialog.run()
if response == gtk.RESPONSE_OK:
self.status = 0
self.button = 0
for n in keys:
w = self.widgets_tree.get_widget(n+'_label')
c = w.get_data('user_data')
setattr(self, n+'_color', c)
self.use_default_color = not checkbutton.get_active()
dialog.destroy()
def _setColor(self, label, color):
c = gdk.color_parse(color)
al = pango.AttrList()
al.insert(pango.AttrBackground(c.red, c.green, c.blue, 0, 10))
label.set_attributes(al)
label.set_data('user_data', color)
def _changeColor(self, w, name, label):
print '_changeColor', name
color = label.get_data('user_data')
dialog = gtk.ColorSelectionDialog(_('Select color'))
dialog.help_button.destroy()
dialog.set_transient_for(self.dialog)
dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
dialog.colorsel.set_current_color(gdk.color_parse(color))
response = dialog.run()
if response == gtk.RESPONSE_OK:
c = dialog.colorsel.get_current_color()
c = '#%02x%02x%02x' % (c.red/256, c.green/256, c.blue/256)
self._setColor(label, c)
dialog.destroy()
def _translateLabels(self):
for n in (
'label31',
'label32',
'label33',
'label34',
'label35',
'label36',
'label37',
):
w = self.widgets_tree.get_widget(n)
w.set_text(gettext(w.get_text()))

View file

@ -21,28 +21,29 @@
__all__ = ['FontsDialog']
## # imports
# imports
## import os, sys
## import types
## import Tkinter
## import tkFont
import gtk, gobject, pango
import gtk.glade
## # PySol imports
# PySol imports
## from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct
## # Toolkit imports
# Toolkit imports
## from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
## from tkutil import bind
from tkwidget import MfxDialog
# /***********************************************************************
# //
# ************************************************************************/
class FontsDialog(MfxDialog):
pass
class FontsDialog:
def __init__(self, parent, title, app, **kw):
pass

View file

@ -51,7 +51,6 @@ from selectgame import SelectGameDialogWithPreview
gettext = _
def ltk2gtk(s):
# label tk to gtk
return gettext(s).replace('&', '_')
@ -67,6 +66,7 @@ class PysolMenubar(PysolMenubarActions):
def __init__(self, app, top, progress=None):
PysolMenubarActions.__init__(self, app, top)
self.progress = progress
self._cb_max = gdk.screen_height()/24
# create menus
menubar = self.createMenubar()
self.top.table.attach(menubar,
@ -89,10 +89,10 @@ class PysolMenubar(PysolMenubarActions):
entries = (
### toolbar
('newgame', gtk.STOCK_NEW,
ltk2gtk('&New game'), 'N',
ltk2gtk('New game'),
self.mNewGame),
('newgame', gtk.STOCK_NEW, # action name, stock
ltk2gtk('&New game'), 'N', # label, accelerator
ltk2gtk('New game'), # tooltip
self.mNewGame), # callback
('open', gtk.STOCK_OPEN,
ltk2gtk('&Open...'), '<control>O',
ltk2gtk('Open a\nsaved game'),
@ -118,11 +118,11 @@ class PysolMenubar(PysolMenubarActions):
ltk2gtk('Auto drop'),
self.mDrop),
('stats', gtk.STOCK_INDEX,
ltk2gtk('Stats'), None,
ltk2gtk('&Statistics'), None,
ltk2gtk('Statistics'),
lambda w, self=self: self.mPlayerStats(mode=101)),
('rules', gtk.STOCK_HELP,
ltk2gtk('Rules'), 'F1',
ltk2gtk('&Rules'), 'F1',
ltk2gtk('Rules'),
self.mHelpRules),
('quit', gtk.STOCK_QUIT,
@ -131,19 +131,21 @@ class PysolMenubar(PysolMenubarActions):
self.mQuit),
### menus
('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')),
('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')),
('file', None, ltk2gtk('&File')),
('recentgames', None, ltk2gtk('R&ecent games')),
('favoritegames', None, ltk2gtk('Fa&vorite games')),
('select', None, ltk2gtk('&Select')),
('edit', None, ltk2gtk('&Edit')),
('game', None, ltk2gtk('&Game')),
('assist', None, ltk2gtk('&Assist')),
('options', None, ltk2gtk('&Options')),
('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
('playablepreview', None,
@ -152,6 +154,12 @@ class PysolMenubar(PysolMenubarActions):
('selectgamebynumber', None,
ltk2gtk('Select game by nu&mber...'), None,
None, self.mSelectGameById),
('addtofavorites', None,
ltk2gtk('A&dd to favorites'), None,
None, self.mAddFavor),
('removefromfavorites', None,
ltk2gtk('R&emove from favorites'), None,
None, self.mDelFavor),
('saveas', None,
ltk2gtk('Save &as...'), None,
None, self.mSaveAs),
@ -188,6 +196,12 @@ class PysolMenubar(PysolMenubarActions):
('cardset', None,
ltk2gtk('Cards&et...'), '<control>E',
None, self.mSelectCardsetDialog),
('timeouts', None,
ltk2gtk('Time&outs...'), None,
None, self.mOptTimeouts),
('colors', None,
ltk2gtk('&Colors...'), None,
None, self.mOptColors),
('contents', None,
ltk2gtk('&Contents'), '<control>F1',
None, self.mHelp),
@ -274,8 +288,10 @@ class PysolMenubar(PysolMenubarActions):
<menu action='file'>
<menuitem action='newgame'/>
<menuitem action='selectgamebynumber'/>
<menuitem action='playablepreview'/>
<menu action='selectgame'/>
<menu action='recentgames'/>
<menu action='favoritegames'/>
<menuitem action='addtofavorites'/>
<menuitem action='removefromfavorites'/>
<separator/>
<menuitem action='open'/>
<menuitem action='save'/>
@ -283,6 +299,12 @@ class PysolMenubar(PysolMenubarActions):
<separator/>
<menuitem action='holdandquit'/>
<menuitem action='quit'/>
<menuitem action='quit'/>
</menu>
<menu action='select'>
<menuitem action='playablepreview'/>
<separator/>
</menu>
<menu action='edit'>
@ -353,6 +375,9 @@ class PysolMenubar(PysolMenubarActions):
</menu>
<menuitem action='stickymouse'/>
<separator/>
<menuitem action='colors'/>
<menuitem action='timeouts'/>
<separator/>
<menuitem action='demologo'/>
<menuitem action='startupsplashscreen'/>
<menu action='toolbar'>
@ -394,19 +419,28 @@ class PysolMenubar(PysolMenubarActions):
ui_manager.insert_action_group(action_group, 0)
self.top.add_accel_group(ui_manager.get_accel_group())
self.top.ui_manager = ui_manager
menubar = ui_manager.get_widget('/menubar')
#ui_manager.get_widget('/menubar/file/recentgames').show()
#ui_manager.get_widget('/menubar/file/favoritegames').show()
games = map(self.app.gdb.get, self.app.gdb.getGamesIdSortedByName())
menu = ui_manager.get_widget('/menubar/select').get_submenu()
self._createSelectMenu(games, menu)
menu_item = ui_manager.get_widget('/menubar/file/selectgame')
menu_item.show()
menu = gtk.Menu()
menu_item.set_submenu(menu)
self._addSelectAllGameSubMenu(games, menu, self.mSelectGame)
menubar = ui_manager.get_widget('/menubar')
return menubar
#
# Select Game menu creation
#
def _getNumGames(self, games, select_data):
ngames = 0
for label, select_func in select_data:
ngames += len(filter(select_func, games))
return ngames
def _createSubMenu(self, menu, label):
menu_item = gtk.MenuItem(label)
menu.add(menu_item)
@ -415,21 +449,26 @@ class PysolMenubar(PysolMenubarActions):
menu_item.set_submenu(submenu)
return submenu
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)
menu_item.show()
menu_item.connect('toggled', command, g.id)
def _addGamesMenuItem(self, menu, gi, short_name=False):
if short_name:
label = gi.short_name
else:
label = gi.name
label = gettext(label)
menu_item = gtk.MenuItem(label)
menu_item.set_data('user_data', gi.id)
menu_item.connect('activate', self.mSelectGame)
menu.add(menu_item)
menu_item.show()
def _addSelectAllGameSubMenu(self, games, menu, command):
cb_max = gdk.screen_height()/24
n, d = 0, cb_max
def _addGamesSubMenu(self, games, menu, short_name=False):
for gi in games:
self._addGamesMenuItem(menu, gi, short_name=short_name)
def _addAllGamesMenu(self, games, menu):
menu = self._createSubMenu(menu, label=ltk2gtk('&All games by name'))
n, d = 0, self._cb_max
i = 0
group = None
while True:
if self.progress: self.progress.update(step=1)
i += 1
@ -440,16 +479,88 @@ class PysolMenubar(PysolMenubarActions):
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)
self._addGamesSubMenu(games[n:n+d], submenu)
n += d
def _addSelectedGamesSubMenu(self, games, menu, select_data):
for label, select_func in select_data:
g = filter(select_func, games)
if not g:
continue
submenu = self._createSubMenu(menu, label=label)
self._addGamesSubMenu(g, submenu)
def _addPopularGamesMenu(self, games, menu):
select_func = lambda gi: gi.si.game_flags & GI.GT_POPULAR
if len(filter(select_func, games)) == 0:
return
data = (ltk2gtk('&Popular games'), select_func)
self._addSelectedGamesSubMenu(games, menu, (data, ))
def _addGamesByType(self, games, menu, label, data):
if self._getNumGames(games, data) == 0:
return
submenu = self._createSubMenu(menu, label=label)
self._addSelectedGamesSubMenu(games, submenu, data)
def _addMahjonggGamesMenu(self, games, menu):
select_func = lambda gi: gi.si.game_type == GI.GT_MAHJONGG
mahjongg_games = filter(select_func, games)
if len(mahjongg_games) == 0:
return
menu = self._createSubMenu(menu, label=ltk2gtk('&Mahjongg games'))
#
def add_menu(games, c0, c1, menu=menu):
if not games:
return
label = c0 + ' - ' + c1
if c0 == c1:
label = c0
submenu = self._createSubMenu(menu, label=label)
self._addGamesSubMenu(games, submenu, short_name=True)
#
games = {}
for gi in mahjongg_games:
c = gettext(gi.short_name).strip()[0]
if games.has_key(c):
games[c].append(gi)
else:
games[c] = [gi]
games = games.items()
games.sort()
#
g0 = []
c0 = c1 = games[0][0]
for c, g1 in games:
if len(g0)+len(g1) >= self._cb_max:
add_menu(g0, c0, c1)
g0 = g1
c0 = c1 = c
else:
g0 += g1
c1 = c
add_menu(g0, c0, c1)
def _createSelectMenu(self, games, menu):
assert isinstance(menu, gtk.Menu)
self._addPopularGamesMenu(games, menu)
for l, d in (
(ltk2gtk('&French games'), GI.SELECT_GAME_BY_TYPE),
(ltk2gtk('&Oriental games'), GI.SELECT_ORIENTAL_GAME_BY_TYPE),
(ltk2gtk('&Special games'), GI.SELECT_SPECIAL_GAME_BY_TYPE),
):
self._addGamesByType(games, menu, l, d)
self._addMahjonggGamesMenu(games, menu)
sep = gtk.SeparatorMenuItem()
menu.add(sep)
self._addAllGamesMenu(games, menu)
#
# menu updates
#
## WARNING: setMenuState: not found: /menubar/file/holdandquit
## WARNING: setMenuState: not found: /menubar/assist/findcard
def setMenuState(self, state, path):
path_map = {
@ -467,7 +578,6 @@ class PysolMenubar(PysolMenubarActions):
menuitem.set_sensitive(state)
def setToolbarState(self, state, path):
path = '/toolbar/'+path
button = self.top.ui_manager.get_widget(path)
@ -481,9 +591,59 @@ class PysolMenubar(PysolMenubarActions):
# menu actions
#
def _createFileChooser(self, title, action, idir, ifile):
def mAddFavor(self, w):
gameid = self.app.game.id
if gameid not in self.app.opt.favorite_gameid:
self.app.opt.favorite_gameid.append(gameid)
self.updateFavoriteGamesMenu()
def mDelFavor(self, w):
gameid = self.app.game.id
if gameid in self.app.opt.favorite_gameid:
self.app.opt.favorite_gameid.remove(gameid)
self.updateFavoriteGamesMenu()
def updateFavoriteGamesMenu(self):
games = self.app.opt.favorite_gameid
self._updateGamesMenu('/menubar/file/favoritegames', games)
in_favor = self.app.game.id in games
item = self.top.ui_manager.get_widget('/menubar/file/addtofavorites')
item.set_sensitive(not in_favor)
item = self.top.ui_manager.get_widget('/menubar/file/removefromfavorites')
item.set_sensitive(in_favor)
def updateRecentGamesMenu(self, games):
self._updateGamesMenu('/menubar/file/recentgames', games)
def _updateGamesMenu(self, path, games):
item = self.top.ui_manager.get_widget(path)
item.show()
menu = item.get_submenu()
menu.show()
#
menu_games = []
def checkFavor(item):
gameid = item.get_data('user_data')
if gameid in games:
menu_games.append(gameid)
else:
menu.remove(item)
menu.foreach(checkFavor)
#
for gameid in games:
if gameid not in menu_games:
gi = self.app.getGameInfo(gameid)
self._addGamesMenuItem(menu, gi)
if not games:
item = gtk.MenuItem(_('Empty'))
item.show()
item.set_sensitive(False)
menu.add(item)
def _createFileChooser(self, title, action, idir, ifile, stock):
d = gtk.FileChooserDialog(title, self.top, action,
(gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT,
(stock, gtk.RESPONSE_ACCEPT,
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
d.set_current_folder(idir)
if ifile:
@ -519,7 +679,8 @@ class PysolMenubar(PysolMenubarActions):
idir = self.app.dn.savegames
filename = self._createFileChooser(_('Open Game'),
gtk.FILE_CHOOSER_ACTION_OPEN,
idir, '')
idir, '',
gtk.STOCK_OPEN)
if filename:
##filename = os.path.normpath(filename)
##filename = os.path.normcase(filename)
@ -547,7 +708,8 @@ class PysolMenubar(PysolMenubarActions):
##print self.game.filename, ifile
filename = self._createFileChooser(_('Save Game'),
gtk.FILE_CHOOSER_ACTION_SAVE,
idir, ifile)
idir, ifile,
gtk.STOCK_SAVE)
if filename:
##filename = os.path.normpath(filename)
##filename = os.path.normcase(filename)
@ -555,14 +717,10 @@ class PysolMenubar(PysolMenubarActions):
self.updateMenus()
def mSelectGame(self, menu_item):
game_id = menu_item.get_data('user_data')
self._mSelectGame(game_id)
def updateFavoriteGamesMenu(self, *args):
pass
def mSelectGame(self, menu_item, game_id):
if menu_item.get_active():
self._mSelectGame(game_id)
def mSelectGameDialogWithPreview(self, *event):
if self._cancelDrag(break_pause=False): return
@ -593,7 +751,7 @@ class PysolMenubar(PysolMenubarActions):
if self._cancelDrag(break_pause=False): return
key = self.app.tabletile_index
if key <= 0:
key = self.app.opt.table_color.lower()
key = self.app.opt.colors['table']
d = SelectTileDialogWithPreview(self.top, app=self.app,
title=_('Select table background'),
manager=self.app.tabletile_manager,

View file

@ -54,7 +54,7 @@ class SelectTileDialogWithPreview(MfxDialog):
self.key = key
self.preview_key = -1
self.all_keys = []
self.table_color = app.opt.table_color
self.table_color = app.opt.colors['table']
# paned
hpaned = gtk.HPaned()
self.hpaned = hpaned
@ -150,7 +150,7 @@ class SelectTileDialogWithPreview(MfxDialog):
canvas.setBackgroundImage(None)
canvas.setTextColor(None)
self.preview_key = key
self.table_color = key
self.colors['table'] = key
else:
# image
tile = self.manager.get(key)
@ -186,7 +186,7 @@ class SelectTileDialogWithPreview(MfxDialog):
if type(self.preview_key) is str:
color = self.preview_key
else:
color = self.app.opt.table_color
color = self.app.opt.colors['table']
win.colorsel.set_current_color(gdk.color_parse(color))
win.connect('delete_event', lambda w, e: win.destroy())
win.ok_button.connect('clicked', self._colorselOkClicked, win)

View file

@ -21,22 +21,87 @@
__all__ = ['TimeoutsDialog']
## # imports
# imports
## import os, sys
## import Tkinter
import gtk, gobject, pango
import gtk.glade
## # PySol imports
## from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct
# PySol imports
## # Toolkit imports
## from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
# Toolkit imports
from tkwidget import MfxDialog
gettext = _
# /***********************************************************************
# //
# ************************************************************************/
class TimeoutsDialog(MfxDialog):
pass
class TimeoutsDialog:
def __init__(self, parent, title, app, **kw):
glade_file = app.dataloader.findFile('pysolfc.glade')
self.widgets_tree = gtk.glade.XML(glade_file)
keys = (
'demo',
'hint',
'raise_card',
'highlight_piles',
'highlight_cards',
'highlight_samerank',
)
dic = {}
for n in keys:
def callback(w, n=n):
sp = self.widgets_tree.get_widget(n+'_spinbutton')
sc = self.widgets_tree.get_widget(n+'_scale')
sp.set_value(sc.get_value())
dic[n+'_scale_value_changed'] = callback
def callback(w, n=n):
sp = self.widgets_tree.get_widget(n+'_spinbutton')
sc = self.widgets_tree.get_widget(n+'_scale')
sc.set_value(sp.get_value())
dic[n+'_spinbutton_value_changed'] = callback
self.widgets_tree.signal_autoconnect(dic)
for n in keys:
v = app.opt.timeouts[n]
w = self.widgets_tree.get_widget(n+'_spinbutton')
w.set_value(v)
w = self.widgets_tree.get_widget(n+'_scale')
w.set_value(v)
self._translateLabels()
dialog = self.widgets_tree.get_widget('timeouts_dialog')
dialog.set_title(title)
dialog.set_transient_for(parent)
dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.status = -1
self.button = -1
response = dialog.run()
if response == gtk.RESPONSE_OK:
self.status = 0
self.button = 0
for n in keys:
w = self.widgets_tree.get_widget(n+'_spinbutton')
setattr(self, n+'_timeout', w.get_value())
dialog.destroy()
def _translateLabels(self):
for n in (
'label25',
'label26',
'label27',
'label28',
'label29',
'label30',
):
w = self.widgets_tree.get_widget(n)
w.set_text(gettext(w.get_text()))

View file

@ -77,11 +77,16 @@ class _CanvasItem:
self.canvas = canvas
canvas._all_items.append(self)
self._is_hidden = False
self._x, self._y = 0, 0
self._group = None
def addtag(self, group):
##print self, 'addtag'
##~ assert isinstance(group._item, CanvasGroup)
self._item.reparent(group._item)
if self._group == group:
print 'addtag: new_group == old_group'
self._group = group
def dtag(self, group):
##print self, 'dtag'
@ -102,11 +107,14 @@ class _CanvasItem:
self._item = None
def lower(self, positions=None):
return # used for reordered shadow; don't need?
print 'lower', self, positions
return # don't need?
## if positions is None:
## self._item.lower_to_bottom()
## self._item.get_property('parent').raise_to_top()
## pass
## ##self._item.lower_to_bottom()
## ##self._item.get_property('parent').lower_to_bottom()
## else:
## print self, positions
## ##~ assert type(positions) is types.IntType and positions > 0
## self._item.lower(positions)
@ -116,13 +124,18 @@ class _CanvasItem:
self._item.raise_to_top()
self._item.get_property('parent').raise_to_top()
else:
print self, 'tkraise', positions # don't used?
#print self, 'tkraise', positions
#self._item.raise_to_top()
##~ assert type(positions) is types.IntType and positions > 0
self._item.raise_(positions)
self._item.raise_to_top() #positions)
def move(self, x, y):
self._item.move(x, y)
moveTo = move
self._x, self._y = self._x+x, self._y+y
def moveTo(self, x, y):
self._item.move(x-self._x, y-self._y)
self._x, self._y = x, y
def show(self):
if self._item:
@ -146,16 +159,22 @@ class MfxCanvasGroup(_CanvasItem):
class MfxCanvasImage(_CanvasItem):
def __init__(self, canvas, x, y, image, anchor=gtk.ANCHOR_NW):
def __init__(self, canvas, x, y, image, anchor=gtk.ANCHOR_NW, group=None):
_CanvasItem.__init__(self, canvas)
self._x, self._y = x, y
if type(anchor) is str:
anchor = anchor_tk2gtk(anchor)
self._item = canvas.root().add(gnome.canvas.CanvasPixbuf,
x=x, y=y,
pixbuf=image.pixbuf,
width=image.width(),
height=image.height(),
anchor=anchor)
if group:
self._group = group
group = group._item
else:
group = canvas.root()
self._item = group.add(gnome.canvas.CanvasPixbuf,
x=x, y=y,
pixbuf=image.pixbuf,
width=image.width(),
height=image.height(),
anchor=anchor)
self._item.show()
def config(self, image):
@ -183,35 +202,52 @@ class MfxCanvasLine(_CanvasItem):
kwargs['arrow_shape_a'] = kw['arrowshape'][0]
kwargs['arrow_shape_b'] = kw['arrowshape'][1]
kwargs['arrow_shape_c'] = kw['arrowshape'][2]
self._item = canvas.root().add(gnome.canvas.CanvasLine,
points=points, **kwargs)
if kw.has_key('group'):
self._group = kw['group']
group = kw['group']._item
else:
group = canvas.root()
self._item = group.add(gnome.canvas.CanvasLine,
points=points, **kwargs)
self._item.show()
#canvas.show_all()
class MfxCanvasRectangle(_CanvasItem):
def __init__(self, canvas, x1, y1, x2, y2,
width=0, fill=None, outline=None):
width=0, fill=None, outline=None, group=None):
_CanvasItem.__init__(self, canvas)
self._x, self._y = x1, y1
kw = {'x1': x1, 'x2': x2, 'y1': y1, 'y2': y2}
if width: kw['width_pixels'] = width
if fill: kw['fill_color'] = fill
if outline: kw['outline_color'] = outline
self._item = canvas.root().add(gnome.canvas.CanvasRect, **kw)
if group:
self._group = group
group = group._item
else:
group = canvas.root()
self._item = group.add(gnome.canvas.CanvasRect, **kw)
self._item.show()
class MfxCanvasText(_CanvasItem):
def __init__(self, canvas, x, y, anchor=gtk.ANCHOR_NW, preview=-1, **kw):
_CanvasItem.__init__(self, canvas)
self._x, self._y = x, y
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,
x=x, y=y, anchor=anchor)
if kw.has_key('group'):
self._group = kw['group']
group = kw['group']._item
del kw['group']
else:
group = canvas.root()
self._item = group.add(gnome.canvas.CanvasText,
x=x, y=y, anchor=anchor)
if not kw.has_key('fill'):
kw['fill'] = canvas._text_color
for k, v in kw.items():
@ -236,7 +272,6 @@ class MfxCanvasText(_CanvasItem):
def __getitem__(self, key):
if key == 'text':
# FIXME
return self._item.get_property('text')
else:
raise AttributeError, key
@ -295,7 +330,7 @@ class MfxCanvas(gnome.canvas.Canvas):
def bind(self, sequence=None, func=None, add=None):
assert add is None
# FIXME
print "TkCanvas bind:", sequence
print 'TkCanvas bind:', sequence
return
def cget(self, attr):
@ -307,7 +342,7 @@ class MfxCanvas(gnome.canvas.Canvas):
return self.get_size()[0]
elif attr == 'height':
return self.get_size()[1]
print "TkCanvas cget:", attr
print 'TkCanvas cget:', attr
raise AttributeError, attr
def xview(self):
@ -327,20 +362,20 @@ class MfxCanvas(gnome.canvas.Canvas):
def configure(self, **kw):
height, width = -1, -1
for k, v in kw.items():
if k in ("background", "bg"):
if k in ('background', 'bg'):
##print 'configure: bg:', v
c = self.get_colormap().alloc_color(v)
self.style.bg[gtk.STATE_NORMAL] = c
elif k == "cursor":
elif k == 'cursor':
if not self.window:
self.realize()
self.window.set_cursor(gdk.Cursor(v))
elif k == "height":
elif k == 'height':
height = v
elif k == "width":
elif k == 'width':
width = v
else:
print "TkCanvas", k, v
print 'TkCanvas', k, v
raise AttributeError, k
if height > 0 and width > 0:
self.set_size_request(width, height)
@ -386,7 +421,7 @@ class MfxCanvas(gnome.canvas.Canvas):
if self._text_color != color:
self._text_color = color
for item in self._text_items:
item.set(fill_color=_self.text_color)
item._item.set(fill_color=self._text_color)
# PySol extension - set a tiled background image
def setTile(self, app, i, force=False):
@ -402,7 +437,8 @@ class MfxCanvas(gnome.canvas.Canvas):
assert tile.filename
assert tile.basename
if not force:
if i == app.tabletile_index and tile.color == app.opt.table_color:
if (i == app.tabletile_index and
tile.color == app.opt.colors['table']):
return False
if self._tile is tile:
return False
@ -420,10 +456,10 @@ class MfxCanvas(gnome.canvas.Canvas):
self.configure(bg=self.top_bg)
color = tile.text_color
if app.opt.table_text_color:
self.setTextColor(app.opt.table_text_color_value)
else:
if app.opt.use_default_text_color:
self.setTextColor(color)
else:
self.setTextColor(app.opt.colors['text'])
return True

View file

@ -1,13 +1,7 @@
## vim:ts=4:et:nowrap
##
##---------------------------------------------------------------------------##
##
## PySol -- a Python Solitaire game
##
## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
@ -23,10 +17,6 @@
## If not, write to the Free Software Foundation, Inc.,
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
## Markus F.X.J. Oberhumer
## <markus.oberhumer@jk.uni-linz.ac.at>
## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html
##
##---------------------------------------------------------------------------##
@ -37,16 +27,13 @@ import gtk.glade
# PySol imports
from pysollib.mfxutil import format_time
from pysollib.settings import TOP_TITLE
from pysollib.settings import TOP_TITLE, PACKAGE
from pysollib.stats import PysolStatsFormatter
# Toolkit imports
from tkwidget import MfxDialog, MfxMessageDialog
glade_file = os.path.join(sys.path[0], 'data', 'pysolfc.glade')
open(glade_file)
gettext = _
# /***********************************************************************
@ -54,6 +41,7 @@ open(glade_file)
# ************************************************************************/
class StatsWriter(PysolStatsFormatter.StringWriter):
def __init__(self, store):
self.store = store
@ -70,7 +58,7 @@ class StatsWriter(PysolStatsFormatter.StringWriter):
return
iter = self.store.append(None)
self.store.set(iter,
0, args[0],
0, gettext(args[0]),
1, args[1],
2, args[2],
3, args[3],
@ -80,9 +68,12 @@ class StatsWriter(PysolStatsFormatter.StringWriter):
7, gameid)
class FullLogWriter(PysolStatsFormatter.StringWriter):
class LogWriter(PysolStatsFormatter.StringWriter):
MAX_ROWS = 10000
def __init__(self, store):
self.store = store
self._num_rows = 0
def p(self, s):
pass
@ -94,13 +85,16 @@ class FullLogWriter(PysolStatsFormatter.StringWriter):
if gameid < 0:
# header
return
if self._num_rows > self.MAX_ROWS:
return
iter = self.store.append(None)
self.store.set(iter,
0, gamename,
0, gettext(gamename),
1, gamenumber,
2, date,
3, status,
4, gameid)
self._num_rows += 1
class Game_StatsDialog:
@ -108,49 +102,153 @@ class Game_StatsDialog:
def __init__(self, parent, header, app, player, gameid):
#
self.app = app
self.player = player
self.gameid = gameid
self.games = {}
self.games_id = [] # sorted by name
#
formatter = PysolStatsFormatter(self.app)
glade_file = app.dataloader.findFile('pysolfc.glade')
#
games = app.gdb.getGamesIdSortedByName()
n = 0
current = 0
for id in games:
won, lost = self.app.stats.getStats(self.player, id)
if won+lost > 0 or id == gameid:
gi = app.gdb.get(id)
if id == gameid:
current = n
self.games[n] = gi
self.games_id.append(id)
n += 1
#
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)
#
table = self.widgets_tree.get_widget('current_game_table')
combo = self._createGameCombo(table, 1, 0, self._currentComboChanged)
# total
self._createText('total')
drawing = self.widgets_tree.get_widget('total_drawingarea')
drawing.connect('expose_event', self._drawingExposeEvent, 'total')
# current session
self._createText('session')
drawing = self.widgets_tree.get_widget('session_drawingarea')
drawing.connect('expose_event', self._drawingExposeEvent, 'session')
# top 10
table = self.widgets_tree.get_widget('top_10_table')
combo = self._createGameCombo(table, 1, 0, self._top10ComboChanged)
self._createTop()
self._updateTop(gameid)
# all games stat
store = self._createStatsList()
writer = StatsWriter(store)
formatter.writeStats(writer, player, header, sort_by='name')
#
# full log
store = self._createLogList('full_log_treeview')
writer = FullLogWriter(store)
writer = LogWriter(store)
formatter.writeFullLog(writer, player, header)
#
# session log
store = self._createLogList('session_log_treeview')
writer = FullLogWriter(store)
writer = LogWriter(store)
formatter.writeSessionLog(writer, player, header)
#
stats_dialog.set_transient_for(parent)
stats_dialog.resize(400, 300)
stats_dialog.run()
self._translateLabels()
dialog = self.widgets_tree.get_widget('stats_dialog')
dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
dialog.set_transient_for(parent)
dialog.resize(500, 340)
dialog.set_title(PACKAGE+' - '+_("Statistics"))
#
dialog.run()
self.status = -1
stats_dialog.destroy()
dialog.destroy()
def _createText(self, name, won, lost):
def _translateLabels(self):
# mnemonic
for n in (
'label1',
'label2',
'label3',
'label4',
'label15',
'label16',
'label17',
'label18',
):
w = self.widgets_tree.get_widget(n)
w.set_text_with_mnemonic(gettext(w.get_label()))
# simple
for n in (
'label5',
'label6',
'label7',
'label14'
):
w = self.widgets_tree.get_widget(n)
w.set_text(gettext(w.get_text()))
# markup
for n in (
'label8',
'label9',
'label10',
'label11',
'label12',
'label13',
'label19',
'label20',
'label21',
'label22',
'label23',
'label24',
):
w = self.widgets_tree.get_widget(n)
s = gettext(w.get_label())
w.set_markup('<b>%s</b>' % s)
def _createGameCombo(self, table, x, y, callback):
combo = gtk.combo_box_new_text()
combo.show()
table.attach(combo,
x, x+1, y, y+1,
gtk.FILL|gtk.EXPAND, 0,
4, 4)
#
n = 0
current = 0
for id in self.games_id:
gi = self.app.gdb.get(id)
combo.append_text(gettext(gi.name))
if id == self.gameid:
current = n
n += 1
combo.set_active(current)
combo.connect('changed', callback) #self._comboChanged)
def _currentComboChanged(self, w):
gi = self.games[w.get_active()]
self.gameid = gi.id
self._createText('total')
drawing = self.widgets_tree.get_widget('total_drawingarea')
self._createChart(drawing, 'total')
self._createText('session')
drawing = self.widgets_tree.get_widget('session_drawingarea')
self._createChart(drawing, 'session')
def _top10ComboChanged(self, w):
gi = self.games[w.get_active()]
self._updateTop(gi.id)
def _createText(self, name):
if name == 'total':
won, lost = self.app.stats.getStats(self.player, self.gameid)
else:
won, lost = self.app.stats.getSessionStats(self.player, self.gameid)
pwon, plost = self._getPwon(won, lost)
label = self.widgets_tree.get_widget(name+'_num_won_label')
label.set_text(str(won))
@ -164,7 +262,15 @@ class Game_StatsDialog:
label.set_text(str(won+lost))
def _createChart(self, drawing, e, won, lost):
def _drawingExposeEvent(self, drawing, e, frame):
self._createChart(drawing, frame)
def _createChart(self, drawing, frame):
if frame == 'total':
won, lost = self.app.stats.getStats(self.player, self.gameid)
else:
won, lost = self.app.stats.getSessionStats(self.player, self.gameid)
pwon, plost = self._getPwon(won, lost)
s, ewon, elost = 0, int(360.0*pwon), int(360.0*plost)
@ -182,34 +288,128 @@ class Game_StatsDialog:
y = y-dy/2
if won+lost > 0:
gc.set_rgb_fg_color(colormap.alloc_color('#007f00'))
gc.set_foreground(colormap.alloc_color('#008000'))
win.draw_arc(gc, True, x, y+dy, w, h, s*64, ewon*64)
gc.set_rgb_fg_color(colormap.alloc_color('#7f0000'))
gc.set_foreground(colormap.alloc_color('black'))
win.draw_arc(gc, False, x, y+dy, w, h, s*64, ewon*64)
gc.set_foreground(colormap.alloc_color('#800000'))
win.draw_arc(gc, True, x, y+dy, w, h, (s+ewon)*64, elost*64)
gc.set_rgb_fg_color(colormap.alloc_color('#00ff00'))
gc.set_foreground(colormap.alloc_color('black'))
win.draw_arc(gc, False, x, y+dy, w, h, (s+ewon)*64, elost*64)
gc.set_foreground(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'))
gc.set_foreground(colormap.alloc_color('black'))
win.draw_arc(gc, False, x, y, w, h, s*64, ewon*64)
gc.set_foreground(colormap.alloc_color('#ff0000'))
win.draw_arc(gc, True, x, y, w, h, (s+ewon)*64, elost*64)
gc.set_foreground(colormap.alloc_color('black'))
win.draw_arc(gc, False, x, y, w, h, (s+ewon)*64, elost*64)
else:
gc.set_rgb_fg_color(colormap.alloc_color('#7f7f7f'))
gc.set_foreground(colormap.alloc_color('#808080'))
win.draw_arc(gc, True, x, y+dy, w, h, 0, 360*64)
gc.set_rgb_fg_color(colormap.alloc_color('#f0f0f0'))
gc.set_foreground(colormap.alloc_color('black'))
win.draw_arc(gc, False, x, y+dy, w, h, 0, 360*64)
gc.set_foreground(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')
gc.set_foreground(colormap.alloc_color('black'))
win.draw_arc(gc, False, x, y, w, h, 0, 360*64)
gc.set_foreground(colormap.alloc_color('#a0a0a0'))
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)
win.draw_layout(gc, x+w/2-tw/2, y+h/2-th/2, pangolayout)
def _createTop(self):
for n in ('top_10_time_treeview',
'top_10_moves_treeview',
'top_10_total_moves_treeview'):
self._createTopList(n)
def _updateTop(self, gameid):
if (not self.app.stats.games_stats.has_key(self.player) or
not self.app.stats.games_stats[self.player].has_key(gameid) or
not self.app.stats.games_stats[self.player][gameid].time_result.top):
return
s = self.app.stats.games_stats[self.player][gameid]
label = self.widgets_tree.get_widget('playing_time_minimum_label')
label.set_text(format_time(s.time_result.min))
label = self.widgets_tree.get_widget('playing_time_maximum_label')
label.set_text(format_time(s.time_result.max))
label = self.widgets_tree.get_widget('playing_time_average_label')
label.set_text(format_time(s.time_result.average))
label = self.widgets_tree.get_widget('moves_minimum_label')
label.set_text(str(s.moves_result.min))
label = self.widgets_tree.get_widget('moves_maximum_label')
label.set_text(str(s.moves_result.max))
label = self.widgets_tree.get_widget('moves_average_label')
label.set_text(str(round(s.moves_result.average, 2)))
label = self.widgets_tree.get_widget('total_moves_minimum_label')
label.set_text(str(s.total_moves_result.min))
label = self.widgets_tree.get_widget('total_moves_maximum_label')
label.set_text(str(s.total_moves_result.max))
label = self.widgets_tree.get_widget('total_moves_average_label')
label.set_text(str(round(s.total_moves_result.average, 2)))
for n, ss in (
('top_10_time_treeview', s.time_result.top),
('top_10_moves_treeview', s.moves_result.top),
('top_10_total_moves_treeview', s.total_moves_result.top)):
self._updateTopList(n, ss)
def _createTopList(self, tv_name):
treeview = self.widgets_tree.get_widget(tv_name)
store = gtk.ListStore(gobject.TYPE_INT, # N
gobject.TYPE_STRING, # number
gobject.TYPE_STRING, # started at
gobject.TYPE_STRING, # result
gobject.TYPE_STRING, # result
)
treeview.set_model(store)
n = 0
for label in (
_('N'),
_('Game number'),
_('Started at'),
_('Result'),
):
column = gtk.TreeViewColumn(label, gtk.CellRendererText(), text=n)
column.set_resizable(True)
##column.set_sort_column_id(n)
treeview.append_column(column)
n += 1
def _updateTopList(self, tv_name, top):
treeview = self.widgets_tree.get_widget(tv_name)
store = treeview.get_model()
store.clear()
row = 1
for i in top:
t = time.strftime('%Y-%m-%d %H:%M',
time.localtime(i.game_start_time))
if isinstance(i.value, float):
# time
r = format_time(i.value)
else:
# moves
r = str(i.value)
iter = store.append(None)
store.set(iter, 0, row, 1, i.game_number, 2, t, 3, r)
row += 1
def _createStatsList(self):
treeview = self.widgets_tree.get_widget('all_games_treeview')
n = 0
for label in (
'',
_('Game'),
_('Played'),
_('Won'),
_('Lost'),
@ -234,10 +434,11 @@ class Game_StatsDialog:
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)
treeview.set_model(sortable)
treeview.set_rules_hint(True)
return store
@ -265,6 +466,7 @@ class Game_StatsDialog:
gobject.TYPE_INT, # gameid
)
treeview.set_model(store)
treeview.set_rules_hint(True)
return store
@ -300,15 +502,10 @@ class Game_StatsDialog:
# ************************************************************************/
SingleGame_StatsDialog = Game_StatsDialog
class AllGames_StatsDialog(MfxDialog):
pass
class FullLog_StatsDialog(AllGames_StatsDialog):
pass
class SessionLog_StatsDialog(FullLog_StatsDialog):
pass
AllGames_StatsDialog = Game_StatsDialog
FullLog_StatsDialog = Game_StatsDialog
SessionLog_StatsDialog = Game_StatsDialog
Top_StatsDialog = Game_StatsDialog
# /***********************************************************************
@ -334,32 +531,32 @@ class Status_StatsDialog(MfxMessageDialog): #MfxDialog
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,
)
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), ),
image=game.app.gimages.logos[3],
image_side='left', image_padx=20,
padx=20,
)
class Top_StatsDialog(MfxDialog):
pass

View file

@ -164,7 +164,9 @@ def createImage(width, height, fill, outline=None):
# ************************************************************************/
def _wrap_b1_press(e):
return e.type == gdk.BUTTON_PRESS and e.button == 1
return (e.type == gdk.BUTTON_PRESS and e.button == 1 and
not (e.state & gdk.CONTROL_MASK) and
not (e.state & gdk.SHIFT_MASK))
def _wrap_b1_double(e):
return e.type == gdk._2BUTTON_PRESS and e.button == 1
@ -179,7 +181,9 @@ def _wrap_b2_press(e):
return e.type == gdk.BUTTON_PRESS and e.button == 2
def _wrap_b3_press(e):
return e.type == gdk.BUTTON_PRESS and e.button == 3
return (e.type == gdk.BUTTON_PRESS and e.button == 3 and
not (e.state & gdk.CONTROL_MASK) and
not (e.state & gdk.SHIFT_MASK))
def _wrap_b3_control(e):
return e.type == gdk.BUTTON_PRESS and e.button == 3 and (e.state & gdk.CONTROL_MASK)

View file

@ -396,9 +396,9 @@ class Stack:
assert self.is_visible and self.images.bottom is None
img = self.getBottomImage()
if img is not None:
self.images.bottom = MfxCanvasImage(self.canvas, self.x, self.y,
image=img, anchor=ANCHOR_NW)
self.images.bottom.addtag(self.group)
self.images.bottom = MfxCanvasImage(self.canvas,self.x, self.y,
image=img,anchor=ANCHOR_NW,
group=self.group)
self.top_bottom = self.images.bottom
# invisible stack bottom
@ -410,8 +410,8 @@ class Stack:
self.items.bottom = MfxCanvasRectangle(self.canvas, self.x, self.y,
self.x + images.CARDW,
self.y + images.CARDH,
fill="", outline="", width=0)
self.items.bottom.addtag(self.group)
fill="", outline="", width=0,
group=self.group)
self.top_bottom = self.items.bottom
# sanity checks
@ -815,8 +815,9 @@ class Stack:
card = self.cards[i]
if not self.basicShallHighlightSameRank(card):
return 0
col = self.game.app.opt.highlight_samerank_colors
info = [ (self, card, card, col[1]) ]
col_1 = self.game.app.opt.colors['samerank_1']
col_2 = self.game.app.opt.colors['samerank_2']
info = [ (self, card, card, col_1) ]
for s in self.game.allstacks:
for c in s.cards:
if c is card: continue
@ -824,9 +825,9 @@ class Stack:
if c.rank != card.rank: continue
# ask the target stack
if s.basicShallHighlightSameRank(c):
info.append((s, c, c, col[3]))
info.append((s, c, c, col_2))
self.game.stats.highlight_samerank = self.game.stats.highlight_samerank + 1
return self.game._highlightCards(info, self.game.app.opt.highlight_samerank_sleep)
return self.game._highlightCards(info, self.game.app.opt.timeouts['highlight_samerank'])
def highlightMatchingCards(self, event):
i = self._findCard(event)
@ -835,7 +836,8 @@ class Stack:
card = self.cards[i]
if not self.basicShallHighlightMatch(card):
return 0
col = self.game.app.opt.highlight_cards_colors
col_1 = self.game.app.opt.colors['cards_1']
col_2 = self.game.app.opt.colors['cards_2']
c1 = c2 = card
info = []
found = 0
@ -857,12 +859,12 @@ class Stack:
j = self.cards.index(c)
if i - 1 == j: c1 = c; continue
if i + 1 == j: c2 = c; continue
info.append((s, c, c, col[3]))
info.append((s, c, c, col_1))
if found:
if info:
self.game.stats.highlight_cards = self.game.stats.highlight_cards + 1
info.append((self, c1, c2, col[1]))
return self.game._highlightCards(info, self.game.app.opt.highlight_cards_sleep)
info.append((self, c1, c2, col_2))
return self.game._highlightCards(info, self.game.app.opt.timeouts['highlight_cards'])
if not self.basicIsBlocked():
self.game.highlightNotMatching()
return 0
@ -886,7 +888,7 @@ class Stack:
##print self.cards[i]
self.cards[i].item.tkraise()
self.game.canvas.update_idletasks()
self.game.sleep(self.game.app.opt.raise_card_sleep)
self.game.sleep(self.game.app.opt.timeouts['raise_card'])
if TOOLKIT == 'tk':
self.cards[i].item.lower(self.cards[i+1].item)
elif TOOLKIT == 'gtk':
@ -1064,8 +1066,8 @@ class Stack:
drag.noshade_stacks = [ self ]
drag.cards = self.getDragCards(i)
drag.index = i
if TOOLKIT == 'gtk':
drag.stack.group.tkraise()
##if TOOLKIT == 'gtk':
## drag.stack.group.tkraise()
images = game.app.images
drag.shadows = self.createShadows(drag.cards)
##sx, sy = 0, 0
@ -1227,7 +1229,8 @@ class Stack:
if drag.shade_img:
drag.shade_img.moveTo(sx, sy)
else:
img = MfxCanvasImage(game.canvas, sx, sy, image=img, anchor=ANCHOR_NW)
img = MfxCanvasImage(game.canvas, sx, sy,
image=img, anchor=ANCHOR_NW)
drag.shade_img = img
# raise/lower the shade image to the correct stacking order
if TOOLKIT == 'tk':
@ -1258,9 +1261,9 @@ class Stack:
#self.game.canvas.update_idletasks()
card = self.cards[-1]
item = MfxCanvasImage(self.game.canvas, card.x, card.y,
image=img, anchor=ANCHOR_NW)
image=img, anchor=ANCHOR_NW,
group=self.group)
#item.tkraise()
item.addtag(self.group)
self.items.shade_item = item
def _unshadeStack(self):
@ -1566,15 +1569,16 @@ class TalonStack(Stack,
# add a redeal image above the bottom image
img = (self.getRedealImages())[self.max_rounds != 1]
if img is not None:
self.images.redeal = MfxCanvasImage(self.game.canvas, cx, cy,
image=img, anchor="center")
self.images.redeal_img = img
self.images.redeal = MfxCanvasImage(self.game.canvas,
cx, cy, image=img,
anchor="center",
group=self.group)
if TOOLKIT == 'tk':
self.images.redeal.tkraise(self.top_bottom)
elif TOOLKIT == 'gtk':
### FIXME
pass
self.images.redeal.addtag(self.group)
self.top_bottom = self.images.redeal
if images.CARDH >= 90:
cy, ca = self.y + images.CARDH - 4, "s"
@ -1585,16 +1589,16 @@ class TalonStack(Stack,
if images.CARDW >= text_width+4 and ca:
# add a redeal text above the bottom image
if self.max_rounds != 1:
self.texts.redeal_str = ""
images = self.game.app.images
self.texts.redeal = MfxCanvasText(self.game.canvas, cx, cy,
anchor=ca, font=font)
self.texts.redeal_str = ""
anchor=ca, font=font,
group=self.group)
if TOOLKIT == 'tk':
self.texts.redeal.tkraise(self.top_bottom)
elif TOOLKIT == 'gtk':
### FIXME
pass
self.texts.redeal.addtag(self.group)
self.top_bottom = self.texts.redeal
def getBottomImage(self):

View file

@ -48,47 +48,43 @@ class ColorsDialog(MfxDialog):
frame.pack(expand=True, fill='both', padx=5, pady=10)
frame.columnconfigure(0, weight=1)
self.table_text_color_var = Tkinter.BooleanVar()
self.table_text_color_var.set(app.opt.table_text_color)
self.table_text_color_value_var = Tkinter.StringVar()
self.table_text_color_value_var.set(app.opt.table_text_color_value)
##self.table_color_var = StringVar()
##self.table_color_var.set(app.opt.table_color)
self.highlight_piles_colors_var = Tkinter.StringVar()
self.highlight_piles_colors_var.set(app.opt.highlight_piles_colors[1])
self.highlight_cards_colors_1_var = Tkinter.StringVar()
self.highlight_cards_colors_1_var.set(app.opt.highlight_cards_colors[1])
self.highlight_cards_colors_2_var = Tkinter.StringVar()
self.highlight_cards_colors_2_var.set(app.opt.highlight_cards_colors[3])
self.highlight_samerank_colors_1_var = Tkinter.StringVar()
self.highlight_samerank_colors_1_var.set(app.opt.highlight_samerank_colors[1])
self.highlight_samerank_colors_2_var = Tkinter.StringVar()
self.highlight_samerank_colors_2_var.set(app.opt.highlight_samerank_colors[3])
self.hintarrow_color_var = Tkinter.StringVar()
self.hintarrow_color_var.set(app.opt.hintarrow_color)
self.highlight_not_matching_color_var = Tkinter.StringVar()
self.highlight_not_matching_color_var.set(app.opt.highlight_not_matching_color)
self.use_default_var = Tkinter.BooleanVar()
self.use_default_var.set(not app.opt.use_default_text_color)
self.text_var = Tkinter.StringVar()
self.text_var.set(app.opt.colors['text'])
self.piles_var = Tkinter.StringVar()
self.piles_var.set(app.opt.colors['piles'])
self.cards_1_var = Tkinter.StringVar()
self.cards_1_var.set(app.opt.colors['cards_1'])
self.cards_2_var = Tkinter.StringVar()
self.cards_2_var.set(app.opt.colors['cards_2'])
self.samerank_1_var = Tkinter.StringVar()
self.samerank_1_var.set(app.opt.colors['samerank_1'])
self.samerank_2_var = Tkinter.StringVar()
self.samerank_2_var.set(app.opt.colors['samerank_2'])
self.hintarrow_var = Tkinter.StringVar()
self.hintarrow_var.set(app.opt.colors['hintarrow'])
self.not_matching_var = Tkinter.StringVar()
self.not_matching_var.set(app.opt.colors['not_matching'])
#
c = Tkinter.Checkbutton(frame, variable=self.table_text_color_var,
c = Tkinter.Checkbutton(frame, variable=self.use_default_var,
text=_("Text foreground:"), anchor='w')
c.grid(row=0, column=0, sticky='we')
l = Tkinter.Label(frame, width=10, height=2,
bg=self.table_text_color_value_var.get(),
textvariable=self.table_text_color_value_var)
bg=self.text_var.get(), textvariable=self.text_var)
l.grid(row=0, column=1, padx=5)
b = Tkinter.Button(frame, text=_('Change...'), width=10,
command=lambda l=l: self.selectColor(l))
b.grid(row=0, column=2)
row = 1
for title, var in (
##('Table:', self.table_color_var),
(_('Highlight piles:'), self.highlight_piles_colors_var),
(_('Highlight cards 1:'), self.highlight_cards_colors_1_var),
(_('Highlight cards 2:'), self.highlight_cards_colors_2_var),
(_('Highlight same rank 1:'), self.highlight_samerank_colors_1_var),
(_('Highlight same rank 2:'), self.highlight_samerank_colors_2_var),
(_('Hint arrow:'), self.hintarrow_color_var),
(_('Highlight not matching:'), self.highlight_not_matching_color_var),
(_('Highlight piles:'), self.piles_var),
(_('Highlight cards 1:'), self.cards_1_var),
(_('Highlight cards 2:'), self.cards_2_var),
(_('Highlight same rank 1:'), self.samerank_1_var),
(_('Highlight same rank 2:'), self.samerank_2_var),
(_('Hint arrow:'), self.hintarrow_var),
(_('Highlight not matching:'), self.not_matching_var),
):
Tkinter.Label(frame, text=title, anchor='w'
).grid(row=row, column=0, sticky='we')
@ -103,21 +99,15 @@ class ColorsDialog(MfxDialog):
focus = self.createButtons(bottom_frame, kw)
self.mainloop(focus, kw.timeout)
#
self.table_text_color = self.table_text_color_var.get()
self.table_text_color_value = self.table_text_color_value_var.get()
##self.table_color = self.table_color_var.get()
self.highlight_piles_colors = (None,
self.highlight_piles_colors_var.get())
self.highlight_cards_colors = (None,
self.highlight_cards_colors_1_var.get(),
None,
self.highlight_cards_colors_2_var.get())
self.highlight_samerank_colors = (None,
self.highlight_samerank_colors_1_var.get(),
None,
self.highlight_samerank_colors_2_var.get())
self.hintarrow_color = self.hintarrow_color_var.get()
self.highlight_not_matching_color = self.highlight_not_matching_color_var.get()
self.use_default_color = not self.use_default_var.get()
self.text_color = self.text_var.get()
self.piles_color = self.piles_var.get()
self.cards_1_color = self.cards_1_var.get()
self.cards_2_color = self.cards_2_var.get()
self.samerank_1_color = self.samerank_1_var.get()
self.samerank_2_color = self.samerank_2_var.get()
self.hintarrow_color = self.hintarrow_var.get()
self.not_matching_color = self.not_matching_var.get()
def selectColor(self, label):
c = askcolor(master=self.top, initialcolor=label.cget('bg'),

View file

@ -72,7 +72,7 @@ class FindCardDialog(Tkinter.Toplevel):
bind(self, "<Escape>", self.destroy)
#
##self.normal_timeout = 400 # in milliseconds
self.normal_timeout = int(1000*game.app.opt.highlight_samerank_sleep)
self.normal_timeout = int(1000*game.app.opt.timeouts['highlight_samerank'])
self.hidden_timeout = 200
self.timer = None

View file

@ -382,9 +382,9 @@ class PysolMenubar(PysolMenubarActions):
menu.add_checkbutton(label=n_("Stick&y mouse"), variable=self.tkopt.sticky_mouse, command=self.mOptStickyMouse)
menu.add_checkbutton(label=n_("Use mouse for undo/redo"), variable=self.tkopt.mouse_undo, command=self.mOptMouseUndo)
menu.add_separator()
menu.add_command(label=n_("&Fonts..."), command=self.mOptFontsOptions)
menu.add_command(label=n_("&Colors..."), command=self.mOptColorsOptions)
menu.add_command(label=n_("Time&outs..."), command=self.mOptTimeoutsOptions)
menu.add_command(label=n_("&Fonts..."), command=self.mOptFonts)
menu.add_command(label=n_("&Colors..."), command=self.mOptColors)
menu.add_command(label=n_("Time&outs..."), command=self.mOptTimeouts)
menu.add_separator()
submenu = MfxMenu(menu, label=n_("&Toolbar"))
createToolbarMenu(self, submenu)
@ -637,7 +637,7 @@ class PysolMenubar(PysolMenubarActions):
self.mSelectGame, self.tkopt.gameid)
def _addSelectAllGameSubMenu(self, games, menu, command, variable):
menu = MfxMenu(menu, label=n_("All games by name"))
menu = MfxMenu(menu, label=n_("&All games by name"))
n, d = 0, self.__cb_max
i = 0
while True:
@ -676,6 +676,12 @@ class PysolMenubar(PysolMenubarActions):
# Select Game menu actions
#
def mSelectGame(self, *args):
self._mSelectGame(self.tkopt.gameid.get())
def mSelectGamePopular(self, *args):
self._mSelectGame(self.tkopt.gameid_popular.get())
def _mSelectGameDialog(self, d):
if d.status == 0 and d.button == 0 and d.gameid != self.game.id:
self.tkopt.gameid.set(d.gameid)
@ -890,6 +896,105 @@ class PysolMenubar(PysolMenubarActions):
self.game.saveGame(filename)
self.updateMenus()
def mOptAutoFaceUp(self, *args):
if self._cancelDrag(): return
self.app.opt.autofaceup = self.tkopt.autofaceup.get()
if self.app.opt.autofaceup:
self.game.autoPlay()
def mOptAutoDrop(self, *args):
if self._cancelDrag(): return
self.app.opt.autodrop = self.tkopt.autodrop.get()
if self.app.opt.autodrop:
self.game.autoPlay()
def mOptAutoDeal(self, *args):
if self._cancelDrag(): return
self.app.opt.autodeal = self.tkopt.autodeal.get()
if self.app.opt.autodeal:
self.game.autoPlay()
def mOptQuickPlay(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.quickplay = self.tkopt.quickplay.get()
def mOptEnableUndo(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.undo = self.tkopt.undo.get()
self.game.updateMenus()
def mOptEnableBookmarks(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.bookmarks = self.tkopt.bookmarks.get()
self.game.updateMenus()
def mOptEnableHint(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.hint = self.tkopt.hint.get()
self.game.updateMenus()
def mOptEnableHighlightPiles(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_piles = self.tkopt.highlight_piles.get()
self.game.updateMenus()
def mOptEnableHighlightCards(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_cards = self.tkopt.highlight_cards.get()
self.game.updateMenus()
def mOptEnableHighlightSameRank(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_samerank = self.tkopt.highlight_samerank.get()
##self.game.updateMenus()
def mOptEnableHighlightNotMatching(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.highlight_not_matching = self.tkopt.highlight_not_matching.get()
##self.game.updateMenus()
def mOptAnimations(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.animations = self.tkopt.animations.get()
def mOptShadow(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shadow = self.tkopt.shadow.get()
def mOptShade(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shade = self.tkopt.shade.get()
def mOptShrinkFaceDown(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shrink_face_down = self.tkopt.shrink_face_down.get()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptShadeFilledStacks(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shade_filled_stacks = self.tkopt.shade_filled_stacks.get()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptMahjonggShowRemoved(self, *args):
if self._cancelDrag(): return
self.app.opt.mahjongg_show_removed = self.tkopt.mahjongg_show_removed.get()
##self.game.updateMenus()
self.game.endGame(bookmark=1)
self.game.quitGame(bookmark=1)
def mOptShisenShowHint(self, *args):
if self._cancelDrag(break_pause=False): return
self.app.opt.shisen_show_hint = self.tkopt.shisen_show_hint.get()
##self.game.updateMenus()
## def mOptSound(self, *args):
## if self._cancelDrag(break_pause=False): return
## self.app.opt.sound = self.tkopt.sound.get()
## if not self.app.opt.sound:
## self.app.audio.stopAll()
def mSelectCardsetDialog(self, *event):
if self._cancelDrag(break_pause=False): return
##strings, default = ("&OK", "&Load", "&Cancel"), 0
@ -957,7 +1062,7 @@ class PysolMenubar(PysolMenubarActions):
if self._cancelDrag(break_pause=False): return
key = self.app.tabletile_index
if key <= 0:
key = self.app.opt.table_color.lower()
key = self.app.opt.colors['table'] ##.lower()
d = SelectTileDialogWithPreview(self.top, app=self.app,
title=_("Select table background"),
manager=self.app.tabletile_manager,
@ -968,13 +1073,6 @@ class PysolMenubar(PysolMenubarActions):
elif d.key > 0 and d.key != self.app.tabletile_index:
self._mOptTableTile(d.key)
## def mOptTableColor(self, *event):
## if self._cancelDrag(break_pause=False): return
## c = tkColorChooser.askcolor(initialcolor=self.app.opt.table_color,
## title=_("Select table color"))
## if c and c[1]:
## self._mOptTableColor(c[1])
def mOptToolbar(self, *event):
##if self._cancelDrag(break_pause=False): return
self.setToolbarSide(self.tkopt.toolbar.get())

View file

@ -121,7 +121,7 @@ class SelectTileDialogWithPreview(MfxDialog):
self.app = app
self.manager = manager
self.key = key
self.table_color = app.opt.table_color
self.table_color = app.opt.colors['table']
if self.TreeDataHolder_Class.data is None:
self.TreeDataHolder_Class.data = self.TreeData_Class(manager, key)
#

View file

@ -48,17 +48,17 @@ class TimeoutsDialog(MfxDialog):
frame.columnconfigure(0, weight=1)
self.demo_sleep_var = Tkinter.DoubleVar()
self.demo_sleep_var.set(app.opt.demo_sleep)
self.demo_sleep_var.set(app.opt.timeouts['demo'])
self.hint_sleep_var = Tkinter.DoubleVar()
self.hint_sleep_var.set(app.opt.hint_sleep)
self.hint_sleep_var.set(app.opt.timeouts['hint'])
self.raise_card_sleep_var = Tkinter.DoubleVar()
self.raise_card_sleep_var.set(app.opt.raise_card_sleep)
self.raise_card_sleep_var.set(app.opt.timeouts['raise_card'])
self.highlight_piles_sleep_var = Tkinter.DoubleVar()
self.highlight_piles_sleep_var.set(app.opt.highlight_piles_sleep)
self.highlight_piles_sleep_var.set(app.opt.timeouts['highlight_piles'])
self.highlight_cards_sleep_var = Tkinter.DoubleVar()
self.highlight_cards_sleep_var.set(app.opt.highlight_cards_sleep)
self.highlight_cards_sleep_var.set(app.opt.timeouts['highlight_cards'])
self.highlight_samerank_sleep_var = Tkinter.DoubleVar()
self.highlight_samerank_sleep_var.set(app.opt.highlight_samerank_sleep)
self.highlight_samerank_sleep_var.set(app.opt.timeouts['highlight_samerank'])
#
#Tkinter.Label(frame, text='Set delays in seconds').grid(row=0, column=0, columnspan=2)
row = 0
@ -80,12 +80,12 @@ class TimeoutsDialog(MfxDialog):
focus = self.createButtons(bottom_frame, kw)
self.mainloop(focus, kw.timeout)
#
self.demo_sleep = self.demo_sleep_var.get()
self.hint_sleep = self.hint_sleep_var.get()
self.raise_card_sleep = self.raise_card_sleep_var.get()
self.highlight_piles_sleep = self.highlight_piles_sleep_var.get()
self.highlight_cards_sleep = self.highlight_cards_sleep_var.get()
self.highlight_samerank_sleep = self.highlight_samerank_sleep_var.get()
self.demo_timeout = self.demo_sleep_var.get()
self.hint_timeout = self.hint_sleep_var.get()
self.raise_card_timeout = self.raise_card_sleep_var.get()
self.highlight_piles_timeout = self.highlight_piles_sleep_var.get()
self.highlight_cards_timeout = self.highlight_cards_sleep_var.get()
self.highlight_samerank_timeout = self.highlight_samerank_sleep_var.get()
def initKw(self, kw):
kw = KwStruct(kw,

View file

@ -77,6 +77,14 @@ class MfxCanvasGroup(Canvas.Group):
return self.canvas.tk.splitlist(self._do("gettags"))
class MfxCanvasImage(Canvas.ImageItem):
def __init__(self, canvas, *args, **kwargs):
group = None
if kwargs.has_key('group'):
group = kwargs['group']
del kwargs['group']
Canvas.ImageItem.__init__(self, canvas, *args, **kwargs)
if group:
self.addtag(group)
def moveTo(self, x, y):
c = self.coords()
self.move(x - int(c[0]), y - int(c[1]))
@ -87,19 +95,33 @@ class MfxCanvasImage(Canvas.ImageItem):
MfxCanvasLine = Canvas.Line
MfxCanvasRectangle = Canvas.Rectangle
class MfxCanvasRectangle(Canvas.Rectangle):
def __init__(self, canvas, *args, **kwargs):
group = None
if kwargs.has_key('group'):
group = kwargs['group']
del kwargs['group']
Canvas.Rectangle.__init__(self, canvas, *args, **kwargs)
if group:
self.addtag(group)
class MfxCanvasText(Canvas.CanvasText):
def __init__(self, canvas, x, y, preview=-1, **kw):
def __init__(self, canvas, x, y, preview=-1, **kwargs):
if preview < 0:
preview = canvas.preview
if preview > 1:
return
if not kw.has_key("fill"):
kw["fill"] = canvas._text_color
apply(Canvas.CanvasText.__init__, (self, canvas, x, y), kw)
if not kwargs.has_key("fill"):
kwargs["fill"] = canvas._text_color
group = None
if kwargs.has_key('group'):
group = kwargs['group']
del kwargs['group']
Canvas.CanvasText.__init__(self, canvas, x, y, **kwargs)
self.text_format = None
canvas._text_items.append(self)
if group:
self.addtag(group)
# /***********************************************************************

View file

@ -790,9 +790,9 @@ class Top_StatsDialog(MfxDialog):
frame.pack(expand=Tkinter.YES, fill=Tkinter.BOTH, padx=5, pady=10)
frame.columnconfigure(0, weight=1)
if app.stats.games_stats.has_key(player) \
and app.stats.games_stats[player].has_key(gameid) \
and app.stats.games_stats[player][gameid].time_result.top:
if (app.stats.games_stats.has_key(player) and
app.stats.games_stats[player].has_key(gameid) and
app.stats.games_stats[player][gameid].time_result.top):
Tkinter.Label(frame, text=_('Minimum')).grid(row=0, column=1)
Tkinter.Label(frame, text=_('Maximum')).grid(row=0, column=2)

View file

@ -501,7 +501,8 @@ class MfxScrolledCanvas:
assert tile.filename
assert tile.basename
if not force:
if i == app.tabletile_index and tile.color == app.opt.table_color:
if (i == app.tabletile_index and
tile.color == app.opt.colors['table']):
return False
#
if not self.canvas.setTile(tile.filename, tile.stretch):
@ -517,10 +518,10 @@ class MfxScrolledCanvas:
##app.top.config(bg=app.top_bg)
color = tile.text_color
if app.opt.table_text_color:
self.canvas.setTextColor(app.opt.table_text_color_value)
else:
if app.opt.use_default_text_color:
self.canvas.setTextColor(color)
else:
self.canvas.setTextColor(app.opt.colors['text'])
return True