summaryrefslogtreecommitdiffstats
path: root/Lib/stdwin/WindowParent.py
blob: 2388443d5a7874bb9f1090646abeb22ace806641 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# 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 some support for a standard main loop here.

import stdwin
from stdwinevents import *

from TransParent import ManageOneChild

Error = 'WindowParent.Error'	# Exception

WindowList = []			# List containing all windows

class WindowParent() = ManageOneChild():
	#
	def create(self, (title, size)):
		self.title = title
		self.size = size		# (width, height)
		self._reset()
		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
	#
	def destroy(self):
		if self.win in WindowList:
			WindowList.remove(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 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
	def no_keybd(self, child): self.do_keybd = 0
	#
	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'
		size = self.child.minsize(self.beginmeasuring())
		self.size = max(self.size[0], size[0]), \
					max(self.size[1], size[1])
		# XXX Don't... stdwin.setdefscrollbars(0, 0)
		stdwin.setdefwinsize(self.size)
		self.win = stdwin.open(self.title)
		self.win.setdocsize(self.size)
		if self.itimer:
			self.win.settimer(self.itimer)
		bounds = (0, 0), self.win.getwinsize()
		self.child.setbounds(bounds)
		self.child.realize()
		self.win.dispatch = self.dispatch
		WindowList.append(self.win)
	#
	def fixup(self):
		self.size = self.child.minsize(self.beginmeasuring())
		self.win.setdocsize(self.size)
		bounds = (0, 0), self.win.getwinsize()
		self.child.setbounds(bounds)
		# Force a redraw of the entire window:
		self.win.change((0, 0), (10000, 10000))
	#
	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, args):
		if self.win:
			self.win.scroll(args)
	#
	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()
		if self.pending_destroy:
			self.destroy()
	#

def MainLoop():
	while WindowList:
		Dispatch(stdwin.getevent())

def Dispatch(event):
	window = event[1]
	if window in WindowList:
		window.dispatch(event)
	else:
		stdwin.fleep()

# Interface used by WindowSched:

def CountWindows():
	return len(WindowList)

def AnyWindow():
	if not WindowList:
		return None
	else:
		return WindowList[0]