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

Merge tile/tkutil.py and tk/tkutil.py.

They were identical.
This commit is contained in:
Shlomi Fish 2016-02-14 15:27:54 +02:00
parent 84e8e39e59
commit 1d7fb6fd61
29 changed files with 36 additions and 452 deletions

View file

@ -138,7 +138,7 @@ The toolkit layer
Important modules of the Tkinter implementation: Important modules of the Tkinter implementation:
tk/tkconst.py, tk/tkutil.py, tk/tkwidget.py, tk/edittextdialog: tk/tkconst.py, ui/tktile/tkutil.py, tk/tkwidget.py, tk/edittextdialog:
Toolkit constants, utils and generic widgets. Toolkit constants, utils and generic widgets.
tk/tkcanvas.py: tk/tkcanvas.py:

View file

@ -25,8 +25,8 @@ from pysollib.settings import TOOLKIT, USE_TILE
if TOOLKIT == 'tk': if TOOLKIT == 'tk':
from pysollib.ui.tktile.tkconst import * from pysollib.ui.tktile.tkconst import *
from pysollib.ui.tktile.tkutil import *
if USE_TILE: if USE_TILE:
from pysollib.tile.tkutil import *
from pysollib.tile.tkcanvas import * from pysollib.tile.tkcanvas import *
from pysollib.tile.tkwrap import * from pysollib.tile.tkwrap import *
from pysollib.tile.tkwidget import * from pysollib.tile.tkwidget import *
@ -49,7 +49,6 @@ if TOOLKIT == 'tk':
from pysollib.tile.selectcardset import * from pysollib.tile.selectcardset import *
from pysollib.tile.selecttree import * from pysollib.tile.selecttree import *
else: else:
from pysollib.tk.tkutil import *
from pysollib.tk.tkcanvas import * from pysollib.tk.tkcanvas import *
from pysollib.tk.tkwrap import * from pysollib.tk.tkwrap import *
from pysollib.tk.tkwidget import * from pysollib.tk.tkwidget import *

View file

@ -32,8 +32,8 @@ import Tkinter
from pysollib.mygettext import _, n_ from pysollib.mygettext import _, n_
# Toolkit imports # Toolkit imports
from tkutil import after, after_cancel from pysollib.ui.tktile.tkutil import after, after_cancel
from tkutil import bind, unbind_destroy, makeImage from pysollib.ui.tktile.tkutil import bind, unbind_destroy, makeImage
from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle
from pysollib.settings import TITLE from pysollib.settings import TITLE

View file

@ -34,7 +34,7 @@ from pysollib.mygettext import _, n_
# Toolkit imports # Toolkit imports
from tkwidget import MfxDialog from tkwidget import MfxDialog
from tkutil import bind from pysollib.ui.tktile.tkutil import bind
from tkwidget import PysolScale from tkwidget import PysolScale

View file

@ -43,7 +43,7 @@ from pysollib.gamedb import GI
# toolkit imports # toolkit imports
from pysollib.ui.tktile.tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS from pysollib.ui.tktile.tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS
from tkutil import bind, after_idle from pysollib.ui.tktile.tkutil import bind, after_idle
from tkwidget import MfxMessageDialog from tkwidget import MfxMessageDialog
from selectgame import SelectGameDialog, SelectGameDialogWithPreview from selectgame import SelectGameDialog, SelectGameDialogWithPreview
from soundoptionsdialog import SoundOptionsDialog from soundoptionsdialog import SoundOptionsDialog

View file

@ -29,7 +29,7 @@ import ttk
# Toolkit imports # Toolkit imports
from pysollib.ui.tktile.tkconst import EVENT_HANDLED from pysollib.ui.tktile.tkconst import EVENT_HANDLED
from tkutil import makeToplevel, setTransient from pysollib.ui.tktile.tkutil import makeToplevel, setTransient
# ************************************************************************ # ************************************************************************
@ -119,7 +119,7 @@ class TestProgressBar:
self.progress.frame.after(30, self.update) self.progress.frame.after(30, self.update)
def progressbar_main(args): def progressbar_main(args):
from tkutil import wm_withdraw from pysollib.ui.tktile.tkutil import wm_withdraw
tk = Tkinter.Tk() tk = Tkinter.Tk()
wm_withdraw(tk) wm_withdraw(tk)
pb = TestProgressBar(tk) pb = TestProgressBar(tk)

