Why are buttons not rendering in a table in gtk2hs

81 views Asked by At

I'm trying to write a simple UI in gtk2hs. It starts with two text boxes and a button. When the button is pressed, it makes a table of buttons of size (m,n) where m and n are taken from the text boxes. For some reason, when the button is pressed, space is allocated for the table but none of the buttons are shown!

import Graphics.UI.Gtk
import Control.Concurrent

t2l :: Int -> Int -> Int -> Int -> Int 
t2l r c rr cc = (r * cc) + c 

buildTable :: Int -> Int -> IO(Table, [Button])
buildTable r c = do
   t <- tableNew r c True
   buttons <- sequence $ take (r * c) (repeat buttonNew)
   mapM (`set` [buttonLabel := "HELLO"]) buttons
   return [tableAttachDefaults t (buttons !! (t2l rr cc r c)) cc (cc+1) rr (rr+1) | cc <- [0..(c+1)] , rr <- [0..(r+1)]]
   return (t,buttons)

main = do
   initGUI
   window <- windowNew
   mainSplit <- vBoxNew False 10
   contPannel <- hBoxNew False 5

   rowTF <- entryNew
   colTF <- entryNew
   buildBTN <- buttonNew
   set buildBTN [buttonLabel := "Build Table"]

   set window [containerChild := mainSplit]
   boxPackStart mainSplit contPannel PackGrow 0
   boxPackStart contPannel rowTF PackGrow 0
   boxPackStart contPannel colTF PackGrow 0
   boxPackStart contPannel buildBTN PackNatural 0

   on window objectDestroy mainQuit
   widgetShowAll window

   on buildBTN buttonActivated $ do
      rT <- get rowTF entryText
      cT <- get colTF entryText
      r <- return $ read rT
      c <- return $ read cT
      (t,b) <- buildTable r c 
      boxPackStart mainSplit t PackGrow 0
      widgetShowAll t
      return ()

   mainGUI
1

There are 1 answers

1
James On

I'm not 100% sure why the error arose, I have some new code which works:

import Graphics.UI.Gtk
import Control.Concurrent

mkBtn :: String -> IO Button
mkBtn label = buttonNew >>= (\b -> set b [buttonLabel := label] >> return b)

buildTable :: Int -> Int -> IO(Grid)
buildTable r c = do
   t <- gridNew
   gridSetRowHomogeneous t True
   mapM (\f -> mkBtn "Hello" >>= (\b -> gridAttach t b (f `mod` c) (f `div` c) 1 1)) [0..(r*c)-1]
   return (t) 

main = do
   initGUI
   window <- windowNew
   mainSplit <- vBoxNew False 10
   contPannel <- hBoxNew False 5

   rowTF <- entryNew
   colTF <- entryNew
   buildBTN <- buttonNew
   set buildBTN [buttonLabel := "Build Table"]

   set window [containerChild := mainSplit]
   boxPackStart mainSplit contPannel PackGrow 0
   boxPackStart contPannel rowTF PackGrow 0
   boxPackStart contPannel colTF PackGrow 0
   boxPackStart contPannel buildBTN PackNatural 0

   on window objectDestroy mainQuit
   widgetShowAll window

   on buildBTN buttonActivated $ do
      rT <- get rowTF entryText
      cT <- get colTF entryText
      r <- return $ read rT
      c <- return $ read cT
      t <- buildTable r c 
      boxPackStart mainSplit t PackGrow 0
      widgetShowAll t
      return ()

   mainGUI

Maybe someone will know why this works and the last didn't? I assume it was how I was creating new buttons.

First thing I changed was from gtk2 to 3, this enabled me to use grid instead of table. Instead of using repeat, I used a helper function mkBtn. The other changes are just how I went about populating the grid. Instead of a rather silly list comprehension, I used mapM and converted the index in the list of buttons to table coords instead of table coords to list index (originally done in t2l)