| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | # Module 'Buttons' | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | # Import module 'rect' renamed as '_rect' to avoid exporting it on | 
					
						
							|  |  |  | # 'from Buttons import *' | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | # | 
					
						
							|  |  |  | import rect | 
					
						
							|  |  |  | _rect = rect | 
					
						
							|  |  |  | del rect | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Field indices in mouse event detail | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | _HV = 0 | 
					
						
							|  |  |  | _CLICKS = 1 | 
					
						
							|  |  |  | _BUTTON = 2 | 
					
						
							|  |  |  | _MASK = 3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | # LabelAppearance provides defaults for all appearance methods. | 
					
						
							|  |  |  | # selected state not visible | 
					
						
							|  |  |  | # disabled --> crossed out | 
					
						
							|  |  |  | # hilited  --> inverted | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class LabelAppearance: | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Initialization | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 	def init_appearance(self): | 
					
						
							|  |  |  | 		self.bounds = _rect.empty | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 		self.enabled = 1 | 
					
						
							|  |  |  | 		self.hilited = 0 | 
					
						
							|  |  |  | 		self.selected = 0 | 
					
						
							|  |  |  | 		self.text = '' | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Size enquiry | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-14 12:57:56 +00:00
										 |  |  | 	def getminsize(self, m, (width, height)): | 
					
						
							| 
									
										
										
										
											1991-08-16 13:04:40 +00:00
										 |  |  | 		width = max(width, m.textwidth(self.text) + 6) | 
					
						
							|  |  |  | 		height = max(height, m.lineheight() + 6) | 
					
						
							|  |  |  | 		return width, height | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def getbounds(self): | 
					
						
							|  |  |  | 		return self.bounds | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Changing the parameters | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def settext(self, text): | 
					
						
							|  |  |  | 		self.text = text | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		if self.bounds <> _rect.empty: | 
					
						
							|  |  |  | 			self.recalctextpos() | 
					
						
							|  |  |  | 			self.redraw() | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def setbounds(self, bounds): | 
					
						
							|  |  |  | 		self.bounds = bounds | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		if self.bounds <> _rect.empty: | 
					
						
							|  |  |  | 			self.recalc() | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1991-04-07 13:32:19 +00:00
										 |  |  | 	def realize(self): | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# Changing the state bits | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def enable(self, flag): | 
					
						
							|  |  |  | 		if flag <> self.enabled: | 
					
						
							|  |  |  | 			self.enabled = flag | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 			if self.bounds <> _rect.empty: | 
					
						
							|  |  |  | 				self.flipenable(self.parent.begindrawing()) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def hilite(self, flag): | 
					
						
							|  |  |  | 		if flag <> self.hilited: | 
					
						
							|  |  |  | 			self.hilited = flag | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 			if self.bounds <> _rect.empty: | 
					
						
							|  |  |  | 				self.fliphilite(self.parent.begindrawing()) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def select(self, flag): | 
					
						
							|  |  |  | 		if flag <> self.selected: | 
					
						
							|  |  |  | 			self.selected = flag | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 			if self.bounds <> _rect.empty: | 
					
						
							|  |  |  | 				self.redraw() | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 	# Recalculate the box bounds and text position. | 
					
						
							|  |  |  | 	# This can be overridden by buttons that draw different boxes | 
					
						
							|  |  |  | 	# or want their text in a different position. | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def recalc(self): | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		if self.bounds <> _rect.empty: | 
					
						
							|  |  |  | 			self.recalcbounds() | 
					
						
							|  |  |  | 			self.recalctextpos() | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def recalcbounds(self): | 
					
						
							|  |  |  | 		self.hilitebounds = _rect.inset(self.bounds, (3, 3)) | 
					
						
							|  |  |  | 		self.crossbounds = self.bounds | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def recalctextpos(self): | 
					
						
							|  |  |  | 		(left, top), (right, bottom) = self.bounds | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		m = self.parent.beginmeasuring() | 
					
						
							|  |  |  | 		h = (left + right - m.textwidth(self.text)) / 2 | 
					
						
							|  |  |  | 		v = (top + bottom - m.lineheight()) / 2 | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		self.textpos = h, v | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 	# Generic drawing interface. | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 	# Do not override redraw() or draw() methods; override drawit() c.s. | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def redraw(self): | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		if self.bounds <> _rect.empty: | 
					
						
							| 
									
										
										
										
											1991-05-14 12:13:40 +00:00
										 |  |  | 			d = self.parent.begindrawing() | 
					
						
							|  |  |  | 			d.erase(self.bounds) | 
					
						
							|  |  |  | 			self.draw(d, self.bounds) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-14 12:57:56 +00:00
										 |  |  | 	def draw(self, d, area): | 
					
						
							|  |  |  | 		area = _rect.intersect([area, self.bounds]) | 
					
						
							| 
									
										
										
										
											1992-01-01 19:35:13 +00:00
										 |  |  | 		if area == _rect.empty: | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		d.cliprect(area) | 
					
						
							|  |  |  | 		self.drawit(d) | 
					
						
							|  |  |  | 		d.noclip() | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# The drawit() method is fairly generic but may be overridden. | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def drawit(self, d): | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		self.drawpict(d) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 		if self.text: | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 			d.text(self.textpos, self.text) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 		if not self.enabled: | 
					
						
							|  |  |  | 			self.flipenable(d) | 
					
						
							|  |  |  | 		if self.hilited: | 
					
						
							|  |  |  | 			self.fliphilite(d) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# Default drawing detail functions. | 
					
						
							|  |  |  | 	# Overriding these is normally sufficient to get different | 
					
						
							|  |  |  | 	# appearances. | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def drawpict(self, d): | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def flipenable(self, d): | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		_xorcross(d, self.crossbounds) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def fliphilite(self, d): | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		d.invert(self.hilitebounds) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-08-16 13:04:40 +00:00
										 |  |  | # A Strut is a label with no width of its own. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class StrutAppearance(LabelAppearance): | 
					
						
							| 
									
										
										
										
											1991-08-16 13:04:40 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-14 12:57:56 +00:00
										 |  |  | 	def getminsize(self, m, (width, height)): | 
					
						
							| 
									
										
										
										
											1991-08-16 13:04:40 +00:00
										 |  |  | 		height = max(height, m.lineheight() + 6) | 
					
						
							|  |  |  | 		return width, height | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | # ButtonAppearance displays a centered string in a box. | 
					
						
							|  |  |  | # selected --> bold border | 
					
						
							|  |  |  | # disabled --> crossed out | 
					
						
							|  |  |  | # hilited  --> inverted | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class ButtonAppearance(LabelAppearance): | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def drawpict(self, d): | 
					
						
							|  |  |  | 		d.box(_rect.inset(self.bounds, (1, 1))) | 
					
						
							|  |  |  | 		if self.selected: | 
					
						
							|  |  |  | 			# Make a thicker box | 
					
						
							|  |  |  | 			d.box(self.bounds) | 
					
						
							|  |  |  | 			d.box(_rect.inset(self.bounds, (2, 2))) | 
					
						
							|  |  |  | 			d.box(_rect.inset(self.bounds, (3, 3))) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # CheckAppearance displays a small square box and a left-justified string. | 
					
						
							|  |  |  | # selected --> a cross appears in the box | 
					
						
							|  |  |  | # disabled --> whole button crossed out | 
					
						
							|  |  |  | # hilited  --> box is inverted | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class CheckAppearance(LabelAppearance): | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-14 12:57:56 +00:00
										 |  |  | 	def getminsize(self, m, (width, height)): | 
					
						
							| 
									
										
										
										
											1991-08-16 13:04:40 +00:00
										 |  |  | 		minwidth = m.textwidth(self.text) + 6 | 
					
						
							|  |  |  | 		minheight = m.lineheight() + 6 | 
					
						
							|  |  |  | 		width = max(width, minwidth + minheight + m.textwidth(' ')) | 
					
						
							|  |  |  | 		height = max(height, minheight) | 
					
						
							|  |  |  | 		return width, height | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	def drawpict(self, d): | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		d.box(self.boxbounds) | 
					
						
							|  |  |  | 		if self.selected: _xorcross(d, self.boxbounds) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 	def recalcbounds(self): | 
					
						
							|  |  |  | 		LabelAppearance.recalcbounds(self) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 		(left, top), (right, bottom) = self.bounds | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		self.size = bottom - top - 4 | 
					
						
							|  |  |  | 		self.boxbounds = (left+2, top+2), (left+2+self.size, bottom-2) | 
					
						
							|  |  |  | 		self.hilitebounds = self.boxbounds | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 	def recalctextpos(self): | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		m = self.parent.beginmeasuring() | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		(left, top), (right, bottom) = self.boxbounds | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		h = right + m.textwidth(' ') | 
					
						
							|  |  |  | 		v = top + (self.size - m.lineheight()) / 2 | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		self.textpos = h, v | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # RadioAppearance displays a round indicator and a left-justified string. | 
					
						
							|  |  |  | # selected --> a dot appears in the indicator | 
					
						
							|  |  |  | # disabled --> whole button crossed out | 
					
						
							|  |  |  | # hilited  --> indicator is inverted | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class RadioAppearance(CheckAppearance): | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def drawpict(self, d): | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		(left, top), (right, bottom) = self.boxbounds | 
					
						
							|  |  |  | 		radius = self.size / 2 | 
					
						
							| 
									
										
										
										
											1991-05-14 12:13:40 +00:00
										 |  |  | 		center = left + radius, top + radius | 
					
						
							|  |  |  | 		d.circle(center, radius) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 		if self.selected: | 
					
						
							| 
									
										
										
										
											1991-05-14 12:13:40 +00:00
										 |  |  | 			d.fillcircle(center, radius*3/5) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | # NoReactivity ignores mouse events. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class NoReactivity: | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 	def init_reactivity(self): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # BaseReactivity defines hooks and asks for mouse events, | 
					
						
							|  |  |  | # but provides only dummy mouse event handlers. | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | # The trigger methods call the corresponding hooks set by the user. | 
					
						
							|  |  |  | # Hooks (and triggers) mean the following: | 
					
						
							|  |  |  | # down_hook	called on some mouse-down events | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | # move_hook	called on some mouse-move events | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | # up_hook	called on mouse-up events | 
					
						
							|  |  |  | # on_hook	called for buttons with on/off state, when it goes on | 
					
						
							|  |  |  | # hook		called when a button 'fires' or a radiobutton goes on | 
					
						
							|  |  |  | # There are usually extra conditions, e.g., hooks are only called | 
					
						
							|  |  |  | # when the button is enabled, or active, or selected (on). | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class BaseReactivity: | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def init_reactivity(self): | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		self.down_hook = self.move_hook = self.up_hook = \ | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 			self.on_hook = self.off_hook = \ | 
					
						
							|  |  |  | 			self.hook = self.active = 0 | 
					
						
							|  |  |  | 		self.parent.need_mouse(self) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def mousetest(self, hv): | 
					
						
							|  |  |  | 		return _rect.pointinrect(hv, self.bounds) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_down(self, detail): | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_move(self, detail): | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_up(self, detail): | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def down_trigger(self): | 
					
						
							|  |  |  | 		if self.down_hook: self.down_hook(self) | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 	def move_trigger(self): | 
					
						
							|  |  |  | 		if self.move_hook: self.move_hook(self) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def up_trigger(self): | 
					
						
							|  |  |  | 		if self.up_hook: self.up_hook(self) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def on_trigger(self): | 
					
						
							|  |  |  | 		if self.on_hook: self.on_hook(self) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def off_trigger(self): | 
					
						
							|  |  |  | 		if self.off_hook: self.off_hook(self) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def trigger(self): | 
					
						
							|  |  |  | 		if self.hook: self.hook(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # ToggleReactivity acts like a simple pushbutton. | 
					
						
							|  |  |  | # It toggles its hilite state on mouse down events. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class ToggleReactivity(BaseReactivity): | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_down(self, detail): | 
					
						
							|  |  |  | 		if self.enabled and self.mousetest(detail[_HV]): | 
					
						
							|  |  |  | 			self.active = 1 | 
					
						
							|  |  |  | 			self.hilite(not self.hilited) | 
					
						
							|  |  |  | 			self.down_trigger() | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_move(self, detail): | 
					
						
							|  |  |  | 		if self.active: | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 			self.move_trigger() | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_up(self, detail): | 
					
						
							|  |  |  | 		if self.active: | 
					
						
							|  |  |  | 			self.up_trigger() | 
					
						
							|  |  |  | 			self.active = 0 | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def down_trigger(self): | 
					
						
							|  |  |  | 		if self.hilited: | 
					
						
							|  |  |  | 			self.on_trigger() | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			self.off_trigger() | 
					
						
							|  |  |  | 		self.trigger() | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # TriggerReactivity acts like a fancy pushbutton. | 
					
						
							|  |  |  | # It hilites itself while the mouse is down within its bounds. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class TriggerReactivity(BaseReactivity): | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_down(self, detail): | 
					
						
							|  |  |  | 		if self.enabled and self.mousetest(detail[_HV]): | 
					
						
							|  |  |  | 			self.active = 1 | 
					
						
							|  |  |  | 			self.hilite(1) | 
					
						
							|  |  |  | 			self.down_trigger() | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_move(self, detail): | 
					
						
							|  |  |  | 		if self.active: | 
					
						
							|  |  |  | 			self.hilite(self.mousetest(detail[_HV])) | 
					
						
							|  |  |  | 			if self.hilited: | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 				self.move_trigger() | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def mouse_up(self, detail): | 
					
						
							|  |  |  | 		if self.active: | 
					
						
							|  |  |  | 			self.hilite(self.mousetest(detail[_HV])) | 
					
						
							|  |  |  | 			if self.hilited: | 
					
						
							|  |  |  | 				self.up_trigger() | 
					
						
							|  |  |  | 				self.trigger() | 
					
						
							|  |  |  | 			self.active = 0 | 
					
						
							|  |  |  | 			self.hilite(0) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # CheckReactivity handles mouse events like TriggerReactivity, | 
					
						
							|  |  |  | # It overrides the up_trigger method to flip its selected state. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class CheckReactivity(TriggerReactivity): | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def up_trigger(self): | 
					
						
							|  |  |  | 		self.select(not self.selected) | 
					
						
							|  |  |  | 		if self.selected: | 
					
						
							|  |  |  | 			self.on_trigger() | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			self.off_trigger() | 
					
						
							|  |  |  | 		self.trigger() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # RadioReactivity turns itself on and the other buttons in its group | 
					
						
							|  |  |  | # off when its up_trigger method is called. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class RadioReactivity(TriggerReactivity): | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	def init_reactivity(self): | 
					
						
							|  |  |  | 		TriggerReactivity.init_reactivity(self) | 
					
						
							|  |  |  | 		self.group = [] | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def up_trigger(self): | 
					
						
							|  |  |  | 		for b in self.group: | 
					
						
							|  |  |  | 			if b <> self: | 
					
						
							|  |  |  | 				if b.selected: | 
					
						
							|  |  |  | 					b.select(0) | 
					
						
							|  |  |  | 					b.off_trigger() | 
					
						
							|  |  |  | 		self.select(1) | 
					
						
							|  |  |  | 		self.on_trigger() | 
					
						
							|  |  |  | 		self.trigger() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Auxiliary class for 'define' method. | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | # Call the initializers in the right order. | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class Define: | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 	def define(self, parent): | 
					
						
							|  |  |  | 		self.parent = parent | 
					
						
							|  |  |  | 		parent.addchild(self) | 
					
						
							|  |  |  | 		self.init_appearance() | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 		self.init_reactivity() | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		return self | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	def destroy(self): | 
					
						
							|  |  |  | 		self.parent = 0 | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-14 12:57:56 +00:00
										 |  |  | 	def definetext(self, parent, text): | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | 		self = self.define(parent) | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | 		self.settext(text) | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | 		return self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-25 18:50:27 +00:00
										 |  |  | # Subroutine to cross out a rectangle. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def _xorcross(d, bounds): | 
					
						
							|  |  |  | 	((left, top), (right, bottom)) = bounds | 
					
						
							|  |  |  | 	# This is s bit funny to make it look better | 
					
						
							|  |  |  | 	left = left + 2 | 
					
						
							|  |  |  | 	right = right - 2 | 
					
						
							|  |  |  | 	top = top + 2 | 
					
						
							|  |  |  | 	bottom = bottom - 3 | 
					
						
							|  |  |  | 	d.xorline(((left, top), (right, bottom))) | 
					
						
							|  |  |  | 	d.xorline((left, bottom), (right, top)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-11-05 19:44:31 +00:00
										 |  |  | # Ready-made button classes. | 
					
						
							| 
									
										
										
										
											1990-10-24 16:39:18 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											1991-12-26 13:06:29 +00:00
										 |  |  | class Label(NoReactivity, LabelAppearance, Define): pass | 
					
						
							|  |  |  | class Strut(NoReactivity, StrutAppearance, Define): pass | 
					
						
							|  |  |  | class PushButton(TriggerReactivity, ButtonAppearance, Define): pass | 
					
						
							|  |  |  | class CheckButton(CheckReactivity, CheckAppearance, Define): pass | 
					
						
							|  |  |  | class RadioButton(RadioReactivity, RadioAppearance, Define): pass | 
					
						
							|  |  |  | class ToggleButton(ToggleReactivity, ButtonAppearance, Define): pass |