| [56ade3b] | 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> |
|---|
| 2 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
|---|
| 3 | |
|---|
| 4 | <head> |
|---|
| 5 | <title>mkWidgets Manual, Part 1 of 2</title> |
|---|
| 6 | <meta http-equiv="Content-Type" content="text/html"/> |
|---|
| 7 | <meta name="DESCRIPTION" content="Tcl/Tk mkWidgets"/> |
|---|
| 8 | <meta name="AUTHOR" content="Michael Kraus"/> |
|---|
| 9 | <meta name="KEYWORDS" content="Tcl, Tk, Tcl/Tk, Scriptics, Scripting, Programming, Extension, Package, mkWidgets"/> |
|---|
| 10 | <style type="text/css"><!-- |
|---|
| 11 | body { font-family: Lucida Sans Unicode, Arial, Helvetica } |
|---|
| 12 | p { font-family: Arial, Helvetica; font-size: .8em; margin: 1em } |
|---|
| 13 | h1 { font-size: 1.2em; font-weight: normal; color: #000000; background: #FFFF40; padding: 0.4em } |
|---|
| 14 | h2 { font-size: 1.0em; font-weight: normal; color: #000080; background: #DDDDDD; padding: 0.1em } |
|---|
| 15 | h3 { font-size: 0.8em; font-weight: normal; color: #000080 } |
|---|
| 16 | h6 { font-size: 0.7em; font-weight: normal; margin: 1em } |
|---|
| 17 | em { font-size: 1em; font-weight: normal; font-style: normal; color: #000080 } |
|---|
| 18 | pre { color: blue; margin: 1em 1em 1em 1em } |
|---|
| 19 | ul { font-family: Arial, Helvetica; font-size: .8em; margin: 1em 1em 1em 3em } |
|---|
| 20 | a { text-decoration: none } |
|---|
| 21 | img { float: right; clear: right; margin: .5em } |
|---|
| 22 | --></style> |
|---|
| 23 | </head> |
|---|
| 24 | |
|---|
| 25 | <body> |
|---|
| 26 | <h1><img src="images/TclLogo.gif" alt=""/> mkWidgets 1.3 Manual, Part 1 of 2</h1> |
|---|
| 27 | <h6>Permission to use, copy, modify, and distribute this software and its documentation |
|---|
| 28 | for any purpose and without fee is hereby granted. The author makes no representations |
|---|
| 29 | about the suitability of this software for any purpose. It is provided "as is" without |
|---|
| 30 | express or implied warranty. By use of this software the user agrees to indemnify and |
|---|
| 31 | hold harmless the author from any claims or liability for loss arising out of such use.<br/> </h6> |
|---|
| 32 | |
|---|
| 33 | <h2> CONTENTS</h2> |
|---|
| 34 | <p> |
|---|
| 35 | mkWidgets 1.3 - A method for writing metawidgets, and a collection of these. |
|---|
| 36 | Part 1: How to build metawidgets (<a href="mkWidgetsCol13.htm">Part 2</a>) |
|---|
| 37 | </p> |
|---|
| 38 | <p> |
|---|
| 39 | <a href="#introduction">Introduction</a><br/> |
|---|
| 40 | <a href="#metawidget">The Metawidget Command</a><br/> |
|---|
| 41 | <a href="#specials">Special Commands</a><br/> |
|---|
| 42 | <a href="#tools">Tool Commands</a><br/> |
|---|
| 43 | <a href="#notes">Notes</a><br/> |
|---|
| 44 | <a href="#examples">Examples</a><br/> |
|---|
| 45 | <a href="#installation">Installation</a><br/> |
|---|
| 46 | <a href="#changes">Changes</a><br/> |
|---|
| 47 | <a href="#author">Author</a><br/> |
|---|
| 48 | </p> |
|---|
| 49 | |
|---|
| 50 | <h2><a name="introduction"> INTRODUCTION</a></h2> |
|---|
| 51 | <p> |
|---|
| 52 | A metawidget is composed of several standard widgets and behaves like a standard widget itself |
|---|
| 53 | (well, almost). Since there is no limit in regards to the number of standard widgets inside a |
|---|
| 54 | metawidget and its overall functionality, metawidgets can be anything from as simple as a |
|---|
| 55 | combobox to as complex as a treecontrol and more. See <a href="mkWidgetsCol13.htm">Part 2</a> of |
|---|
| 56 | this manual for details. |
|---|
| 57 | </p> |
|---|
| 58 | <p> |
|---|
| 59 | mkWidgets 1.3 is written entirely in Tcl/Tk and does not require any other extensions (unlike version 1.0, |
|---|
| 60 | where mkGeneric and mkClasses was required). It provides two things: |
|---|
| 61 | </p> |
|---|
| 62 | <ul> |
|---|
| 63 | <li>A fairly easy method to write metawidgets, provided by the package <em>Metawidget</em>. It uses |
|---|
| 64 | namespaces to implement something similar to classes and objects.</li> |
|---|
| 65 | <li>A collection of metawidgets, some of them being pretty snappy. This collection is loaded with |
|---|
| 66 | the package "mkWidgets" which itself requests the Metawidget package.</li> |
|---|
| 67 | </ul> |
|---|
| 68 | <p> |
|---|
| 69 | The main characteristics of a regular widget in Tk are: |
|---|
| 70 | </p> |
|---|
| 71 | <ul> |
|---|
| 72 | <li>It is an instance of a widget class, e.g. "Button".</li> |
|---|
| 73 | <li>It can have methods, called "widget commands".</li> |
|---|
| 74 | <li>It has properties, called "options" which are controlled by the method "configure".</li> |
|---|
| 75 | <li>It is organized in a tree-shaped hierarchy, i.e. it has one parent and may have children.</li> |
|---|
| 76 | <li>It is destroyed by the "destroy" command, including all children.</li> |
|---|
| 77 | <li>It can have event bindings attached to it.</li> |
|---|
| 78 | <li>It can be packed, placed and gridded.</li> |
|---|
| 79 | </ul> |
|---|
| 80 | <p> |
|---|
| 81 | The <em>Metawidget</em> package allows for the definition of metawidgets that behave |
|---|
| 82 | almost the same way as regular Tk widgets. A metawidgets attributes are: |
|---|
| 83 | </p> |
|---|
| 84 | <ul> |
|---|
| 85 | <li>It is an instance of a class defined with the command "metawidget"</li> |
|---|
| 86 | <li>It can have commands, which are defined via "metawidget command"</li> |
|---|
| 87 | <li>It has options, which are defined via "metawidget option"</li> |
|---|
| 88 | <li>It is defined in the same hierarchy tree like all other widgets</li> |
|---|
| 89 | <li>It is destroyed with "destroy" like all other widgets</li> |
|---|
| 90 | <li>It can have event bindings like all other widgets. Some restrictions apply.</li> |
|---|
| 91 | <li>It can be packed, placed and gridded. Some restrictions apply to children.</li> |
|---|
| 92 | </ul> |
|---|
| 93 | <p> |
|---|
| 94 | The Metawidget package is basically a code generator. One can build metawidgets in a |
|---|
| 95 | rather abstract and simple way by defining new widget commands and options, |
|---|
| 96 | while the package takes care of namespace handling and Tcl code generation. |
|---|
| 97 | </p> |
|---|
| 98 | <p> |
|---|
| 99 | A nice new feature in this version is the <em>metawidget export</em> command. |
|---|
| 100 | It returns the standard Tcl code that is generated by the Metawidget package |
|---|
| 101 | for a particular metawidget. By simply integrating this code into an application, |
|---|
| 102 | the dependency to mkWidgets can be eliminated. |
|---|
| 103 | </p> |
|---|
| 104 | |
|---|
| 105 | <h2><a name="metawidget"> THE METAWIDGET COMMAND</a></h2> |
|---|
| 106 | <p> |
|---|
| 107 | A Metawidget is defined with the "metawidget" command and its subcommands "create", |
|---|
| 108 | "proc", "option" and "command". It can be deleted with "delete", and information can be |
|---|
| 109 | retrieved with "info" or "names". |
|---|
| 110 | </p> |
|---|
| 111 | <h3>metawidget create ClassName InitProc ExitProc ?-type WidgetType? ?-default WidgetName? ?-command CommandName? ?args?</h3> |
|---|
| 112 | <p> |
|---|
| 113 | This command creates a new metawidget class with the name ClassName. According to existing |
|---|
| 114 | naming conventions, ClassName must start with an uppercase letter. InitProc specifies a script |
|---|
| 115 | that is evaluated on each instantiation of a metawidget. It usually contains code to create |
|---|
| 116 | any internal widgets that make up the metawidget, and to initialize options and other state |
|---|
| 117 | information. The current metawidget is referenced by means of the automatic variable $this. |
|---|
| 118 | ExitProc is evaluated when a metawidget is destroyed. As with InitProc, the metawidget's |
|---|
| 119 | name is stored in the variable $this. The ExitProc usually releases any resources such as |
|---|
| 120 | open channels. |
|---|
| 121 | </p> |
|---|
| 122 | <p> |
|---|
| 123 | Each metawidget has a widget that encloses all other widgets. This widget is automatically |
|---|
| 124 | created and is an invisible frame by default. By means of the -type option, a different widget |
|---|
| 125 | type can be specified, for instants a toplevel widget. |
|---|
| 126 | </p> |
|---|
| 127 | <p> |
|---|
| 128 | The -default option specifies where calls to the standard metawidget commands configure and cget |
|---|
| 129 | shall be redirected to, if they are not explicitely defined with "metawidget option". |
|---|
| 130 | Also, all commands not explicitely defined with "metawidget command" will be redirected to the default widget. |
|---|
| 131 | WidgetName must be the name of one of the internal widgets, <em>relative</em> to its enclosing widget. |
|---|
| 132 | If no default widget is specified, the enclosing widget is taken. |
|---|
| 133 | </p> |
|---|
| 134 | <p> |
|---|
| 135 | The -command option specifies what the name of the new widget command shall be. By default, it |
|---|
| 136 | is the same as the metawidget's ClassName, but all in lowercase letters. |
|---|
| 137 | </p> |
|---|
| 138 | <p> |
|---|
| 139 | In addition, an arbitrary number of option-value pairs may be specified. They will directly be |
|---|
| 140 | applied to the enclosing widget and hence must be allowed option values for a frame or whatever |
|---|
| 141 | widget type has been specified by means of the -type option. |
|---|
| 142 | </p> |
|---|
| 143 | |
|---|
| 144 | <h3>metawidget proc ClassName ProcName Args Body</h3> |
|---|
| 145 | <p> |
|---|
| 146 | This command defines a procedure that is associated with a metawidget. It is defined just like |
|---|
| 147 | a regular procedure, i.e. it has a name, a list of arguments, and a body. As with the InitProc |
|---|
| 148 | and the ExitProc from the "metawidget create" command, the automatic variable $this represents |
|---|
| 149 | the current metawidget. Metawidget procedures can be called only from within another metawidget |
|---|
| 150 | procedure of the very same widget instance. They are used to implement code that is associated |
|---|
| 151 | to metawidget options and/or commands. |
|---|
| 152 | </p> |
|---|
| 153 | |
|---|
| 154 | <h3>metawidget command ClassName CommandName ProcName</h3> |
|---|
| 155 | <p> |
|---|
| 156 | This defines a metawidget command and associates it with a metawidget procedure. |
|---|
| 157 | Metawidget commands are identical to regular widget commands and are specified right |
|---|
| 158 | after the widget name, like in ".mybutton invoke". When a metawidget's command is |
|---|
| 159 | called, its associated procedure is executed, hereby passing all arguments that might |
|---|
| 160 | have been specified after the command. Note that even if no metawidget commands |
|---|
| 161 | are defined, a metawidget will still accept all commands that exist for its default widget. |
|---|
| 162 | </p> |
|---|
| 163 | |
|---|
| 164 | <h3>metawidget option ClassName OptionName ?SetProc? ?GetProc?</h3> |
|---|
| 165 | <p> |
|---|
| 166 | This defines a metawidget option. Metawidget options are those that require special |
|---|
| 167 | processing, i.e. they are in most cases not a real option of any of its internal widgets. |
|---|
| 168 | As with metawidget commands, a metawidget that has no such metawidget options defined |
|---|
| 169 | will still accept all options that apply to the metawidget's default widget. |
|---|
| 170 | </p> |
|---|
| 171 | <p> |
|---|
| 172 | There are three ways to define metawidget options: By means of a widget-variable (see below), |
|---|
| 173 | by means of a metawidget procedure or with a combination of both: |
|---|
| 174 | </p> |
|---|
| 175 | <p> |
|---|
| 176 | Some options do not require immediate processing. It is rather sufficient to store their |
|---|
| 177 | value in a variable for later reference. An example is the -command option of a regular |
|---|
| 178 | button: When this option is set, nothing happens. A metawidget option of that kind |
|---|
| 179 | is created without specifying SetProc and GetProc. The metawidget will simply store |
|---|
| 180 | the value in a widget-variable that has the same name as the option. |
|---|
| 181 | </p> |
|---|
| 182 | <p> |
|---|
| 183 | Many times, when an option is set, it requires code to be executed. For instants, there |
|---|
| 184 | must be <em>some</em> code that actually changes a button's background color, when its |
|---|
| 185 | value for the -background option is changed. If that piece of code eventually stores the |
|---|
| 186 | new color in a variable, then the option's current value can always be looked up there. |
|---|
| 187 | This is equivalent to creating a metawidget option where SetProc is a metawidget procedure. |
|---|
| 188 | Every time this option is set, SetProc is called with the new option value as its only |
|---|
| 189 | argument. If the option's value is retrieved by means of the cget command, the actual |
|---|
| 190 | value is taken from its widget-variable. Therefore SetProc <em>must</em> set this widget-variable |
|---|
| 191 | to the option's new value. |
|---|
| 192 | </p> |
|---|
| 193 | <p> |
|---|
| 194 | If, in addition, a GetProc is specified, then it is called every time the option's value |
|---|
| 195 | is requested with the cget command. GetProc <em>must</em> return the option's value, |
|---|
| 196 | in whatever way it is retrieved, and is called without arguments. |
|---|
| 197 | </p> |
|---|
| 198 | |
|---|
| 199 | <h3>metawidget delete ClassName</h3> |
|---|
| 200 | <p> |
|---|
| 201 | The delete subcommand deletes a metawidget class. This should not be called if instances |
|---|
| 202 | of that class still exist. |
|---|
| 203 | </p> |
|---|
| 204 | |
|---|
| 205 | <h3>metawidget names</h3> |
|---|
| 206 | <p> |
|---|
| 207 | This simply returns all currently defined metawidgets. |
|---|
| 208 | </p> |
|---|
| 209 | |
|---|
| 210 | <h3>metawidget info ClassName procs | commands | options</h3> |
|---|
| 211 | <p> |
|---|
| 212 | This returns the procedures, commands and options defined for the specified class. |
|---|
| 213 | It always returns a list where each element is a sublist of the arguments that |
|---|
| 214 | were used during the definition of the procs, commands or options. |
|---|
| 215 | </p> |
|---|
| 216 | |
|---|
| 217 | <h3>metawidget export ClassName</h3> |
|---|
| 218 | <p> |
|---|
| 219 | The code as generated by the Metawidget package is returned. It is standard Tcl with |
|---|
| 220 | no dependencies to the package itself. Consequently, by simply pasting the code into |
|---|
| 221 | a standard application, metawidgets can be used without their definition and without |
|---|
| 222 | having to source the Metawidget package. |
|---|
| 223 | </p> |
|---|
| 224 | |
|---|
| 225 | <h2><a name="specials"> SPECIAL COMMANDS</a></h2> |
|---|
| 226 | <p> |
|---|
| 227 | A metawidget instance is basically like an object in the object oriented programming world: |
|---|
| 228 | It has a constructor (InitProc), a destructor (ExitProc), methods (the commands), and |
|---|
| 229 | properties (the options). Consequently, it has something like private variables, here |
|---|
| 230 | called widget-variables, and also class-static variables, called class-variables. |
|---|
| 231 | </p> |
|---|
| 232 | <p> |
|---|
| 233 | A widget-variable is specific to an <em>instance</em> of a metawidget. Widget-variables |
|---|
| 234 | can be set and retrieved in any metawidget procedure and remain state in-between calls. |
|---|
| 235 | They are neither really global nor local, and can have a different value in each instance. |
|---|
| 236 | Widget-variables are controlled by a set of "my" commands. |
|---|
| 237 | </p> |
|---|
| 238 | <p> |
|---|
| 239 | A class-variable is specific to a metawidget's <em>class</em>. As with widget-variables |
|---|
| 240 | class-variables can be set and retrieved in any metawidget procedure and remain state |
|---|
| 241 | in-between calls. They exist exactly once for all instances of a class and are therefore |
|---|
| 242 | suited to exchange data between objects and to store information that is identical |
|---|
| 243 | for all instances of a class. Widget-variables are controlled by a set of "our" commands. |
|---|
| 244 | </p> |
|---|
| 245 | |
|---|
| 246 | <h3>my WidgetVar ?NewValue?</h3> |
|---|
| 247 | <p> |
|---|
| 248 | Sets or retrieves a widget-variable. Similar to the standard "set" command, it can be called with |
|---|
| 249 | the name of a variable to retrieve the value of this variable or to set it to a new value. |
|---|
| 250 | </p> |
|---|
| 251 | |
|---|
| 252 | <h3>unmy WidgetVar ?WidgetVar ...?</h3> |
|---|
| 253 | <p> |
|---|
| 254 | Unsets widget-variables. Although the command's name seems nonsense, it is a nice equivalent to |
|---|
| 255 | the standard command "unset". |
|---|
| 256 | </p> |
|---|
| 257 | |
|---|
| 258 | <h3>myarray option WidgetArray ?args?</h3> |
|---|
| 259 | <p> |
|---|
| 260 | Not only scalar widget-variables can be defined, but also arrays. This command is just |
|---|
| 261 | like the standard "array" command, except that it applies to widget-arrays. |
|---|
| 262 | </p> |
|---|
| 263 | |
|---|
| 264 | <h3>myinfo class, myinfo vars, myinfo exists WidgetVar</h3> |
|---|
| 265 | <p> |
|---|
| 266 | Either returns the metawidget's class name, or all currently defined widget-variables, |
|---|
| 267 | or a flag if the specified WidgetVar exists. |
|---|
| 268 | </p> |
|---|
| 269 | |
|---|
| 270 | <h3>our ClassVar ?NewValue?</h3> |
|---|
| 271 | <p> |
|---|
| 272 | Sets or retrieves a class-variable. Similar to the standard "set" command, it can be called with |
|---|
| 273 | the name of a variable to retrieve the value of this variable or to set it to a new value. |
|---|
| 274 | </p> |
|---|
| 275 | |
|---|
| 276 | <h3>unour ClassVar ?ClassVar ...?</h3> |
|---|
| 277 | <p> |
|---|
| 278 | Unsets class-variables. Although the command's name seems nonsense, it is a nice equivalent to |
|---|
| 279 | the standard command "unset". |
|---|
| 280 | </p> |
|---|
| 281 | |
|---|
| 282 | <h3>ourarray option ClassArray ?args?</h3> |
|---|
| 283 | <p> |
|---|
| 284 | Not only scalar class-variables can be defined, but also arrays. This command is just |
|---|
| 285 | like the standard "array" command, except that it applies to class-arrays. |
|---|
| 286 | </p> |
|---|
| 287 | |
|---|
| 288 | <h3>ourinfo vars, ourinfo exists ClassVar</h3> |
|---|
| 289 | <p> |
|---|
| 290 | Either returns all currently defined class-variables, or a flag if the specified ClassVar exists. |
|---|
| 291 | </p> |
|---|
| 292 | |
|---|
| 293 | <h2><a name="tools"> TOOL COMMANDS</a></h2> |
|---|
| 294 | |
|---|
| 295 | <p> |
|---|
| 296 | Some tool commands are also imported into every metawidget class. They all start with |
|---|
| 297 | "mkw." and are not really necessary, but make some things easier (they are merely Tcl-only |
|---|
| 298 | rip-offs of my favorites from the mkGeneric package). |
|---|
| 299 | </p> |
|---|
| 300 | |
|---|
| 301 | <h3>mkw.lassign List ?VarName ...?</h3> |
|---|
| 302 | <p> |
|---|
| 303 | Assigns all elements in List to the given VarNames from left to right. I.e. the first |
|---|
| 304 | element in List is assigned to the first VarName, the second element to the second |
|---|
| 305 | VarName and so on. If there are more VarNames than elements in List, |
|---|
| 306 | the remaining VarNames are left unchanged. |
|---|
| 307 | </p> |
|---|
| 308 | |
|---|
| 309 | <h3>mkw.lextend List ?Value ...?</h3> |
|---|
| 310 | <p> |
|---|
| 311 | If Value is not yet an element of List, Value is appended to the list and the extended list |
|---|
| 312 | is returned. Otherwise, the command simply returns List. |
|---|
| 313 | </p> |
|---|
| 314 | |
|---|
| 315 | <h3>mkw.lshrink List ?Value ...?</h3> |
|---|
| 316 | <p> |
|---|
| 317 | If Value is an element of List, Value is deleted from the list and the reduced list is returned. |
|---|
| 318 | Otherwise, the command simply returns List. |
|---|
| 319 | </p> |
|---|
| 320 | |
|---|
| 321 | <h3>mkw.lchange List OldValue NewValue</h3> |
|---|
| 322 | <p> |
|---|
| 323 | If OldValue is an element of List, OldValue is replaced by NewValue and the modified list |
|---|
| 324 | is returned. Otherwise, the command simply returns List. |
|---|
| 325 | </p> |
|---|
| 326 | |
|---|
| 327 | <h3>mkw.decode Expr List ?DefaultValue?</h3> |
|---|
| 328 | <p> |
|---|
| 329 | List must consist of an even number of elements. Each odd-numbered element in List is compared |
|---|
| 330 | against Expr. If it matches, the element on the right of the matching element in List is returned. |
|---|
| 331 | If there is no match and a DefaultValue is specified, it is returned. Otherwise the command |
|---|
| 332 | returns nothing. (This is similar to "string map", which is not available in Tcl 8.0). |
|---|
| 333 | </p> |
|---|
| 334 | |
|---|
| 335 | <h3>mkw.complete Expr List</h3> |
|---|
| 336 | <p> |
|---|
| 337 | Expr is compared against each of the elements in List to find a match. A match occurs if Expr |
|---|
| 338 | is identical to one of the elements, or if it is a unique abbreviation for exactly one of them. |
|---|
| 339 | In this case the matching element is returned, otherwise an error is created. |
|---|
| 340 | </p> |
|---|
| 341 | |
|---|
| 342 | <h3>mkw.options List ?OptionSpec ...?</h3> |
|---|
| 343 | <p> |
|---|
| 344 | This is a simple option processing routine. options can have no arguments (like |
|---|
| 345 | with lsort -dictionary) or one argument (like fconfigure ... -blocking 1). List is |
|---|
| 346 | expected to consist of any combination of zero- or one-argument options, e.g. |
|---|
| 347 | '-dictionary -command mySort -index 1 -decreasing'. Allowed options are specified with |
|---|
| 348 | an arbitrary number of option specifications. For options with no argument, the OptionSpec |
|---|
| 349 | is simply the name of the option, e.g. -dictionary. For options with a value, an OptionSpec |
|---|
| 350 | consists of two or three elements: The first is the option name, the second either a list of |
|---|
| 351 | allowed values or an asterisk * for any value. The third element is optional and specifies a |
|---|
| 352 | default value if the option is not found in List. |
|---|
| 353 | </p> |
|---|
| 354 | <p> |
|---|
| 355 | For each option found, a variable with the same name as the option is set in the calling |
|---|
| 356 | procedure's context. This variable's value is either a 1 for options without argument, |
|---|
| 357 | or the option's value. Option names can be abbreviated, as well as option values that map to |
|---|
| 358 | a list of allowed values in the OptionSpec. The command will return an error message, if an |
|---|
| 359 | unknown option was found, or, if one of the OptionSpecs is a plain *, return all elements |
|---|
| 360 | in List that could not be resolved. |
|---|
| 361 | </p> |
|---|
| 362 | |
|---|
| 363 | <h2><a name="notes"> NOTES</a></h2> |
|---|
| 364 | |
|---|
| 365 | <h3>Bindings</h3> |
|---|
| 366 | <p> |
|---|
| 367 | The bindtags of a metawidget are modified, so that the widget type of the enclosing widget |
|---|
| 368 | is replaced by the class name of the metawidget. The default class binding for the event |
|---|
| 369 | <Destroy> is redefined and now calls the metawidget's ExitProc. Besides that, |
|---|
| 370 | any binding to a metawidget will apply to its enclosing widget. |
|---|
| 371 | </p> |
|---|
| 372 | <p> |
|---|
| 373 | If a metawidget procedure needs to be called from within a binding script, then this |
|---|
| 374 | procedure has to be "exported" via a metawidget command. Binding scripts are evaluated from |
|---|
| 375 | within the global namespace and therefore don't know any of the metawidget's procedures. |
|---|
| 376 | </p> |
|---|
| 377 | |
|---|
| 378 | <h3>Geometry Management</h3> |
|---|
| 379 | <p> |
|---|
| 380 | Many metawidgets are "final". That is, they wont have child widgets other than their internal |
|---|
| 381 | widgets (those that constitute the metawidget). A combobox, for instants, would not like to |
|---|
| 382 | have other widgets packed inside it. However, some metawidgets like the Textframe example below, |
|---|
| 383 | make only sense with other widgets inside them. Other metawidgets of that kind are Document, Pane |
|---|
| 384 | and Tabcontrol. |
|---|
| 385 | </p> |
|---|
| 386 | <p> |
|---|
| 387 | This can be a problem, if these widgets are true children of the metawidget, for a) the metawidget |
|---|
| 388 | has already some children (or it wouldn't be a metawidget...), and b) there is no control of where |
|---|
| 389 | the new children will be placed, gridded or packed together with the metawidget's own children. |
|---|
| 390 | </p> |
|---|
| 391 | <p> |
|---|
| 392 | One solution is to simply document the particular child of the metawidget where other children may be legally |
|---|
| 393 | placed into. E.g. in the case of the Document metawidget, this would be <em>$this.work</em>. This is |
|---|
| 394 | a document's work area, and other widgets should be put inside it. These widgets may or may not be logical |
|---|
| 395 | children of <em>$this.work</em>. |
|---|
| 396 | </p> |
|---|
| 397 | <p> |
|---|
| 398 | Another solution is to define the metawidget commands pack, place and grid. They would accept the usual arguments |
|---|
| 399 | for these three native commands, but would also ensure that widgets appear in the right spot, by sort of |
|---|
| 400 | redirecting the widgets into the work area. |
|---|
| 401 | Obviously, that is not so nice as using pack, place and grid in the usual way. However, it's |
|---|
| 402 | not really new either: Complex widgets like canvas and text also place other objects inside |
|---|
| 403 | them by using e.g. .canvas create ... or .text window ... |
|---|
| 404 | </p> |
|---|
| 405 | |
|---|
| 406 | <h3>Option Database</h3> |
|---|
| 407 | <p> |
|---|
| 408 | The option database is not supported in this version (quote from "Tcl and the Tk Toolkit": |
|---|
| 409 | "I suggest that you use it as little as possible"). |
|---|
| 410 | </p> |
|---|
| 411 | |
|---|
| 412 | <h3>Configure Command</h3> |
|---|
| 413 | <p> |
|---|
| 414 | Calling a metawidget with the configure command but without additional arguments will only |
|---|
| 415 | return the options list of the default widget but not the metawidget options. |
|---|
| 416 | </p> |
|---|
| 417 | |
|---|
| 418 | <h3>Command and Option Abbreviation</h3> |
|---|
| 419 | <p> |
|---|
| 420 | Commands and options can be abbreviated, but the way they are being resolved is not quite clean. |
|---|
| 421 | As described above, a command (or option) that is not specified with "metawidget command" (or |
|---|
| 422 | "metawidget option") will be applied to the default widget. An abbreviated command (or option) |
|---|
| 423 | would first be resolved within the metawidget commands (or metawidget options), and then within |
|---|
| 424 | the default widget commands (or options). So, if there's a metawidget option "-compute" and the |
|---|
| 425 | default widget is a button, then the string "-com" would apply to both "-compute" and "-command". |
|---|
| 426 | However, instead of raising an error, "-compute" will be called. |
|---|
| 427 | </p> |
|---|
| 428 | <h3>Backward Compatibility</h3> |
|---|
| 429 | <p> |
|---|
| 430 | The current version 1.3 introduces a minor incompatibility that was necessary to make metawidgets |
|---|
| 431 | behave a bit more like native widgets: The <em>-type</em> option of the <em>metawidget</em> command |
|---|
| 432 | now only accepts the values <em>frame</em> and <em>toplevel</em>. Other widget types are not allowed |
|---|
| 433 | anymore. The benefit of this is that a call to <em>winfo class <i>metawidget</i></em> now returns |
|---|
| 434 | the correct class name of that metawidget (which is achieved with the <em>-class</em> option only |
|---|
| 435 | available for <em>frame</em> and <em>toplevel</em> window types). |
|---|
| 436 | </p> |
|---|
| 437 | <p> |
|---|
| 438 | Document metawidget: If you pack, place or grid a widget inside a document metawidget, and this widget |
|---|
| 439 | is a logical child of the document metawidget, then it will get an <Enter> binding which will reset |
|---|
| 440 | the mouse cursor whenever it enters this widget. If the widget is not a child of the document |
|---|
| 441 | metawidget, then the binding will not be applied because it is not required for a correct mouse cursor |
|---|
| 442 | behavior. The new <Enter> bind script would overwrite other <Enter> bind scripts that you might |
|---|
| 443 | have defined. Conversively, you'd have to be careful not to overwrite this <Enter> bind script. |
|---|
| 444 | </p> |
|---|
| 445 | |
|---|
| 446 | |
|---|
| 447 | <h2><a name="examples"> EXAMPLES</a></h2> |
|---|
| 448 | <p> |
|---|
| 449 | The collection of metawidgets that comes with this package provides a good source of |
|---|
| 450 | examples. Each file contains a procedure "test" that creates an instance of |
|---|
| 451 | the related metawidget. |
|---|
| 452 | </p> |
|---|
| 453 | <p> |
|---|
| 454 | Nevertheless, here is closer look on a metawidget called Textframe. It is nothing more |
|---|
| 455 | but a decorative frame with a title text embedded in the upper part. |
|---|
| 456 | </p> |
|---|
| 457 | <p> |
|---|
| 458 | So, in the first approach, it would consist of a frame widget and a label widget. But |
|---|
| 459 | since the label sticks out of the decorative frame in both directions, this frame cannot |
|---|
| 460 | be the enclosing object. Also, all external widgets that shall be put inside the textframe, |
|---|
| 461 | would probably overlap or otherwise interfere with the label widget. Therefore, |
|---|
| 462 | two additional, invisible frames must be defined: One is the enclosing widget, the |
|---|
| 463 | other one is used for packing, placing or gridding all external widgets inside it. |
|---|
| 464 | In between these two frames is the decorative, visible frame and the label. |
|---|
| 465 | </p> |
|---|
| 466 | |
|---|
| 467 | <pre> |
|---|
| 468 | +-----------------+ |
|---|
| 469 | | %% LABEL %%%%%% |--- enclosing frame |
|---|
| 470 | | % +---------+ % | |
|---|
| 471 | | % | ....... | %----- decorative frame |
|---|
| 472 | | % | ....... | % | |
|---|
| 473 | | % | ....... |------- inner frame |
|---|
| 474 | | % +---------+ % | |
|---|
| 475 | | %%%%%%%%%%%%%%% | |
|---|
| 476 | +-----------------+ |
|---|
| 477 | </pre> |
|---|
| 478 | |
|---|
| 479 | <pre> |
|---|
| 480 | package require Metawidget |
|---|
| 481 | |
|---|
| 482 | # metawidget textframe |
|---|
| 483 | # creates a frame with a title text. other widgets can be packed inside |
|---|
| 484 | # the textframe. The textframe can be configured like a regular frame |
|---|
| 485 | # widget. Extra options are -text for the title text and -font |
|---|
| 486 | # for the title font. |
|---|
| 487 | |
|---|
| 488 | metawidget create Textframe { |
|---|
| 489 | # create all internal widgets |
|---|
| 490 | frame $this._frm_ -border 2 -relief groove ;# decorative frame |
|---|
| 491 | frame $this._inn_ -border 0 ;# inner frame |
|---|
| 492 | label $this._txt_ -border 0 -padx 0 -pady 0 ;# label |
|---|
| 493 | |
|---|
| 494 | # position all internal widgets. |
|---|
| 495 | # only one here, the other two are packed in the -font member. |
|---|
| 496 | place $this._txt_ -in $this._frm_ -x 12 -y 0 -anchor w |
|---|
| 497 | |
|---|
| 498 | # preset all metawidget options. |
|---|
| 499 | -text {} |
|---|
| 500 | -font [$this._txt_ cget -font] |
|---|
| 501 | } {} -default _frm_ |
|---|
| 502 | |
|---|
| 503 | # option -text |
|---|
| 504 | # since the default widget is the decorative frame, all options for |
|---|
| 505 | # the label widget must be explicitely redirected to it. |
|---|
| 506 | |
|---|
| 507 | metawidget proc Textframe -text { sText } { |
|---|
| 508 | $this._txt_ configure -text $sText |
|---|
| 509 | my -text $sText |
|---|
| 510 | } |
|---|
| 511 | |
|---|
| 512 | # option -font |
|---|
| 513 | # this is more complex. the font cannot just be set and that's it. |
|---|
| 514 | # the decorative frame needs to cross the label vertically centered. |
|---|
| 515 | # the new height of the label determines the padding of the decorative |
|---|
| 516 | # and the inner frames, requiring them to be repacked each time the |
|---|
| 517 | # font is changed. |
|---|
| 518 | |
|---|
| 519 | metawidget proc Textframe -font { sFont } { |
|---|
| 520 | $this._txt_ configure -font $sFont |
|---|
| 521 | my -font $sFont |
|---|
| 522 | |
|---|
| 523 | update |
|---|
| 524 | |
|---|
| 525 | set iPad [expr [winfo height $this._txt_] / 2 + 1] |
|---|
| 526 | pack $this._frm_ -fill both -expand 1 -padx $iPad -pady $iPad |
|---|
| 527 | pack $this._inn_ -in $this._frm_ -fill both -expand 1 -padx $iPad -pady $iPad |
|---|
| 528 | } |
|---|
| 529 | |
|---|
| 530 | # command pack |
|---|
| 531 | # command for packing other widgets inside the text frame. for grid and |
|---|
| 532 | # place this can be implemented in a similar way. the option -in |
|---|
| 533 | # $this._inn_ takes care that everything ends up in the inner frame. |
|---|
| 534 | |
|---|
| 535 | metawidget proc Textframe pack_ { sWidget args } { |
|---|
| 536 | eval pack $sWidget -in $this._inn_ $args |
|---|
| 537 | } |
|---|
| 538 | |
|---|
| 539 | # define metawidget options and commands with their associated procs |
|---|
| 540 | |
|---|
| 541 | metawidget option Textframe -text -text |
|---|
| 542 | metawidget option Textframe -font -font |
|---|
| 543 | metawidget command Textframe pack pack_ |
|---|
| 544 | |
|---|
| 545 | # test it |
|---|
| 546 | |
|---|
| 547 | textframe .t -text { Title } |
|---|
| 548 | button .b -text Destroy -command { destroy .t } |
|---|
| 549 | |
|---|
| 550 | pack .t -fill both -expand 1 |
|---|
| 551 | pack .b -fill x -side bottom |
|---|
| 552 | |
|---|
| 553 | array set aFont {0 {Helv 9} 1 {Courier 15 bold}} |
|---|
| 554 | array set aFrame {0 groove 1 solid} |
|---|
| 555 | |
|---|
| 556 | checkbutton .c1 -text {Other Font} -variable iC1 -command { .t config -font $aFont($iC1) } |
|---|
| 557 | checkbutton .c2 -text {Other Frame} -variable iC2 -command { .t config -relief $aFrame($iC2) } |
|---|
| 558 | |
|---|
| 559 | .t pack .c1 -side top -anchor w |
|---|
| 560 | .t pack .c2 -side top -anchor w |
|---|
| 561 | </pre> |
|---|
| 562 | |
|---|
| 563 | <h2><a name="installation"> INSTALLATION</a></h2> |
|---|
| 564 | <p> |
|---|
| 565 | mkWidgets is written in pure Tcl/Tk (version 8) and does not contain any other |
|---|
| 566 | package dependencies. |
|---|
| 567 | </p> |
|---|
| 568 | <p> |
|---|
| 569 | To install, place the directory "mkWidgets1.3" in one of the directories contained in |
|---|
| 570 | the global Tcl variable "auto_path". For a standard Tcl/Tk installation, this is commonly |
|---|
| 571 | "c:/program files/tcl/lib" (Windows) and "/usr/local/lib" (Unix). |
|---|
| 572 | </p> |
|---|
| 573 | |
|---|
| 574 | <h2><a name="changes"> CHANGES</a></h2> |
|---|
| 575 | <p> |
|---|
| 576 | Changes from 1.0 to 1.2 |
|---|
| 577 | </p> |
|---|
| 578 | <ul> |
|---|
| 579 | <li>Eliminated dependency to mkGeneric and mkClasses</li> |
|---|
| 580 | <li>Added the <em>metawidget export</em> feature</li> |
|---|
| 581 | <li>Significantly extented the metawidgets collection</li> |
|---|
| 582 | <li>Fixed some bugs</li> |
|---|
| 583 | </ul> |
|---|
| 584 | <p> |
|---|
| 585 | Changes from 1.2 to 1.3 |
|---|
| 586 | </p> |
|---|
| 587 | <ul> |
|---|
| 588 | <li>Fixed various bugs. Thanks much to all who contributed!</li> |
|---|
| 589 | <li>Added the <em>names</em> member to the Toolbar metawidget</li> |
|---|
| 590 | <li>Added an always visible position indicator when a Pane is being dragged</li> |
|---|
| 591 | <li>Made the Combobox metawidget behave better</li> |
|---|
| 592 | <li>Document windows cannot be moved outside their parent anymore</li> |
|---|
| 593 | <li>A Document window now remembers its former position when deiconified</li> |
|---|
| 594 | <li>The mouse cursor changes to arrows over the border of a Document window</li> |
|---|
| 595 | <li>Improved the Arrange class function of the Document metawidget</li> |
|---|
| 596 | <li>Added <em>column exists</em> to Listcontrol and Gridcontrol metawidgets</li> |
|---|
| 597 | <li>Names for tags, icons, columns, nodes are now list-protected and may contain white spaces</li> |
|---|
| 598 | <li><em>winfo class <i>metawidget</i></em> now returns the correct class, but...</li> |
|---|
| 599 | <li>Had to restrict the allowed values for the <em>-type<em> option of the metawidget command to <em>frame</em> and <em>toplevel</em></li> |
|---|
| 600 | </ul> |
|---|
| 601 | |
|---|
| 602 | <h2><a name="author"> AUTHOR</a></h2> |
|---|
| 603 | <p> |
|---|
| 604 | Michael Kraus<br/> |
|---|
| 605 | <a href="mailto:michael@kraus5.de">mailto:michael@kraus5.de</a><br/> |
|---|
| 606 | <a href="http://mkextensions.sourceforge.net">http://mkextensions.sourceforge.net</a><br/> |
|---|
| 607 | </p> |
|---|
| 608 | </body> |
|---|
| 609 | |
|---|
| 610 | </html> |
|---|