1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
# A 'WindowParent' is the only module that uses real stdwin functionality.
# It is the root of the tree.
# It should have exactly one child when realized.
#
# There is also an alternative interface to "mainloop" here.
import stdwin
from stdwinevents import *
import mainloop
from TransParent import ManageOneChild
Error = 'WindowParent.Error' # Exception
class WindowParent(ManageOneChild):
#
def create(self, title, size):
self.title = title
self.size = size # (width, height)
self._reset()
self.close_hook = WindowParent.delayed_destroy
return self
#
def _reset(self):
self.child = None
self.win = None
self.itimer = 0
self.do_mouse = 0
self.do_keybd = 0
self.do_timer = 0
self.do_altdraw = 0
self.pending_destroy = 0
self.close_hook = None
self.menu_hook = None
#
def destroy(self):
mainloop.unregister(self.win)
if self.child: self.child.destroy()
self._reset()
#
def delayed_destroy(self):
# This interface to be used by 'Close' buttons etc.;
# destroying a window from within a button hook
# is not a good idea...
self.pending_destroy = 1
#
def close_trigger(self):
if self.close_hook: self.close_hook(self)
#
def menu_trigger(self, menu, item):
if self.menu_hook:
self.menu_hook(self, menu, item)
#
def need_mouse(self, child): self.do_mouse = 1
def no_mouse(self, child): self.do_mouse = 0
#
def need_keybd(self, child):
self.do_keybd = 1
self.child.activate()
def no_keybd(self, child):
self.do_keybd = 0
self.child.deactivate()
#
def need_timer(self, child): self.do_timer = 1
def no_timer(self, child): self.do_timer = 0
#
def need_altdraw(self, child): self.do_altdraw = 1
def no_altdraw(self, child): self.do_altdraw = 0
#
def realize(self):
if self.win:
raise Error, 'realize(): called twice'
if not self.child:
raise Error, 'realize(): no child'
# Compute suggested size
self.size = self.child.getminsize(self.beginmeasuring(), \
self.size)
save_defsize = stdwin.getdefwinsize()
scrwidth, scrheight = stdwin.getscrsize()
width, height = self.size
if width > scrwidth:
width = scrwidth * 2/3
if height > scrheight:
height = scrheight * 2/3
stdwin.setdefwinsize(width, height)
self.hbar, self.vbar = stdwin.getdefscrollbars()
self.win = stdwin.open(self.title)
stdwin.setdefwinsize(save_defsize)
self.win.setdocsize(self.size)
if self.itimer:
self.win.settimer(self.itimer)
width, height = self.win.getwinsize()
if self.hbar:
width = self.size[0]
if self.vbar:
height = self.size[1]
self.child.setbounds(((0, 0), (width, height)))
self.child.realize()
self.win.dispatch = self.dispatch
mainloop.register(self.win)
#
def fixup(self):
# XXX This could share code with realize() above
self.size = self.child.getminsize(self.beginmeasuring(), \
self.win.getwinsize())
self.win.setdocsize(self.size)
width, height = self.win.getwinsize()
if self.hbar:
width = self.size[0]
if self.vbar:
height = self.size[1]
self.child.setbounds(((0, 0), (width, height)))
# Force a redraw of the entire window:
self.win.change((0, 0), self.size)
#
def beginmeasuring(self):
# Return something with which a child can measure text
if self.win:
return self.win.begindrawing()
else:
return stdwin
#
def begindrawing(self):
if self.win:
return self.win.begindrawing()
else:
raise Error, 'begindrawing(): not realized yet'
#
def getwindow(self):
if self.win:
return self.win
else:
raise Error, 'getwindow(): not realized yet'
#
def change(self, area):
if self.win:
self.win.change(area)
#
def scroll(self, area, vector):
if self.win:
self.win.scroll(area, vector)
#
def settimer(self, itimer):
if self.win:
self.win.settimer(itimer)
else:
self.itimer = itimer
#
# Only call dispatch once we are realized
#
def dispatch(self, (type, win, detail)):
if type == WE_DRAW:
d = self.win.begindrawing()
self.child.draw(d, detail)
del d
if self.do_altdraw: self.child.altdraw(detail)
elif type == WE_MOUSE_DOWN:
if self.do_mouse: self.child.mouse_down(detail)
elif type == WE_MOUSE_MOVE:
if self.do_mouse: self.child.mouse_move(detail)
elif type == WE_MOUSE_UP:
if self.do_mouse: self.child.mouse_up(detail)
elif type in (WE_CHAR, WE_COMMAND):
if self.do_keybd: self.child.keybd(type, detail)
elif type == WE_TIMER:
if self.do_timer: self.child.timer()
elif type == WE_SIZE:
self.fixup()
elif type == WE_CLOSE:
self.close_trigger()
elif type == WE_MENU:
self.menu_trigger(detail)
if self.pending_destroy:
self.destroy()
#
def MainLoop():
mainloop.mainloop()
def Dispatch(event):
mainloop.dispatch(event)
# Interface used by WindowSched:
def CountWindows():
return mainloop.countwindows()
def AnyWindow():
return mainloop.anywindow()
|