# jtkutils.tcl

## Introduction

The jtkutils.tcl library file is distributed as part of the jstools package. It consists of procedures useful in constructing dialogue boxes and laying out userinterface components, convenience procedures for working with the selection, procedures to help support session management, and procedures for setting fonts.

This document describes jtkutils.tcl version 2001.02.10.

## Usage

### Accessing the Library

In order to use the jtkutils.tcl library, it (and any other libraries it depends on) must be in your Tcl `auto_path`, described in `tclvars`(n). Information about how to arrange that, and other conventions common to the jstools libraries, is in the Usage section of The jstools Libraries.

## Credits and Copyright

### Author

Jay Sekora
`js@aq.org`
`http://www.aq.org/~js/`

### Copyright

The library is copyright © 1992-2001 by Jay Sekora, but may be freely redistributed under the conditions at the top of the file.

## Overview

### Procedures

`::jstools::wm_client` - set the session client hostname
`::jstools::wm_command` - set the session client command
`::jstools::new_toplevel` - create a new toplevel, avoiding name conflicts
`::jstools::selection_if_any` - return selection if it exists, else {}
`::jstools::no_selection` - true if there is no selection
`::jstools::beep` - flash a widget and/or ring the X display's bell
`::jstools::default_button` - bind Return to default button
`::jstools::cancel_button` - set up bindings for cancel button
`::jstools::dialogue` - position a toplevel near center of screen
`::jstools::dialog` - alias for `::jstools::dialogue`
`::jstools::rule` - return a frame widget suitable for use as a divider
`::jstools::filler` - return a frame widget suitable for use as a spacer
`::jstools::configure_font` - configure widget with font from list, or default`
` `::jstools::configure_tag_font` - configure text tag with font from list, or default
`::jstools::active_window` - return or set the most recent active window
`::jstools::jwinfo` - manipulate properties associated with windows
`::jstools::tlinfo` - manipulate properties associated with windows

### See Also

jinit.tcl

## ::jstools::wm_client

### Usage

`::jstools::wm_client` [hostname]

### Arguments

hostname, if specified, is the machine to claim to be running on

### Description

This procedure is normally called without arguments, in which case it tries to determine the name of the machine the current application is running on, and sets that as the X `client' machine, for the use of session managers. If hostname is specified, that will be set as the X client hostname.

This procedure tries to determine the hostname by looking in several places for the Unix `hostname`(1) command; if it can't find `hostname`(1), it will set the client hostname to ``localhost`'.

## ::jstools::wm_command

### Usage

`::jstools::wm_command` [command]

### Arguments

command, if specified, is the command line to register

### Example

`global argv0
::jstools::wm_command [list $argv0 +$line $filename]`

### Description

This procedure is normally called without arguments, in which case it sets the X client command (used by session managers) to the command line that was used to invoke the current application, as best it can determine, using the Tcl variables `argv0` and `argv`. (For details of these variables, see the `wish`(1) or `tclsh`(1) manual pages.) If command is specified, it will be used instead. (It should have proper Tcl list structure, so the `list`(n) or `concat`(n) command is likely to be useful.)

## ::jstools::new_toplevel

### Usage

`::jstools::new_toplevel` prefix`` [args]

### Arguments

prefix will be the initial part of the new toplevel widget
args, if any, are configuration options for the new toplevel

###
Example

`set tl [::jstools::new_toplevel .notice]
message $tl.msg -text $text
button $tl.b -text OK -command [list destroy $tl]
pack $tl.msg $tl.b -fill x`

### Description

This procedure creates a new toplevel widget with a name that won't conflict with any existing widget. It does this by taking the prefix (which must start with a period) and adding the lowest possible integer suffix to it that will not produce the name of a widget that already exists. For instance, if you specify prefix as `.more` and no window named `.more0` already exists, the new window will be named `more0`. The name of the created window is returned.

## ::jstools::selection_if_any

### Usage

`::jstools::selection_if_any`

### Description

This convenience procedure, from R. James Noble `<kjx@comp.vuw.ac.nz>`, returns the selection if there is one, and the empty string `{}` otherwise.

