module Graphics.Gloss.Internals.Interface.ViewPort.KeyMouse
(callback_viewPort_keyMouse)
where
import Graphics.Gloss.ViewPort
import Graphics.Gloss.Geometry.Angle
import Graphics.Gloss.Geometry.Vector
import Graphics.Gloss.Internals.Interface.ViewPort.Command
import Graphics.Gloss.Internals.Interface.Callback
import qualified Graphics.Gloss.Internals.Interface.ViewPort.ControlState as VPC
import qualified Graphics.UI.GLUT as GLUT
import qualified Graphics.Rendering.OpenGL.GL as GL
import Data.IORef
import Control.Monad
callback_viewPort_keyMouse
:: IORef ViewPort
-> IORef VPC.State
-> Callback
callback_viewPort_keyMouse portRef controlRef
= KeyMouse (viewPort_keyMouse portRef controlRef)
viewPort_keyMouse portRef controlRef key keyState keyMods pos
= do commands <- controlRef `getsIORef` VPC.stateCommands
viewPort_keyMouse2 commands portRef controlRef key keyState keyMods pos
viewPort_keyMouse2
commands portRef controlRef
key keyState keyMods
pos
| isCommand commands CRestore key keyMods
, keyState == GLUT.Down
= do portRef `modifyIORef` \s -> s
{ viewPortScale = 1
, viewPortTranslate = (0, 0)
, viewPortRotate = 0 }
GLUT.postRedisplay Nothing
| isCommand commands CBumpZoomOut key keyMods
, keyState == GLUT.Down
= controlZoomOut portRef controlRef
| isCommand commands CBumpZoomIn key keyMods
, keyState == GLUT.Down
= controlZoomIn portRef controlRef
| isCommand commands CBumpLeft key keyMods
, keyState == GLUT.Down
= motionBump portRef controlRef (20, 0)
| isCommand commands CBumpRight key keyMods
, keyState == GLUT.Down
= motionBump portRef controlRef (20, 0)
| isCommand commands CBumpUp key keyMods
, keyState == GLUT.Down
= motionBump portRef controlRef (0, 20)
| isCommand commands CBumpDown key keyMods
, keyState == GLUT.Down
= motionBump portRef controlRef (0, 20)
| isCommand commands CBumpClockwise key keyMods
, keyState == GLUT.Down
= do portRef `modifyIORef` \s -> s {
viewPortRotate
= (\r -> r + 5)
$ viewPortRotate s }
GLUT.postRedisplay Nothing
| isCommand commands CBumpCClockwise key keyMods
, keyState == GLUT.Down
= do portRef `modifyIORef` \s -> s {
viewPortRotate
= (\r -> r 5)
$ viewPortRotate s }
GLUT.postRedisplay Nothing
| isCommand commands CTranslate key keyMods
, keyState == GLUT.Down
= do let GL.Position posX posY = pos
controlRef `modifyIORef` \s -> s {
VPC.stateTranslateMark
= Just ( fromIntegral posX
, fromIntegral posY) }
GLUT.postRedisplay Nothing
| isCommand commands CTranslate key keyMods
, keyState == GLUT.Up
= do controlRef `modifyIORef` \s -> s {
VPC.stateTranslateMark = Nothing }
GLUT.postRedisplay Nothing
| isCommand commands CRotate key keyMods
, keyState == GLUT.Down
= do let GL.Position posX posY = pos
controlRef `modifyIORef` \s -> s {
VPC.stateRotateMark
= Just ( fromIntegral posX
, fromIntegral posY) }
GLUT.postRedisplay Nothing
| isCommand commands CRotate key keyMods
, keyState == GLUT.Up
= do controlRef `modifyIORef` \s -> s {
VPC.stateRotateMark = Nothing }
GLUT.postRedisplay Nothing
| otherwise
= return ()
controlZoomIn portRef controlRef
= do scaleStep <- controlRef `getsIORef` VPC.stateScaleStep
portRef `modifyIORef` \s -> s {
viewPortScale = viewPortScale s * scaleStep }
GLUT.postRedisplay Nothing
controlZoomOut portRef controlRef
= do scaleStep <- controlRef `getsIORef` VPC.stateScaleStep
portRef `modifyIORef` \s -> s {
viewPortScale = viewPortScale s / scaleStep }
GLUT.postRedisplay Nothing
motionBump
portRef controlRef
(bumpX, bumpY)
= do
(transX, transY)
<- portRef `getsIORef` viewPortTranslate
s <- portRef `getsIORef` viewPortScale
r <- portRef `getsIORef` viewPortRotate
let offset = (bumpX / s, bumpY / s)
let (oX, oY) = rotateV (degToRad r) offset
portRef `modifyIORef` \s -> s
{ viewPortTranslate
= ( transX oX
, transY + oY) }
GLUT.postRedisplay Nothing
getsIORef ref fun
= liftM fun $ readIORef ref