vty-ui-1.8: doc/ch3/widgetimpl_api.tex
\section{The \fw{WidgetImpl} API}
\label{sec:widgetimpl_api}
The \fw{WidgetImpl} type is the type of widget implementations. You
have already seen some of its fields in previous sections.
\begin{haskellcode}
data WidgetImpl a = WidgetImpl {
state :: a
, visibie :: Bool
, render_ :: Widget a -> DisplayRegion -> RenderContext
-> IO Image
, growHorizontal_ :: a -> IO Bool
, growVertical_ :: a -> IO Bool
, setCurrentPosition_ :: Widget a -> DisplayRegion -> IO ()
, getCursorPosition_ :: Widget a -> IO (Maybe DisplayRegion)
, focused :: Bool
, currentSize :: DisplayRegion
, currentPosition :: DisplayRegion
, normalAttribute :: Attr
, focusAttribute :: Attr
, keyEventHandler :: Widget a -> Key -> [Modifier] -> IO Bool
, gainFocusHandlers :: Handlers (Widget a)
, loseFocusHandlers :: Handlers (Widget a)
}
\end{haskellcode}
The \fw{WidgetImpl} functions are similar to many top-level functions.
Whenever a \fw{Wid\-get\-Impl} function ends with an underscore, there
is a top-level function with the same name without the underscore that
you should use to invoke the respective functionality on any widget
reference you hold. We will see many examples of this convention in
this chapter.
The following fields are managed automatically and should not be
overridden by widget implementors but are explained here for
completeness:
\begin{itemize}
\item \fw{focused} -- \fw{True} if this widget is focused. As
explained in Section \ref{sec:focus}, although one widget has the
user's focus, internally many widgets may share it in a hierarchy.
\item \fw{visible} -- \fw{True} if this widget is visible. Visible
widgets will be rendered as usual, but invisible widgets
automatically render to empty images and do not grow horizontally or
vertically. This field can be manipulated with \fw{setVisible} and
read with \fw{getVisible}.
\item \fw{currentSize} -- the ``current'' size of the widget, i.e.,
the size of the \fw{Image} \textit{after} the last time the widget
was rendered.
\item \fw{currentPosition} -- the ``current'' position of the widget's
upper-left corner, i.e., the position of the widget's upper-left
corner \textit{after} the last time the widget was rendered.
Sometimes used when positioning child widgets and when positioning
the cursor, if any.
\item \fw{normalAttribute} -- the widget's normal attribute. Defaults
to Vty's \fw{defAttr} value, which merges transparently with the
\fw{RenderContext}'s normal attribute.
\item \fw{focusAttribute} -- the widget's focus attribute. Defaults
to Vty's \fw{defAttr} value, which merges transparently with the
\fw{RenderContext}'s focus attribute.
\item \fw{keyEventHandler} -- the action responsible for handling key
events for this widget. The default implementation merely starts
calling the sequence of user-registered key event handlers; it is
strongly recommended that you \textit{not} replace this, but use
\fw{onKeyPressed} to register key handlers instead.
\item \fw{gainFocusHandlers} -- the actions responsible for handling
the widget's focus gain event. You can add your own handlers with
\fw{onGainFocus} as described in Section \ref{sec:focus}. For more
information about event handling and the \fw{Handlers} type, see
Section \ref{sec:event_handlers}.
\item \fw{loseFocusHandlers} -- the actions responisible for handling
the widget's focus loss event. You can add your own handlers with
\fw{onLoseFocus} as described in Section \ref{sec:focus}. For more
information about event handling and the \fw{Handlers} type, see
Section \ref{sec:event_handlers}.
\end{itemize}
The following fields are important to widget implementors and,
depending on widget requirements, need to be overridden:
\begin{itemize}
\item \fw{state} -- the state of the widget as described in Section
\ref{sec:new_widget_type}. Use the \fw{getState} function to read
this state and use the \fw{updateWidgetState} function to modify it.
\item \fw{render\_} -- the rendering routine for the widget. If this
widget wraps child widgets, this function is responsible for
rendering them and composing the resulting \fw{Image}s into a final
\fw{Image}.
\item \fw{growHorizontal\_} -- the \textit{horizontal growth policy
function}. See Section \ref{sec:growth_policy_functions}.
\item \fw{growVertical\_} -- the \textit{vertical growth policy
function}. See Section \ref{sec:growth_policy_functions}.
\item \fw{setCurrentPosition\_} -- this function is used to set the
current position -- the position of the upper-left corner -- of the
widget. This is included in the \fw{WidgetImpl} API so that you can
override it if your widget wraps others or has special logic for
setting their positions. See Section \ref{sec:widget_positioning}.
\item \fw{getCursorPosition\_} -- this function may be used to
indicate that this widget should display a cursor when it has the
focus. The way that it does this is by returning a
\fw{DisplayRegion}. The default implementation returns
\fw{Nothing}, which indicates that the widget does not want to
position the cursor. For implementations which do show the cursor,
the returned position should be relative to the position returned by
\fw{getCurrentPosition}. See Section \ref{sec:cursor_positioning}.
\end{itemize}
We've already introduced the \fw{state} and \fw{render\_} functions.
Now we'll go into detail on the use of the other functions.