## ::jstools::no_selection

### Description

This procedure returns true (`1`) if there is no current selection, and false (0) if there is a valid selection. It's useful as a test before doing `selection get` or manipulating the selection. Note that `::jstools::no_selection` will be true if there's an X selection, even if it's not in the current application.

## ::jstools::beep

### Usage

`::jstools::beep` widget

### Argument

widget is the widget to call the user's attention to

### Description

This procedure tries to get the user's attention, either by briefly flashes a widget, reversing the foreground and background colours (if `J_PREFS(visiblebell)` is true), or by ringing the X display's bell (if `J_PREFS(audiblebell)` is true), or both.

Ideally, the widget argument should name a widget with distinct background and foreground colours for the visible bell to work; `::jstools::beep` tries to do something reasonable with widgets that don't have both a foreground and a background colour, but it won't work in every case.

## ::jstools::default_button

### Usage

`::jstools::default_button` button`` widget...

### Arguments

button is the path name of the Cancel button
widget... are a series of widgets that can get keyboard focus, to bind to

### Example

`::jstools::default_button .buttons.call .name.entry .phone.entry`

### Description

This procedure arranges a keyboard shortcut for pressing a default button. The widget arguments are widgets that might get the keyboard focus. For each widget, the Return key is bound so as to invoke button. Typically, you'd create a panel with a default button, and possibly some entry and/or text widgets, and invoke `::jstools::default_button` listing all the entry and text widgets. You can also use focus to give the keyboard focus to the toplevel widget, and specify it instead (or as well).

## ::jstools::cancel_button

### Usage

`::jstools::cancel_button` button`` widget...

### Arguments

button is the path name of the Cancel button
widget... are a series of widgets that can get keyboard focus, to bind to

### Description

This procedure arranges several keyboard shortcuts for pressing a Cancel button. The widget arguments are widgets that might get the keyboard focus. For each widget, Control-c, Control-g, Meta-q, Meta-period, and Escape are bound so as to invoke button. Typically, you'd create a panel with a Cancel button and some entry and/or text widgets, and invoke `::jstools::cancel_button` listing all the entry and text widgets. You can also use `focus` to give the keyboard focus to the toplevel widget, and specify it instead (or as well).

## ::jstools::dialogue

## ::jstools::dialog

### Usage

`::jstools::dialogue` widget

### Argument

widget is the toplevel widget to position

### Description

This (probably misnamed) procedure simply positions a toplevel, widget, near the middle of the screen (centred halfway across, and onethird down from the top), and raises it. It only takes effect if the global variable `J_PREFS(autoposition)` is true (`1`); otherwise it lets the window manager position it. (A window manager will typically ask the user to position the new window with the mouse.) If you use `::j::read_standard_prefs` (in jprefs.tcl) and `::j::global_pref_panel` (in jprefpanel.tcl), your users can choose whether they want dialogue panels autopositioned or not.

You can invoke this procedure as either `::jstools::dialogue` or `::jstools::dialog`.

## ::jstools::rule

### Usage

`::jstools::rule` parent`` [args]

### Argument

parent is the widget you're packing the rule into

### Options

args are options to configure the appearance of the returned frame

### Examples

`pack \
$w.textbg \
[::jstools::rule $w] \
$w.textfg \
[::jstools::rule $w] \
$w.textsb \
[::jstools::rule $w] \
$w.textsf \
-in $w -fill x
pack \
.foo.title \
[::jstools::rule .foo -height 1 -background black] \
.foo.buttons \
-in .foo -side top -fill x -expand yes`

### Description

This procedure returns a thin sunken frame intended to be used as a `rule' - a narrow groove between other widgets. You typically use it in brackets directly in a `pack` command. By default, the frame returned is a 2x2 pixel square, but you typically specify either ``-fill x`' or ``-fill y`' when you pack it so that it gets stretched in one direction or the other. If you specify any args, they're used to configure the frame, so you can change its size (or other aspects of its appearance - you can make it raised instead of sunken, for instance, or change its color). You can also control its behaviour by arguments to the `pack` command.

