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): |
Guido van Rossum | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame^] | 25 | self.child = None |
| 26 | self.win = None |
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 | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame^] | 33 | self.close_hook = None |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 34 | # |
| 35 | def destroy(self): |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 36 | if self.win in WindowList: |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame] | 37 | WindowList.remove(self.win) |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 38 | if self.child: self.child.destroy() |
| 39 | self._reset() |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 40 | # |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame] | 41 | def delayed_destroy(self): |
| 42 | # This interface to be used by 'Close' buttons etc.; |
| 43 | # destroying a window from within a button hook |
| 44 | # is not a good idea... |
| 45 | self.pending_destroy = 1 |
| 46 | # |
Guido van Rossum | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame^] | 47 | def close_trigger(self): |
| 48 | if self.close_hook: self.close_hook(self) |
| 49 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 50 | def need_mouse(self, child): self.do_mouse = 1 |
| 51 | def no_mouse(self, child): self.do_mouse = 0 |
| 52 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 53 | def need_keybd(self, child): self.do_keybd = 1 |
| 54 | def no_keybd(self, child): self.do_keybd = 0 |
| 55 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 56 | def need_timer(self, child): self.do_timer = 1 |
| 57 | def no_timer(self, child): self.do_timer = 0 |
| 58 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 59 | def need_altdraw(self, child): self.do_altdraw = 1 |
| 60 | def no_altdraw(self, child): self.do_altdraw = 0 |
| 61 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 62 | def realize(self): |
| 63 | if self.win: |
| 64 | raise Error, 'realize(): called twice' |
| 65 | if not self.child: |
| 66 | raise Error, 'realize(): no child' |
| 67 | size = self.child.minsize(self.beginmeasuring()) |
| 68 | self.size = max(self.size[0], size[0]), \ |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 69 | max(self.size[1], size[1]) |
Guido van Rossum | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame^] | 70 | # XXX Don't... stdwin.setdefscrollbars(0, 0) |
| 71 | stdwin.setdefwinsize(self.size) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 72 | self.win = stdwin.open(self.title) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 73 | self.win.setdocsize(self.size) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 74 | if self.itimer: |
| 75 | self.win.settimer(self.itimer) |
| 76 | bounds = (0, 0), self.win.getwinsize() |
| 77 | self.child.setbounds(bounds) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 78 | self.child.realize() |
| 79 | self.win.dispatch = self.dispatch |
| 80 | WindowList.append(self.win) |
| 81 | # |
| 82 | def fixup(self): |
| 83 | self.size = self.child.minsize(self.beginmeasuring()) |
| 84 | self.win.setdocsize(self.size) |
| 85 | bounds = (0, 0), self.win.getwinsize() |
| 86 | self.child.setbounds(bounds) |
Guido van Rossum | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame^] | 87 | # Force a redraw of the entire window: |
| 88 | self.win.change((0, 0), (10000, 10000)) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 89 | # |
| 90 | def beginmeasuring(self): |
| 91 | # Return something with which a child can measure text |
| 92 | if self.win: |
| 93 | return self.win.begindrawing() |
| 94 | else: |
| 95 | return stdwin |
| 96 | # |
| 97 | def begindrawing(self): |
| 98 | if self.win: |
| 99 | return self.win.begindrawing() |
| 100 | else: |
| 101 | raise Error, 'begindrawing(): not realized yet' |
| 102 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 103 | def getwindow(self): |
| 104 | if self.win: |
| 105 | return self.win |
| 106 | else: |
| 107 | raise Error, 'getwindow(): not realized yet' |
| 108 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 109 | def change(self, area): |
| 110 | if self.win: |
| 111 | self.win.change(area) |
| 112 | # |
| 113 | def scroll(self, args): |
| 114 | if self.win: |
| 115 | self.win.scroll(args) |
| 116 | # |
| 117 | def settimer(self, itimer): |
| 118 | if self.win: |
| 119 | self.win.settimer(itimer) |
| 120 | else: |
| 121 | self.itimer = itimer |
| 122 | # |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame] | 123 | # Only call dispatch once we are realized |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 124 | # |
| 125 | def dispatch(self, (type, win, detail)): |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame] | 126 | if type = WE_DRAW: |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 127 | d = self.win.begindrawing() |
| 128 | self.child.draw(d, detail) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 129 | del d |
| 130 | if self.do_altdraw: self.child.altdraw(detail) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 131 | elif type = WE_MOUSE_DOWN: |
| 132 | if self.do_mouse: self.child.mouse_down(detail) |
| 133 | elif type = WE_MOUSE_MOVE: |
| 134 | if self.do_mouse: self.child.mouse_move(detail) |
| 135 | elif type = WE_MOUSE_UP: |
| 136 | if self.do_mouse: self.child.mouse_up(detail) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 137 | elif type in (WE_CHAR, WE_COMMAND): |
| 138 | if self.do_keybd: self.child.keybd(type, detail) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 139 | elif type = WE_TIMER: |
| 140 | if self.do_timer: self.child.timer() |
| 141 | elif type = WE_SIZE: |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 142 | self.fixup() |
| 143 | elif type = WE_CLOSE: |
Guido van Rossum | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame^] | 144 | self.close_trigger() |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame] | 145 | if self.pending_destroy: |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 146 | self.destroy() |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 147 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 148 | |
| 149 | def MainLoop(): |
| 150 | while WindowList: |
| 151 | Dispatch(stdwin.getevent()) |
| 152 | |
| 153 | def Dispatch(event): |
| 154 | window = event[1] |
| 155 | if window in WindowList: |
| 156 | window.dispatch(event) |
| 157 | else: |
| 158 | stdwin.fleep() |
| 159 | |
| 160 | # Interface used by WindowSched: |
| 161 | |
| 162 | def CountWindows(): |
| 163 | return len(WindowList) |
| 164 | |
| 165 | def AnyWindow(): |
| 166 | if not WindowList: |
| 167 | return None |
| 168 | else: |
| 169 | return WindowList[0] |