module Hoodle.Coroutine.Draw where
import Control.Applicative
import qualified Data.IntMap as M
import Control.Lens (view,set)
import Control.Monad
import Control.Monad.Trans
import Control.Monad.State
import Graphics.Rendering.Cairo
import Graphics.UI.Gtk hiding (get,set)
import Data.Hoodle.BBox
import Hoodle.Accessor
import Hoodle.Type.Alias
import Hoodle.Type.Canvas
import Hoodle.Type.Coroutine
import Hoodle.Type.Enum
import Hoodle.Type.Event
import Hoodle.Type.PageArrangement
import Hoodle.Type.HoodleState
import Hoodle.View.Draw
data DrawingFunctionSet =
DrawingFunctionSet { singleEditDraw :: DrawingFunction SinglePage EditMode
, singleSelectDraw :: DrawingFunction SinglePage SelectMode
, contEditDraw :: DrawingFunction ContinuousPage EditMode
, contSelectDraw :: DrawingFunction ContinuousPage SelectMode
}
invalidateGeneral :: CanvasId -> Maybe BBox -> DrawFlag
-> DrawingFunction SinglePage EditMode
-> DrawingFunction SinglePage SelectMode
-> DrawingFunction ContinuousPage EditMode
-> DrawingFunction ContinuousPage SelectMode
-> MainCoroutine ()
invalidateGeneral cid mbbox flag drawf drawfsel drawcont drawcontsel = do
xst <- get
selectBoxAction (fsingle xst) (fcont xst) . getCanvasInfo cid $ xst
where fsingle :: HoodleState -> CanvasInfo SinglePage -> MainCoroutine ()
fsingle xstate cvsInfo = do
let cpn = PageNum . view currentPageNum $ cvsInfo
isCurrentCvs = cid == getCurrentCanvasId xstate
epage = getCurrentPageEitherFromHoodleModeState cvsInfo (view hoodleModeState xstate)
cvs = view drawArea cvsInfo
msfc = view mDrawSurface cvsInfo
case epage of
Left page -> do
liftIO (unSinglePageDraw drawf isCurrentCvs (cvs,msfc) (cpn,page)
<$> view viewInfo <*> pure mbbox <*> pure flag $ cvsInfo )
return ()
Right tpage -> do
liftIO (unSinglePageDraw drawfsel isCurrentCvs (cvs,msfc) (cpn,tpage)
<$> view viewInfo <*> pure mbbox <*> pure flag $ cvsInfo )
return ()
fcont :: HoodleState -> CanvasInfo ContinuousPage -> MainCoroutine ()
fcont xstate cvsInfo = do
let hdlmodst = view hoodleModeState xstate
isCurrentCvs = cid == getCurrentCanvasId xstate
case hdlmodst of
ViewAppendState hdl -> do
hdl' <- liftIO (unContPageDraw drawcont isCurrentCvs cvsInfo mbbox hdl flag)
put (set hoodleModeState (ViewAppendState hdl') xstate)
SelectState thdl -> do
thdl' <- liftIO (unContPageDraw drawcontsel isCurrentCvs cvsInfo mbbox thdl flag)
put (set hoodleModeState (SelectState thdl') xstate)
invalidateOther :: MainCoroutine ()
invalidateOther = do
xstate <- get
let currCvsId = getCurrentCanvasId xstate
cinfoMap = getCanvasInfoMap xstate
keys = M.keys cinfoMap
mapM_ invalidate (filter (/=currCvsId) keys)
invalidate :: CanvasId -> MainCoroutine ()
invalidate = invalidateInBBox Nothing Clear
invalidateInBBox :: Maybe BBox
-> DrawFlag
-> CanvasId -> MainCoroutine ()
invalidateInBBox mbbox flag cid = do
xst <- get
geometry <- liftIO $ getCanvasGeometryCvsId cid xst
invalidateGeneral cid mbbox flag
drawSinglePage (drawSinglePageSel geometry) drawContHoodle (drawContHoodleSel geometry)
invalidateAllInBBox :: Maybe BBox
-> DrawFlag
-> MainCoroutine ()
invalidateAllInBBox mbbox flag = applyActionToAllCVS (invalidateInBBox mbbox flag)
invalidateAll :: MainCoroutine ()
invalidateAll = invalidateAllInBBox Nothing Clear >> liftIO (putStrLn "The SLOW invalidateAll Called")
invalidateCurrent :: MainCoroutine ()
invalidateCurrent = invalidate . getCurrentCanvasId =<< get
invalidateTemp :: CanvasId -> Surface -> Render () -> MainCoroutine ()
invalidateTemp cid tempsurface rndr = do
xst <- get
selectBoxAction (fsingle xst) (fsingle xst) . getCanvasInfo cid $ xst
where fsingle xstate cvsInfo = do
let canvas = view drawArea cvsInfo
pnum = PageNum . view currentPageNum $ cvsInfo
geometry <- liftIO $ getCanvasGeometryCvsId cid xstate
win <- liftIO $ widgetGetDrawWindow canvas
let xformfunc = cairoXform4PageCoordinate geometry pnum
liftIO $ renderWithDrawable win $ do
setSourceSurface tempsurface 0 0
setOperator OperatorSource
paint
xformfunc
rndr
invalidateTempBasePage :: CanvasId -> Surface -> PageNum -> Render ()
-> MainCoroutine ()
invalidateTempBasePage cid tempsurface pnum rndr = do
xst <- get
selectBoxAction (fsingle xst) (fsingle xst) . getCanvasInfo cid $ xst
where fsingle xstate cvsInfo = do
let canvas = view drawArea cvsInfo
geometry <- liftIO $ getCanvasGeometryCvsId cid xstate
win <- liftIO $ widgetGetDrawWindow canvas
let xformfunc = cairoXform4PageCoordinate geometry pnum
liftIO $ renderWithDrawable win $ do
setSourceSurface tempsurface 0 0
setOperator OperatorSource
paint
xformfunc
rndr
chkCvsIdNInvalidate :: CanvasId -> MainCoroutine ()
chkCvsIdNInvalidate cid = do
currcid <- liftM (getCurrentCanvasId) get
when (currcid /= cid) (changeCurrentCanvasId cid >> invalidateAll)
waitSomeEvent :: (UserEvent -> Bool) -> MainCoroutine UserEvent
waitSomeEvent p = do
r <- nextevent
case r of
UpdateCanvas cid ->
invalidateInBBox Nothing Efficient cid >> waitSomeEvent p
_ -> if p r then return r else waitSomeEvent p