cpython/Lib/stdwin/WindowParent.py

166 lines
4.0 KiB
Python
Executable File

# 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 some support for a standard main loop here.
import stdwin
from stdwinevents import *
from TransParent import ManageOneChild
Error = 'WindowParent.Error' # Exception
WindowList = [] # List containing all windows
class WindowParent() = ManageOneChild():
#
def create(self, (title, size)):
self.title = title
self.size = size # (width, height)
self._reset()
return self
#
def _reset(self):
self.child = 0
self.win = 0
self.itimer = 0
self.do_mouse = 0
self.do_keybd = 0
self.do_timer = 0
self.do_altdraw = 0
self.pending_destroy = 0
#
def destroy(self):
if self.win in WindowList:
WindowList.remove(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 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
def no_keybd(self, child): self.do_keybd = 0
#
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'
size = self.child.minsize(self.beginmeasuring())
self.size = max(self.size[0], size[0]), \
max(self.size[1], size[1])
stdwin.setdefscrollbars(0, 0)
# XXX Compensate stdwin bug:
# XXX should really be stdwin.setdefwinsize(self.size)
stdwin.setdefwinsize(self.size[0]+4, self.size[1]+2)
self.win = stdwin.open(self.title)
self.win.setdocsize(self.size)
if self.itimer:
self.win.settimer(self.itimer)
bounds = (0, 0), self.win.getwinsize()
self.child.setbounds(bounds)
self.child.realize()
self.win.dispatch = self.dispatch
WindowList.append(self.win)
#
def fixup(self):
self.size = self.child.minsize(self.beginmeasuring())
self.win.setdocsize(self.size)
bounds = (0, 0), self.win.getwinsize()
self.child.setbounds(bounds)
#
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, args):
if self.win:
self.win.scroll(args)
#
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.delayed_destroy()
if self.pending_destroy:
self.destroy()
#
def MainLoop():
while WindowList:
Dispatch(stdwin.getevent())
def Dispatch(event):
window = event[1]
if window in WindowList:
window.dispatch(event)
else:
stdwin.fleep()
# Interface used by WindowSched:
def CountWindows():
return len(WindowList)
def AnyWindow():
if not WindowList:
return None
else:
return WindowList[0]