% vim: set tw=72: % Part of Hetris \section{The user interface module (UI)} The user interface is the most obvious case where multiple implementations are sensible. User interfaces are one of the less well developed areas in the Haskell community, but the new FFI allows us to easily and portably define a Haskell interface to curses. We don't show the actual interface here, but it should be easy to understand from the C documentation; the \hsmodule{Curses} module exports it. While as far as the game is concerned the user interface is a single idea, the input and output aspects are really completely separate in curses. We therefore split the functionality off into separate modules which are both imported by \hsmodule{UI}. The initialisation and shutdown functions come under neither category so we leave them in the main module. \begin{code} module UI (init_ui, shutdown_ui, make_board, get_event, do_changes) where import Data import UI.HSCurses.Curses (initScr, cBreak, echo, keypad, cursSet, CursorVisibility(..), endWin) import Input import Output \end{code} The actual initialisation work is standard curses startup stuff: we initialise the curses system, enter cbreak mode (disable line buffering etc) and turn off echoing in common with the vast majority of curses programs. We also enable the keypad mode so that we can use the arrow keys to control the movement of the active piece. Finally we ask for the cursor to be invisible. The maximum board size depends on how the board is drawn, and the logic for that is in the \hsmodule{Output} module. We therefore have that module export a function that gives this maximum size and we return that value. \begin{code} init_ui :: IO (Vector, Vector) init_ui = do w <- initScr cBreak True echo False keypad w True cursSet CursorInvisible max_size \end{code} Shutting the interface down is rather simpler---we just call the curses shutdown function. \begin{code} shutdown_ui :: IO () shutdown_ui = do _ <- endWin return () \end{code}