Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 1 | # A 'WindowParent' is the only module that uses real stdwin functionality. |
| 2 | # It is the root of the tree. |
| 3 | # It should have exactly one child when realized. |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 4 | # |
| 5 | # There is also some support for a standard main loop here. |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 6 | |
| 7 | import stdwin |
| 8 | from stdwinevents import * |
| 9 | |
| 10 | from TransParent import ManageOneChild |
| 11 | |
| 12 | Error = 'WindowParent.Error' # Exception |
| 13 | |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 14 | WindowList = [] # List containing all windows |
| 15 | |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 16 | class WindowParent() = ManageOneChild(): |
| 17 | # |
| 18 | def create(self, (title, size)): |
| 19 | self.title = title |
| 20 | self.size = size # (width, height) |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 21 | self._reset() |
| 22 | return self |
| 23 | # |
| 24 | def _reset(self): |
| 25 | self.child = 0 |
| 26 | self.win = 0 |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 27 | self.itimer = 0 |
| 28 | self.do_mouse = 0 |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 29 | self.do_keybd = 0 |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 30 | self.do_timer = 0 |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 31 | self.do_altdraw = 0 |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 32 | self.pending_destroy = 0 |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 33 | # |
| 34 | def destroy(self): |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 35 | if self.win in WindowList: |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 36 | WindowList.remove(self.win) |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 37 | if self.child: self.child.destroy() |
| 38 | self._reset() |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 39 | # |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 40 | def delayed_destroy(self): |
| 41 | # This interface to be used by 'Close' buttons etc.; |
| 42 | # destroying a window from within a button hook |
| 43 | # is not a good idea... |
| 44 | self.pending_destroy = 1 |
| 45 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 46 | def need_mouse(self, child): self.do_mouse = 1 |
| 47 | def no_mouse(self, child): self.do_mouse = 0 |
| 48 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 49 | def need_keybd(self, child): self.do_keybd = 1 |
| 50 | def no_keybd(self, child): self.do_keybd = 0 |
| 51 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 52 | def need_timer(self, child): self.do_timer = 1 |
| 53 | def no_timer(self, child): self.do_timer = 0 |
| 54 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 55 | def need_altdraw(self, child): self.do_altdraw = 1 |
| 56 | def no_altdraw(self, child): self.do_altdraw = 0 |
| 57 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 58 | def realize(self): |
| 59 | if self.win: |
| 60 | raise Error, 'realize(): called twice' |
| 61 | if not self.child: |
| 62 | raise Error, 'realize(): no child' |
| 63 | size = self.child.minsize(self.beginmeasuring()) |
| 64 | self.size = max(self.size[0], size[0]), \ |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 65 | max(self.size[1], size[1]) |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 66 | stdwin.setdefscrollbars(0, 0) |
Guido van Rossum | fc8e0d9 | 1990-12-26 15:34:48 +0000 | [diff] [blame] | 67 | # XXX Compensate stdwin bug: |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 68 | # XXX should really be stdwin.setdefwinsize(self.size) |
| 69 | stdwin.setdefwinsize(self.size[0]+4, self.size[1]+2) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 70 | self.win = stdwin.open(self.title) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 71 | self.win.setdocsize(self.size) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 72 | if self.itimer: |
| 73 | self.win.settimer(self.itimer) |
| 74 | bounds = (0, 0), self.win.getwinsize() |
| 75 | self.child.setbounds(bounds) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 76 | self.child.realize() |
| 77 | self.win.dispatch = self.dispatch |
| 78 | WindowList.append(self.win) |
| 79 | # |
| 80 | def fixup(self): |
| 81 | self.size = self.child.minsize(self.beginmeasuring()) |
| 82 | self.win.setdocsize(self.size) |
| 83 | bounds = (0, 0), self.win.getwinsize() |
| 84 | self.child.setbounds(bounds) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 85 | # |
| 86 | def beginmeasuring(self): |
| 87 | # Return something with which a child can measure text |
| 88 | if self.win: |
| 89 | return self.win.begindrawing() |
| 90 | else: |
| 91 | return stdwin |
| 92 | # |
| 93 | def begindrawing(self): |
| 94 | if self.win: |
| 95 | return self.win.begindrawing() |
| 96 | else: |
| 97 | raise Error, 'begindrawing(): not realized yet' |
| 98 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 99 | def getwindow(self): |
| 100 | if self.win: |
| 101 | return self.win |
| 102 | else: |
| 103 | raise Error, 'getwindow(): not realized yet' |
| 104 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 105 | def change(self, area): |
| 106 | if self.win: |
| 107 | self.win.change(area) |
| 108 | # |
| 109 | def scroll(self, args): |
| 110 | if self.win: |
| 111 | self.win.scroll(args) |
| 112 | # |
| 113 | def settimer(self, itimer): |
| 114 | if self.win: |
| 115 | self.win.settimer(itimer) |
| 116 | else: |
| 117 | self.itimer = itimer |
| 118 | # |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 119 | # Only call dispatch once we are realized |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 120 | # |
| 121 | def dispatch(self, (type, win, detail)): |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 122 | if type = WE_DRAW: |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 123 | d = self.win.begindrawing() |
| 124 | self.child.draw(d, detail) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 125 | del d |
| 126 | if self.do_altdraw: self.child.altdraw(detail) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 127 | elif type = WE_MOUSE_DOWN: |
| 128 | if self.do_mouse: self.child.mouse_down(detail) |
| 129 | elif type = WE_MOUSE_MOVE: |
| 130 | if self.do_mouse: self.child.mouse_move(detail) |
| 131 | elif type = WE_MOUSE_UP: |
| 132 | if self.do_mouse: self.child.mouse_up(detail) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 133 | elif type in (WE_CHAR, WE_COMMAND): |
| 134 | if self.do_keybd: self.child.keybd(type, detail) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 135 | elif type = WE_TIMER: |
| 136 | if self.do_timer: self.child.timer() |
| 137 | elif type = WE_SIZE: |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 138 | self.fixup() |
| 139 | elif type = WE_CLOSE: |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame^] | 140 | self.delayed_destroy() |
| 141 | if self.pending_destroy: |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 142 | self.destroy() |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 143 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 144 | |
| 145 | def MainLoop(): |
| 146 | while WindowList: |
| 147 | Dispatch(stdwin.getevent()) |
| 148 | |
| 149 | def Dispatch(event): |
| 150 | window = event[1] |
| 151 | if window in WindowList: |
| 152 | window.dispatch(event) |
| 153 | else: |
| 154 | stdwin.fleep() |
| 155 | |
| 156 | # Interface used by WindowSched: |
| 157 | |
| 158 | def CountWindows(): |
| 159 | return len(WindowList) |
| 160 | |
| 161 | def AnyWindow(): |
| 162 | if not WindowList: |
| 163 | return None |
| 164 | else: |
| 165 | return WindowList[0] |