## ::jstools::filler

### Usage

`::jstools::filler` parent`` [args]

### Argument

parent is the widget you're packing the filler into

### Options

args are options to configure the appearance of the returned frame

### Examples

`pack [::jstools::filler $w]
$w.name [::jstools::filler $w] $w.rgb \
[::jstools::filler $w] $w.patch [::jstools::filler $w] \
-in $w -side right
pack \
.foo.title \
[::jstools::filler .foo -height 25] \
.foo.buttons \
-in .foo -side top -fill x -expand yes`

### Description

This procedure returns a frame intended to be used as a `filler' - as padding to control the spacing between other widgets. You typically use it in brackets directly in a `pack` command. By default, the frame returned is a 10x10 pixel square. If you specify any args, they're used to configure the frame, so you can change its size. You can also control its behaviour by arguments to the `pack` command.

When its created, the filler is lowered to the bottom of the stacking order. This means that it will be below its parent, so if it's a different colour than its parent, it won't create a gap. (The simple way of thinking about this, without worrying about stacking orders and packing, is that the filler is invisible and the parent shows through.)

## ::jstools::hide_pointer

### Usage

`::jstools::hide_pointer` widget

### Argument

widget is the name of the widget whose mouse pointer is to be hid

### Description

This procedure hides the mouse pointer of widget, by setting it to a blank bitmap. It's useful so that the mouse pointer doesn't obscure text while the user is typing. It's called automatically by the standard jstools bindings libraries for text and entry widgets, but you can use it for other purposes as well.

## ::jstools::show_pointer

### Usage

`::jstools::show_pointer` widget

### Argument

widget is the name of the widget whose mouse pointer is to be restored

### Description

This procedure restores the mouse pointer of widget to the widget default. Note that that may not be the same as what it was before `::jstools::hide_pointer` was called. This should be called whenever the user moves the mouse after `::jstools::hide_pointer` has been called, so that the user can follow the mouse. It's called automatically by the standard jstools bindings libraries for text and entry widgets, but you can use it for other purposes as well.

## ::jstools::configure_font

### Usage

`::jstools::configure_font` widget`` fontlist

### Arguments

widget is the widget whose font you want to set
The first element of fontlist is the font to use (or ``default`')

### Examples

`::jstools::configure_font .t \
-*-lucidabright-medium-r-normal--*-100-75-75-*-100-*-*

::jstools::configure_font .t koi9

::jstools::configure_font .t default

`

### Description

This procedure configures widget to use the first font in fontlist. If that font is ``default`', then the X default font for widget will be used. If it is `{}` (the empty string), then 12-point Courier will be used.

The reason for the odd use of fontlist - and, in fact, for the existence of this procedure at all - is that in previous versions of Tk trying to configure a widget to use a font that didn't exist on the system was an error. This procedure provided a way to cycle through a series of fonts, using the first one that was available.

## ::jstools::configure_tag_font

### Usage

`::jstools::configure_tag_font` widget`` tag`` fontlist

### Arguments

widget is the text widget that tag is in
tag is the tag whose font you want to set
The first element of fontlist is the font to use (or ``default`')

### Example

`::jstools::configure_tag_font .t bold \
-*-garamond-bold-r-normal--*-120-*

::jstools::configure_tag_font .t code fixed

`

### Description

