1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
This commit is contained in:
Shlomi Fish 2017-04-17 14:22:26 +03:00
parent 40dcd6633c
commit 727c1765ad
4 changed files with 120 additions and 98 deletions

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,14 +19,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
# imports
import sys, os, string, time
import string
import gobject
import pango, gtk
import gtk
import pango
from gtk import gdk
@ -37,12 +38,15 @@ from gtk import gdk
def wm_withdraw(window):
window.hide()
def wm_deiconify(window):
window.present()
def wm_map(window, maximized=None):
window.show()
def makeToplevel(parent, title=None, class_=None, gtkclass=gtk.Window):
window = gtkclass()
if not hasattr(window, 'table'):
@ -52,20 +56,20 @@ def makeToplevel(parent, title=None, class_=None, gtkclass=gtk.Window):
window.realize() # needed for set_icon_name()
if title:
window.set_title(title)
##~ window.set_icon_name(title)
# ~ window.set_icon_name(title)
if class_:
## window.set_wmclass(???) ## FIXME
# window.set_wmclass(???) # FIXME
pass
return window
def setTransient(window, parent, relx=0.5, rely=0.3, expose=1):
window.realize()
##~ grab_add(window)
# ~ grab_add(window)
if parent:
window.set_transient_for(parent)
if expose:
#window.unmap() # Become visible at the desired location
# window.unmap() # Become visible at the desired location
pass
@ -122,7 +126,6 @@ class _PysolPixmap:
# FIXME
pass
def clone(self):
pixbuf = self.pixbuf.copy()
im = _PysolPixmap(pixbuf=pixbuf)
@ -145,18 +148,22 @@ class _PysolPixmap:
def loadImage(file):
return _PysolPixmap(file=file)
def copyImage(image, x, y, width, height):
# FIXME
return image.clone()
def createImage(width, height, fill, outline=None):
# FIXME
return _PysolPixmap(width=width, height=height, fill=fill, outline=outline)
def shadowImage(image):
# FIXME
return None
def markImage(image):
# FIXME
return image
@ -172,41 +179,56 @@ def _wrap_b1_press(e):
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
def _wrap_b1_control(e):
return e.type == gdk.BUTTON_PRESS and e.button == 1 and (e.state & gdk.CONTROL_MASK)
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)
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 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)
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)
def _wrap_b1_release(e):
return e.type == gdk.BUTTON_RELEASE and e.button == 1
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, 'button-press-event'),
'<ButtonPress-1>': (_wrap_b1_press, 'button-press-event'),
@ -223,21 +245,22 @@ _wrap_handlers = {
'<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)
## import pprint; pprint.pprint(_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>
# NOT BOUND: <Unmap>
__bindings = {}
def _wrap_event(widget, event, l):
for wrap, func in l:
if wrap(event):
#print "event:", wrap, func, event
# print "event:", wrap, func, event
return func(event)
return 0
@ -245,7 +268,7 @@ 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
wrap, signal = wrap
#
@ -261,7 +284,7 @@ def bind(widget, sequence, func, add=None):
def unbind_destroy(widget):
k = id(widget)
if k in __bindings:
## FIXME
# FIXME
del __bindings[k]
@ -273,10 +296,12 @@ def after(widget, ms, func, *args):
timer = gobject.timeout_add(ms, func, *args)
return timer
def after_idle(widget, func, *args):
gobject.idle_add(func, *args)
return None
def after_cancel(t):
if t is not None:
gobject.source_remove(t)
@ -297,9 +322,8 @@ def create_pango_font_desc(font):
def get_text_width(text, font=None, root=None):
if root:
pango_font_desc = create_pango_font_desc(font)
# pango_font_desc = create_pango_font_desc(font)
pangolayout = root.create_pango_layout(text)
width = pangolayout.get_pixel_extents()[1][2]
return width
return 0

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,28 +19,28 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
# imports
import os, sys
import gtk
gdk = gtk.gdk
# PySol imports
from pysollib.mygettext import _, n_
from pysollib.mygettext import _
# Toolkit imports
from tkutil import makeToplevel, setTransient, wm_withdraw
from tkutil import setTransient
from pysollib.mfxutil import kwdefault, KwStruct, openURL
gdk = gtk.gdk
# ************************************************************************
# *
# ************************************************************************
class _MyDialog(gtk.Dialog):
def __init__(self):
gtk.Dialog.__init__(self)
@ -60,6 +60,7 @@ class _MyDialog(gtk.Dialog):
class MfxDialog(_MyDialog):
img = {}
button_img = {}
def __init__(self, parent, title='',
timeout=0,
resizable=0,
@ -78,19 +79,18 @@ class MfxDialog(_MyDialog):
self.button = -1
self.buttons = []
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.window.resize(width, height)
self.set_title(title)
#
self.connect('key-press-event', self._keyPressEvent)
def createBox(self, widget_class=gtk.HBox):
box = widget_class(spacing=5)
box.set_border_width(5)
@ -112,7 +112,7 @@ class MfxDialog(_MyDialog):
stock = {"info": gtk.STOCK_DIALOG_INFO,
"error": gtk.STOCK_DIALOG_ERROR,
"warning": gtk.STOCK_DIALOG_WARNING,
"question": gtk.STOCK_DIALOG_QUESTION} [kw['bitmap']]
"question": gtk.STOCK_DIALOG_QUESTION}[kw['bitmap']]
im = gtk.image_new_from_stock(stock, gtk.ICON_SIZE_DIALOG)
box.pack_start(im)
im.set_property('xpad', kw['bitmap_padx'])
@ -137,14 +137,14 @@ class MfxDialog(_MyDialog):
continue
if isinstance(text, (list, tuple)):
text, index = text
else: # str
else: # str
index = i
text = text.replace('&', '_')
b = gtk.Button(text)
b.set_property('can-default', True)
if index == default:
b.grab_focus()
#b.grab_default()
# b.grab_default()
b.set_data("user_data", index)
b.connect("clicked", self.done)
box.pack_start(b)
@ -164,9 +164,9 @@ class MfxDialog(_MyDialog):
image=None, image_side="left",
image_padx=10, image_pady=20,
)
## # default to separator if more than one button
## sw = len(kw.strings) > 1
## kwdefault(kw.__dict__, separator=sw)
# # default to separator if more than one button
# sw = len(kw.strings) > 1
# kwdefault(kw.__dict__, separator=sw)
return kw
def done(self, button):
@ -181,7 +181,7 @@ class MfxDialog(_MyDialog):
class MfxMessageDialog(MfxDialog):
def __init__(self, parent, title, **kw):
##print 'MfxMessageDialog', kw
# print 'MfxMessageDialog', kw
kw = self.initKw(kw)
MfxDialog.__init__(self, parent, title, **kw)
@ -198,13 +198,13 @@ class MfxMessageDialog(MfxDialog):
label.show()
self.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
##self.set_position(gtk.WIN_POS_CENTER)
# self.set_position(gtk.WIN_POS_CENTER)
self.show_all()
gtk.main()
def initKw(self, kw):
#if kw.has_key('bitmap'):
# if kw.has_key('bitmap'):
# kwdefault(kw, width=250, height=150)
return MfxDialog.initKw(self, kw)
@ -243,14 +243,14 @@ class PysolAboutDialog(MfxDialog):
self.createButtons(bottom_box, kw)
self.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
##self.set_position(gtk.WIN_POS_CENTER)
# self.set_position(gtk.WIN_POS_CENTER)
self.show_all()
event_box.window.set_cursor(gdk.Cursor(gdk.HAND2))
gtk.main()
def initKw(self, kw):
#if kw.has_key('bitmap'):
# if kw.has_key('bitmap'):
# kwdefault(kw, width=250, height=150)
return MfxDialog.initKw(self, kw)
@ -270,7 +270,8 @@ class MfxExceptionDialog(MfxDialog):
text = text + "\n"
text = text + "\n"
if isinstance(ex, EnvironmentError) and ex.filename is not None:
t = '[Errno %s] %s:\n%s' % (ex.errno, ex.strerror, repr(ex.filename))
t = '[Errno %s] %s:\n%s' % \
(ex.errno, ex.strerror, repr(ex.filename))
else:
t = str(ex)
kw.text = text + t
@ -326,10 +327,5 @@ class MfxSimpleEntry(_MyDialog):
self.quit()
class SelectDialogTreeData:
pass

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,21 +19,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
# imports
import os, sys, time, types
import time
import gtk
from gtk import gdk
# PySol imports
## from pysollib.images import Images
# from pysollib.images import Images
from pysollib.settings import TITLE, VERSION
# Toolkit imports
from tkutil import makeToplevel, loadImage
from tkutil import makeToplevel
# ************************************************************************
@ -43,8 +43,10 @@ from tkutil import makeToplevel, loadImage
class TclError:
pass
def make_help_toplevel(parent, title=None, class_=None):
return makeToplevel(parent, title=title, class_=class_, gtkclass=_MfxToplevel)
return makeToplevel(
parent, title=title, class_=class_, gtkclass=_MfxToplevel)
# ************************************************************************
@ -54,9 +56,9 @@ def make_help_toplevel(parent, title=None, class_=None):
class _MfxToplevel(gtk.Window):
def __init__(self, *args, **kw):
gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL)
#self.vbox = gtk.VBox()
#self.vbox.show()
#self.add(self.vbox)
# self.vbox = gtk.VBox()
# self.vbox.show()
# self.add(self.vbox)
self.table = gtk.Table(3, 6, False)
self.add(self.table)
self.connect('destroy', self.mainquit)
@ -67,20 +69,20 @@ class _MfxToplevel(gtk.Window):
if attr == 'cursor':
# FIXME
return gdk.LEFT_PTR
return self.get_window().get_cursor(v)
# return self.get_window().get_cursor(v)
elif attr in ("background", "bg"):
c = self.style.bg[gtk.STATE_NORMAL]
c = '#%02x%02x%02x' % (c.red/256, c.green/256, c.blue/256)
return c
print "Toplevel cget:", attr
##~ raise AttributeError, attr
print("Toplevel cget:", attr)
# ~ raise AttributeError, attr
return None
def configure(self, **kw):
height, width = -1, -1
for k, v in kw.items():
if k in ("background", "bg"):
##print "Toplevel configure: bg"
# print "Toplevel configure: bg"
pass
elif k == "cursor":
self.setCursor(v)
@ -89,17 +91,16 @@ class _MfxToplevel(gtk.Window):
elif k == "width":
width = v
else:
print "Toplevel configure:", k, v
raise AttributeError, k
print("Toplevel configure:", k, v)
raise AttributeError(k)
if height > 0 and width > 0:
##print 'configure: size:', width, height
## FIXME
#self.set_default_size(width, height)
#self.set_size_request(width, height)
#self.set_geometry_hints(base_width=width, base_height=height)
# print 'configure: size:', width, height
# FIXME
# self.set_default_size(width, height)
# self.set_size_request(width, height)
# self.set_geometry_hints(base_width=width, base_height=height)
pass
config = configure
def mainloop(self):
@ -112,7 +113,8 @@ class _MfxToplevel(gtk.Window):
pass
def setCursor(self, cursor):
self.get_window().set_cursor(cursor_new(v))
# self.get_window().set_cursor(cursor_new(v))
pass
def tk_setPalette(self, *args):
# FIXME ?
@ -122,7 +124,7 @@ class _MfxToplevel(gtk.Window):
self.update_idletasks()
def update_idletasks(self):
##print '_MfxToplevel.update_idletasks'
# print '_MfxToplevel.update_idletasks'
while gtk.events_pending():
gtk.main_iteration(True)
@ -137,7 +139,7 @@ class _MfxToplevel(gtk.Window):
return gdk.screen_height()
def winfo_screendepth(self):
##print 'winfo_screendepth', self.window.get_geometry()
# print 'winfo_screendepth', self.window.get_geometry()
return self.window.get_geometry()[-1]
def wm_command(self, *args):
@ -148,35 +150,35 @@ class _MfxToplevel(gtk.Window):
self.present()
def wm_geometry(self, newGeometry=None):
##print 'wm_geometry', newGeometry
# print 'wm_geometry', newGeometry
if not newGeometry:
pass
##self.reshow_with_initial_size()
##self.resize(1, 1)
# self.reshow_with_initial_size()
# self.resize(1, 1)
else:
pass
##w, h = newGeometry
##self.resize(w, h)
# w, h = newGeometry
# self.resize(w, h)
def wm_group(self, pathName=None):
# FIXME
pass
def wm_iconbitmap(self, name):
print 'wm_iconbitmap:', name
print('wm_iconbitmap:', name)
if name and name[0] == '@' and name[-4:] == '.xbm':
name = name[1:-4] + '.xpm'
bg = self.get_style().bg[gtk.STATE_NORMAL]
pixmap, mask = create_pixmap_from_xpm(self, bg, name)
self.set_icon(pixmap, mask)
# bg = self.get_style().bg[gtk.STATE_NORMAL]
# pixmap, mask = create_pixmap_from_xpm(self, bg, name)
# self.set_icon(pixmap, mask)
def wm_iconname(self, name):
pass
##~ self.set_icon_name(name)
# ~ self.set_icon_name(name)
def wm_minsize(self, width, height):
pass
##~ self.set_geometry_hints(min_width=width, min_height=height)
# ~ self.set_geometry_hints(min_width=width, min_height=height)
def wm_title(self, title):
self.set_title(title)
@ -185,33 +187,32 @@ class _MfxToplevel(gtk.Window):
self.present()
def option_add(self, *args):
##print self, 'option_add'
# print self, 'option_add'
pass
def option_get(self, *args):
if args and args[0] == 'font':
return self.get_style().font_desc.to_string()
print '_MfxToplevel: option_get', args
print('_MfxToplevel: option_get', args)
return None
def grid_columnconfigure(self, *args, **kw):
##print self, 'grid_columnconfigure'
# print self, 'grid_columnconfigure'
pass
def grid_rowconfigure(self, *args, **kw):
##print self, 'grid_rowconfigure'
# print self, 'grid_rowconfigure'
pass
def interruptSleep(self, *args, **kw):
##print self, 'interruptSleep'
# print self, 'interruptSleep'
pass
def wm_state(self):
##print self, 'wm_state'
# print self, 'wm_state'
pass
# ************************************************************************
# * The root toplevel window of an application.
# ************************************************************************
@ -226,21 +227,22 @@ class MfxRoot(_MfxToplevel):
self.app = app
def initToolkit(self, app, fg=None, bg=None, font=None, theme=None):
sw, sh, sd = self.winfo_screenwidth(), self.winfo_screenheight(), self.winfo_screendepth()
##self.wm_group(self)
sw, sh = self.winfo_screenwidth(), self.winfo_screenheight()
# self.wm_group(self)
self.wm_title(TITLE + ' ' + VERSION)
##self.wm_iconname(TITLE + ' ' + VERSION)
# self.wm_iconname(TITLE + ' ' + VERSION)
if sw < 640 or sh < 480:
self.wm_minsize(400, 300)
else:
self.wm_minsize(520, 360)
##self.self.wm_maxsize(9999, 9999) # unlimited
# self.self.wm_maxsize(9999, 9999) # unlimited
# sometimes an update() is needed under Windows, whereas
# under Unix an update_idletask() would be enough...
def busyUpdate(self):
game = None
if self.app: game = self.app.game
if self.app:
game = self.app.game
if not game:
self.update()
elif not game.busy:
@ -257,6 +259,6 @@ class MfxRoot(_MfxToplevel):
if self.app and self.app.menubar:
self.app.menubar.mQuit()
else:
##self.after_idle(self.quit)
# self.after_idle(self.quit)
pass
return True

View file

@ -10,7 +10,7 @@ use String::ShellQuote qw/ shell_quote /;
# my $cmd = shell_quote( 'flake8', '.' );
my $cmd = shell_quote( 'flake8',
grep { not($_ eq './pysollib/pysoltk.py') } glob('./pysollib/*.py ./pysollib/[cm]*/*.py ./pysollib/pysolgtk/{[a-s]*,t[a-i]*,tk[a-s]*}.py') );
grep { not($_ eq './pysollib/pysoltk.py') } glob('./pysollib/*.py ./pysollib/[cm]*/*.py ./pysollib/pysolgtk/{[a-s]*,t[a-i]*,tk*}.py') );
# TEST
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );