Package teamwork :: Package widgets :: Package htmlViewer :: Module tkutil
[hide private]
[frames] | no frames]

Source Code for Module teamwork.widgets.htmlViewer.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 isinstance(parent,Tkinter.Toplevel) and \ 116 parent.wm_state() != "withdrawn": 117 window.wm_transient(parent) 118 # actualize geometry information 119 window.update_idletasks() 120 # show 121 x, y = __getWidgetXY(window, parent, relx=relx, rely=rely) 122 if need_fix: 123 if expose: 124 wm_deiconify(window) 125 window.wm_geometry("+%d+%d" % (x, y)) 126 else: 127 window.wm_geometry("+%d+%d" % (x, y)) 128 if expose: 129 window.wm_deiconify()
130
131 -def makeToplevel(parent, title=None, class_=None):
132 # Create a Toplevel window. 133 # 134 # This is a shortcut for a Toplevel() instantiation plus calls to 135 # set the title and icon name of the window. 136 if class_: 137 window = Tkinter.Toplevel(parent, class_=class_) 138 else: 139 window = Tkinter.Toplevel(parent) 140 ##window.wm_group(parent) 141 ##window.wm_command("") 142 if os.name == "posix": 143 window.wm_command("/bin/true") 144 ##window.wm_protocol("WM_SAVE_YOURSELF", None) 145 if title: 146 window.wm_title(title) 147 window.wm_iconname(title) 148 return window
149 150 makeHelpToplevel = makeToplevel 151
152 -def __getWidgetXY(widget, parent, relx=None, rely=None, 153 w_width=None, w_height=None):
154 if w_width is None: 155 w_width = widget.winfo_reqwidth() 156 if w_height is None: 157 w_height = widget.winfo_reqheight() 158 s_width = widget.winfo_screenwidth() 159 s_height = widget.winfo_screenheight() 160 m_x = m_y = 0 161 m_width, m_height = s_width, s_height 162 if parent and parent.winfo_ismapped(): 163 ##print parent.wm_geometry() 164 ##print parent.winfo_geometry(), parent.winfo_x(), parent.winfo_y(), parent.winfo_rootx(), parent.winfo_rooty(), parent.winfo_vrootx(), parent.winfo_vrooty() 165 m_x = m_y = None 166 if os.name == "nt": 167 try: 168 m_width, m_height, m_x, m_y = wm_get_geometry(parent) 169 except: 170 pass 171 if m_x is None: 172 m_x = parent.winfo_x() 173 m_y = parent.winfo_y() 174 m_width = parent.winfo_width() 175 m_height = parent.winfo_height() 176 if relx is None: relx = 0.5 177 if rely is None: rely = 0.3 178 else: 179 if relx is None: relx = 0.5 180 if rely is None: rely = 0.5 181 m_x = max(m_x, 0) 182 m_y = max(m_y, 0) 183 else: 184 if relx is None: relx = 0.5 185 if rely is None: rely = 0.3 186 x = m_x + int((m_width - w_width) * relx) 187 y = m_y + int((m_height - w_height) * rely) 188 ##print x, y, w_width, w_height, m_x, m_y, m_width, m_height 189 # make sure the widget is fully on screen 190 if x < 0: x = 0 191 elif x + w_width + 32 > s_width: x = max(0, (s_width - w_width) / 2) 192 if y < 0: y = 0 193 elif y + w_height + 32 > s_height: y = max(0, (s_height - w_height) / 2) 194 return x, y
195 196 197 # /*********************************************************************** 198 # // bind wrapper - Tkinter doesn't properly delete all bindings 199 # ************************************************************************/ 200 201 __mfx_bindings = {} 202 __mfx_wm_protocols = ("WM_DELETE_WINDOW", "WM_TAKE_FOCUS", "WM_SAVE_YOURSELF") 203
204 -def bind(widget, sequence, func, add=None):
205 assert callable(func) 206 if sequence in __mfx_wm_protocols: 207 funcid = widget._register(func) 208 widget.tk.call("wm", "protocol", widget._w, sequence, funcid) 209 elif add is None: 210 funcid = widget.bind(sequence, func) 211 else: 212 ##add = add and "+" or "" 213 funcid = widget.bind(sequence, func, add) 214 k = id(widget) 215 if __mfx_bindings.has_key(k): 216 __mfx_bindings[k].append((sequence, funcid)) 217 else: 218 __mfx_bindings[k] = [(sequence, funcid)]
219
220 -def unbind_destroy(widget):
221 if widget is None: 222 return 223 k = id(widget) 224 if __mfx_bindings.has_key(k): 225 for sequence, funcid in __mfx_bindings[k]: 226 ##print widget, sequence, funcid 227 try: 228 if sequence in __mfx_wm_protocols: 229 widget.tk.call("wm", "protocol", widget._w, sequence, "") 230 ##widget.deletecommand(funcid) 231 else: 232 widget.unbind(sequence, funcid) 233 except Tkinter.TclError: 234 pass 235 del __mfx_bindings[k]
236 ##for k in __mfx_bindings.keys(): print __mfx_bindings[k] 237 ##print len(__mfx_bindings.keys()) 238 239 240 # /*********************************************************************** 241 # // timer wrapper - Tkinter doesn't properly delete all commands 242 # ************************************************************************/ 243
244 -def after(widget, ms, func, *args):
245 timer = apply(widget.after, (ms, func) + args) 246 command = widget._tclCommands[-1] 247 return (timer, command, widget)
248
249 -def after_idle(widget, func, *args):
250 return apply(after, (widget, "idle", func) + args)
251
252 -def after_cancel(t):
253 if t is not None: 254 t[2].after_cancel(t[0]) 255 try: 256 t[2].deletecommand(t[1]) 257 except Tkinter.TclError: 258 pass
259 260 261 # /*********************************************************************** 262 # // image handling 263 # ************************************************************************/ 264
265 -def makeImage(file=None, data=None, dither=None, alpha=None):
266 kw = {} 267 if data is None: 268 assert file is not None 269 kw["file"] = file 270 else: 271 assert data is not None 272 kw["data"] = data 273 if os.name == "nt": 274 if dither is not None: 275 kw["dither"] = dither 276 if alpha is not None: 277 kw["alpha"] = alpha 278 return apply(Tkinter.PhotoImage, (), kw)
279 280 loadImage = makeImage 281
282 -def copyImage(image, x, y, width, height):
283 dest = Tkinter.PhotoImage(width=width, height=height) 284 assert dest.width() == width 285 assert dest.height() == height 286 dest.blank() 287 image.tk.call(dest, "copy", image.name, "-from", x, y, x+width, y+height) 288 assert dest.width() == width 289 assert dest.height() == height 290 return dest
291
292 -def fillImage(image, fill, outline=None):
293 if not fill and not outline: 294 return 295 width = image.width() 296 height = image.height() 297 ow = 1 # outline width 298 if width <= 2*ow or height <= 2*ow: 299 fill = fill or outline 300 outline = None 301 if not outline: 302 f = (fill,) * width 303 f = (f,) * height 304 assert len(f) == height 305 image.put(f) 306 elif not fill: 307 l = ((outline,) * width,) 308 for y in range(0, ow): 309 image.put(l, (0, y)) 310 for y in range(height-ow, height): 311 image.put(l, (0, y)) 312 p = ((outline,) * ow,) 313 for y in range(ow, height-ow): 314 image.put(p, (0, y)) 315 image.put(p, (width-ow, y)) 316 else: 317 l1 = (outline,) * width 318 l2 = (outline,) * ow + (fill,) * (width-2*ow) + (outline,) * ow 319 f = (l1,) * ow + (l2,) * (height-2*ow) + (l1,) * ow 320 assert len(f) == height 321 image.put(f)
322
323 -def createImage(width, height, fill, outline=None):
324 image = Tkinter.PhotoImage(width=width, height=height) 325 assert image.width() == width 326 assert image.height() == height 327 image.blank() 328 fillImage(image, fill, outline) 329 return image
330