View file

@ -36,7 +36,7 @@ from pysollib.util import CARDSET
from pysollib.resource import CSI from pysollib.resource import CSI
# Toolkit imports # Toolkit imports
from tkutil import loadImage from pysollib.ui.tktile.tkutil import loadImage
from tkwidget import MfxDialog, MfxScrolledCanvas, PysolScale from tkwidget import MfxDialog, MfxScrolledCanvas, PysolScale
from tkcanvas import MfxCanvasImage from tkcanvas import MfxCanvasImage
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode

View file

@ -35,7 +35,7 @@ from pysollib.gamedb import GI
from pysollib.resource import CSI from pysollib.resource import CSI
# Toolkit imports # Toolkit imports
from tkutil import unbind_destroy from pysollib.ui.tktile.tkutil import unbind_destroy
from tkwidget import MfxDialog, MfxScrolledCanvas from tkwidget import MfxDialog, MfxScrolledCanvas
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas

View file

@ -36,7 +36,7 @@ import Canvas
from pysollib.mfxutil import Image, ImageTk from pysollib.mfxutil import Image, ImageTk
# Toolkit imports # Toolkit imports
from tkutil import bind, unbind_destroy, loadImage from pysollib.ui.tktile.tkutil import bind, unbind_destroy, loadImage
# ************************************************************************ # ************************************************************************

View file

@ -41,7 +41,7 @@ from pysollib.mfxutil import Struct, openURL
from pysollib.settings import TITLE from pysollib.settings import TITLE
# Toolkit imports # Toolkit imports
from tkutil import bind, unbind_destroy from pysollib.ui.tktile.tkutil import bind, unbind_destroy
from tkwidget import MfxMessageDialog from tkwidget import MfxMessageDialog
from statusbar import HtmlStatusbar from statusbar import HtmlStatusbar

View file

@ -46,7 +46,7 @@ from pysollib.stats import PysolStatsFormatter, ProgressionFormatter
from pysollib.settings import TOP_TITLE from pysollib.settings import TOP_TITLE
# Toolkit imports # Toolkit imports
from tkutil import bind, unbind_destroy, loadImage from pysollib.ui.tktile.tkutil import bind, unbind_destroy, loadImage
from tkwidget import MfxDialog, MfxMessageDialog from tkwidget import MfxDialog, MfxMessageDialog

View file

@ -26,7 +26,7 @@ import os
import Tkinter import Tkinter
# Toolkit imports # Toolkit imports
from tkutil import bind from pysollib.ui.tktile.tkutil import bind
from tkwidget import MfxScrolledCanvas from tkwidget import MfxScrolledCanvas

View file

@ -44,9 +44,9 @@ from pysollib.mfxutil import destruct, kwdefault, KwStruct, openURL
from pysollib.settings import WIN_SYSTEM from pysollib.settings import WIN_SYSTEM
# Toolkit imports # Toolkit imports
from tkutil import after, after_cancel from pysollib.ui.tktile.tkutil import after, after_cancel
from tkutil import bind, unbind_destroy from pysollib.ui.tktile.tkutil import bind, unbind_destroy
from tkutil import makeToplevel, setTransient from pysollib.ui.tktile.tkutil import makeToplevel, setTransient
from tkcanvas import MfxCanvas from tkcanvas import MfxCanvas

View file

@ -40,7 +40,7 @@ from pysollib.winsystems import TkSettings
from pysollib.ui.tktile.tkconst import EVENT_HANDLED from pysollib.ui.tktile.tkconst import EVENT_HANDLED
from tkwidget import MfxTooltip from tkwidget import MfxTooltip
from menubar import createToolbarMenu, MfxMenu from menubar import createToolbarMenu, MfxMenu
from tkutil import loadImage from pysollib.ui.tktile.tkutil import loadImage
# ************************************************************************ # ************************************************************************

