\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#324: A Standard Dialog For Font Selection}
\date{August 08, 2008}
\author{Adrian Robert, Daniel A. Steffen}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#324}&\textbf{A Standard Dialog For Font Selection}\\\hline
Author&

Adrian Robert \tipmail{adrian.b.robert}{gmail.com}
\par
Daniel A. Steffen \tipmail{das}{users.sourceforge.net}
\\
Created&Friday, \(\text{8}^{\text{th}}\) August 2008\\
Type&Project\\
Tcl Version&\(8.6\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.7 $\\
Keywords&Tk\\
Obsoletes&213\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

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.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{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 \textbf{tk\_getOpenFile} and \textbf{tk\_chooseColor}. Another dialog that these platforms provide and which some Tk programs would find useful is a \textit{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 \textbf{tk fontchooser} instead of e.g. \textbf{tk\_chooseFont}.

\section{Proposal}

Tk shall have a new command ensemble \textbf{tk fontchooser} with the following syntax:

\begin{quote}
\textbf{tk fontchooser configure} ?\textit{-option value -option value ...}?
\end{quote}

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

\begin{quote}
\textbf{tk fontchooser show}
\end{quote}

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

\begin{quote}
\textbf{tk fontchooser hide}
\end{quote}

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

\subsection{Configuration Options}
\begin{description}
\item[-parent]
specifies/returns the parent window of the font selection dialog (similar to the \textit{-parent} option to other dialogs).
\item[-title]
specifies/returns the title of the dialog. Has no effect on platforms where the font selection dialog does not support titles.
\item[-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).
\item[-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] of the ``FONT DESCRIPTION'' section in font(n) (i.e. a list of the form \textit{\{family size style ?style ...?\}}).
\item[-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.
\end{description}

\subsection{Events}

\tiplangle{}\tiplangle{}TkFontchooserVisibility\tiprangle{}\tiprangle{}

\begin{quote}
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 \textbf{tk fontchooser show/hide} commands being called. Binding scripts can determine the current visibility of the dialog by querying the \textit{-visible} configuration option.
\end{quote}

\tiplangle{}\tiplangle{}TkFontchooserFontChanged\tiprangle{}\tiprangle{}

\begin{quote}
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 \textit{-font} configuration option being set. Binding scripts can determine the currently selected font by querying the \textit{-font} configuration option.
\end{quote}

\section{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 \textbf{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 \textit{-command} callback and the \textit{\tiplangle{}\tiplangle{}TkFontchooser*\tiprangle{}\tiprangle{}} 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 \textit{-command} callback and \textit{\tiplangle{}\tiplangle{}TkFontchooserFontChanged\tiprangle{}\tiprangle{}} 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 \textit{-command} callback should only act on the widget with the focus. The recommended practice is to set font dialog \textit{-font} and \textit{-command} configuration options in per-widget \textit{\tiplangle{}FocusIn\tiprangle{}} handlers (and if necessary to unset them --- i.e. set to the empty string --- in corresponding \textit{\tiplangle{}FocusOut\tiprangle{}} 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 \textbf{tk fontchooser}, only the \textit{-command} callback set by the interpreter that most recently called \textbf{tk fontchooser configure} or \textbf{tk fontchooser show} will be invoked in response to user action and only the \textit{-parent} set by that interpreter will receive \textit{\tiplangle{}\tiplangle{}TkFontchooser*\tiprangle{}\tiprangle{}} virtual events.

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

\section{Example}

The following example demonstrates the recommended practice of updating the font dialog configuration with the focus:
\begingroup\small\begin{verbatim}
 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
\end{verbatim}
\endgroup

\section{Alternatives}

\cite{tip213} 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: \textbf{tk::choosefont}, \textbf{tk::chooseFont}, \textbf{tk::fontChooser}, \textbf{tk\_chooseFont}.

\section{Reference Implementation}

Tk Patch 1477426 [\url{http://sourceforge.net/support/tracker.php?aid=1477426}]

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\begin{thebibliography}{TIP \#1}
\addcontentsline{toc}{section}{References}
\bibitem[TIP \#213]{tip213}
Donal K. Fellows,
Pat Thoyts,
\emph{A Standard Dialog for Font Selection},
on-line at \url{http://purl.org/tcl/tip/213.html}
\end{thebibliography}
\end{document}
