I'm very slowly getting up to speed in Haskell, trying to get a gui toolgit usable, etc. I followed a basic tutorial on using glade to create a simple GUI app and now I'm trying to modularize it. In particular, I wanted to leverage functions instead of doing everything in main. The first thing I did was create separate functions for accessing buttons and associating code to be executed when the buttons are clicked. It works fine but if you look at the code below, I have to carry the entire glade XML "variable" around with me. I realize we don't do global in Haskell but it seems to me there has to be a better mechanism rather than carrying every single variable around in functions. Obviously in the OO world, the XML stuff would just be an instance variable in a class so implicitly available everywhere. What's the "right" way to do this in the Haskell world?
module Main (main) where
import Graphics.UI.Gtk
import Graphics.UI.Gtk.Glade
getButton :: GladeXML -> String -> IO Button
getButton gladeXML buttonName =
xmlGetWidget gladeXML castToButton buttonName
onButtonClick :: GladeXML -> String -> [IO a] -> IO ()
onButtonClick gladeXML buttonName codeSequence = do
aButton <- getButton gladeXML buttonName
_ <- onClicked aButton $ do -- Run the sequence of operations when user clicks
sequence_ codeSequence
return ()
loadGladeFile :: FilePath -> IO (Maybe GladeXML)
loadGladeFile filename = do
g <- xmlNew filename
return g
main :: IO ()
main = do
_ <- initGUI -- Setup
-- Load the Glade XML file
Just xml <- loadGladeFile "tutorial.glade"
-- Create main window (everything inside will be created too)
window <- xmlGetWidget xml castToWindow "window1"
-- Define what to do when we quit
_ <- onDestroy window mainQuit
-- Show the wondow
widgetShowAll window
-- Associate an onClick event with a button
onButtonClick xml "button1" [putStrLn "Hello, world"]
-- Off we go
mainGUI