packages feed

AutoForms-0.4.0: src/Graphics/UI/AF/AFWx.hs

-- |AutoForm functions closely integrated with WxHaskell.
module Graphics.UI.AF.AFWx
    ( -- * Example
      -- $example
      -- * Creating widgets
      makeWidget, makeWidget', AFWx
    , module Graphics.UI.AF.General.MySYB
    -- * 'AF.EC'
    , AF.EC, AF.ECCreator
    , AF.limit, AF.giveFocus
    , AF.mapValue
    -- ** GUI-layout of 'AF.EC' types
    , AF.layoutAs, AF.singleColumn, AF.dualColumn, AF.singleRow
    , AF.finalDepth
    )
where

import qualified Graphics.UI.AF.WxFormAll                as AF
import qualified Graphics.UI.AF.WxForm.EditorComponent   as AF
import qualified Graphics.UI.AF.WxForm.ComIO             as ComIO

import Graphics.UI.WX hiding (parent)
import Graphics.UI.WXCore
import Graphics.UI.AF.General.MySYB

import Control.Monad(liftM)

-- |Contains a widget representing an arbitrary type.
data AFWx a = AFWx { pickComIO  :: ComIO.ComIO a
                   , pickLayout :: Layout
                   }

instance Widget (AFWx a) where
    widget = pickLayout

instance Commanding (AFWx a) where
    command = newEvent "Commanding" getter setter
        where getter w        = get (pickComIO w) (on command)
              setter w action = set (pickComIO w) [ on command := action ]

instance Able (AFWx a) where
    enabled = mapToAFWx "Able" enabled

instance Valued AFWx where
    value = mapToAFWx "Value" value

mapToAFWx :: String -> Attr (ComIO.ComIO a) a1 -> Attr (AFWx a) a1
mapToAFWx name attribute = newAttr name getter setter
    where getter w     = get (pickComIO w) attribute
          setter w val = set (pickComIO w) [ attribute := val ]

-- |A more constrained version of 'makeWidget''.
makeWidget :: (AF.ECCreator a)
           => a
           -> Window w
           -> [Prop (AFWx a)]
           -> IO (AFWx a)
makeWidget x parent props = makeWidget' id x parent props

-- |Creating a widget for any type, which is an instance of ECCreator.
makeWidget' :: (AF.ECCreator a)
            => (AF.EC a -> AF.EC a) -- ^Used to transform the created widget. See 'AF.limit', 'AF.giveFocus'
                                    -- and the functions in "AF.AutoForm".
                                    -- Also see the EmbeddedTree example.
            -> a                    -- ^The value to represent in a GUI.
            -> Window w             -- ^The window (or panel) to represent the value in.
            -> [Prop (AFWx a)]      -- ^Initial properties to set.
            -> IO (AFWx a)
makeWidget' ecToEC x parent props =
    do (comIO, widAndGui) <- AF.runWxM (AF.runEC $ ecToEC $ AF.mkCom x) parent (return ()) parent
       (lay, _)     <- maybe AF.nonEditableLayout AF.unboxedLayout (liftM snd widAndGui)
       let afwx = AFWx comIO lay
       set afwx props
       return $ AFWx comIO lay

{- $example
An example of using AutoForm and WxHaskell together:

>import Graphics.UI.WX
>import Graphics.UI.AF.AFWx
>
>main :: IO ()
>main = start $
>     do w <- frame [text := "Small example"]
>        p <- panel w []
> 
>        wid <- makeWidget (0.96::Double, 123::Int, "asdf") p [ ]
>        setWidButton <- button p [ text := "Set widget"
>                                 , on command := set wid [ value := (0.32, 456, "New Value") ]
>                                 ]
>
>        set w [ layout := container p $ fill $ column 10
>                           [ widget wid, widget setWidButton ]
>              ]

-}