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