blob: 71d734c931404b30a00d68084e896ceaf0df3ccc [file] [log] [blame]
Just van Rossum64350b42001-11-02 19:17:16 +00001from Carbon import Ctl, Controls
2from Carbon import Evt, Qd, Win
Just van Rossum40f9b7b1999-01-30 22:39:17 +00003import Wbase
Just van Rossum64350b42001-11-02 19:17:16 +00004
Just van Rossum40f9b7b1999-01-30 22:39:17 +00005
6class ControlWidget(Wbase.ClickableWidget):
7
8 """Baseclass for all native controls."""
9
Jack Jansenb6b6c6c2001-12-04 13:30:29 +000010 def __init__(self, possize, title = "Control", procID = 0, callback = None, value = 0, min = 0, max = 1, viewsize = 0):
Just van Rossum40f9b7b1999-01-30 22:39:17 +000011 Wbase.ClickableWidget.__init__(self, possize)
12 self._control = None
13 self._title = title
14 self._callback = callback
15 self._procID = procID
16 self._value = value
17 self._min = min
18 self._max = max
19 self._enabled = 1
Jack Jansenb6b6c6c2001-12-04 13:30:29 +000020 self._viewsize = viewsize
Just van Rossum40f9b7b1999-01-30 22:39:17 +000021
22 def open(self):
23 self._calcbounds()
Jack Jansenb6b6c6c2001-12-04 13:30:29 +000024
25 # NewControl doesn't accept 32-bit value, min, or max, so for consistency
26 # with the new 32-bit set/get methods, out-of-range values are initially
27 # set as zero, followed by a 32-bit set of the actual value.
28 # Values not representable in 16 bits will fail on MacOS 8.1, however
29 # the vast majority of control usage should still be compatible.
30 _value, _min, _max = self._value, self._min, self._max
31 if -32768 <= _value <= 32767:
32 bigvalue = None
33 else:
34 bigvalue = _value
35 _value = 0
36 if -32768 <= _min <= 32767:
37 bigmin = None
38 else:
39 bigmin = _min
40 _min = 0
41 if -32768 <= _max <= 32767:
42 bigmax = None
43 else:
44 bigmax = _max
45 _max = 0
Just van Rossum40f9b7b1999-01-30 22:39:17 +000046 self._control = Ctl.NewControl(self._parentwindow.wid,
47 self._bounds,
48 self._title,
49 1,
Jack Jansenb6b6c6c2001-12-04 13:30:29 +000050 _value,
51 _min,
52 _max,
Just van Rossum40f9b7b1999-01-30 22:39:17 +000053 self._procID,
54 0)
Jack Jansenb6b6c6c2001-12-04 13:30:29 +000055 if bigvalue:
56 self._control.SetControl32BitValue(bigvalue)
57 if bigmin:
58 self._control.SetControl32BitMinimum(bigmin)
59 if bigmax:
60 self._control.SetControl32BitMaximum(bigmax)
Just van Rossumf376ef02001-11-18 14:12:43 +000061 if self._viewsize:
Jack Jansenb6b6c6c2001-12-04 13:30:29 +000062 try:
63 self._control.SetControlViewSize(self._viewsize)
64 # Not available in MacOS 8.1, but that's OK since it only affects
65 # proportional scrollbars which weren't available in 8.1 either.
66 except NotImplementedError:
67 pass
Just van Rossum40f9b7b1999-01-30 22:39:17 +000068 self.enable(self._enabled)
69
70 def adjust(self, oldbounds):
71 self.SetPort()
72 self._control.HideControl()
73 self._control.MoveControl(self._bounds[0], self._bounds[1])
74 self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
75 if self._visible:
76 Qd.EraseRect(self._bounds)
77 self._control.ShowControl()
Jack Jansen73023402001-01-23 14:58:20 +000078 self.GetWindow().ValidWindowRect(self._bounds)
Just van Rossum40f9b7b1999-01-30 22:39:17 +000079
80 def close(self):
81 self._control.HideControl()
82 self._control = None
83 Wbase.ClickableWidget.close(self)
84
85 def enable(self, onoff):
86 if self._control and self._enabled <> onoff:
87 self._control.HiliteControl((not onoff) and 255)
88 self._enabled = onoff
89
90 def show(self, onoff):
91 self._visible = onoff
92 for w in self._widgets:
93 w.show(onoff)
94 if onoff:
95 self._control.ShowControl()
96 else:
97 self._control.HideControl()
98
99 def activate(self, onoff):
100 self._activated = onoff
101 if self._enabled:
Just van Rossuma73f78b2001-11-02 21:12:52 +0000102 if onoff:
103 self._control.ActivateControl()
104 else:
105 self._control.DeactivateControl()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000106
107 def draw(self, visRgn = None):
108 if self._visible:
109 self._control.Draw1Control()
110
111 def test(self, point):
Just van Rossumf376ef02001-11-18 14:12:43 +0000112 if Qd.PtInRect(point, self._bounds) and self._enabled:
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000113 return 1
Just van Rossumf376ef02001-11-18 14:12:43 +0000114 #ctltype, control = Ctl.FindControl(point, self._parentwindow.wid)
115 #if self._enabled and control == self._control:
116 # return 1
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000117
118 def click(self, point, modifiers):
119 if not self._enabled:
120 return
121 part = self._control.TrackControl(point)
122 if part:
123 if self._callback:
124 Wbase.CallbackCall(self._callback, 0)
125
126 def settitle(self, title):
127 if self._control:
128 self._control.SetControlTitle(title)
129 self._title = title
130
131 def gettitle(self):
132 return self._title
Just van Rossum2dd4d162001-11-02 22:51:42 +0000133
134 def set(self, value):
135 if self._control:
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000136 if -32768 <= value <= 32767:
137 # No 32-bit control support in MacOS 8.1, so use
138 # the 16-bit interface when possible.
139 self._control.SetControlValue(value)
140 else:
141 self._control.SetControl32BitValue(value)
Just van Rossum2dd4d162001-11-02 22:51:42 +0000142 else:
143 self._value = value
144
145 def get(self):
146 if self._control:
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000147 try:
148 return self._control.GetControl32BitValue()
149 # No 32-bit control support in MacOS 8.1, so fall
150 # back to the 16-bit interface when needed.
151 except NotImplementedError:
152 return self._control.GetControlValue()
Just van Rossum2dd4d162001-11-02 22:51:42 +0000153 else:
154 return self._value
155
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000156
157class Button(ControlWidget):
158
159 """Standard push button."""
160
Just van Rossumf376ef02001-11-18 14:12:43 +0000161 procID = Controls.pushButProc | Controls.useWFont
162
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000163 def __init__(self, possize, title = "Button", callback = None):
Just van Rossumf376ef02001-11-18 14:12:43 +0000164 ControlWidget.__init__(self, possize, title, self.procID, callback, 0, 0, 1)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000165 self._isdefault = 0
166
167 def push(self):
168 if not self._enabled:
169 return
Just van Rossumf376ef02001-11-18 14:12:43 +0000170 # emulate the pushing of the button
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000171 import time
Just van Rossuma73f78b2001-11-02 21:12:52 +0000172 self._control.HiliteControl(Controls.kControlButtonPart)
Just van Rossumf376ef02001-11-18 14:12:43 +0000173 Qd.QDFlushPortBuffer(self._parentwindow.wid, None) # needed under OSX
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000174 time.sleep(0.1)
175 self._control.HiliteControl(0)
176 if self._callback:
177 Wbase.CallbackCall(self._callback, 0)
178
179 def enable(self, onoff):
180 if self._control and self._enabled <> onoff:
181 self._control.HiliteControl((not onoff) and 255)
182 self._enabled = onoff
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000183
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000184 def show(self, onoff):
185 ControlWidget.show(self, onoff)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000186
187 def draw(self, visRgn = None):
188 if self._visible:
189 self._control.Draw1Control()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000190
Just van Rossumf376ef02001-11-18 14:12:43 +0000191 def open(self):
192 ControlWidget.open(self)
193 if self._isdefault:
194 self._setdefault(self._isdefault)
195
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000196 def _setdefault(self, onoff):
Just van Rossumf376ef02001-11-18 14:12:43 +0000197 c = self._control
198 if c is not None:
199 if onoff:
200 data = "\xFF"
201 else:
202 data = "\0"
203 # hide before changing state, otherwise the button isn't always
204 # redrawn correctly, although it's quite different under Aqua
205 # and Classic...
206 c.HideControl()
207 c.SetControlData(Controls.kControlNoPart,
208 Controls.kControlPushButtonDefaultTag, data)
209 c.ShowControl()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000210 self._isdefault = onoff
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000211
212 def adjust(self, oldbounds):
213 if self._isdefault:
214 old = Qd.InsetRect(oldbounds, -4, -4)
215 new = Qd.InsetRect(self._bounds, -4, -4)
216 Qd.EraseRect(old)
Jack Jansen73023402001-01-23 14:58:20 +0000217 self.GetWindow().InvalWindowRect(old)
218 self.GetWindow().InvalWindowRect(new)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000219 ControlWidget.adjust(self, oldbounds)
220
221
Just van Rossumf376ef02001-11-18 14:12:43 +0000222class BevelButton(Button):
223 procID = Controls.kControlBevelButtonNormalBevelProc | Controls.useWFont
224
225
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000226class CheckBox(ControlWidget):
227
228 """Standard checkbox."""
229
230 def __init__(self, possize, title = "Checkbox", callback = None, value = 0):
231 procID = Controls.checkBoxProc | Controls.useWFont
232 ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
233
234 def click(self, point, modifiers):
235 if not self._enabled:
236 return
237 part = self._control.TrackControl(point)
238 if part:
239 self.toggle()
240 if self._callback:
241 Wbase.CallbackCall(self._callback, 0, self.get())
242
243 def push(self):
244 if not self._enabled:
245 return
246 self.toggle()
247 if self._callback:
248 Wbase.CallbackCall(self._callback, 0, self.get())
249
250 def toggle(self):
251 self.set(not self.get())
Just van Rossum2dd4d162001-11-02 22:51:42 +0000252
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000253
254class RadioButton(ControlWidget):
255
256 """Standard radiobutton."""
257
258 # XXX We need a radiogroup widget; this is too kludgy.
259
260 def __init__(self, possize, title, thebuttons, callback = None, value = 0):
261 procID = Controls.radioButProc | Controls.useWFont
262 ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
263 self.thebuttons = thebuttons
264 thebuttons.append(self)
265
266 def close(self):
267 self.thebuttons = None
268 ControlWidget.close(self)
269
270 def click(self, point, modifiers):
271 if not self._enabled:
272 return
273 part = self._control.TrackControl(point)
274 if part:
275 self.set(1)
276 if self._callback:
277 Wbase.CallbackCall(self._callback, 0, 1)
278
279 def push(self):
280 if not self._enabled:
281 return
282 self.set(1)
283 if self._callback:
284 Wbase.CallbackCall(self._callback, 0, 1)
285
286 def set(self, value):
287 for button in self.thebuttons:
288 if button._control:
289 button._control.SetControlValue(button == self)
290 else:
291 button._value = (button == self)
Just van Rossum2dd4d162001-11-02 22:51:42 +0000292
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000293
294class Scrollbar(ControlWidget):
295
296 """Standard scrollbar."""
297
298 def __init__(self, possize, callback = None, value = 0, min = 0, max = 0):
299 procID = Controls.scrollBarProc
300 ControlWidget.__init__(self, possize, "", procID, callback, value, min, max)
301
302 # interface
Just van Rossum2dd4d162001-11-02 22:51:42 +0000303# def set(self, value):
304# if self._callback:
305# Wbase.CallbackCall(self._callback, 1, value)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000306
307 def up(self):
308 if self._callback:
309 Wbase.CallbackCall(self._callback, 1, '+')
310
311 def down(self):
312 if self._callback:
313 Wbase.CallbackCall(self._callback, 1, '-')
314
315 def pageup(self):
316 if self._callback:
317 Wbase.CallbackCall(self._callback, 1, '++')
318
319 def pagedown(self):
320 if self._callback:
321 Wbase.CallbackCall(self._callback, 1, '--')
322
323 def setmin(self, min):
Just van Rossumf376ef02001-11-18 14:12:43 +0000324 if self._control is not None:
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000325 if -32768 <= min <= 32767:
326 # No 32-bit control support in MacOS 8.1, so use
327 # the 16-bit interface when possible.
328 self._control.SetControlMinimum(min)
329 else:
330 self._control.SetControl32BitMinimum(min)
Just van Rossumf376ef02001-11-18 14:12:43 +0000331 else:
332 self._min = min
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000333
Just van Rossum2dd4d162001-11-02 22:51:42 +0000334 def setmax(self, max):
Just van Rossumf376ef02001-11-18 14:12:43 +0000335 if self._control is not None:
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000336 if -32768 <= max <= 32767:
337 # No 32-bit control support in MacOS 8.1, so use
338 # the 16-bit interface when possible.
339 self._control.SetControlMaximum(max)
340 else:
341 self._control.SetControl32BitMaximum(max)
Just van Rossumf376ef02001-11-18 14:12:43 +0000342 else:
343 self._max = max
Just van Rossum2dd4d162001-11-02 22:51:42 +0000344
Just van Rossumf376ef02001-11-18 14:12:43 +0000345 def setviewsize(self, viewsize):
346 if self._control is not None:
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000347 try:
348 self._control.SetControlViewSize(viewsize)
349 # Not available in MacOS 8.1, but that's OK since it only affects
350 # proportional scrollbars which weren't available in 8.1 either.
351 except NotImplementedError:
352 pass
Just van Rossumf376ef02001-11-18 14:12:43 +0000353 else:
354 self._viewsize = viewsize
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000355
356 def getmin(self):
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000357 try:
358 return self._control.GetControl32BitMinimum()
359 # No 32-bit control support in MacOS 8.1, so fall
360 # back to the 16-bit interface when needed.
361 except NotImplementedError:
362 return self._control.GetControlMinimum()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000363
364 def getmax(self):
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000365 try:
366 return self._control.GetControl32BitMaximum()
367 # No 32-bit control support in MacOS 8.1, so fall
368 # back to the 16-bit interface when needed.
369 except NotImplementedError:
370 return self._control.GetControlMaximum()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000371
372 # internals
373 def click(self, point, modifiers):
374 if not self._enabled:
375 return
376 # custom TrackControl. A mousedown in a scrollbar arrow or page area should
377 # generate _control hits as long as the mouse is a) down, b) still in the same part
378 part = self._control.TestControl(point)
379 if Controls.inUpButton <= part <= Controls.inPageDown:
380 self._control.HiliteControl(part)
381 self._hit(part)
382 oldpart = part
Just van Rossumeb67a7b1999-04-21 09:24:02 +0000383 # slight delay before scrolling at top speed...
384 now = Evt.TickCount()
385 while Evt.StillDown():
386 if (Evt.TickCount() - now) > 18: # 0.3 seconds
387 break
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000388 while Evt.StillDown():
389 part = self._control.TestControl(point)
390 if part == oldpart:
391 self._control.HiliteControl(part)
392 self._hit(part)
393 else:
394 self._control.HiliteControl(0)
395 self.SetPort()
396 point = Evt.GetMouse()
397 self._control.HiliteControl(0)
398 elif part == Controls.inThumb:
399 part = self._control.TrackControl(point)
400 if part:
401 self._hit(part)
402
403 def _hit(self, part):
404 if part == Controls.inThumb:
Jack Jansenb6b6c6c2001-12-04 13:30:29 +0000405 try:
406 value = self._control.GetControl32BitValue()
407 # No 32-bit control support in MacOS 8.1, so fall
408 # back to the 16-bit interface when needed.
409 except NotImplementedError:
410 value = self._control.GetControlValue()
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000411 elif part == Controls.inUpButton:
412 value = "+"
413 elif part == Controls.inDownButton:
414 value = "-"
415 elif part == Controls.inPageUp:
416 value = "++"
417 elif part == Controls.inPageDown:
418 value = "--"
419 if self._callback:
420 Wbase.CallbackCall(self._callback, 1, value)
421
422 def draw(self, visRgn = None):
423 if self._visible:
424 self._control.Draw1Control()
Just van Rossumf376ef02001-11-18 14:12:43 +0000425 #Qd.FrameRect(self._bounds)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000426
427 def adjust(self, oldbounds):
428 self.SetPort()
Jack Jansen73023402001-01-23 14:58:20 +0000429 self.GetWindow().InvalWindowRect(oldbounds)
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000430 self._control.HideControl()
431 self._control.MoveControl(self._bounds[0], self._bounds[1])
432 self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
433 if self._visible:
434 Qd.EraseRect(self._bounds)
435 if self._activated:
436 self._control.ShowControl()
437 else:
438 Qd.FrameRect(self._bounds)
Jack Jansen73023402001-01-23 14:58:20 +0000439 self.GetWindow().ValidWindowRect(self._bounds)
Just van Rossum2dd4d162001-11-02 22:51:42 +0000440
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000441
Just van Rossum40f9b7b1999-01-30 22:39:17 +0000442def _scalebarvalue(absmin, absmax, curmin, curmax):
443 if curmin <= absmin and curmax >= absmax:
444 return None
445 if curmin <= absmin:
446 return 0
447 if curmax >= absmax:
448 return 32767
449 perc = float(curmin-absmin) / float((absmax - absmin) - (curmax - curmin))
450 return int(perc*32767)
451