phooey-0.1: src/Graphics/UI/Phooey/ArrowUI.hs
{-# OPTIONS -fglasgow-exts #-}
----------------------------------------------------------------------
-- |
-- Module : Graphics.UI.Phooey.ArrowUI
-- Copyright : (c) Conal Elliott 2006
-- License : LGPL
--
-- Maintainer : conal@conal.net
-- Stability : provisional
-- Portability : portable
--
-- A functional UI arrow. See explanation and examples in
-- "Graphics.UI.Phooey".
----------------------------------------------------------------------
module Graphics.UI.Phooey.ArrowUI
(
-- * The UI arrow
UI(..), runUI, runNamedUI
-- * High-level widgets
, stringDisplay, showDisplay, textEntry, islider
, checkBoxDisplay, checkBoxEntry, title
-- * Explicit layout
, fromTop, fromBottom, fromLeft, fromRight, flipLayout
-- * Internal (extensibility)
, ui, sourceOp, onLayoutT
) where
import Control.Arrow
import Graphics.UI.WX (Layout,boxed)
import Graphics.UI.Phooey.Imperative (Source,skip)
import Graphics.UI.Phooey.TagT (Unop)
import Graphics.UI.Phooey.LayoutT
import qualified Graphics.UI.Phooey.MonadUI as M
import Graphics.UI.Phooey.AmA
{----------------------------------------------------------
The UI arrow
----------------------------------------------------------}
-- | The UI arrow
newtype UI i o = UI (AmA (Kleisli M.UI) IO i o)
deriving (Arrow,ArrowLoop)
-- | Run a 'UI' with window title \"Phooey GUI\".
runUI :: UI () () -> IO ()
runUI = runNamedUI "Phooey GUI"
-- | Run a 'UI' with given window title.
runNamedUI :: String -> UI () () -> IO ()
runNamedUI str (UI (AmA (Kleisli f))) = M.runUI str (f skip >> return ())
-- | Wrap up monadic UI function as a 'UI'
ui :: (Source i -> M.UI (Source o)) -> UI i o
ui = UI . AmA . Kleisli
{----------------------------------------------------------
High-level widgets
----------------------------------------------------------}
-- | String display widget
stringDisplay :: UI String ()
stringDisplay = ui M.stringDisplay
-- | Showable display widget
showDisplay :: Show a => UI a ()
showDisplay = pure show >>> stringDisplay
-- or: ui M.showDisplay
-- | Simple text input widget
textEntry :: UI () String
textEntry = ui (const M.textEntry)
-- | Slider widget with static initial value and dynamic bounds (min,max)
islider :: Int -> UI (Int,Int) Int
islider initial = ui (M.islider initial)
-- | String display widget
checkBoxDisplay :: UI Bool ()
checkBoxDisplay = ui M.checkBoxDisplay
-- | Simple checkbox input widget
checkBoxEntry :: Bool -> UI () Bool
checkBoxEntry initial = ui (const (M.checkBoxEntry initial))
-- | Wrap a title around a 'UI'
title :: String -> Unop (UI a b)
title str = mapLayoutU (boxed str)
{----------------------------------------------------------
Layout
----------------------------------------------------------}
-- | Lay out from top to bottom
fromTop :: Unop (UI a b)
fromTop = onLayoutT fromTopL
-- | Lay out from bottom to top
fromBottom :: Unop (UI a b)
fromBottom = onLayoutT fromBottomL
-- | Lay out from left to right
fromLeft :: Unop (UI a b)
fromLeft = onLayoutT fromLeftL
-- | Lay out from right to left
fromRight :: Unop (UI a b)
fromRight = onLayoutT fromRightL
-- | Reverse layout
flipLayout :: Unop (UI a b)
flipLayout = onLayoutT flipL
---- Misc unexported
sourceOp :: Unop (M.UI (Source b)) -> Unop (UI a b)
sourceOp f (UI (AmA (Kleisli g))) = ui (f . g)
mapLayoutU :: Unop Layout -> Unop (UI a b)
mapLayoutU f = sourceOp (M.mapLayout f)
onLayoutT :: LayoutTOp IO -> Unop (UI a b)
onLayoutT f = sourceOp (M.onLayoutT f)