diff options
Diffstat (limited to 'lib/Phi/Widget.hs')
-rw-r--r-- | lib/Phi/Widget.hs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/Phi/Widget.hs b/lib/Phi/Widget.hs new file mode 100644 index 0000000..a4850e7 --- /dev/null +++ b/lib/Phi/Widget.hs @@ -0,0 +1,67 @@ +{-# LANGUAGE ExistentialQuantification, TypeFamilies #-} + +module Phi.Widget ( Widget(..) + , WidgetClass(..) + , WidgetState(..) + , separator + , createWidgetState + , layoutWidgets + , renderWidgets + ) where + +import Control.Monad + +import Graphics.Rendering.Cairo + + +class WidgetClass a where + type WidgetData a :: * + + initialState :: a -> WidgetData a + + minSize :: a -> Int + + weight :: a -> Float + weight _ = 0 + + layout :: a -> Int -> Int -> WidgetData a + layout widget _ _ = initialState widget + + render :: a -> WidgetData a -> Int -> Int -> Render () + +data Widget = forall a. WidgetClass a => Widget a + +data WidgetState = forall a. WidgetClass a => WidgetState { stateWidget :: a + , stateWidth :: Int + , stateHeight :: Int + , statePrivateData :: WidgetData a + } + +createWidgetState :: Widget -> WidgetState +createWidgetState (Widget w) = WidgetState { stateWidget = w + , stateWidth = 0 + , stateHeight = 0 + , statePrivateData = initialState w + } + +layoutWidgets :: [WidgetState] -> Int -> Int -> [WidgetState] +layoutWidgets widgets w h = map layoutWidget widgets + where + layoutWidget state = state { stateWidth = w, stateHeight = h } + +renderWidgets :: [WidgetState] -> Render () +renderWidgets widgets = forM_ widgets $ \WidgetState { stateWidget = widget, stateWidth = w, stateHeight = h, statePrivateData = priv } -> render widget priv w h + + +data Separator = Separator Int Float + +instance WidgetClass Separator where + type WidgetData Separator = () + initialState _ = () + + minSize (Separator s _) = s + weight (Separator _ w) = w + render _ _ _ _ = return () + +separator :: Int -> Float -> Widget +separator s w = Widget $ Separator s w |