From fellowsd@cs.man.ac.uk Wed Nov 19 15:25:19 CST 1997 Article: 75427 of comp.lang.tcl Path: uuneo.neosoft.com!ultraneo.neosoft.com!news-out.internetmci.com!newsfeed.internetmci.com!205.252.116.205!howland.erols.net!recycled.news.erols.com!nntp.news.xara.net!xara.net!peer.news.nildram.co.uk!pavilion!peernews.ftech.net!159.170.4.40.MISMATCH!news.smsuk.smed.com!yama.mcc.ac.uk!cs.man.ac.uk!fellowsd From: fellowsd@cs.man.ac.uk (Donal K. Fellows) Newsgroups: comp.lang.tcl Subject: Re: Tutorial material needed [Was: Re: length of string in pixels] Date: 11 Nov 1997 12:54:20 GMT Organization: Dept of Computer Science, University of Manchester, U.K. Lines: 263 Message-ID: <649khs$5gf$1@m1.cs.man.ac.uk> References: <345F70C2.64B5BAEF@awinc.com> <345FB73B.52F2E819@awinc.com> <34631DA1.23F1CEB8@neovision.com> <6473a3$19l$2@srv38s4u.cas.org> NNTP-Posting-Host: r8h.cs.man.ac.uk Xref: uuneo.neosoft.com comp.lang.tcl:75427 In article <6473a3$19l$2@srv38s4u.cas.org>, wrote: > According to Marc Graham : >> No one has ever gotten "option get" to work correctly! No one >> understands name and class in the Xdb! > > Okay Tk experts. There is the claim. Surely one of you folk who are > using option get could take some time to write up a tutorial explaining > how to use option get not only to manage application writer options but > also Tk core options? Happy to take up the challenge. --- 0. The Underlying Hierarchy The widget hierarchy is really a forest (multi-rooted tree) with each application being one tree. The branches of the tree are the widgets, and the leaves of the tree are the options of the widgets. 1. Basic Option Specification Use To specify an option to a widget using the option database, you need to specify the pathname of the widget whose option you want to set, the option which is going to be set, and the value you want to set it to. The option database is a collection of these. If the application is called spong, and you have a widget called .foo.bar, then you can set the cursor for that widget to be a watch (or semantic equivalent on non-Unix platforms) using a resource database entry of: spong.foo.bar.cursor: watch ^^^^^^^^^^^^^ ^^^^^^ ^^^^^ path option value There are several ways of making this entry into the resource database (under unix/X): a) Placing the entry in your ~/.Xdefaults file which Tk reads in when it starts up. [*] This is a system-wide file. b) Using xrdb to enter it into the system-wide resource database, which Tk reads when it starts up. [*] c) Using [option add spong.foo.bar.cursor watch] This is specific to the particular app. that performed the operation. d) Placing the entry in a file somewhere and using [option readfile] to load it in. This is probably the easiest technique for application writers. This is specific to the particular app. that performed the operation, but it is especially useful for loading the defaults for an application. You can always find out the name of a window using [winfo name $win] though this is mostly only useful when examining . [**] The name of an option is either listed in the manual page where the widget is described, or in the options(n) manual page. It is usually the same as the -option name, except with the second and all subsequent words within the name capitalised. Thus, -borderwidth has the option name borderWidth 2. Widget Classes Each widget has a class as well as a name. Classes are distinguished >from names by starting with a capital letter, and they are useful for when you want to set the options of a collection of similar windows. The class of most widgets is fixed, but for frames and toplevels, you can set it to be something new. I strongly recommend doing this for toplevels, and particularly those where you will be creating then with more than one name, as it lets you separate different kinds of windows (particularly non-modal dialog boxes) from each other. The use of programmer-defined classes for frames is mostly less useful, but can come into its own in highly complex widget hierarchies, and is crucial to supporting megawidgets correctly in the option database. When specifying the class of a widget (via the -class option, which cannot be specified via the resource mechanism) you should take care not to use the class of any of the normal widgets (like Button, Scrollbar, Text, etc.) to prevent confusion, if nothing else. The resource entry: spong.foo.Button.cursor: watch tells all the buttons that are children of .foo in the application called spong to have a watch cursor. You can always find out the class of window using [winfo class $win] 3. Application Classes Applications also have a class, which starts out as a capitalised version of the name of . This can be probed in the obvious way. The name and class of . is rarely of any use to the application writer, and should probably be left to users as a way for them to use when adding their own resource specifications. 4. Option Classes Each option, in addition to its name, has a class so that related options can be referred to by a single entry in the database. The class of an option is usually the same as the name of the option, except with the first letter capitalised as well. Note that this is not always true (particularly for less common options,) and that you should look up the option in the appropriate manual page if you are not sure. e.g. To set all the background-related options for .foo.bar, you could use a database entry like this: spong.foo.bar.Background: white 5. Wildcards in Paths It quickly becomes very tedious to write the full path to a widget whenever you want to specify an option using the database, and quite often you want to refer to widgets that are at an uncertain depth. By using the wildcard, *, for a section of the path, you can make a database entry that refers to the options of many widgets at once. This is particularly useful when used at the beginning of the path, as it can also match any application name, so allowing for the case when a user starts up the application twice and Tk is forced to choose a different name for the app. The following sets the background-related options for all buttons to be white. If used in a system-wide resource database, this will be applied across all applications (and may well be recognised by non-Tk applications.) It is perfectly safe if used in the context of something loaded into the application's database using [option add] or [option readfile] *Button.Background: white Obviously, you cannot use a wildcard for a particular option name since there is no value that is universally accepted for all options, and wildcards have no meaning in the context of values. 6. Option Priorities Tk manages options according to their priority, taking the most recently encountered option at the highest priority where something can be found to match. There are five primary priority levels. From lowest to highest, they are: widgetDefault The hard-coded default for the particular option. It is only useful to set something at this level when you are writing a megawidget, as everything else overrides it. startupFile This level should be used by application writers when reading application-level option database entries. More on this later. userDefault This level should be used by application writers when reading in per-user option database entries. The system-wide options in the user's .Xdefaults file and attached to the user's display are loaded at this level. interactive This level should be used for all entries made because of user actions (e.g. because of what a user does in a configuration management dialog.) This is the default level for the [option] command to work at. "programmed" This is not a conventional level, but rather the pseudo-level that all options that are specified as part of a widget configure subcommand are introduced at. Anything introduced by this route will override all entries in the option database for the particular option and widget, though it will have no truly persistent effect, and if you destroyed and recreated the widget, the effects of this setting would be lost. For more information, see the option(n) manual page. 7. Setting Up the Option Database It is generally the case that it is a good thing that users should be able to configure the way that their applications look. Doing this with Tk is relatively easy, provided an application defaults file is used. Otherwise, it can be very tricky. When creating an application defaults file, you should make all specifications of the look of a widget via that file. Thus, things like the border width, relief, cursor, foreground and background of the widgets can be usefully defined via this route. The easiest place to create the file is in the same directory as the Tcl script that loads the app-def file, so you can load it using a command like: option readfile [file join [file dirname [info script]] myapp.def] startup If you then add another command to load a user's app-def file, like: catch {option readfile [file join ~ myapp.def] user} it becomes easy for a user to override any of the settings in the application's defaults. 8. Introducing Your Own Options It is easy to add your own options to a widget.[***] To do this, make it so that every time you need to option the value, you perform an [option get] command. This requires three arguments: The pathname of the widget, so it knows where in the (virtual) tree to look for the option. Note that the widget _must_ exist before you perform the lookup. This can be real a P.I.T.A The name of the option. You probably ought to make sure that this doesn't overlap with any of the standard option names, or the effects could well be undefined. The class of the option. This can quite frequently be shared with a standard option, and usually ought to reflect the sort of value that can be used with the option. Thus, if you accept fonts in that option value, you are recommended to use the class Font in the [option get] command. It is acceptable to only read the option database once, when the widget being used as the pathname is created. 9. Problems and Caveats Some things cannot be specified by defaults files (notably the -class option to some widgets) and some probably should not be specified by defaults files (particularly those options that affect the behaviour of the interface, like -command, -variable, -xscrollcommand, etc.) as otherwise the interface can end up completely non-functional. Often those options are only usefully set in the context of part of the application anyway. Furthermore, some things cannot be specified by options (layout options for pack and grid, or the items on a menu) even though it would be useful to do so. You can work around this, but it is not especially easy. To make things worse, some window/session managers (notably Mwm/CDE) set "useful" options like *Background, which can make life rather interesting. I've had problems with debugging the interface of an application from user reports because of this. Note that there is no automatic update of existing widgets when the database is modified. If you want this, you will need to implement it yourself. There are probably more problems involved with the option database, but that is all I can think of right now... :^) 10. Copyright, etc. Copyright (c) 1997 Donal K. Fellows. Permission to distribute this message via USENET is granted, but all commercial use is forbidden. If you want to use this message commercially, please contact the author. [* This also occurs after an [option clear] operation.] [** The linkage between the name of . and the value returned by [winfo name .] can be broken by the [tk appname] command. ] [*** This is only from the point-of-view of the option database. Adding them from the PoV of the configure command is a business for megawidgets only. ] --- Donal. -- Donal K. Fellows http://r8h.cs.man.ac.uk:8000/ Boing! Boing! Boing! fellowsd@cs.man.ac.uk Dept. Comp. Sci, Univ. Manchester, U.K. +44-161-275-6137 -- I have a really good anti-spam mail filter in use. Don't bother spamming me...