View file

@ -35,8 +35,8 @@ import Tkinter
from pysollib.mygettext import _, n_ from pysollib.mygettext import _, n_
# Toolkit imports # Toolkit imports
from tkutil import after, after_cancel from pysollib.ui.tktile.tkutil import after, after_cancel
from tkutil import bind, unbind_destroy, makeImage from pysollib.ui.tktile.tkutil import bind, unbind_destroy, makeImage
from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle
from pysollib.settings import TITLE from pysollib.settings import TITLE

View file

@ -33,7 +33,7 @@ from pysollib.mfxutil import KwStruct
# Toolkit imports # Toolkit imports
from tkwidget import MfxDialog from tkwidget import MfxDialog
from tkutil import bind from pysollib.ui.tktile.tkutil import bind
# ************************************************************************ # ************************************************************************
# * # *

View file

@ -43,7 +43,7 @@ from pysollib.gamedb import GI
# toolkit imports # toolkit imports
from pysollib.ui.tktile.tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS from pysollib.ui.tktile.tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS
from tkutil import bind, after_idle from pysollib.ui.tktile.tkutil import bind, after_idle
from tkwidget import MfxMessageDialog from tkwidget import MfxMessageDialog
from selectgame import SelectGameDialog, SelectGameDialogWithPreview from selectgame import SelectGameDialog, SelectGameDialogWithPreview
from soundoptionsdialog import SoundOptionsDialog from soundoptionsdialog import SoundOptionsDialog

View file

@ -32,7 +32,7 @@ from pysollib.mfxutil import KwStruct, Struct
# Toolkit imports # Toolkit imports
from tkwidget import MfxDialog from tkwidget import MfxDialog
from tkutil import bind from pysollib.ui.tktile.tkutil import bind
# ************************************************************************ # ************************************************************************
@ -157,7 +157,7 @@ class PlayerOptionsDialog(MfxDialog):
def playeroptionsdialog_main(args): def playeroptionsdialog_main(args):
from tkutil import wm_withdraw from pysollib.ui.tktile.tkutil import wm_withdraw
opt = Struct(player="Test", update_player_stats=1) opt = Struct(player="Test", update_player_stats=1)
app = Struct(opt=opt) app = Struct(opt=opt)
tk = Tkinter.Tk() tk = Tkinter.Tk()

View file

@ -28,7 +28,7 @@ import Tkinter
# Toolkit imports # Toolkit imports
from pysollib.ui.tktile.tkconst import EVENT_HANDLED from pysollib.ui.tktile.tkconst import EVENT_HANDLED
from tkutil import makeToplevel, setTransient from pysollib.ui.tktile.tkutil import makeToplevel, setTransient
# ************************************************************************ # ************************************************************************
@ -132,7 +132,7 @@ class TestProgressBar:
self.progress.frame.after(30, self.update) self.progress.frame.after(30, self.update)
def progressbar_main(args): def progressbar_main(args):
from tkutil import wm_withdraw from pysollib.ui.tktile.tkutil import wm_withdraw
tk = Tkinter.Tk() tk = Tkinter.Tk()
wm_withdraw(tk) wm_withdraw(tk)
pb = TestProgressBar(tk) pb = TestProgressBar(tk)

View file

@ -34,7 +34,7 @@ from pysollib.util import CARDSET
from pysollib.resource import CSI from pysollib.resource import CSI
# Toolkit imports # Toolkit imports
from tkutil import loadImage from pysollib.ui.tktile.tkutil import loadImage
from tkwidget import MfxDialog, MfxScrolledCanvas from tkwidget import MfxDialog, MfxScrolledCanvas
from tkcanvas import MfxCanvasImage from tkcanvas import MfxCanvasImage
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode

View file

@ -36,7 +36,7 @@ from pysollib.help import help_html
from pysollib.resource import CSI from pysollib.resource import CSI
# Toolkit imports # Toolkit imports
from tkutil import unbind_destroy from pysollib.ui.tktile.tkutil import unbind_destroy
from tkwidget import MfxDialog, MfxScrolledCanvas from tkwidget import MfxDialog, MfxScrolledCanvas
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas

