brillo-2.0.0: Brillo/Internals/Interface/Backend/Types.hs
{-# OPTIONS -fspec-constr-count=5 #-}
{-# LANGUAGE Rank2Types #-}
module Brillo.Internals.Interface.Backend.Types (
module Brillo.Internals.Interface.Backend.Types,
module Brillo.Data.Cursor,
module Brillo.Data.Display,
)
where
import Brillo.Data.Cursor
import Brillo.Data.Display
import Brillo.Data.FileDialog (FileDialog)
import Data.IORef (IORef)
{-| The functions every backend window managed backend needs to support.
The Backend module interfaces with the window manager, and handles opening
and closing the window, and managing key events etc.
It doesn't know anything about drawing lines or setting colors.
When we get a display callback, Brillo will perform OpenGL actions, and
the backend needs to have OpenGL in a state where it's able to accept them.
-}
class Backend a where
{-| Initialize the state used by the backend.
If you don't use any state, make a Unit-like type.
-}
initBackendState :: a
{-| Perform any initialization that needs to happen before opening a window
The Boolean flag indicates if any debug information should be printed to
the terminal
-}
initializeBackend :: IORef a -> Bool -> IO ()
-- | Perform any deinitialization and close the backend.
exitBackend :: IORef a -> IO ()
-- | Open a window with the given display mode.
openWindow :: IORef a -> Display -> IO ()
-- | Dump information about the backend to the terminal.
dumpBackendState :: IORef a -> IO ()
-- | Install the display callbacks.
installDisplayCallback :: IORef a -> [Callback] -> IO ()
-- | Install the window close callback.
installWindowCloseCallback :: IORef a -> IO ()
-- | Install the reshape callbacks.
installReshapeCallback :: IORef a -> [Callback] -> IO ()
-- | Install the refresh callback (called during live resize on macOS).
installRefreshCallback :: IORef a -> [Callback] -> IO ()
-- | Install the keymouse press callbacks.
installKeyMouseCallback :: IORef a -> [Callback] -> IO ()
-- | Install the mouse motion callbacks.
installMotionCallback :: IORef a -> [Callback] -> IO ()
-- | Install the file/directory drop callbacks.
installDropCallback :: IORef a -> [Callback] -> IO ()
-- | Install the idle callbacks.
installIdleCallback :: IORef a -> [Callback] -> IO ()
-- | The mainloop of the backend.
runMainLoop :: IORef a -> IO ()
-- | A function that signals that screen has to be updated.
postRedisplay :: IORef a -> IO ()
-- | Function that returns (width,height) of the window in pixels.
getWindowDimensions :: IORef a -> IO (Int, Int)
-- | Function that returns (width,height) of a fullscreen window in pixels.
getScreenSize :: IORef a -> IO (Int, Int)
-- | Open a file dialog to pick files/directories.
openFileDialog :: IORef a -> FileDialog -> IO (Maybe [FilePath])
{-| Function that reports the time elapsed since the application started.
(in seconds)
-}
elapsedTime :: IORef a -> IO Double
-- | Function that puts the current thread to sleep for 'n' seconds.
sleep :: IORef a -> Double -> IO ()
-- | Set the cursor shape for the window.
setCursor :: IORef a -> CursorShape -> IO ()
-- The callbacks should work for all backends. We pass a reference to the
-- backend state so that the callbacks have access to the class dictionary and
-- can thus call the appropriate backend functions.
-- | Display callback has no arguments.
type DisplayCallback =
forall a. (Backend a) => IORef a -> IO ()
-- | Arguments: KeyType, Key Up \/ Down, Ctrl \/ Alt \/ Shift pressed, latest mouse location.
type KeyboardMouseCallback =
forall a.
(Backend a) =>
IORef a ->
Key ->
KeyState ->
Modifiers ->
(Int, Int) ->
IO ()
-- | No arguments.
type IdleCallback =
forall a. (Backend a) => IORef a -> IO ()
-- | Arguments: (PosX,PosY) in pixels.
type MotionCallback =
forall a. (Backend a) => IORef a -> (Int, Int) -> IO ()
-- | Arguments: [FilePath] of dropped files.
type DropCallback =
forall a. (Backend a) => IORef a -> [FilePath] -> IO ()
-- | Arguments: (Width,Height) in pixels.
type ReshapeCallback =
forall a. (Backend a) => IORef a -> (Int, Int) -> IO ()
-------------------------------------------------------------------------------
data Callback
= Display DisplayCallback
| KeyMouse KeyboardMouseCallback
| Idle IdleCallback
| Motion MotionCallback
| Drop DropCallback
| Reshape ReshapeCallback
-- | Check if this is an `Idle` callback.
isIdleCallback :: Callback -> Bool
isIdleCallback cc =
case cc of
Idle _ -> True
_ -> False
-------------------------------------------------------------------------------
-- This is Brillo's view of mouse and keyboard events.
-- The actual events provided by the backends are converted to this form
-- by the backend module.
data Key
= Char Char
| SpecialKey SpecialKey
| MouseButton MouseButton
deriving (Show, Eq, Ord)
data MouseButton
= LeftButton
| MiddleButton
| RightButton
| WheelUp
| WheelDown
| AdditionalButton Int
deriving (Show, Eq, Ord)
data KeyState
= Down
| Up
deriving (Show, Eq, Ord)
data SpecialKey
= KeyUnknown
| KeySpace
| KeyEsc
| KeyF1
| KeyF2
| KeyF3
| KeyF4
| KeyF5
| KeyF6
| KeyF7
| KeyF8
| KeyF9
| KeyF10
| KeyF11
| KeyF12
| KeyF13
| KeyF14
| KeyF15
| KeyF16
| KeyF17
| KeyF18
| KeyF19
| KeyF20
| KeyF21
| KeyF22
| KeyF23
| KeyF24
| KeyF25
| KeyUp
| KeyDown
| KeyLeft
| KeyRight
| KeyTab
| KeyEnter
| KeyBackspace
| KeyInsert
| KeyNumLock
| KeyBegin
| KeyDelete
| KeyPageUp
| KeyPageDown
| KeyHome
| KeyEnd
| KeyShiftL
| KeyShiftR
| KeyCtrlL
| KeyCtrlR
| KeyAltL
| KeyAltR
| KeyPad0
| KeyPad1
| KeyPad2
| KeyPad3
| KeyPad4
| KeyPad5
| KeyPad6
| KeyPad7
| KeyPad8
| KeyPad9
| KeyPadDivide
| KeyPadMultiply
| KeyPadSubtract
| KeyPadAdd
| KeyPadDecimal
| KeyPadEqual
| KeyPadEnter
deriving (Show, Eq, Ord)
data Modifiers
= Modifiers
{ shift :: KeyState
, ctrl :: KeyState
, alt :: KeyState
}
deriving (Show, Eq, Ord)