Allure-0.4.2: src/Keys.hs
module Keys where
import Prelude hiding (Left, Right)
import qualified Data.Map as M
import qualified Data.List as L
import Data.Char
import Data.Maybe
import Geometry
import Dir
-- TODO: if the file grows much larger, split it and move a part to Utils/
-- | Frontend-independent datatype to represent keys.
data Key =
Esc
| Return
| Tab
| PgUp
| PgDn
| Left
| Right
| Up
| Down
| End
| Begin
| Home
| KP !Char -- ^ a keypad key for a character (digits and operators)
| Char !Char -- ^ a single printable character
| Unknown !String -- ^ an unknown key, collected to warn the user later
deriving (Ord, Eq)
showKey :: Key -> String
showKey (Char ' ') = "<space>" -- warnings about "command ( )" look wrong
showKey (Char c) = [c]
showKey Esc = "ESC" -- these three are common and terse abbreviations
showKey Return = "RET"
showKey Tab = "TAB"
showKey PgUp = "<page-up>"
showKey PgDn = "<page-down>"
showKey Left = "<left>"
showKey Right = "<right>"
showKey Up = "<up>"
showKey Down = "<down>"
showKey End = "<end>"
showKey Begin = "<begin>"
showKey Home = "<home>"
showKey (KP c) = "<KeyPad " ++ [c] ++ ">"
showKey (Unknown s) = s
instance Show Key where
show = showKey
dirChars :: [Char]
dirChars = ['y', 'k', 'u', 'l', 'n', 'j', 'b', 'h']
dirKeys :: [Key]
dirKeys = map Char dirChars
dirUKeys :: [Key]
dirUKeys = map (Char . toUpper) dirChars
-- | Maps a keypad movement key to the canonical form.
-- Hard-coded not to bloat config files.
canonMoveKey :: Key -> Key
canonMoveKey =
let assocs = (Begin, Char '.') : (KP '5', Char '.') :
zip [Home, Up, PgUp, Right, PgDn, Down, End, Left] dirKeys ++
zip (map KP ['7', '8', '9', '6', '3', '2', '1', '4']) dirUKeys
m = M.fromList assocs
in \ e -> fromMaybe e (M.lookup e m)
-- | Configurable event handler for the direction keys. Is used to
-- handle player moves, but can also be used for directed commands
-- such as close door.
handleDirection :: X -> Key -> (Dir -> a) -> a -> a
handleDirection lxsize e h k =
let assocs = zip dirKeys (moves lxsize)
in maybe k h (L.lookup e assocs)
-- | Configurable event handler for the upper direction keys.
handleUDirection :: X -> Key -> (Dir -> a) -> a -> a
handleUDirection lxsize e h k =
let assocs = zip dirUKeys (moves lxsize)
in maybe k h (L.lookup e assocs)
-- | Translate key from a GTK string description to our internal key type.
-- To be used, in particular, for the macros in the config file.
keyTranslate :: String -> Key
keyTranslate "less" = Char '<'
keyTranslate "greater" = Char '>'
keyTranslate "period" = Char '.'
keyTranslate "colon" = Char ':'
keyTranslate "comma" = Char ','
keyTranslate "space" = Char ' '
keyTranslate "question" = Char '?'
keyTranslate "dollar" = Char '$'
keyTranslate "asterisk" = Char '*'
keyTranslate "KP_Multiply" = Char '*'
keyTranslate "slash" = Char '/'
keyTranslate "KP_Divide" = Char '/'
keyTranslate "underscore" = Char '_'
keyTranslate "minus" = Char '-'
keyTranslate "KP_Subtract" = Char '-'
keyTranslate "Escape" = Esc
keyTranslate "Return" = Return
keyTranslate "Tab" = Tab
keyTranslate "KP_Up" = Up
keyTranslate "KP_Down" = Down
keyTranslate "KP_Left" = Left
keyTranslate "KP_Right" = Right
keyTranslate "KP_Home" = Home
keyTranslate "KP_End" = End
keyTranslate "KP_Page_Up" = PgUp
keyTranslate "KP_Page_Down" = PgDn
keyTranslate "KP_Begin" = Begin
keyTranslate "KP_Enter" = Return
keyTranslate ['K','P','_',c] = KP c
keyTranslate [c] = Char c
keyTranslate s = Unknown s