Package nMOLDYN :: Package GUI :: Package HTMLReader :: Module tkutil
[hide private]
[frames] | no frames]

Source Code for Module nMOLDYN.GUI.HTMLReader.tkutil

  1  ## vim:ts=4:et:nowrap 
  2  ## 
  3  ##---------------------------------------------------------------------------## 
  4  ## 
  5  ## PySol -- a Python Solitaire game 
  6  ## 
  7  ## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer 
  8  ## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer 
  9  ## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer 
 10  ## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer 
 11  ## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer 
 12  ## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer 
 13  ## All Rights Reserved. 
 14  ## 
 15  ## This program is free software; you can redistribute it and/or modify 
 16  ## it under the terms of the GNU General Public License as published by 
 17  ## the Free Software Foundation; either version 2 of the License, or 
 18  ## (at your option) any later version. 
 19  ## 
 20  ## This program is distributed in the hope that it will be useful, 
 21  ## but WITHOUT ANY WARRANTY; without even the implied warranty of 
 22  ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 23  ## GNU General Public License for more details. 
 24  ## 
 25  ## You should have received a copy of the GNU General Public License 
 26  ## along with this program; see the file COPYING. 
 27  ## If not, write to the Free Software Foundation, Inc., 
 28  ## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 29  ## 
 30  ## Markus F.X.J. Oberhumer 
 31  ## <markus@oberhumer.com> 
 32  ## http://www.oberhumer.com/pysol 
 33  ## 
 34  ##---------------------------------------------------------------------------## 
 35   
 36   
 37  # imports 
 38  import sys, os, re, string, time, types 
 39  import Tkinter 
 40   
 41  # Toolkit imports 
 42  import tkinit 
 43  from tkconst import tkversion 
 44  from tkfont import getFont 
 45   
 46   
 47  # /*********************************************************************** 
 48  # // window manager util 
 49  # ************************************************************************/ 
 50   
