packages feed

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.