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 | # |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 5 | # There is also an alternative interface to "mainloop" here. |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 6 | |
| 7 | import stdwin |
| 8 | from stdwinevents import * |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 9 | import mainloop |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 10 | |
| 11 | from TransParent import ManageOneChild |
| 12 | |
| 13 | Error = 'WindowParent.Error' # Exception |
| 14 | |
Guido van Rossum | ce08448 | 1991-12-26 13:06:29 +0000 | [diff] [blame] | 15 | class WindowParent(ManageOneChild): |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 16 | # |
| 17 | def create(self, (title, size)): |
| 18 | self.title = title |
| 19 | self.size = size # (width, height) |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 20 | self._reset() |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 21 | self.close_hook = WindowParent.delayed_destroy |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 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 | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 34 | self.menu_hook = None |
Guido van Rossum | 52cea43 | 1991-01-23 13:43:16 +0000 | [diff] [blame] | 35 | # |
| 36 | def destroy(self): |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 37 | mainloop.unregister(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 | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 50 | def menu_trigger(self, (menu, item)): |
| 51 | if self.menu_hook: |
| 52 | self.menu_hook(self, menu, item) |
| 53 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 54 | def need_mouse(self, child): self.do_mouse = 1 |
| 55 | def no_mouse(self, child): self.do_mouse = 0 |
| 56 | # |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 57 | def need_keybd(self, child): |
| 58 | self.do_keybd = 1 |
| 59 | self.child.activate() |
| 60 | def no_keybd(self, child): |
| 61 | self.do_keybd = 0 |
| 62 | self.child.deactivate() |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 63 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 64 | def need_timer(self, child): self.do_timer = 1 |
| 65 | def no_timer(self, child): self.do_timer = 0 |
| 66 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 67 | def need_altdraw(self, child): self.do_altdraw = 1 |
| 68 | def no_altdraw(self, child): self.do_altdraw = 0 |
| 69 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 70 | def realize(self): |
| 71 | if self.win: |
| 72 | raise Error, 'realize(): called twice' |
| 73 | if not self.child: |
| 74 | raise Error, 'realize(): no child' |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 75 | # Compute suggested size |
| 76 | self.size = self.child.getminsize(self.beginmeasuring(), \ |
| 77 | self.size) |
| 78 | save_defsize = stdwin.getdefwinsize() |
| 79 | scrwidth, scrheight = stdwin.getscrsize() |
| 80 | width, height = self.size |
| 81 | if width > scrwidth: |
| 82 | width = scrwidth * 2/3 |
| 83 | if height > scrheight: |
| 84 | height = scrheight * 2/3 |
| 85 | stdwin.setdefwinsize(width, height) |
| 86 | self.hbar, self.vbar = stdwin.getdefscrollbars() |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 87 | self.win = stdwin.open(self.title) |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 88 | stdwin.setdefwinsize(save_defsize) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 89 | self.win.setdocsize(self.size) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 90 | if self.itimer: |
| 91 | self.win.settimer(self.itimer) |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 92 | width, height = self.win.getwinsize() |
| 93 | if self.hbar: |
| 94 | width = self.size[0] |
| 95 | if self.vbar: |
| 96 | height = self.size[1] |
| 97 | self.child.setbounds((0, 0), (width, height)) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 98 | self.child.realize() |
| 99 | self.win.dispatch = self.dispatch |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 100 | mainloop.register(self.win) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 101 | # |
| 102 | def fixup(self): |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 103 | # XXX This could share code with realize() above |
| 104 | self.size = self.child.getminsize(self.beginmeasuring(), \ |
| 105 | self.win.getwinsize()) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 106 | self.win.setdocsize(self.size) |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 107 | width, height = self.win.getwinsize() |
| 108 | if self.hbar: |
| 109 | width = self.size[0] |
| 110 | if self.vbar: |
| 111 | height = self.size[1] |
| 112 | self.child.setbounds((0, 0), (width, height)) |
Guido van Rossum | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame] | 113 | # Force a redraw of the entire window: |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 114 | self.win.change((0, 0), self.size) |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 115 | # |
| 116 | def beginmeasuring(self): |
| 117 | # Return something with which a child can measure text |
| 118 | if self.win: |
| 119 | return self.win.begindrawing() |
| 120 | else: |
| 121 | return stdwin |
| 122 | # |
| 123 | def begindrawing(self): |
| 124 | if self.win: |
| 125 | return self.win.begindrawing() |
| 126 | else: |
| 127 | raise Error, 'begindrawing(): not realized yet' |
| 128 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 129 | def getwindow(self): |
| 130 | if self.win: |
| 131 | return self.win |
| 132 | else: |
| 133 | raise Error, 'getwindow(): not realized yet' |
| 134 | # |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 135 | def change(self, area): |
| 136 | if self.win: |
| 137 | self.win.change(area) |
| 138 | # |
| 139 | def scroll(self, args): |
| 140 | if self.win: |
| 141 | self.win.scroll(args) |
| 142 | # |
| 143 | def settimer(self, itimer): |
| 144 | if self.win: |
| 145 | self.win.settimer(itimer) |
| 146 | else: |
| 147 | self.itimer = itimer |
| 148 | # |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame] | 149 | # Only call dispatch once we are realized |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 150 | # |
| 151 | def dispatch(self, (type, win, detail)): |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 152 | if type == WE_DRAW: |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 153 | d = self.win.begindrawing() |
| 154 | self.child.draw(d, detail) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 155 | del d |
| 156 | if self.do_altdraw: self.child.altdraw(detail) |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 157 | elif type == WE_MOUSE_DOWN: |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 158 | if self.do_mouse: self.child.mouse_down(detail) |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 159 | elif type == WE_MOUSE_MOVE: |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 160 | if self.do_mouse: self.child.mouse_move(detail) |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 161 | elif type == WE_MOUSE_UP: |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 162 | if self.do_mouse: self.child.mouse_up(detail) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 163 | elif type in (WE_CHAR, WE_COMMAND): |
| 164 | if self.do_keybd: self.child.keybd(type, detail) |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 165 | elif type == WE_TIMER: |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 166 | if self.do_timer: self.child.timer() |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 167 | elif type == WE_SIZE: |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 168 | self.fixup() |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 169 | elif type == WE_CLOSE: |
Guido van Rossum | aa17917 | 1991-05-14 12:22:25 +0000 | [diff] [blame] | 170 | self.close_trigger() |
Guido van Rossum | bdfcfcc | 1992-01-01 19:35:13 +0000 | [diff] [blame] | 171 | elif type == WE_MENU: |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 172 | self.menu_trigger(detail) |
Guido van Rossum | fb9149c | 1991-04-21 19:28:44 +0000 | [diff] [blame] | 173 | if self.pending_destroy: |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 174 | self.destroy() |
Guido van Rossum | 2e44967 | 1990-11-05 19:44:36 +0000 | [diff] [blame] | 175 | # |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 176 | |
| 177 | def MainLoop(): |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 178 | mainloop.mainloop() |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 179 | |
| 180 | def Dispatch(event): |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 181 | mainloop.dispatch(event) |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 182 | |
| 183 | # Interface used by WindowSched: |
| 184 | |
| 185 | def CountWindows(): |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 186 | return mainloop.countwindows() |
Guido van Rossum | 117dbcb | 1991-04-07 13:37:05 +0000 | [diff] [blame] | 187 | |
| 188 | def AnyWindow(): |
Guido van Rossum | e825f15 | 1991-08-16 13:22:23 +0000 | [diff] [blame] | 189 | return mainloop.anywindow() |