packages feed

intricacy-0.4.1: KeyBindings.hs

-- This file is part of Intricacy
-- Copyright (C) 2013 Martin Bays <mbays@sdf.org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of version 3 of the GNU General Public License as
-- published by the Free Software Foundation, or any later version.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see http://www.gnu.org/licenses/.

module KeyBindings (KeyBindings, bindings, findBindings, findBinding, showKey, showKeyFriendly) where

import Data.Maybe
import Data.Char
import Data.List

import Command
import Hex
import GameStateTypes
import InputMode

type KeyBindings = [ (Char,Command) ]

ctrl, unctrl :: Char -> Char
ctrl c = toEnum $ fromEnum c - 64
unctrl c = toEnum $ fromEnum c + 64

lowerToo :: KeyBindings -> KeyBindings
lowerToo = concat . map addLower
    where addLower b@(c, cmd) = [ b, (toLower c, cmd) ]

qwertyViHex =
    [ ('l', CmdDir WHSHook hu)
    , ('h', CmdDir WHSHook $ neg hu)
    , ('b', CmdDir WHSHook hw)
    , ('u', CmdDir WHSHook $ neg hw)
    , ('y', CmdDir WHSHook hv)
    , ('n', CmdDir WHSHook $ neg hv)
    , ('L', CmdDir WHSWrench hu)
    , ('H', CmdDir WHSWrench $ neg hu)
    , ('B', CmdDir WHSWrench hw)
    , ('U', CmdDir WHSWrench $ neg hw)
    , ('Y', CmdDir WHSWrench hv)
    , ('N', CmdDir WHSWrench $ neg hv)
    , ('k', CmdRotate WHSHook 1)
    , ('j', CmdRotate WHSHook $ -1)
    ]
qwertyLeftHex =
    [ ('d', CmdDir WHSHook hu)
    , ('a', CmdDir WHSHook $ neg hu)
    , ('z', CmdDir WHSHook hw)
    , ('e', CmdDir WHSHook $ neg hw)
    , ('w', CmdDir WHSHook hv)
    , ('x', CmdDir WHSHook $ neg hv)
    , ('D', CmdDir WHSWrench hu)
    , ('A', CmdDir WHSWrench $ neg hu)
    , ('Z', CmdDir WHSWrench hw)
    , ('E', CmdDir WHSWrench $ neg hw)
    , ('W', CmdDir WHSWrench hv)
    , ('X', CmdDir WHSWrench $ neg hv)
    , ('q', CmdRotate WHSHook 1)
    , ('c', CmdRotate WHSHook $ -1)
    , ('S', CmdWait)
    , ('s', CmdWait)
    ]
dvorakMidHex =
    [ ('i', CmdDir WHSWrench hu)
    , ('e', CmdDir WHSWrench $ neg hu)
    , ('j', CmdDir WHSWrench hw)
    , ('y', CmdDir WHSWrench $ neg hw)
    , ('p', CmdDir WHSWrench hv)
    , ('k', CmdDir WHSWrench $ neg hv)
    ]

keypadHex =
    [ ('5', CmdWait)
    , ('6', CmdDir WHSSelected hu)
    , ('4', CmdDir WHSSelected $ neg hu)
    , ('1', CmdDir WHSSelected hw)
    , ('9', CmdDir WHSSelected $ neg hw)
    , ('7', CmdDir WHSSelected hv)
    , ('3', CmdDir WHSSelected $ neg hv)
    , ('8', CmdRotate WHSSelected 1)
    , ('2', CmdRotate WHSSelected $ -1)
    ]

miscLockGlobal = lowerToo
    [ ('X', CmdUndo)
    , ('\b', CmdUndo)
    , ('R', CmdRedo)
    , (ctrl 'R', CmdRedo)
    , (ctrl 'U', CmdUndo)
    , ('^', CmdReset)
    , ('.', CmdWait)
    , ('Z', CmdWait)
    , ('M', CmdMark)
    , ('\'', CmdJumpMark)
    ]

miscGlobal = lowerToo
    [ ('Q', CmdQuit)
    , (ctrl 'C', CmdQuit)
    , ('?', CmdHelp)
    , (ctrl 'B', CmdBind)
    , (ctrl 'L', CmdRedraw)
    , (ctrl 'Z', CmdSuspend)
    , ('%', CmdToggleColourMode)
    ]