This procedure is very similar to `::jstools::configure_font`, but instead of setting the font of the entire widget, it sets the font for the particular tag tag in the text widget widget. See `::jstools::configure_font` for a description of how fontlist is used (and why it's interpreted the way it is).

## ::jstools::active_window

### Usage

`::jstools::active_window` [options]`` [w]

### Argument

w, if given, is the widget to set active

### Option

`-class` class`` (default `any`)

### Example

`bind Text <FocusIn> {::jstools::active_window %W}
` [...]`
proc capitalise {} {
set w [::jstools::active_window -class Text]
if {$w == "none"} {
::jstools::alert -text "No active window!"
} else {
set text [string toupper [$w get 1.0 end]]
$w delete 1.0 end
$w insert end $text
}
}`

### Description

This procedure is used to manage multiwindow or multidocument applications, where it's important to keep track of which window is currently active (e.g. so that future commands can be applied to it).

You should arrange to make a window active with `::jstools::active_window` whenever the user starts using it. For a text or entry widget, this might appropriately be done whenever the widget gains keyboard focus. For a canvas, you might do this whenever the user clicks in the canvas.

Any commands that should act upon the currentlyactive window (rather than being called with a specific window as an argument, or having a window path hardcoded into them) will use `::jstools::active_window` to find out what window to operate on.

If called with an argument w, `::jstools::active_window` records the fact that w is the current active window (and will remain so until a subsequent call to `::jstools::active_window`). It also records the fact that w is the current active window of its class, where that class typically corresponds to the Tk class of the window (i.e. its type: Text, Entry, Label, etc.) The class can be specified, however, so theoretically it need not correspond to a Tk window class.

If called without an argument w, and without class specified (or with class specified as ``any`'), it returns the name of the current or most recent active window (of any class). If no window has ever been active, it returns ``none`'.

If called with no argument w, but with class specified (as something other than ``any`'), it returns the name of the most recent (or current) active window of class class. If no window of class class has ever been active, it returns ``none`'.

## ::jstools::jwinfo

### Usage

`::jstools::jwinfo` w`` action`` [property]`` [value]

### Arguments

w is the window whose properties you're querying or setting
action is one of `get`, `set`, `defined`, `unset`, or `list`
property is an arbitrary property name
value is the value to set property to, or a default value for property

### Description

This procedure allows you to associate arbitrary properties with widget names. (For instance, if you have a widget whose contents can be saved, you might want to associate a filename with it.)

If action is `set`, then widget w's property named property is set to value (and value is returned).

If action is `get`, then if a property named property is defined for w, that property's current value is returned. Otherwise, value is returned (but property remains undefined for w).

If action is `defined`, then this procedure returns `1` (true) if a property named property is currently defined for w, and `0` (false) otherwise.

If action is `unset`, than the w's property named property is deleted.

If action is `list`, then this procedure returns a (possibly empty) list of all the properties currently defined for w.

If value is omitted, it defaults to the empty string, so ``::jstools::jwinfo .w get foo`' will return the empty string if the window `.w` doesn't currently have a `foo` property associated with it. The same is true of property, although I don't recommend this except with `list`.

## ::jstools::tlinfo

### Usage

`::jstools::tlinfo` w`` action`` [property]`` [value]

### Arguments

w is the window whose properties you're querying or setting
action is one of `get`, `set`, `defined`, `unset`, or `list`
property is an arbitrary property name
value is the value to set property to, or a default value for property

### Description

This procedure behaves identically to `::jstools::jwinfo`, except that instead of manipulating or querying properties associated with widget w, it manipulates or queries properties associated with w's toplevel widget. In all cases, a statement beginning ``::jstools::tlinfo` w`` ...' should behave identically with the corresponding statement beginning ``::jstools::jwinfo [winfo toplevel` w`]` ...'.

The `::jstools::tlinfo` command is provided as a convenience, because a multidocument application may find it easier to treat all the widgets within the toplevel window that represents a single document as a unit. Also, you can easily associate information to be used in bindings to a toplevel with that toplevel. (For instance, in a dialogue panel a different button might be the default depending on the state of a panel. You could use `::jstools::tlinfo` to record the name of the current default button, for use when the user presses Return.)

## Bugs and Misfeatures

- `::jstools::configure_font` and `::jstools::configure_tag_font` are relics; they don't currently do much useful. Originally, they cycled through a list of fonts, trying each until they found one that existed on the system. This was necessary since early versions of Tk treated a nonexistent font as an error. Under recent versions of Tk, however, configuring the font of a widget or text tag always succeeds, using the closest approximation Tk can find on the system to the requested font if the requested font isn't available. Therefore, the only useful thing these procedures do now is interpret `default` and `{}` specially.
- `::jstools::dialogue` is misnamed, since it can be used to centre any toplevel, and it doesn't affect the behaviour, function, or structure of the toplevel widget centred.

`
`