# 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()