module Graphics.UI.Sifflet.RPanel
(
RPanel, newRPanel, rpanelId, rpanelRoot, rpanelContent
, rpanelAddWidget, rpanelAddWidgets, rpanelNewRow
, rpanelAddRows
)
where
import Control.Monad
import Graphics.UI.Sifflet.LittleGtk
import Language.Sifflet.Util
debugTracing :: Bool
debugTracing = False
data RPanel
= RPanel {
rpId :: String
, rpRoot :: GtkFrame
, rpContent :: [[String]]
, rpFrame :: GtkFrame
, rpExpander :: Expander
, rpVBox :: VBox
, rpCurrentRow :: HBox
, rpCurrentRowFreeWidth :: Int
, rpMaxWidth :: Int
, rpHPad :: Int
}
rpanelId :: RPanel -> String
rpanelId = rpId
rpanelRoot :: RPanel -> GtkFrame
rpanelRoot = rpRoot
rpanelContent :: RPanel -> [[String]]
rpanelContent = rpContent
newRPanel :: String -> Int -> Int -> Int -> IO RPanel
newRPanel cid hpad vpad maxWidth = do
{
frame <- frameNew
; expander <- expanderNew cid
; expanderSetExpanded expander True
; set frame [containerChild := expander]
; vbox <- vBoxNew False vpad
; widgetSetSizeRequest vbox maxWidth (1)
; set expander [containerChild := vbox]
; hbox <- hBoxNew False hpad
; boxPackStart vbox hbox PackNatural 0
; return $ RPanel {rpId = cid
, rpRoot = frame
, rpFrame = frame
, rpExpander = expander
, rpVBox = vbox
, rpCurrentRow = hbox
, rpContent = [[]]
, rpCurrentRowFreeWidth = maxWidth hpad
, rpMaxWidth = maxWidth hpad
, rpHPad = hpad
}
}
rpanelAddWidgets :: (WidgetClass widget) =>
RPanel -> [(String, widget)] -> IO RPanel
rpanelAddWidgets rp pairs =
let addPair rp' (widgetId, widget) = rpanelAddWidget rp' widgetId widget
in foldM addPair rp pairs
rpanelAddWidget :: (WidgetClass widget) =>
RPanel -> String -> widget -> IO RPanel
rpanelAddWidget rp widgetId widget = do
{
Requisition widgetWidth _ <- widgetSizeRequest widget
; let freeWidth = rpCurrentRowFreeWidth rp
freeWidth' = freeWidth widgetWidth rpHPad rp
; if freeWidth' >= 0 || freeWidth == rpMaxWidth rp
then do
{
let content' = insertLastLast (rpContent rp) widgetId
packMode =
PackGrow
; boxPackStart (rpCurrentRow rp) widget packMode 0
; when debugTracing $
putStr (unlines ["Adding " ++ widgetId ++
" width " ++ show widgetWidth
, "Free width = " ++ show freeWidth ++
" -> " ++ show freeWidth'
, "Content -> " ++ show content'])
; return $ rp {rpContent = content'
, rpCurrentRowFreeWidth = freeWidth'}
}
else
do
{
rp' <- rpanelNewRow rp
; rpanelAddWidget rp' widgetId widget
}
}
rpanelNewRow :: RPanel -> IO RPanel
rpanelNewRow rp = do
{
hbox <- hBoxNew False (rpHPad rp)
; boxPackStart (rpVBox rp) hbox PackNatural 0
; return $ rp {rpCurrentRow = hbox
, rpContent = insertLast (rpContent rp) []
, rpCurrentRowFreeWidth = rpMaxWidth rp}
}
rpanelAddRows :: (WidgetClass widget) =>
RPanel -> [[(String, widget)]] -> IO RPanel
rpanelAddRows rp rows = foldM rpanelAddRow rp rows
rpanelAddRow :: (WidgetClass widget) =>
RPanel -> [(String, widget)] -> IO RPanel
rpanelAddRow rp row =
rpanelAddWidgets rp row >>= rpanelNewRow