aboutsummaryrefslogtreecommitdiff
path: root/src/Chelleport.hs
blob: be4f3aca95e2608514736742ec87311d20138adb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module Chelleport where

import Chelleport.AppShell (setupAppShell)
import qualified Chelleport.AppState as AppState
import Chelleport.Context (initializeContext)
import Chelleport.Control (anyAlphanumeric, anyDigit, checkKey, ctrl, eventToKeycode, hjklDirection, key, pressed, released, shift)
import Chelleport.KeySequence (keycodeToInt, toKeyChar)
import Chelleport.Types
import Chelleport.Utils ((<||>))
import qualified Chelleport.View
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Reader (ReaderT (runReaderT))
import Data.Maybe (fromMaybe)
import qualified SDL

run :: IO ()
run = do
  ctx <- initializeContext
  runAppWithCtx ctx $
    setupAppShell
      ctx
      AppState.initialState
      AppState.update
      eventHandler
      Chelleport.View.render
  where
    runAppWithCtx :: (MonadIO m) => DrawContext -> AppM m x -> m x
    runAppWithCtx ctx = (`runReaderT` ctx) . runAppM

eventHandler :: State -> SDL.Event -> Maybe AppAction
eventHandler state event = do
  let hjkl = key SDL.KeycodeH <||> key SDL.KeycodeJ <||> key SDL.KeycodeK <||> key SDL.KeycodeL
  case SDL.eventPayload event of
    SDL.QuitEvent -> Just ShutdownApp
    SDL.KeyboardEvent ev
      -- Esc: Quit
      | checkKey [key SDL.KeycodeEscape, pressed] ev -> Just ShutdownApp
      -- <C-s>: Enable search mode
      | checkKey [ctrl, key SDL.KeycodeS, pressed] ev -> Just $ SetMode defaultSearchMode
      -- <C-t>: Enable hints mode
      | checkKey [ctrl, key SDL.KeycodeT, pressed] ev -> Just $ SetMode defaultHintsMode
      -- <C-n>, <C-p>: Search increment next/prev
      | checkKey [ctrl, key SDL.KeycodeN, pressed] ev -> Just $ IncrementHighlightIndex (stateRepetition state)
      | checkKey [ctrl, key SDL.KeycodeP, pressed] ev -> Just $ IncrementHighlightIndex (-1 * stateRepetition state)
      -- <C-hjkl>: Movement
      | checkKey [ctrl, hjkl, pressed] ev ->
          MoveMouseInDirection . hjklDirection <$> toKeyChar (eventToKeycode ev)
      -- Space / Shift+Space : Left click/chain left click
      | checkKey [key SDL.KeycodeSpace, pressed] ev ->
          if shift ev
            then Just $ ChainMouseClick LeftClick
            else Just $ TriggerMouseClick LeftClick
      -- Backspace: Reset keys
      | checkKey [key SDL.KeycodeBackspace, pressed] ev -> Just ResetKeys
      -- <C-v>: Toggle mouse dragging
      | checkKey [ctrl, key SDL.KeycodeV, pressed] ev -> Just MouseDragToggle
      -- minus / underscore: Right click/chain right click
      | checkKey [key SDL.KeycodeMinus <||> key SDL.KeycodeUnderscore, pressed] ev ->
          if shift ev
            then Just $ ChainMouseClick RightClick
            else Just $ TriggerMouseClick RightClick
      -- 0-9: Repetition digit
      | checkKey [anyDigit, pressed] ev ->
          Just $ UpdateRepetition (fromMaybe 0 $ keycodeToInt $ eventToKeycode ev)
      -- A-Z
      | checkKey [anyAlphanumeric, pressed] ev -> Just $ HandleKeyInput $ eventToKeycode ev
      -- Shift press/release: Toggle shift mode
      | checkKey [pressed, key SDL.KeycodeRShift <||> key SDL.KeycodeLShift] ev -> Just $ UpdateShiftState True
      | checkKey [released, key SDL.KeycodeRShift <||> key SDL.KeycodeLShift] ev -> Just $ UpdateShiftState False
    _ -> Nothing