module Graphics.UI.WX.Menu
(
MenuBar, Menu, menuBar, menuPopup, menuPane, menuHelp
, menuRes, menuBarLoadRes
, menu, menuId
, MenuItem, menuItem, menuQuit, menuAbout, menuItemEx
, menuItemOnCommandRes, menuLine, menuSub, menuRadioItem
, ToolBar, toolBar, toolBarEx
, ToolBarItem, toolMenu, toolMenuFromBitmap, toolItem, toolControl, tool
, StatusField, statusBar, statusField, statusWidth
, menuList, menubar, statusbar
) where
import Data.Char( toUpper )
import Data.List( partition, intersperse )
import System.IO.Unsafe (unsafePerformIO)
import Foreign.Ptr( nullPtr )
import Graphics.UI.WXCore hiding (Event)
import Graphics.UI.WX.Types
import Graphics.UI.WX.Attributes
import Graphics.UI.WX.Layout
import Graphics.UI.WX.Classes
import Graphics.UI.WX.Events
menubar :: WriteAttr (Frame a) [Menu ()]
menubar
= menuBar
menuBar :: WriteAttr (Frame a) [Menu ()]
menuBar
= writeAttr "menubar" setter
where
setter frame menus
= do mb <- menuBarCreate wxMB_DOCKABLE
mapM_ (append mb) menus
frameSetMenuBar frame mb
mapM_ (evtHandlerSetAndResetMenuCommands frame) menus
vis <- windowIsShown frame
if (vis && wxToolkit == WxMac && (div wxVersion 100) >= 25)
then do windowHide frame
windowShow frame
return ()
else return ()
append mb menu
= do title <- menuGetTitle menu
menuSetTitle menu ""
menuBarAppend mb menu title
menuBarLoadRes :: Window a -> FilePath -> String -> IO (MenuBar ())
menuBarLoadRes parent rc name =
do
res <- xmlResourceCreateFromFile rc wxXRC_USE_LOCALE
m <- xmlResourceLoadMenuBar res parent name
return m
menuPopup :: Menu b -> Point -> Window a -> IO ()
menuPopup menu pt parent
= do windowPopupMenu parent menu pt
return ()
menuList :: [Prop (Menu ())] -> IO (Menu ())
menuList
= menuPane
menuPane :: [Prop (Menu ())] -> IO (Menu ())
menuPane props
= do m <- menuCreate "" wxMENU_TEAROFF
set m props
return m
menuHelp :: [Prop (Menu ())] -> IO (Menu ())
menuHelp props
= menuPane ([text := "&Help"] ++ props)
menuRes :: Window a -> String -> [Prop (Menu ())] -> IO (Menu ())
menuRes parent menu_name props =
do
menu <- xmlResourceGetMenu parent menu_name
set menu props
return menu
instance Textual (Menu a) where
text
= newAttr "text" menuGetTitle menuSetTitle
menuSub :: Menu b -> Menu a -> [Prop (MenuItem ())] -> IO (MenuItem ())
menuSub parent menu props
= do id <- idCreate
label <- case (findProperty text "" props) of
Just (txt,_) -> return txt
Nothing -> do title <- menuGetTitle menu
if (null title)
then return "<empty>"
else return title
menuSetTitle menu ""
menuAppendSub parent id label menu ""
menuPropagateEvtHandlers menu
item <- menuFindItem parent id
set item props
return item
menuLine :: Menu a -> IO ()
menuLine menu
= menuAppendSeparator menu
menuItem :: Menu a -> [Prop (MenuItem ())] -> IO (MenuItem ())
menuItem menu props
= do let kind = case (findProperty checkable False props) of
Just (True,_) -> wxITEM_CHECK
_ -> wxITEM_NORMAL
menuItemKind menu kind props
menuRadioItem :: Menu a -> [Prop (MenuItem ())] -> IO (MenuItem ())
menuRadioItem menu props
= menuItemKind menu wxITEM_RADIO ([checked := True] ++ props)
menuItemKind menu kind props
= do id <- idCreate
let label = case (findProperty text "" props) of
Nothing -> "<empty>"
Just (txt,_) -> txt
menuItemEx menu id label kind props
menuAbout :: Menu a -> [Prop (MenuItem ())] -> IO (MenuItem ())
menuAbout menu props
= menuItemId menu wxID_ABOUT "&About..." props
menuQuit :: Menu a -> [Prop (MenuItem ())] -> IO (MenuItem ())
menuQuit menu props
= menuItemId menu wxID_EXIT "&Quit\tCtrl+Q" props
menuItemId :: Menu a -> Id -> String -> [Prop (MenuItem ())] -> IO (MenuItem ())
menuItemId menu id label props
= menuItemEx menu id label wxITEM_NORMAL props
menuItemEx :: Menu a -> Id -> String -> Int -> [Prop (MenuItem ())] -> IO (MenuItem ())
menuItemEx menu id label kind props
= do if (kind == wxITEM_RADIO)
then menuAppendRadioItem menu id label ""
else menuAppend menu id label "" (kind == wxITEM_CHECK)
item <- menuFindItem menu id
set item props
return item
instance Able (MenuItem a) where
enabled = newAttr "enabled" menuItemIsEnabled menuItemEnable
instance Textual (MenuItem a) where
text
= reflectiveAttr "text" menuItemGetItemLabel menuItemSetItemLabel
instance Help (MenuItem a) where
help = newAttr "help" menuItemGetHelp menuItemSetHelp
instance Checkable (MenuItem a) where
checkable = reflectiveAttr "checkable" menuItemIsCheckable (\m c -> menuItemSetCheckable m c)
checked = newAttr "checked" menuItemIsChecked menuItemCheck
instance Identity (MenuItem a) where
identity = newAttr "identity" menuItemGetId menuItemSetId
menu :: MenuItem a -> Event (Window w) (IO ())
menu item
= let id = unsafePerformIO (get item identity)
in menuId id
menuId :: Id -> Event (Window w) (IO ())
menuId id
= newEvent "menu" (\w -> evtHandlerGetOnMenuCommand w id) (\w h -> evtHandlerOnMenuCommand w id h)
instance Commanding (MenuItem a) where
command
= newEvent "command" menuItemGetOnCommand menuItemOnCommand
menuItemGetOnCommand :: MenuItem a -> IO (IO ())
menuItemGetOnCommand item
= do id <- get item identity
topmenu <- menuItemGetTopMenu item
evtHandlerGetOnMenuCommand topmenu id
menuItemOnCommand :: MenuItem a -> IO () -> IO ()
menuItemOnCommand item io
= do id <- get item identity
topmenu <- menuItemGetTopMenu item
evtHandlerOnMenuCommand topmenu id io
menuUpdateEvtHandlers topmenu (insert id io)
frame <- menuGetFrame topmenu
when (not (objectIsNull frame)) (evtHandlerOnMenuCommand frame id io)
where
insert key val [] = [(key,val)]
insert key val ((k,v):xs) | key == k = (key,val):xs
| otherwise = (k,v):insert key val xs
menuItemOnCommandRes :: Window a -> String -> IO () -> IO ()
menuItemOnCommandRes win item_name handler =
do
res <- xmlResourceGet
item_id <- xmlResourceGetXRCID res item_name
evtHandlerOnMenuCommand win item_id handler
menuPropagateEvtHandlers :: Menu a -> IO ()
menuPropagateEvtHandlers menu
= do parent <- menuGetTopMenu menu
handlers <- menuGetEvtHandlers menu
menuSetEvtHandlers menu []
menuSetEvtHandlers parent handlers
menuGetFrame :: Menu a -> IO (Frame ())
menuGetFrame menu
= do menubar <- menuGetMenuBar menu
if (objectIsNull menubar)
then return objectNull
else menuBarGetFrame menubar
menuItemGetTopMenu :: MenuItem a -> IO (Menu ())
menuItemGetTopMenu item
= do menu <- menuItemGetMenu item
menuGetTopMenu menu
menuGetTopMenu :: Menu a -> IO (Menu ())
menuGetTopMenu menu
= do parent <- menuGetParent menu
if (objectIsNull parent)
then return (downcastMenu menu)
else menuGetTopMenu parent
evtHandlerSetAndResetMenuCommands :: EvtHandler a -> Menu b -> IO ()
evtHandlerSetAndResetMenuCommands evtHandler menu
= do handlers <- menuGetEvtHandlers menu
menuSetEvtHandlers menu []
mapM_ (\(id,io) -> evtHandlerOnMenuCommand evtHandler id io) handlers
menuUpdateEvtHandlers menu f
= do hs <- menuGetEvtHandlers menu
menuSetEvtHandlers menu (f hs)
menuGetEvtHandlers :: Menu a -> IO [(Id,IO ())]
menuGetEvtHandlers menu
= do mbHandlers <- unsafeEvtHandlerGetClientData menu
case mbHandlers of
Nothing -> return []
Just hs -> return hs
menuSetEvtHandlers :: Menu a -> [(Id,IO ())] -> IO ()
menuSetEvtHandlers menu hs
= evtHandlerSetClientData menu (return ()) hs
toolBar :: Frame a -> [Prop (ToolBar ())] -> IO (ToolBar ())
toolBar parent props
= toolBarEx parent True True props
toolBarEx :: Frame a -> Bool -> Bool -> [Prop (ToolBar ())] -> IO (ToolBar ())
toolBarEx parent showText showDivider props
= do let style = ( wxTB_DOCKABLE .+. wxTB_FLAT
.+. (if showText then wxTB_TEXT else 0)
.+. (if showDivider then 0 else wxTB_NODIVIDER)
)
t <- toolBarCreate parent idAny rectNull style
frameSetToolBar parent t
set t props
return t
data ToolBarItem = ToolBarItem (ToolBar ()) Id Bool
instance Able ToolBarItem where
enabled
= newAttr "enabled" getter setter
where
getter (ToolBarItem toolbar id isToggle)
= toolBarGetToolEnabled toolbar id
setter (ToolBarItem toolbar id isToggle) enable
= toolBarEnableTool toolbar id enable
instance Tipped ToolBarItem where
tooltip
= newAttr "tooltip" getter setter
where
getter (ToolBarItem toolbar id isToggle)
= toolBarGetToolShortHelp toolbar id
setter (ToolBarItem toolbar id isToggle) txt
= toolBarSetToolShortHelp toolbar id txt
instance Help ToolBarItem where
help
= newAttr "help" getter setter
where
getter (ToolBarItem toolbar id isToggle)
= toolBarGetToolLongHelp toolbar id
setter (ToolBarItem toolbar id isToggle) txt
= toolBarSetToolLongHelp toolbar id txt
instance Checkable ToolBarItem where
checkable
= readAttr "checkable" getter
where
getter (ToolBarItem toolbar id isToggle)
= return isToggle
checked
= newAttr "checked" getter setter
where
getter (ToolBarItem toolbar id isToggle)
= toolBarGetToolState toolbar id
setter (ToolBarItem toolbar id isToggle) toggle
= toolBarToggleTool toolbar id toggle
instance Identity ToolBarItem where
identity
= readAttr "identity" getter
where
getter (ToolBarItem toolbar id isToggle)
= return id
instance Commanding ToolBarItem where
command
= newEvent "command" getter setter
where
getter (ToolBarItem toolbar id isToggle)
= evtHandlerGetOnMenuCommand toolbar id
setter (ToolBarItem toolbar id isToggle) io
= evtHandlerOnMenuCommand toolbar id io
tool :: ToolBarItem -> Event (Window w) (IO ())
tool (ToolBarItem toolbar id isToggle)
= newEvent "tool" getter setter
where
getter w
= evtHandlerGetOnMenuCommand w id
setter w io
= evtHandlerOnMenuCommand w id io
toolMenu :: ToolBar a -> MenuItem a -> String -> FilePath -> [Prop ToolBarItem] -> IO ToolBarItem
toolMenu toolbar menuitem label bitmapPath props
= withBitmapFromFile bitmapPath $ \bitmap ->
toolMenuFromBitmap toolbar menuitem label bitmap props
toolMenuFromBitmap :: ToolBar a -> MenuItem a -> String -> Bitmap b -> [Prop ToolBarItem] -> IO ToolBarItem
toolMenuFromBitmap toolbar menuitem label bitmap props
= do isToggle <- get menuitem checkable
id <- get menuitem identity
lhelp <- get menuitem help
shelp <- get menuitem help
toolBarAddTool2 toolbar id label bitmap nullBitmap
(if isToggle then wxITEM_CHECK else wxITEM_NORMAL)
shelp lhelp
let t = ToolBarItem (downcastToolBar toolbar) id isToggle
set t props
toolBarRealize toolbar
return t
toolItem :: ToolBar a -> String -> Bool -> FilePath -> [Prop ToolBarItem] -> IO ToolBarItem
toolItem toolbar label isCheckable bitmapPath props
= withBitmapFromFile bitmapPath $ \bitmap ->
do id <- idCreate
toolBarAddTool2 toolbar id label bitmap nullBitmap
(if isCheckable then wxITEM_CHECK else wxITEM_NORMAL)
"" ""
let t = ToolBarItem (downcastToolBar toolbar) id isCheckable
set t props
toolBarRealize toolbar
return t
toolControl :: ToolBar a -> Control b -> IO ()
toolControl toolbar control
= do toolBarAddControl toolbar control
return ()
data StatusField = SF (Var Int) (Var (StatusBar ())) (Var Int) (Var String)
statusWidth :: Attr StatusField Int
statusWidth
= newAttr "statusWidth" getter setter
where
getter (SF vwidth _ _ _)
= varGet vwidth
setter (SF vwidth _ _ _) w
= varSet vwidth w
statusField :: [Prop StatusField] -> IO StatusField
statusField props
= do vwidth<- varCreate (1)
vsbar <- varCreate objectNull
vidx <- varCreate (1)
vtext <- varCreate ""
let sf = SF vwidth vsbar vidx vtext
set sf props
return sf
instance Textual StatusField where
text
= newAttr "text" get set
where
get (SF _ vsbar vidx vtext)
= varGet vtext
set (SF _ vsbar vidx vtext) text
= do varSet vtext text
idx <- varGet vidx
if (idx >= 0)
then do sbar <- varGet vsbar
statusBarSetStatusText sbar text idx
else return ()
statusbar :: WriteAttr (Frame a) [StatusField]
statusbar
= statusBar
statusBar :: WriteAttr (Frame a) [StatusField]
statusBar
= writeAttr "statusbar" set
where
set f fields
= do ws <- mapM (\field -> get field statusWidth) fields
sb <- statusBarCreateFields f ws
mapM_ (setsb sb) (zip [0..] fields )
setsb sb (idx,SF _ vsbar vidx vtext)
= do varSet vsbar sb
varSet vidx idx
text <- varGet vtext
statusBarSetStatusText sb text idx