summaryrefslogtreecommitdiffstats
path: root/Doc/mac/libmacui.tex
blob: 8e42e6a505e361bd568e4f65a56c720f4487a41a (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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
\section{Standard module \sectcode{EasyDialogs}}
\label{module-EasyDialogs}
\stmodindex{EasyDialogs}

The \code{EasyDialogs} module contains some simple dialogs for
the Macintosh, modelled after the \code{stdwin} dialogs with similar
names. All routines have an optional parameter \var{id} with which you
can override the DLOG resource used for the dialog, as long as the
item numbers correspond. See the source for details.

The \code{EasyDialogs} module defines the following functions:

\renewcommand{\indexsubitem}{(in module EasyDialogs)}

\begin{funcdesc}{Message}{str}
A modal dialog with the message text \var{str}, which should be at
most 255 characters long, is displayed. Control is returned when the
user clicks ``OK''.
\end{funcdesc}

\begin{funcdesc}{AskString}{prompt\optional{\, default}}
Ask the user to input a string value, in a modal dialog. \var{Prompt}
is the promt message, the optional \var{default} arg is the initial
value for the string. All strings can be at most 255 bytes
long. \var{AskString} returns the string entered or \code{None} in
case the user cancelled.
\end{funcdesc}

\begin{funcdesc}{AskYesNoCancel}{question\optional{\, default}}
Present a dialog with text \var{question} and three buttons labelled
``yes'', ``no'' and ``cancel''. Return \code{1} for yes, \code{0} for
no and \code{-1} for cancel. The default return value chosen by
hitting return is \code{0}. This can be changed with the optional
\var{default} argument.
\end{funcdesc}

\begin{funcdesc}{ProgressBar}{\optional{label\, maxval}}
Display a modeless progress dialog with a thermometer bar. \var{Label}
is the textstring displayed (default ``Working...''), \var{maxval} is
the value at which progress is complete (default 100). The returned
object has one method, \code{set(value)}, which sets the value of the
progress bar. The bar remains visible until the object returned is
discarded.

The progress bar has a ``cancel'' button, but it is currently
non-functional.
\end{funcdesc}

Note that \code{EasyDialogs} does not currently use the notification
manager. This means that displaying dialogs while the program is in
the background will lead to unexpected results and possibly
crashes. Also, all dialogs are modeless and hence expect to be at the
top of the stacking order. This is true when the dialogs are created,
but windows that pop-up later (like a console window) may also result
in crashes.


\section{Standard module \sectcode{FrameWork}}
\stmodindex{FrameWork}

The \code{FrameWork} module contains classes that together provide a
framework for an interactive Macintosh application. The programmer
builds an application by creating subclasses that override various
methods of the bases classes, thereby implementing the functionality
wanted. Overriding functionality can often be done on various
different levels, i.e. to handle clicks in a single dialog window in a
non-standard way it is not necessary to override the complete event
handling.

The \code{FrameWork} is still very much work-in-progress, and the
documentation describes only the most important functionality, and not
in the most logical manner at that. Examine the source or the examples
for more details.

The \code{FrameWork} module defines the following functions:

\renewcommand{\indexsubitem}{(in module FrameWork)}

\begin{funcdesc}{Application}{}
An object representing the complete application. See below for a
description of the methods. The default \code{__init__} routine
creates an empty window dictionary and a menu bar with an apple menu.
\end{funcdesc}

\begin{funcdesc}{MenuBar}{}
An object representing the menubar. This object is usually not created
by the user.
\end{funcdesc}

\begin{funcdesc}{Menu}{bar\, title\optional{\, after}}
An object representing a menu. Upon creation you pass the
\code{MenuBar} the menu appears in, the \var{title} string and a
position (1-based) \var{after} where the menu should appear (default:
at the end).
\end{funcdesc}

\begin{funcdesc}{MenuItem}{menu\, title\optional{\, shortcut\, callback}}
Create a menu item object. The arguments are the menu to crate the
item it, the item title string and optionally the keyboard shortcut
and a callback routine. The callback is called with the arguments
menu-id, item number within menu (1-based), current front window and
the event record.

In stead of a callable object the callback can also be a string. In
this case menu selection causes the lookup of a method in the topmost
window and the application. The method name is the callback string
with \code{'domenu_'} prepended.

Calling the \code{MenuBar} \code{fixmenudimstate} method sets the
correct dimming for all menu items based on the current front window.
\end{funcdesc}

\begin{funcdesc}{Separator}{menu}
Add a separator to the end of a menu.
\end{funcdesc}

\begin{funcdesc}{SubMenu}{menu\, label}
Create a submenu named \var{label} under menu \var{menu}. The menu
object is returned.
\end{funcdesc}

\begin{funcdesc}{Window}{parent}
Creates a (modeless) window. \var{Parent} is the application object to
which the window belongs. The window is not displayed until later.
\end{funcdesc}

\begin{funcdesc}{DialogWindow}{parent}
Creates a modeless dialog window.
\end{funcdesc}

\begin{funcdesc}{windowbounds}{width\, height}
Return a \code{(left, top, right, bottom)} tuple suitable for creation
of a window of given width and height. The window will be staggered
with respect to previous windows, and an attempt is made to keep the
whole window on-screen. The window will however always be exact the
size given, so parts may be offscreen.
\end{funcdesc}

\begin{funcdesc}{setwatchcursor}{}
Set the mouse cursor to a watch.
\end{funcdesc}

\begin{funcdesc}{setarrowcursor}{}
Set the mouse cursor to an arrow.
\end{funcdesc}

\subsection{Application objects}
Application objects have the following methods, among others:

\renewcommand{\indexsubitem}{(Application method)}

\begin{funcdesc}{makeusermenus}{}
Override this method if you need menus in your application. Append the
menus to \code{self.menubar}.
\end{funcdesc}

\begin{funcdesc}{getabouttext}{}
Override this method to return a text string describing your
application. Alternatively, override the \code{do_about} method for
more elaborate about messages.
\end{funcdesc}

\begin{funcdesc}{mainloop}{\optional{mask\, wait}}
This routine is the main event loop, call it to set your application
rolling. \var{Mask} is the mask of events you want to handle,
\var{wait} is the number of ticks you want to leave to other
concurrent application (default 0, which is probably not a good
idea). While raising \code{self} to exit the mainloop is still
supported it is not recommended, call \code{self._quit} instead.

The event loop is split into many small parts, each of which can be
overridden. The default methods take care of dispatching events to
windows and dialogs, handling drags and resizes, Apple Events, events
for non-FrameWork windows, etc.

In general, all event handlers should return 1 if the event is fully
handled and 0 otherwise (because the front window was not a FrameWork
window, for instance). This is needed so that update events and such
can be passed on to other windows like the Sioux console window.
Calling \code{MacOS.HandleEvent} is not allowed within \var{our_dispatch}
or its callees, since this may result in an infinite loop if the
code is called through the python inner-loop event handler.
\end{funcdesc}

\begin{funcdesc}{asyncevents}{onoff}
Call this method with a nonzero parameter to enable
asynchronous event handling. This will tell the inner interpreter loop
to call the application event handler \var{async_dispatch} whenever events
are available. This will cause FrameWork window updates and the user
interface to remain working during long computations, but will slow the
interpreter down and may cause surprising results in non-reentrant code
(such as FrameWork itself). By default \var{async_dispatch} will immedeately
call \var{our_dispatch} but you may override this to handle only certain
events asynchronously. Events you do not handle will be passed to Sioux
and such.

The old on/off value is returned.
\end{funcdesc}

\begin{funcdesc}{_quit}{}
Terminate the event \code{mainloop} at the next convenient moment.
\end{funcdesc}

\begin{funcdesc}{do_char}{c\, event}
The user typed character \var{c}. The complete details of the event
can be found in the \var{event} structure. This method can also be
provided in a \code{Window} object, which overrides the
application-wide handler if the window is frontmost.
\end{funcdesc}

\begin{funcdesc}{do_dialogevent}{event}
Called early in the event loop to handle modeless dialog events. The
default method simply dispatches the event to the relevant dialog (not
through the the \code{DialogWindow} object involved). Override if you
need special handling of dialog events (keyboard shortcuts, etc).
\end{funcdesc}

\begin{funcdesc}{idle}{event}
Called by the main event loop when no events are available. The
null-event is passed (so you can look at mouse position, etc).
\end{funcdesc}

\subsection{Window Objects}

Window objects have the following methods, among others:

\renewcommand{\indexsubitem}{(Window method)}

\begin{funcdesc}{open}{}
Override this method to open a window. Store the MacOS window-id in
\code{self.wid} and call \code{self.do_postopen} to register the
window with the parent application.
\end{funcdesc}

\begin{funcdesc}{close}{}
Override this method to do any special processing on window
close. Call \code{self.do_postclose} to cleanup the parent state.
\end{funcdesc}

\begin{funcdesc}{do_postresize}{width\, height\, macoswindowid}
Called after the window is resized. Override if more needs to be done
than calling \code{InvalRect}.
\end{funcdesc}

\begin{funcdesc}{do_contentclick}{local\, modifiers\, event}
The user clicked in the content part of a window. The arguments are
the coordinates (window-relative), the key modifiers and the raw
event.
\end{funcdesc}

\begin{funcdesc}{do_update}{macoswindowid\, event}
An update event for the window was received. Redraw the window.
\end{funcdesc}

\begin{funcdesc}{do_activate}{activate\, event}
The window was activated (\code{activate==1}) or deactivated
(\code{activate==0}). Handle things like focus highlighting, etc.
\end{funcdesc}

\subsection{ControlsWindow Object}

ControlsWindow objects have the following methods besides those of
\code{Window} objects:

\renewcommand{\indexsubitem}{(ControlsWindow method)}

\begin{funcdesc}{do_controlhit}{window\, control\, pcode\, event}
Part \code{pcode} of control \code{control} was hit by the
user. Tracking and such has already been taken care of.
\end{funcdesc}

\subsection{ScrolledWindow Object}

ScrolledWindow objects are ControlsWindow objects with the following
extra methods:

\renewcommand{\indexsubitem}{(ScrolledWindow method)}

\begin{funcdesc}{scrollbars}{\optional{wantx\, wanty}}
Create (or destroy) horizontal and vertical scrollbars. The arguments
specify which you want (default: both). The scrollbars always have
minimum \code{0} and maximum \code{32767}.
\end{funcdesc}

\begin{funcdesc}{getscrollbarvalues}{}
You must supply this method. It should return a tuple \code{x, y}
giving the current position of the scrollbars (between \code{0} and
\code{32767}). You can return \code{None} for either to indicate the
whole document is visible in that direction.
\end{funcdesc}

\begin{funcdesc}{updatescrollbars}{}
Call this method when the document has changed. It will call
\code{getscrollbarvalues} and update the scrollbars.
\end{funcdesc}

\begin{funcdesc}{scrollbar_callback}{which\, what\, value}
Supplied by you and called after user interaction. \code{Which} will
be \code{'x'} or \code{'y'}, \code{what} will be \code{'-'},
\code{'--'}, \code{'set'}, \code{'++'} or \code{'+'}. For
\code{'set'}, \code{value} will contain the new scrollbar position.
\end{funcdesc}

\begin{funcdesc}{scalebarvalues}{absmin\, absmax\, curmin\, curmax}
Auxiliary method to help you calculate values to return from
\code{getscrollbarvalues}. You pass document minimum and maximum value
and topmost (leftmost) and bottommost (rightmost) visible values and
it returns the correct number or \code{None}.
\end{funcdesc}

\begin{funcdesc}{do_activate}{onoff\, event}
Takes care of dimming/highlighting scrollbars when a window becomes
frontmost vv. If you override this method call this one at the end of
your method.
\end{funcdesc}

\begin{funcdesc}{do_postresize}{width\, height\, window}
Moves scrollbars to the correct position. Call this method initially
if you override it.
\end{funcdesc}

\begin{funcdesc}{do_controlhit}{window\, control\, pcode\, event}
Handles scrollbar interaction. If you override it call this method
first, a nonzero return value indicates the hit was in the scrollbars
and has been handled.
\end{funcdesc}

\subsection{DialogWindow Objects}

DialogWindow objects have the following methods besides those of
\code{Window} objects:

\renewcommand{\indexsubitem}{(DialogWindow method)}

\begin{funcdesc}{open}{resid}
Create the dialog window, from the DLOG resource with id
\var{resid}. The dialog object is stored in \code{self.wid}.
\end{funcdesc}

\begin{funcdesc}{do_itemhit}{item\, event}
Item number \var{item} was hit. You are responsible for redrawing
toggle buttons, etc.
\end{funcdesc}

\section{Standard module \sectcode{MiniAEFrame}}
\stmodindex{MiniAEFrame}

The module \var{MiniAEFrame} provides a framework for an application
that can function as an OSA server, i.e. receive and process
AppleEvents. It can be used in conjunction with \var{FrameWork} or
standalone.

This module is temporary, it will eventually be replaced by a module
that handles argument names better and possibly automates making your
application scriptable.

The \var{MiniAEFrame} module defines the following classes:

\renewcommand{\indexsubitem}{(in module MiniAEFrame)}

\begin{funcdesc}{AEServer}{}
A class that handles AppleEvent dispatch. Your application should
subclass this class together with either
\code{MiniAEFrame.MiniApplication} or
\code{FrameWork.Application}. Your \code{__init__} method should call
the \code{__init__} method for both classes.
\end{funcdesc}

\begin{funcdesc}{MiniApplication}{}
A class that is more or less compatible with
\code{FrameWork.Application} but with less functionality. Its
eventloop supports the apple menu, command-dot and AppleEvents, other
events are passed on to the Python interpreter and/or Sioux.
Useful if your application wants to use \code{AEServer} but does not
provide its own windows, etc.
\end{funcdesc}

\subsection{AEServer Objects}

\renewcommand{\indexsubitem}{(AEServer method)}

\begin{funcdesc}{installaehandler}{classe\, type\, callback}
Installs an AppleEvent handler. \code{Classe} and \code{type} are the
four-char OSA Class and Type designators, \code{'****'} wildcards are
allowed. When a matching AppleEvent is received the parameters are
decoded and your callback is invoked.
\end{funcdesc}

\begin{funcdesc}{callback}{_object\, **kwargs}
Your callback is called with the OSA Direct Object as first positional
parameter. The other parameters are passed as keyword arguments, with
the 4-char designator as name. Three extra keyword parameters are
passed: \code{_class} and \code{_type} are the Class and Type
designators and \code{_attributes} is a dictionary with the AppleEvent
attributes.

The return value of your method is packed with
\code{aetools.packevent} and sent as reply.
\end{funcdesc}

Note that there are some serious problems with the current
design. AppleEvents which have non-identifier 4-char designators for
arguments are not implementable, and it is not possible to return an
error to the originator. This will be addressed in a future release.