From: Duncan C. <dun...@wo...> - 2007-08-14 08:44:39
|
Sat Aug 11 07:10:48 PDT 2007 hth...@zo... * Gtk+2.0 Tutorial Port (part 1) Start of a port to Gtk2Hs of the Gtk+2.0 tutorial included in the Gtk documentation. Note: Chapter 2 is supposed to be an introductory overview, as in the original, but for Gtk2Hs. I'm hoping someone who knows more will jump in here. The implemented chapters are: 1. Contents and copyright, as required by the original authors 2. To be written by an expert... 3. Getting Started 4. Packing Widgets 5.a. Packing Demonstration Program 5.b. Packing Using Tables 6. The Button Widget 7. Adjustments, Scale and Range The examples have been tested with Gtk2Hs-0.9.12 (the first ones with .11) on Fedora 6. The html files have been taken from the original Gtk+2.0 tutorial, processed in Open Office Writer html mode, and then cleaned up with Screem and tidy. There are still some unreferred name tags left from the original. adddir ./docs/tutorial/Tutorial_Port adddir ./docs/tutorial/Tutorial_Port/Example_Code adddir ./docs/tutorial/Tutorial_Port/Images addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap3a.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap3a.hs 1 +{- GTK 2.0 Tutorial: Chapter 3a, Getting Started + + To run with GHCi: ghci GtkChap3.hs + To compile with GHC: ghc --make GtkChap3.hs -o chap +-} + [_$_] +import Graphics.UI.Gtk + +main :: IO () +main = do [_$_] + initGUI + window <- windowNew + widgetShowAll window + mainGUI + +{- Notes: + 1) Watch the upper and lower case occurrences + 2) Ctl-z to abort GHCi, not Ctl-c [_$_] +-} [_$_] + + + + [_$_] addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap3b.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap3b.hs 1 +import Graphics.UI.Gtk + +hello :: (ButtonClass o) => o -> IO () +hello b = set b [buttonLabel := "Hello World"] + +main :: IO () +main = do [_$_] + initGUI + window <- windowNew + button <- buttonNew + set window [windowDefaultWidth := 200, windowDefaultHeight := 200, + containerChild := button , containerBorderWidth := 10 ] + onClicked button (hello button) + onDestroy window mainQuit + widgetShowAll window + mainGUI [_$_] + +{- Notes: + 1) the default size of the window is set to 200 x 200 pixels + 2) when the button is clicked the hello function is 'executed' +-} addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap4.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap4.hs 1 +-- GTK 2.0 Tutorial: Chapter 4, Moving On + +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + hbox <- hBoxNew True 10 + button1 <- buttonNewWithLabel "Button 1" + button2 <- buttonNewWithLabel "Button 2" + set window [windowDefaultWidth := 200, windowDefaultHeight := 200, + containerBorderWidth := 10, containerChild := hbox ] + boxPackStart hbox button1 PackGrow 0 + boxPackStart hbox button2 PackGrow 0 + widgetShowAll window + onDestroy window mainQuit + mainGUI addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap5a.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap5a.hs 1 +-- GTK 2.0 Tutorial: Chapter 5a, Packing Widgets + +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + vbox <- vBoxNew False 0 + set window [containerBorderWidth := 10, [_$_] + windowTitle := "Packing Demonstration", + containerChild := vbox ] + label1 <- labelNew (Just "hBoxNew False 0") + miscSetAlignment label1 0 0 + boxPackStart vbox label1 PackNatural 0 + box1 <- makeBox False 0 PackNatural 0 + boxPackStart vbox box1 PackNatural 0 + box2 <- makeBox False 0 PackRepel 0 + boxPackStart vbox box2 PackNatural 0 [_$_] + box3 <- makeBox False 0 PackGrow 0 + boxPackStart vbox box3 PackNatural 0 + sep1 <- hSeparatorNew + boxPackStart vbox sep1 PackNatural 10 [_$_] + label2 <- labelNew (Just "hBoxNew True 0") + miscSetAlignment label2 0 0 + boxPackStart vbox label2 PackNatural 0 + box4 <- makeBox True 0 PackNatural 0 + boxPackStart vbox box4 PackNatural 0 + box5 <- makeBox True 0 PackRepel 0 + boxPackStart vbox box5 PackNatural 0 [_$_] + box6 <- makeBox False 0 PackGrow 0 + boxPackStart vbox box6 PackNatural 0 + sep <- hSeparatorNew + boxPackStart vbox sep PackNatural 10 [_$_] + quitbox <- hBoxNew False 0 + boxPackStart vbox quitbox PackNatural 0 + quitbutton <- buttonNewWithLabel "Quit" + boxPackStart quitbox quitbutton PackRepel 0 + onClicked quitbutton mainQuit [_$_] + onDestroy window mainQuit [_$_] + widgetShowAll window + mainGUI + + +makeBox :: Bool -> Int -> Packing -> Int -> IO HBox +makeBox homogeneous spacing packing padding = do + box <- hBoxNew homogeneous spacing + button1 <- buttonNewWithLabel "boxPackStart" + boxPackStart box button1 packing padding + button2 <- buttonNewWithLabel "box" + boxPackStart box button2 packing padding + button3 <- buttonNewWithLabel "button" + boxPackStart box button3 packing padding + button4 <- case packing of [_$_] + PackNatural -> buttonNewWithLabel "PackNatural" + PackRepel -> buttonNewWithLabel "PackRepel" + PackGrow -> buttonNewWithLabel "PackGrow" + boxPackStart box button4 packing padding [_$_] + button5 <- buttonNewWithLabel (show padding) + boxPackStart box button5 packing padding [_$_] + return box addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap5b.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap5b.hs 1 +-- GTK 2.0 Tutorial: Chapter 5b, Table + +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + set window [windowTitle := "Table", containerBorderWidth := 20, + windowDefaultWidth := 150, windowDefaultHeight := 100 ] + table <- tableNew 2 2 True + containerAdd window table + button1 <- buttonNewWithLabel "On" + onClicked button1 (buttonSwitch button1) + tableAttachDefaults table button1 0 1 0 1 + button2 <- buttonNewWithLabel "Off" + onClicked button2 (buttonSwitch button2) + tableAttachDefaults table button2 1 2 0 1 + button3 <- buttonNewWithLabel "Quit" + onClicked button3 mainQuit + tableAttachDefaults table button3 0 2 1 2 + onDestroy window mainQuit [_$_] + widgetShowAll window + mainGUI + +buttonSwitch :: Button -> IO () +buttonSwitch b = do + txt <- buttonGetLabel b + let newtxt = case txt of + "Off" -> "On" + "On" -> "Off" + buttonSetLabel b newtxt [_$_] + + addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap6a.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap6a.hs 1 +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + set window [windowTitle := "Pix", + containerBorderWidth := 10 ] + button <- buttonNew + onClicked button (putStrLn "button clicked") + box <- labelBox "info.xpm" "cool button" + containerAdd button box + containerAdd window button + widgetShowAll window + onDestroy window mainQuit + mainGUI + +labelBox :: FilePath -> String -> IO HBox +labelBox fn txt = do + box <- hBoxNew False 0 + set box [containerBorderWidth := 2 ] + image <- imageNewFromFile fn + label <- labelNew (Just txt) + boxPackStart box image PackNatural 3 [_$_] + boxPackStart box label PackNatural 3 + return box [_$_] addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap6b.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap6b.hs 1 +-- Chapter 7, Radio Button + +-- packeds not good! + +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + set window [windowTitle := "Radio Button", containerBorderWidth := 5 , + windowDefaultWidth := 200, windowDefaultHeight := 150 ] + box1 <- vBoxNew False 0 + containerAdd window box1 + box2 <- vBoxNew False 10 + containerSetBorderWidth box2 10 + boxPackStart box1 box2 PackNatural 0 + button1 <- radioButtonNewWithLabel "button 1" + boxPackStart box2 button1 PackNatural 0 + button2 <- radioButtonNewWithLabelFromWidget button1 "button 2" + boxPackStart box2 button2 PackNatural 0 + button3 <- radioButtonNewWithLabelFromWidget button2 "button 3" + boxPackStart box2 button3 PackNatural 0 + toggleButtonSetActive button2 True + onToggled button1 (setRadioState button1) + onToggled button2 (setRadioState button2) + onToggled button3 (setRadioState button3) + sep <- hSeparatorNew + boxPackStart box1 sep PackNatural 0 + box3 <- vBoxNew False 10 + containerSetBorderWidth box3 10 + boxPackStart box1 box3 PackNatural 0 + closeb <- buttonNewWithLabel "close" + boxPackStart box3 closeb PackNatural 0 + onClicked closeb mainQuit + widgetShowAll window + onDestroy window mainQuit + mainGUI + +setRadioState :: RadioButton -> IO () +setRadioState b = do + state <- toggleButtonGetActive b + label <- get b buttonLabel + putStrLn ("State " ++ label ++ " now is " ++ (show state)) + + addfile ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap7.hs hunk ./docs/tutorial/Tutorial_Port/Example_Code/GtkChap7.hs 1 +-- Chapter 9, Range Widgets, Example + +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + set window [windowTitle := "range controls", + windowDefaultWidth := 250 ] + mainbox <- vBoxNew False 10 + containerAdd window mainbox + containerSetBorderWidth mainbox 10 + + box1 <- hBoxNew False 0 + boxPackStart mainbox box1 PackGrow 0 + adj1 <- adjustmentNew 0.0 0.0 101.0 0.1 1.0 1.0 + vsc <- vScaleNew adj1 + boxPackStart box1 vsc PackGrow 0 + + box2 <- vBoxNew False 0 + boxPackStart box1 box2 PackGrow 0 [_$_] + + hsc1 <- hScaleNew adj1 + boxPackStart box2 hsc1 PackGrow 0 + hsc2 <- hScaleNew adj1 + boxPackStart box2 hsc2 PackGrow 0 + + chb <- checkButtonNewWithLabel "Display Value on Scale Widgets" + boxPackStart mainbox chb PackNatural 10 + toggleButtonSetActive chb True + + box3 <- hBoxNew False 10 + boxPackStart mainbox box3 PackNatural 0 + label1 <- labelNew (Just "Scale Value Position:") + boxPackStart box3 label1 PackNatural 0 + opt1 <- makeOpt1 + boxPackStart box3 opt1 PackNatural 0 + + box4 <- hBoxNew False 10 + boxPackStart mainbox box4 PackNatural 0 + label2 <- labelNew (Just "Scale Update Policy:") + boxPackStart box4 label2 PackNatural 0 + opt2 <- makeOpt2 + boxPackStart box4 opt2 PackNatural 0 + + adj2 <- adjustmentNew 1.0 0.0 5.0 1.0 1.0 0.0 + + box5 <- hBoxNew False 0 + containerSetBorderWidth box5 10 + boxPackStart mainbox box5 PackGrow 0 + label3 <- labelNew (Just "Scale Digits:") + boxPackStart box5 label3 PackNatural 10 + dsc <- hScaleNew adj2 + boxPackStart box5 dsc PackGrow 0 + scaleSetDigits dsc 0 + + adj3 <- adjustmentNew 1.0 1.0 101.0 1.0 1.0 0.0 + + box6 <- hBoxNew False 0 + containerSetBorderWidth box6 10 + boxPackStart mainbox box6 PackGrow 0 + label4 <- labelNew (Just "Scrollbar Page Size:") + boxPackStart box6 label4 PackNatural 10 + psc <- hScaleNew adj3 + boxPackStart box6 psc PackGrow 0 + scaleSetDigits psc 0 + + onToggled chb $ do toggleDisplay chb [hsc1,hsc2] + toggleDisplay chb [vsc] + + onChanged opt1 $ do setScalePos opt1 hsc1 [_$_] + setScalePos opt1 hsc2 + setScalePos opt1 vsc + + onChanged opt2 $ do setUpdatePol opt2 hsc1 [_$_] + setUpdatePol opt2 hsc2 + setUpdatePol opt2 vsc + + onValueChanged adj2 $ do setDigits hsc1 adj2 + setDigits hsc2 adj2 + setDigits vsc adj2 + + onValueChanged adj3 $ do val <- adjustmentGetValue adj3 + adjustmentSetPageSize adj1 val + + widgetShowAll window + onDestroy window mainQuit + mainGUI + +makeOpt1 :: IO ComboBox +makeOpt1 = do + cb <- comboBoxNewText + comboBoxAppendText cb "TOP" [_$_] + comboBoxAppendText cb "BOTTOM" + comboBoxAppendText cb "LEFT" [_$_] + comboBoxAppendText cb "RIGHT" [_$_] + comboBoxSetActive cb 0 + return cb + +setScalePos :: ScaleClass self => ComboBox -> self -> IO () +setScalePos cb sc = do + ntxt <- comboBoxGetActiveText cb + let pos = case ntxt of + (Just "TOP") -> PosTop + (Just "BOTTOM") -> PosBottom + (Just "LEFT") -> PosLeft + (Just "RIGHT") -> PosRight + Nothing -> error "GtkChap9.hs setScalePos: no position set" + scaleSetValuePos sc pos [_$_] + + [_$_] +makeOpt2 :: IO ComboBox +makeOpt2 = do + cb <- comboBoxNewText + comboBoxAppendText cb "Continuous" [_$_] + comboBoxAppendText cb "Discontinuous" + comboBoxAppendText cb "Delayed" [_$_] + comboBoxSetActive cb 0 + return cb + +setUpdatePol :: RangeClass self => ComboBox -> self -> IO () +setUpdatePol cb sc = do + ntxt <- comboBoxGetActiveText cb + let pol = case ntxt of + (Just "Continuous") -> UpdateContinuous + (Just "Discontinuous") -> UpdateDiscontinuous + (Just "Delayed") -> UpdateDelayed + Nothing -> error "GtkChap9.hs setUpdatePol: no policy set" + rangeSetUpdatePolicy sc pol [_$_] + +toggleDisplay :: ScaleClass self => CheckButton -> [self] -> IO () +toggleDisplay b scls = sequence_ (map change scls) where [_$_] + change sc = do st <- toggleButtonGetActive b + scaleSetDrawValue sc st + +setDigits :: ScaleClass self => self -> Adjustment -> IO () +setDigits sc adj = do val <- get adj adjustmentValue + set sc [scaleDigits := (round val) ] + + [_$_] addfile ./docs/tutorial/Tutorial_Port/Example_Code/info.xpm hunk ./docs/tutorial/Tutorial_Port/Example_Code/info.xpm 1 +/* XPM */ +static char *openfile[] = { +/* width height num_colors chars_per_pixel */ +" 20 19 66 2", +/* colors */ +".. c None", +".# c #000000", +".a c #dfdfdf", +".b c #7f7f7f", +".c c #006f6f", +".d c #00efef", +".e c #009f9f", +".f c #004040", +".g c #00bfbf", +".h c #ff0000", +".i c #ffffff", +".j c #7f0000", +".k c #007070", +".l c #00ffff", +".m c #00a0a0", +".n c #004f4f", +".o c #00cfcf", +".p c #8f8f8f", +".q c #6f6f6f", +".r c #a0a0a0", +".s c #7f7f00", +".t c #007f7f", +".u c #5f5f5f", +".v c #707070", +".w c #00f0f0", +".x c #009090", +".y c #ffff00", +".z c #0000ff", +".A c #00afaf", +".B c #00d0d0", +".C c #00dfdf", +".D c #005f5f", +".E c #00b0b0", +".F c #001010", +".G c #00c0c0", +".H c #000f0f", +".I c #00007f", +".J c #005050", +".K c #002f2f", +".L c #dfcfcf", +".M c #dfd0d0", +".N c #006060", +".O c #00e0e0", +".P c #00ff00", +".Q c #002020", +".R c #dfc0c0", +".S c #008080", +".T c #001f1f", +".U c #003f3f", +".V c #007f00", +".W c #00000f", +".X c #000010", +".Y c #00001f", +".Z c #000020", +".0 c #00002f", +".1 c #000030", +".2 c #00003f", +".3 c #000040", +".4 c #00004f", +".5 c #000050", +".6 c #00005f", +".7 c #000060", +".8 c #00006f", +".9 c #000070", +"#. c #7f7f80", +"## c #9f9f9f", +/* pixels */ +"........................................", +"........................................", +"........................................", +".......................#.#.#............", +".....................#.......#...#......", +"...............................#.#......", +".......#.#.#.................#.#.#......", +".....#.y.i.y.#.#.#.#.#.#.#..............", +".....#.i.y.i.y.i.y.i.y.i.#..............", +".....#.y.i.y.i.y.i.y.i.y.#..............", +".....#.i.y.i.y.#.#.#.#.#.#.#.#.#.#.#....", +".....#.y.i.y.#.s.s.s.s.s.s.s.s.s.#......", +".....#.i.y.#.s.s.s.s.s.s.s.s.s.#........", +".....#.y.#.s.s.s.s.s.s.s.s.s.#..........", +".....#.#.s.s.s.s.s.s.s.s.s.#............", +".....#.#.#.#.#.#.#.#.#.#.#..............", +"........................................", +"........................................", +"........................................" +}; addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap3a.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap3a.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap3b.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap3b.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap4.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap4.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap5a1.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap5a1.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap5a2.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap5a2.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap5b.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap5b.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap6a.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap6a.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap6b.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap6b.png addfile ./docs/tutorial/Tutorial_Port/Images/GtkChap7.png binary ./docs/tutorial/Tutorial_Port/Images/GtkChap7.png addfile ./docs/tutorial/Tutorial_Port/chap1.html hunk ./docs/tutorial/Tutorial_Port/chap1.html 1 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> + +<html> +<head> + <meta name="generator" content= + "HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org"> + <meta http-equiv="CONTENT-TYPE" content= + "text/html; charset=us-ascii"> + + <title>Gtk2Hs Tutorial</title> +</head> + +<body lang="en-US" text="#000000" link="#0000FF" vlink="#840084" +bgcolor="#FFFFFF" dir="ltr"> + <h2 align="center"><a name="Gtk2Hs-TUT" id= + "Gtk2Hs-TUT"></a><a name="AEN2" id="AEN2"></a>Gtk2Hs + Tutorial (part 1)</h2> + + <h3>Hans van Thiel</h3> + <hr> + <br> + <br> + + <h3>The start of a port and adaptation to Gtk2Hs of the:</h3> + + <h3>GTK+2.0 Tutorial by</h3> + + <h3><a name="AEN6" id="AEN6"></a>Tony Gale</h3> + + <h3><a name="AEN9" id="AEN9"></a>Ian Main</h3> + + <h3><a name="AEN12" id="AEN12"></a>& the GTK team</h3> + <hr> + + <dl> + <dt><b>Table of Contents</b></dt> + + <dt><br> + <br> + Introduction and Overview: not available yet...</dt> + + <dt><br> + <a href="chap3.html">Getting Started</a></dt> + + <dt><br> + <a href="chap4.html">Packing Widgets</a></dt> + + <dt><br> + <a href="chap5a.html">Packing Demonstration Program</a></dt> + + <dt><br> + <a href="chap5b.html">Packing Using Tables</a></dt> + + <dt><br> + <a href="chap6.html">The Button Widget</a></dt> + + <dt><br> + <a href="chap7.html">Adjustments, Scale and Range</a></dt> + </dl><br> + <hr> + <br> + + <h1><a name="CH-COPYRIGHT" id="CH-COPYRIGHT"></a>Tutorial + Copyright and Permissions Notice</h1> + + <p>The GTK Tutorial is Copyright (C) 1997 Ian Main.</p> + + <p>Copyright (C) 1998-2002 Tony Gale.</p> + + <p>Copyright (C) 2007 Hans van Thiel</p> + + <p>Permission is granted to make and distribute verbatim copies + of this manual provided the copyright notice and this permission + notice are preserved on all copies.</p> + + <p>Permission is granted to copy and distribute modified versions + of this document under the conditions for verbatim copying, + provided that this copyright notice is included exactly as in the + original, and that the entire resulting derived work is + distributed under the terms of a permission notice identical to + this one.</p> + + <p>Permission is granted to copy and distribute translations of + this document into another language, under the above conditions + for modified versions.</p> + + <p>If you are intending to incorporate this document into a + published work, please contact the maintainer, and we will make + an effort to ensure that you have the most up to date information + available.</p> + + <p>There is no guarantee that this document lives up to its + intended purpose. This is simply provided as a free resource. As + such, the authors and maintainers of the information provided + within can not make any guarantee that the information is even + accurate.</p> + <hr> + + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0"> + <tr valign="top"> + <td width="33%"> + <p align="left"><br></p> + </td> + + <td width="34%"> + <p align="center"><br></p> + </td> + + <td width="33%"> + <p align="right"><a href="chap3.html">Next + >>></a></p> + </td> + </tr> + + <tr valign="top"> + <td width="33%"> + <p align="left"><br></p> + </td> + + <td width="34%"> + <p align="center"> </p> + </td> + + <td width="33%"> + <p align="right"><br></p> + </td> + </tr> + </table> +</body> +</html> addfile ./docs/tutorial/Tutorial_Port/chap3.html hunk ./docs/tutorial/Tutorial_Port/chap3.html 1 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> + +<html> +<head> + <meta name="generator" content= + "HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org"> + <meta http-equiv="CONTENT-TYPE" content= + "text/html; charset=us-ascii"> + + <title>Getting Started</title> +</head> + +<body lang="en-US" text="#000000" link="#0000FF" vlink="#840084" +bgcolor="#FFFFFF" dir="ltr"> + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0"> + <tr> + <th colspan="3"> + <p align="center">Gtk2Hs Tutorial</p> + </th> + </tr> + + <tr valign="bottom"> + <td width="10%"> + <p align="left"><a href= + "chap1.html"><<<Previous</a></p> + </td> + + <td width="80%"></td> + + <td width="10%"> + <p align="right"><a href="chap4.html">Next + >>></a></p> + </td> + </tr> + </table> + <hr> + + <h3><a name="CH-GETTINGSTARTED" id= + "CH-GETTINGSTARTED"></a>Getting Started</h3> + + <p>The first thing to do, of course, is download Gtk2Hs and + install it. You can always get the latest version from <a href= + "http://haskell.org/gtk2hs/">http://haskell.org/gtk2hs/</a> and + several Linux versions have their own Gtk2Hs packages. For + Windows there is an installer available.</p> + + <p>The next thing is to open the Gtk2Hs API reference + documentation for your version. You will need to use this + extensively to be able to find the names for widgets, methods, + attributes and signals you might want to use. The <i>contents</i> + list all modules and there is also an <i>index</i>. Inside each + module description there is also a class hierarchy. If a method, + attribute or signal you expect is missing, it might belong to one + of the super classes of which your widget type is an + instance.</p> + + <p>To begin our introduction to Gk2Hs, we'll start with the + simplest program possible. This program will create a 200x200 + pixel window and has no way of exiting except to be killed by + using the shell.</p> + + <p><img src="./Images/GtkChap3a.png" align="bottom" alt= + "GtkChap3a"></p> + + <table summary="haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +import Graphics.UI.Gtk + +main :: IO () +main = do [_$_] + initGUI + window <- windowNew + widgetShowAll window + mainGUI +</pre> + </td> + </tr> + </table> + + <p>You can compile the above program with the Glasgow Haskell + Compiler (GHC) using:</p> + + <p><tt>ghc --make GtkChap3a.hs -o Chap3a</tt></p> + + <p>assuming GtkChap3a.hs is the filename. Alternatively you can + use the interactive GHCi, for earlier and later versions of + Gtk2Hs. (Because of threading problems intermediate versions will + not work interactively. Gtk2Hs does not work with Hugs.)</p> + + <p>The first line imports the Gtk2Hs graphics library.</p> + + <p>All Gtk2Hs programs run in main and the first line:</p> + + <table summary="haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> + initGUI +</pre> + </td> + </tr> + </table> + + <p>is called in all Gk2Hs applications. The next two lines of + code create and display a window.</p> + + <table summary="haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> + window <- windowNew + widgetShowAll window +</pre> + </td> + </tr> + </table> + + <p>Rather than create a window of 0x0 size, a window without + children is set to 200x200 by default so you can still manipulate + it. Widgets that can be visible (not all can) may be shown or + hidden using their own methods, but the second line works on a + widget (here the window) and all its children.</p> + + <p>The last line enters the Gtk2Hs main processing loop.</p> + + <table summary="haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> + mainGUI +</pre> + </td> + </tr> + </table> + + <p>mainGUI is another call you will see in every Gtk2Hs + application. When control reaches this point, Gtk2Hs will sleep + waiting for X events (such as button or key presses), timeouts, + or file IO notifications to occur. In our simple example, + however, events are ignored.</p> + + <h3><a name="SEC-HELLOWORLD" id="SEC-HELLOWORLD"></a>Hello World + in Gtk2Hs</h3> + + <p>Now for a program with a widget (a button). It's the classic + hello world à la Gtk2Hs.</p> + + <p><img src="./Images/GtkChap3b.png" name="graphics2" align= + "bottom" alt="GtkChap3b" id="graphics2"></p> + + <p>If the button is clicked it will display the text <i>Hello + World</i>. This is implemented in the Haskell function + <i>hello</i> with a button <i>b</i> as its argument. The type + declaration actually states the type variable <i>o</i> is an + instance of class <i>ButtonClass</i>. Gtk2Hs extensively uses + Haskell classes to map the object hierarchy of the original Gtk + widgets. Each widget in Gtk2Hs, of course, has a Haskell + type.</p> + + <p>Widgets, and the classes their types belong to, usually have + attributes. These can be set either by named methods or by the + general <i>set</i> function, which uses a list like notation as + shown below. Of special interest here is the + <i>containerChild</i> attribute of the window (actually a super + class of the window) which states the relationship with the + button. Because of this <i>widgetShowAll window</i> will also + make the button visible.</p> + + <p>Widgets are connected to other widgets in a graphical + dependency tree (not to be confused with the class hierarchy). + Gtk2hs also works with the Glade visual interface designer and, + if you use Glade, such connections are visible in the <i>Widget + tree</i> window. There is a separate introductory tutorial on how + to use Glade with Gtk2Hs.</p> + + <table summary="haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +import Graphics.UI.Gtk + +hello :: (ButtonClass o) => o -> IO () +hello b = set b [buttonLabel := "Hello World"] + +main :: IO () +main = do [_$_] + initGUI + window <- windowNew + button <- buttonNew + set window [windowDefaultWidth := 200, windowDefaultHeight := 200, + containerChild := button , containerBorderWidth := 10 ] + onClicked button (hello button) + onDestroy window mainQuit + widgetShowAll window + mainGUI [_$_] +</pre> + </td> + </tr> + </table> + <hr> + + <p>Gtk2Hs is event driven. The mainGUI function will sleep until + something happens, like a mouse being clicked, a window being + destroyed or something else typical for a widget. Such events + then trigger signals which in turn trigger user defined functions + to be evaluated. In this case the <i>onClicked</i> signal, + emitted by the user clicking the button, is linked to the text + being displayed on the same button. When the user destroys the + window, unlike as with the first program, <i>main</i> now exits + cleanly.</p> + + <p><br> + <br></p> + + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0"> + <tr valign="top"> + <td width="33%"> + <p align="left"><a href="chap1.html"><<< + Previous</a></p> + </td> + + <td width="34%"> + <p align="center"><a href="chap1.html">Home</a></p> + </td> + + <td width="33%"> + <p align="right"><a href="chap4.html">Next + >>></a></p> + </td> + </tr> + + <tr valign="top"> + <td width="33%"> + <p align="left">Contents</p> + </td> + + <td width="34%"> + <p align="center"> </p> + </td> + + <td width="33%"> + <p align="right">Packing Widgets</p> + </td> + </tr> + </table> + + <p><br> + <br></p> +</body> +</html> addfile ./docs/tutorial/Tutorial_Port/chap4.html hunk ./docs/tutorial/Tutorial_Port/chap4.html 1 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> + +<html> +<head> + <meta name="generator" content= + "HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org"> + + <title>Packing Widgets</title> +</head> + +<body lang="en-US" text="#000000" link="#0000FF" vlink="#840084" +bgcolor="#FFFFFF" dir="ltr"> + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0" style= + "page-break-before: always"> + <tr> + <th colspan="3"> + <p align="center">GTK2Hs Tutorial</p> + </th> + </tr> + + <tr valign="bottom"> + <td width="10%"> + <p align="left"><a href= + "chap3.html"><<<Previous</a></p> + </td> + + <td width="80%"></td> + + <td width="10%"> + <p align="right"><a href="chap5a.html">Next + >>></a></p> + </td> + </tr> + </table> + <hr> + + <h1><a name="CH-PACKINGWIDGETS" id= + "CH-PACKINGWIDGETS"></a>Packing Widgets</h1> + + <p>When creating an application, you'll want to put more than one + widget inside a window. Our first <i>helloworld</i> example only + used one widget so we could simply use a <i>set</i> (of the + <i>containerChild</i> attribute) or a <i>containerAdd</i> to + "pack" the widget into the window. But when you want to put more + than one widget into a window, how do you control where that + widget is positioned? This is where packing comes in.</p> + + <h1><a name="SEC-THEORYOFPACKINGBOXES" id= + "SEC-THEORYOFPACKINGBOXES"></a>Theory of Packing Boxes</h1> + + <p>Most packing is done by creating boxes. These are invisible + widget containers that we can pack our widgets into which come in + two forms, a horizontal box, and a vertical box. When packing + widgets into a horizontal box, the objects are inserted + horizontally from left to right or right to left depending on the + call used. In a vertical box, widgets are packed from top to + bottom or vice versa. You may use any combination of boxes inside + or beside other boxes to create the desired effect.</p> + + <p>To create a new horizontal box, we use <i>hBoxNew</i>, and for + vertical boxes, <i>vBoxNew</i>. Both take a Bool and an Int + parameter. The first will give all children equal space + allotments if set True and the second sets the number of pixels + to place by default between the children.</p> + + <p>The <i>boxPackStart</i> and <i>boxPackEnd</i> functions are + used to place objects inside of these containers. The + <i>boxPackStart</i> function will start at the top and work its + way down in a vbox, and pack left to right in an hbox. + <i>boxPackEnd</i> will do the opposite, packing from bottom to + top in a vbox, and right to left in an hbox. Using these + functions allows us to right justify or left justify our widgets + and may be mixed in any way to achieve the desired effect. We + will use <i>boxPackStart</i> in most of our examples. An object + may be another container or a widget. In fact, many widgets are + actually containers themselves, including the button, but we + usually only use a label inside a button.</p> + + <p><img src="Images/GtkChap4.png" name="graphics1" alt="GtkChap4" + align="bottom" width="210" height="229" border="0" id= + "graphics1"></p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="0" bgcolor="#E0E0E0"> + <col width="256*"> + + <tr> + <td width="100%"> + <pre> +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + hbox <- hBoxNew True 10 + button1 <- buttonNewWithLabel "Button 1" + button2 <- buttonNewWithLabel "Button 2" + set window [windowDefaultWidth := 200, windowDefaultHeight := 200, + containerBorderWidth := 10, containerChild := hbox ] + boxPackStart hbox button1 PackGrow 0 + boxPackStart hbox button2 PackGrow 0 + widgetShowAll window + onDestroy window mainQuit + mainGUI +</pre> + </td> + </tr> + </table> + + <p><br> + <br></p> + + <p>By using these calls, GTK knows where you want to place your + widgets so it can do automatic resizing and other nifty things. + The <i>Packing</i> parameter specifies the way the widgets in the + container behave when the window is resized. <i>PackNatural</i> + means the widgets will retain their size and stay where they are, + <i>PackGrow</i> <span style="font-style: normal">means they will + be resized, and using</span> <i>PackRepel</i> t<span style= + "font-style: normal">he widgets will be padded equally on both + sides. The last parameter is an Int, which specifies any extra + padding to be put between this child and its + neighbours.</span></p> + + <p style="font-style: normal">Note that the packing only applies + to the dimension of the box. If, for example, you specify + <i>PackNatural</i> instead of <i>Packgrow</i> in the above, + resizing horizontally will keep the buttons at their original + size, but resizing vertically will also resize the buttons. This + is because the buttons are placed homogoneously in the horizontal + box (first parameter <i>True</i>) and the box itself will resize + with the window. The next example will make the effects more + clear.</p> + <hr> + + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0"> + <tr valign="top"> + <td width="33%"> + <p align="left"><a href="chap3.html"><<< + Previous</a></p> + </td> + + <td width="34%"> + <p align="center"><a href="chap1.html">Home</a></p> + </td> + + <td width="33%"> + <p align="right"><a href="chap5a.html">Next + >>></a></p> + </td> + </tr> + + <tr valign="top"> + <td width="33%"> + <p align="left">Getting Started</p> + </td> + + <td width="34%"> + <p align="center"> </p> + </td> + + <td width="33%"> + <p align="right">Packing Demonstration Program</p> + </td> + </tr> + </table> + + <p><br> + <br></p> +</body> +</html> addfile ./docs/tutorial/Tutorial_Port/chap5a.html hunk ./docs/tutorial/Tutorial_Port/chap5a.html 1 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> + +<html> +<head> + <meta name="generator" content= + "HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org"> + <meta http-equiv="CONTENT-TYPE" content= + "text/html; charset=us-ascii"> + + <title>Packing Demonstration Program</title> +</head> + +<body lang="en-US" text="#000000" link="#0000FF" vlink="#840084" +bgcolor="#FFFFFF" dir="ltr"> + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0" style= + "page-break-before: always"> + <tr> + <th colspan="3"> + <p align="center">Gtk2HsTutorial</p> + </th> + </tr> + + <tr valign="bottom"> + <td width="10%"> + <p align="left"><a href= + "chap4.html"><<<Previous</a></p> + </td> + + <td width="80%"> + <p align="center">Packing Demonstration</p> + </td> + + <td width="10%"> + <p align="right"><a href="chap5b.html">Next + >>></a></p> + </td> + </tr> + </table> + <hr> + + <h1><a name="SEC-PACKINGDEMONSTRATIONPROGRAM" id= + "SEC-PACKINGDEMONSTRATIONPROGRAM"></a>Packing Demonstration + Program</h1> + + <p>The base of all widgets here is a vertical box, which itself + is a child of the window. The child widgets are not displayed + homogeneously and there is no additional spacing (other than the + standard spacing). There are 6 horizontal boxes in the vertical + box, as defined by the function makeBox, which has the type as + shown. Furthermore, there are 2 labels in the vertical box as + well as 2 horizontal separators. The last widget is the quit + button, whose <i>onClicked</i> signal is attached to the + <i>mainQuit</i> function.</p> + + <p>The separators are created with <i>hSeparatorNew</i> and they + are spaced by <i>boxPackStart</i> with a padding of 10 pixels. + The labels are created by <i>labelNew</i> which takes a <i>Maybe + String</i> and their positioning is set by + <i>miscSetAlignment</i> to be left and top justified.</p> + + <p><br></p> + + <p><img src="Images/GtkChap5a1.png" name="graphics1" alt= + "GtkChap5a" align="bottom" width="505" height="328" border="0" + id="graphics1"></p> + + <p>The function <i>makeBox :: Bool -> Int -> Packing -> + Int -> IO HBox</i> demonstrates how Gtk2Hs widgets fit into + the Haskell type system. <i>Packing</i> is just a type like + <i>Int</i> and <i>Bool</i> and <i>IO HBox is just like IO + String</i> in the usual IO. The function creates 5 buttons, + labels them with the appropriate text and packs them into a + horizontal box. The function is then used in the main program to + create the desired ways of packing.</p><br> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + vbox <- vBoxNew False 0 + set window [containerBorderWidth := 10, [_$_] + windowTitle := "Packing Demonstration", + containerChild := vbox ] + label1 <- labelNew (Just "hBoxNew False 0") + miscSetAlignment label1 0 0 + boxPackStart vbox label1 PackNatural 0 + box1 <- makeBox False 0 PackNatural 0 + boxPackStart vbox box1 PackNatural 0 + box2 <- makeBox False 0 PackRepel 0 + boxPackStart vbox box2 PackNatural 0 [_$_] + box3 <- makeBox False 0 PackGrow 0 + boxPackStart vbox box3 PackNatural 0 + sep1 <- hSeparatorNew + boxPackStart vbox sep1 PackNatural 10 [_$_] + label2 <- labelNew (Just "hBoxNew True 0") + miscSetAlignment label2 0 0 + boxPackStart vbox label2 PackNatural 0 + box4 <- makeBox True 0 PackNatural 0 + boxPackStart vbox box4 PackNatural 0 + box5 <- makeBox True 0 PackRepel 0 + boxPackStart vbox box5 PackNatural 0 [_$_] + box6 <- makeBox False 0 PackGrow 0 + boxPackStart vbox box6 PackNatural 0 + sep <- hSeparatorNew + boxPackStart vbox sep PackNatural 10 [_$_] + quitbox <- hBoxNew False 0 + boxPackStart vbox quitbox PackNatural 0 + quitbutton <- buttonNewWithLabel "Quit" + boxPackStart quitbox quitbutton PackRepel 0 + onClicked quitbutton mainQuit [_$_] + onDestroy window mainQuit [_$_] + widgetShowAll window + mainGUI + + +makeBox :: Bool -> Int -> Packing -> Int -> IO HBox +makeBox homogeneous spacing packing padding = do + box <- hBoxNew homogeneous spacing + button1 <- buttonNewWithLabel "boxPackStart" + boxPackStart box button1 packing padding + button2 <- buttonNewWithLabel "box" + boxPackStart box button2 packing padding + button3 <- buttonNewWithLabel "button" + boxPackStart box button3 packing padding + button4 <- case packing of [_$_] + PackNatural -> buttonNewWithLabel "PackNatural" + PackRepel -> buttonNewWithLabel "PackRepel" + PackGrow -> buttonNewWithLabel "PackGrow" + boxPackStart box button4 packing padding [_$_] + button5 <- buttonNewWithLabel (show padding) + boxPackStart box button5 packing padding [_$_] + return box +</pre> + </td> + </tr> + </table> + + <p>The image below shows the effects of resizing the window + horizontally. In the first group, with homogeneous <i>False</i> + horizontal resizing leaves the first row of buttons as it is, + spaces the second row evenly, and enlarges the buttons in the + third row. In the second group the buttons are set to be packed + homogeneously, and the first 2 rows will look the same. Resizing + the window vertically just add extra space at the end, because + the vertical box was initialized with <i>False</i>.</p><img src= + "Images/GtkChap5a2.png" name="graphics2" alt="GtkChap5a resized" + align="bottom" id="graphics2"><br> + <hr> + + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0"> + <tr valign="top"> + <td width="33%"> + <p align="left"><a href="chap4.html"><<< + Previous</a></p> + </td> + + <td width="34%"> + <p align="center"><a href="chap1.html">Home</a></p> + </td> + + <td width="33%"> + <p align="right"><a href="chap5b.html">Next + >>></a></p> + </td> + </tr> + + <tr valign="top"> + <td width="50%"> + <p align="left">Packing Widgets</p> + </td> + + <td width="50%"> + <p align="right">Packing Using Tables</p> + </td> + </tr> + </table> + + <p><br> + <br></p> +</body> +</html> addfile ./docs/tutorial/Tutorial_Port/chap5b.html hunk ./docs/tutorial/Tutorial_Port/chap5b.html 1 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> + +<html> +<head> + <meta name="generator" content= + "HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org"> + <meta http-equiv="CONTENT-TYPE" content= + "text/html; charset=us-ascii"> + + <title>Packing Using Tables</title> +</head> + +<body lang="en-US" text="#000000" link="#0000FF" vlink="#840084" +bgcolor="#FFFFFF" dir="ltr"> + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0"> + <tr> + <th colspan="3"> + <p align="center">Gtk2Hs Tutorial</p> + </th> + </tr> + + <tr valign="bottom"> + <td width="10%"> + <p align="left"><a href="chap5a.html"><<< + Previous</a></p> + </td> + + <td width="80%"> + <p align="center">Tables</p> + </td> + + <td width="10%"> + <p align="right"><a href="chap6.html">Next + >>></a></p> + </td> + </tr> + </table> + <hr> + + <h2><a name="SEC-PACKINGUSINGTABLES" id= + "SEC-PACKINGUSINGTABLES"></a>Packing Using Tables</h2> + + <p>Let's take a look at another way of packing - Tables. These + can be extremely useful in certain situations.</p> + + <p>Using tables, we create a grid that we can place widgets in. + The widgets may take up as many spaces as we specify.</p> + + <p>The first thing to look at, of course, is the <i>tableNew</i> + function:</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +tableNew :: Int -> Int -> Bool -> IO Table +</pre> + </td> + </tr> + </table> + + <p>The first argument is the number of rows to make in the table, + while the second, obviously, is the number of columns.</p> + + <p>The boolean argument (homogeneous) has to do with how the + table's boxes are sized. If homogeneous is TRUE, the table boxes + are resized to the size of the largest widget in the table. If + homogeneous is FALSE, the size of a table boxes is dictated by + the tallest widget in its same row, and the widest widget in its + column.</p> + + <p>The rows and columns are laid out from 0 to n, where n was the + number specified in the call to <i>tableNew</i>. So, if you + specify rows = 2 and columns = 2, the layout would look something + like this:</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> + 0 1 2 +0+----------+----------+ + | | | +1+----------+----------+ + | | | +2+----------+----------+ +</pre> + </td> + </tr> + </table> + + <p>Note that the coordinate system starts in the upper left hand + corner. To place a widget into a box, use the following + function:</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +tableAttach :: (TableClass self, WidgetClass child) => [_$_] + self -- self - the table + -> child -- child - The widget to add. + -> Int [_$_] +-- leftAttach - the column number to attach the left side of a child widget to. + -> Int [_$_] +-- rightAttach - the column number to attach the right side of a child widget to. + -> Int -- topAttach - the row number to attach the top of a child widget to. + -> Int -- bottomAttach - the row number to attach the bottom of a child widget to. + -> [AttachOptions] [_$_] +-- xoptions - Used to specify the properties of the child widget when the table is resized. + -> [AttachOptions] [_$_] +-- yoptions - The same as xoptions, except this field determines behaviour of vertical resizing. + -> Int [_$_] +-- xpadding - An integer value specifying the padding on the left and right of the widget being added to the table. + -> Int -- ypadding - The amount of padding above and below the child widget. + -> IO () +</pre> + </td> + </tr> + </table> + + <p>The first argument (self) is the table you've created and the + second (child) the widget you wish to place in the table.</p> + + <p>The left and right attach arguments specify where to place the + widget, and how many boxes to use. If you want a button in the + lower right table entry of our 2x2 table, and want it to fill + that entry <i>only</i>, left_attach would be = 1, right_attach = + 2, top_attach = 1, bottom_attach = 2.</p> + + <p>Now, if you wanted a widget to take up the whole top row of + our 2x2 table, you'd use left_attach = 0, right_attach = 2, + top_attach = 0, bottom_attach = 1.</p> + + <p>The xoptions and yoptions are used to specify packing options + and the list may contain more than one to allow multiple + options.</p> + + <p>These options are:</p> + + <dl> + <dt><tt>Fill</tt></dt> + + <dd>If the table box is larger than the widget, and + <tt>Fill</tt> is specified, the widget will expand to use all + the room available.</dd> + + <dt><tt>Shrink</tt></dt> + + <dd>If the table widget was allocated less space then was + requested (usually by the user resizing the window), then the + widgets would normally just be pushed off the bottom of the + window and disappear. If <tt>Shrink</tt> is specified, the + widgets will shrink with the table.</dd> + + <dt><tt>Expand</tt></dt> + + <dd>This will cause the table to expand to use up any remaining + space in the window.</dd> + </dl> + + <p>Padding is just like in boxes, creating a clear area around + the widget specified in pixels.</p> + + <p><i>tableAttach</i> has many options. So, there's a + shortcut:</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +tableAttachDefaults :: (TableClass self, WidgetClass widget) => self [_$_] + -> widget -- widget - The child widget to add. + -> Int [_$_] +-- leftAttach - The column number to attach the left side of the child widget to. + -> Int [_$_] +-- rightAttach - The column number to attach the right side of the child widget to. + -> Int [_$_] +-- topAttach - The row number to attach the top of the child widget to. + -> Int [_$_] +-- bottomAttach - The row number to attach the bottom of the child widget to. + -> IO () +</pre> + </td> + </tr> + </table> + + <p>The values used for the <i>AttachOptions</i> are <tt>[Expand, + Fill]</tt>, and the padding is set to 0. The rest of the + arguments are identical to the previous function.</p> + + <p>We also have tableSetRowSpacing and tableSetColSpacing. These + place spacing at the specified row or column.</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +tableSetRowSpacing :: TableClass self=> self-> Int -> Int -> IO () +</pre> + </td> + </tr> + </table> + + <p>and,</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +tableSetColSpacing :: TableClass self => self -> Int -> Int -> IO () +</pre> + </td> + </tr> + </table> + + <p>The first <i>Int</i> argument is the row/column and the second + the spacing in pixels. Note that for columns, the space goes to + the right of the column, and for rows, the space goes below the + row.</p> + + <p>You can also set a consistent spacing of all rows and/or + columns with:</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +tableSetRowSpacings :: TableClass self=> self-> Int -> IO () +</pre> + </td> + </tr> + </table> + + <p>and,</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +tableSetColSpacings :: TableClass self => self -> Int -> IO () +</pre> + </td> + </tr> + </table> + + <p>Note that with these calls, the last row and last column do + not get any spacing.</p> + + <p><br> + <br></p> + + <h2><a name="SEC-TABLEPACKINGEXAMPLES" id= + "SEC-TABLEPACKINGEXAMPLES"></a>Table Packing Example</h2> + + <p>Here we make a window with three buttons in a 2x2 table. The + first two buttons will be placed in the upper row. A third, quit + button, is placed in the lower row, spanning both columns. Which + means it should look something like this:</p> + + <p><img src="Images/GtkChap5b.png" align="bottom" alt= + "Table Packing"></p> + + <p>Here's the source code:</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="2" bgcolor="#E0E0E0"> + <tr> + <td> + <pre> +import Graphics.UI.Gtk + +main :: IO () +main = do + initGUI + window <- windowNew + set window [windowTitle := "Table", containerBorderWidth := 20, + windowDefaultWidth := 150, windowDefaultHeight := 100 ] + table <- tableNew 2 2 True + containerAdd window table + button1 <- buttonNewWithLabel "On" + onClicked button1 (buttonSwitch button1) + tableAttachDefaults table button1 0 1 0 1 + button2 <- buttonNewWithLabel "Off" + onClicked button2 (buttonSwitch button2) + tableAttachDefaults table button2 1 2 0 1 + button3 <- buttonNewWithLabel "Quit" + onClicked button3 mainQuit + tableAttachDefaults table button3 0 2 1 2 + onDestroy window mainQuit [_$_] + widgetShowAll window + mainGUI + +buttonSwitch :: Button -> IO () +buttonSwitch b = do + txt <- buttonGetLabel b + let newtxt = case txt of + "Off" -> "On" + "On" -> "Off" + buttonSetLabel b newtxt [_$_] +</pre> + </td> + </tr> + </table> + <hr> + + <p>The <i>buttonSwitch</i> function is attached to both buttons + in the top row. The <i>buttonGetLabel</i> function is an example + of how to get an attribute from a widget using a standard method. + There is also a more general alternative <i>get</i> (analogous to + <i>set</i>) which takes a widget and an attribute. In the above + example this should be:</p> + + <table summary="Haskell code" width="100%" border="0" + cellpadding="2" cellspacing="0" bgcolor="#E0E0E0"> + <col width="256*"> + + <tr> + <td width="100%"> + <p>txt <- get b buttonLabel</p> + </td> + </tr> + </table> + + <p>with the same result.</p> + + <table summary="links to other pages" width="100%" border="0" + cellpadding="0" cellspacing="0"> + <tr valign="top"> + <td width="33%"> + <p align="left"><a href="chap5a.html"><<< + Previous</a></p> + </td> + + <td width="34%"> + <p align="center"><a href="chap1.html">Home</a></p> + </td> + + <td width="33%"> + <p align="right"><a href="chap6.html">Next + >>></a></p> + </td> + </tr> + + <tr valign="top"> + <td width="33%"> + <p align="left">Packing Demonstration</p> + </td> + + <td width="33%"> + <p align="right">Button Widget</p> + </td> + </tr> + </table> + + <p><br> + <br></p> +</body> +</html> addfile ./docs/tutorial/Tutorial_Port/chap6.html hunk ./docs/tutorial/Tutorial_Port/chap6.html 1 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> + +<html> +<head> + <meta name="generator" content= + "HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org"> + <meta http-equiv="CONTENT-TYPE" content= + "text/html; charset=us-ascii"> + + <title>The Button Widget</title> +</head> + +<body lang="en-US" text="#000000" link="#0000FF" vlink="#840084" +bgcolor... [truncated message content] |