module Graphics.Gloss.Internals.Interface.ViewPort.Motion
(callback_viewPort_motion)
where
import Graphics.Gloss.ViewPort
import Graphics.Gloss.Geometry.Angle
import Graphics.Gloss.Geometry.Vector
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 Control.Monad
import Data.IORef
callback_viewPort_motion
:: IORef ViewPort
-> IORef VPC.State
-> Callback
callback_viewPort_motion portRef controlRef
= Motion (viewPort_motion portRef controlRef)
viewPort_motion
portRef controlRef
pos
= do
translateMark <- controlRef `getsIORef` VPC.stateTranslateMark
rotateMark <- controlRef `getsIORef` VPC.stateRotateMark
(case translateMark of
Nothing -> return ()
Just (markX, markY)
-> motionTranslate
portRef controlRef
(fromIntegral markX, fromIntegral markY)
pos )
(case rotateMark of
Nothing -> return ()
Just (markX, markY)
-> motionRotate
portRef controlRef
(fromIntegral markX, fromIntegral markY)
pos )
motionTranslate
portRef controlRef
(markX, markY)
(GL.Position posX posY)
= do
(transX, transY)
<- portRef `getsIORef` viewPortTranslate
s <- portRef `getsIORef` viewPortScale
r <- portRef `getsIORef` viewPortRotate
let dX = fromIntegral $ markX posX
let dY = fromIntegral $ markY posY
let offset = (dX / s, dY / s)
let (oX, oY) = rotateV (degToRad r) offset
portRef `modifyIORef` \s -> s
{ viewPortTranslate
= ( transX oX
, transY + oY) }
controlRef `modifyIORef` \s -> s
{ VPC.stateTranslateMark
= Just (fromIntegral posX, fromIntegral posY) }
GLUT.postRedisplay Nothing
motionRotate
portRef controlRef
(markX, markY)
(GL.Position posX posY)
= do
rotate <- portRef `getsIORef` viewPortRotate
rotateFactor <- controlRef `getsIORef` VPC.stateRotateFactor
portRef `modifyIORef` \s -> s
{ viewPortRotate
= rotate + rotateFactor * fromIntegral (posX markX) }
controlRef `modifyIORef` \s -> s
{ VPC.stateRotateMark
= Just (fromIntegral posX, fromIntegral posY) }
GLUT.postRedisplay Nothing
getsIORef ref fun
= liftM fun $ readIORef ref