{-# LANGUAGE UnicodeSyntax, FlexibleContexts #-}
module GraphRewriting.GL.Canvas (setupCanvas) where

import Prelude.Unicode
import qualified Graphics.UI.GLUT as GL
import Graphics.Rendering.OpenGL (($=))
import GraphRewriting.Graph
import GraphRewriting.Graph.Read
import GraphRewriting.Pattern
import qualified GraphRewriting.Graph.Write.Unsafe as Unsafe
import GraphRewriting.GL.Render
import GraphRewriting.GL.Global
import Data.IORef
import GraphRewriting.Layout.Rotation
import GraphRewriting.Layout.Position
import qualified Data.Set as Set
import Data.Functor ()
import Data.Maybe (catMaybes, listToMaybe)
import Data.Vector.Class


setupCanvas  (View Position n, Render n', View Rotation n', View Position n')
             (Graph n  Graph n')  (Edge  [n']  [(Vector2, Vector2)])  IORef (GlobalVars n)  IO GL.Window
setupCanvas :: forall n n'.
(View Position n, Render n', View Rotation n', View Position n') =>
(Graph n -> Graph n')
-> (Edge -> [n'] -> [(Vector2, Vector2)])
-> IORef (GlobalVars n)
-> IO Window
setupCanvas Graph n -> Graph n'
project Edge -> [n'] -> [(Vector2, Vector2)]
hyperEdgeToLines IORef (GlobalVars n)
globalVars = do
	Window
canvas  String -> IO Window
forall (m :: * -> *). MonadIO m => String -> m Window
GL.createWindow String
"Graph"
	StateVar (Color4 GLfloat)
GL.clearColor StateVar (Color4 GLfloat) -> Color4 GLfloat -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
StateVar (Color4 GLfloat) -> Color4 GLfloat -> m ()
$= (GLfloat -> GLfloat -> GLfloat -> GLfloat -> Color4 GLfloat
forall a. a -> a -> a -> a -> Color4 a
GL.Color4 GLfloat
1 GLfloat
1 GLfloat
1 GLfloat
0  GL.Color4 GL.GLclampf)
	StateVar GLfloat
GL.lineWidth StateVar GLfloat -> GLfloat -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
StateVar GLfloat -> GLfloat -> m ()
$= GLfloat
2
	IORef GLdouble
aspect  GLdouble -> IO (IORef GLdouble)
forall a. a -> IO (IORef a)
newIORef GLdouble
1
	IORef (Vector3 GLdouble)
focus   Vector3 GLdouble -> IO (IORef (Vector3 GLdouble))
forall a. a -> IO (IORef a)
newIORef (Vector3 GLdouble -> IO (IORef (Vector3 GLdouble)))
-> Vector3 GLdouble -> IO (IORef (Vector3 GLdouble))
forall a b. (a -> b) -> a -> b
$ GLdouble -> GLdouble -> GLdouble -> Vector3 GLdouble
forall a. a -> a -> a -> Vector3 a
GL.Vector3 GLdouble
0 GLdouble
0 GLdouble
0
	IORef GLdouble
zoom    GLdouble -> IO (IORef GLdouble)
forall a. a -> IO (IORef a)
newIORef (GLdouble
1  GL.GLdouble)
	Node -> Rewrite n ()
origLayoutStep  GlobalVars n -> Node -> Rewrite n ()
forall n. GlobalVars n -> Node -> Rewrite n ()
layoutStep (GlobalVars n -> Node -> Rewrite n ())
-> IO (GlobalVars n) -> IO (Node -> Rewrite n ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
	(Node -> Rewrite n ())
-> IORef GLdouble
-> IORef (Vector3 GLdouble)
-> IORef GLdouble
-> (Graph n -> Graph n')
-> (Edge -> [n'] -> [(Vector2, Vector2)])
-> IORef (GlobalVars n)
-> IO ()
forall {n} {n}.
(Render n, View Rotation n, View Position n, View Position n) =>
(Node -> Rewrite n ())
-> IORef GLdouble
-> IORef (Vector3 GLdouble)
-> IORef GLdouble
-> (Graph n -> Graph n)
-> (Edge -> [n] -> [(Vector2, Vector2)])
-> IORef (GlobalVars n)
-> IO ()
registerCallbacks Node -> Rewrite n ()
origLayoutStep IORef GLdouble
aspect IORef (Vector3 GLdouble)
focus IORef GLdouble
zoom Graph n -> Graph n'
project Edge -> [n'] -> [(Vector2, Vector2)]
hyperEdgeToLines IORef (GlobalVars n)
globalVars
	StateVar Cursor
GL.cursor StateVar Cursor -> Cursor -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
StateVar Cursor -> Cursor -> m ()
$= Cursor
GL.LeftArrow
	Window -> IO Window
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Window
canvas

registerCallbacks :: (Node -> Rewrite n ())
-> IORef GLdouble
-> IORef (Vector3 GLdouble)
-> IORef GLdouble
-> (Graph n -> Graph n)
-> (Edge -> [n] -> [(Vector2, Vector2)])
-> IORef (GlobalVars n)
-> IO ()
registerCallbacks Node -> Rewrite n ()
origLayoutStep IORef GLdouble
aspect IORef (Vector3 GLdouble)
focus IORef GLdouble
zoom Graph n -> Graph n
project Edge -> [n] -> [(Vector2, Vector2)]
hyperEdgeToLines IORef (GlobalVars n)
globalVars = do
	IO ()
autozoom
	SettableStateVar (IO ())
GL.displayCallback SettableStateVar (IO ()) -> IO () -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (IO ()) -> IO () -> m ()
$= IO ()
display
	SettableStateVar (Maybe ReshapeCallback)
GL.reshapeCallback SettableStateVar (Maybe ReshapeCallback)
-> Maybe ReshapeCallback -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe ReshapeCallback)
-> Maybe ReshapeCallback -> m ()
$= ReshapeCallback -> Maybe ReshapeCallback
forall a. a -> Maybe a
Just ReshapeCallback
reshape
	SettableStateVar (Maybe KeyboardMouseCallback)
GL.keyboardMouseCallback SettableStateVar (Maybe KeyboardMouseCallback)
-> Maybe KeyboardMouseCallback -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe KeyboardMouseCallback)
-> Maybe KeyboardMouseCallback -> m ()
$= KeyboardMouseCallback -> Maybe KeyboardMouseCallback
forall a. a -> Maybe a
Just KeyboardMouseCallback
forall {p}. Key -> KeyState -> p -> Position -> IO ()
inputCallback

	where

	zoomBy :: GLdouble -> IO ()
zoomBy GLdouble
factor = IORef GLdouble -> (GLdouble -> GLdouble) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef GLdouble
zoom (GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
* GLdouble
factor) IO () -> IO (GlobalVars n) -> IO (GlobalVars n)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars IO (GlobalVars n) -> (GlobalVars n -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Window -> IO ()
redisplay (Window -> IO ())
-> (GlobalVars n -> Window) -> GlobalVars n -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalVars n -> Window
forall n. GlobalVars n -> Window
canvas

	inputCallback :: Key -> KeyState -> p -> Position -> IO ()
inputCallback (GL.MouseButton MouseButton
GL.WheelUp)   KeyState
_ p
_ Position
_ = GLdouble -> IO ()
zoomBy GLdouble
1.1
	inputCallback (GL.MouseButton MouseButton
GL.WheelDown) KeyState
_ p
_ Position
_ = GLdouble -> IO ()
zoomBy GLdouble
0.9

	inputCallback (GL.MouseButton MouseButton
GL.RightButton) KeyState
GL.Down p
mod Position
pos = do
		IORef (GlobalVars n) -> IO ()
forall {n}. IORef (GlobalVars n) -> IO ()
pause IORef (GlobalVars n)
globalVars
		Maybe Node
node  Position -> IO (Maybe Node)
nodeAt Position
pos
		case Maybe Node
node of
			Maybe Node
Nothing  () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
			Just Node
n   do
				()
_  (\Int
idx  (Rule n -> Rule n) -> Int -> IORef (GlobalVars n) -> IO ()
forall n.
(Rule n -> Rule n) -> Int -> IORef (GlobalVars n) -> IO ()
applyLeafRules (Node -> Rule n -> Rule n
forall (m :: * -> *) n a.
Monad m =>
Node -> PatternT n m a -> PatternT n m a
nextIs Node
n) Int
idx IORef (GlobalVars n)
globalVars) (Int -> IO ()) -> (GlobalVars n -> Int) -> GlobalVars n -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalVars n -> Int
forall n. GlobalVars n -> Int
selectedRule (GlobalVars n -> IO ()) -> IO (GlobalVars n) -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
				IORef (GlobalVars n) -> IO ()
forall {n}. IORef (GlobalVars n) -> IO ()
highlight IORef (GlobalVars n)
globalVars

	inputCallback (GL.MouseButton MouseButton
GL.RightButton) KeyState
GL.Up p
mod (GL.Position GLsizei
x GLsizei
y) = IORef (GlobalVars n) -> IO ()
forall {n}. View Position n => IORef (GlobalVars n) -> IO ()
resume IORef (GlobalVars n)
globalVars

	inputCallback (GL.MouseButton MouseButton
GL.LeftButton) KeyState
GL.Up p
mod Position
pos = do
		IORef (GlobalVars n) -> (GlobalVars n -> GlobalVars n) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (GlobalVars n)
globalVars ((GlobalVars n -> GlobalVars n) -> IO ())
-> (GlobalVars n -> GlobalVars n) -> IO ()
forall a b. (a -> b) -> a -> b
$ \GlobalVars n
v  GlobalVars n
v {layoutStep = origLayoutStep}
		Int -> IO () -> IO ()
GL.addTimerCallback Int
50 (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ SettableStateVar (Maybe (Position -> IO ()))
GL.motionCallback SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> m ()
$= Maybe (Position -> IO ())
forall a. Maybe a
Nothing
	inputCallback (GL.MouseButton MouseButton
GL.LeftButton) KeyState
GL.Down p
mod Position
from = do
		Maybe Node
node  Position -> IO (Maybe Node)
nodeAt Position
from
		case Maybe Node
node of
			Maybe Node
Nothing  SettableStateVar (Maybe (Position -> IO ()))
GL.motionCallback SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> m ()
$= (Position -> IO ()) -> Maybe (Position -> IO ())
forall a. a -> Maybe a
Just (Position -> Position -> IO ()
scrollCallback Position
from)
			Just Node
n   do
				let fixN :: Node -> Rewrite n ()
fixN Node
node = if Node
n Node -> Node -> Bool
forall α. Eq α => α -> α -> Bool
 Node
node
					then do
						Vector2
pos  (Position -> Vector2) -> Node -> Rewrite n Vector2
forall v n (m :: * -> *) a.
(View v n, MonadReader (Graph n) m, MonadFail m) =>
(v -> a) -> Node -> m a
examineNode Position -> Vector2
position Node
node
						Node -> Rewrite n ()
origLayoutStep Node
node
						Node -> Position -> Rewrite n ()
forall v n. View v n => Node -> v -> Rewrite n ()
Unsafe.updateNode Node
node (Vector2 -> Position
Position Vector2
pos)
					else Node -> Rewrite n ()
origLayoutStep Node
node
				IORef (GlobalVars n) -> (GlobalVars n -> GlobalVars n) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (GlobalVars n)
globalVars ((GlobalVars n -> GlobalVars n) -> IO ())
-> (GlobalVars n -> GlobalVars n) -> IO ()
forall a b. (a -> b) -> a -> b
$ \GlobalVars n
v  GlobalVars n
v {layoutStep = fixN}
				SettableStateVar (Maybe (Position -> IO ()))
GL.motionCallback SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> m ()
$= (Position -> IO ()) -> Maybe (Position -> IO ())
forall a. a -> Maybe a
Just (Node -> Position -> IO ()
dragCallback Node
n)
		where
		dragCallback :: Node -> Position -> IO ()
dragCallback Node
n Position
to = do
			SettableStateVar (Maybe (Position -> IO ()))
GL.motionCallback SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> m ()
$= Maybe (Position -> IO ())
forall a. Maybe a
Nothing
			GL.Vertex3 GLdouble
tx GLdouble
ty GLdouble
_  Position -> IO (Vertex3 GLdouble)
unproject Position
to
			let v :: Vector2
v = GLdouble -> GLdouble -> Vector2
Vector2 (GLdouble -> GLdouble
convertGLdouble GLdouble
tx) (GLdouble -> GLdouble
convertGLdouble GLdouble
ty)
			(Graph n -> Graph n) -> IORef (GlobalVars n) -> IO ()
forall {n}. (Graph n -> Graph n) -> IORef (GlobalVars n) -> IO ()
modifyGraph (Rewrite n () -> Graph n -> Graph n
forall n a. Rewrite n a -> Graph n -> Graph n
execGraph (Rewrite n () -> Graph n -> Graph n)
-> Rewrite n () -> Graph n -> Graph n
forall a b. (a -> b) -> a -> b
$ Node -> Position -> Rewrite n ()
forall v n. View v n => Node -> v -> Rewrite n ()
Unsafe.updateNode Node
n (Vector2 -> Position
Position Vector2
v)) IORef (GlobalVars n)
globalVars
			Int -> IO () -> IO ()
GL.addTimerCallback Int
40 (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ SettableStateVar (Maybe (Position -> IO ()))
GL.motionCallback SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> m ()
$= (Position -> IO ()) -> Maybe (Position -> IO ())
forall a. a -> Maybe a
Just (Node -> Position -> IO ()
dragCallback Node
n)

		scrollCallback :: Position -> Position -> IO ()
scrollCallback Position
from Position
to = do
			SettableStateVar (Maybe (Position -> IO ()))
GL.motionCallback SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> m ()
$= Maybe (Position -> IO ())
forall a. Maybe a
Nothing
			GL.Vertex3 GLdouble
fx GLdouble
fy GLdouble
_  Position -> IO (Vertex3 GLdouble)
unproject Position
from
			GL.Vertex3 GLdouble
tx GLdouble
ty GLdouble
_  Position -> IO (Vertex3 GLdouble)
unproject Position
to
			IORef (Vector3 GLdouble)
-> (Vector3 GLdouble -> Vector3 GLdouble) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (Vector3 GLdouble)
focus ((Vector3 GLdouble -> Vector3 GLdouble) -> IO ())
-> (Vector3 GLdouble -> Vector3 GLdouble) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(GL.Vector3 GLdouble
x GLdouble
y GLdouble
_)  GLdouble -> GLdouble -> GLdouble -> Vector3 GLdouble
forall a. a -> a -> a -> Vector3 a
GL.Vector3 (GLdouble
x GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
+ GLdouble
tx GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
- GLdouble
fx) (GLdouble
y GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
+ GLdouble
ty GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
- GLdouble
fy) GLdouble
0
			Window -> IO ()
redisplay (Window -> IO ())
-> (GlobalVars n -> Window) -> GlobalVars n -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalVars n -> Window
forall n. GlobalVars n -> Window
canvas (GlobalVars n -> IO ()) -> IO (GlobalVars n) -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
			Int -> IO () -> IO ()
GL.addTimerCallback Int
40 (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ SettableStateVar (Maybe (Position -> IO ()))
GL.motionCallback SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
SettableStateVar (Maybe (Position -> IO ()))
-> Maybe (Position -> IO ()) -> m ()
$= (Position -> IO ()) -> Maybe (Position -> IO ())
forall a. a -> Maybe a
Just (Position -> Position -> IO ()
scrollCallback Position
to)

	inputCallback (GL.Char Char
'z') KeyState
GL.Up p
_ Position
_ = IO ()
autozoom
	inputCallback (GL.Char Char
' ') KeyState
GL.Up p
_ Position
_ = do
		Bool
isPaused  GlobalVars n -> Bool
forall n. GlobalVars n -> Bool
paused (GlobalVars n -> Bool) -> IO (GlobalVars n) -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
		if Bool
isPaused then IORef (GlobalVars n) -> IO ()
forall {n}. View Position n => IORef (GlobalVars n) -> IO ()
resume IORef (GlobalVars n)
globalVars else IORef (GlobalVars n) -> IO ()
forall {n}. IORef (GlobalVars n) -> IO ()
pause IORef (GlobalVars n)
globalVars
	inputCallback Key
_ KeyState
_ p
_ Position
_ = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

	autozoom :: IO ()
autozoom = let margin :: GLdouble
margin = GLdouble
2 in do
		[n]
ns  Graph n -> [n]
forall n. Graph n -> [n]
nodes (Graph n -> [n])
-> (GlobalVars n -> Graph n) -> GlobalVars n -> [n]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalVars n -> Graph n
forall n. GlobalVars n -> Graph n
graph (GlobalVars n -> [n]) -> IO (GlobalVars n) -> IO [n]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
		let maxDist :: GLdouble
maxDist = [GLdouble] -> GLdouble
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([GLdouble] -> GLdouble) -> [GLdouble] -> GLdouble
forall a b. (a -> b) -> a -> b
$ (GLdouble -> GLdouble) -> [GLdouble] -> [GLdouble]
forall a b. (a -> b) -> [a] -> [b]
map GLdouble -> GLdouble
forall a. Num a => a -> a
abs ([GLdouble] -> [GLdouble]) -> [GLdouble] -> [GLdouble]
forall a b. (a -> b) -> a -> b
$ [[GLdouble]] -> [GLdouble]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Vector2 -> GLdouble
v2x Vector2
p, Vector2 -> GLdouble
v2y Vector2
p] | Vector2
p  (Position -> Vector2) -> n -> Vector2
forall v n field. View v n => (v -> field) -> n -> field
examine Position -> Vector2
position (n -> Vector2) -> [n] -> [Vector2]
forall a b. (a -> b) -> [a] -> [b]
`map` [n]
ns]
		IORef (Vector3 GLdouble) -> Vector3 GLdouble -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Vector3 GLdouble)
focus (Vector3 GLdouble -> IO ()) -> Vector3 GLdouble -> IO ()
forall a b. (a -> b) -> a -> b
$ GLdouble -> GLdouble -> GLdouble -> Vector3 GLdouble
forall a. a -> a -> a -> Vector3 a
GL.Vector3 GLdouble
0 GLdouble
0 GLdouble
0
		IORef GLdouble -> GLdouble -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef GLdouble
zoom (GLdouble -> IO ()) -> GLdouble -> IO ()
forall a b. (a -> b) -> a -> b
$ GLdouble
1 GLdouble -> GLdouble -> GLdouble
forall a. Fractional a => a -> a -> a
/ (GLdouble -> GLdouble
convertDouble GLdouble
maxDist GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
+ GLdouble
margin)

	display :: IO ()
display = do
		[ClearBuffer] -> IO ()
GL.clear [ClearBuffer
GL.ColorBuffer]
		IO ()
GL.loadIdentity
		GLdouble
a  IORef GLdouble -> IO GLdouble
forall a. IORef a -> IO a
readIORef IORef GLdouble
aspect
		if GLdouble
a GLdouble -> GLdouble -> Bool
forall a. Ord a => a -> a -> Bool
< GLdouble
1 then GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
GL.ortho2D (-GLdouble
1) GLdouble
1 (-GLdouble
1GLdouble -> GLdouble -> GLdouble
forall a. Fractional a => a -> a -> a
/GLdouble
a) (GLdouble
1GLdouble -> GLdouble -> GLdouble
forall a. Fractional a => a -> a -> a
/GLdouble
a) else GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
GL.ortho2D (-GLdouble
1GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
*GLdouble
a) (GLdouble
1GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
*GLdouble
a) (-GLdouble
1) GLdouble
1
		GLdouble
z  IORef GLdouble -> IO GLdouble
forall a. IORef a -> IO a
readIORef IORef GLdouble
zoom
		GLdouble -> GLdouble -> GLdouble -> IO ()
forall c. MatrixComponent c => c -> c -> c -> IO ()
GL.scale GLdouble
z GLdouble
z GLdouble
1
		Vector3 GLdouble -> IO ()
forall c. MatrixComponent c => Vector3 c -> IO ()
GL.translate (Vector3 GLdouble -> IO ()) -> IO (Vector3 GLdouble) -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IORef (Vector3 GLdouble) -> IO (Vector3 GLdouble)
forall a. IORef a -> IO a
readIORef IORef (Vector3 GLdouble)
focus

		Color3 GLfloat -> IO ()
forall a. Color a => a -> IO ()
GL.color (GLfloat -> GLfloat -> GLfloat -> Color3 GLfloat
forall a. a -> a -> a -> Color3 a
GL.Color3 GLfloat
0 GLfloat
0 GLfloat
0  GL.Color3 GL.GLfloat)
		Graph n
g  Graph n -> Graph n
project (Graph n -> Graph n)
-> (GlobalVars n -> Graph n) -> GlobalVars n -> Graph n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalVars n -> Graph n
forall n. GlobalVars n -> Graph n
graph (GlobalVars n -> Graph n) -> IO (GlobalVars n) -> IO (Graph n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
		((Vector2, Vector2) -> IO ()) -> [(Vector2, Vector2)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Vector2 -> Vector2 -> IO ()) -> (Vector2, Vector2) -> IO ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Vector2 -> Vector2 -> IO ()
renderLine) (((Edge, [n]) -> [(Vector2, Vector2)])
-> [(Edge, [n])] -> [(Vector2, Vector2)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Edge -> [n] -> [(Vector2, Vector2)])
-> (Edge, [n]) -> [(Vector2, Vector2)]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Edge -> [n] -> [(Vector2, Vector2)]
hyperEdgeToLines) (Graph n -> [(Edge, [n])]
forall n. Graph n -> [(Edge, [n])]
edges Graph n
g))
		Set Node
hl  GlobalVars n -> Set Node
forall n. GlobalVars n -> Set Node
highlighted (GlobalVars n -> Set Node) -> IO (GlobalVars n) -> IO (Set Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
		((Node, n) -> IO ()) -> [(Node, n)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Set Node -> (Node, n) -> IO ()
forall n.
(Render n, View Position n, View Rotation n) =>
Set Node -> (Node, n) -> IO ()
renderNode Set Node
hl) (Rewrite n [Node] -> Graph n -> [Node]
forall n a. Rewrite n a -> Graph n -> a
evalGraph Rewrite n [Node]
forall n (m :: * -> *). MonadReader (Graph n) m => m [Node]
readNodeList Graph n
g [Node] -> [n] -> [(Node, n)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` Graph n -> [n]
forall n. Graph n -> [n]
nodes Graph n
g)
		Window
w  GlobalVars n -> Window
forall n. GlobalVars n -> Window
menu (GlobalVars n -> Window) -> IO (GlobalVars n) -> IO Window
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
		Window -> IO ()
redisplay Window
w -- redisplay the menu subwindow

		IO ()
forall (m :: * -> *). MonadIO m => m ()
GL.swapBuffers

	nodeAt  GL.Position  IO (Maybe Node)
	nodeAt :: Position -> IO (Maybe Node)
nodeAt Position
glPos = do
		GL.Vertex3 GLdouble
x GLdouble
y GLdouble
_  Position -> IO (Vertex3 GLdouble)
unproject Position
glPos
		let pos :: Vector2
pos = GLdouble -> GLdouble -> Vector2
Vector2 (GLdouble -> GLdouble
convertGLdouble GLdouble
x) (GLdouble -> GLdouble
convertGLdouble GLdouble
y)
		Graph n
g  Graph n -> Graph n
project (Graph n -> Graph n)
-> (GlobalVars n -> Graph n) -> GlobalVars n -> Graph n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalVars n -> Graph n
forall n. GlobalVars n -> Graph n
graph (GlobalVars n -> Graph n) -> IO (GlobalVars n) -> IO (Graph n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
		Maybe Node -> IO (Maybe Node)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Node -> IO (Maybe Node)) -> Maybe Node -> IO (Maybe Node)
forall a b. (a -> b) -> a -> b
$ [Node] -> Maybe Node
forall a. [a] -> Maybe a
listToMaybe ([Node] -> Maybe Node) -> [Node] -> Maybe Node
forall a b. (a -> b) -> a -> b
$ [Maybe Node] -> [Node]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe Node] -> [Node]) -> [Maybe Node] -> [Node]
forall a b. (a -> b) -> a -> b
$ Rewrite n [Maybe Node] -> Graph n -> [Maybe Node]
forall n a. Rewrite n a -> Graph n -> a
evalGraph (Reader (Graph n) [Maybe Node] -> Rewrite n [Maybe Node]
forall n (m :: * -> *) a.
MonadReader (Graph n) m =>
Reader (Graph n) a -> m a
readOnly (Reader (Graph n) [Maybe Node] -> Rewrite n [Maybe Node])
-> Reader (Graph n) [Maybe Node] -> Rewrite n [Maybe Node]
forall a b. (a -> b) -> a -> b
$ (Node -> ReaderT (Graph n) Identity (Maybe Node))
-> Reader (Graph n) [Maybe Node]
forall n (m :: * -> *) a.
MonadReader (Graph n) m =>
(Node -> m a) -> m [a]
withNodes ((Node -> ReaderT (Graph n) Identity (Maybe Node))
 -> Reader (Graph n) [Maybe Node])
-> (Node -> ReaderT (Graph n) Identity (Maybe Node))
-> Reader (Graph n) [Maybe Node]
forall a b. (a -> b) -> a -> b
$ Vector2 -> Node -> ReaderT (Graph n) Identity (Maybe Node)
forall {m :: * -> *} {n}.
(View Position n, MonadReader (Graph n) m, MonadFail m) =>
Vector2 -> Node -> m (Maybe Node)
checkPos Vector2
pos) Graph n
g
		where checkPos :: Vector2 -> Node -> m (Maybe Node)
checkPos Vector2
pos Node
n = do
			Vector2
npos  (Position -> Vector2) -> Node -> m Vector2
forall v n (m :: * -> *) a.
(View v n, MonadReader (Graph n) m, MonadFail m) =>
(v -> a) -> Node -> m a
examineNode Position -> Vector2
position Node
n
			Maybe Node -> m (Maybe Node)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Node -> m (Maybe Node)) -> Maybe Node -> m (Maybe Node)
forall a b. (a -> b) -> a -> b
$ if Vector2 -> GLdouble
forall v. Vector v => v -> GLdouble
vmag (Vector2
pos Vector2 -> Vector2 -> Vector2
forall a. Num a => a -> a -> a
- Vector2
npos) GLdouble -> GLdouble -> Bool
forall a. Ord a => a -> a -> Bool
< GLdouble
1 then Node -> Maybe Node
forall a. a -> Maybe a
Just Node
n else Maybe Node
forall a. Maybe a
Nothing

	reshape :: ReshapeCallback
reshape s :: Size
s@(GL.Size GLsizei
w GLsizei
h) = do
		IORef GLdouble -> GLdouble -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef GLdouble
aspect GLdouble
newAspect
		StateVar (Position, Size)
GL.viewport StateVar (Position, Size) -> (Position, Size) -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
StateVar (Position, Size) -> (Position, Size) -> m ()
$= (GLsizei -> GLsizei -> Position
GL.Position GLsizei
0 GLsizei
0, Size
s)
		StateVar MatrixMode
GL.matrixMode StateVar MatrixMode -> MatrixMode -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
StateVar MatrixMode -> MatrixMode -> m ()
$= MatrixMode
GL.Projection
		IO ()
GL.loadIdentity
		GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
GL.perspective GLdouble
0 GLdouble
newAspect (-GLdouble
1) GLdouble
1
		StateVar MatrixMode
GL.matrixMode StateVar MatrixMode -> MatrixMode -> IO ()
forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
forall (m :: * -> *).
MonadIO m =>
StateVar MatrixMode -> MatrixMode -> m ()
$= GLsizei -> MatrixMode
GL.Modelview GLsizei
0
		where newAspect :: GLdouble
newAspect = GLsizei -> GLdouble
forall a b. (Integral a, Num b) => a -> b
fromIntegral GLsizei
w GLdouble -> GLdouble -> GLdouble
forall a. Fractional a => a -> a -> a
/ GLsizei -> GLdouble
forall a b. (Integral a, Num b) => a -> b
fromIntegral (GLsizei -> GLsizei -> GLsizei
forall a. Ord a => a -> a -> a
max GLsizei
1 GLsizei
h)

unproject  GL.Position  IO (GL.Vertex3 GL.GLdouble)
unproject :: Position -> IO (Vertex3 GLdouble)
unproject (GL.Position GLsizei
x GLsizei
y) = do
	GL.Size GLsizei
winWidth GLsizei
winHeight  StateVar Size -> IO Size
forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
forall (m :: * -> *). MonadIO m => StateVar Size -> m Size
GL.get StateVar Size
GL.windowSize
	let pos :: Vertex3 GLdouble
pos = GLdouble -> GLdouble -> GLdouble -> Vertex3 GLdouble
forall a. a -> a -> a -> Vertex3 a
GL.Vertex3 (GLsizei -> GLdouble
forall a b. (Integral a, Num b) => a -> b
fromIntegral GLsizei
x) (GLsizei -> GLdouble
forall a b. (Integral a, Num b) => a -> b
fromIntegral (GLsizei -> GLdouble) -> GLsizei -> GLdouble
forall a b. (a -> b) -> a -> b
$ GLsizei -> GLsizei
forall a b. (Integral a, Num b) => a -> b
fromIntegral GLsizei
winHeight GLsizei -> GLsizei -> GLsizei
forall a. Num a => a -> a -> a
- GLsizei
y) GLdouble
0
	GLmatrix GLdouble
modelview   MatrixMode -> IO (GLmatrix GLdouble)
getMatrix (GLsizei -> MatrixMode
GL.Modelview GLsizei
1)
	GLmatrix GLdouble
projection  MatrixMode -> IO (GLmatrix GLdouble)
getMatrix MatrixMode
GL.Projection
	(Position, Size)
viewport    StateVar (Position, Size) -> IO (Position, Size)
forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
forall (m :: * -> *).
MonadIO m =>
StateVar (Position, Size) -> m (Position, Size)
GL.get StateVar (Position, Size)
GL.viewport
	Vertex3 GLdouble
-> GLmatrix GLdouble
-> GLmatrix GLdouble
-> (Position, Size)
-> IO (Vertex3 GLdouble)
forall (m :: * -> *).
Matrix m =>
Vertex3 GLdouble
-> m GLdouble
-> m GLdouble
-> (Position, Size)
-> IO (Vertex3 GLdouble)
GL.unProject Vertex3 GLdouble
pos GLmatrix GLdouble
modelview GLmatrix GLdouble
projection (Position, Size)
viewport

getMatrix  GL.MatrixMode  IO (GL.GLmatrix GL.GLdouble)
getMatrix :: MatrixMode -> IO (GLmatrix GLdouble)
getMatrix = StateVar (GLmatrix GLdouble) -> IO (GLmatrix GLdouble)
forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
forall (m :: * -> *).
MonadIO m =>
StateVar (GLmatrix GLdouble) -> m (GLmatrix GLdouble)
GL.get (StateVar (GLmatrix GLdouble) -> IO (GLmatrix GLdouble))
-> (MatrixMode -> StateVar (GLmatrix GLdouble))
-> MatrixMode
-> IO (GLmatrix GLdouble)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe MatrixMode -> StateVar (GLmatrix GLdouble)
forall (m :: * -> *) c.
(Matrix m, MatrixComponent c) =>
Maybe MatrixMode -> StateVar (m c)
GL.matrix (Maybe MatrixMode -> StateVar (GLmatrix GLdouble))
-> (MatrixMode -> Maybe MatrixMode)
-> MatrixMode
-> StateVar (GLmatrix GLdouble)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MatrixMode -> Maybe MatrixMode
forall a. a -> Maybe a
Just

renderNode  (Render n, View Position n, View Rotation n)  Set.Set Node  (Node,n)  IO ()
renderNode :: forall n.
(Render n, View Position n, View Rotation n) =>
Set Node -> (Node, n) -> IO ()
renderNode Set Node
highlighted (Node
ref,n
n) = IO () -> IO ()
forall a. IO a -> IO a
GL.preservingMatrix (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
	Vector3 GLdouble -> IO ()
forall c. MatrixComponent c => Vector3 c -> IO ()
GL.translate (Vector2 -> Vector3 GLdouble
vector (Vector2 -> Vector3 GLdouble) -> Vector2 -> Vector3 GLdouble
forall a b. (a -> b) -> a -> b
$ (Position -> Vector2) -> n -> Vector2
forall v n field. View v n => (v -> field) -> n -> field
examine Position -> Vector2
position n
n)
	GLdouble -> Vector3 GLdouble -> IO ()
forall c. MatrixComponent c => c -> Vector3 c -> IO ()
GL.rotate (GLdouble -> GLdouble
convertDouble (GLdouble -> GLdouble) -> GLdouble -> GLdouble
forall a b. (a -> b) -> a -> b
$ (Rotation -> GLdouble) -> n -> GLdouble
forall v n field. View v n => (v -> field) -> n -> field
examine Rotation -> GLdouble
rotation n
n GLdouble -> GLdouble -> GLdouble
forall a. Num a => a -> a -> a
* GLdouble
180 GLdouble -> GLdouble -> GLdouble
forall a. Fractional a => a -> a -> a
/ GLdouble
forall a. Floating a => a
pi) (GLdouble -> GLdouble -> GLdouble -> Vector3 GLdouble
forall a. a -> a -> a -> Vector3 a
GL.Vector3 GLdouble
0 GLdouble
0 GLdouble
1  GL.Vector3 GL.GLdouble)
	if Node
ref Node -> Set Node -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Node
highlighted
		then Color3 GLfloat -> IO ()
forall a. Color a => a -> IO ()
GL.color (GLfloat -> GLfloat -> GLfloat -> Color3 GLfloat
forall a. a -> a -> a -> Color3 a
GL.Color3 GLfloat
1 GLfloat
0 GLfloat
0  GL.Color3 GL.GLfloat)
		else Color3 GLfloat -> IO ()
forall a. Color a => a -> IO ()
GL.color (GLfloat -> GLfloat -> GLfloat -> Color3 GLfloat
forall a. a -> a -> a -> Color3 a
GL.Color3 GLfloat
0 GLfloat
0 GLfloat
0  GL.Color3 GL.GLfloat)
	n -> IO ()
forall a. Render a => a -> IO ()
render n
n

renderLine  Vector2  Vector2  IO ()
renderLine :: Vector2 -> Vector2 -> IO ()
renderLine Vector2
p1 Vector2
p2 = PrimitiveMode -> IO () -> IO ()
forall a. PrimitiveMode -> IO a -> IO a
GL.renderPrimitive PrimitiveMode
GL.Lines (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Vector2 -> IO ()
vertex Vector2
p1 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Vector2 -> IO ()
vertex Vector2
p2