vty-ui-1.6: doc/ch4/FormattedText.tex
\section{Text}
\label{sec:text}
The \fw{Text} module provides a widget for rendering text strings in
user interfaces. The text widget type, \fw{Widget FormattedText}, can
be used to render simple strings or more complex text arrangements.
A \fw{FormattedText} widget can be created from a \fw{String} with the
\fw{plainText} function and can be laid out in the usual way:
\begin{haskellcode}
t1 <- plainText "blue" >>= withNormalAttribute (fgColor blue)
t2 <- plainText "green" >>= withNormalAttribute (fgColor green)
ui <- (return t1) <++> (return t2)
\end{haskellcode}
\subsection{Updating Text Widgets}
\label{sec:updatingText}
The contents of a text widget can be set in one of three ways:
\begin{itemize}
\item Initially, as a parameter to \fw{plainText} and \fw{textWidget}
\item As a \fw{Text} parameter to \fw{setText}
\item As a list parameter of \fw{(Text, Attr)} with
\fw{setTextWithAttrs}
\end{itemize}
All text widget update functions \textit{tokenize} their inputs,
finding contiguous sequences of whitespace and non-whitespace
characters and newlines, and store the list of tokens in the widget.
Each token is assigned a default attribute of \fw{def\_attr}, which
defaults to the ``normal'' attribute of the widget (see Section
\ref{sec:attributes} for more information on attributes).
The \fw{setText} function merely takes a \fw{Text} value, tokenizes
it, and assigns the default attribute to all tokens.
The \fw{setTextWithAttrs} function provides finer control over the
initial attribute assignment to the text because it lets you specify
the initial contents of the widget with your own attribute
assignments. This can be done instead of (or in addition to) the use
of formatters for maximum control over the final visual representation
of the text.
In the following example, we create a text widget and then assign it a
string with different attributes for each of the words:
\begin{haskellcode}
t <- plainText ""
setTextWithAttrs t [ ("foo", fgColor green)
, (" ", def_attr)
, ("bar", fgColor yellow)
, (" ", def_attr)
, ("baz", red `on` blue)
]
\end{haskellcode}
\subsection{Formatters}
In addition to rendering plain text strings, we can use ``formatters''
to change the arrangement and attributes of text. Formatters can
manipulate structure and attributes to change the text layout and
appearance.
To use a formatter with a text widget, we must use a different
constructor function, \fw{text\-Widget}:
\begin{haskellcode}
t <- textWidget someFormatter "foobar"
\end{haskellcode}
In addition, the formatter for a text widget can be set at any time
with \fw{set\-Text\-Formatter}:
\begin{haskellcode}
setTextFormatter t someFormatter
\end{haskellcode}
When a text widget's contents are updated, the text is automatically
broken up into tokens (see Section \ref{sec:updatingText}). It is
these tokens on which formatters operate.
The \fw{Text} module provides an example formatter called \fw{wrap}.
\fw{wrap} wraps the text to fit into the \fw{DisplayRegion} available
at rendering time, so this will end up doing the right thing depending
on the parent widget of the \fw{FormattedText} widget. Here is an
example using \fw{wrap}:
\begin{haskellcode}
t <- textWidget wrap "(some long text message)"
\end{haskellcode}
Formatters form a \fw{Monoid}, and we can use this functionality to
compose formatters:
\begin{haskellcode}
t <- textWidget (someFormatter `mappend` wrap) "Foo bar baz"
\end{haskellcode}
For detailed information on the token types on which the formatters
operate, see the \fw{Text.Trans.Tokenize} module.
\subsubsection{Growth Policy}
\fw{FormattedText} widgets do not grow horizontally or vertically.