View file

@ -35,7 +35,7 @@ import Tkinter, Canvas
from pysollib.mfxutil import Image, ImageTk from pysollib.mfxutil import Image, ImageTk
# Toolkit imports # Toolkit imports
from tkutil import bind, unbind_destroy, loadImage from pysollib.ui.tktile.tkutil import bind, unbind_destroy, loadImage
# ************************************************************************ # ************************************************************************

View file

@ -40,7 +40,7 @@ from pysollib.mfxutil import Struct, openURL
from pysollib.settings import TITLE from pysollib.settings import TITLE
# Toolkit imports # Toolkit imports
from tkutil import bind, unbind_destroy from pysollib.ui.tktile.tkutil import bind, unbind_destroy
from tkwidget import MfxMessageDialog from tkwidget import MfxMessageDialog
from statusbar import HtmlStatusbar from statusbar import HtmlStatusbar

View file

@ -44,7 +44,7 @@ from pysollib.stats import PysolStatsFormatter, ProgressionFormatter
from pysollib.settings import TOP_TITLE from pysollib.settings import TOP_TITLE
# Toolkit imports # Toolkit imports
from tkutil import bind, unbind_destroy, loadImage from pysollib.ui.tktile.tkutil import bind, unbind_destroy, loadImage
from tkwidget import MfxDialog, MfxMessageDialog from tkwidget import MfxDialog, MfxMessageDialog
from tkwidget import MfxScrolledCanvas from tkwidget import MfxScrolledCanvas

View file

@ -26,7 +26,7 @@ import os
import Tkinter import Tkinter
# Toolkit imports # Toolkit imports
from tkutil import bind from pysollib.ui.tktile.tkutil import bind
from tkwidget import MfxScrolledCanvas from tkwidget import MfxScrolledCanvas

View file

