|
1 |
|
2 :mod:`FrameWork` --- Interactive application framework |
|
3 ====================================================== |
|
4 |
|
5 .. module:: FrameWork |
|
6 :platform: Mac |
|
7 :synopsis: Interactive application framework. |
|
8 :deprecated: |
|
9 |
|
10 |
|
11 The :mod:`FrameWork` module contains classes that together provide a framework |
|
12 for an interactive Macintosh application. The programmer builds an application |
|
13 by creating subclasses that override various methods of the bases classes, |
|
14 thereby implementing the functionality wanted. Overriding functionality can |
|
15 often be done on various different levels, i.e. to handle clicks in a single |
|
16 dialog window in a non-standard way it is not necessary to override the complete |
|
17 event handling. |
|
18 |
|
19 .. warning:: |
|
20 |
|
21 This module is removed in 3.0. |
|
22 |
|
23 Work on the :mod:`FrameWork` has pretty much stopped, now that :mod:`PyObjC` is |
|
24 available for full Cocoa access from Python, and the documentation describes |
|
25 only the most important functionality, and not in the most logical manner at |
|
26 that. Examine the source or the examples for more details. The following are |
|
27 some comments posted on the MacPython newsgroup about the strengths and |
|
28 limitations of :mod:`FrameWork`: |
|
29 |
|
30 |
|
31 .. epigraph:: |
|
32 |
|
33 The strong point of :mod:`FrameWork` is that it allows you to break into the |
|
34 control-flow at many different places. :mod:`W`, for instance, uses a different |
|
35 way to enable/disable menus and that plugs right in leaving the rest intact. |
|
36 The weak points of :mod:`FrameWork` are that it has no abstract command |
|
37 interface (but that shouldn't be difficult), that its dialog support is minimal |
|
38 and that its control/toolbar support is non-existent. |
|
39 |
|
40 The :mod:`FrameWork` module defines the following functions: |
|
41 |
|
42 |
|
43 .. function:: Application() |
|
44 |
|
45 An object representing the complete application. See below for a description of |
|
46 the methods. The default :meth:`__init__` routine creates an empty window |
|
47 dictionary and a menu bar with an apple menu. |
|
48 |
|
49 |
|
50 .. function:: MenuBar() |
|
51 |
|
52 An object representing the menubar. This object is usually not created by the |
|
53 user. |
|
54 |
|
55 |
|
56 .. function:: Menu(bar, title[, after]) |
|
57 |
|
58 An object representing a menu. Upon creation you pass the ``MenuBar`` the menu |
|
59 appears in, the *title* string and a position (1-based) *after* where the menu |
|
60 should appear (default: at the end). |
|
61 |
|
62 |
|
63 .. function:: MenuItem(menu, title[, shortcut, callback]) |
|
64 |
|
65 Create a menu item object. The arguments are the menu to create, the item title |
|
66 string and optionally the keyboard shortcut and a callback routine. The callback |
|
67 is called with the arguments menu-id, item number within menu (1-based), current |
|
68 front window and the event record. |
|
69 |
|
70 Instead of a callable object the callback can also be a string. In this case |
|
71 menu selection causes the lookup of a method in the topmost window and the |
|
72 application. The method name is the callback string with ``'domenu_'`` |
|
73 prepended. |
|
74 |
|
75 Calling the ``MenuBar`` :meth:`fixmenudimstate` method sets the correct dimming |
|
76 for all menu items based on the current front window. |
|
77 |
|
78 |
|
79 .. function:: Separator(menu) |
|
80 |
|
81 Add a separator to the end of a menu. |
|
82 |
|
83 |
|
84 .. function:: SubMenu(menu, label) |
|
85 |
|
86 Create a submenu named *label* under menu *menu*. The menu object is returned. |
|
87 |
|
88 |
|
89 .. function:: Window(parent) |
|
90 |
|
91 Creates a (modeless) window. *Parent* is the application object to which the |
|
92 window belongs. The window is not displayed until later. |
|
93 |
|
94 |
|
95 .. function:: DialogWindow(parent) |
|
96 |
|
97 Creates a modeless dialog window. |
|
98 |
|
99 |
|
100 .. function:: windowbounds(width, height) |
|
101 |
|
102 Return a ``(left, top, right, bottom)`` tuple suitable for creation of a window |
|
103 of given width and height. The window will be staggered with respect to previous |
|
104 windows, and an attempt is made to keep the whole window on-screen. However, the |
|
105 window will however always be the exact size given, so parts may be offscreen. |
|
106 |
|
107 |
|
108 .. function:: setwatchcursor() |
|
109 |
|
110 Set the mouse cursor to a watch. |
|
111 |
|
112 |
|
113 .. function:: setarrowcursor() |
|
114 |
|
115 Set the mouse cursor to an arrow. |
|
116 |
|
117 |
|
118 .. _application-objects: |
|
119 |
|
120 Application Objects |
|
121 ------------------- |
|
122 |
|
123 Application objects have the following methods, among others: |
|
124 |
|
125 |
|
126 .. method:: Application.makeusermenus() |
|
127 |
|
128 Override this method if you need menus in your application. Append the menus to |
|
129 the attribute :attr:`menubar`. |
|
130 |
|
131 |
|
132 .. method:: Application.getabouttext() |
|
133 |
|
134 Override this method to return a text string describing your application. |
|
135 Alternatively, override the :meth:`do_about` method for more elaborate "about" |
|
136 messages. |
|
137 |
|
138 |
|
139 .. method:: Application.mainloop([mask[, wait]]) |
|
140 |
|
141 This routine is the main event loop, call it to set your application rolling. |
|
142 *Mask* is the mask of events you want to handle, *wait* is the number of ticks |
|
143 you want to leave to other concurrent application (default 0, which is probably |
|
144 not a good idea). While raising *self* to exit the mainloop is still supported |
|
145 it is not recommended: call ``self._quit()`` instead. |
|
146 |
|
147 The event loop is split into many small parts, each of which can be overridden. |
|
148 The default methods take care of dispatching events to windows and dialogs, |
|
149 handling drags and resizes, Apple Events, events for non-FrameWork windows, etc. |
|
150 |
|
151 In general, all event handlers should return ``1`` if the event is fully handled |
|
152 and ``0`` otherwise (because the front window was not a FrameWork window, for |
|
153 instance). This is needed so that update events and such can be passed on to |
|
154 other windows like the Sioux console window. Calling :func:`MacOS.HandleEvent` |
|
155 is not allowed within *our_dispatch* or its callees, since this may result in an |
|
156 infinite loop if the code is called through the Python inner-loop event handler. |
|
157 |
|
158 |
|
159 .. method:: Application.asyncevents(onoff) |
|
160 |
|
161 Call this method with a nonzero parameter to enable asynchronous event handling. |
|
162 This will tell the inner interpreter loop to call the application event handler |
|
163 *async_dispatch* whenever events are available. This will cause FrameWork window |
|
164 updates and the user interface to remain working during long computations, but |
|
165 will slow the interpreter down and may cause surprising results in non-reentrant |
|
166 code (such as FrameWork itself). By default *async_dispatch* will immediately |
|
167 call *our_dispatch* but you may override this to handle only certain events |
|
168 asynchronously. Events you do not handle will be passed to Sioux and such. |
|
169 |
|
170 The old on/off value is returned. |
|
171 |
|
172 |
|
173 .. method:: Application._quit() |
|
174 |
|
175 Terminate the running :meth:`mainloop` call at the next convenient moment. |
|
176 |
|
177 |
|
178 .. method:: Application.do_char(c, event) |
|
179 |
|
180 The user typed character *c*. The complete details of the event can be found in |
|
181 the *event* structure. This method can also be provided in a ``Window`` object, |
|
182 which overrides the application-wide handler if the window is frontmost. |
|
183 |
|
184 |
|
185 .. method:: Application.do_dialogevent(event) |
|
186 |
|
187 Called early in the event loop to handle modeless dialog events. The default |
|
188 method simply dispatches the event to the relevant dialog (not through the |
|
189 ``DialogWindow`` object involved). Override if you need special handling of |
|
190 dialog events (keyboard shortcuts, etc). |
|
191 |
|
192 |
|
193 .. method:: Application.idle(event) |
|
194 |
|
195 Called by the main event loop when no events are available. The null-event is |
|
196 passed (so you can look at mouse position, etc). |
|
197 |
|
198 |
|
199 .. _window-objects: |
|
200 |
|
201 Window Objects |
|
202 -------------- |
|
203 |
|
204 Window objects have the following methods, among others: |
|
205 |
|
206 |
|
207 .. method:: Window.open() |
|
208 |
|
209 Override this method to open a window. Store the Mac OS window-id in |
|
210 :attr:`self.wid` and call the :meth:`do_postopen` method to register the window |
|
211 with the parent application. |
|
212 |
|
213 |
|
214 .. method:: Window.close() |
|
215 |
|
216 Override this method to do any special processing on window close. Call the |
|
217 :meth:`do_postclose` method to cleanup the parent state. |
|
218 |
|
219 |
|
220 .. method:: Window.do_postresize(width, height, macoswindowid) |
|
221 |
|
222 Called after the window is resized. Override if more needs to be done than |
|
223 calling ``InvalRect``. |
|
224 |
|
225 |
|
226 .. method:: Window.do_contentclick(local, modifiers, event) |
|
227 |
|
228 The user clicked in the content part of a window. The arguments are the |
|
229 coordinates (window-relative), the key modifiers and the raw event. |
|
230 |
|
231 |
|
232 .. method:: Window.do_update(macoswindowid, event) |
|
233 |
|
234 An update event for the window was received. Redraw the window. |
|
235 |
|
236 |
|
237 .. method:: Window.do_activate(activate, event) |
|
238 |
|
239 The window was activated (``activate == 1``) or deactivated (``activate == 0``). |
|
240 Handle things like focus highlighting, etc. |
|
241 |
|
242 |
|
243 .. _controlswindow-object: |
|
244 |
|
245 ControlsWindow Object |
|
246 --------------------- |
|
247 |
|
248 ControlsWindow objects have the following methods besides those of ``Window`` |
|
249 objects: |
|
250 |
|
251 |
|
252 .. method:: ControlsWindow.do_controlhit(window, control, pcode, event) |
|
253 |
|
254 Part *pcode* of control *control* was hit by the user. Tracking and such has |
|
255 already been taken care of. |
|
256 |
|
257 |
|
258 .. _scrolledwindow-object: |
|
259 |
|
260 ScrolledWindow Object |
|
261 --------------------- |
|
262 |
|
263 ScrolledWindow objects are ControlsWindow objects with the following extra |
|
264 methods: |
|
265 |
|
266 |
|
267 .. method:: ScrolledWindow.scrollbars([wantx[, wanty]]) |
|
268 |
|
269 Create (or destroy) horizontal and vertical scrollbars. The arguments specify |
|
270 which you want (default: both). The scrollbars always have minimum ``0`` and |
|
271 maximum ``32767``. |
|
272 |
|
273 |
|
274 .. method:: ScrolledWindow.getscrollbarvalues() |
|
275 |
|
276 You must supply this method. It should return a tuple ``(x, y)`` giving the |
|
277 current position of the scrollbars (between ``0`` and ``32767``). You can return |
|
278 ``None`` for either to indicate the whole document is visible in that direction. |
|
279 |
|
280 |
|
281 .. method:: ScrolledWindow.updatescrollbars() |
|
282 |
|
283 Call this method when the document has changed. It will call |
|
284 :meth:`getscrollbarvalues` and update the scrollbars. |
|
285 |
|
286 |
|
287 .. method:: ScrolledWindow.scrollbar_callback(which, what, value) |
|
288 |
|
289 Supplied by you and called after user interaction. *which* will be ``'x'`` or |
|
290 ``'y'``, *what* will be ``'-'``, ``'--'``, ``'set'``, ``'++'`` or ``'+'``. For |
|
291 ``'set'``, *value* will contain the new scrollbar position. |
|
292 |
|
293 |
|
294 .. method:: ScrolledWindow.scalebarvalues(absmin, absmax, curmin, curmax) |
|
295 |
|
296 Auxiliary method to help you calculate values to return from |
|
297 :meth:`getscrollbarvalues`. You pass document minimum and maximum value and |
|
298 topmost (leftmost) and bottommost (rightmost) visible values and it returns the |
|
299 correct number or ``None``. |
|
300 |
|
301 |
|
302 .. method:: ScrolledWindow.do_activate(onoff, event) |
|
303 |
|
304 Takes care of dimming/highlighting scrollbars when a window becomes frontmost. |
|
305 If you override this method, call this one at the end of your method. |
|
306 |
|
307 |
|
308 .. method:: ScrolledWindow.do_postresize(width, height, window) |
|
309 |
|
310 Moves scrollbars to the correct position. Call this method initially if you |
|
311 override it. |
|
312 |
|
313 |
|
314 .. method:: ScrolledWindow.do_controlhit(window, control, pcode, event) |
|
315 |
|
316 Handles scrollbar interaction. If you override it call this method first, a |
|
317 nonzero return value indicates the hit was in the scrollbars and has been |
|
318 handled. |
|
319 |
|
320 |
|
321 .. _dialogwindow-objects: |
|
322 |
|
323 DialogWindow Objects |
|
324 -------------------- |
|
325 |
|
326 DialogWindow objects have the following methods besides those of ``Window`` |
|
327 objects: |
|
328 |
|
329 |
|
330 .. method:: DialogWindow.open(resid) |
|
331 |
|
332 Create the dialog window, from the DLOG resource with id *resid*. The dialog |
|
333 object is stored in :attr:`self.wid`. |
|
334 |
|
335 |
|
336 .. method:: DialogWindow.do_itemhit(item, event) |
|
337 |
|
338 Item number *item* was hit. You are responsible for redrawing toggle buttons, |
|
339 etc. |
|
340 |