Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | |
2 | <html> | |
3 | <head> | |
4 | <meta name="description" content="Pmw - a toolkit for building high-level compound widgets in Python"> | |
5 | <meta name="content" content="python, megawidget, mega widget, compound widget, gui, tkinter"> | |
6 | <title>Pmw todo list</title> | |
7 | </head> | |
8 | ||
9 | <body bgcolor="#ffffff" text="#000000" link="#0000ee" | |
10 | vlink="551a8b" alink="ff0000"> | |
11 | ||
12 | <h1 ALIGN="CENTER">Pmw todo list</h1> | |
13 | ||
14 | <p> | |
15 | This is a long list of suggestions and enhancements for Pmw. If | |
16 | you are interested in doing any of these, please let the Pmw maintainer | |
17 | (<em>gregm@iname.com</em>) know.</p> | |
18 | ||
19 | <p><strong>New Pmw megawidgets</strong></p> | |
20 | <ul><li><p>Multicolumn listbox.</p> | |
21 | <p> Useful features - smooth scrolling, embedded images, different | |
22 | fonts and colours, text correctly masked when it is longer than | |
23 | its column width, interactive resizing of columns.</p> | |
24 | ||
25 | <p> Probably should be implemented as canvas widget rather than by | |
26 | using multiple frames or multiple listboxes. There would be a | |
27 | lot of work needed to position all the elements - you can't just | |
28 | pack or grid them.</p> | |
29 | ||
30 | ||
31 | </li> | |
32 | <li><p>File dialog.</p> | |
33 | ||
34 | </li> | |
35 | <li><p>Main window class (App class), with menu bar, information line | |
36 | with status boxes and an about box. (See iwidgets' mainwindow | |
37 | class for example.) This should handle creation of multiple main | |
38 | windows, recycling of unused main windows and should exit if | |
39 | last open main window is closed.</p> | |
40 | ||
41 | </li> | |
42 | <li><p>Searchable text megawidget.</p> | |
43 | ||
44 | </li> | |
45 | <li><p>Tree browser.</p> | |
46 | ||
47 | </li> | |
48 | <li><p>Check out Doug Hellmann's contributed megawidgets at | |
49 | <http://www.mindspring.com/~doughellmann/Projects/PmwContribD> or | |
50 | <http://members.home.net/doughellmann/PmwContribD/> | |
51 | and integrate into Pmw.</p> | |
52 | ||
53 | </li></ul> | |
54 | ||
55 | <p><strong>Changes to current megawidgets</strong></p> | |
56 | <p> MegaToplevel</p> | |
57 | <ul><li><p>Modify activate() geometry argument to allow window positioning | |
58 | relative to the pointer, another window or the screen and | |
59 | allow the centering of the window relative to the | |
60 | positioning point or by a specified offset. Also add the | |
61 | ability to position the window so that the mouse is over a | |
62 | particular widget in the toplevel.</p> | |
63 | <p> Should handle all combinations of</p> | |
64 | <dl><dd><pre> when (always/first) | |
65 | where (center/geometry/mouse) | |
66 | parent (screen/window) | |
67 | ||
68 | and None (don't position)</pre></dd></dl> | |
69 | ||
70 | ||
71 | <p> Check Tix4.1.0/library/DialogS.tcl center method for how to | |
72 | center over another window</p> | |
73 | ||
74 | <p> Check iwidget's shell.itk for code to center widget over | |
75 | screen or another widget.</p> | |
76 | ||
77 | <p> See Pmw.Balloon code for how to position over pointer.</p> | |
78 | ||
79 | <p> Tcl code to center over another (parent) window:</p> | |
80 | <dl><dd><pre> # center client relative to master (default xoff, yoff = -1) | |
81 | set geomaster [split [wm geometry $master] "x+"] | |
82 | set geoclient [split [wm geometry $client] "x+"] | |
83 | ||
84 | if {$xoff == -1} { | |
85 | set xoff [expr ( | |
86 | ([lindex $geomaster 0] - [lindex $geoclient 0]) / 2)] | |
87 | } | |
88 | set newxpos [expr [lindex $geomaster 2] + $xoff] | |
89 | ||
90 | if {$yoff == -1} { | |
91 | set yoff [expr ( | |
92 | ([lindex $geomaster 1] - [lindex $geoclient 1]) / 2)] | |
93 | } | |
94 | set newypos [expr [lindex $geomaster 3] + $yoff] | |
95 | ||
96 | wm geometry $client +$newxpos+$newypos</pre></dd></dl> | |
97 | ||
98 | ||
99 | <p> More tcl code to center dialog over another (parent) window:</p> | |
100 | <dl><dd><pre> (args: parent dlg) | |
101 | # First, display the dialog offscreen to get dimensions. | |
102 | set screenW [winfo screenwidth $parent] | |
103 | set screenH [winfo screenheight $parent] | |
104 | set w [expr $screenW + 1] | |
105 | wm geometry $dlg +$w+0 | |
106 | update | |
107 | ||
108 | # Get relative center of parent. | |
109 | set w [winfo width $parent] | |
110 | set h [winfo height $parent] | |
111 | set w [expr $w/2] | |
112 | set h [expr $h/2] | |
113 | ||
114 | # Get and add screen offset of parent. | |
115 | set w [expr $w + [winfo rootx $parent]] | |
116 | set h [expr $h + [winfo rooty $parent]] | |
117 | ||
118 | # Get dimensions of dialog. | |
119 | set dlgW [winfo width $dlg] | |
120 | set dlgH [winfo height $dlg] | |
121 | ||
122 | # Make adjustments for actual dimensions of dialog. | |
123 | set w [expr $w - $dlgW / 2] | |
124 | set h [expr $h - $dlgH / 2] | |
125 | ||
126 | # Let's keep the entire dialog onscreen at all times. | |
127 | # Center in screen if things are awry. | |
128 | set recenter 0 | |
129 | if { $w < 0 } { set recenter 1 } | |
130 | if { $h < 0 } { set recenter 1 } | |
131 | if { [expr $w + $dlgW] > $screenW } { set recenter 1 } | |
132 | if { [expr $h + $dlgH] > $screenH } { set recenter 1 } | |
133 | if { $recenter } { | |
134 | set w [expr ($screenW -$dlgW) / 2] | |
135 | set h [expr ($screenH - $dlgH) / 2] | |
136 | } | |
137 | ||
138 | wm geometry $dlg +$w+$h</pre></dd></dl> | |
139 | ||
140 | ||
141 | ||
142 | </li> | |
143 | <li><p>Add geometry argument to show() (same as activate() above).</p> | |
144 | ||
145 | </li></ul> | |
146 | ||
147 | <p> Dialog</p> | |
148 | <ul><li><p>Add label (header?) to Dialog class. May not be necessary, or | |
149 | too complicated.</p> | |
150 | ||
151 | </li></ul> | |
152 | ||
153 | <p> ButtonBox</p> | |
154 | <ul><li><p>When a horizontal ButtonBox is stretched, the left button | |
155 | stays anchored to the left edge and there is too much space | |
156 | between the last button and the right edge.</p> | |
157 | ||
158 | </li> | |
159 | <li><p>Add an option to either evenly space the buttons across the | |
160 | button box, or to keep them together and justify them to the | |
161 | left, right or center. Check that deleting buttons works | |
162 | correctly.</p> | |
163 | ||
164 | </li></ul> | |
165 | ||
166 | <p> ComboBox</p> | |
167 | <ul><li><p>Remove arrowrelief option from ComboBox and do what counter | |
168 | does: gets value of arrow's relief just before sinking it, | |
169 | then restores it later.</p> | |
170 | ||
171 | </li> | |
172 | <li><p>Change bindings: remove all bindings from arrow key and remove | |
173 | arrow key from <tab> focus sequence; only implement these | |
174 | bindings on the entry widget:</p> | |
175 | <dl><dd><pre> Up popup dropdown list, scroll up if already displayed | |
176 | Down popup dropdown list, scroll down if already displayed | |
177 | Esc popdown dropdown list, return entry to previous value | |
178 | Enter popdown dropdown list, execute current selection</pre></dd></dl> | |
179 | ||
180 | <p> Remove bindings from listbox and scrollbar(s), so that all | |
181 | bindings are via the entry widget?</p> | |
182 | ||
183 | ||
184 | </li> | |
185 | <li><p>When entering keys when list is displayed, scroll list to | |
186 | first entry beginning with entered keys. If no match, | |
187 | scroll list to top.</p> | |
188 | ||
189 | </li> | |
190 | <li><p>Remove many of the arrow bindings from Pmw.ComboBox - there | |
191 | are just too many key bindings on the arrow button. There | |
192 | is no need for it to respond to keys such as the up/down | |
193 | keys when the adjacent Entry widget already does so. I | |
194 | propose to remove all Pmw.ComboBox arrow button key bindings | |
195 | except for <space>, which can be used to bring up the | |
196 | dropdown list. The Entry widget behaviour would remain | |
197 | unchanged: when it has focus, you can use the up/down keys | |
198 | to go to the next/previous entries and then use <Return> to | |
199 | invoke the selection command.</p> | |
200 | <p> Alternatively, make the bindings the same as the MS-Windows | |
201 | combobox. (Use the url entry field in Navigator or IE as an | |
202 | example of MS-Windows behaviour). These have been reported | |
203 | to be:</p> | |
204 | <ul><li><p>All mouse actions are exclusively triggered by the left | |
205 | button.</p> | |
206 | ||
207 | </li> | |
208 | <li><p>Right button displays "Direkthilfe" on my german system | |
209 | ("Direct Help"). This is a floating button, that | |
210 | triggers display of a tool tip like the |?| button that | |
211 | appears next to the |x| at the right end of the title | |
212 | bar of some native windows dialogs.</p> | |
213 | ||
214 | </li> | |
215 | <li><p>The arrow is very slim (acutally flat: width/height is | |
216 | about 2/1)</p> | |
217 | ||
218 | </li> | |
219 | <li><p>Entry and popup have the same color ("window color")</p> | |
220 | ||
221 | </li> | |
222 | <li><p>The popup has a 1 pixel dark border, no spacing between | |
223 | popup and scrollbar.</p> | |
224 | ||
225 | </li> | |
226 | <li><p>If the box has the focus, the full entry is displayed in | |
227 | "selected" style.</p> | |
228 | ||
229 | </li> | |
230 | <li><p>If the box has the focus, up and left keys rotate items | |
231 | up, down and right keys rotate items down, all with | |
232 | immediate effect.</p> | |
233 | ||
234 | </li> | |
235 | <li><p>If the box has the focus, keys a-z (not case sensitive) | |
236 | rotate through the items with same first character, with | |
237 | immediate effect.</p> | |
238 | ||
239 | </li> | |
240 | <li><p>No separate focus for the arrowbutton</p> | |
241 | ||
242 | </li> | |
243 | <li><p>Discussing how the combobox behaves with arrow keys when | |
244 | it has the focus: "The concept is almost identical to | |
245 | what you already have, just gives more visual feedback. | |
246 | In your current implementation you allow to rotate | |
247 | through the values with the up and down arrow keys, | |
248 | showing the strings in the entryfield, and accepting the | |
249 | values when the user presses the spacebar (hmmm, how can | |
250 | I exit this without moving back to the original value | |
251 | manually?). On Windows, the choice is not shown in the | |
252 | entryfield, but the popup opens when you press the up or | |
253 | down arrow keys, as if you clicked on the arrowbutton, | |
254 | and you then navigate the values in the listbox. This | |
255 | avoids the display of not finally selected values in the | |
256 | entryfield and is a lot more obvious and less confusing. | |
257 | The current behaviour certainly confused me, which is | |
258 | why I first proposed the changes to the moveup/down | |
259 | methods." (Georg Mischler)</p> | |
260 | ||
261 | </li></ul> | |
262 | ||
263 | <p> Also, check bindings on other megawidgets for consistency.</p> | |
264 | ||
265 | ||
266 | </li> | |
267 | <li><p>Modify Pmw.ComboBox so that the width of the entry widget is | |
268 | forced to be the same as the width of the dropdown listbox. | |
269 | If the "width" option to the standard listbox is 0, Tk sets | |
270 | the requested width of the listbox to be just large enough | |
271 | to hold the widest element in the listbox. Using this | |
272 | option, I can see that listbox.winfo_reqwidth() is changing | |
273 | as I insert items into an unmapped listbox. The question | |
274 | is, how do I get notified of these events so that I can set | |
275 | the width of the entry?</p> | |
276 | <p> The problem is that the listbox is in another toplevel which | |
277 | has not yet been displayed, so I can't bind to <Configure> | |
278 | to determine its width.</p> | |
279 | ||
280 | <p> One suggestion is to override the insert and delete methods | |
281 | of the Listbox class. The problem with this is what if the | |
282 | font changed, or the borderwidth, etc? You would need to | |
283 | override and check many more methods.</p> | |
284 | ||
285 | ||
286 | </li> | |
287 | <li><p>Add ability to tearoff dropdown list (suggested by Dean N. | |
288 | Williams).</p> | |
289 | ||
290 | </li> | |
291 | <li><p>Should be able to disable/enable arrow button.</p> | |
292 | ||
293 | </li></ul> | |
294 | ||
295 | <p> Counter</p> | |
296 | <ul><li><p>Add option for different increment/decrement behaviour. For | |
297 | example, assuming increment is 1:</p> | |
298 | <ol><li><p>Current behaviour - move to the next multiple of the | |
299 | increment, eg: 1.0 -> 2.0, 1.234 -> 2.0</p> | |
300 | ||
301 | </li> | |
302 | <li><p>Add or subtract the increment to whatever is displayed, | |
303 | eg: 1.0 -> 2.0, 1.234 -> 2.234</p> | |
304 | ||
305 | </li> | |
306 | <li><p>Move to the next multiple of the increment, offset by some value. | |
307 | eg: (if offset is 0.5) 0.5 -> 1.5, 1.234 -> 1.5, 1.678 -> 2.5</p> | |
308 | ||
309 | </li></ol> | |
310 | ||
311 | </li> | |
312 | <li><p>Add wrap option (to wrap around at limits) (then don't need | |
313 | time24 arg to <strong>'time'</strong> datatype).</p> | |
314 | ||
315 | </li> | |
316 | <li><p>Add a state option to disable Counter.</p> | |
317 | ||
318 | </li> | |
319 | <li><p>Add option to Counter to allow the buttons to be on the same | |
320 | side, one on top of the other, like Tix, Itcl, Motif, | |
321 | Windows 95, etc. There should probably also be an option to | |
322 | lay the current large buttons on the same side of the entry | |
323 | field, next to each other.</p> | |
324 | ||
325 | </li> | |
326 | <li><p>Redo TimeCounter using vertical Counter, add limitcommand | |
327 | option to Counter to allow overflow from seconds to minutes | |
328 | to hours</p> | |
329 | ||
330 | </li></ul> | |
331 | ||
332 | <p> Arrowed megawidgets (Counter, ComboBox, TimeCounter)</p> | |
333 | <ul><li><p>Potential construction speed up if Canvas arrows are replaced | |
334 | by Label with Bitmap or BitmapImage. The hard part would be | |
335 | to make the bitmap change size depending on size of Label.</p> | |
336 | ||
337 | </li> | |
338 | <li><p>Pmw.drawarrow should draw arrows which look like Tk cascade | |
339 | menu arrows.</p> | |
340 | ||
341 | </li></ul> | |
342 | ||
343 | <p> EntryField</p> | |
344 | <ul><li><p>Can it be modified to change all entered characters to upper | |
345 | or lower case automatically? Or first-upper or | |
346 | first-of-each-word-upper?</p> | |
347 | ||
348 | </li> | |
349 | <li><p>If the validity of the currently displayed text is ERROR, | |
350 | allow any changes, even those which result in invalid text. | |
351 | This is useful when invalid data has been given to the | |
352 | <strong>value</strong> option and the user is trying to correct it.</p> | |
353 | ||
354 | </li></ul> | |
355 | ||
356 | <p> LabeledWidget</p> | |
357 | <ul><li><p>Add tix-style border.</p> | |
358 | ||
359 | </li></ul> | |
360 | ||
361 | <p> MenuBar</p> | |
362 | <ul><li><p>Maybe Pmw.MenuBar should also have (optional) balloon help | |
363 | for menu items as well as menu buttons. I am not sure | |
364 | whether users would find this useful.</p> | |
365 | ||
366 | </li> | |
367 | <li><p>The status help hints do not appear when using F10/arrow | |
368 | keys.</p> | |
369 | ||
370 | </li> | |
371 | <li><p>Look at the Tk8.0 menu demo and check the help bindings for | |
372 | ideas, in particular, how can you get help when using | |
373 | keyboard bindings.</p> | |
374 | ||
375 | </li> | |
376 | <li><p>Check the new menu features in Tk8.0 for creating "native" | |
377 | menu bars and the special ".help" menu.</p> | |
378 | ||
379 | </li> | |
380 | <li><p>Add index() method.</p> | |
381 | ||
382 | </li> | |
383 | <li><p>Add a <strong>'position'</strong> option to addmenu and deletemenu methods. | |
384 | This option should accept an index number, a menuName or | |
385 | <strong>Pmw.END</strong>.</p> | |
386 | ||
387 | </li> | |
388 | <li><p>Look at itcl menubar for ideas.</p> | |
389 | ||
390 | </li></ul> | |
391 | ||
392 | <p> Balloon</p> | |
393 | <ul><li><p>Positioning of the balloon with respect to the target | |
394 | widget or canvas item: There are a number of ways that | |
395 | Pmw.Balloon could be improved. For example, currently the | |
396 | the top left corner of the balloon is positioned relative to | |
397 | the bottom left corner of the target, offset by the | |
398 | [xy]offset options. These options apply to all targets - | |
399 | they can not be set differently for different targets.</p> | |
400 | <p> To make it more configurable, the user should be able to | |
401 | specify, for each target:</p> | |
402 | <ul><li><p>the base position in the target relative to which the | |
403 | balloon should be placed (n, s, e, w, nw, sw, ne, se, c) | |
404 | (Currently sw)</p> | |
405 | ||
406 | </li> | |
407 | <li><p>the x and y offsets (Default (20, 1))</p> | |
408 | ||
409 | </li> | |
410 | <li><p>the position in the balloon that should be placed at the | |
411 | offset position (n, s, e, w, nw, sw, ne, se, c) | |
412 | (Currently nw)</p> | |
413 | <p> Note, if this is anything other than nw, | |
414 | update_idletasks() will need to be called to get the | |
415 | size of the balloon before it is positioned - there is a | |
416 | possibility that this may cause weird ugly flashing.</p> | |
417 | ||
418 | ||
419 | </li> | |
420 | <li><p>whether either the base x or y position should be taken | |
421 | relative to the current mouse position rather than as | |
422 | one of the corners of the target. This would be useful | |
423 | for large targets, such as text widgets, or strange | |
424 | shaped canvas items. This could be specified using | |
425 | special base positions, such as (nm, sm, em, wm). For | |
426 | example, for <strong>'sm'</strong>, the x base position is the mouse x | |
427 | position and y base position is the bottom (south) edge | |
428 | of the target.</p> | |
429 | ||
430 | </li></ul> | |
431 | ||
432 | <p> The user should be able to specify global defaults for all | |
433 | of these, as well as be able to override them for each | |
434 | target. The Pmw.Balloon options and their defaults could | |
435 | be:</p> | |
436 | <dl><dd><pre> basepoint sw # Position on target. | |
437 | anchor nw # Position on the balloon | |
438 | xoffset 20 # x distance between basepoint and anchor | |
439 | yoffset 1 # y distance between basepoint and anchor</pre></dd></dl> | |
440 | ||
441 | ||
442 | <p> To be able to override these, the bind() and tagbind() | |
443 | methods would have to accept these as additional arguments. | |
444 | Each would default to None, in which case the default values | |
445 | at the time the balloon is deiconified would be used.</p> | |
446 | ||
447 | <p> I'm not sure about how to handle the case when the balloon | |
448 | is configured to come up under the mouse. When this happens | |
449 | the balloon flashes on and off continuously. This can | |
450 | happen now if you set the yoffset to a negative number. | |
451 | Should the balloon widget detect this and do something about | |
452 | it?</p> | |
453 | ||
454 | ||
455 | </li> | |
456 | <li><p>Add showballoon(x, y, text) method to Balloon and use in | |
457 | balloon help for a listbox:</p> | |
458 | <p> On 3 Dec, Michael Lackhoff wrote:</p> | |
459 | ||
460 | <dl><dd><pre> And another question: | |
461 | Is it possible to create a balloon-help for the entries | |
462 | in the listbox? Not all the information is in the | |
463 | listbox and it would be nice if a balloon help could | |
464 | give addtional information.</pre></dd></dl> | |
465 | ||
466 | <p> Rather than popup a balloon help window as the mouse moves | |
467 | over items in the listbox, I think it would be better if it | |
468 | pops up after you clicked on an item (or a short time | |
469 | afterwards). Pmw.Balloon displays the balloon help a short | |
470 | time after the mouse enters a widget, so is not directly | |
471 | usable in this case. However, a method could be added to | |
472 | Pmw.Balloon to request it to popup the balloon at a | |
473 | particular x,y position. This method could be called from | |
474 | the listbox_focus method above. Something like:</p> | |
475 | <dl><dd><pre> def listbox_focus(self, event): | |
476 | self.indexlist.component('listbox').focus_set()</pre></dd></dl> | |
477 | ||
478 | <dl><dd><pre> text = self.indexlist.getcurselection() | |
479 | # expand text to whatever you want: | |
480 | text = 'This is ' + text | |
481 | self.balloon.showballoon(x, y, text)</pre></dd></dl> | |
482 | ||
483 | ||
484 | <p> The Pmw.Balloon showballoon() method would have to set a | |
485 | timer which sometime later calls another method which | |
486 | displays the text. You would also need to bind | |
487 | <ButtonRelease-1> to a hideballoon() method which withdraws | |
488 | the popup.</p> | |
489 | ||
490 | ||
491 | </li> | |
492 | <li><p>The balloon can be displayed off-screen if the window is | |
493 | near the edge of the screen. Add a fix so that the balloon | |
494 | always stays on the screen (but does not popup under the | |
495 | mouse, otherwise it will immediately pop down).</p> | |
496 | ||
497 | </li> | |
498 | <li><p>Add a fix so that the balloon does not disappear if the | |
499 | mouse enters it. Could do this by setting a short timer on | |
500 | the Leave event before withdrawing the balloon and if there | |
501 | is an Enter event on the balloon itself, do not withdraw it.</p> | |
502 | ||
503 | </li> | |
504 | <li><p>For tagged items in text widgets, the balloon is placed | |
505 | relative to the character in the tagged item closest to the | |
506 | mouse. This is not consistent: in the other cases | |
507 | (including canvas), the balloon is placed relative to the | |
508 | bottom left corner of the widget or canvas item. This | |
509 | should also be the case for text items.</p> | |
510 | ||
511 | </li> | |
512 | <li><p>Is the new (in Tk8) "<<MenuSelect>>" event useful for | |
513 | balloon and/or status help.</p> | |
514 | ||
515 | </li></ul> | |
516 | ||
517 | <p> MessageBar</p> | |
518 | <ul><li><p>Finish logmessage functionality.</p> | |
519 | ||
520 | </li> | |
521 | <li><p>Add colours and fonts to MessageBar message types. For | |
522 | example, systemerror message types could have bold font on a | |
523 | red background.</p> | |
524 | ||
525 | </li> | |
526 | <li><p>Add message logging history view (like the ddd debugger).</p> | |
527 | ||
528 | </li></ul> | |
529 | ||
530 | <p> NoteBook</p> | |
531 | <ul><li><p>Notebook should recalculate layout if the requested size of a tab | |
532 | changes (eg font size, text, etc).</p> | |
533 | ||
534 | </li> | |
535 | <li><p>The tabpos option should accept <em>s</em>, <em>e</em> and <em>w</em> as well as <em>n</em>.</p> | |
536 | ||
537 | </li> | |
538 | <li><p>Possible new options (borrowed from iwidgets):</p> | |
539 | <ul><li><p><strong>equaltabs</strong></p> | |
540 | <p> If set to true, causes horizontal tabs to be equal in | |
541 | in width and vertical tabs to equal in height.</p> | |
542 | ||
543 | <p> Specifies whether to force tabs to be equal sized or | |
544 | not. A value of true means constrain tabs to be equal | |
545 | sized. A value of false allows each tab to size based | |
546 | on the text label size. The value may have any of the | |
547 | forms accepted by the Tcl_GetBoolean, such as true, | |
548 | false, 0, 1, yes, or no.</p> | |
549 | ||
550 | <p> For horizontally positioned tabs (tabpos is either s or | |
551 | n), true forces all tabs to be equal width (the width | |
552 | being equal to the longest label plus any padX speci- | |
553 | fied). Horizontal tabs are always equal in height.</p> | |
554 | ||
555 | <p> For vertically positioned tabs (tabpos is either w or | |
556 | e), true forces all tabs to be equal height (the height | |
557 | being equal to the height of the label with the largest | |
558 | font). Vertically oriented tabs are always equal in | |
559 | width.</p> | |
560 | ||
561 | <p> Could have a special value which sets equal sized and | |
562 | also forces tabs to completely fill notebook width | |
563 | (apparently like | |
564 | Windows).</p> | |
565 | ||
566 | ||
567 | </li> | |
568 | <li><p><strong>tabgap</strong></p> | |
569 | <p> Specifies the amount of pixel space to place between | |
570 | each tab. Value may be any pixel offset value. In addi- | |
571 | tion, a special keyword overlap can be used as the | |
572 | value to achieve a standard overlap of tabs. This value | |
573 | may have any of the forms acceptable to Tk_GetPixels. </p> | |
574 | ||
575 | ||
576 | </li> | |
577 | <li><p><strong>raiseselect</strong></p> | |
578 | <p> Sets whether to raise selected tabs slightly (2 pixels).</p> | |
579 | ||
580 | <p> Specifes whether to slightly raise the selected tab | |
581 | from the rest of the tabs. The selected tab is drawn 2 | |
582 | pixels closer to the outside of the tabnotebook than | |
583 | the unselected tabs. A value of true says to raise | |
584 | selected tabs, a value of false turns this feature off. | |
585 | The default is false. The value may have any of the | |
586 | forms accepted by the Tcl_GetBoolean, such as true, | |
587 | false, 0, 1, yes, or no.</p> | |
588 | ||
589 | ||
590 | </li> | |
591 | <li><p><strong>bevelamount</strong></p> | |
592 | <p> Specifies pixel size of tab corners. 0 means no corners.</p> | |
593 | ||
594 | ||
595 | </li></ul> | |
596 | ||
597 | </li> | |
598 | <li><p>There should be a way to temporarily hide a page, without | |
599 | deleting it (like pack_forget). (Suggested by Michel Sanner)</p> | |
600 | ||
601 | </li></ul> | |
602 | ||
603 | <p> OptionMenu</p> | |
604 | <ul><li><p>Should accept focus and obey up and down arrow keys.</p> | |
605 | ||
606 | </li></ul> | |
607 | ||
608 | <p> PanedWidget</p> | |
609 | <ul><li><p>Add index() method</p> | |
610 | ||
611 | </li> | |
612 | <li><p>Modify all methods so that they accept <strong>Pmw.END</strong> as a pane | |
613 | identifier as well as an index or a name.</p> | |
614 | ||
615 | </li> | |
616 | <li><p>Check iwidgets pane and panedwindow classes.</p> | |
617 | ||
618 | </li></ul> | |
619 | ||
620 | <p> RadioSelect</p> | |
621 | <ul><li><p>Add insert() and delete() methods.</p> | |
622 | ||
623 | </li> | |
624 | <li><p>The index method should have <strong>forInsert</strong> argument.</p> | |
625 | ||
626 | </li> | |
627 | <li><p>Add Pmw.SELECT to index() method. For single selectmode | |
628 | this returns an integer, for multiple selectmode this | |
629 | returns a list of integers.</p> | |
630 | ||
631 | </li> | |
632 | <li><p>Add option to set background color on selected buttons. | |
633 | Maybe should also be able set selected foreground as well. | |
634 | Any others?</p> | |
635 | ||
636 | </li></ul> | |
637 | ||
638 | <p> LogicalFont</p> | |
639 | <ul><li><p>Add boldFixed fonts,</p> | |
640 | ||
641 | </li> | |
642 | <li><p>Search for closest size font if no exact match.</p> | |
643 | ||
644 | </li> | |
645 | <li><p>Maybe replace with Tk8.0 font mechanism.</p> | |
646 | ||
647 | </li> | |
648 | <li><p>Can the Tk8.0 font measuring functionality be used in Pmw somehow?</p> | |
649 | ||
650 | </li></ul> | |
651 | ||
652 | <p> Scrolled widgets</p> | |
653 | <ul><li><p>Can some common scrolling methods be factored out, either as | |
654 | a base class, "ScrolledMixin" mixin class or as helper functions? | |
655 | Candidate methods: constructor, destroy, interior, _hscrollMode, | |
656 | _vscrollMode, _configureScrollCommands, _scrollXNow, _scrollYNow, | |
657 | _scrollBothLater, _scrollBothNow, _toggleHorizScrollbar, | |
658 | _toggleVertScrollbar.</p> | |
659 | ||
660 | </li> | |
661 | <li><p>ScrolledField should have optional arrow buttons, so that it | |
662 | can still be scrolled even if the mouse does not have a | |
663 | middle button.</p> | |
664 | ||
665 | </li></ul> | |
666 | ||
667 | <p> Miscellaneous</p> | |
668 | <ul><li><p>Add a button to the Pmw "Stack trace window" which | |
669 | optionally removes all grabs:</p> | |
670 | <p> I normally interact with the "Stack trace window" | |
671 | immediately, and dismiss it afterwards. In many cases | |
672 | where a bug appears like this, the rest of the application | |
673 | is still functional (many of the problems appearing at | |
674 | this stage of development of my application are unforeseen | |
675 | exceptions communicating with a robot on the other end of | |
676 | a socket, not affecting the GUI per se). For that reason | |
677 | I'd prefer if the "stack trace window" would push another | |
678 | grab on the grab stack (if any grabs are active at the | |
679 | moment the exception occurs). Could the window have an | |
680 | extra "Terminate application" option for this case?</p> | |
681 | ||
682 | ||
683 | </li> | |
684 | <li><p>need to handle component option queries in configure():</p> | |
685 | <dl><dd><pre> foo = Pmw.AboutDialog(applicationname = 'abc XYZ') | |
686 | foo.component('message').configure('text') - works | |
687 | foo.cget('message_text') - works | |
688 | foo.configure('message_text') - doesn't</pre></dd></dl> | |
689 | ||
690 | ||
691 | </li> | |
692 | <li><p>Implement bindings (ComboBox, etc) via a dictionary lookup, | |
693 | to allow people to invent new bindings, such as for | |
694 | handicapped users. (Suggested by Michael McLay)</p> | |
695 | ||
696 | </li> | |
697 | <li><p>Modify bundlepmw.py so that it checks Pmw.def to see that no | |
698 | files have been missed.</p> | |
699 | ||
700 | </li> | |
701 | <li><p>Potential cheap speedup by adding this to each module, or | |
702 | inside functions if it has a loop containing calls to | |
703 | builtins:</p> | |
704 | <dl><dd><pre> from __builtin__ import *</pre></dd></dl> | |
705 | ||
706 | ||
707 | </li> | |
708 | <li><p>Look at how update_idletasks and after_* are used in Pmw - | |
709 | are they consistent? could it be improved? What are the | |
710 | problems of using these on other bits of an application | |
711 | (such as when the size of the toplevel is being determined | |
712 | for the window manager).</p> | |
713 | ||
714 | </li> | |
715 | <li><p>If lots of errors occur (such as in a fast time callback) | |
716 | the error window may not appear, since Tk will wait until it | |
717 | is idle - which may never occur. The solution is to call | |
718 | update_idletask when updating the error window, but only | |
719 | after a short time has passed. This will provide better | |
720 | user response. However, it may not be possible to do this | |
721 | if some python interpretes (omppython, for example) do not | |
722 | handle calls to update_idletasks at certain times.</p> | |
723 | ||
724 | </li> | |
725 | <li><p>In the Pmw FAQ, in the "Why don't Pmw megawidgets have a | |
726 | <strong>'state'</strong> option?" section, it mentions several Pmw | |
727 | megawidgets that can not be disabled. Fix them.</p> | |
728 | ||
729 | </li> | |
730 | <li><p>Add RCSID version string to all files.</p> | |
731 | ||
732 | </li> | |
733 | <li><p>When raising exceptions use the third argument to raise:</p> | |
734 | <dl><dd><pre> raise SimulationException, msg, sys.exc_info()[2]</pre></dd></dl> | |
735 | ||
736 | ||
737 | </li> | |
738 | <li><p>When update_idletasks is called all pending changes are | |
739 | flushed to the window system server. However, it may take | |
740 | some time for the server to display the changes. If it is | |
741 | required that the display be up-to-date, update_idletasks | |
742 | should be followed by a call that blocks until processed by | |
743 | the server and a reply received. This may be useful in | |
744 | Pmw.busycallback to ensure the busy cursor remains visible | |
745 | until the display is actually modified.</p> | |
746 | ||
747 | </li> | |
748 | <li><p>There is a small bug which appears only with Tk8.0 (the bug | |
749 | is not apparent with Tk4.2). If a dialog is activated and | |
750 | pops up directly over the cursor and the dialog has a | |
751 | default button, then pressing the <strong>Return</strong> | |
752 | key will not invoke the default button. If you move the | |
753 | mouse out of and then back into the dialog, pressing the | |
754 | <strong>Return</strong> key will work. This behaviour has | |
755 | been noticed in Tcl-only programs, so it is probably a bug | |
756 | in Tk. (Tested on Solaris.)</p> | |
757 | ||
758 | </li> | |
759 | <li><p>Modify PmwBlt.py to use blt2.4 instead of blt8.0.unoff. | |
760 | Nick Belshaw <nickb@earth.ox.ac.uk> is looking at wrapping | |
761 | the new BLT StripChart and TabSet into Pmw.</p> | |
762 | ||
763 | </li> | |
764 | <li><p>Perhaps Pmw should have its own exception defined, like | |
765 | TkInters's TclError, perhaps called PmwError.</p> | |
766 | ||
767 | </li> | |
768 | <li><p>This one is caused by a bug in the implementation of Tcl/Tk | |
769 | for Microsoft Windows NT (and maybe other Microsoft | |
770 | products). Mouse release events can get lost if the | |
771 | grab_set and grab_release commands are used and the mouse | |
772 | goes outside of the window while the mouse button is down. | |
773 | This can occur while Pmw modal dialogs are active. Below | |
774 | is some Tkinter-only code which demonstrates the problem. | |
775 | Maybe there is a work around.</p> | |
776 | <dl><dd><pre> # Test script to demonstrate bug in Tk | |
777 | #implementation of grab under NT. | |
778 | ||
779 | # Click on "Dialog" to bring up the modal | |
780 | # dialog window. Then button down on the scale, | |
781 | # move the mouse outside the window, | |
782 | # then button up. The scale slider will still | |
783 | # be sunken and clicks on the "OK" button | |
784 | # will be ineffective. | |
785 | ||
786 | import Tkinter | |
787 | ||
788 | def activate(): | |
789 | waitVar.set(0) | |
790 | toplevel.deiconify() | |
791 | toplevel.wait_visibility() | |
792 | toplevel.grab_set() # Problem here | |
793 | toplevel.focus_set() | |
794 | toplevel.wait_variable(waitVar) | |
795 | ||
796 | def deactivate(): | |
797 | toplevel.withdraw() | |
798 | toplevel.grab_release() # and here | |
799 | waitVar.set(1) | |
800 | ||
801 | root = Tkinter.Tk() | |
802 | toplevel = Tkinter.Toplevel() | |
803 | waitVar = Tkinter.IntVar() | |
804 | toplevel.withdraw() | |
805 | scale = Tkinter.Scale(toplevel, orient='horizontal', length=200) | |
806 | scale.pack() | |
807 | button = Tkinter.Button(toplevel, text='OK', command=deactivate) | |
808 | button.pack() | |
809 | ||
810 | button = Tkinter.Button(text='Dialog', command=activate) | |
811 | button.pack() | |
812 | button = Tkinter.Button(text='Exit', command=root.destroy) | |
813 | button.pack() | |
814 | ||
815 | root.mainloop()</pre></dd></dl> | |
816 | ||
817 | ||
818 | </li></ul> | |
819 | ||
820 | ||
821 | <p><strong>Documentation</strong></p> | |
822 | <ul><li><p>Document how to get Pmw working on a Mac, for example:</p> | |
823 | <ul><li><p>Unzip and untar</p> | |
824 | <p> This depends on what you use to unpack the tar file. If | |
825 | you use (macgzip and) SunTar you have to tell it that files | |
826 | with ".py" extensions are text files (in the | |
827 | preferences/file type section). If you use stuffit | |
828 | expander: this can be made to do the conversion | |
829 | correctly, but it could be that this only works if you set | |
830 | the .py extension correctly in Internet Config.</p> | |
831 | ||
832 | <ul><li><p>Where do you untar Pmw?</p> | |
833 | ||
834 | </li> | |
835 | <li><p>How do you get line terminators correct (carriage | |
836 | return/line feed)?</p> | |
837 | ||
838 | </li> | |
839 | <li><p>Is there any problem with file name case? (mixed | |
840 | upper/lower case)</p> | |
841 | ||
842 | </li> | |
843 | <li><p>Is there any problem with file name length?</p> | |
844 | ||
845 | </li></ul> | |
846 | <p> (Joseph Saltiel says: It was the same type of operation | |
847 | as in Windows/Unix. Run a program that unzips it and | |
848 | untars it. It seems to get case and length right on its | |
849 | own.)</p> | |
850 | ||
851 | ||
852 | </li> | |
853 | <li><p>Let python know where Pmw is</p> | |
854 | <ul><li><p>If Pmw is in its own folder you will have to add the | |
855 | parent of that folder to the sys paths in Edit | |
856 | PythonPaths. If it is in the Python home folder, you | |
857 | do not need to do this.</p> | |
858 | ||
859 | </li> | |
860 | <li><p>Make sure that the Pmw folder is called "Pmw" and not | |
861 | something else. Since Pmw is a package, python expects | |
862 | to find a "Pmw" folder somewhere in sys.path.</p> | |
863 | ||
864 | </li></ul> | |
865 | <p> (Joseph Saltiel says: With the Python distribution on the | |
866 | Mac there is an application called editPythonPrefs, when | |
867 | you run it it gives you a list of a paths. These paths | |
868 | are similiar to the PYTHONPATH variable. I just added the | |
869 | path to Pmw at the bottom of this list.)</p> | |
870 | ||
871 | ||
872 | </li></ul> | |
873 | ||
874 | </li> | |
875 | <li><p>Document general ideas about building guis, eg:</p> | |
876 | <p> When I write gui applications, I usually defer creation of windows | |
877 | as much as possible - this means that the application starts up | |
878 | quickly because it usually only has to create the main window. | |
879 | Whenever another window is required for the first time, it is | |
880 | created then. When the user has finished with the window, the | |
881 | window is withdrawn, not deleted, so that next time it is required | |
882 | it much faster to come up.</p> | |
883 | ||
884 | <p> In summary - don't create a window until you need and | |
885 | don't destroy a window if you may want it again.</p> | |
886 | ||
887 | <p> The amount of memory required to keep the windows should not be | |
888 | very much - except for very long running programs where the user | |
889 | may create thousands of different windows.</p> | |
890 | ||
891 | ||
892 | </li> | |
893 | <li><p>Add class hierarchy diagram to documentation:</p> | |
894 | <dl><dd><pre> MegaArchetype | |
895 | MegaToplevel | |
896 | etc | |
897 | MegaWidget | |
898 | etc</pre></dd></dl> | |
899 | ||
900 | ||
901 | </li> | |
902 | <li><p>Add to doco something like: "Another way to extend a Pmw | |
903 | megawidget is to specify a non-default type for one of the | |
904 | components. For example <code>text_pytype = FontText</code>."</p> | |
905 | ||
906 | </li> | |
907 | <li><p>Document pyclass and pyclass = None (options for null components | |
908 | are ignored; the only time this can be used is with the | |
909 | Group's tag component - all | |
910 | other's use the component widget in some way)</p> | |
911 | ||
912 | </li> | |
913 | <li><p>Create index of all Pmw methods, functions, options, components.</p> | |
914 | ||
915 | </li> | |
916 | <li><p>Add description of how to run the Pmw demos without installing.</p> | |
917 | ||
918 | </li> | |
919 | <li><p>Add description of how to install Pmw.</p> | |
920 | ||
921 | </li> | |
922 | <li><p>Describe grid structure of megawidgets, so that it is possible | |
923 | to extend megawidgets by adding new widgets into the interior | |
924 | (hence avoiding a childsite in most megawidgets)</p> | |
925 | ||
926 | </li> | |
927 | <li><p>Document error display and difference between callback and | |
928 | binding error reports.</p> | |
929 | ||
930 | </li> | |
931 | <li><p>Document difference between <strong>'Helvetica 12'</strong> and <strong>'Helvetica size: 12'</strong> | |
932 | in logicalfont.</p> | |
933 | ||
934 | </li> | |
935 | <li><p>Add to howtouse, to describe using the option database to set | |
936 | options for a specific megawidget:</p> | |
937 | <dl><dd><pre> import Pmw | |
938 | root = Pmw.initialise(useTkOptionDb = 1) | |
939 | root.option_add('*entryfield24*Label.text', 'German') | |
940 | e = Pmw.EntryField(hull_name = 'entryfield24', labelpos = 'w') | |
941 | e.pack() | |
942 | root.update()</pre></dd></dl> | |
943 | ||
944 | ||
945 | </li> | |
946 | <li><p>Also document hull_name and hull_class.</p> | |
947 | ||
948 | </li> | |
949 | <li><p>Finish FAQ, ReleaseProcedure and StructuredText test.</p> | |
950 | ||
951 | </li> | |
952 | <li><p>Put html through gifwizard and html lint.</p> | |
953 | <dl><dd><pre> http://www.cen.uiuc.edu/cgi-bin/weblint | |
954 | (eg: http://www.cre.canon.co.uk/~neilb/weblint/manpage.html)</pre></dd></dl> | |
955 | ||
956 | ||
957 | </li> | |
958 | <li><p>Delete comments from source if they have been added to docs | |
959 | (should not have two copies of anything).</p> | |
960 | ||
961 | </li> | |
962 | <li><p>Need to document non-standard initial values for component | |
963 | options, such as border in ButtonBox and Dialog's childsite.</p> | |
964 | ||
965 | </li> | |
966 | <li><p>Docs should have DEFAULT BINDINGS section (like iwidget combobox).</p> | |
967 | ||
968 | </li> | |
969 | <li><p>Promote home page:</p> | |
970 | <dl><dd><pre> http://www.geocities.com/homestead/promote.html | |
971 | http://www.submit-it.com/subopt.htm, etc</pre></dd></dl> | |
972 | ||
973 | ||
974 | </li> | |
975 | <li><p>Create man pages as well as html (modify createmanuals to produce both).</p> | |
976 | ||
977 | </li> | |
978 | <li><p>Maybe something with html frames like: itcl2.2/html/index.html</p> | |
979 | ||
980 | </li> | |
981 | <li><p>Add to starting.html a note that Pmw is a python "package" and add | |
982 | a pointer to python documentation on packages.</p> | |
983 | ||
984 | </li> | |
985 | <li><p>Document scrolled widget implementations, explaining why they | |
986 | are all slightly different (because the underlying widgets which | |
987 | are being scrolled have different behaviors).</p> | |
988 | ||
989 | </li> | |
990 | <li><p>Make copyright clearer. Maybe borrow python's?</p> | |
991 | ||
992 | </li></ul> | |
993 | ||
994 | <p><strong>Demos</strong></p> | |
995 | <ul><li><p>Check for missing demos.</p> | |
996 | ||
997 | </li> | |
998 | <li><p>In all demos can move the three lines beginning with "Import Pmw | |
999 | from the sibling directory", to inside "if __name__" clause. | |
1000 | Also, "sibling directory" is now incorrect. Also, add note that | |
1001 | this is only necessary when running demos without installing Pmw.</p> | |
1002 | ||
1003 | </li> | |
1004 | <li><p>Change demo/All.py so that it displays the traceback if it | |
1005 | cannot load or run a demo (easier for users to report errors).</p> | |
1006 | ||
1007 | </li> | |
1008 | <li><p>Add option to demo/All.py: "Display demos in separate window" | |
1009 | to allow resizing of sub-demos</p> | |
1010 | ||
1011 | </li> | |
1012 | <li><p>TimeCounter and Spectrum demos beep when they come up, using:</p> | |
1013 | <dl><dd><pre> root.option_add('*EntryField*value', 'VALUE')</pre></dd></dl> | |
1014 | ||
1015 | ||
1016 | </li> | |
1017 | <li><p>In demos, add <code>title = 'blah'</code> to top of file and replace | |
1018 | <code>root.title(..)</code> with <code>root.title(title)</code> at bottom.</p> | |
1019 | ||
1020 | </li> | |
1021 | <li><p>Add comprehensive speed test demo which creates one or more of | |
1022 | each (common) megawidget. Remove old SpeedTest demo.</p> | |
1023 | ||
1024 | </li> | |
1025 | <li><p>Check demos work when called from ptui. (Changes have to do | |
1026 | with calling compile/exec where __name__ is not the name of the | |
1027 | All.py script, but is <strong>'__builtin__'</strong>)</p> | |
1028 | ||
1029 | </li> | |
1030 | <li><p>PromptDialog demo should not remember password.</p> | |
1031 | ||
1032 | </li> | |
1033 | <li><p>Finish Counter, Radioselect demos.</p> | |
1034 | ||
1035 | </li> | |
1036 | <li><p>Modify the All demo so that you can reload a demo module.</p> | |
1037 | ||
1038 | </li> | |
1039 | <li><p>The syntax-coloured code viewer looks strange on Microsoft NT, | |
1040 | because the size of the fonts differ. Check out Guido's | |
1041 | idle-0.1 text colouring for Pmw code viewer.</p> | |
1042 | ||
1043 | </li> | |
1044 | <li><p>Document restrictions on adding bindings to a megawidget: you | |
1045 | probably need to bind to components of the megawidget and also | |
1046 | check that you are not destroying bindings set up by the | |
1047 | megawidget itself.</p> | |
1048 | ||
1049 | </li> | |
1050 | <li><p>Add a demo that demonstrates setting the color scheme at run time.</p> | |
1051 | ||
1052 | </li></ul> | |
1053 | ||
1054 | <p><strong>Tests</strong></p> | |
1055 | <ul><li><p>Check for missing tests, such as TimeCounter, RadioSelect, | |
1056 | SelectionDialog, MessageBar, MenuBar, ComboBoxDialog, Balloon.</p> | |
1057 | ||
1058 | </li> | |
1059 | <li><p>Create test for useTkOptionDb option to Pmw.initialise().</p> | |
1060 | ||
1061 | </li> | |
1062 | <li><p>Check that destroyed widgets' python classes are garbage | |
1063 | collected (add test and/or demo).</p> | |
1064 | ||
1065 | </li> | |
1066 | <li><p>Add tests for changecolor, setscheme, etc.</p> | |
1067 | ||
1068 | </li> | |
1069 | <li><p>Need Resources test.</p> | |
1070 | ||
1071 | </li> | |
1072 | <li><p>Create tests for deriving from Pmw classes (eg ComboBox).</p> | |
1073 | ||
1074 | </li></ul> | |
1075 | ||
1076 | <p><strong>Ideas</strong></p> | |
1077 | <ul><li><p>Add more Tix (www.xpi.com/tix/screenshot.html) and iwidgets widgets.</p> | |
1078 | ||
1079 | </li> | |
1080 | <li><p>Look at spinner.itk for how to do vertical orientation on | |
1081 | same side for Counter.</p> | |
1082 | ||
1083 | </li> | |
1084 | <li><p>Investigate these new features in Tk8.0 and see if they could be | |
1085 | used in Pmw:</p> | |
1086 | <dl><dd><pre> embedded images in text widgets | |
1087 | destroy command ignores windows that don't exist | |
1088 | </pre></dd></dl> | |
1089 | ||
1090 | ||
1091 | </li></ul> | |
1092 | ||
1093 | ||
1094 | ||
1095 | <center><P ALIGN="CENTER"> | |
1096 | <IMG SRC = blue_line.gif ALT = "" WIDTH=320 HEIGHT=5> | |
1097 | </p></center> | |
1098 | ||
1099 | ||
1100 | <font size=-1> | |
1101 | <center><P ALIGN="CENTER"> | |
1102 | Pmw 1.2 - | |
1103 | 5 Aug 2003 | |
1104 | - <a href="index.html">Home</a> | |
1105 | ||
1106 | </p></center> | |
1107 | </font> | |
1108 | ||
1109 | </body> | |
1110 | </html> | |
1111 |