In this chapter, we discuss some of the multiple-item widgets in GTK--. The notebooks and toolbars sections in this chapter assume a decent understanding of the material in the container widgets chapter; go back and read it if you haven't already.
The Fixed widget places its children at relative coordinates, which you specify. The widgets can also be moved.
The constructor for Gtk::Fixed
is:
Gtk::Fixed();
Place children in the Fixed container using
void Gtk::Fixed::put(const Gtk::Widget &widget,
gint16 x,
gint16 y);
You can then move them using
void Gtk::Fixed::move(const Gtk::Widget &widget,
gint16 x,
gint16 y);
Although the Fixed container is a multiple-item widget, it doesn't provide STL-like access to its child widgets. If you'll need access to the widgets you put in the Fixed container, it will probably be a good idea for you to maintain your own list of them.
The following example illustrates how to use Gtk::Fixed
:
Source location: examples/fixed/fixed.cc
/* example-start fixed fixed.c */
#include <gtk--/button.h>
#include <gtk--/fixed.h>
#include <gtk--/window.h>
#include <gtk--/main.h>
class AppWindow : public Gtk::Window
{
gint x;
gint y;
public:
AppWindow ();
~AppWindow ();
void move_button(Gtk::Fixed*,Gtk::Button*);
/* Here we connect the "destroy" event to a signal handler */
virtual gint delete_event_impl (GdkEventAny*);
};
AppWindow::AppWindow()
: Gtk::Window(GTK_WINDOW_TOPLEVEL), x(50), y(50)
{
Gtk::Fixed *fixed;
Gtk::Button *button;
gint i;
/* Create a new window */
set_title("Fixed Container");
/* Sets the border width of the window. */
set_border_width (10);
/* Create a Fixed Container */
fixed = manage( new Gtk::Fixed() );
add(*fixed);
for (i = 1 ; i <= 3 ; i++) {
/* Creates a new button with the label "Press me" */
button = manage( new Gtk::Button("Press me") );
/* When the button receives the "clicked" signal, it will call the
* function move_button() passing it the Fixed Containter as its
* argument. */
button->clicked.connect(bind(slot(this,&AppWindow::move_button),fixed,button));
/* This packs the button into the fixed containers window. */
fixed->put (*button, i*50, i*50);
}
show_all ();
}
AppWindow::~AppWindow() {}
gint AppWindow::delete_event_impl (GdkEventAny*)
{
Gtk::Main::quit();
return 0;
}
/* This callback function moves the button to a new position
* in the Fixed container. */
void AppWindow::move_button( Gtk::Fixed *fixed,
Gtk::Button *button )
{
x = (x+30)%300;
y = (y+50)%300;
fixed->move(*button, x, y);
}
int main( int argc,
char *argv[] )
{
/* Initialise GTK */
Gtk::Main app(&argc, &argv);
AppWindow window;
/* Enter the event loop */
Gtk::Main::run ();
return(0);
}
/* example-end */
The Layout container is similar to the Fixed container except that it implements an infinite (where infinity is less than 2^32) scrolling area. Xwindows has a limitation where windows can be at most 32767 pixels wide or tall. The Layout container gets around this limitation by doing some exotic stuff using window and bit gravities, so that you can have smooth scrolling even when you have many child widgets in your scrolling area.
The Layout container operates similarly to the Viewport, but it contains multiple widgets instead of just one. If you'll be placing a large number of widgets in the viewing area, the Layout container is a good choice.
A Layout container is created using:
Gtk::Layout(Gtk::Adjustment &hadjustment,
Gtk::Adjustment &vadjustment);
Gtk::Layout();
These are exactly like the Viewport constructors, and work the same.
You can add and move widgets in the Layout container using the
following two methods, which work the same as their counterparts in
Gtk::Fixed
:
void Gtk::Layout::put(const Gtk::Widget &widget,
gint x,
gint y);
void Gtk::Layout::move(const Gtk::Widget &widget,
gint x,
gint y);
Unlike the Viewport and Fixed widgets, the maximum size of the Layout widget can be changed. This is done using:
void Gtk::Layout::set_size(guint width,
guint height);
Layout containers are one of the very few widgets in GTK-- that
actively repaint themselves as they are being changed (the vast
majority of the GTK-- widgets queue redrawing requests, which are
processed when control returns to the gtk_main()
function).
Therefore, when you're making a large number of changes in a Layout
container, it will repaint itself for each one. This is inefficient
and unnecessary. To temporarily stop the Layout container from
repainting itself, call
void Gtk::Layout::freeze();
Once you're done making your changes, call
void Gtk::Layout::thaw();
Calling thaw()
after a freeze()
causes the Layout widget to
repaint itself, making all your changes visible in one go.
You can use the following four methods to get and set the Layout container's adjustment widgets:
Gtk::Adjustment* Gtk::Layout::get_hadjustment();
Gtk::Adjustment* Gtk::Layout::get_vadjustment();
void Gtk::Layout::set_hadjustment(Gtk::Adjustment &adjustment);
void Gtk::Layout::set_vadjustment(Gtk::Adjustment &adjustment);
As with the Fixed container, Layout has no STL-like list associated with it; if you need a list of its child widgets, you're on your own.
Button boxes are a convenient way to quickly arrange a group of
buttons. They come in both horizontal (Gtk::HButtonBox
) and
vertical (Gtk::VButtonBox
) flavours; the two types are exactly
alike, except in name and orientation.
One interesting feature of button boxes is that all of them in a
given program can share certain settings, such as inter-button
spacing. The idea is that you can impose consistency on your
interface this way. Methods which change a given setting for all
button boxes have default
in their names.
The constructors for button boxes are:
Gtk::HButtonBox();
Gtk::VButtonBox();
Buttons are added to a button box using the add()
method:
Gtk::ButtonBox::add(GtkWidget &child);
You can set the spacing between the buttons using
void Gtk::ButtonBox::set_spacing_default(gint spacing);
gint Gtk::ButtonBox::get_spacing_default();
gint get_spacing();
void set_spacing(gint spacing);
set_spacing_default()
and get_spacing_default()
operate on
every button box in your program. Most of the button box
parameters have default
methods like this; we'll only point
them out here.
You can set and get a minimum size for the buttons using
gint Gtk::ButtonBox::get_child_size_default_width();
gint Gtk::ButtonBox::get_child_size_default_height();
void Gtk::ButtonBox::set_child_size_default(gint min_width,gint min_height);
gint Gtk::ButtonBox::get_child_size_width();
gint Gtk::ButtonBox::get_child_size_height();
void Gtk::ButtonBox::set_child_size(gint min_width,gint min_height);
You can also change the padding for each button in the button box using
gint Gtk::ButtonBox::get_child_ipadding_default_x();
gint Gtk::ButtonBox::get_child_ipadding_default_y();
void Gtk::ButtonBox::set_child_ipadding_default(gint ipad_x,gint ipad_y);
gint Gtk::ButtonBox::get_child_ipadding_x();
gint Gtk::ButtonBox::get_child_ipadding_y();
void Gtk::ButtonBox::set_child_ipadding(gint ipad_x,gint ipad_y);
Button boxes support several layout styles. These can be retrieved and changed using:
GtkButtonBoxStyle Gtk::ButtonBox::get_layout_default();
void Gtk::ButtonBox::set_layout_default(GtkButtonBoxStyle layout);
GtkButtonBoxStyle Gtk::ButtonBox::get_layout();
void Gtk::ButtonBox::set_layout(GtkButtonBoxStyle layout_style);
where layout
is one of
GTK_BUTTONBOX_DEFAULT_STYLE
GTK_BUTTONBOX_SPREAD
GTK_BUTTONBOX_EDGE
GTK_BUTTONBOX_START
GTK_BUTTONBOX_END
Run the example to see what these styles do.
There's also a function to set the layout and spacing at the same time:
void set_layout_spacing(GtkButtonBoxStyle layout,
gint spacing);
(There is no default
version of set_layout_spacing()
.)
Once again, button boxes don't provide an STL-like list container.
This example illustrates all the different layout settings for button boxes.
Source location: examples/buttonbox/buttonbox.cc
/* example-start buttonbox buttonbox.c */
#include <gtk--/box.h>
#include <gtk--/buttonbox.h>
#include <gtk--/frame.h>
#include <gtk--/button.h>
#include <gtk--/window.h>
#include <gtk--/main.h>
class BBox : public Gtk::Frame
{
public:
BBox (gint horizontal,
const Gtk::string& title,
gint spacing,
gint child_w,
gint child_h,
GtkButtonBoxStyle layout);
};
BBox::BBox (gint horizontal,
const Gtk::string& title,
gint spacing,
gint child_w,
gint child_h,
GtkButtonBoxStyle layout)
: Gtk::Frame(title)
{
Gtk::ButtonBox *bbox;
Gtk::Button *button;
if (horizontal)
bbox = manage( new Gtk::HButtonBox () );
else
bbox = manage( new Gtk::VButtonBox () );
bbox->set_border_width (5);
add (*bbox);
/* Set the appearance of the Button Box */
bbox->set_layout (layout);
bbox->set_spacing (spacing);
bbox->set_child_size (child_w, child_h);
button = manage( new Gtk::Button ("OK"));
bbox->add (*button);
button = manage( new Gtk::Button ("Cancel"));
bbox->add (*button);
button = manage( new Gtk::Button ("Help"));
bbox->add (*button);
}
class AppWindow : public Gtk::Window
{
public:
AppWindow ();
~AppWindow ();
virtual gint delete_event_impl (GdkEventAny*);
};
AppWindow::AppWindow()
: Gtk::Window(GTK_WINDOW_TOPLEVEL)
{
Gtk::Box *main_vbox;
Gtk::Box *vbox;
Gtk::Box *hbox;
Gtk::Frame *frame_horz;
Gtk::Frame *frame_vert;
set_title ("Button Boxes");
set_border_width (10);
main_vbox = manage( new Gtk::VBox(false, 0) );
add (*main_vbox);
frame_horz = manage( new Gtk::Frame ("Horizontal Button Boxes") );
main_vbox->pack_start (*frame_horz, true, true, 10);
vbox = manage( new Gtk::VBox (false, 0) );
vbox -> set_border_width (10);
frame_horz-> add (*vbox);
vbox->pack_start (*manage( new BBox (true, "Spread (spacing 40)",
40, 85, 20, GTK_BUTTONBOX_SPREAD)),
true, true, 0);
vbox->pack_start (*manage( new BBox (true, "Edge (spacing 30)",
30, 85, 20, GTK_BUTTONBOX_EDGE)),
true, true, 5);
vbox->pack_start (*manage( new BBox (true, "Start (spacing 20)",
20, 85, 20, GTK_BUTTONBOX_START)),
true, true, 5);
vbox->pack_start (*manage( new BBox (true, "end (spacing 10)",
10, 85, 20, GTK_BUTTONBOX_END)),
true, true, 5);
frame_vert = manage( new Gtk::Frame ("Vertical Button Boxes") );
main_vbox->pack_start (*frame_vert, true, true, 10);
hbox = manage( new Gtk::HBox (false, 0) );
hbox->set_border_width (10);
frame_vert->add (*hbox);
hbox->pack_start (*manage( new BBox (false, "Spread (spacing 5)",
5, 85, 20, GTK_BUTTONBOX_SPREAD)),
true, true, 0);
hbox->pack_start (*manage( new BBox (false, "Edge (spacing 30)",
30, 85, 20, GTK_BUTTONBOX_EDGE)),
true, true, 5);
hbox->pack_start (*manage( new BBox (false, "Start (spacing 20)",
20, 85, 20, GTK_BUTTONBOX_START)),
true, true, 5);
hbox->pack_start (*manage( new BBox (false, "End (spacing 10)",
10, 85, 20, GTK_BUTTONBOX_END)),
true, true, 5);
show_all ();
}
AppWindow::~AppWindow() {}
gint AppWindow::delete_event_impl (GdkEventAny*)
{
Gtk::Main::quit();
return 0;
}
int main( int argc,
char *argv[] )
{
Gtk::Main main (argc,argv);
AppWindow window;
/* Enter the event loop */
Gtk::Main::run ();
return(0);
}
/* example-end */
Toolbars are those rows of buttons one often sees just beneath the menubars of GUI applications. They're meant to give the user quick access to often-used commands, some of which might be buried deep in the menubar hierarchy.
Most people think of toolbars as a row of little square buttons with all-but-meaningless icons on them, such as those found in the products of certain very large software vendors. While GTK can't force your icons to have obvious meanings, it can help you make your toolbars less opaque, because GTK toolbars can contain almost any type of widget.
Still, toolbars do generally contain picture-buttons, so the GTK toolbar provides special support for this GUI idiom. In GTK--, you can use the toolbar helper objects to create special toolbar items having icons, labels, and tooltips. You can then let your users decide whether they want to see just the icons, or the icons and labels, or just the labels, as certain web-browsers let you do. This way, once your users have finally learnt the meaning of your pictograms, they can dispense with the captions, saving a bit of room in the window. (Picture-only toolbars also tend to look slicker in screenshots, as certain very large software vendors know all too well.)
For those of you interested in making meaningful icons - which I hope includes nearly all of you that will be releasing GUI software to the public - there's a classic work on the subject of symbols by the great Adrain Frutiger (designer of the typefaces Univers and Frutiger), entitled Signs and Symbols: Their Design and Meaning (English translation by Andrew Bluhm, published in the US by Watson-Guptill Publications, ISBN 0823048268), which probably everybody who designs anything graphic should read.
At any rate, here's the constructor for Gtk::Toolbar
:
Gtk::Toolbar(GtkOrientation orientation,
GtkToolbarStyle style );
where orientation
may be one of
GTK_ORIENTATION_HORIZONTAL
GTK_ORIENTATION_VERTICAL
and style
may be one of
GTK_TOOLBAR_TEXT
GTK_TOOLBAR_ICONS
GTK_TOOLBAR_BOTH
As previously noted, you can insert two types of elements into a
toolbar: toolbar items, and regular widgets. (Note that style
applies only to the specially made toolbar items and not to button
widgets inserted as widgets.) Both types of elements are inserted the
same way, using classes from the Gtk::Toolbar_Helpers
namespace.
The various helper objects are:
Element
- used for inserting arbitrary widgetsSpace
- a blank spot, used to separate groups of elementsButtonElem
- a regular button elementToggleElem
- a toggle-button elementRadioElem
- a radio-button elementHere's the constructor for Element
:
Element(Widget& w,
const nstring &tooltip_text=0,
const nstring &tooltip_private_text=0);
w
is the widget to insert, and tooltip_text
is the text for the
element's tooltip. You can ignore tooltip_private_text
.
The constructors for ButtonElem
and ToggleElem
are exactly
alike; each has three forms. Here are the ButtonElem
constructors:
// text + icon
ButtonElem(const nstring &text,
Widget &content,
SigC::Slot0<void> callback,
const nstring &tooltip_text=0,
const nstring &tooltip_private_text=0);
// icon only
ButtonElem(Widget &content,
SigC::Slot0<void> callback,
const nstring &tooltip_text=0,
const nstring &tooltip_private_text=0);
// text only
ButtonElem(const nstring &text,
SigC::Slot0<void> callback,
const nstring &tooltip_text=0,
const nstring &tooltip_private_text=0);
The only difference between these is whether they take an icon, text,
or both as arguments. text
is the text to display below the
icon. content
is the icon; note that any widget can be inserted
here, but generally this will be a pixmap or other display widget.
callback
is the callback to use for the button.
tooltip_text
will be displayed in the button's tooltip, and you
can safely ignore tooltip_private_text
.
The RadioElem
constructors are the same as those for
ButtonElem
and RadioElem
, but they take an additional
argument specifying the group for the radio button. Here they are:
// text + icon
RadioElem(Gtk::RadioButton_Helpers::Group& group,
const nstring& text,
Widget& content,
SigC::Slot0<void> callback=0,
const nstring& tooltip_text=0,
const nstring& tooltip_private_text=0);
// icon only
RadioElem(Gtk::RadioButton_Helpers::Group& group,
Widget& content,
SigC::Slot0<void> callback=0,
const nstring& tooltip_text=0,
const nstring& tooltip_private_text=0);
// text only
RadioElem(Gtk::RadioButton_Helpers::Group& group,
const nstring& text,
SigC::Slot0<void> callback=0,
const nstring& tooltip_text=0,
const nstring& tooltip_private_text=0);
The group
argument is the only addition here; it works exactly
like the group
argument for normal radio buttons. See the
Radio Buttons section for details.
The toolbar's contents are manipulated through an STL-like list, which
you can obtain using the tools()
method:
ToolList& tools();
For example, to add a text-only button tool to the toolbar, we could write
toolbar.tools().push_back(Gtk::Toolbar_Helpers::ButtonElem(
"Crash",slot(&crash_cb),"Causes the program to dump core");
Since it's inconvenient to have to type Gtk::Toolbar_Helpers
all
the time, you might want to add a using
declaration. However,
don't add a global using namespace Gtk::Toolbar_Helpers
declaration; place this only in some localised scope, to avoid clashes
with other Helpers
namespaces.
Here's an example program which displays a toolbar:
Source location: examples/toolbar/toolbar.cc
#include <stdio.h>
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gtk--/main.h>
#include <gtk--/toolbar.h>
#include <gtk--/button.h>
#include <gtk--/togglebutton.h>
#include <gtk--/radiobutton.h>
#include <gtk--/box.h>
#include <gtk--/window.h>
using namespace SigC;
class MainWindowClass : public Gtk::Window {
private:
Gtk::HBox main_hbox;
Gtk::HBox hbox;
Gtk::Button button;
Gtk::Toolbar toolbar;
void quit_pressed_cb(void);
void toolbar_button_cb(char *);
public:
MainWindowClass (void);
~MainWindowClass (void);
};
void MainWindowClass::toolbar_button_cb(char *c)
{
printf("toolbar_button_cb : %s\n",c);
}
MainWindowClass::MainWindowClass(void) : Gtk::Window(GTK_WINDOW_TOPLEVEL),
main_hbox(false,0),
hbox(false,0),
button("Quit")
{
set_usize(400,50);
add(main_hbox);
main_hbox.add(hbox);
hbox.pack_start(button,false,false,0);
hbox.pack_start(toolbar,false,false,0);
button.clicked.connect( slot(this,&MainWindowClass::quit_pressed_cb) );
{
using namespace Gtk::Toolbar_Helpers;
toolbar.tools().push_back(ButtonElem( "Click me",
bind<char*>( slot(this,&MainWindowClass::toolbar_button_cb),
"'Click me' button"),
"toolbar btn",""));
toolbar.tools().push_back(Space());
toolbar.tools().push_back(ButtonElem( "Click me too",
bind<char*>( slot(this, &MainWindowClass::toolbar_button_cb),
"'Click me too' button"),
"other toolbar btn", ""));
toolbar.tools().push_back(ToggleElem( "Toggle me",
bind<char*>( slot(this, &MainWindowClass::toolbar_button_cb),
"This is from a toggle connector"),
"toggle duh", ""));
Gtk::RadioButton::Group gr;
toolbar.tools().push_back(RadioElem(gr,"R1"));
toolbar.tools().push_back(RadioElem(gr,"R2"));
toolbar.tools().push_back(RadioElem(gr,"R3"));
}
toolbar.show();
button.show();
hbox.show();
main_hbox.show();
}
MainWindowClass::~MainWindowClass(void)
{}
void MainWindowClass::quit_pressed_cb(void)
{
Gtk::Main::quit();
}
int main(gint argc, gchar **argv)
{
Gtk::Main kit(argc,argv);
MainWindowClass main_window;
main_window.show();
kit.run();
return(0);
}
A notebook consists of a set of stacked "pages", each of which can contain one widget. Labelled "tabs" are provided to allow the user to select a page. These are useful in a large number of situations; you can make a single dialog do a lot of work using a notebook.
The Gtk::Notebook
widget uses an STL-like list to contain the
pages; these are constructed using helper objects. See the section on
using multiple-item widgets
for information on how GTK-- lists and helper objects work; the
notebook widget is used there as an example.
The constructor for Gtk::Notebook
takes no arguments:
Gtk::Notebook();
To insert pages into a notebook, use the TabElem
helper:
Gtk::Notebook_Helpers::TabElem(Widget& child,Widget& tab);
Gtk::Notebook_Helpers::TabElem(Widget& child,const string& s);
In both constructors, child
is the child widget to place in the
page itself. tab
, in the first constructor, is a widget to be
placed in the tab; this will generally be a display widget such as an
icon or a label. Most often, you'll be placing labels in a tab, and
the second constructor lets you pass a string for argument s
;
using this constructor will cause a label to be built from the string.
You can access the notebook's page list through the method
Gtk::Notebook_Helpers::PageList& Gtk::Notebook::pages();
A PageList
contains a list of Page
s, which provide some
useful methods (shown unqualified):
Widget* get_child();
Widget* get_tab();
void set_tab (Widget* tab=0);
void set_tab (Widget& tab);
void set_tab_text(const nstring& str=0);
bool get_expand();
bool get_fill();
GtkPackType get_pack();
void set_tab_packing(bool expand,bool fill,GtkPackType pack_type);
get_child()
and get_tab()
return the child and tab widgets
for the Page
, respectively.
set_tab()
lets you change a tab's widget. You can pass either a
pointer to the widget, or the widget itself. set_tab_text
sets
the tab to contain a new label, the text of which will be str
.
set_tab_packing
lets you change the packing parameters of the
tab-list. If expand
is set, then the tabs will be spaced out
evenly across the edge they're on; if fill
is set, the tabs
themselves will be sized such that there will be no space between
them. pack_type
can be either GTK_PACK_START
or
GTK_PACK_END
.
There are a number of things you can do to the notebook widget itself. GTK notebooks allow their tabs to be placed along any edge of the notebook's display area; you can set or retrieve the placement using
void Gtk::Notebook::set_tab_pos(GtkPositionType pos);
GtkPositionType Gtk::Notebook::get_tab_pos();
where pos
is one of
GTK_POS_LEFT
GTK_POS_RIGHT
GTK_POS_TOP
GTK_POS_BOTTOM
Here are some other useful Gtk::Notebook
methods (shown
unqualified):
gint get_current_page_num();
Returns the index of the current page.
Gtk::Widget* get_nth_page(gint page_number);
Returns the child widget of page page_number
.
gint page_num(const Gtk::Widget& child);
Returns the page number of the page containing the given child widget.
void set_page(gint page_number);
void next_page();
void prev_page();
set_page
selects page number page_number
. next_page()
and prev_page()
cause the next and previous pages to be selected,
respectively. Both functions wrap around if they are on the first or
last pages.
Page* get_current();
Returns the Page
object for the currently selected page.
bool get_show_tabs();
void set_show_tabs(bool show_tabs);
Set or retrieve the visibility of the tab-list.
bool get_show_border();
void set_show_border(bool show_border);
Notebooks have a border, which includes the tab-list; use
set_show_border()
to change its visibility.
void set_homogeneous_tabs(bool homogeneous);
Forces all of the tabs to be the same size.
void set_tab_border(gint border_width);
void set_tab_hborder(guint tab_hborder);
void set_tab_vborder(guint tab_vborder);
void set_scrollable(bool scrollable);
Sets whether the tab-list will be scrollable if there are more tabs than can be displayed all at once.
void popup_enable();
void popup_disable();
The notebook can have an optional popup menu which will display when the user right-clicks on the tab-list; the menu will contain a list of all the pages. This can be useful if there are a large number of pages in the notebook. You can enable or disable the popup menu with these functions.
As you can see, there's rather a lot to the notebook widget. We haven't been exhaustive here; see the GTK-- reference manual and source code for more information.
It's that time again. This example program demonstrates the use of the notebook widget.
Source location: examples/notebook/notebook.cc
#include <stdio.h>
#include <gtk--/window.h>
#include <gtk--/checkbutton.h>
#include <gtk--/frame.h>
#include <gtk--/main.h>
#include <gtk--/notebook.h>
#include <gtk--/table.h>
struct Book : public Gtk::Notebook
{
void rotate_book ();
void tabsborder_book ();
void remove_book ();
};
/* This function rotates the position of the tabs */
void Book::rotate_book ()
{
gint pos=(gint)(get_tab_pos());
++pos;
set_tab_pos ((GtkPositionType)(pos%4));
}
/* Add/Remove the page tabs and the borders */
void Book::tabsborder_book ()
{
set_show_tabs (!get_show_tabs());
set_show_border (!get_show_border());
}
/* Remove a page from the notebook */
void Book::remove_book ()
{
Gtk::Notebook::Page *page;
page = get_current();
pages().remove(page);
/* Need to refresh the widget --
This forces the widget to redraw itself. */
draw(NULL);
}
struct AppWindow: public Gtk::Window
{
AppWindow();
~AppWindow();
gint delete_event_impl (GdkEventAny*)
{
Gtk::Main::quit();
return 0;
}
};
AppWindow::AppWindow()
: Gtk::Window(GTK_WINDOW_TOPLEVEL)
{
Gtk::Button *button;
Gtk::Table *table;
Book *notebook;
Gtk::CheckButton *checkbutton;
int i;
char bufferf[32];
char bufferl[32];
set_border_width (10);
table = manage( new Gtk::Table(3,6,false) );
add (*table);
/* Create a new notebook, place the position of the tabs */
notebook = manage( new Book() );
notebook->set_tab_pos (GTK_POS_TOP);
table->attach (*notebook, 0,6,0,1);
/* Lets append a bunch of pages to the notebook */
for (i=0; i < 5; i++)
{
Gtk::Frame *frame;
sprintf(bufferf, "Append Frame %d", i+1);
sprintf(bufferl, "Page %d", i+1);
frame = manage( new Gtk::Frame (bufferf) );
frame->set_border_width (10);
frame->set_usize (100, 75);
frame->show ();
notebook->pages().push_back(
Gtk::Notebook_Helpers::TabElem(*frame,bufferl));
}
/* Now lets add a page to a specific spot */
checkbutton = manage( new Gtk::CheckButton ("Check me please!") );
checkbutton->set_usize (100, 75);
checkbutton->show ();
notebook->pages().insert(++(notebook->pages().begin()),
Gtk::Notebook_Helpers::TabElem (*checkbutton,
"Check me please!")
);
/* Now finally lets prepend pages to the notebook */
for (i=0; i < 5; i++)
{
Gtk::Frame *frame;
sprintf(bufferf, "Prepend Frame %d", i+1);
sprintf(bufferl, "PPage %d", i+1);
frame = manage( new Gtk::Frame (bufferf) );
frame->set_border_width (10);
frame->set_usize (100, 75);
frame->show ();
notebook->pages().push_front(
Gtk::Notebook_Helpers::TabElem(*frame,bufferl));
}
/* Set what page to start at (page 4) */
notebook->set_page (3);
/* Create a bunch of buttons */
button = manage( new Gtk::Button("close") );
button->clicked.connect(Gtk::Main::quit.slot());
table->attach(*button, 0,1,1,2);
button = manage( new Gtk::Button("next page") );
button->clicked.connect(slot(notebook,&Gtk::Notebook::next_page));
table->attach(*button, 1,2,1,2);
button = manage( new Gtk::Button("prev page") );
button->clicked.connect(slot(notebook,&Gtk::Notebook::prev_page));
table->attach(*button, 2,3,1,2);
button = manage( new Gtk::Button("tab position") );
button->clicked.connect(slot(notebook,&Book::rotate_book));
table->attach(*button, 3,4,1,2);
button = manage( new Gtk::Button("tabs/border on/off") );
button->clicked.connect(slot(notebook,&Book::tabsborder_book));
table->attach(*button, 4,5,1,2);
button = manage( new Gtk::Button("remove page") );
button->clicked.connect(slot(notebook,&Book::remove_book));
table->attach(*button, 5,6,1,2);
show_all();
}
AppWindow::~AppWindow() {}
int main (int argc, char *argv[])
{
Gtk::Main m(&argc, &argv);
AppWindow app;
Gtk::Main::run();
return(0);
}