{-# LANGUAGE MultiParamTypeClasses, StandaloneDeriving, ExistentialQuantification, FlexibleInstances #-} module Phi.Widgets.AlphaBox ( AlphaBox , alphaBox ) where import Phi.Types import Phi.Widget import Control.Monad import Control.Monad.State.Strict import Graphics.Rendering.Cairo data AlphaBox w s c d = (Widget w s c d) => AlphaBox !Double !w data AlphaBoxCache w s c d = (Widget w s c d) => AlphaBoxCache !c instance (Eq s, Display d) => Widget (AlphaBox w s c d) s (AlphaBoxCache w s c d) d where initWidget (AlphaBox _ w) = initWidget w initCache (AlphaBox _ w) = AlphaBoxCache $ initCache w minSize (AlphaBox _ w) = minSize w weight (AlphaBox _ w) = weight w render (AlphaBox alpha w) s x y width height screen = do AlphaBoxCache c <- get (surfaces, c') <- liftIO $ flip runStateT c $ render w s x y width height screen put $ AlphaBoxCache c' let surfacesWidths = zipWith (\(updated, SurfaceSlice x surf) x' -> (updated, x, x'-x, surf)) surfaces (map (\(_, SurfaceSlice x _) -> x) (tail surfaces) ++ [width]) forM surfacesWidths $ \(updated, x, surfWidth, surf) -> do surf' <- liftIO $ createImageSurface FormatARGB32 surfWidth height renderWith surf' $ do setOperator OperatorSource withPatternForSurface surf setSource paint setOperator OperatorDestIn setSourceRGBA 0 0 0 alpha paint return (updated, SurfaceSlice x surf') handleMessage (AlphaBox _ w) = handleMessage w alphaBox :: (Widget w s c d) => Double -> w -> AlphaBox w s c d alphaBox = AlphaBox