The
Notebook
widget is a collection of "pages" that
overlap each other. Each page is different, and only one will
be visible at a time. Pages 'contain' some other widget, which
you must supply.
To create a new notebook widget:
NotebookNew :: IO Notebook
Once the notebook has been created, there are a number of functions and attributes to use and to customize it.The following attributes determine the position of the tabs, and whether they are visible at all.
notebookTabPos :: NotebookClass self => Attr self PositionType notebookShowTabs :: NotebookClass self => Attr self Bool
The PositionType has constructors
PosLeft
,
PosRight
,
PosTop
(the default) and
PosBottom.
Next we will look at how to add pages to the notebook. There are three ways, append, prepend and insert.
noteBookAppendPage :: (NotebookClass self, WidgetClass child) => self -> child -- the widget to use as the contents of the page -> String -- the label text -> IO Int -- the index (page number) of the new page (starting at 0)
The function
notebookPrependPage
has exactly the same signature.
It will, of course, return 0 as its index. The function
notebookInsertPage
takes the index at which to
insert the page as an additional parameter. You can remove
pages with
notebookRemovePage.
A
Notebook
is a container widget and you can use
other containers as a child, including horizontal and vertical
boxes. Therefore you can build quite complex pages, and set
their layouts with the usual packing functions.
The listed functions to add, prepend and insert pages only work with textual tabs. All three also have versions which allow for a popup menu to appear, and with those you can use any widget as a label.
notebookAppendPageMenu :: (NotebookClass self, WidgetClass child, WidgetClass tabLabel, WidgetClass menuLabel) => self -> child -- the widget to use as the contents of the page -> tabLabel -- the widget to use as the label of the page -> menuLabel -- the widget to use as the label of the popup menu -> IO Int -- the index (page number) of the new page (starting at 0)
notebookPrependPageMenu
and
notebookInsertPageMenu
will place the new page
first or at the designated index, respectively.
Some useful attributes (but see the API Documentation for more) are:
notebookScrollable :: NotebookClass self => Attr self Bool notebookCurrentPage :: NotebookClass self => Attr self Int notebookEnablePopup :: NotebookClass self => Attr self Bool
If the number of pages is large you can set
notebookScrollable
. Use
notebookCurrentPage
or the function
notebookSetCurrentPage
to open the notebook at
another page than the (default) first one. The attribute
notebookEnablePopup
determines whether the user's
clicking the right mouse button on a tab will show a popup menu
of all the available pages. That is, if the menu fuctions have
been defined.
A
Notebook
widget has its own signal handling
function:
onSwitchPage :: NotebookClass nb => nb -> (Int -> IO ()) -> IO (ConnectId nb)
The function you must supply takes a page index returned by
onSwitchPage
and must do some output.
The examples show a catalogue of
StockItem
icon sets in different ways.
Stock items were summarily discussed in chapter 4.5. Recall
that a
StockItem
is known throughout GTK+ (and Gtk2Hs).
The following function produces a list of all stock
identifiers.
stockListIds :: IO [StockId]
A
StockId
is a
String
and in Gtk2Hs has the form:
stockCopy
,
stockDialogError
etc. In GTK+ the corresponding
form is: gtk-copy, gtk-dialog-error and so on. The example
defines a function tabName to convert the GTK+ identifiers in
the StockId list to names for the notebook tabs. The function
myNewPage
uses
imageNewFromStock
to get the icon into an
Image
widget, which is then added to the page. It
returns the page index, but this is not used. To get a list of
all pages use
sequence
instead of
sequence_
Note that the icon size, in pixels, may be restricted. The default is 4 and the value used here, 6, is also allowed but a size of 8 produces a run time error with GHCi.
import Graphics.UI.Gtk import Data.Char (toUpper) main :: IO () main= do initGUI window <- windowNew set window [windowTitle := "Notebook Example 1", windowDefaultWidth := 300, windowDefaultHeight := 200 ] ntbk <- notebookNew containerAdd window ntbk set ntbk [notebookScrollable := True, notebookTabPos := PosBottom] stls <- stockListIds sequence_ (map (myNewPage ntbk) stls) onSwitchPage ntbk (putStrLn . ((++)"Page: ") . show) widgetShowAll window onDestroy window mainQuit mainGUI tabName :: StockId -> String tabName st = (drop 3) (conv st) where conv (x:[]) = x:[] conv (x:y:ys) | x == '-' = (toUpper y):(conv ys) | otherwise = x: (conv (y:ys)) myNewPage :: Notebook -> StockId -> IO Int myNewPage noteb stk = do img <- imageNewFromStock stk 6 pagenum <- notebookAppendPage noteb img (tabName stk) return pagenum
A second way to show the catalogue is to put the icons in the notebook tabs.
To do this we need the menu style of adding pages, and we've
also defined a menu tab consisting of the first letter of the
name string. The result is a popup menu consisting of 98
letters, which itself will scroll. It can simply be disabled
through the
notebookEnablePopup
attribute. The content of each
page is the Gtk2Hs stock item identifier (see
Graphics.UI.Gtk.General.StockItems).
import Graphics.UI.Gtk import Data.Char (toUpper) main :: IO () main= do initGUI window <- windowNew set window [windowTitle := "Notebook Example 2", windowDefaultWidth := 300, windowDefaultHeight := 200 ] ntbk <- notebookNew containerAdd window ntbk set ntbk [notebookScrollable := True, notebookEnablePopup := True, notebookTabPos := PosRight ] stls <- stockListIds sequence_ (map (myNewPage ntbk) stls) onSwitchPage ntbk (putStrLn . ((++)"Page: ") . show) widgetShowAll window onDestroy window mainQuit mainGUI tabName :: StockId -> String tabName st = (drop 3) (conv st) where conv (x:[]) = x:[] conv (x:y:ys) | x == '-' = (toUpper y):(conv ys) | otherwise = x: (conv (y:ys)) myNewPage :: Notebook -> StockId -> IO Int myNewPage noteb stk = do img <- imageNewFromStock stk 4 let nmstr = tabName stk men <- labelNew (Just ((take 1) nmstr)) cont <- labelNew (Just ("stock" ++ nmstr)) pagenum <- notebookAppendPageMenu noteb cont img men return pagenum