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

* improved support GTK (alpha)

git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@48 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
skomoroh 2006-08-15 21:15:02 +00:00
parent 4870bc56cb
commit 2fcfcf8e99
13 changed files with 657 additions and 391 deletions

View file

@ -770,6 +770,10 @@ class Application:
self.intro.progress.destroy()
destruct(self.intro.progress)
self.intro.progress = None
if TOOLKIT == 'gtk':
## FIXME
self.top.update_idletasks()
self.top.show_now()
# prepare game
autoplay = 0
if self.nextgame.loadedgame is not None:

View file

@ -483,7 +483,7 @@ def pysol_exit(app):
if app.audio is not None:
app.audio.destroy() # shut down audio
destruct(app.audio)
app.wm_withdraw()
##app.wm_withdraw()
if app.canvas is not None:
app.canvas.destroy()
destruct(app.canvas)

View file

@ -45,6 +45,7 @@ from tkutil import setTransient
from tkutil import color_tk2gtk, color_gtk2tk
from selectcardset import SelectCardsetDialogWithPreview
from selectcardset import SelectCardsetByTypeDialogWithPreview
from selecttile import SelectTileDialogWithPreview
# /***********************************************************************
@ -57,8 +58,6 @@ class PysolMenubar(PysolMenubarActions):
def __init__(self, app, top, progress=None):
PysolMenubarActions.__init__(self, app, top)
self.progress = progress
##self.menus = None
##self.menu_items = None
# create menus
menubar = self.createMenubar()
self.top.table.attach(menubar,
@ -68,22 +67,6 @@ class PysolMenubar(PysolMenubarActions):
menubar.show()
## menubar, accel = self.createMenus()
## # additional key bindings
## ### FIXME
## ###self.accel.add("Space", None, None, None, None)
## # delete the old menubar
## # set the menubar
## ##~ accel.attach(self.top)
## top.add_accel_group(accel)
## w = menubar.get_widget('<main>')
## self.top.vbox.pack_start(w, expand=FALSE, fill=FALSE)
## self.top.vbox.reorder_child(w, 0)
## self.__menubar = menubar
## self.__accel = accel
## self.menus = menubar
#
# create menubar
#
@ -106,13 +89,14 @@ class PysolMenubar(PysolMenubarActions):
('Rules', gtk.STOCK_HELP, 'Rules', None, 'Rules', self.mHelpRules),
('Quit', gtk.STOCK_QUIT, 'Quit', '<control>Q', 'Quit PySol', self.mQuit),
("FileMenu", None, "_File" ),
("SelectGame", None, "Select _game"),
("EditMenu", None, '_Edit'),
("GameMenu", None, "_Game"),
("AssistMenu", None, "_Assist"),
("OptionsMenu", None, "_Options"),
("HelpMenu", None, "_Help"),
("FileMenu", None, "_File" ),
("SelectGame", None, "Select _game"),
("EditMenu", None, '_Edit'),
("GameMenu", None, "_Game"),
("AssistMenu", None, "_Assist"),
("OptionsMenu", None, "_Options"),
('AnimationsMenu', None, '_Animations'),
("HelpMenu", None, "_Help"),
('SelectGameByNumber', None, "Select game by number...", None, None, self.mSelectGameById),
("SaveAs", None, 'Save _as...', None, None, self.m),
@ -121,12 +105,13 @@ class PysolMenubar(PysolMenubarActions):
("Status", None, 'S_tatus...', "T", None, self.mStatus),
("Hint", None, '_Hint', "H", None, self.mHint),
("HighlightPiles", None, 'Highlight _piles', None, None, self.mHighlightPiles),
("Demo", None, '_Demo', "<control>D", None, self.mDemo),
("DemoAllGames", None, 'Demo (all games)', None, None, self.mMixedDemo),
("Contents", None, '_Contents', 'F1', None, self.mHelp),
("About", None, '_About PySol...', None, None, self.mHelpAbout),
("Demo", None, '_Demo', "<control>D", None, self.mDemo),
("DemoAllGames", None, 'Demo (all games)', None, None, self.mMixedDemo),
("TableTile", None, "Table t_ile...", None, None, self.mOptTableTile),
("Contents", None, '_Contents', 'F1', None, self.mHelp),
("About", None, '_About PySol...', None, None, self.mHelpAbout),
)
#
toggle_entries = (
("Confirm", None, '_Confirm', None, None, self.mOptConfirm),
("Autoplay", None, 'Auto_play', "P", None, self.mOptAutoDrop),
@ -136,7 +121,15 @@ class PysolMenubar(PysolMenubarActions):
("ShadeLegalMoves", None, 'Shade legal moves', None, None, self.mOptShade),
)
#
animations_entries = (
("AnimationNone", None, "_None", None, None, 0),
("AnimationFast", None, "_Fast", None, None, 1),
("AnimationTimer", None, "_Timer based", None, None, 2),
("AnimationSlow", None, "_Slow", None, None, 3),
("AnimationVerySlow", None, "_Very slow", None, None, 4),
)
#
ui_info = '''<ui>
<menubar name='MenuBar'>
@ -178,6 +171,15 @@ class PysolMenubar(PysolMenubarActions):
<menuitem action='Autoplay'/>
<menuitem action='AutomaticFaceUp'/>
<menuitem action='HighlightMatchingCards'/>
<separator/>
<menuitem action='TableTile'/>
<menu action='AnimationsMenu'>
<menuitem action='AnimationNone'/>
<menuitem action='AnimationFast'/>
<menuitem action='AnimationTimer'/>
<menuitem action='AnimationSlow'/>
<menuitem action='AnimationVerySlow'/>
</menu>
<menuitem action='CardShadow'/>
<menuitem action='ShadeLegalMoves'/>
</menu>
@ -198,6 +200,9 @@ class PysolMenubar(PysolMenubarActions):
action_group = gtk.ActionGroup("PySolActions")
action_group.add_actions(entries)
action_group.add_toggle_actions(toggle_entries)
action_group.add_radio_actions(animations_entries,
self.app.opt.animations,
self.mOptAnimations)
ui_manager.insert_action_group(action_group, 0)
self.top.add_accel_group(ui_manager.get_accel_group())
@ -250,151 +255,6 @@ class PysolMenubar(PysolMenubarActions):
n += d
## def _initItemFactory(self):
## self.menu_items = (
## ("/_File", None, None, 0, "<Branch>"),
## ("/File/<tearoff>", None, None, 0, "<Tearoff>"),
## ("/File/_New Game", "<control>N", self.mNewGame, 0, ""),
## ("/File/Select _game", None, None, 0, "<Branch>"),
## )
## #
## # /File/Select game
## #
## mi, radio = [], "<RadioItem>"
## games = self.app.gdb.getGamesIdSortedByName()
## i = 0
## path = "/File/Select game"
## columnbreak = 25
## n = 0
## mm = []
## t1 = t2 = None
## for id in games:
## if t1 is None:
## t1 = self.app.getGameMenuitemName(id)[:3]
## if n == columnbreak:
## t2 = self.app.getGameMenuitemName(id)[:3]
## pp = '%s/%s-%s' % (path, t1, t2)
## mi.append((pp, None, None, 0, '<Branch>'))
## for m in mm:
## p = '%s/%s' % (pp, m[0])
## mi.append((p, None, self.mSelectGame, m[1], radio))
## if radio[0] == '<':
## radio = re.sub('_', '', p)
## n = 0
## mm = []
## t1 = t2
## mm.append((self.app.getGameMenuitemName(id), id))
## n += 1
## t2 = self.app.getGameMenuitemName(id)[:3]
## pp = '%s/%s-%s' % (path, t1, t2)
## mi.append((pp, None, None, 0, '<Branch>'))
## for m in mm:
## p = '%s/%s' % (pp, m[0])
## mi.append((p, None, self.mSelectGame, m[1], radio))
## self.menu_items = self.menu_items + tuple(mi)
## self.tkopt.gameid.path = radio
## #
## #
## #
## self.menu_items = self.menu_items + (
## ("/File/Select game by number...", None, self.mSelectGameById, 0, ""),
## ("/File/<sep>", None, None, 0, "<Separator>"),
## ("/File/_Open", "<control>O", self.m, 0, ""),
## ("/File/_Save", "<control>S", self.mSave, 0, ""),
## ("/File/Save _as...", None, self.m, 0, ""),
## ("/File/<sep>", None, None, 0, "<Separator>"),
## ("/File/_Quit", "<control>Q", self.mQuit, 0, ""),
## ("/_Edit", None, None, 0, "<Branch>"),
## ("/Edit/<tearoff>", None, None, 0, "<Tearoff>"),
## ("/Edit/_Undo", "Z", self.mUndo, 0, ""),
## ("/Edit/_Redo", "R", self.mRedo, 0, ""),
## ("/Edit/Redo _all", None, self.mRedoAll, 0, ""),
## ("/Edit/<sep>", None, None, 0, "<Separator>"),
## ("/Edit/Restart _game", "<control>G", self.mRestart, 0, ""),
## ("/_Game", None, None, 0, "<Branch>"),
## ("/Game/<tearoff>", None, None, 0, "<Tearoff>"),
## ("/Game/_Deal cards", "D", self.mDeal, 0, ""),
## ("/Game/_Auto drop", "A", self.mDrop, 0, ""),
## ("/Game/<sep>", None, None, 0, "<Separator>"),
## ("/Game/S_tatus...", "T", self.mStatus, 0, ""),
## ("/_Assist", None, None, 0, "<Branch>"),
## ("/Assist/<tearoff>", None, None, 0, "<Tearoff>"),
## ("/Assist/_Hint", "H", self.mHint, 0, ""),
## ("/Assist/Highlight _piles", "Shift", self.mHighlightPiles, 0, ""),
## ("/Assist/<sep>", None, None, 0, "<Separator>"),
## ("/Assist/_Demo", "<control>D", self.mDemo, 0, ""),
## ("/Assist/Demo (all games)", "", self.mMixedDemo, 0, ""),
## ("/_Options", None, None, 0, "<Branch>"),
## ("/Options/<tearoff>", None, None, 0, "<Tearoff>"),
## ("/Options/_Confirm", None, self.mOptConfirm, 0, "<ToggleItem>"),
## ("/Options/Auto_play", "P", self.mOptAutoDrop, 0, "<ToggleItem>"),
## ("/Options/_Automatic _face up", "F", self.mOptAutoFaceUp, 0, "<ToggleItem>"),
## ("/Options/Highlight _matching cards", None, self.mOptEnableHighlightCards, 0, "<ToggleItem>"),
## ("/Options/<sep>", None, None, 0, "<Separator>"),
## )
## mi, radio = [], "<RadioItem>"
## path = "/Options/Cards_et"
## mi.append((path, None, None, 0, "<Branch>"))
## for i in range(self.app.cardset_manager.len()):
## columnbreak = i > 0 and (i % 25) == 0
## p = path + '/' + self.app.cardset_manager.get(i).name
## mi.append((p, None, self.mOptCardset, i, radio))
## if radio[0] == '<':
## radio = re.sub('_', '', p)
## self.menu_items = self.menu_items + tuple(mi)
## ## self.tkopt.cardset.path = radio
## self.menu_items = self.menu_items + (
## ("/Options/Table color...", None, self.mOptTableColor, 0, ""),
## )
## mi, radio = [], "<RadioItem>"
## path = "/Options/_Animations"
## mi.append((path, None, None, 0, "<Branch>"))
## i = 0
## for k in ("_None", "_Fast", "_Timer based"):
## p = path + '/' + k
## mi.append((p, None, self.mOptAnimations, i, radio))
## if radio[0] == '<':
## radio = re.sub('_', '', p)
## i = i + 1
## self.menu_items = self.menu_items + tuple(mi)
## self.tkopt.animations.path = radio
## self.menu_items = self.menu_items + (
## ("/Options/Card shadow", None, self.mOptShadow, 0, "<ToggleItem>"),
## ("/Options/Shade legal moves", None, self.mOptShade, 0, "<ToggleItem>"),
## ("/Options/<sep>", None, None, 0, "<Separator>"),
## ("/Options/_Hint options...", None, self.mOptHintOptions, 0, ""),
## ("/Options/_Demo options...", None, self.mOptDemoOptions, 0, ""),
## ("/_Help", None, None, 0, "<LastBranch>"),
## ("/Help/<tearoff>", None, None, 0, "<Tearoff>"),
## ("/Help/_Contents", "F1", self.mHelp, 0, ""),
## ("/Help/_Rules", None, self.mHelpRules, 0, ""),
## ("/Help/<sep>", None, None, 0, "<Separator>"),
## ("/Help/_About PySol...", None, self.mHelpAbout, 0, ""),
## )
def createMenus(self):
return self._initUI()
if not self.menu_items:
self._initItemFactory()
accel = gtk.AccelGroup()
item_factory = gtk.ItemFactory(gtk.MenuBar, '<main>', accel)
item_factory.create_items(self.menu_items)
return item_factory, accel
#
# menu updates
#
@ -423,27 +283,21 @@ class PysolMenubar(PysolMenubarActions):
def mOptCardset(self, *args):
pass
def mOptTableColor(self, *args):
win = gtk.ColorSelectionDialog("Select table color")
win.help_button.destroy()
win.set_position(gtk.WIN_POS_MOUSE)
win.colorsel.set_current_color(gdk.color_parse(self.app.opt.table_color))
##win.colorsel.set_update_policy(UPDATE_CONTINUOUS)
def delete_event(widget, *event):
widget.destroy()
def ok_button_clicked(_button, self=self, win=win):
c = win.colorsel.get_current_color()
c = '#%02x%02x%02x' % (c.red/256, c.green/256, c.blue/256)
win.destroy()
self.app.opt.table_color = c
self.game.canvas.config(bg=self.app.opt.table_color)
self.top.config(bg=self.app.opt.table_color)
win.connect("delete_event", delete_event)
win.ok_button.connect("clicked", ok_button_clicked)
win.cancel_button.connect("clicked", win.destroy)
setTransient(win, self.top)
win.show()
def 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 mOptConfirm(self, *args):
pass
@ -461,3 +315,16 @@ class PysolMenubar(PysolMenubarActions):
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)

View file

@ -69,10 +69,11 @@ class PysolProgressBar:
0, 0)
# hbox-1: image
## if images and images[0]:
## im = images[0].clone()
## im.show()
## hbox.pack_start(im, FALSE, FALSE)
if images and images[0]:
im = gtk.Image()
im.set_from_pixbuf(images[0].pixbuf)
hbox.pack_start(im, expand=False, fill=False)
im.show()
# hbox-2:vbox
vbox = gtk.VBox()
vbox.show()
@ -87,16 +88,17 @@ class PysolProgressBar:
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
##~ c = self.pbar.get_colormap().alloc_color(color)
##~ self.pbar.style.bg[gtk.STATE_PRELIGHT] = c
##~ style = self.pbar.get_style().copy()
##~ style.bg[gtk.STATE_PRELIGHT] = c
##~ self.pbar.set_style(style)
# hbox-3:image
## if images and images[1]:
## im = images[1].clone()
## im.show()
## hbox.pack_start(im, FALSE, FALSE)
if images and images[1]:
im = gtk.Image()
im.set_from_pixbuf(images[1].pixbuf)
hbox.pack_end(im, expand=False)
im.show()
# set icon
if app:
try:
@ -105,9 +107,9 @@ class PysolProgressBar:
pixmap, mask = create_pixmap_from_xpm(self.top, bg, name)
self.top.set_icon(pixmap, mask)
except: pass
##~ self.top.get_window().set_cursor(cursor_new(gdk.WATCH))
setTransient(self.top, parent)
self.top.show()
self.top.window.set_cursor(gdk.Cursor(gdk.WATCH))
self.update(percent=0)
def destroy(self):

View file

@ -1,17 +1,7 @@
## vim:ts=4:et:nowrap
##
##---------------------------------------------------------------------------##
##
## PySol -- a Python Solitaire game
##
## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
## All Rights Reserved.
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
@ -27,24 +17,219 @@
## If not, write to the Free Software Foundation, Inc.,
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
## Markus F.X.J. Oberhumer
## <markus@oberhumer.com>
## http://www.oberhumer.com/pysol
##
##---------------------------------------------------------------------------##
## # imports
# imports
## import os, string, sys, types
## import Tkinter, tkColorChooser
import gobject, gtk
from gtk import gdk
## # PySol imports
## from pysollib.mfxutil import destruct, Struct, KwStruct
## from pysollib.resource import CSI
from pysollib.resource import CSI
from pysollib.mfxutil import kwdefault, KwStruct
## # Toolkit imports
# Toolkit imports
## from tkutil import loadImage
## from tkwidget import MfxDialog, MfxScrolledCanvas
## from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
## from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas
from tkwidget import MfxDialog
from tkcanvas import MfxCanvas
from tkutil import setTransient
class SelectTileDialogWithPreview(MfxDialog):
def __init__(self, parent, title, app, manager, key=None, **kw):
kw = self.initKw(kw)
MfxDialog.__init__(self, parent, title, **kw)
#
top_box, bottom_box = self.createBox()
#
if key is None:
key = manager.getSelected()
self.app = app
self.manager = manager
self.key = key
self.preview_key = -1
self.all_keys = []
self.table_color = app.opt.table_color
sw = gtk.ScrolledWindow()
sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
top_box.pack_start(sw)
#
model = self._create_tree_model(manager, key)
treeview = gtk.TreeView(model)
treeview.set_rules_hint(True)
treeview.set_headers_visible(False)
renderer = gtk.CellRendererText()
renderer.set_property('xalign', 0.0)
column = gtk.TreeViewColumn('Tiles', renderer, text=0)
column.set_clickable(True)
treeview.append_column(column)
sw.add(treeview)
treeview.expand_all()
selection = treeview.get_selection()
selection.connect('changed', self.treeview_show_selected)
treeview.connect('row-activated', self.row_activated)
self.treeview = treeview
#
self.preview = MfxCanvas(top_box) # width=w2
top_box.pack_end(self.preview)
self.preview.show()
self.createButtons(bottom_box, kw)
self.updatePreview(key)
self.show_all()
gtk.main()
def _getSelected(self):
selection = self.treeview.get_selection()
model, path = selection.get_selected_rows()
if not path:
return None
iter = model.get_iter(path[0])
index = model.get_value(iter, 1)
if index < 0:
return None
return self.all_keys[index]
def row_activated(self, w, row, col):
print 'row_activated_event', row, col
def treeview_show_selected(self, w):
key = self._getSelected()
self.updatePreview(key)
def _create_tree_model(self, manager, key):
self.all_keys = []
index = 0
#
model = gtk.TreeStore(gobject.TYPE_STRING,
gobject.TYPE_INT)
#
iter = model.append(None)
model.set(iter, 0, _('Solid color'), 1, -1)
for color, value in ((_('Blue'), '#0082df'),
(_('Green'), '#008200'),
(_('Navy'), '#000086'),
(_('Olive'), '#868200'),
(_('Orange'), '#f79600'),
(_('Teal'), '#008286'),):
child_iter = model.append(iter)
model.set(child_iter, 0, color, 1, index)
self.all_keys.append(value)
index += 1
#
tiles = manager.getAllSortedByName()
tiles = filter(lambda obj: not obj.error, tiles)
tiles = filter(lambda tile: tile.index > 0 and tile.filename, tiles)
#
iter = model.append(None)
model.set(iter, 0, _('All Backgrounds'), 1, -1)
if tiles:
for tile in tiles:
child_iter = model.append(iter)
model.set(child_iter, 0, tile.name, 1, index)
self.all_keys.append(tile.index)
index += 1
else:
child_iter = model.append(iter)
model.set(child_iter, 0, _('(no tiles)'), 1, -1)
return model
def updatePreview(self, key):
##print 'updatePreview:', key
if key is None:
return
if key == self.preview_key:
return
canvas = self.preview
canvas.deleteAllItems()
if type(key) is str:
# solid color
canvas.config(bg=key)
##canvas.setTile(None)
##canvas.setTextColor(None)
self.preview_key = key
self.table_color = key
else:
# image
tile = self.manager.get(key)
if tile:
if self.preview.setTile(self.app, key):
return
self.preview_key = -1
def initKw(self, kw):
kwdefault(kw,
strings=(_('&OK'), _('&Solid color...'), _('&Cancel'),),
default=0,
resizable=1,
font=None,
padx=10, pady=10,
width=600, height=400,
##~ buttonpadx=10, buttonpady=5,
)
return MfxDialog.initKw(self, kw)
def _colorselOkClicked(self, w, d):
c = d.colorsel.get_current_color()
c = '#%02x%02x%02x' % (c.red/256, c.green/256, c.blue/256)
d.destroy()
self.updatePreview(c)
selection = self.treeview.get_selection()
selection.unselect_all()
def createColorsel(self):
win = gtk.ColorSelectionDialog('Select table color')
win.help_button.destroy()
win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
if type(self.preview_key) is str:
color = self.preview_key
else:
color = self.app.opt.table_color
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)
win.cancel_button.connect('clicked', lambda w: win.destroy())
setTransient(win, self)
win.show()
def done(self, button):
b = button.get_data('user_data')
if b == 1:
self.createColorsel()
return
if b == 0:
self.key = self._getSelected()
if not self.key:
self.key = self.preview_key
self.status = 0
self.button = b
self.hide()
self.quit()

View file

@ -33,7 +33,6 @@
# imports
import os, sys
import gtk
TRUE, FALSE = True, False
# PySol imports
@ -42,25 +41,54 @@ TRUE, FALSE = True, False
# //
# ************************************************************************/
class PysolStatusbar:
def __init__(self, top):
class BasicStatusbar:
def __init__(self, top, row, column, columnspan):
self.top = top
self.side = '#init#'
self._widgets = []
self.hbox = gtk.HBox()
top.table.attach(self.hbox,
column, column+columnspan, row, row+1,
gtk.EXPAND | gtk.FILL, 0,
0, 0)
self.createLabel('space', width=2)
def createLabel(self, name, fill=False, expand=False, grip=False, width=0):
label = gtk.Statusbar()
self.hbox.pack_start(label, fill=fill, expand=expand)
label.show()
if not grip:
label.set_has_resize_grip(False)
setattr(self, name + "_label", label)
label.set_size_request(width*8, -1)
##lb = label.get_children()[0].get_children()[0]
##lb.set_justify(gtk.JUSTIFY_CENTER)
self._widgets.append(label)
##label.push(0, '')
def updateText(self, **kw):
pass
for k, v in kw.items():
label = getattr(self, k + "_label")
label.pop(0)
label.push(0, unicode(v))
def configLabel(self, name, **kw):
print 'statusbar.configLabel', kw
pass
def show(self, side='bottom', resize=0):
return 0
def show(self, show=True, resize=False):
if show:
self.hbox.show()
else:
self.hbox.hide()
return True
def hide(self, resize=0):
self.show(None, resize)
def hide(self, resize=False):
self.show(False, resize)
return True
def getSide(self):
return self.side
def destroy(self):
pass
@ -69,7 +97,25 @@ class PysolStatusbar:
# /***********************************************************************
# //
# ************************************************************************/
class PysolStatusbar(BasicStatusbar):
def __init__(self, top):
BasicStatusbar.__init__(self, top, row=4, column=0, columnspan=3)
#
for n, t, w in (
("time", _("Playing time"), 10),
("moves", _('Moves/Total moves'), 10),
("gamenumber", _("Game number"), 26),
("stats", _("Games played: won/lost"), 12),
):
self.createLabel(n, width=w)
#
l = self.createLabel("info", fill=True, expand=True, grip=True)
class HelpStatusbar(BasicStatusbar):
def __init__(self, top):
BasicStatusbar.__init__(self, top, row=5, column=0, columnspan=3)
self.createLabel("info", fill=True, expand=True)
class HelpStatusbar(PysolStatusbar):
pass

View file

@ -51,6 +51,7 @@
# imports
import os, sys, types
import gobject
import gtk
from gtk import gdk
import gnome.canvas
@ -123,6 +124,10 @@ class _CanvasItem:
def hide(self):
self._item.hide()
def connect(self, signal, func, args):
##print signal
self._item.connect('event', func, args)
class MfxCanvasGroup(_CanvasItem):
def __init__(self, canvas):
@ -148,15 +153,49 @@ class MfxCanvasImage(_CanvasItem):
self._item.set(pixbuf=image.pixbuf)
## arrow = MfxCanvasLine(self.canvas, x1, y1, x2, y2, width=7,
## fill=self.app.opt.hintarrow_color,
## arrow="last", arrowshape=(30,30,10))
## arrow = MfxCanvasLine(game.canvas,
## coords,
## {'width': w,
## 'fill': game.app.opt.hintarrow_color,
## ##'arrow': 'last',
## ##'arrowshape': (s1, s1, s2)
## }
## )
class MfxCanvasLine(_CanvasItem):
def __init__(self, canvas, x1, y1, x2, y2, width, fill, arrow, arrowshape):
def __init__(self, canvas, *points, **kw):
_CanvasItem.__init__(self, canvas)
# FIXME
self._item = None
kwargs = {}
if kw.has_key('arrow'):
if kw['arrow'] == 'first':
kwargs['first_arrowhead'] = True
elif kw['arrow'] == 'last':
kwargs['last_arrowhead'] = True
elif kw['arrow'] == 'both':
kwargs['first_arrowhead'] = True
kwargs['last_arrowhead'] = True
if kw.has_key('fill'):
kwargs['fill_color'] = kw['fill']
if kw.has_key('width'):
kwargs['width_units'] = float(kw['width'])
if kw.has_key('arrowshape'):
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)
self._item.show()
canvas.show_all()
class MfxCanvasRectangle(_CanvasItem):
def __init__(self, canvas, x1, y1, x2, y2, width, fill, outline):
_CanvasItem.__init__(self, canvas)
self._item = canvas.root().add('rect', x1=x1, y1=y1, x2=x2, y2=y2,
width_pixels=width, outline_color=outline)
if fill is not None:
@ -209,11 +248,14 @@ class MfxCanvasText(_CanvasItem):
class MfxCanvas(gnome.canvas.Canvas):
def __init__(self, top, bg=None, highlightthickness=0):
print 'MfxCanvas', bg
self.preview = 0
# Tkinter compat
self.items = {}
self._all_items = []
self._text_items = []
self._width, self._height = -1, -1
self._tile = None
# private
self.__tileimage = None
self.__tiles = []
@ -226,20 +268,28 @@ class MfxCanvas(gnome.canvas.Canvas):
c = self.get_colormap().alloc(bg)
style.bg[gtk.STATE_NORMAL] = c
self.set_style(style)
##self.set_scroll_region(0, 0, gdk.screen_width(), gdk.screen_height())
top.table.attach(self,
0, 1, 2, 3,
gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL,
0, 0)
self.top_bg = top.style.bg[gtk.STATE_NORMAL]
##
self.top = top
self.xmargin, self.ymargin = 0, 0
self.connect('size-allocate', self._sizeAllocate)
def __setattr__(self, name, value):
self.__dict__[name] = value
def _sizeAllocate(self, w, rect):
##print '_sizeAllocate', rect.x, rect.y, rect.width, rect.height
if self._width > 0:
w = self._width
h = min(self._height, rect.height)
self.set_scroll_region(0,0,w,h)
if self._tile and self._tile.filename:
self._setTile()
def bind(self, sequence=None, func=None, add=None):
assert add is None
# FIXME
@ -292,6 +342,9 @@ class MfxCanvas(gnome.canvas.Canvas):
i._item.destroy()
##i._item = None
self._all_items = []
if self.__tileimage:
self.__tileimage.destroy()
self.__tileimage = None
# PySol extension
def findCard(self, stack, event):
@ -312,8 +365,8 @@ class MfxCanvas(gnome.canvas.Canvas):
# PySol extension - set a tiled background image
def setTile(self, app, i, force=False):
##print 'setTile'
tile = app.tabletile_manager.get(i)
##print 'setTile', i, tile
if tile is None or tile.error:
return False
if i == 0:
@ -326,18 +379,20 @@ class MfxCanvas(gnome.canvas.Canvas):
if not force:
if i == app.tabletile_index and tile.color == app.opt.table_color:
return False
if self._tile is tile:
return False
#
if not self._setTile(tile.filename, tile.stretch):
tile.error = True
return False
self._tile = tile
if i == 0:
if self.__tileimage:
self.__tileimage.destroy()
self.__tileimage = None
self.configure(bg=tile.color)
##app.top.config(bg=tile.color)
color = None
else:
self.configure(bg=app.top_bg)
##app.top.config(bg=app.top_bg)
self._setTile()
self.configure(bg=self.top_bg)
color = tile.text_color
if app.opt.table_text_color:
@ -349,36 +404,56 @@ class MfxCanvas(gnome.canvas.Canvas):
### FIXME: should use style.bg_pixmap ????
def _setTile(self, image, stretch=False):
self.realize()
self.show_now()
sw, sh = self.get_size()
print self.get_size()
return
try:
if image and type(image) is types.StringType:
image = loadImage(image)
except:
return 0
for item in self.__tiles:
item.destroy()
self.__tiles = []
# must keep a reference to the image, otherwise Python will
# garbage collect it...
self.__tileimage = image
if image is None:
return 1
iw, ih = image.width(), image.height()
sw = max(self.winfo_screenwidth(), 1024)
sh = max(self.winfo_screenheight(), 768)
for x in range(0, sw - 1, iw):
for y in range(0, sh - 1, ih):
item = self.root().add('image', x=x, y=y, width=iw, height=ih,
image=image.im._im,
anchor=gtk.ANCHOR_NW)
item.lower_to_bottom()
self.__tiles.append(item)
return 1
def _setTile(self):
if not self._tile:
return
##print '_setTile:', self.get_size(), self._tile.filename
#
filename = self._tile.filename
stretch = self._tile.stretch
if not filename:
return False
if not self.window: # not realized yet
return False
self.setBackgroundImage(filename, stretch)
def setBackgroundImage(self, filename, stretch):
width, height = self.get_size()
pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
w, h = pixbuf.get_width(), pixbuf.get_height()
dx, dy = self.world_to_window(0, 0)
dx, dy = int(dx), int(dy)
if self.__tileimage:
self.__tileimage.destroy()
self.__tileimage = None
if stretch:
bg_pixbuf = pixbuf.scale_simple(width, height, gdk.INTERP_BILINEAR)
else:
bg_pixbuf = gdk.Pixbuf(pixbuf.get_colorspace(),
pixbuf.get_has_alpha(),
pixbuf.get_bits_per_sample(),
width, height)
y = 0
while y < height:
x = 0
while x < width:
ww = min(w, width-x)
hh = min(h, height-y)
pixbuf.copy_area(0, 0, ww, hh, bg_pixbuf, x, y)
x += w
y += h
w = self.root().add(gnome.canvas.CanvasPixbuf,
pixbuf=bg_pixbuf, x=0-dx, y=0-dy)
w.lower_to_bottom()
self.__tileimage = w
def setTopImage(self, image, cw=0, ch=0):
## FIXME
@ -386,25 +461,31 @@ class MfxCanvas(gnome.canvas.Canvas):
def update_idletasks(self):
##print 'MfxCanvas.update_idletasks'
#gdk.window_process_all_updates()
#self.show_now()
self.update_now()
##gdk.window_process_all_updates()
self.show_now()
def grid(self, *args, **kw):
#print '1 >->', self.window
if self.window:
#print '2 >->', self.window
self.window.resize(self._width, self._height)
self.top.table.attach(self,
0, 1, 2, 3,
gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL | gtk.SHRINK,
0, 0)
self.show()
def _resize(self):
##print '_resize:', self._width, self._height
#if self.window:
self.set_size(self._width, self._height)
self.window.resize(self._width, self._height)
def setInitialSize(self, width, height):
print 'setInitialSize:', width, height
##print 'setInitialSize:', width, height
self._width, self._height = width, height
self.set_size_request(width, height)
#self.set_size(width, height)
#self.queue_resize()
self.set_scroll_region(0,0,width,height)
#if self.window:
# self.window.resize(width, height)
gobject.idle_add(self._resize, priority=gobject.PRIORITY_HIGH_IDLE)
class MfxScrolledCanvas(MfxCanvas):

View file

@ -33,7 +33,8 @@
# imports
import sys, os, string, time, types
import gtk
import gobject
import pango, gtk
from gtk import gdk
TRUE, FALSE = True, False
@ -44,14 +45,13 @@ TRUE, FALSE = True, False
# ************************************************************************/
def wm_withdraw(window):
##window.unmap()
pass
window.hide()
def wm_deiconify(window):
window.show_all()
window.present()
def wm_map(window, maximized=None):
window.show_all()
window.show()
def wm_set_icon(window, icon):
pass
@ -157,12 +157,24 @@ def createImage(width, height, fill, outline=None):
def _wrap_b1_press(e):
return e.type == gdk.BUTTON_PRESS and e.button == 1
def _wrap_b1_double(e):
return e.type == gdk._2BUTTON_PRESS and e.button == 1
def _wrap_b1_control(e):
return e.type == gdk.BUTTON_PRESS and e.button == 1 and (e.state & gdk.CONTROL_MASK)
def _wrap_b1_shift(e):
return e.type == gdk.BUTTON_PRESS and e.button == 1 and (e.state & gdk.SHIFT_MASK)
def _wrap_b2_press(e):
return e.type == gdk.BUTTON_PRESS and e.button == 2
def _wrap_b3_press(e):
return e.type == gdk.BUTTON_PRESS and e.button == 3
def _wrap_b3_control(e):
return e.type == gdk.BUTTON_PRESS and e.button == 3 and (e.state & gdk.CONTROL_MASK)
def _wrap_b1_motion(e):
return e.type == gdk.MOTION_NOTIFY and (e.state & gdk.BUTTON_PRESS_MASK)
@ -172,23 +184,35 @@ def _wrap_b1_release(e):
def _wrap_key_press(e, key):
return e.type == gdk.KEY_PRESS and e.key == key
def _wrap_enter(e):
return e.type == gdk.ENTER_NOTIFY
def _wrap_leave(e):
return e.type == gdk.LEAVE_NOTIFY
_wrap_handlers = {
'<1>': _wrap_b1_press,
'<ButtonPress-1>': _wrap_b1_press,
'<2>': _wrap_b2_press,
'<ButtonPress-2>': _wrap_b2_press,
'<3>': _wrap_b3_press,
'<ButtonPress-3>': _wrap_b3_press,
'<Motion>': _wrap_b1_motion,
'<ButtonRelease-1>': _wrap_b1_release,
'<1>': (_wrap_b1_press, 'button-press-event'),
'<ButtonPress-1>': (_wrap_b1_press, 'button-press-event'),
'<Double-1>': (_wrap_b1_double, 'button-press-event'),
'<Control-1>': (_wrap_b1_control, 'button-press-event'),
'<Shift-1>': (_wrap_b1_shift, 'button-press-event'),
'<2>': (_wrap_b2_press, 'button-press-event'),
'<ButtonPress-2>': (_wrap_b2_press, 'button-press-event'),
'<3>': (_wrap_b3_press, 'button-press-event'),
'<ButtonPress-3>': (_wrap_b3_press, 'button-press-event'),
'<Control-3>': (_wrap_b3_control, 'button-press-event'),
'<Motion>': (_wrap_b1_motion, 'motion-notify-event'),
'<ButtonRelease-1>': (_wrap_b1_release, 'button-release-event'),
'<Enter>': (_wrap_enter, 'enter-notify-event'),
'<Leave>': (_wrap_leave, 'leave-notify-event'),
}
for c in " " + string.letters:
seq = "<" + c + ">"
if not _wrap_handlers.has_key(seq):
_wrap_handlers[seq] = lambda e, key=c: _wrap_key_press(e, key)
#print _wrap_handlers
## for c in " " + string.letters:
## seq = "<" + c + ">"
## if not _wrap_handlers.has_key(seq):
## _wrap_handlers[seq] = lambda e, key=c: _wrap_key_press(e, key)
## import pprint; pprint.pprint(_wrap_handlers)
## NOT BOUND: <Unmap>
__bindings = {}
@ -204,22 +228,20 @@ def _wrap_event(widget, event, l):
def bind(widget, sequence, func, add=None):
wrap = _wrap_handlers.get(sequence)
if not wrap:
##print "NOT BOUND:", sequence
print "NOT BOUND:", sequence
return
# HACK for MfxCanvasItem
if hasattr(widget, '_item'):
widget = widget._item
wrap, signal = wrap
#
k = id(widget)
if __bindings.has_key(k):
__bindings[k].append((wrap, func))
else:
l = [(wrap, func)]
widget.connect('event', _wrap_event, l)
widget.connect(signal, _wrap_event, l)
__bindings[k] = l
def unbind_destroy(widget):
return
k = id(widget)
if __bindings.has_key(k):
## FIXME
@ -231,37 +253,28 @@ def unbind_destroy(widget):
# ************************************************************************/
def after(widget, ms, func, *args):
## FIXME
return None
timer = gtk.timeout_add(ms, func, *args)
return timer
def after_idle(widget, func, *args):
## FIXME
gobject.idle_add(func, *args)
return None
def after_cancel(t):
if t is not None:
## FIXME
pass
gtk.timeout_remove(t)
# /***********************************************************************
# // font
# ************************************************************************/
getFont_cache = {}
def getFont(name, cardw=0):
key = (name, cardw)
font = getFont_cache.get(key)
if font:
return font
# default
### FIXME
font = "Helvetica-14"
font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"
getFont_cache[key] = font
return font
def getTextWidth(text, font=None, root=None):
return 10
if root:
pango_font_desc = pango.FontDescription(font[0]+' '+str(font[1]))
pangolayout = root.create_pango_layout(text)
width = pangolayout.get_pixel_extents()[1][2]
return width
return 0

View file

@ -34,13 +34,15 @@
import os, sys
import gtk
TRUE, FALSE = True, False
from gtk import gdk
# PySol imports
# Toolkit imports
from tkutil import makeToplevel, setTransient, wm_withdraw
from pysollib.mfxutil import kwdefault, KwStruct
# /***********************************************************************
# //
@ -49,8 +51,8 @@ from tkutil import makeToplevel, setTransient, wm_withdraw
class _MyDialog(gtk.Dialog):
def __init__(self):
gtk.Dialog.__init__(self)
self.style = self.get_style().copy()
self.set_style(self.style)
style = self.get_style().copy()
self.set_style(style)
self.connect("destroy", self.quit)
self.connect("delete_event", self.quit)
@ -67,12 +69,13 @@ class MfxDialog(_MyDialog):
def __init__(self, parent, title='',
timeout=0,
resizable=0,
width=-1, height=-1,
text='', justify='center',
strings=("OK",), default=0,
width=0, separatorwidth=0,
separatorwidth=0,
font=None,
buttonfont=None,
padx='20', pady='20',
padx=20, pady=20,
bitmap=None, bitmap_side='left',
bitmap_padx=20, bitmap_pady=20,
image=None, image_side='left',
@ -80,52 +83,116 @@ class MfxDialog(_MyDialog):
_MyDialog.__init__(self)
self.status = 1
self.button = -1
bitmap = None
self.init(parent, text, strings, default, bitmap, TRUE)
#font = "Times-14"
## if font:
## self.style.font = load_font(font)
## self.set_style(self.style)
self.set_title(title)
self.show()
gtk.main()
def init(self, parent, message="", buttons=(), default=-1,
pixmap=None, modal=TRUE):
modal=True
if modal:
setTransient(self, parent)
# settings
if width > 0 or height > 0:
self.set_size_request(width, height)
#self.window.resize(width, height)
self.set_title(title)
#
self.connect('key-press-event', self._keyPressEvent)
self.show()
def createBox(self):
hbox = gtk.HBox(spacing=5)
hbox.set_border_width(5)
self.vbox.pack_start(hbox)
hbox.show()
## if pixmap:
## self.realize()
## pixmap = gtk.Pixmap(self, pixmap)
## hbox.pack_start(pixmap, expand=FALSE)
## pixmap.show()
label = gtk.Label(message)
hbox.pack_start(label)
label.show()
for i in range(len(buttons)):
text = buttons[i]
return hbox, self.action_area
def createBitmaps(self, box, kw):
if kw['bitmap']:
stock = {"info": gtk.STOCK_DIALOG_INFO,
"error": gtk.STOCK_DIALOG_ERROR,
"warning": gtk.STOCK_DIALOG_WARNING,
"question": gtk.STOCK_DIALOG_QUESTION} [kw['bitmap']]
im = gtk.image_new_from_stock(stock, gtk.ICON_SIZE_DIALOG)
box.pack_start(im)
im.xpad, im.ypad = kw['bitmap_padx'], kw['bitmap_pady']
im.show()
elif kw['image']:
im = gtk.Image()
im.set_from_pixbuf(kw['image'].pixbuf)
if kw['image_side'] == 'left':
box.pack_start(im)
else:
box.pack_end(im)
im.xpad, im.ypad = kw['image_padx'], kw['image_pady']
im.show()
def createButtons(self, box, kw):
strings, default = kw['strings'], kw['default']
for i in range(len(strings)):
text = strings[i]
if not text:
continue
text = text.replace('&', '_')
b = gtk.Button(text)
b.set_flags(gtk.CAN_DEFAULT)
if i == default:
b.grab_focus()
b.grab_default()
##~ b.grab_default()
b.set_data("user_data", i)
b.connect("clicked", self.click)
self.action_area.pack_start(b)
b.connect("clicked", self.done)
box.pack_start(b)
b.show()
self.ret = None
def click(self, button):
def initKw(self, kw):
kwdefault(kw,
timeout=0, resizable=0,
text="", justify="center",
strings=(_("&OK"),),
default=0,
width=0,
padx=20, pady=20,
bitmap=None, bitmap_side="left",
bitmap_padx=10, bitmap_pady=20,
image=None, image_side="left",
image_padx=10, image_pady=20,
)
## # default to separator if more than one button
## sw = 2 * (len(kw.strings) > 1)
## kwdefault(kw.__dict__, separatorwidth=sw)
return kw
def done(self, button):
self.status = 0
self.button = button.get_data("user_data")
self.quit()
def _keyPressEvent(self, w, e):
if gdk.keyval_name(e.keyval) == 'Escape':
self.quit()
MfxMessageDialog = MfxDialog
class MfxMessageDialog(MfxDialog):
def __init__(self, parent, title, **kw):
##print 'MfxMessageDialog', kw
kw = self.initKw(kw)
MfxDialog.__init__(self, parent, title, **kw)
top_box, bottom_box = self.createBox()
self.createBitmaps(top_box, kw)
label = gtk.Label(kw['text'])
label.set_justify(gtk.JUSTIFY_CENTER)
label.xpad, label.ypad = kw['padx'], kw['pady']
top_box.pack_start(label)
self.createButtons(bottom_box, kw)
label.show()
gtk.main()
def initKw(self, kw):
if kw.has_key('bitmap'):
kwdefault(kw, width=250, height=150)
return MfxDialog.initKw(self, kw)
# /***********************************************************************
@ -170,13 +237,13 @@ class MfxSimpleEntry(_MyDialog):
self.button = 0
self.status = 1
self.value = value
self.init(parent, label, TRUE)
self.init(parent, label, True)
self.entry.set_text(str(value))
self.set_title(title)
self.show()
gtk.main()
def init(self, parent, message="", modal=TRUE):
def init(self, parent, message="", modal=True):
if modal:
setTransient(self, parent)
box = gtk.VBox(spacing=10)
@ -192,7 +259,7 @@ class MfxSimpleEntry(_MyDialog):
self.entry.show()
self.entry.grab_focus()
button = gtk.Button("OK")
button.connect("clicked", self.click)
button.connect("clicked", self.done)
button.set_flags(CAN_DEFAULT)
self.action_area.pack_start(button)
button.show()
@ -203,7 +270,7 @@ class MfxSimpleEntry(_MyDialog):
self.action_area.pack_start(button)
button.show()
def click(self, button):
def done(self, button):
self.status = 0
self.value = self.entry.get_text()
self.quit()

View file

@ -198,7 +198,7 @@ class _MfxToplevel(gtk.Window):
pass
def wm_deiconify(self):
self.show_all()
self.present()
def wm_geometry(self, newGeometry=None):
##print 'wm_geometry', newGeometry
@ -293,6 +293,7 @@ class MfxRoot(_MfxToplevel):
# FIXME - make sleep interruptible
def sleep(self, seconds):
gdk.window_process_all_updates()
time.sleep(seconds)
def wmDeleteWindow(self, *args):

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

@ -197,10 +197,11 @@ class SelectTileDialogWithPreview(MfxDialog):
canvas.setTextColor(None)
self.preview_key = key
self.table_color = key
return
tile = self.manager.get(key)
if tile:
if self.preview.setTile(self.app, key):
return
self.preview_key = -1
else:
# image
tile = self.manager.get(key)
if tile:
if self.preview.setTile(self.app, key):
return
self.preview_key = -1

View file

@ -40,13 +40,12 @@ __all__ = ['PysolStatusbar',
import os, sys, Tkinter
if __name__ == '__main__':
d = os.path.abspath(os.path.join(sys.path[0], '..', '..'))
d = os.path.abspath(os.path.join(sys.path[0], os.pardir, os.pardir))
sys.path.append(d)
import gettext
gettext.install('pysol', d, unicode=True)
# PySol imports
from pysollib.mfxutil import destruct
# Toolkit imports
from tkwidget import MfxTooltip
@ -137,8 +136,8 @@ class MfxStatusbar:
self._show = show
return True
def hide(self, resize=0):
self.show(None, resize)
def hide(self, resize=False):
self.show(False, resize)
def destroy(self):
for w in self._tooltips: