# TIP 324: A Standard Dialog For Font Selection
	Author:         Adrian Robert <adrian.b.robert@gmail.com>
	Author:         Daniel A. Steffen <das@users.sourceforge.net>
	State:          Final
	Type:           Project
	Vote:           Done
	Created:        08-Aug-2008
	Post-History:   
	Keywords:       Tk
	Obsoletes:      213
	Tcl-Version:    8.6
	Tk-Ticket:      1477426
-----

# Abstract

This TIP proposes the addition of a font selection dialog to the set of common
dialogs already available in Tk. Where possible, this dialog will be
implemented using the host platform's standard dialogs.

# Rationale

A number of platforms \(including Windows and Mac OS X\) have standard dialogs
for common user-oriented tasks, for which Tk provides an interface via commands
such as **tk\_getOpenFile** and **tk\_chooseColor**.
Another dialog that these platforms provide and which some Tk programs would
find useful is a _standard font selector_.
This TIP proposes adding a command to Tk to allow access to the platform
font selection dialog where available, or to a dialog implemented in Tcl
otherwise.

Unlike the existing dialog commands, the new font dialog command will not
return a result, as on some platforms \(Mac OS X\) the standard font dialog is
modeless while on others \(Windows\) it is modal. To accommodate this difference,
all user interaction with the dialog will be communicated to the caller via
callbacks or virtual events. To emphasize this difference in operation between
the new command and the existing Tk dialog commands the proposed name is **tk
fontchooser** instead of e.g. **tk\_chooseFont**.

# Proposal

Tk shall have a new command ensemble **tk fontchooser** with the following
syntax:

 > **tk fontchooser configure** ?_-option value -option value ..._?

set or query one or more of the configurations options below \(analogous to Tk
widget configuration\).

 > **tk fontchooser show**

show the font selection dialog. Depending on the platform, may return
immediately or only once the dialog has been withdrawn.

 > **tk fontchooser hide**

hide the font selection dialog if it is visible and cause any pending
**tk fontchooser show** command to return.

## Configuration Options

 -parent: specifies/returns the parent window of the font selection dialog
 \(similar to the _-parent_ option to other dialogs\).

 -title: specifies/returns the title of the dialog. Has no effect on platforms
 where the font selection dialog does not support titles.

 -font: specifies/returns the font that is currently selected in the dialog if
 it is visible, or that will be initially selected when the dialog is shown \(if
 supported by the platform\). Can be set to the empty string to indicate that no
 font should be selected. Fonts can be specified in any form given by the "FONT
 DESCRIPTION" section in font\(n\).

 -command: specifies/returns the command prefix to be called when a font
 selection has been made by the user. The command prefix is evaluated at the
 global level after having the specification of the selected font appended. On
 platforms where the font selection dialog offers the user control of further
 font attributes \(such as color\), additional key/value pairs may be appended
 before evaluation. Can be set to the empty string to indicate that no callback
 should be invoked. Fonts are specified by a list of form [[3]](3.md) of the "FONT
 DESCRIPTION" section in font\(n\) \(i.e. a list of the form _\{family size style
 ?style ...?\}_\).

 -visible: read-only option that returns a boolean indicating whether the font
 selection dialog is currently visible. Attempting to set this option results
 in an error.

## Events

<<TkFontchooserVisibility>>

 > virtual event sent to the dialog parent whenever the visibility of the font
 selection dialog changes, both as a result of user action \(e.g. disposing of
 the dialog via OK/Cancel button or close box\) and of the **tk fontchooser
 show/hide** commands being called. Binding scripts can determine the current
 visibility of the dialog by querying the _-visible_ configuration option.

<<TkFontchooserFontChanged>>

 > virtual event sent to the dialog parent whenever the font selection dialog
 is visible and the selected font changes, both as a result of user action and
 of the _-font_ configuration option being set. Binding scripts can determine
 the currently selected font by querying the _-font_ configuration option.

# Notes

Whenever a platform provides a suitable font dialog in its  API, Tk
shall not use a script-based alternative, even if this means missing
out on features like the title or dynamic updating of the font during
the selection process. This will help to ensure Tk applications meet
platform-specific user-interface design guidelines.

Callers should not expect a result from **tk fontchooser show** and may not
assume that the dialog has been withdrawn or closed when the command returns.
All user interaction with the dialog is communicated to the caller via the
_-command_ callback and the _<<TkFontchooser\*>>_ virtual events. It is
implementation dependent which exact user actions result in the callback being
called resp. the virtual events being sent. Where an Apply or OK button is
present in the dialog, it is expected for that button to trigger the
_-command_ callback and _<<TkFontchooserFontChanged>>_ virtual event.
However, on some implementations other user actions may also have that effect;
on Mac OS X for instance, the standard font selection dialog immediately
reflects all user choices to the caller.

In the presence of multiple widgets intended to be influenced by the font
selection dialog, care needs to be taken to correctly handle focus changes: the
font selected in the dialog should always match the current font of the widget
with the focus, and the _-command_ callback should only act on the widget
with the focus. The recommended practice is to set font dialog _-font_ and
_-command_ configuration options in per-widget _<FocusIn>_ handlers \(and if
necessary to unset them - i.e. set to the empty string - in corresponding
_<FocusOut>_ handlers\). This is particularly important for implementors of
library code using the font selection dialog, to avoid conflicting with
application code that may also want to use the dialog.

Because the font selection dialog is application-global, in the presence of
multiple interpreters calling **tk fontchooser**, only the _-command_
callback set by the interpreter that most recently called **tk fontchooser
configure** or **tk fontchooser show** will be invoked in response to user
action and only the _-parent_ set by that interpreter will receive
_<<TkFontchooser\*>>_ virtual events.

The font dialog implementation may only store \(and return\) **font actual**
data as the value of the _-font_ configuration option. This can be an issue
when _-font_ is set to a named font, if that font is subsequently changed,
the font dialog _-font_ option needs to be set again to ensure its selected
font matches the new value of the named font.

# Example

The following example demonstrates the recommended practice of updating the
font dialog configuration with the focus:

	 proc tip324demo {} {
	     wm title . "TIP324 Demo"
	     tk fontchooser configure -parent .
	     button .b -command fcToggle -takefocus 0; fcVisibility .b
	     bind . <<TkFontchooserVisibility>> [list fcVisibility .b]
	     foreach w {.t1 .t2} {
	         text $w -width 20 -height 4 -borderwidth 1 -relief solid
	         bind $w <FocusIn> [list fcFocus $w]
	         $w insert end "Text Widget $w"
	     }
	     .t1 configure -font {Courier 14}
	     .t2 configure -font {Times 16}
	     pack .b .t1 .t2; focus .t1
	 }
	 proc fcToggle {} {
	     tk fontchooser [expr {[tk fontchooser configure -visible] ?
	             "hide" : "show"}]
	 }
	 proc fcVisibility {w} {
	     $w configure -text [expr {[tk fontchooser configure -visible] ?
	             "Hide Font Dialog" : "Show Font Dialog"}]
	 }
	 proc fcFocus {w} {
	     tk fontchooser configure -font [$w cget -font] -command [list fcFont $w]
	 }
	 proc fcFont {w font args} {
	     $w configure -font [font actual $font]
	 }
	 tip324demo

# Alternatives

[[213]](213.md) was an earlier proposal for a font selection dialog API, it was withdrawn
when it became clear that it was incompatible with platforms where the standard
font dialog is modeless.

Alternative names for the new command have been proposed: **tk::choosefont**,
**tk::chooseFont**, **tk::fontChooser**, **tk\_chooseFont**.

# Reference Implementation

Tk Patch 1477426
<http://sourceforge.net/support/tracker.php?aid=1477426> 

# Copyright

This document has been placed in the public domain.