@ -1,414 +0,0 @@
#!/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.
## Copyright (C) 2005-2009 Skomoroh
##
## 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 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
##---------------------------------------------------------------------------##
__all__ = ['wm_withdraw',
'wm_deiconify',
'wm_map',
'wm_get_geometry',
#'setTransient',
#'makeToplevel',
'make_help_toplevel',
'bind',
'unbind_destroy',
'after',
'after_idle',
'after_cancel',
#'makeImage',
'copyImage',
'loadImage',
#'fillImage',
'createImage',
'shadowImage',
'markImage',
'createBottom',
'resizeBottom',
'get_text_width',
]
# imports
import re
import Tkinter
from tkFont import Font
# PySol imports
from pysollib.mfxutil import Image, ImageTk, ImageOps
from pysollib.settings import TITLE, WIN_SYSTEM
# ************************************************************************
# * window manager util
# ************************************************************************
def wm_withdraw(window):
window.wm_withdraw()
def wm_deiconify(window):
window.wm_deiconify()
def wm_map(window, maximized=0):
if window.wm_state() != "iconic":
if maximized and WIN_SYSTEM == "win32":
window.wm_state("zoomed")
else:
wm_deiconify(window)
__wm_get_geometry_re = re.compile(r"^(\d+)x(\d+)\+([\-]?\d+)\+([\-]?\d+)$")
def wm_get_geometry(window):
g = window.wm_geometry()
m = __wm_get_geometry_re.search(g)
if not m:
raise Tkinter.TclError("invalid geometry "+str(g))
l = map(int, m.groups())
if window.wm_state() == "zoomed":
# workaround as Tk returns the "unzoomed" origin
l[2] = l[3] = 0
return l
# ************************************************************************
# * window util
# ************************************************************************
def setTransient(window, parent, relx=None, rely=None, expose=1):
# Make an existing toplevel window transient for a parent.
#
# The window must exist but should not yet have been placed; in
# other words, this should be called after creating all the
# subwidget but before letting the user interact.
# remain invisible while we figure out the geometry
window.wm_withdraw()
window.wm_group(parent)
if parent and parent.wm_state() != "withdrawn":
window.wm_transient(parent)
# actualize geometry information
window.update_idletasks()
# show
x, y = __getWidgetXY(window, parent, relx=relx, rely=rely)
window.wm_geometry("+%d+%d" % (x, y))
if expose:
window.wm_deiconify()
def makeToplevel(parent, title=None):
# Create a Toplevel window.
#
# This is a shortcut for a Toplevel() instantiation plus calls to
# set the title and icon name of the window.
window = Tkinter.Toplevel(parent) #, class_=TITLE)
##window.wm_group(parent)
##window.wm_command("")
if WIN_SYSTEM == "x11":
window.wm_command("/bin/true")
##window.wm_protocol("WM_SAVE_YOURSELF", None)
if title:
window.wm_title(title)
window.wm_iconname(title)
return window
def make_help_toplevel(app, title=None):
# Create an independent Toplevel window.
from pysollib.winsystems import init_root_window
window = Tkinter.Tk(className=TITLE)
init_root_window(window, app)
return window
def __getWidgetXY(widget, parent, relx=None, rely=None,
w_width=None, w_height=None):
if w_width is None:
w_width = widget.winfo_reqwidth()
if w_height is None:
w_height = widget.winfo_reqheight()
s_width = widget.winfo_screenwidth()
s_height = widget.winfo_screenheight()
m_x = m_y = 0
m_width, m_height = s_width, s_height
if parent and parent.winfo_ismapped():
##print parent.wm_geometry()
##print parent.winfo_geometry(), parent.winfo_x(), parent.winfo_y(), parent.winfo_rootx(), parent.winfo_rooty(), parent.winfo_vrootx(), parent.winfo_vrooty()
m_x = m_y = None
if WIN_SYSTEM == "win32":
try:
m_width, m_height, m_x, m_y = wm_get_geometry(parent)
except:
pass
if m_x is None:
m_x = parent.winfo_x()
m_y = parent.winfo_y()
m_width = parent.winfo_width()
m_height = parent.winfo_height()
if relx is None: relx = 0.5
if rely is None: rely = 0.3
else:
if relx is None: relx = 0.5
if rely is None: rely = 0.5
m_x = max(m_x, 0)
m_y = max(m_y, 0)
else:
if relx is None: relx = 0.5
if rely is None: rely = 0.3
x = m_x + int((m_width - w_width) * relx)
y = m_y + int((m_height - w_height) * rely)
##print x, y, w_width, w_height, m_x, m_y, m_width, m_height
# make sure the widget is fully on screen
if x < 0: x = 0
elif x + w_width + 32 > s_width: x = max(0, (s_width - w_width) / 2)
if y < 0: y = 0
elif y + w_height + 32 > s_height: y = max(0, (s_height - w_height) / 2)
return x, y
# ************************************************************************
# * bind wrapper - Tkinter doesn't properly delete all bindings
# ************************************************************************
__mfx_bindings = {}
__mfx_wm_protocols = ("WM_DELETE_WINDOW", "WM_TAKE_FOCUS", "WM_SAVE_YOURSELF")
def bind(widget, sequence, func, add=None):
##assert callable(func) # XXX: removed in py3k
if sequence in __mfx_wm_protocols:
funcid = widget._register(func)
widget.tk.call("wm", "protocol", widget._w, sequence, funcid)
elif add is None:
funcid = widget.bind(sequence, func)
else:
##add = add and "+" or ""
funcid = widget.bind(sequence, func, add)
k = id(widget)
if k in __mfx_bindings:
__mfx_bindings[k].append((sequence, funcid))
else:
__mfx_bindings[k] = [(sequence, funcid)]
def unbind_destroy(widget):
if widget is None:
return
k = id(widget)
if k in __mfx_bindings:
for sequence, funcid in __mfx_bindings[k]:
##print widget, sequence, funcid
try:
if sequence in __mfx_wm_protocols:
widget.tk.call("wm", "protocol", widget._w, sequence, "")
##widget.deletecommand(funcid)
else:
widget.unbind(sequence, funcid)
except Tkinter.TclError:
pass
del __mfx_bindings[k]
##for k in __mfx_bindings.keys(): print __mfx_bindings[k]
##print len(__mfx_bindings.keys())
# ************************************************************************
# * timer wrapper - Tkinter doesn't properly delete all commands
# ************************************************************************
def after(widget, ms, func, *args):
timer = widget.after(ms, func, *args)
command = widget._tclCommands[-1]
return (timer, command, widget)
def after_idle(widget, func, *args):
return after(widget, "idle", func, *args)
def after_cancel(t):
if t is not None:
t[2].after_cancel(t[0])
try:
t[2].deletecommand(t[1])
except Tkinter.TclError:
pass
# ************************************************************************
# * image handling
# ************************************************************************
if Image:
class PIL_Image(ImageTk.PhotoImage):
def __init__(self, file=None, image=None, pil_image_orig=None):
if file:
image = Image.open(file).convert('RGBA')
ImageTk.PhotoImage.__init__(self, image)
self._pil_image = image
if pil_image_orig:
self._pil_image_orig = pil_image_orig
else:
self._pil_image_orig = image
def subsample(self, r):
im = self._pil_image
w, h = im.size
w, h = int(float(w)/r), int(float(h)/r)
im = im.resize((w, h))
im = PIL_Image(image=im)
return im
def resize(self, xf, yf):
w, h = self._pil_image_orig.size
w0, h0 = int(w*xf), int(h*yf)
im = self._pil_image_orig.resize((w0,h0), Image.ANTIALIAS)
return PIL_Image(image=im, pil_image_orig=self._pil_image_orig)
def makeImage(file=None, data=None, dither=None, alpha=None):
kw = {}
if data is None:
assert file is not None
kw["file"] = file
else:
#assert data is not None
kw["data"] = data
if Image:
# use PIL
if file:
im = PIL_Image(file)
return im
# fromstring(mode, size, data, decoder_name='raw', *args)
else:
return Tkinter.PhotoImage(data=data)
return Tkinter.PhotoImage(**kw)
loadImage = makeImage
def copyImage(image, x, y, width, height):
if Image:
if isinstance(image, PIL_Image):
return ImageTk.PhotoImage(image._pil_image.crop((x, y, x+width, y+height)))
dest = Tkinter.PhotoImage(width=width, height=height)
assert dest.width() == width
assert dest.height() == height
dest.blank()
image.tk.call(dest, "copy", image.name, "-from", x, y, x+width, y+height)
assert dest.width() == width
assert dest.height() == height
return dest
def fillImage(image, fill, outline=None):
if not fill and not outline:
return
width = image.width()
height = image.height()
ow = 1 # outline width
if width <= 2*ow or height <= 2*ow:
fill = fill or outline
outline = None
if not outline:
f = (fill,) * width
f = (f,) * height
assert len(f) == height
image.put(f)
elif not fill:
l = ((outline,) * width,)
for y in range(0, ow):
image.put(l, (0, y))
for y in range(height-ow, height):
image.put(l, (0, y))
p = ((outline,) * ow,)
for y in range(ow, height-ow):
image.put(p, (0, y))
image.put(p, (width-ow, y))
else:
l1 = (outline,) * width
l2 = (outline,) * ow + (fill,) * (width-2*ow) + (outline,) * ow
f = (l1,) * ow + (l2,) * (height-2*ow) + (l1,) * ow
assert len(f) == height
image.put(f)
def createImage(width, height, fill, outline=None):
image = Tkinter.PhotoImage(width=width, height=height)
assert image.width() == width
assert image.height() == height
image.blank()
fillImage(image, fill, outline)
return image
def shadowImage(image, color='#3896f8', factor=0.3):
if not hasattr(image, '_pil_image'):
return None
im = image._pil_image
if Image.VERSION >= '1.1.7':
# use an alpha image
sh = Image.new('RGBA', im.size, color)
sh.putalpha(100)
out = Image.composite(sh, im, im)
return PIL_Image(image=out)
sh = Image.new('RGBA', im.size, color)
tmp = Image.blend(im, sh, factor)
out = Image.composite(tmp, im, im)
return PIL_Image(image=out)
def markImage(image):
assert Image
if 1: # shadow
color, factor = '#6ae400', 0.3
sh = Image.new('RGBA', image.size, color)
tmp = Image.blend(image, sh, factor)
else: # negate
tmp = ImageOps.invert(image.convert('RGB'))
out = Image.composite(tmp, image, image)
return out
def _createBottomImage(image, color='white', backfile=None):
th = 1 # thickness
sh = Image.new('RGBA', image.size, color)
out = Image.composite(sh, image, image)
w, h = image.size
size = (w-th*2, h-th*2)
tmp = Image.new('RGBA', size, color)
tmp.putalpha(60)
mask = out.resize(size, Image.ANTIALIAS)
out.paste(tmp, (th,th), mask)
if backfile:
back = Image.open(backfile).convert('RGBA')
w0, h0 = back.size
w1, h1 = w, h
a = min(float(w1)/w0, float(h1)/h0)
a = a*0.9
w0, h0 = int(w0*a), int(h0*a)
back = back.resize((w0,h0), Image.ANTIALIAS)
x, y = (w1 - w0) / 2, (h1 - h0) / 2
out.paste(back, (x,y), back)
return out
def createBottom(maskimage, color='white', backfile=None):
if not hasattr(maskimage, '_pil_image'):
return None
maskimage = maskimage._pil_image
out = _createBottomImage(maskimage, color, backfile)
return PIL_Image(image=out)
def resizeBottom(image, maskimage, color='white', backfile=None):
maskimage = maskimage._pil_image
out = _createBottomImage(maskimage, color, backfile)
image['image'] = out
# ************************************************************************
# * font utils
# ************************************************************************
def get_text_width(text, font, root=None):
return Font(root=root, font=font).measure(text)

