packages feed

brillo-2.0.0: Brillo/Internals/Interface/Event.hs

{-# LANGUAGE RankNTypes #-}

module Brillo.Internals.Interface.Event (
  Event (..),
  keyMouseEvent,
  motionEvent,
  dropEvent,
  pickEvent,
)
where

import Brillo.Internals.Interface.Backend
import Data.IORef


-- | Possible input events.
data Event
  = EventKey Key KeyState Modifiers (Float, Float)
  | EventMotion (Float, Float)
  | EventResize (Int, Int)
  | EventDrop [FilePath]
  | EventPick [FilePath]
  deriving (Eq, Show)


keyMouseEvent ::
  forall a.
  (Backend a) =>
  IORef a ->
  Key ->
  KeyState ->
  Modifiers ->
  (Int, Int) ->
  IO Event
keyMouseEvent backendRef key keyState modifiers pos =
  EventKey key keyState modifiers <$> convertPoint backendRef pos


motionEvent ::
  forall a.
  (Backend a) =>
  IORef a ->
  (Int, Int) ->
  IO Event
motionEvent backendRef pos =
  EventMotion <$> convertPoint backendRef pos


dropEvent ::
  forall a.
  (Backend a) =>
  IORef a ->
  [FilePath] ->
  IO Event
dropEvent _backendRef paths =
  return $ EventDrop paths


pickEvent ::
  forall a.
  (Backend a) =>
  IORef a ->
  [FilePath] ->
  IO Event
pickEvent _backendRef paths =
  return $ EventPick paths


convertPoint ::
  forall a.
  (Backend a) =>
  IORef a ->
  (Int, Int) ->
  IO (Float, Float)
convertPoint backendRef pos =
  do
    (sizeX_, sizeY_) <- getWindowDimensions backendRef
    let (sizeX, sizeY) = (fromIntegral sizeX_, fromIntegral sizeY_)

    let (px_, py_) = pos
    let px = fromIntegral px_
    let py = sizeY - fromIntegral py_

    let px' = px - sizeX / 2
    let py' = py - sizeY / 2
    let pos' = (px', py')
    return pos'