A Component is an action that produces a Widget Behavior - WidgetB. 
A WidgetB is an abstract representation of a primitive widget (Widget.lhs). 
A WidgetB being a widget behavior may be dynamic. 
There are several types of Component and WidgetB: 
representing top level windows (WComponent); 
widgets, such as buttons, that live inside top level windows (Component); 
and canvas items, that live in canvases (CComponent).

There is a generic widget type that represents any widget.

data GWidgetB a 

There are a few functions that will work on any abstract component or widget. 
These are all defined to work on the type (GUI (GWidgetB a))


\begin{code}
module Component where
import Widget
import WH
import DisplayWidget (displayWidget,displayWindow)
import FranCore
import qualified StaticTypes as S
import BVars
import GUI
import PrimWidget
import HasInput

instance IfBehavior (GUI (GWidgetB a)) where
 ifB b c1 c2 = do w1 <- c1;w2 <- c2;return $ ifB b w1 w2

type Component = GUI WidgetB
type WComponent = GUI WindowWidgetB
type CComponent = GUI CanvasWidgetB

emptyComponent :: GUI (GWidgetB a)
emptyComponent = return $ emptyWidgetB

cwidget :: (Bindable w,CanvasItem w) => w -> CanvasWidgetB
cwidget w = GWidgetB $ CW w

wwidget :: (Bindable w,WindowItem w) => PrimWidget w -> WindowWidgetB
wwidget w = GWidgetB $ WW w

widget :: (Bindable w,PanelItem w) => PrimWidget w -> WidgetB
widget w = GWidgetB $ PW w

render :: WComponent -> GUI ()
render c = do {w <- c;withGUIDef $ displayWindow w}

display :: WComponent -> IO ()
display = start . render

groupn :: Int -> [a] -> [[a]]
groupn n = takeWhile (not . null) . map (take n) . iterate (drop n)

matrix :: Int -> [Component] -> Component
matrix n cs = matrix' $ groupn n cs

matrix' :: [[Component]] -> Component
matrix' ws = nabove $ map nbeside ws


bindActionC :: Action -> Listener UserAction -> GUI (GWidgetB a) 
           -> GUI (GWidgetB a)
bindActionC a l c = do
 w <- c
 return $! GrabInput a l w

instance Has_Input (GUI (GWidgetB a)) where
 bindAction = bindActionC

instance Packable Component where
 above w1 w2 = do
   x <- w1
   y <- w2
   return $ x `above` y
 beside w1 w2 = do
   x <- w1
   y <- w2
   return $ x `beside` y
 fill f w = w >>= return . fill f
 expand b w = w >>= return . expand b
 expandB b w = w >>= return . expandB b
 fillB b w = w >>= return . fillB b
 pad p w = w >>= return . pad p
 padI p w = w >>= return . padI p 
 padB p w = w >>= return . padB p
 padIB p w = w >>= return . padIB p
 packAnchor p w = w >>= return . packAnchor p
 packAnchorB p w = w >>= return . packAnchorB p

instance PackCollection (CollectionB ListOp List) Component where
 nabove ls = do
   ws <- mapG id ls 
   return $ nabove ws
 nbeside ls = do
   ws <- mapG id ls
   return $ nbeside ws
 
instance PackCollection [] Component where
 nabove ls = do
   ws <- mapG id ls 
   return $ nabove ws
 nbeside ls = do
   ws <- mapG id ls
   return $ nbeside ws

instance Pile (CollectionB ListOp List) CComponent where
 pile ls = do
  ws <- mapG id ls
  return $ pile ws

instance Pile [] CComponent where
 pile ls = do 
  ws <- mapG id ls
  return $ pile ws

instance Pile (CollectionB ListOp List) WComponent where
 pile ls = do
   ws <- mapG id ls 
   return $ pile ws

instance Pile [] WComponent where
 pile ls = do
   ws <- mapG id ls 
   return $ pile ws


instance Transformable2B CComponent where
  t *% cw = do w <- cw
	       return $ t *% w

instance Over CComponent where
 over c1 c2 = do 
  w1 <- c1
  w2 <- c2
  return $ w1 `over` w2

withStyle :: [Conf Style] -> GUI (GWidgetB w) -> GUI (GWidgetB w)
withStyle cs g = do
 w <- withStyle' cs g
 return $ WithStyle cs w
\end{code}