lockGlobal = keypadHex ++ qwertyViHex ++ miscGlobal ++ miscLockGlobal

playOnly = lowerToo
    [ ('O', CmdOpen)
    , (' ', CmdWait)
    , ('\r', CmdWait)
    , ('\n', CmdWait)
    , ('\t', CmdToggle)
    , ('*', CmdTile $ WrenchTile zero)
    , ('/', CmdTile HookTile)
    , ('@', CmdTile HookTile)
    ]
replayOnly =
    [ (' ', CmdReplayForward 1)
    ]
editMisc = lowerToo
    [ ('P', CmdPlay)
    , (' ', CmdSelect)
    , ('\r', CmdSelect)
    , ('\n', CmdSelect)
    , ('T', CmdTest)
    , ('W', CmdWriteState)
    , (ctrl 'S', CmdWriteState)
    , ('=', CmdMerge)
    , ('+', CmdMerge)
    , ('&', CmdMerge)
    , ('0', CmdDelete)
    , ('E', CmdDelete)
    ]
tilesPaintRow = lowerToo
    [ ('G', CmdTile BallTile)
    , ('F', CmdTile $ ArmTile zero False)
    , ('D', CmdTile $ PivotTile zero)
    , ('S', CmdTile $ SpringTile Relaxed zero)
    , ('A', CmdTile $ BlockTile [])
    , ('Z', CmdDelete)
    ]
tilesAscii =
    [ ('o', CmdTile $ PivotTile zero)
    , ('O', CmdTile BallTile)
    , ('S', CmdTile $ SpringTile Relaxed zero)
    --, ('s', CmdTile $ SpringTile Stretched zero)
    --, ('$', CmdTile $ SpringTile Compressed zero)
    , ('-', CmdTile $ ArmTile zero False)
    --, ('-', CmdTile $ ArmTile hu False)
    , ('\\', CmdTile $ ArmTile hv False)
    , ('/', CmdTile $ ArmTile hw False)
    , ('@', CmdTile HookTile)
    , ('*', CmdTile $ WrenchTile zero)
    , ('#', CmdTile $ BlockTile [])
    ]
editOnly = tilesPaintRow ++ editMisc ++ tilesAscii

playBindings = playOnly ++ lockGlobal
replayBindings = replayOnly ++ lockGlobal
editBindings = editOnly ++ lockGlobal
metaBindings = lowerToo
    [ ('C', CmdSelCodename Nothing)
    , ('H', CmdHome)
    , ('B', CmdBackCodename)
    , ('S', CmdSolve Nothing)
    , ('D', CmdDeclare Nothing)
    , ('V', CmdViewSolution Nothing)
    , ('R', CmdRegister)
    , ('P', CmdPlaceLock Nothing)
    , ('E', CmdEdit)
    , ('L', CmdSelectLock)
    , ('O', CmdPrevLock)
    , ('N', CmdNextLock)
    , ('A', CmdAuth)
    , ('T', CmdTutorials)
    , ('+', CmdShowRetired)
    , ('#', CmdPlayLockSpec Nothing)
    , ('$', CmdSetServer)
    , ('^', CmdToggleCacheOnly)
    , ('>', CmdNextPage)
    , ('<', CmdPrevPage)
    ] ++ miscGlobal

bindings :: InputMode -> KeyBindings
bindings IMEdit = editBindings
bindings IMPlay = playBindings
bindings IMMeta = metaBindings
bindings IMReplay = replayBindings
bindings _ = []

findBindings :: KeyBindings -> Command -> [Char]
findBindings bdgs cmd = nub
    $ [ ch | (ch,cmd') <- bdgs, cmd'==cmd ]
    ++ [ ch | CmdInputChar ch <- [cmd] ]

findBinding :: KeyBindings -> Command -> Maybe Char
findBinding = (listToMaybe.) . findBindings

showKey ch | isPrint ch = [ch]
showKey ch | isPrint (unctrl ch) = ('^':[unctrl ch])
showKey _ = "[?]"

showKeyFriendly ' ' = "space"
showKeyFriendly '\r' = "return"
showKeyFriendly '\n' = "newline"
showKeyFriendly '\t' = "tab"
showKeyFriendly '\b' = "bksp"
showKeyFriendly ch = showKey ch