aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--specs/Specs/KeySequenceSpec.hs17
-rw-r--r--src/Chelleport.hs26
-rw-r--r--src/Chelleport/KeySequence.hs20
3 files changed, 52 insertions, 11 deletions
diff --git a/specs/Specs/KeySequenceSpec.hs b/specs/Specs/KeySequenceSpec.hs
index 570f1f9..d094741 100644
--- a/specs/Specs/KeySequenceSpec.hs
+++ b/specs/Specs/KeySequenceSpec.hs
@@ -1,6 +1,6 @@
module Specs.KeySequenceSpec where
-import Chelleport.KeySequence (generateKeyCells, nextChars)
+import Chelleport.KeySequence (findMatchPosition, generateKeyCells, nextChars)
import Test.Hspec
test = do
@@ -37,3 +37,18 @@ test = do
["HJA", "HJB", "LJA", "LJB"],
["HJA", "HJB", "LJA", "LJB"]
]
+
+ describe "#findMatchPosition" $ do
+ it "returns the position of the matching key sequence" $ do
+ findMatchPosition "ABD" [["XYZ", "ABC"], ["AMK", "BBL", "ABD"]]
+ `shouldBe` Just (1, 2)
+
+ context "when sequence is incomplete" $ do
+ it "returns nothing" $ do
+ findMatchPosition "AB" [["XYZ", "ABC"], ["AMK", "BBL", "ABD"]]
+ `shouldBe` Nothing
+
+ context "when there are no matches" $ do
+ it "returns nothing" $ do
+ findMatchPosition "FOO" [["XYZ", "ABC"], ["AMK", "BBL", "ABD"]]
+ `shouldBe` Nothing
diff --git a/src/Chelleport.hs b/src/Chelleport.hs
index 74c61e7..4f6aa7b 100644
--- a/src/Chelleport.hs
+++ b/src/Chelleport.hs
@@ -2,11 +2,12 @@ module Chelleport where
import Chelleport.AppShell (Action (AppAction, SysQuit), DrawContext (ctxWindow), setupAppShell)
import Chelleport.Draw (colorLightGray, colorWhite, renderText)
-import Chelleport.KeySequence (eventToKeycode, generateKeyCells, isValidKey, nextChars, toKeyChar)
+import Chelleport.KeySequence (eventToKeycode, findMatchPosition, generateKeyCells, isValidKey, nextChars, toKeyChar)
import Control.Monad (forM_, unless, void)
import Data.IORef (modifyIORef', newIORef, readIORef)
import Data.List (isPrefixOf)
import qualified Data.Text as Text
+import Foreign.C (CInt (CInt))
import qualified SDL
import Unsafe.Coerce (unsafeCoerce)
@@ -20,12 +21,6 @@ data AppAction = FilterSequence SDL.Keycode | SetupGrid
open :: IO ()
open = setupAppShell initialState update eventToAction render
-padded :: Int -> a -> [a] -> [a]
-padded 0 _ ls = ls
-padded n x ls
- | length ls > n = ls
- | otherwise = padded (n - 1) x (ls ++ [x])
-
initialState :: DrawContext -> IO State
initialState _ctx = do
let cells = generateKeyCells (rows, columns) hintKeys
@@ -64,11 +59,22 @@ render state ctx = do
update :: State -> DrawContext -> AppAction -> IO State
update state _ctx SetupGrid = pure state
-update state _ctx (FilterSequence key) =
+update state ctx (FilterSequence key) =
case validChars >>= (\chars -> (,chars) <$> toKeyChar key) of
Just (keyChar, validChars')
- | keyChar `elem` validChars' ->
- pure state {stateKeySequence = stateKeySequence state ++ [keyChar]}
+ | keyChar `elem` validChars' -> do
+ (SDL.V2 width height) <- SDL.get $ SDL.windowSize $ ctxWindow ctx :: IO (SDL.V2 CInt)
+ let newKeySequence = stateKeySequence state ++ [keyChar]
+ let rows = stateCells state
+ let wcell = width `div` unsafeCoerce (length $ head rows)
+ let hcell = height `div` unsafeCoerce (length rows)
+ case findMatchPosition newKeySequence rows of
+ Just (row, col) -> do
+ let x = wcell * unsafeCoerce col
+ let y = hcell * unsafeCoerce row
+ SDL.warpMouse SDL.WarpGlobal (SDL.P $ SDL.V2 x y)
+ Nothing -> pure ()
+ pure state {stateKeySequence = newKeySequence}
_ -> pure state
where
validChars = nextChars (stateKeySequence state) (stateCells state)
diff --git a/src/Chelleport/KeySequence.hs b/src/Chelleport/KeySequence.hs
index 88658f1..1046a98 100644
--- a/src/Chelleport/KeySequence.hs
+++ b/src/Chelleport/KeySequence.hs
@@ -2,8 +2,15 @@ module Chelleport.KeySequence where
import Data.List (isPrefixOf, nub)
import qualified Data.Map as Map
+import Data.Maybe (isJust)
import qualified SDL
+-- padded :: Int -> a -> [a] -> [a]
+-- padded 0 _ ls = ls
+-- padded n x ls
+-- | length ls > n = ls
+-- | otherwise = padded (n - 1) x (ls ++ [x])
+
safeHead :: a -> [a] -> a
safeHead def [] = def
safeHead _ (x : _) = x
@@ -17,6 +24,19 @@ nextChars keys cells =
matches = concatMap (filter (isPrefixOf keys)) cells
result = concatMap (take 1 . drop (length keys)) matches
+findMatchPosition :: [Char] -> [[[Char]]] -> Maybe (Int, Int)
+findMatchPosition keys = findWithIndex findMatch 0
+ where
+ findMatch row =
+ fst <$> findWithIndex (\c -> if c == keys then Just () else Nothing) 0 row
+
+ findWithIndex :: (x -> Maybe r) -> Int -> [x] -> Maybe (Int, r)
+ findWithIndex _pred _index [] = Nothing
+ findWithIndex predicate index (x : ls) =
+ case predicate x of
+ Just item -> Just (index, item)
+ Nothing -> findWithIndex predicate (index + 1) ls
+
isValidKey :: SDL.Keycode -> Bool
isValidKey key = Map.member key keycodeMapping