51 -def wm_withdraw(window):
52 window.wm_withdraw()
53
54 -def wm_deiconify(window):
55 need_fix = os.name == "nt" and tkversion < (8, 3, 0, 0) 56 if need_fix: 57 # FIXME: This is needed so the window pops up on top on Windows. 58 try: 59 window.wm_iconify() 60 window.update_idletasks() 61 except Tkinter.TclError: 62 # wm_iconify() may fail if the window is transient 63 pass 64 window.wm_deiconify()
65
66 -def wm_map(window, maximized=0):
67 if window.wm_state() != "iconic": 68 if maximized and os.name == "nt": 69 window.wm_state("zoomed") 70 else: 71 wm_deiconify(window)
72
73 -def wm_set_icon(window, filename):
74 if not filename: 75 return 76 if os.name == "posix": 77 window.wm_iconbitmap("@" + filename) 78 window.wm_iconmask("@" + filename)
79 80 __wm_get_geometry_re = re.compile(r"^(\d+)x(\d+)\+([\-]?\d+)\+([\-]?\d+)$") 81
82 -def wm_get_geometry(window):
83 g = window.wm_geometry() 84 m = __wm_get_geometry_re.search(g) 85 if not m: 86 raise Tkinter.TclError, "invalid geometry " + str(g) 87 l = map(int, m.groups()) 88 if window.wm_state() == "zoomed": 89 # workaround as Tk returns the "unzoomed" origin 90 l[2] = l[3] = 0 91 return l
92 93 94 # /*********************************************************************** 95 # // window util 96 # ************************************************************************/ 97
98 -def setTransient(window, parent, relx=None, rely=None, expose=1):
99 # Make an existing toplevel window transient for a parent. 100 # 101 # The window must exist but should not yet have been placed; in 102 # other words, this should be called after creating all the 103 # subwidget but before letting the user interact. 104 105 # remain invisible while we figure out the geometry 106 window.wm_withdraw() 107 window.wm_group(parent) 108 need_fix = os.name == "nt" and tkversion < (8, 3, 0, 0) 109 if need_fix: 110 # FIXME: This is needed to avoid ugly frames on Windows. 111 window.wm_geometry("+%d+%d" % (-10000, -10000)) 112 if expose and parent is not None: 113 # FIXME: This is needed so the window pops up on top on Windows. 114 window.wm_iconify() 115 if parent and parent.wm_state() != "withdrawn": 116 window.wm_transient(parent) 117 # actualize geometry information 118 window.update_idletasks() 119 # show 120 x, y = __getWidgetXY(window, parent, relx=relx, rely=rely) 121 if need_fix: 122 if expose: 123 wm_deiconify(window) 124 window.wm_geometry("+%d+%d" % (x, y)) 125 else: 126 window.wm_geometry("+%d+%d" % (x, y)) 127 if expose: 128 window.wm_deiconify()
129
130 -def makeToplevel(parent, title=None, class_=None):
131 # Create a Toplevel window. 132 # 133 # This is a shortcut for a Toplevel() instantiation plus calls to 134 # set the title and icon name of the window. 135 if class_: 136 window = Tkinter.Toplevel(parent, class_=class_) 137 else: 138 window = Tkinter.Toplevel(parent) 139 ##window.wm_group(parent) 140 ##window.wm_command("") 141 if os.name == "posix": 142 window.wm_command("/bin/true") 143 ##window.wm_protocol("WM_SAVE_YOURSELF", None) 144 if title: 145 window.wm_title(title) 146 window.wm_iconname(title) 147 return window
148 149 makeHelpToplevel = makeToplevel 150
151 -def __getWidgetXY(widget, parent, relx=None, rely=None, 152 w_width=None, w_height=None):
153 if w_width is None: 154 w_width = widget.winfo_reqwidth() 155 if w_height is None: 156 w_height = widget.winfo_reqheight() 157 s_width = widget.winfo_screenwidth() 158 s_height = widget.winfo_screenheight() 159 m_x = m_y = 0 160 m_width, m_height = s_width, s_height 161 if parent and parent.winfo_ismapped(): 162 ##print parent.wm_geometry() 163 ##print parent.winfo_geometry(), parent.winfo_x(), parent.winfo_y(), parent.winfo_rootx(), parent.winfo_rooty(), parent.winfo_vrootx(), parent.winfo_vrooty() 164 m_x = m_y = None 165 if os.name == "nt": 166 try: 167 m_width, m_height, m_x, m_y = wm_get_geometry(parent) 168 except: 169 pass 170 if m_x is None: 171 m_x = parent.winfo_x() 172 m_y = parent.winfo_y() 173 m_width = parent.winfo_width() 174 m_height = parent.winfo_height() 175 if relx is None: relx = 0.5 176 if rely is None: rely = 0.3 177 else: 178 if relx is None: relx = 0.5 179 if rely is None: rely = 0.5 180 m_x = max(m_x, 0) 181 m_y = max(m_y, 0) 182 else: 183 if relx is None: relx = 0.5 184 if rely is None: rely = 0.3 185 x = m_x + int((m_width - w_width) * relx) 186 y = m_y + int((m_height - w_height) * rely) 187 ##print x, y, w_width, w_height, m_x, m_y, m_width, m_height 188 # make sure the widget is fully on screen 189 if x < 0: x = 0 190 elif x + w_width + 32 > s_width: x = max(0, (s_width - w_width) / 2) 191 if y < 0: y = 0 192 elif y + w_height + 32 > s_height: y = max(0, (s_height - w_height) / 2) 193 return x, y
194 195 196 # /*********************************************************************** 197 # // bind wrapper - Tkinter doesn't properly delete all bindings 198 # ************************************************************************/ 199 200 __mfx_bindings = {} 201 __mfx_wm_protocols = ("WM_DELETE_WINDOW", "WM_TAKE_FOCUS", "WM_SAVE_YOURSELF") 202
203 -def bind(widget, sequence, func, add=None):
204 assert callable(func) 205 if sequence in __mfx_wm_protocols: 206 funcid = widget._register(func) 207 widget.tk.call("wm", "protocol", widget._w, sequence, funcid) 208 elif add is None: 209 funcid = widget.bind(sequence, func) 210 else: 211 ##add = add and "+" or "" 212 funcid = widget.bind(sequence, func, add) 213 k = id(widget) 214 if __mfx_bindings.has_key(k): 215 __mfx_bindings[k].append((sequence, funcid)) 216 else: 217 __mfx_bindings[k] = [(sequence, funcid)]
218
219 -def unbind_destroy(widget):
220 if widget is None: 221 return 222 k = id(widget) 223 if __mfx_bindings.has_key(k): 224 for sequence, funcid in __mfx_bindings[k]: 225 ##print widget, sequence, funcid 226 try: 227 if sequence in __mfx_wm_protocols: 228 widget.tk.call("wm", "protocol", widget._w, sequence, "") 229 ##widget.deletecommand(funcid) 230 else: 231 widget.unbind(sequence, funcid) 232 except Tkinter.TclError: 233 pass 234 del __mfx_bindings[k]
235 ##for k in __mfx_bindings.keys(): print __mfx_bindings[k] 236 ##print len(__mfx_bindings.keys()) 237 238 239 # /*********************************************************************** 240 # // timer wrapper - Tkinter doesn't properly delete all commands 241 # ************************************************************************/ 242
243 -def after(widget, ms, func, *args):
244 timer = apply(widget.after, (ms, func) + args) 245 command = widget._tclCommands[-1] 246 return (timer, command, widget)
247
248 -def after_idle(widget, func, *args):
249 return apply(after, (widget, "idle", func) + args)
250
251 -def after_cancel(t):
252 if t is not None: 253 t[2].after_cancel(t[0]) 254 try: 255 t[2].deletecommand(t[1]) 256 except Tkinter.TclError: 257 pass
258 259 260 # /*********************************************************************** 261 # // image handling 262 # ************************************************************************/ 263
264 -def makeImage(file=None, data=None, dither=None, alpha=None):
265 kw = {} 266 if data is None: 267 assert file is not None 268 kw["file"] = file 269 else: 270 assert data is not None 271 kw["data"] = data 272 if os.name == "nt": 273 if dither is not None: 274 kw["dither"] = dither 275 if alpha is not None: 276 kw["alpha"] = alpha 277 return apply(Tkinter.PhotoImage, (), kw)
278 279 loadImage = makeImage 280
281 -def copyImage(image, x, y, width, height):
282 dest = Tkinter.PhotoImage(width=width, height=height) 283 assert dest.width() == width 284 assert dest.height() == height 285 dest.blank() 286 image.tk.call(dest, "copy", image.name, "-from", x, y, x+width, y+height) 287 assert dest.width() == width 288 assert dest.height() == height 289 return dest
290
291 -def fillImage(image, fill, outline=None):
292 if not fill and not outline: 293 return 294 width = image.width() 295 height = image.height() 296 ow = 1 # outline width 297 if width <= 2*ow or height <= 2*ow: 298 fill = fill or outline 299 outline = None 300 if not outline: 301 f = (fill,) * width 302 f = (f,) * height 303 assert len(f) == height 304 image.put(f) 305 elif not fill: 306 l = ((outline,) * width,) 307 for y in range(0, ow): 308 image.put(l, (0, y)) 309 for y in range(height-ow, height): 310 image.put(l, (0, y)) 311 p = ((outline,) * ow,) 312 for y in range(ow, height-ow): 313 image.put(p, (0, y)) 314 image.put(p, (width-ow, y)) 315 else: 316 l1 = (outline,) * width 317 l2 = (outline,) * ow + (fill,) * (width-2*ow) + (outline,) * ow 318 f = (l1,) * ow + (l2,) * (height-2*ow) + (l1,) * ow 319 assert len(f) == height 320 image.put(f)
321
322 -def createImage(width, height, fill, outline=None):
323 image = Tkinter.PhotoImage(width=width, height=height) 324 assert image.width() == width 325 assert image.height() == height 326 image.blank() 327 fillImage(image, fill, outline) 328 return image
329