View file

@ -43,9 +43,9 @@ from pysollib.mfxutil import destruct, kwdefault, KwStruct, openURL
from pysollib.settings import WIN_SYSTEM from pysollib.settings import WIN_SYSTEM
# Toolkit imports # Toolkit imports
from tkutil import after, after_cancel from pysollib.ui.tktile.tkutil import after, after_cancel
from tkutil import bind, unbind_destroy from pysollib.ui.tktile.tkutil import bind, unbind_destroy
from tkutil import makeToplevel, setTransient from pysollib.ui.tktile.tkutil import makeToplevel, setTransient
from tkcanvas import MfxCanvas from tkcanvas import MfxCanvas

View file

@ -154,7 +154,6 @@ for module_name in [
'pysollib.tile.tkhtml', 'pysollib.tile.tkhtml',
'pysollib.tile.tkstats', 'pysollib.tile.tkstats',
'pysollib.tile.tktree', 'pysollib.tile.tktree',
'pysollib.tile.tkutil',
'pysollib.tile.tkwidget', 'pysollib.tile.tkwidget',
'pysollib.tile.tkwrap', 'pysollib.tile.tkwrap',
'pysollib.tile.toolbar', 'pysollib.tile.toolbar',
@ -182,13 +181,13 @@ for module_name in [
'pysollib.tk.tkhtml', 'pysollib.tk.tkhtml',
'pysollib.tk.tkstats', 'pysollib.tk.tkstats',
'pysollib.tk.tktree', 'pysollib.tk.tktree',
'pysollib.tk.tkutil',
'pysollib.tk.tkwidget', 'pysollib.tk.tkwidget',
'pysollib.tk.tkwrap', 'pysollib.tk.tkwrap',
'pysollib.tk.toolbar', 'pysollib.tk.toolbar',
'pysollib.tk.wizarddialog', 'pysollib.tk.wizarddialog',
'pysollib.ui.tktile.menubar', 'pysollib.ui.tktile.menubar',
'pysollib.ui.tktile.tkconst', 'pysollib.ui.tktile.tkconst',
'pysollib.ui.tktile.tkutil',
'pysollib.util', 'pysollib.util',
'pysollib.winsystems.aqua', 'pysollib.winsystems.aqua',
'pysollib.winsystems.common', 'pysollib.winsystems.common',