-- This file is part of Intricacy -- Copyright (C) 2013 Martin Bays -- -- 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 Nothing) , (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