-<!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" []>
+<!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!notation PNG system "PNG">
+<!entity % local.notation.class "| PNG">
+]>
<book id="gtk-tut">
<bookinfo>
- <date>March 1st 2001</date>
- <title>GTK+ 1.2 Tutorial</title>
+ <date>October 27, 2002</date>
+ <title>GTK+ 2.0 Tutorial</title>
<authorgroup>
<author>
<firstname>Tony</firstname>
<firstname>Ian</firstname>
<surname>Main</surname>
</author>
+ <author>
+ <firstname>& the GTK team</firstname>
+ </author>
</authorgroup>
<abstract>
- <para> This is a tutorial on how to use GTK (the GIMP Toolkit) through its C
+ <para>This is a tutorial on how to use GTK (the GIMP Toolkit) through its C
interface.</para>
</abstract>
</bookinfo>
<toc></toc>
+<!-- ***************************************************************** -->
+<chapter id="ch-TutorialDownload">
+<title>Tutorial Availability</title>
+
+<para>A copy of this tutorial in SGML and HTML is distributed with each
+source code release of GTK+. For binary distributions, please check with
+you vendor.</para>
+
+<para>A copy is available online for reference at <ulink
+url="http://www.gtk.org/tutorial">www.gtk.org/tutorial</ulink>.</para>
+
+<para>A packaged verion of this tutorial is available from
+<ulink url="ftp:/ftp.gtk.org/pub/gtk/tutorial">
+ftp.gtk.org/pub/gtk/tutorial</ulink> which contains the tutorial in
+various different formats. This
+package is primary for those people wanting to have the tutorial
+available for offline reference and for printing.</para>
+
+</chapter>
+
<!-- ***************************************************************** -->
<chapter id="ch-Introduction">
<title>Introduction</title>
GNU Network Object Model Environment (GNOME) project. GTK is built on
top of GDK (GIMP Drawing Kit) which is basically a wrapper around the
low-level functions for accessing the underlying windowing functions
-(Xlib in the case of the X windows system). The primary authors of GTK
-are:</para>
+(Xlib in the case of the X windows system), and gdk-pixbuf, a library for
+client-side image manipulation.
+</para>
+<para>The primary authors of GTK are:</para>
<itemizedlist>
<listitem><simpara> Peter Mattis <ulink url="mailto:petm@xcf.berkeley.edu">
</listitem>
</itemizedlist>
+<para>GTK is currently maintained by:</para>
+
+<itemizedlist>
+<listitem><simpara> Owen Taylor <ulink url="mailto:otaylor@redhat.com">
+otaylor@redhat.com</ulink></simpara>
+</listitem>
+<listitem><simpara> Tim Janik <ulink url="mailto:timj@gtk.org">
+timj@gtk.org</ulink></simpara>
+</listitem>
+</itemizedlist>
+
<para>GTK is essentially an object oriented application programmers
interface (API). Although written completely in C, it is implemented
using the idea of classes and callback functions (pointers to
replacements for some standard calls, as well as some additional
functions for handling linked lists, etc. The replacement functions
are used to increase GTK's portability, as some of the functions
-implemented here are not available or are nonstandard on other unixes
+implemented here are not available or are nonstandard on other Unixes
such as g_strerror(). Some also contain enhancements to the libc
-versions, such as g_malloc that has enhanced debugging utilities.</para>
+versions, such as g_malloc() that has enhanced debugging utilities.</para>
+
+<para>In version 2.0, GLib has picked up the type system which forms the
+foundation for GTK's class hierarchy, the signal system which is used
+throughout GTK, a thread API which abstracts the different native thread APIs
+of the various platforms and a facility for loading modules.
+</para>
+
+<para>As the last component, GTK uses the Pango library for internationalized
+text output.
+</para>
<para>This tutorial describes the C interface to GTK. There are GTK
bindings for many other languages including C++, Guile, Perl, Python,
-TOM, Ada95, Objective C, Free Pascal, and Eiffel. If you intend to
+TOM, Ada95, Objective C, Free Pascal, Eiffel, Java and C#. If you intend to
use another language's bindings to GTK, look at that binding's
documentation first. In some cases that documentation may describe
some important conventions (which you should know first) and then
<title>Getting Started</title>
<para>The first thing to do, of course, is download the GTK source and
-install it. You can always get the latest version from ftp.gtk.org in
-/pub/gtk. You can also view other sources of GTK information on
+install it. You can always get the latest version from <ulink
+url="ftp://ftp.gtk.org/pub/gtk">ftp.gtk.org</ulink>. You can also view
+other sources of GTK information on
<ulink url="http://www.gtk.org/">http://www.gtk.org/</ulink>. GTK
-uses GNU autoconf for configuration. Once untar'd, type ./configure
---help to see a list of options.</para>
+uses GNU autoconf for configuration. Once untar'd, type
+<literal>./configure --help</literal> to see a list of options.</para>
<para>The GTK source distribution also contains the complete source to all
of the examples used in this tutorial, along with Makefiles to aid
program possible. This program will create a 200x200 pixel window and
has no way of exiting except to be killed by using the shell.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/base.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start base base.c -->
gtk_main ();
- return(0);
+ return 0;
}
<!-- example-end -->
</programlisting>
<para>You can compile the above program with gcc using:</para>
<para><literallayout>
-<literal>gcc base.c -o base `gtk-config --cflags --libs`</literal>
+<literal>gcc base.c -o base `pkg-config --cflags --libs gtk+-2.0`</literal>
</literallayout></para>
<para>The meaning of the unusual compilation options is explained below in
<link linkend="sec-Compiling">Compiling Hello World</link>.</para>
-<para>All programs will of course include gtk/gtk.h which declares the
-variables, functions, structures, etc. that will be used in your GTK
+<para>All programs will of course include <filename>gtk/gtk.h</filename> which
+declares the variables, functions, structures, etc. that will be used in your GTK
application.</para>
<para>The next line:</para>
gtk_init (&argc, &argv);
</programlisting>
-<para>calls the function gtk_init(gint *argc, gchar ***argv) which will be
-called in all GTK applications. This sets up a few things for us such
-as the default visual and color map and then proceeds to call
-gdk_init(gint *argc, gchar ***argv). This function initializes the
-library for use, sets up default signal handlers, and checks the
-arguments passed to your application on the command line, looking for
+<para>calls the function gtk_init(gint *argc, gchar ***argv) which will be called
+in all GTK applications. This sets up a few things for us such as the default visual
+and color map and then proceeds to call gdk_init(gint *argc, gchar ***argv).
+This function initializes the library for use, sets up default signal handlers, and
+checks the arguments passed to your application on the command line, looking for
one of the following:</para>
<itemizedlist spacing=Compact>
</listitem>
<listitem><simpara> <literal>--sync</literal></simpara>
</listitem>
-<listitem><simpara> <literal>--no-xshm</literal></simpara>
-</listitem>
<listitem><simpara> <literal>--name</literal></simpara>
</listitem>
<listitem><simpara> <literal>--class</literal></simpara>
<para>Now for a program with a widget (a button). It's the classic
hello world a la GTK.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/helloworld.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start helloworld helloworld.c -->
/* Change TRUE to FALSE and the main window will be destroyed with
* a "delete_event". */
- return(TRUE);
+ return TRUE;
}
/* Another callback */
void destroy( GtkWidget *widget,
gpointer data )
{
- gtk_main_quit();
+ gtk_main_quit ();
}
int main( int argc,
/* This is called in all GTK applications. Arguments are parsed
* from the command line and are returned to the application. */
- gtk_init(&argc, &argv);
+ gtk_init (&argc, &argv);
/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
* titlebar), we ask it to call the delete_event () function
* as defined above. The data passed to the callback
* function is NULL and is ignored in the callback function. */
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (delete_event), NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (delete_event), NULL);
/* Here we connect the "destroy" event to a signal handler.
* This event occurs when we call gtk_widget_destroy() on the window,
* or if we return FALSE in the "delete_event" callback. */
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (destroy), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (destroy), NULL);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* When the button receives the "clicked" signal, it will call the
* function hello() passing it NULL as its argument. The hello()
* function is defined above. */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (hello), NULL);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (hello), NULL);
/* This will cause the window to be destroyed by calling
* gtk_widget_destroy(window) when "clicked". Again, the destroy
* signal could come from here, or the window manager. */
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
/* This packs the button into the window (a gtk container). */
gtk_container_add (GTK_CONTAINER (window), button);
<para>To compile use:</para>
<para><literallayout>
-<literal>gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \</literal>
-<literal> `gtk-config --libs`</literal>
+<literal>gcc -Wall -g helloworld.c -o helloworld `pkg-config --cflags gtk+-2.0` \</literal>
+<literal> `pkg-config --libs gtk+-2.0`</literal>
</literallayout></para>
-<para>This uses the program <literal>gtk-config</literal>, which comes with GTK. This
-program "knows" what compiler switches are needed to compile programs
-that use GTK. <literal>gtk-config --cflags</literal> will output a list of include
-directories for the compiler to look in, and <literal>gtk-config --libs</>
+<para>This uses the program <literal>pkg-config</literal>, which can be obtained from
+<ulink url="http://www.freedesktop.org">www.freedesktop.org</ulink>. This program
+reads the <filename>.pc</filename> which comes with GTK to determine what
+compiler switches are needed to compile programs that use GTK.
+<literal>pkg-config --cflags gtk+-2.0</literal> will output a list of include
+directories for the compiler to look in, and
+<literal>pkg-config --libs gtk+-2.0</literal>
will output the list of libraries for the compiler to link with and
the directories to find them in. In the above example they could have
been combined into a single instance, such as
-<literal>`gtk-config --cflags --libs`</literal>.</para>
+<literal>pkg-config --cflags --libs gtk+-2.0</literal>.</para>
<para>Note that the type of single quote used in the compile command above
is significant.</para>
<para>The libraries that are usually linked in are:</para>
<itemizedlist>
-<listitem><simpara>The GTK library (-lgtk), the widget library, based on top of GDK.</simpara>
+<listitem><simpara>The GTK library (<literal>-lgtk</literal>), the widget library,
+based on top of GDK.</simpara>
</listitem>
-<listitem><simpara>The GDK library (-lgdk), the Xlib wrapper.</simpara>
+<listitem><simpara>The GDK library (<literal>-lgdk</literal>), the Xlib wrapper.</simpara>
</listitem>
-<listitem><simpara>The gmodule library (-lgmodule), which is used to load run time
-extensions.</simpara>
+<listitem><simpara>The gdk-pixbuf library (<literal>-lgdk_pixbuf</literal>), the image
+manipulation library.</simpara>
</listitem>
-<listitem><simpara>The GLib library (-lglib), containing miscellaneous functions;
-only g_print() is used in this particular example. GTK is built on top
-of glib so you will always require this library. See the section on
+<listitem><simpara>The Pango library (<literal>-lpango</literal>) for internationalized
+text.</simpara>
+</listitem>
+
+<listitem><simpara>The gobject library (<literal>-lgobject</literal>), containing the
+type system on which GTK is based.</simpara>
+</listitem>
+
+<listitem><simpara>The gmodule library (<literal>-lgmodule</literal>), which is used
+to load run time extensions.</simpara>
+</listitem>
+
+<listitem><simpara>The GLib library (<literal>-lglib</literal>), containing miscellaneous
+functions; only g_print() is used in this particular example. GTK is built on top
+of GLib so you will always require this library. See the section on
<link linkend="ch-glib">GLib</link> for details.</simpara>
</listitem>
-<listitem><simpara>The Xlib library (-lX11) which is used by GDK.</simpara>
+<listitem><simpara>The Xlib library (<literal>-lX11</literal>) which is used by GDK.</simpara>
</listitem>
-<listitem><simpara>The Xext library (-lXext). This contains code for shared memory
-pixmaps and other X extensions.</simpara>
+<listitem><simpara>The Xext library (<literal>-lXext</literal>). This contains code
+for shared memory pixmaps and other X extensions.</simpara>
</listitem>
-<listitem><simpara>The math library (-lm). This is used by GTK for various
-purposes.</simpara>
+<listitem><simpara>The math library (<literal>-lm</literal>). This is used by GTK
+for various purposes.</simpara>
</listitem>
</itemizedlist>
<sect1 id="sec-TheoryOfSignalsAndCallbacks">
<title>Theory of Signals and Callbacks</title>
+<note>
+<para>In version 2.0, the signal system has been moved from GTK to GLib, therefore the
+functions and types explained in this section have a "g_" prefix rather than a "gtk_"
+prefix. We won't go into details about the extensions which the GLib 2.0 signal system
+has relative to the GTK 1.2 signal system.</para>
+</note>
+
<para>Before we look in detail at <emphasis>helloworld</emphasis>, we'll discuss signals
and callbacks. GTK is an event driven toolkit, which means it will
-sleep in gtk_main until an event occurs and control is passed to the
+sleep in gtk_main() until an event occurs and control is passed to the
appropriate function.</para>
<para>This passing of control is done using the idea of "signals". (Note
using a function such as:</para>
<programlisting role="C">
-gint gtk_signal_connect( GtkObject *object,
- gchar *name,
- GtkSignalFunc func,
- gpointer func_data );
+gulong g_signal_connect( gpointer *object,
+ const gchar *name,
+ GCallback func,
+ gpointer func_data );
</programlisting>
<para>where the first argument is the widget which will be emitting the
<para>where the first argument will be a pointer to the widget that emitted
the signal, and the second a pointer to the data given as the last
-argument to the gtk_signal_connect() function as shown above.</para>
+argument to the g_signal_connect() function as shown above.</para>
<para>Note that the above form for a signal callback function declaration is
only a general guide, as some widget specific signals generate
-different calling parameters. For example, the CList "select_row"
-signal provides both row and column parameters.</para>
+different calling parameters.</para>
<para>Another call used in the <emphasis>helloworld</emphasis> example, is:</para>
<programlisting role="C">
-gint gtk_signal_connect_object( GtkObject *object,
- gchar *name,
- GtkSignalFunc func,
- GtkObject *slot_object );
+gulong g_signal_connect_swapped( gpointer *object,
+ const gchar *name,
+ GCallback func,
+ gpointer *slot_object );
</programlisting>
-<para>gtk_signal_connect_object() is the same as gtk_signal_connect() except
+<para>g_signal_connect_swapped() is the same as g_signal_connect() except
that the callback function only uses one argument, a pointer to a GTK
object. So when using this function to connect signals, the callback
should be of the form</para>
</programlisting>
<para>where the object is usually a widget. We usually don't setup callbacks
-for gtk_signal_connect_object however. They are usually used to call a
+for g_signal_connect_swapped() however. They are usually used to call a
GTK function that accepts a single widget or object as an argument, as
is the case in our <emphasis>helloworld</emphasis> example.</para>
<para>The purpose of having two functions to connect signals is simply to
allow the callbacks to have a different number of arguments. Many
functions in the GTK library accept only a single GtkWidget pointer as
-an argument, so you want to use the gtk_signal_connect_object() for
+an argument, so you want to use the g_signal_connect_swapped() for
these, whereas for your functions, you may need to have additional
data supplied to the callbacks.</para>
</listitem>
<listitem><simpara> button_release_event</simpara>
</listitem>
+<listitem><simpara> scroll_event</simpara>
+</listitem>
<listitem><simpara> motion_notify_event</simpara>
</listitem>
<listitem><simpara> delete_event</simpara>
</listitem>
<listitem><simpara> proximity_out_event</simpara>
</listitem>
-<listitem><simpara> drag_begin_event</simpara>
-</listitem>
-<listitem><simpara> drag_request_event</simpara>
-</listitem>
-<listitem><simpara> drag_end_event</simpara>
+<listitem><simpara> visibility_notify_event</simpara>
</listitem>
-<listitem><simpara> drop_enter_event</simpara>
+<listitem><simpara> client_event</simpara>
</listitem>
-<listitem><simpara> drop_leave_event</simpara>
+<listitem><simpara> no_expose_event</simpara>
</listitem>
-<listitem><simpara> drop_data_available_event</simpara>
-</listitem>
-<listitem><simpara> other_event</simpara>
+<listitem><simpara> window_state_event</simpara>
</listitem>
</itemizedlist>
<para>In order to connect a callback function to one of these events you
-use the function gtk_signal_connect, as described above, using one of
+use the function g_signal_connect(), as described above, using one of
the above event names as the <literal>name</literal> parameter. The callback
function for events has a slightly different form than that for
signals:</para>
gpointer callback_data );
</programlisting>
-<para>GdkEvent is a C <literal>union</literal> structure whose type will depend upon which
-of the above events has occurred. In order for us to tell which event
+<para>GdkEvent is a C <literal>union</literal> structure whose type will depend upon
+which of the above events has occurred. In order for us to tell which event
has been issued each of the possible alternatives has a <literal>type</literal>
member that reflects the event being issued. The other components
of the event structure will depend upon the type of the
GDK_SELECTION_NOTIFY
GDK_PROXIMITY_IN
GDK_PROXIMITY_OUT
- GDK_DRAG_BEGIN
- GDK_DRAG_REQUEST
- GDK_DROP_ENTER
- GDK_DROP_LEAVE
- GDK_DROP_DATA_AVAIL
+ GDK_DRAG_ENTER
+ GDK_DRAG_LEAVE
+ GDK_DRAG_MOTION
+ GDK_DRAG_STATUS
+ GDK_DROP_START
+ GDK_DROP_FINISHED
GDK_CLIENT_EVENT
GDK_VISIBILITY_NOTIFY
GDK_NO_EXPOSE
- GDK_OTHER_EVENT /* Deprecated, use filters instead */
+ GDK_SCROLL
+ GDK_WINDOW_STATE
+ GDK_SETTING
</programlisting>
<para>So, to connect a callback function to one of these events we would use
something like:</para>
<programlisting role="C">
-gtk_signal_connect( GTK_OBJECT(button), "button_press_event",
- GTK_SIGNAL_FUNC(button_press_callback),
- NULL);
+g_signal_connect (G_OBJECT (button), "button_press_event",
+ G_CALLBACK (button_press_callback), NULL);
</programlisting>
<para>This assumes that <literal>button</literal> is a Button widget. Now, when the
mouse is over the button and a mouse button is pressed, the function
-<literal>button_press_callback</literal> will be called. This function may be
-declared as:</para>
+button_press_callback() will be called. This function may be declared as:</para>
<programlisting role="C">
static gint button_press_callback( GtkWidget *widget,
mechanism. Returning TRUE indicates that the event has been handled,
and that it should not propagate further. Returning FALSE continues
the normal event handling. See the section on
-<link linkend="ch-AdvancedEventsAndSignals">Advanced Event and Signal Handling</link> for more details on this
-propagation process.</para>
+<link linkend="ch-AdvancedEventsAndSignals">Advanced Event and Signal Handling</link>
+for more details on this propagation process.</para>
<para>For details on the GdkEvent data types, see the appendix entitled
<link linkend="app-GDKEventTypes">GDK Event Types</link>.</para>
+<para>The GDK selection and drag-and-drop APIs also emit a number of events which
+are reflected in GTK by the signals. See <link
+linkend="sec-SignalsOnSourceWidgets">Signals on the source widget</link> and <link
+linkend="sec-SignalsOnDestWidgets">Signals on the destination widget</link>
+for details on the signatures of the callback functions for these signals:</para>
+
+<itemizedlist spacing=Compact>
+<listitem><simpara> selection_received</simpara>
+</listitem>
+<listitem><simpara> selection_get</simpara>
+</listitem>
+<listitem><simpara> drag_begin_event</simpara>
+</listitem>
+<listitem><simpara> drag_end_event</simpara>
+</listitem>
+<listitem><simpara> drag_data_delete</simpara>
+</listitem>
+<listitem><simpara> drag_motion</simpara>
+</listitem>
+<listitem><simpara> drag_drop</simpara>
+</listitem>
+<listitem><simpara> drag_data_get</simpara>
+</listitem>
+<listitem><simpara> drag_data_received</simpara>
+</listitem>
+</itemizedlist>
+
</sect1>
<!-- ----------------------------------------------------------------- -->
{
g_print ("delete event occurred\n");
- return (TRUE);
+ return TRUE;
}
</programlisting>
GtkWidget *button;
</programlisting>
-<para>Here is our gtk_init again. As before, this initializes the toolkit,
+<para>Here is our gtk_init() again. As before, this initializes the toolkit,
and parses the arguments found on the command line. Any argument it
recognizes from the command line, it removes from the list, and
modifies argc and argv to make it look like they never existed,
in the window widget as the object to destroy. The second is emitted
when, in the "delete_event" handler, we return FALSE.
-The <literal>GTK_OBJECT</literal> and <literal>GTK_SIGNAL_FUNC</literal> are macros that perform
-type casting and checking for us, as well as aid the readability of
+The <literal>G_OBJECT</literal> and <literal>G_CALLBACK</literal> are macros
+that perform type casting and checking for us, as well as aid the readability of
the code.</para>
<programlisting role="C">
- gtk_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (delete_event), NULL);
- gtk_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (destroy), NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (delete_event), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (destroy), NULL);
</programlisting>
<para>This next function is used to set an attribute of a container object.
is emitted when we click the button with our mouse pointer.</para>
<programlisting role="C">
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (hello), NULL);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (hello), NULL);
</programlisting>
<para>We are also going to use this button to exit our program. This will
order they are set up. You may have as many callback functions as you
need, and all will be executed in the order you connected
them. Because the gtk_widget_destroy() function accepts only a
-GtkWidget *widget as an argument, we use the
-gtk_signal_connect_object() function here instead of straight
-gtk_signal_connect().</para>
+GtkWidget *widget as an argument, we use the g_signal_connect_swapped()
+function here instead of straight g_signal_connect().</para>
<programlisting role="C">
- gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
</programlisting>
<para>This is a packing call, which will be explained in depth later on in
<para>And the final return. Control returns here after gtk_quit() is called.</para>
<programlisting role="C">
- return (0);
+ return 0;
</programlisting>
<para>Now, when we click the mouse button on a GTK button, the widget emits
<para>There are a few things you probably noticed in the previous examples
that need explaining. The gint, gchar, etc. that you see are typedefs
-to int and char, respectively, that are part of the GLlib system. This
+to int and char, respectively, that are part of the GLib system. This
is done to get around that nasty dependency on the size of simple data
types when doing calculations.</para>
<para>A good example is "gint32" which will be typedef'd to a 32 bit integer
for any given platform, whether it be the 64 bit alpha, or the 32 bit
i386. The typedefs are very straightforward and intuitive. They are
-all defined in glib/glib.h (which gets included from gtk.h).</para>
+all defined in <filename>glib/glib.h</filename> (which gets included from
+<filename>gtk.h</filename>).</para>
<para>You'll also notice GTK's ability to use GtkWidget when the function
-calls for an Object. GTK is an object oriented design, and a widget
+calls for a GtkObject. GTK is an object oriented design, and a widget
is an object.</para>
</sect1>
<sect1 id="sec-MoreOnSignalHandlers">
<title>More on Signal Handlers</title>
-<para>Lets take another look at the gtk_signal_connect declaration.</para>
+<para>Lets take another look at the g_signal_connect() declaration.</para>
<programlisting role="C">
-gint gtk_signal_connect( GtkObject *object,
- gchar *name,
- GtkSignalFunc func,
+gulong g_signal_connect( gpointer object,
+ const gchar *name,
+ GCallback func,
gpointer func_data );
</programlisting>
-<para>Notice the gint return value? This is a tag that identifies your
+<para>Notice the gulong return value? This is a tag that identifies your
callback function. As stated above, you may have as many callbacks per
signal and per object as you need, and each will be executed in turn,
in the order they were attached.</para>
<para>This tag allows you to remove this callback from the list by using:</para>
<programlisting role="C">
-void gtk_signal_disconnect( GtkObject *object,
- gint id );
+void g_signal_handler_disconnect( gpointer object,
+ gulong id );
</programlisting>
<para>So, by passing in the widget you wish to remove the handler from, and
disconnect a signal handler.</para>
<para>You can also temporarily disable signal handlers with the
-gtk_signal_handler_block() and gtk_signal_handler_unblock() family of
+g_signal_handler_block() and g_signal_handler_unblock() family of
functions.</para>
<programlisting role="C">
-void gtk_signal_handler_block( GtkObject *object,
- guint handler_id );
-
-void gtk_signal_handler_block_by_func( GtkObject *object,
- GtkSignalFunc func,
- gpointer data );
-
-void gtk_signal_handler_block_by_data( GtkObject *object,
- gpointer data );
+void g_signal_handler_block( gpointer object,
+ gulong id );
-void gtk_signal_handler_unblock( GtkObject *object,
- guint handler_id );
+void g_signal_handlers_block_by_func( gpointer object,
+ GCallback func,
+ gpointer data );
-void gtk_signal_handler_unblock_by_func( GtkObject *object,
- GtkSignalFunc func,
- gpointer data );
+void g_signal_handler_unblock( gpointer object,
+ gulong id );
-void gtk_signal_handler_unblock_by_data( GtkObject *object,
- gpointer data);
+void g_signal_handlers_unblock_by_func( gpointer object,
+ GCallback func,
+ gpointer data );
</programlisting>
</sect1>
better examples of callbacks. This will also introduce us to our next
topic, packing widgets.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/helloworld2.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start helloworld2 helloworld2.c -->
void callback( GtkWidget *widget,
gpointer data )
{
- g_print ("Hello again - %s was pressed\n", (char *) data);
+ g_print ("Hello again - %s was pressed\n", (gchar *) data);
}
/* another callback */
GdkEvent *event,
gpointer data )
{
- gtk_main_quit();
- return(FALSE);
+ gtk_main_quit ();
+ return FALSE;
}
int main( int argc,
/* Here we just set a handler for delete_event that immediately
* exits GTK. */
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (delete_event), NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (delete_event), NULL);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* We create a box to pack widgets into. This is described in detail
* in the "packing" section. The box is not really visible, it
* is just used as a tool to arrange widgets. */
- box1 = gtk_hbox_new(FALSE, 0);
+ box1 = gtk_hbox_new (FALSE, 0);
/* Put the box into the main window. */
gtk_container_add (GTK_CONTAINER (window), box1);
/* Now when the button is clicked, we call the "callback" function
* with a pointer to "button 1" as its argument */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (callback), (gpointer) "button 1");
/* Instead of gtk_container_add, we pack this button into the invisible
* box, which has been packed into the window. */
- gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);
/* Always remember this step, this tells GTK that our preparation for
* this button is complete, and it can now be displayed. */
- gtk_widget_show(button);
+ gtk_widget_show (button);
/* Do these same steps again to create a second button */
button = gtk_button_new_with_label ("Button 2");
/* Call the same callback function with a different argument,
* passing a pointer to "button 2" instead. */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (callback), (gpointer) "button 2");
- gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (box1), button, TRUE, TRUE, 0);
/* The order in which we show the buttons is not really important, but I
* recommend showing the window last, so it all pops up at once. */
- gtk_widget_show(button);
+ gtk_widget_show (button);
- gtk_widget_show(box1);
+ gtk_widget_show (box1);
gtk_widget_show (window);
options to gtk_box_pack_start() while reading the next section. Try
resizing the window, and observe the behavior.</para>
-<para>Just as a side note, there is another useful define for
-gtk_window_new() - <literal>GTK_WINDOW_DIALOG</literal>. This interacts with the
-window manager a little differently and should be used for transient
-windows.</para>
-
</sect1>
</chapter>
<para>When creating an application, you'll want to put more than one widget
inside a window. Our first <emphasis>helloworld</emphasis> example only used one
-widget so we could simply use a gtk_container_add call to "pack" the
+widget so we could simply use a gtk_container_add() call 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.</para>
<para>
<inlinemediaobject>
<imageobject>
-<imagedata fileref="gtk_tut_packbox1.jpg">
+<imagedata fileref="images/packbox1.png" format="png">
</imageobject>
</inlinemediaobject>
</para>
buttons into the hbox. Each of the buttons is packed into the hbox the
same way (i.e., same arguments to the gtk_box_pack_start() function).</para>
-<para>This is the declaration of the gtk_box_pack_start function.</para>
+<para>This is the declaration of the gtk_box_pack_start() function.</para>
<programlisting role="C">
void gtk_box_pack_start( GtkBox *box,
GtkWidget *child,
- gint expand,
- gint fill,
- gint padding );
+ gboolean expand,
+ gboolean fill,
+ guint padding );
</programlisting>
<para>The first argument is the box you are packing the object into, the
(FALSE). Setting expand to FALSE will allow you to do right and left
justification of your widgets. Otherwise, they will all expand to fit
into the box, and the same effect could be achieved by using only one
-of gtk_box_pack_start or gtk_box_pack_end.</para>
+of gtk_box_pack_start() or gtk_box_pack_end().</para>
<para>The fill argument to the gtk_box_pack functions control whether the
extra space is allocated to the objects themselves (TRUE), or as extra
<para>When creating a new box, the function looks like this:</para>
<programlisting role="C">
-GtkWidget *gtk_hbox_new (gint homogeneous,
- gint spacing);
+GtkWidget *gtk_hbox_new ( gboolean homogeneous,
+ gint spacing );
</programlisting>
-<para>The homogeneous argument to gtk_hbox_new (and the same for
-gtk_vbox_new) controls whether each object in the box has the same
+<para>The homogeneous argument to gtk_hbox_new() (and the same for
+gtk_vbox_new()) controls whether each object in the box has the same
size (i.e., the same width in an hbox, or the same height in a
-vbox). If it is set, the gtk_box_pack routines function essentially
+vbox). If it is set, the gtk_box_pack() routines function essentially
as if the <literal>expand</literal> argument was always turned on.</para>
<para>What's the difference between spacing (set when the box is created)
<para>
<inlinemediaobject>
<imageobject>
-<imagedata fileref="gtk_tut_packbox2.jpg">
+<imagedata fileref="images/packbox2.png" format="png">
</imageobject>
</inlinemediaobject>
</para>
GdkEvent *event,
gpointer data )
{
- gtk_main_quit();
+ gtk_main_quit ();
return FALSE;
}
/* Make a new hbox filled with button-labels. Arguments for the
* variables we're interested are passed in to this function.
* We do not show the box, but do show everything inside. */
-GtkWidget *make_box( gint homogeneous,
- gint spacing,
- gint expand,
- gint fill,
- gint padding )
+GtkWidget *make_box( gboolean homogeneous,
+ gint spacing,
+ gboolean expand,
+ gboolean fill,
+ guint padding )
{
GtkWidget *box;
GtkWidget *button;
/* You should always remember to connect the delete_event signal
* to the main window. This is very important for proper intuitive
* behavior */
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (delete_event), NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (delete_event), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* We create a vertical box (vbox) to pack the horizontal boxes into.
button = gtk_button_new_with_label ("Quit");
/* Setup the signal to terminate the program when the button is clicked */
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_main_quit),
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_main_quit),
+ G_OBJECT (window));
/* Pack the button into the quitbox.
* The last 3 arguments to gtk_box_pack_start are:
* expand, fill, padding. */
gtk_main ();
/* Control returns here when gtk_main_quit() is called, but not when
- * gtk_exit is used. */
+ * exit() is used. */
return 0;
}
<para>Using tables, we create a grid that we can place widgets in. The
widgets may take up as many spaces as we specify.</para>
-<para>The first thing to look at, of course, is the gtk_table_new function:</para>
+<para>The first thing to look at, of course, is the gtk_table_new() function:</para>
<programlisting role="C">
-GtkWidget *gtk_table_new( gint rows,
- gint columns,
- gint homogeneous );
+GtkWidget *gtk_table_new( guint rows,
+ guint columns,
+ gboolean homogeneous );
</programlisting>
<para>The first argument is the number of rows to make in the table, while
To place a widget into a box, use the following function:</para>
<programlisting role="C">
-void gtk_table_attach( GtkTable *table,
- GtkWidget *child,
- gint left_attach,
- gint right_attach,
- gint top_attach,
- gint bottom_attach,
- gint xoptions,
- gint yoptions,
- gint xpadding,
- gint ypadding );
+void gtk_table_attach( GtkTable *table,
+ GtkWidget *child,
+ guint left_attach,
+ guint right_attach,
+ guint top_attach,
+ guint bottom_attach,
+ GtkAttachOptions xoptions,
+ GtkAttachOptions yoptions,
+ guint xpadding,
+ guint ypadding );
</programlisting>
<para>The first argument ("table") is the table you've created and the
<para>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 ONLY,
+table entry of our 2x2 table, and want it to fill that entry <emphasis>only</emphasis>,
left_attach would be = 1, right_attach = 2, top_attach = 1,
bottom_attach = 2.</para>
<para>These options are:</para>
-<itemizedlist>
-<listitem><simpara><literal>GTK_FILL</literal> - If the table box is larger than the widget, and
+<variablelist>
+<varlistentry>
+<term><literal>GTK_FILL</literal></term>
+<listitem><para>If the table box is larger than the widget, and
<literal>GTK_FILL</literal> is specified, the widget will expand to use all the room
-available.</simpara>
+available.</para>
</listitem>
+</varlistentry>
-<listitem><simpara><literal>GTK_SHRINK</literal> - If the table widget was allocated less space
+<varlistentry>
+<term><literal>GTK_SHRINK</literal></term>
+<listitem><para>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 <literal>GTK_SHRINK</literal> is specified, the widgets will shrink
-with the table.</simpara>
+with the table.</para>
</listitem>
+</varlistentry>
-<listitem><simpara><literal>GTK_EXPAND</literal> - This will cause the table to expand to use up
-any remaining space in the window.</simpara>
+<varlistentry>
+<term><literal>GTK_EXPAND</literal></term>
+<listitem><para>This will cause the table to expand to use up
+any remaining space in the window.</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
<para>Padding is just like in boxes, creating a clear area around the widget
specified in pixels.</para>
-<para>gtk_table_attach() has a LOT of options. So, there's a shortcut:</para>
+<para>gtk_table_attach() has a <emphasis>lot</emphasis> of options.
+So, there's a shortcut:</para>
<programlisting role="C">
void gtk_table_attach_defaults( GtkTable *table,
GtkWidget *widget,
- gint left_attach,
- gint right_attach,
- gint top_attach,
- gint bottom_attach );
+ guint left_attach,
+ guint right_attach,
+ guint top_attach,
+ guint bottom_attach );
</programlisting>
-<para>The X and Y options default to <literal>GTK_FILL | GTK_EXPAND</literal>, and X and Y
-padding are set to 0. The rest of the arguments are identical to the
+<para>The X and Y options default to <literal>GTK_FILL | GTK_EXPAND</literal>,
+and X and Y padding are set to 0. The rest of the arguments are identical to the
previous function.</para>
<para>We also have gtk_table_set_row_spacing() and
<programlisting role="C">
void gtk_table_set_row_spacing( GtkTable *table,
- gint row,
- gint spacing );
+ guint row,
+ guint spacing );
</programlisting>
<para>and</para>
<programlisting role="C">
void gtk_table_set_col_spacing ( GtkTable *table,
- gint column,
- gint spacing );
+ guint column,
+ guint spacing );
</programlisting>
<para>Note that for columns, the space goes to the right of the column, and
<programlisting role="C">
void gtk_table_set_row_spacings( GtkTable *table,
- gint spacing );
+ guint spacing );
</programlisting>
<para>And,</para>
<programlisting role="C">
void gtk_table_set_col_spacings( GtkTable *table,
- gint spacing );
+ guint spacing );
</programlisting>
<para>Note that with these calls, the last row and last column do not get
<para>
<inlinemediaobject>
<imageobject>
-<imagedata fileref="gtk_tut_table.jpg">
+<imagedata fileref="images/table.png" format="png">
</imageobject>
</inlinemediaobject>
</para>
/* Set a handler for delete_event that immediately
* exits GTK. */
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (delete_event), NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (delete_event), NULL);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 20);
/* When the button is clicked, we call the "callback" function
* with a pointer to "button 1" as its argument */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (callback), (gpointer) "button 1");
/* Insert button 1 into the upper left quadrant of the table */
- gtk_table_attach_defaults (GTK_TABLE(table), button, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 0, 1);
gtk_widget_show (button);
/* When the button is clicked, we call the "callback" function
* with a pointer to "button 2" as its argument */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (callback), (gpointer) "button 2");
/* Insert button 2 into the upper right quadrant of the table */
- gtk_table_attach_defaults (GTK_TABLE(table), button, 1, 2, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 2, 0, 1);
gtk_widget_show (button);
/* When the button is clicked, we call the "delete_event" function
* and the program exits */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (delete_event), NULL);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (delete_event), NULL);
/* Insert the quit button into the both
* lower quadrants of the table */
- gtk_table_attach_defaults (GTK_TABLE(table), button, 0, 2, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 2, 1, 2);
gtk_widget_show (button);
<para>The general steps to creating a widget in GTK are:</para>
<orderedlist>
-<listitem><simpara> gtk_*_new - one of various functions to create a new widget.
+<listitem><simpara> gtk_*_new() - one of various functions to create a new widget.
These are all detailed in this section.</simpara>
</listitem>
given item, and perform the cast. Some common ones you will see are:</para>
<programlisting role="C">
- GTK_WIDGET(widget)
- GTK_OBJECT(object)
- GTK_SIGNAL_FUNC(function)
- GTK_CONTAINER(container)
- GTK_WINDOW(window)
- GTK_BOX(box)
+ G_OBJECT (object)
+ GTK_WIDGET (widget)
+ GTK_OBJECT (object)
+ GTK_SIGNAL_FUNC (function)
+ GTK_CONTAINER (container)
+ GTK_WINDOW (window)
+ GTK_BOX (box)
</programlisting>
<para>These are all used to cast arguments in functions. You'll see them in the
function's declaration.</para>
<para>As you can see below in the class hierarchy, all GtkWidgets are
-derived from the Object base class. This means you can use a widget
+derived from the GObject base class. This means you can use a widget
in any place the function asks for an object - simply use the
-<literal>GTK_OBJECT()</literal> macro.</para>
+<literal>G_OBJECT()</literal> macro.</para>
<para>For example:</para>
<programlisting role="C">
-gtk_signal_connect( GTK_OBJECT(button), "clicked",
- GTK_SIGNAL_FUNC(callback_function), callback_data);
+g_signal_connect( G_OBJECT (button), "clicked",
+ G_CALLBACK (callback_function), callback_data);
</programlisting>
<para>This casts the button into an object, and provides a cast for the
<para>Unfortunately, these macros are not extensively covered in the
tutorial, but I recommend taking a look through the GTK header
-files. It can be very educational. In fact, it's not difficult to
-learn how a widget works just by looking at the function declarations.</para>
+files or the GTK API reference manual. It can be very educational. In fact,
+it's not difficult to learn how a widget works just by looking at the
+function declarations.</para>
</sect1>
<sect1 id="sec-WidgetHierarchy">
<title>Widget Hierarchy</title>
-<para>For your reference, here is the class hierarchy tree used to implement widgets.</para>
+<para>For your reference, here is the class hierarchy tree used to implement
+widgets. (Deprecated widgets and auxiliary classes have been omitted.)</para>
<programlisting role="C">
+GObject
+ |
GtkObject
+GtkWidget
| +GtkMisc
| | +GtkLabel
- | | | +GtkAccelLabel
- | | | `GtkTipsQuery
+ | | | `GtkAccelLabel
| | +GtkArrow
- | | +GtkImage
- | | `GtkPixmap
+ | | `GtkImage
| +GtkContainer
| | +GtkBin
| | | +GtkAlignment
| | | | `GtkOptionMenu
| | | +GtkItem
| | | | +GtkMenuItem
- | | | | | +GtkCheckMenuItem
- | | | | | | `GtkRadioMenuItem
- | | | | | `GtkTearoffMenuItem
- | | | | +GtkListItem
- | | | | `GtkTreeItem
+ | | | | +GtkCheckMenuItem
+ | | | | | `GtkRadioMenuItem
+ | | | | +GtkImageMenuItem
+ | | | | +GtkSeparatorMenuItem
+ | | | | `GtkTearoffMenuItem
| | | +GtkWindow
- | | | | +GtkColorSelectionDialog
| | | | +GtkDialog
- | | | | | `GtkInputDialog
- | | | | +GtkDrawWindow
- | | | | +GtkFileSelection
- | | | | +GtkFontSelectionDialog
+ | | | | | +GtkColorSelectionDialog
+ | | | | | +GtkFileSelection
+ | | | | | +GtkFontSelectionDialog
+ | | | | | +GtkInputDialog
+ | | | | | `GtkMessageDialog
| | | | `GtkPlug
| | | +GtkEventBox
| | | +GtkHandleBox
| | | | `GtkVButtonBox
| | | +GtkVBox
| | | | +GtkColorSelection
+ | | | | +GtkFontSelection
| | | | `GtkGammaCurve
| | | `GtkHBox
| | | +GtkCombo
| | | `GtkStatusbar
- | | +GtkCList
- | | | `GtkCTree
| | +GtkFixed
- | | +GtkNotebook
- | | | `GtkFontSelection
| | +GtkPaned
| | | +GtkHPaned
| | | `GtkVPaned
| | +GtkLayout
- | | +GtkList
| | +GtkMenuShell
| | | +GtkMenuBar
| | | `GtkMenu
+ | | +GtkNotebook
| | +GtkSocket
| | +GtkTable
+ | | +GtkTextView
| | +GtkToolbar
- | | `GtkTree
+ | | `GtkTreeView
| +GtkCalendar
| +GtkDrawingArea
| | `GtkCurve
| +GtkEditable
| | +GtkEntry
- | | | `GtkSpinButton
- | | `GtkText
+ | | `GtkSpinButton
| +GtkRuler
| | +GtkHRuler
| | `GtkVRuler
| +GtkSeparator
| | +GtkHSeparator
| | `GtkVSeparator
+ | +GtkInvisible
| +GtkPreview
- | `GtkProgress
- | `GtkProgressBar
- +GtkData
- | +GtkAdjustment
- | `GtkTooltips
- `GtkItemFactory
+ | `GtkProgressBar
+ +GtkAdjustment
+ +GtkCellRenderer
+ | +GtkCellRendererPixbuf
+ | +GtkCellRendererText
+ | +GtkCellRendererToggle
+ +GtkItemFactory
+ +GtkTooltips
+ `GtkTreeViewColumn
</programlisting>
</sect1>
GtkArrow
GtkBin
GtkBox
+GtkButton
+GtkCheckButton
+GtkFixed
GtkImage
-GtkItem
GtkLabel
-GtkPixmap
+GtkMenuItem
+GtkNotebook
+GtkPaned
+GtkRadioButton
+GtkRange
GtkScrolledWindow
GtkSeparator
GtkTable
+GtkToolbar
GtkAspectFrame
GtkFrame
GtkVBox
<para>We'll further our exploration of GTK by examining each widget in turn,
creating a few simple functions to display them. Another good source
-is the testgtk.c program that comes with GTK. It can be found in
-gtk/testgtk.c.</para>
+is the <literal>testgtk</literal> program that comes with GTK. It can be found in
+<filename>tests/testgtk.c</filename>.</para>
</sect1>
</chapter>
<title>Normal Buttons</title>
<para>We've almost seen all there is to see of the button widget. It's
-pretty simple. There are however two ways to create a button. You can
-use the gtk_button_new_with_label() to create a button with a label,
-or use gtk_button_new() to create a blank button. It's then up to you
-to pack a label or pixmap into this new button. To do this, create a
-new box, and then pack your objects into this box using the usual
-gtk_box_pack_start, and then use gtk_container_add to pack the box
-into the button.</para>
+pretty simple. There is however more than one way to create a button. You can
+use the gtk_button_new_with_label() or gtk_button_new_with_mnemonic() to create
+a button with a label, use gtk_button_new_from_stock() to create a button
+containing the image and text from a stock item or use gtk_button_new() to
+create a blank button. It's then up to you to pack a label or pixmap into
+this new button. To do this, create a new box, and then pack your objects into
+this box using the usual gtk_box_pack_start(), and then use gtk_container_add()
+to pack the box into the button.</para>
+
+<para>Here's an example of using gtk_button_new() to create a button with a
+image and a label in it. I've broken up the code to create a box from the rest
+so you can use it in your programs. There are further examples of using images
+later in the tutorial.</para>
-<para>Here's an example of using gtk_button_new to create a button with a
-picture and a label in it. I've broken up the code to create a box
-from the rest so you can use it in your programs. There are further
-examples of using pixmaps later in the tutorial.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/buttons.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
<programlisting role="C">
<!-- example-start buttons buttons.c -->
/* Create a new hbox with an image and a label packed into it
* and return the box. */
-GtkWidget *xpm_label_box( GtkWidget *parent,
- gchar *xpm_filename,
+GtkWidget *xpm_label_box( gchar *xpm_filename,
gchar *label_text )
{
- GtkWidget *box1;
+ GtkWidget *box;
GtkWidget *label;
- GtkWidget *pixmapwid;
- GdkPixmap *pixmap;
- GdkBitmap *mask;
- GtkStyle *style;
-
- /* Create box for xpm and label */
- box1 = gtk_hbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (box1), 2);
+ GtkWidget *image;
- /* Get the style of the button to get the
- * background color. */
- style = gtk_widget_get_style(parent);
+ /* Create box for image and label */
+ box = gtk_hbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 2);
- /* Now on to the xpm stuff */
- pixmap = gdk_pixmap_create_from_xpm (parent->window, &mask,
- &style->bg[GTK_STATE_NORMAL],
- xpm_filename);
- pixmapwid = gtk_image_new_from_file (xpm_filename);
+ /* Now on to the image stuff */
+ image = gtk_image_new_from_file (xpm_filename);
/* Create a label for the button */
label = gtk_label_new (label_text);
- /* Pack the pixmap and label into the box */
- gtk_box_pack_start (GTK_BOX (box1),
- pixmapwid, FALSE, FALSE, 3);
-
- gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 3);
+ /* Pack the image and label into the box */
+ gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 3);
- gtk_widget_show(pixmapwid);
- gtk_widget_show(label);
+ gtk_widget_show (image);
+ gtk_widget_show (label);
- return(box1);
+ return box;
}
/* Our usual callback function */
/* GtkWidget is the storage type for widgets */
GtkWidget *window;
GtkWidget *button;
- GtkWidget *box1;
+ GtkWidget *box;
gtk_init (&argc, &argv);
gtk_window_set_title (GTK_WINDOW (window), "Pixmap'd Buttons!");
-#if 1
/* It's a good idea to do this for all windows. */
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (exit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (exit), NULL);
-#endif
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (gtk_main_quit), NULL);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
- gtk_widget_realize(window);
/* Create a new button */
button = gtk_button_new ();
/* Connect the "clicked" signal of the button to our callback */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (callback), (gpointer) "cool button");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (callback), (gpointer) "cool button");
/* This calls our box creating function */
- box1 = xpm_label_box(window, "info.xpm", "cool button");
+ box = xpm_label_box ("info.xpm", "cool button");
/* Pack and show all our widgets */
- gtk_widget_show(box1);
+ gtk_widget_show (box);
- gtk_container_add (GTK_CONTAINER (button), box1);
+ gtk_container_add (GTK_CONTAINER (button), box);
- gtk_widget_show(button);
+ gtk_widget_show (button);
gtk_container_add (GTK_CONTAINER (window), button);
/* Rest in gtk_main and wait for the fun to begin! */
gtk_main ();
- return(0);
+ return 0;
}
<!-- example-end -->
</programlisting>
-<para>The xpm_label_box function could be used to pack xpm's and labels into
+<para>The xpm_label_box() function could be used to pack images and labels into
any widget that can be a container.</para>
-<para>Notice in <literal>xpm_label_box</literal> how there is a call to
-<literal>gtk_widget_get_style</literal>. Every widget has a "style", consisting of
-foreground and background colors for a variety of situations, font
-selection, and other graphics data relevant to a widget. These style
-values are defaulted in each widget, and are required by many GDK
-function calls, such as <literal>gdk_pixmap_create_from_xpm</literal>, which here is
-given the "normal" background color. The style data of widgets may
-be customized, using <link linkend="ch-GTKRCFiles">GTK's rc files</link>.</para>
-
-<para>Also notice the call to <literal>gtk_widget_realize</literal> after setting the
-window's border width. This function uses GDK to create the X
-windows related to the widget. The function is automatically called
-when you invoke <literal>gtk_widget_show</literal> for a widget, and so has not been
-shown in earlier examples. But the call to
-<literal>gdk_pixmap_create_from_xpm</literal> requires that its <literal>window</literal> argument
-refer to a real X window, so it is necessary to realize the widget
-before this GDK call.</para>
-
<para>The Button widget has the following signals:</para>
<itemizedlist>
<programlisting role="C">
GtkWidget *gtk_toggle_button_new( void );
-GtkWidget *gtk_toggle_button_new_with_label( gchar *label );
+GtkWidget *gtk_toggle_button_new_with_label( const gchar *label );
+
+GtkWidget *gtk_toggle_button_new_with_mnemonic( const gchar *label );
</programlisting>
<para>As you can imagine, these work identically to the normal button widget
-calls. The first creates a blank toggle button, and the second, a
-button with a label widget already packed into it.</para>
+calls. The first creates a blank toggle button, and the last two, a
+button with a label widget already packed into it. The _mnemonic() variant
+additionally parses the label for '_'-prefixed mnemonic characters.</para>
<para>To retrieve the state of the toggle widget, including radio and check
buttons, we use a construct as shown in our example below. This tests
-the state of the toggle, by accessing the <literal>active</literal> field of the
+the state of the toggle button, by accessing the <literal>active</literal> field of the
toggle widget's structure, after first using the
<literal>GTK_TOGGLE_BUTTON</literal> macro to cast the widget pointer into a toggle
widget pointer. The signal of interest to us emitted by toggle
<programlisting role="C">
void toggle_button_callback (GtkWidget *widget, gpointer data)
{
- if (GTK_TOGGLE_BUTTON (widget)->active)
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
{
/* If control reaches here, the toggle button is down */
<programlisting role="C">
void gtk_toggle_button_set_active( GtkToggleButton *toggle_button,
- gint state );
+ gboolean is_active );
</programlisting>
<para>The above call can be used to set the state of the toggle button, and
the right of them. These are often used for toggling options on and
off in applications.</para>
-<para>The two creation functions are similar to those of the normal button.</para>
+<para>The creation functions are similar to those of the normal button.</para>
<programlisting role="C">
GtkWidget *gtk_check_button_new( void );
-GtkWidget *gtk_check_button_new_with_label ( gchar *label );
+GtkWidget *gtk_check_button_new_with_label ( const gchar *label );
+
+GtkWidget *gtk_check_button_new_with_mnemonic ( const gchar *label );
</programlisting>
-<para>The new_with_label function creates a check button with a label beside
-it.</para>
+<para>The gtk_check_button_new_with_label() function creates a check button
+with a label beside it.</para>
<para>Checking the state of the check button is identical to that of the
toggle button.</para>
<programlisting role="C">
GtkWidget *gtk_radio_button_new( GSList *group );
+GtkWidget *gtk_radio_button_new_from_widget( GtkRadioButton *group );
+
GtkWidget *gtk_radio_button_new_with_label( GSList *group,
- gchar *label );
+ const gchar *label );
+
+GtkWidget* gtk_radio_button_new_with_label_from_widget( GtkRadioButton *group,
+ const gchar *label );
+
+GtkWidget *gtk_radio_button_new_with_mnemonic( GSList *group,
+ const gchar *label );
+
+GtkWidget *gtk_radio_button_new_with_mnemonic_from_widget( GtkRadioButton *group,
+ const gchar *label );
+
</programlisting>
<para>You'll notice the extra argument to these calls. They require a group
-to perform their duty properly. The first call to
-gtk_radio_button_new or gtk_radio_button_new_with_label
-should pass NULL as the first argument. Then create a group using:</para>
+to perform their duty properly. The first call to gtk_radio_button_new() or
+gtk_radio_button_new_with_label() should pass NULL as the first argument.
+Then create a group using:</para>
<programlisting role="C">
-GSList *gtk_radio_button_group( GtkRadioButton *radio_button );
+GSList *gtk_radio_button_get_group( GtkRadioButton *radio_button );
</programlisting>
-<para>The important thing to remember is that gtk_radio_button_group must be
-called for each new button added to the group, with the previous
-button passed in as an argument. The result is then passed into the
-next call to gtk_radio_button_new or
-gtk_radio_button_new_with_label. This allows a chain of buttons to be
-established. The example below should make this clear.</para>
+<para>The important thing to remember is that gtk_radio_button_get_group() must be
+called for each new button added to the group, with the previous button passed
+in as an argument. The result is then passed into the next call to
+gtk_radio_button_new() or gtk_radio_button_new_with_label(). This allows a
+chain of buttons to be established. The example below should make this clear.</para>
<para>You can shorten this slightly by using the following syntax, which
-removes the need for a variable to hold the list of buttons. This form
-is used in the example to create the third button:</para>
+removes the need for a variable to hold the list of buttons:</para>
<programlisting role="C">
button2 = gtk_radio_button_new_with_label(
- gtk_radio_button_group (GTK_RADIO_BUTTON (button1)),
+ gtk_radio_button_get_group (GTK_RADIO_BUTTON (button1)),
+ "button2");
+</programlisting>
+
+<para>
+The _from_widget() variants of the creation functions allow you to shorten this
+further, by omitting the gtk_radio_button_get_group() call. This form is used
+in the example to create the third button:
+</para>
+
+<programlisting role="C">
+ button2 = gtk_radio_button_new_with_label_from_widget(
+ GTK_RADIO_BUTTON (button1),
"button2");
</programlisting>
<programlisting role="C">
void gtk_toggle_button_set_active( GtkToggleButton *toggle_button,
- gint state );
+ gboolean state );
</programlisting>
<para>This is described in the section on toggle buttons, and works in
<para>The following example creates a radio button group with three buttons.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/radiobuttons.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start radiobuttons radiobuttons.c -->
GdkEvent *event,
gpointer data )
{
- gtk_main_quit();
+ gtk_main_quit ();
return FALSE;
}
GtkWidget *separator;
GSList *group;
- gtk_init(&argc,&argv);
+ gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC(close_application),
- NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (close_application),
+ NULL);
gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_widget_show (button);
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
- button = gtk_radio_button_new_with_label(group, "button2");
+ button = gtk_radio_button_new_with_label (group, "button2");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
- button = gtk_radio_button_new_with_label(
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
- "button3");
+ button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button),
+ "button3");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
gtk_widget_show (box2);
button = gtk_button_new_with_label ("close");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC(close_application),
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (close_application),
+ G_OBJECT (window));
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show (window);
- gtk_main();
+ gtk_main ();
return 0;
}
<!-- example-end -->
</programlisting>
-<!-- TODO: check out gtk_radio_button_new_from_widget function - TRG -->
-
</sect1>
</chapter>
create one yourself. You create an adjustment using:</para>
<programlisting role="C">
-GtkObject *gtk_adjustment_new( gfloat value,
- gfloat lower,
- gfloat upper,
- gfloat step_increment,
- gfloat page_increment,
- gfloat page_size );
+GtkObject *gtk_adjustment_new( gdouble value,
+ gdouble lower,
+ gdouble upper,
+ gdouble step_increment,
+ gdouble page_increment,
+ gdouble page_size );
</programlisting>
<para>The <literal>value</literal> argument is the initial value you want to give to the
<para>Now, you're probably thinking, since text widgets and viewports insist
on setting everything except the <literal>value</literal> of their adjustments,
-while scrollbars will <emphasis>only</emphasis> touch the adjustment's <literal>value</literal>, if
-you <emphasis>share</emphasis> an adjustment object between a scrollbar and a text
-widget, manipulating the scrollbar will automagically adjust the text
-widget? Of course it will! Just like this:</para>
+while scrollbars will <emphasis>only</emphasis> touch the adjustment's
+<literal>value</literal>, if you <emphasis>share</emphasis> an adjustment
+object between a scrollbar and a text widget, manipulating the scrollbar will
+automagically adjust the viewport widget? Of course it will! Just like this:</para>
<programlisting role="C">
/* creates its own adjustments */
- text = gtk_text_new (NULL, NULL);
+ viewport = gtk_viewport_new (NULL, NULL);
/* uses the newly-created adjustment for the scrollbar as well */
- vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text)->vadj);
+ vscrollbar = gtk_vscrollbar_new (gtk_viewport_get_vadjustment (viewport));
</programlisting>
</sect1>
<programlisting role="C">
struct _GtkAdjustment
{
- GtkData data;
+ GtkObject parent_instance;
- gfloat lower;
- gfloat upper;
- gfloat value;
- gfloat step_increment;
- gfloat page_increment;
- gfloat page_size;
+ gdouble lower;
+ gdouble upper;
+ gdouble value;
+ gdouble step_increment;
+ gdouble page_increment;
+ gdouble page_size;
};
</programlisting>
-<para>The first thing you should know is that there aren't any handy-dandy
-macros or accessor functions for getting the <literal>value</literal> out of an
-Adjustment, so you'll have to (horror of horrors) do it like a
-<emphasis>real</emphasis> C programmer. Don't worry - the <literal>GTK_ADJUSTMENT
-(Object)</literal> macro does run-time type checking (as do all the GTK
-type-casting macros, actually).</para>
+<para>If you don't like to poke directly at struct internals like a
+<emphasis>real</emphasis> C programmer, you can use the following accessor to
+inspect the <literal>value</literal> of an adjustment:</para>
+
+<programlisting role="C">
+gdouble gtk_adjustment_get_value( GtkAdjustment *adjustment);
+</programlisting>
-<para>Since, when you set the <literal>value</literal> of an adjustment, you generally
+<para>Since, when you set the <literal>value</literal> of an Adjustment, you generally
want the change to be reflected by every widget that uses this
adjustment, GTK provides this convenience function to do this:</para>
<programlisting role="C">
void gtk_adjustment_set_value( GtkAdjustment *adjustment,
- gfloat value );
+ gdouble value );
</programlisting>
<para>As mentioned earlier, Adjustment is a subclass of Object just
signal on an adjustment whenever they change its value. This happens
both when user input causes the slider to move on a range widget, as
well as when the program explicitly changes the value with
-<literal>gtk_adjustment_set_value()</literal>. So, for example, if you have a scale
+gtk_adjustment_set_value(). So, for example, if you have a scale
widget, and you want to change the rotation of a picture whenever its
value changes, you would create a callback like this:</para>
<programlisting role="C">
void cb_rotate_picture (GtkAdjustment *adj, GtkWidget *picture)
{
- set_picture_rotation (picture, adj->value);
+ set_picture_rotation (picture, gtk_adjustment_get_value (adj));
...
</programlisting>
<para>and connect it to the scale widget's adjustment like this:</para>
<programlisting role="C">
-gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (cb_rotate_picture), picture);
+g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (cb_rotate_picture), (gpointer) picture);
</programlisting>
<para>What about when a widget reconfigures the <literal>upper</literal> or <literal>lower</literal>
this:</para>
<programlisting role="C">
-gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "changed");
+g_signal_emit_by_name (G_OBJECT (adjustment), "changed");
</programlisting>
<para>Now go forth and adjust!</para>
<title>Range Widgets</title>
<para>The category of range widgets includes the ubiquitous scrollbar widget
-and the less common "scale" widget. Though these two types of widgets
+and the less common scale widget. Though these two types of widgets
are generally used for different purposes, they are quite similar in
function and implementation. All range widgets share a set of common
graphic elements, each of which has its own X window and receives
<para>There are separate types for horizontal and vertical scrollbars.
There really isn't much to say about these. You create them with the
-following functions, defined in <literal><gtk/gtkhscrollbar.h></literal>
-and <literal><gtk/gtkvscrollbar.h></literal>:</para>
+following functions:</para>
<programlisting role="C">
GtkWidget *gtk_hscrollbar_new( GtkAdjustment *adjustment );
<para>As with scrollbars, there are separate widget types for horizontal and
vertical scale widgets. (Most programmers seem to favour horizontal
scale widgets.) Since they work essentially the same way, there's no
-need to treat them separately here. The following functions, defined
-in <literal><gtk/gtkvscale.h></literal> and
-<literal><gtk/gtkhscale.h></literal>, create vertical and horizontal scale
-widgets, respectively:</para>
+need to treat them separately here. The following functions create vertical and
+horizontal scale widgets, respectively:</para>
<programlisting role="C">
GtkWidget *gtk_vscale_new( GtkAdjustment *adjustment );
+GtkWidget *gtk_vscale_new_with_range( gdouble min,
+ gdouble max,
+ gdouble step );
+
GtkWidget *gtk_hscale_new( GtkAdjustment *adjustment );
+
+GtkWidget *gtk_hscale_new_with_range( gdouble min,
+ gdouble max,
+ gdouble step );
</programlisting>
<para>The <literal>adjustment</literal> argument can either be an adjustment which has
-already been created with <literal>gtk_adjustment_new()</literal>, or <literal>NULL</literal>, in
+already been created with gtk_adjustment_new(), or NULL, in
which case, an anonymous Adjustment is created with all of its
-values set to <literal>0.0</literal> (which isn't very useful in this case). In
-order to avoid confusing yourself, you probably want to create your
-adjustment with a <literal>page_size</literal> of <literal>0.0</literal> so that its <literal>upper</literal>
-value actually corresponds to the highest value the user can select.
-(If you're <emphasis>already</emphasis> thoroughly confused, read the section on <link
-linkend="ch-Adjustments">Adjustments</link> again for an explanation of
-what exactly adjustments do and how to create and manipulate them.)</para>
+values set to <literal>0.0</literal> (which isn't very useful in this case).
+In order to avoid confusing yourself, you probably want to create your
+adjustment with a <literal>page_size</literal> of <literal>0.0</literal> so
+that its <literal>upper</literal> value actually corresponds to the highest
+value the user can select. The _new_with_range()Â variants take care of creating
+a suitable adjustment. (If you're <emphasis>already</emphasis> thoroughly
+confused, read the section on <link linkend="ch-Adjustments">Adjustments</link>
+again for an explanation of what exactly adjustments do and how to create and
+manipulate them.)</para>
</sect2>
<programlisting role="C">
void gtk_scale_set_draw_value( GtkScale *scale,
- gint draw_value );
+ gboolean draw_value );
</programlisting>
<para>As you might have guessed, <literal>draw_value</literal> is either <literal>TRUE</literal> or
<literal>FALSE</literal>, with predictable consequences for either one.</para>
<para>The value displayed by a scale widget is rounded to one decimal point
-by default, as is the <literal>value</literal> field in its GtkAdjustment. You can
+by default, as is the <literal>value</literal> field in its Adjustment. You can
change this with:</para>
<programlisting role="C">
GtkPositionType pos );
</programlisting>
-<para>The argument <literal>pos</literal> is of type <literal>GtkPositionType</literal>, which is
-defined in <literal><gtk/gtkenums.h></literal>, and can take one of the
-following values:</para>
+<para>The argument <literal>pos</literal> is of type <literal>GtkPositionType</literal>,
+which can take one of the following values:</para>
<programlisting role="C">
GTK_POS_LEFT
<literal><gtk/gtkscale.h></literal>. The header files for all GTK widgets
are automatically included when you include
<literal><gtk/gtk.h></literal>. But you should look over the header files
-of all widgets that interest you,</para>
+of all widgets that interest you, in order to learn more about their functions
+and features.</para>
</sect2>
</sect1>
<literal><gtk/gtkenums.h></literal> as type <literal>enum GtkUpdateType</literal>,
are:</para>
-<itemizedlist>
-<listitem><simpara>GTK_UPDATE_CONTINUOUS - This is the default. The
+<variablelist>
+<varlistentry>
+<term><literal>GTK_UPDATE_CONTINUOUS</literal></term>
+<listitem><para>This is the default. The
"value_changed" signal is emitted continuously, i.e., whenever the
-slider is moved by even the tiniest amount.</simpara>
+slider is moved by even the tiniest amount.</para>
</listitem>
-
-<listitem><simpara>GTK_UPDATE_DISCONTINUOUS - The "value_changed" signal is
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_UPDATE_DISCONTINUOUS</literal></term>
+<listitem><para>The "value_changed" signal is
only emitted once the slider has stopped moving and the user has
-released the mouse button.</simpara>
+released the mouse button.</para>
</listitem>
-
-<listitem><simpara>GTK_UPDATE_DELAYED - The "value_changed" signal is emitted
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_UPDATE_DELAYED</literal></term>
+<listitem><para>The "value_changed" signal is emitted
when the user releases the mouse button, or if the slider stops moving
-for a short period of time.</simpara>
+for a short period of time.</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
<para>The update policy of a range widget can be set by casting it using the
-<literal>GTK_RANGE (Widget)</literal> macro and passing it to this function:</para>
+<literal>GTK_RANGE(widget)</literal> macro and passing it to this function:</para>
<programlisting role="C">
void gtk_range_set_update_policy( GtkRange *range,
signal on it, like this:</para>
<programlisting role="C">
-gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "changed");
+g_signal_emit_by_name (G_OBJECT (adjustment), "changed");
</programlisting>
</sect2>
adjustment's <literal>page_increment</literal> to be added or subtracted from its
<literal>value</literal>, and the slider to be moved accordingly. Clicking mouse
button-2 in the trough will jump the slider to the point at which the
-button was clicked. Clicking any button on a scrollbar's arrows will
-cause its adjustment's value to change <literal>step_increment</literal> at a time.</para>
-
-<para>It may take a little while to get used to, but by default, scrollbars
-as well as scale widgets can take the keyboard focus in GTK. If you
-think your users will find this too confusing, you can always disable
-this by unsetting the <literal>GTK_CAN_FOCUS</literal> flag on the scrollbar, like
-this:</para>
-
-<programlisting role="C">
-GTK_WIDGET_UNSET_FLAGS (scrollbar, GTK_CAN_FOCUS);
-</programlisting>
+button was clicked. Clicking button-3 in the trough of a range or any button on
+a scrollbar's arrows will cause its adjustment's value to change by
+<literal>step_increment</literal> at a time.</para>
-<para>The key bindings (which are, of course, only active when the widget
-has focus) are slightly different between horizontal and vertical
-range widgets, for obvious reasons. They are also not quite the same
-for scale widgets as they are for scrollbars, for somewhat less
-obvious reasons (possibly to avoid confusion between the keys for
-horizontal and vertical scrollbars in scrolled windows, where both
-operate on the same area).</para>
-
-<!-- ----------------------------------------------------------------- -->
-<sect2>
-<title>Vertical Range Widgets</title>
+<para>Scrollbars are not focusable, thus have no key bindings. The key bindings
+for the other range widgets (which are, of course, only active when the widget
+has focus) are do <emphasis>not</emphasis> differentiate between horizontal and
+vertical range widgets.</para>
-<para>All vertical range widgets can be operated with the up and down arrow
-keys, as well as with the <literal>Page Up</literal> and <literal>Page Down</literal> keys. The
-arrows move the slider up and down by <literal>step_increment</literal>, while
-<literal>Page Up</literal> and <literal>Page Down</literal> move it by <literal>page_increment</literal>.</para>
+<para>All range widgets can be operated with the left, right, up and down arrow
+keys, as well as with the <literal>Page Up</literal> and <literal>Page Down</literal>
+keys. The arrows move the slider up and down by <literal>step_increment</literal>, while
+<literal>Page Up</literal> and <literal>Page Down</literal> move it by
+<literal>page_increment</literal>.</para>
<para>The user can also move the slider all the way to one end or the other
-of the trough using the keyboard. With the VScale widget, this is
-done with the <literal>Home</literal> and <literal>End</literal> keys, whereas with the
-VScrollbar widget, this is done by typing <literal>Control-Page Up</literal>
-and <literal>Control-Page Down</literal>.</para>
-
-</sect2>
-
-<!-- ----------------------------------------------------------------- -->
-<sect2>
-<title>Horizontal Range Widgets</title>
+of the trough using the keyboard. This is done with the <literal>Home</literal>
+and <literal>End</literal> keys.</para>
-<para>The left and right arrow keys work as you might expect in these
-widgets, moving the slider back and forth by <literal>step_increment</literal>. The
-<literal>Home</literal> and <literal>End</literal> keys move the slider to the ends of the trough.
-For the HScale widget, moving the slider by <literal>page_increment</literal> is
-accomplished with <literal>Control-Left</literal> and <literal>Control-Right</literal>,
-while for HScrollbar, it's done with <literal>Control-Home</literal> and
-<literal>Control-End</literal>.</para>
-
-</sect2>
</sect1>
<!-- ----------------------------------------------------------------- -->
<title>Example</title>
<para>This example is a somewhat modified version of the "range controls"
-test from <literal>testgtk.c</literal>. It basically puts up a window with three
+test from <filename>testgtk.c</filename>. It basically puts up a window with three
range widgets all connected to the same adjustment, and a couple of
controls for adjusting some of the parameters mentioned above and in
the section on adjustments, so you can see how they affect the way
these widgets work for the user.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/rangewidgets.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start rangewidgets rangewidgets.c -->
* adjustment to the value specified by the "Page Size" scale */
set->page_size = get->value;
set->page_increment = get->value;
- /* Now emit the "changed" signal to reconfigure all the widgets that
- * are attached to this adjustment */
- g_signal_emit_by_name (GTK_OBJECT (set), "changed");
+
+ /* This sets the adjustment and makes it emit the "changed" signal to
+ reconfigure all the widgets that are attached to this signal. */
+ gtk_adjustment_set_value (set, CLAMP (set->value,
+ set->lower,
+ (set->upper - set->page_size)));
}
void cb_draw_value( GtkToggleButton *button )
/* Convenience functions */
-GtkWidget *make_menu_item( gchar *name,
- GtkSignalFunc callback,
- gpointer data )
+GtkWidget *make_menu_item (gchar *name,
+ GCallback callback,
+ gpointer data)
{
GtkWidget *item;
item = gtk_menu_item_new_with_label (name);
- g_signal_connect (GTK_OBJECT (item), "activate",
- callback, data);
+ g_signal_connect (G_OBJECT (item), "activate",
+ callback, (gpointer) data);
gtk_widget_show (item);
return item;
/* Standard window-creating stuff */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC(gtk_main_quit),
- NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
gtk_window_set_title (GTK_WINDOW (window), "range controls");
box1 = gtk_vbox_new (FALSE, 0);
/* Reuse the same adjustment */
hscale = gtk_hscale_new (GTK_ADJUSTMENT (adj1));
- gtk_widget_set_size_request (GTK_WIDGET (hscale), 200, 30);
+ gtk_widget_set_size_request (GTK_WIDGET (hscale), 200, -1);
scale_set_default_values (GTK_SCALE (hscale));
gtk_box_pack_start (GTK_BOX (box3), hscale, TRUE, TRUE, 0);
gtk_widget_show (hscale);
/* A checkbutton to control whether the value is displayed or not */
button = gtk_check_button_new_with_label("Display value on scale widgets");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
- g_signal_connect (GTK_OBJECT (button), "toggled",
- GTK_SIGNAL_FUNC(cb_draw_value), NULL);
+ g_signal_connect (G_OBJECT (button), "toggled",
+ G_CALLBACK (cb_draw_value), NULL);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);
- opt = gtk_option_menu_new();
- menu = gtk_menu_new();
+ opt = gtk_option_menu_new ();
+ menu = gtk_menu_new ();
item = make_menu_item ("Top",
- GTK_SIGNAL_FUNC(cb_pos_menu_select),
+ G_CALLBACK (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_TOP));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- item = make_menu_item ("Bottom", GTK_SIGNAL_FUNC (cb_pos_menu_select),
+ item = make_menu_item ("Bottom", G_CALLBACK (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_BOTTOM));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- item = make_menu_item ("Left", GTK_SIGNAL_FUNC (cb_pos_menu_select),
+ item = make_menu_item ("Left", G_CALLBACK (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_LEFT));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- item = make_menu_item ("Right", GTK_SIGNAL_FUNC (cb_pos_menu_select),
- GINT_TO_POINTER (GTK_POS_RIGHT));
+ item = make_menu_item ("Right", G_CALLBACK (cb_pos_menu_select),
+ GINT_TO_POINTER (GTK_POS_RIGHT));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu);
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);
- opt = gtk_option_menu_new();
- menu = gtk_menu_new();
+ opt = gtk_option_menu_new ();
+ menu = gtk_menu_new ();
item = make_menu_item ("Continuous",
- GTK_SIGNAL_FUNC (cb_update_menu_select),
+ G_CALLBACK (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_CONTINUOUS));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = make_menu_item ("Discontinuous",
- GTK_SIGNAL_FUNC (cb_update_menu_select),
- GINT_TO_POINTER (GTK_UPDATE_DISCONTINUOUS));
+ G_CALLBACK (cb_update_menu_select),
+ GINT_TO_POINTER (GTK_UPDATE_DISCONTINUOUS));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = make_menu_item ("Delayed",
- GTK_SIGNAL_FUNC (cb_update_menu_select),
+ G_CALLBACK (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_DELAYED));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show (label);
adj2 = gtk_adjustment_new (1.0, 0.0, 5.0, 1.0, 1.0, 0.0);
- g_signal_connect (GTK_OBJECT (adj2), "value_changed",
- GTK_SIGNAL_FUNC (cb_digits_scale), NULL);
+ g_signal_connect (G_OBJECT (adj2), "value_changed",
+ G_CALLBACK (cb_digits_scale), NULL);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adj2));
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
gtk_widget_show (label);
adj2 = gtk_adjustment_new (1.0, 1.0, 101.0, 1.0, 1.0, 0.0);
- g_signal_connect (GTK_OBJECT (adj2), "value_changed",
- GTK_SIGNAL_FUNC (cb_page_size), adj1);
+ g_signal_connect (G_OBJECT (adj2), "value_changed",
+ G_CALLBACK (cb_page_size), (gpointer) adj1);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adj2));
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_button_new_with_label ("Quit");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC(gtk_main_quit),
- NULL);
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
int main( int argc,
char *argv[] )
{
- gtk_init(&argc, &argv);
+ gtk_init (&argc, &argv);
- create_range_controls();
+ create_range_controls ();
- gtk_main();
+ gtk_main ();
return 0;
}
<!-- example-end -->
</programlisting>
-<para>You will notice that the program does not call <literal>gtk_signal_connect</literal>
+<para>You will notice that the program does not call g_signal_connect()
for the "delete_event", but only for the "destroy" signal. This will
still perform the desired function, because an unhandled
"delete_event" will result in a "destroy" signal being given to the
<para>To create a new label, use:</para>
<programlisting role="C">
-GtkWidget *gtk_label_new( char *str );
+GtkWidget *gtk_label_new( const char *str );
+
+GtkWidget *gtk_label_new_with_mnemonic( const char *str );
</programlisting>
<para>The sole argument is the string you wish the label to display.</para>
<para>To change the label's text after creation, use the function:</para>
<programlisting role="C">
-void gtk_label_set_text( GtkLabel *label,
- char *str );
+void gtk_label_set_text( GtkLabel *label,
+ const char *str );
</programlisting>
<para>The first argument is the label you created previously (cast
<para>To retrieve the current string, use:</para>
<programlisting role="C">
-void gtk_label_get( GtkLabel *label,
- char **str );
+const gchar* gtk_label_get_text( GtkLabel *label );
</programlisting>
-<para>The first argument is the label you've created, and the second,
-the return for the string. Do not free the return string, as it is
-used internally by GTK.</para>
+<para>Do not free the returned string, as it is used internally by GTK.</para>
<para>The label text can be justified using:</para>
underlined. For example, the string <literal>"__ __"</literal> would underline the
first two characters and eight and ninth characters.</para>
+<note><para>If you simply want to have an underlined accelerator ("mnemonic")
+in your label, you should use gtk_label_new_with_mnemonic() or
+gtk_label_set_text_with_mnemonic(), not gtk_label_set_pattern().</para>
+</note>
+
<para>Below is a short example to illustrate these functions. This example
makes use of the Frame widget to better demonstrate the label
-styles. You can ignore this for now as the <link linkend="sec-Frames">Frame</link> widget is explained later on.</para>
+styles. You can ignore this for now as the <link linkend="sec-Frames">Frame</link>
+widget is explained later on.</para>
+
+<para>In GTK+ 2.0, label texts can contain markup for font and other text attribute
+changes, and labels may be selectable (for copy-and-paste). These advanced features
+won't be explained here.</para>
+
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/label.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
<programlisting role="C">
<!-- example-start label label.c -->
GtkWidget *label;
/* Initialise GTK */
- gtk_init(&argc, &argv);
+ gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC(gtk_main_quit),
- NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
gtk_window_set_title (GTK_WINDOW (window), "Label");
vbox = gtk_vbox_new (FALSE, 5);
<para>Here's a brief example to illustrate their use.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/arrow.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start arrow arrow.c -->
GtkWidget *button;
GtkWidget *arrow;
- button = gtk_button_new();
+ button = gtk_button_new ();
arrow = gtk_arrow_new (arrow_type, shadow_type);
gtk_container_add (GTK_CONTAINER (button), arrow);
- gtk_widget_show(button);
- gtk_widget_show(arrow);
+ gtk_widget_show (button);
+ gtk_widget_show (arrow);
- return(button);
+ return button;
}
int main( int argc,
gtk_window_set_title (GTK_WINDOW (window), "Arrow Buttons");
/* It's a good idea to do this for all windows. */
- gtk_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_container_add (GTK_CONTAINER (window), box);
/* Pack and show all our widgets */
- gtk_widget_show(box);
+ gtk_widget_show (box);
- button = create_arrow_button(GTK_ARROW_UP, GTK_SHADOW_IN);
+ button = create_arrow_button (GTK_ARROW_UP, GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
- button = create_arrow_button(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+ button = create_arrow_button (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
- button = create_arrow_button(GTK_ARROW_LEFT, GTK_SHADOW_ETCHED_IN);
+ button = create_arrow_button (GTK_ARROW_LEFT, GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
- button = create_arrow_button(GTK_ARROW_RIGHT, GTK_SHADOW_ETCHED_OUT);
+ button = create_arrow_button (GTK_ARROW_RIGHT, GTK_SHADOW_ETCHED_OUT);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
gtk_widget_show (window);
/* Rest in gtk_main and wait for the fun to begin! */
gtk_main ();
- return(0);
+ return 0;
}
<!-- example-end -->
</programlisting>
<para>These are the little text strings that pop up when you leave your
pointer over a button or other widget for a few seconds. They are easy
to use, so I will just explain them without giving an example. If you
-want to see some code, take a look at the testgtk.c program
+want to see some code, take a look at the <filename>testgtk.c</filename> program
distributed with GTK.</para>
<para>Widgets that do not receive events (widgets that do not have their
<para>Disable an enabled set of tooltips.</para>
-<programlisting role="C">
-void gtk_tooltips_set_delay( GtkTooltips *tooltips,
- gint delay );
-</programlisting>
-
-<para>Sets how many milliseconds you have to hold your pointer over the
-widget before the tooltip will pop up. The default is 500
-milliseconds (half a second).</para>
-
-<programlisting role="C">
-void gtk_tooltips_set_colors( GtkTooltips *tooltips,
- GdkColor *background,
- GdkColor *foreground );
-</programlisting>
-
-<para>Set the foreground and background color of the tooltips.</para>
-
<para>And that's all the functions associated with tooltips. More than
you'll ever want to know :-)</para>
pretty easy to use, as you will see with the code below. But first
lets start out with the calls to create a new progress bar.</para>
-<para>There are two ways to create a progress bar, one simple that takes
-no arguments, and one that takes an Adjustment object as an
-argument. If the former is used, the progress bar creates its own
-adjustment object.</para>
-
<programlisting role="C">
GtkWidget *gtk_progress_bar_new( void );
-
-GtkWidget *gtk_progress_bar_new_with_adjustment( GtkAdjustment *adjustment );
-</programlisting>
-
-<para>The second method has the advantage that we can use the adjustment
-object to specify our own range parameters for the progress bar.</para>
-
-<para>The adjustment of a progress object can be changed dynamically using:</para>
-
-<programlisting role="C">
-void gtk_progress_set_adjustment( GtkProgress *progress,
- GtkAdjustment *adjustment );
</programlisting>
<para>Now that the progress bar has been created we can use it.</para>
<programlisting role="C">
-void gtk_progress_bar_update( GtkProgressBar *pbar,
- gfloat percentage );
+void gtk_progress_bar_set_fraction ( GtkProgressBar *pbar,
+ gdouble fraction );
</programlisting>
<para>The first argument is the progress bar you wish to operate on, and the
GTK_PROGRESS_TOP_TO_BOTTOM
</programlisting>
-<para>When used as a measure of how far a process has progressed, the
-ProgressBar can be set to display its value in either a continuous
-or discrete mode. In continuous mode, the progress bar is updated for
-each value. In discrete mode, the progress bar is updated in a number
-of discrete blocks. The number of blocks is also configurable.</para>
-
-<para>The style of a progress bar can be set using the following function.</para>
-
-<programlisting role="C">
-void gtk_progress_bar_set_bar_style( GtkProgressBar *pbar,
- GtkProgressBarStyle style );
-</programlisting>
-
-<para>The <literal>style</literal> parameter can take one of two values:</para>
-
-<programlisting role="C">
- GTK_PROGRESS_CONTINUOUS
- GTK_PROGRESS_DISCRETE
-</programlisting>
-
-<para>The number of discrete blocks can be set by calling</para>
-
-<programlisting role="C">
-void gtk_progress_bar_set_discrete_blocks( GtkProgressBar *pbar,
- guint blocks );
-</programlisting>
-
<para>As well as indicating the amount of progress that has occured, the
-progress bar may be set to just indicate that there is some
-activity. This can be useful in situations where progress cannot be
-measured against a value range. Activity mode is not effected by the
-bar style that is described above, and overrides it. This mode is
-either TRUE or FALSE, and is selected by the following function.</para>
+progress bar may be set to just indicate that there is some activity.
+This can be useful in situations where progress cannot be measured against
+a value range. The following function indicates that some progress has been
+made.</para>
<programlisting role="C">
-void gtk_progress_set_activity_mode( GtkProgress *progress,
- guint activity_mode );
+void gtk_progress_bar_pulse ( GtkProgressBar *progress );
</programlisting>
-<para>The step size of the activity indicator, and the number of blocks are
-set using the following functions.</para>
+<para>The step size of the activity indicator is set using the following
+function.</para>
<programlisting role="C">
-void gtk_progress_bar_set_activity_step( GtkProgressBar *pbar,
- guint step );
-
-void gtk_progress_bar_set_activity_blocks( GtkProgressBar *pbar,
- guint blocks );
+void gtk_progress_bar_set_pulse_step( GtkProgressBar *pbar,
+ gdouble fraction );
</programlisting>
-<para>When in continuous mode, the progress bar can also display a
+<para>When not in activity mode, the progress bar can also display a
configurable text string within its trough, using the following
function.</para>
<programlisting role="C">
-void gtk_progress_set_format_string( GtkProgress *progress,
- gchar *format);
+void gtk_progress_bar_set_text( GtkProgressBar *progress,
+ const gchar *text );
</programlisting>
-<para>The <literal>format</literal> argument is similiar to one that would be used in a C
-<literal>printf</literal> statement. The following directives may be used within the
-format string:</para>
+<note><para>Note that gtk_progress_set_text() doesn't support the printf()-like formatting
+of the GTK+ 1.2 Progressbar.</para></note>
-<itemizedlist>
-<listitem><simpara> %p - percentage</simpara>
-</listitem>
-<listitem><simpara> %v - value</simpara>
-</listitem>
-<listitem><simpara> %l - lower range value</simpara>
-</listitem>
-<listitem><simpara> %u - upper range value</simpara>
-</listitem>
-</itemizedlist>
+<para>You can turn off the display of the string by calling gtk_progess_bar_set_text()
+again with NULL as second argument.</para>
-<para>The displaying of this text string can be toggled using:</para>
+<para>The current text setting of a progressbar can be retrieved with the
+following function. Do not free the returned string.</para>
<programlisting role="C">
-void gtk_progress_set_show_text( GtkProgress *progress,
- gint show_text );
+const gchar *gtk_progress_bar_get_text( GtkProgressBar *pbar );
</programlisting>
-<para>The <literal>show_text</literal> argument is a boolean TRUE/FALSE value. The
-appearance of the text can be modified further using:</para>
-
-<programlisting role="C">
-void gtk_progress_set_text_alignment( GtkProgress *progress,
- gfloat x_align,
- gfloat y_align );
-</programlisting>
+<para>Progress Bars are usually used with timeouts or other such functions
+(see section on <link linkend="ch-Timeouts">Timeouts, I/O and Idle Functions</link>)
+to give the illusion of multitasking. All will employ the
+gtk_progress_bar_set_fraction() or gtk_progress_bar_pulse() functions in the
+same manner.</para>
-<para>The <literal>x_align</literal> and <literal>y_align</literal> arguments take values between 0.0
-and 1.0. Their values indicate the position of the text string within
-the trough. Values of 0.0 for both would place the string in the top
-left hand corner; values of 0.5 (the default) centres the text, and
-values of 1.0 places the text in the lower right hand corner.</para>
+<para>Here is an example of the progress bar, updated using timeouts. This
+code also shows you how to reset the Progress Bar.</para>
-<para>The current text setting of a progress object can be retrieved using
-the current or a specified adjustment value using the following two
-functions. The character string returned by these functions should be
-freed by the application (using the g_free() function). These
-functions return the formatted string that would be displayed within
-the trough.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/progressbar.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
<programlisting role="C">
-gchar *gtk_progress_get_current_text( GtkProgress *progress );
+<!-- example-start progressbar progressbar.c -->
-gchar *gtk_progress_get_text_from_value( GtkProgress *progress,
- gfloat value );
-</programlisting>
+#include <gtk/gtk.h>
-<para>There is yet another way to change the range and value of a progress
-object using the following function:</para>
-
-<programlisting role="C">
-void gtk_progress_configure( GtkProgress *progress,
- gfloat value,
- gfloat min,
- gfloat max );
-</programlisting>
-
-<para>This function provides quite a simple interface to the range and value
-of a progress object.</para>
-
-<para>The remaining functions can be used to get and set the current value
-of a progess object in various types and formats:</para>
-
-<programlisting role="C">
-void gtk_progress_set_percentage( GtkProgress *progress,
- gfloat percentage );
-
-void gtk_progress_set_value( GtkProgress *progress,
- gfloat value );
-
-gfloat gtk_progress_get_value( GtkProgress *progress );
-
-gfloat gtk_progress_get_current_percentage( GtkProgress *progress );
-
-gfloat gtk_progress_get_percentage_from_value( GtkProgress *progress,
- gfloat value );
-</programlisting>
-
-<para>These functions are pretty self explanatory. The last function uses
-the the adjustment of the specified progess object to compute the
-percentage value of the given range value.</para>
-
-<para>Progress Bars are usually used with timeouts or other such functions
-(see section on <link linkend="ch-Timeouts">Timeouts, I/O and Idle Functions</link>) to give
-the illusion of multitasking. All will employ the
-gtk_progress_bar_update function in the same manner.</para>
-
-<para>Here is an example of the progress bar, updated using timeouts. This
-code also shows you how to reset the Progress Bar.</para>
-
-<programlisting role="C">
-<!-- example-start progressbar progressbar.c -->
-
-#include <gtk/gtk.h>
-
-typedef struct _ProgressData {
- GtkWidget *window;
- GtkWidget *pbar;
- int timer;
-} ProgressData;
+typedef struct _ProgressData {
+ GtkWidget *window;
+ GtkWidget *pbar;
+ int timer;
+ gboolean activity_mode;
+} ProgressData;
/* Update the value of the progress bar so that we get
* some movement */
gint progress_timeout( gpointer data )
{
- gfloat new_val;
- GtkAdjustment *adj;
-
- /* Calculate the value of the progress bar using the
- * value range set in the adjustment object */
-
- new_val = gtk_progress_get_value( GTK_PROGRESS(data) ) + 1;
-
- adj = GTK_PROGRESS (data)->adjustment;
- if (new_val > adj->upper)
- new_val = adj->lower;
-
- /* Set the new value */
- gtk_progress_set_value (GTK_PROGRESS (data), new_val);
-
- /* As this is a timeout function, return TRUE so that it
- * continues to get called */
- return TRUE;
+ ProgressData *pdata = (ProgressData *)data;
+ gdouble new_val;
+
+ if (pdata->activity_mode)
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
+ else
+ {
+ /* Calculate the value of the progress bar using the
+ * value range set in the adjustment object */
+
+ new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
+
+ if (new_val > 1.0)
+ new_val = 0.0;
+
+ /* Set the new value */
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
+ }
+
+ /* As this is a timeout function, return TRUE so that it
+ * continues to get called */
+ return TRUE;
}
-/* Callback that toggles the text display within the progress
- * bar trough */
+/* Callback that toggles the text display within the progress bar trough */
void toggle_show_text( GtkWidget *widget,
ProgressData *pdata )
{
- gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
- GTK_TOGGLE_BUTTON (widget)->active);
+ const gchar *text;
+
+ text = gtk_progress_bar_get_text (GTK_PROGRESS_BAR (pdata->pbar));
+ if (text && *text)
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar), "");
+ else
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar), "some text");
}
-/* Callback that toggles the activity mode of the progress
- * bar */
+/* Callback that toggles the activity mode of the progress bar */
void toggle_activity_mode( GtkWidget *widget,
ProgressData *pdata )
{
- gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
- GTK_TOGGLE_BUTTON (widget)->active);
+ pdata->activity_mode = !pdata->activity_mode;
+ if (pdata->activity_mode)
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
+ else
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), 0.0);
}
-/* Callback that toggles the continuous mode of the progress
- * bar */
-void set_continuous_mode( GtkWidget *widget,
- ProgressData *pdata )
-{
- gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
- GTK_PROGRESS_CONTINUOUS);
+
+/* Callback that toggles the orientation of the progress bar */
+void toggle_orientation( GtkWidget *widget,
+ ProgressData *pdata )
+{
+ switch (gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (pdata->pbar))) {
+ case GTK_PROGRESS_LEFT_TO_RIGHT:
+ gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
+ GTK_PROGRESS_RIGHT_TO_LEFT);
+ break;
+ case GTK_PROGRESS_RIGHT_TO_LEFT:
+ gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
+ GTK_PROGRESS_LEFT_TO_RIGHT);
+ break;
+ default:
+ // do nothing
+ }
}
-/* Callback that toggles the discrete mode of the progress
- * bar */
-void set_discrete_mode( GtkWidget *widget,
- ProgressData *pdata )
-{
- gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
- GTK_PROGRESS_DISCRETE);
-}
/* Clean up allocated memory and remove the timer */
void destroy_progress( GtkWidget *widget,
ProgressData *pdata)
{
- gtk_timeout_remove (pdata->timer);
- pdata->timer = 0;
- pdata->window = NULL;
- g_free(pdata);
- gtk_main_quit();
+ gtk_timeout_remove (pdata->timer);
+ pdata->timer = 0;
+ pdata->window = NULL;
+ g_free (pdata);
+ gtk_main_quit ();
}
int main( int argc,
GtkWidget *align;
GtkWidget *separator;
GtkWidget *table;
- GtkAdjustment *adj;
GtkWidget *button;
GtkWidget *check;
GtkWidget *vbox;
gtk_init (&argc, &argv);
- /* Allocate memory for the data that is passwd to the callbacks */
- pdata = g_malloc( sizeof(ProgressData) );
+ /* Allocate memory for the data that is passed to the callbacks */
+ pdata = g_malloc (sizeof (ProgressData));
- pdata->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
+ pdata->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
- g_signal_connect (GTK_OBJECT (pdata->window), "destroy",
- GTK_SIGNAL_FUNC (destroy_progress),
- pdata);
- gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
- gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
+ g_signal_connect (G_OBJECT (pdata->window), "destroy",
+ G_CALLBACK (destroy_progress),
+ (gpointer) pdata);
+ gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
+ gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
vbox = gtk_vbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
- gtk_container_add (GTK_CONTAINER (pdata->window), vbox);
- gtk_widget_show(vbox);
+ gtk_container_add (GTK_CONTAINER (pdata->window), vbox);
+ gtk_widget_show (vbox);
/* Create a centering alignment object */
align = gtk_alignment_new (0.5, 0.5, 0, 0);
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 5);
- gtk_widget_show(align);
-
- /* Create a Adjusment object to hold the range of the
- * progress bar */
- adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 150, 0, 0, 0);
-
- /* Create the GtkProgressBar using the adjustment */
- pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
-
- /* Set the format of the string that can be displayed in the
- * trough of the progress bar:
- * %p - percentage
- * %v - value
- * %l - lower range value
- * %u - upper range value */
- gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
- "%v from [%l-%u] (=%p%%)");
- gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
- gtk_widget_show(pdata->pbar);
+ gtk_widget_show (align);
+
+ /* Create the GtkProgressBar */
+ pdata->pbar = gtk_progress_bar_new ();
+
+ gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
+ gtk_widget_show (pdata->pbar);
/* Add a timer callback to update the value of the progress bar */
- pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
+ pdata->timer = gtk_timeout_add (100, progress_timeout, pdata);
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
- gtk_widget_show(separator);
+ gtk_widget_show (separator);
/* rows, columns, homogeneous */
table = gtk_table_new (2, 3, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
- gtk_widget_show(table);
+ gtk_widget_show (table);
/* Add a check button to select displaying of the trough text */
check = gtk_check_button_new_with_label ("Show text");
gtk_table_attach (GTK_TABLE (table), check, 0, 1, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
- 5, 5);
- g_signal_connect (GTK_OBJECT (check), "clicked",
- GTK_SIGNAL_FUNC (toggle_show_text),
- pdata);
- gtk_widget_show(check);
+ 5, 5);
+ g_signal_connect (G_OBJECT (check), "clicked",
+ G_CALLBACK (toggle_show_text),
+ (gpointer) pdata);
+ gtk_widget_show (check);
/* Add a check button to toggle activity mode */
check = gtk_check_button_new_with_label ("Activity mode");
gtk_table_attach (GTK_TABLE (table), check, 0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5, 5);
- g_signal_connect (GTK_OBJECT (check), "clicked",
- GTK_SIGNAL_FUNC (toggle_activity_mode),
- pdata);
- gtk_widget_show(check);
-
- separator = gtk_vseparator_new ();
- gtk_table_attach (GTK_TABLE (table), separator, 1, 2, 0, 2,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
- 5, 5);
- gtk_widget_show(separator);
-
- /* Add a radio button to select continuous display mode */
- button = gtk_radio_button_new_with_label (NULL, "Continuous");
- gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
- 5, 5);
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (set_continuous_mode),
- pdata);
- gtk_widget_show (button);
+ g_signal_connect (G_OBJECT (check), "clicked",
+ G_CALLBACK (toggle_activity_mode),
+ (gpointer) pdata);
+ gtk_widget_show (check);
- /* Add a radio button to select discrete display mode */
- button = gtk_radio_button_new_with_label(
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
- "Discrete");
- gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,
+ /* Add a check button to toggle orientation */
+ check = gtk_check_button_new_with_label ("Right to Left");
+ gtk_table_attach (GTK_TABLE (table), check, 0, 1, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5, 5);
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (set_discrete_mode),
- pdata);
- gtk_widget_show (button);
-
- separator = gtk_hseparator_new ();
- gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
- gtk_widget_show(separator);
+ g_signal_connect (G_OBJECT (check), "clicked",
+ G_CALLBACK (toggle_orientation),
+ (gpointer) pdata);
+ gtk_widget_show (check);
/* Add a button to exit the program */
button = gtk_button_new_with_label ("close");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (pdata->window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (pdata->window));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
/* This makes it so the button is the default. */
/* This grabs this button to be the default button. Simply hitting
* the "Enter" key will cause this button to activate. */
gtk_widget_grab_default (button);
- gtk_widget_show(button);
+ gtk_widget_show (button);
- gtk_widget_show (pdata->window);
+ gtk_widget_show (pdata->window);
gtk_main ();
"action_area".</para>
<para>The Dialog widget can be used for pop-up messages to the user, and
-other similar tasks. It is really basic, and there is only one
-function for the dialog box, which is:</para>
+other similar tasks. There are two functions to create a new Dialog.</para>
<programlisting role="C">
GtkWidget *gtk_dialog_new( void );
-</programlisting>
-
-<para>So to create a new dialog box, use,</para>
-<programlisting role="C">
- GtkWidget *window;
- window = gtk_dialog_new ();
+GtkWidget *gtk_dialog_new_with_buttons( const gchar *title,
+ GtkWindow *parent,
+ GtkDialogFlags flags,
+ const gchar *first_button_text,
+ ... );
</programlisting>
-<para>This will create the dialog box, and it is now up to you to use it.
-You could pack a button in the action_area by doing something like this:</para>
+<para>The first function will create an empty dialog, and it is now up to you to use
+ it. You could pack a button in the action_area by doing something like this:</para>
<programlisting role="C">
button = ...
the boxes provided. For example, you could pack a table into the
vertical box.</para>
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-Pixmaps">
-<title>Pixmaps</title>
-
-<para>Pixmaps are data structures that contain pictures. These pictures can
-be used in various places, but most commonly as icons on the X
-desktop, or as cursors.</para>
-
-<para>A pixmap which only has 2 colors is called a bitmap, and there are a
-few additional routines for handling this common special case.</para>
-
-<para>To understand pixmaps, it would help to understand how X window
-system works. Under X, applications do not need to be running on the
-same computer that is interacting with the user. Instead, the various
-applications, called "clients", all communicate with a program which
-displays the graphics and handles the keyboard and mouse. This
-program which interacts directly with the user is called a "display
-server" or "X server." Since the communication might take place over
-a network, it's important to keep some information with the X server.
-Pixmaps, for example, are stored in the memory of the X server. This
-means that once pixmap values are set, they don't need to keep getting
-transmitted over the network; instead a command is sent to "display
-pixmap number XYZ here." Even if you aren't using X with GTK
-currently, using constructs such as Pixmaps will make your programs
-work acceptably under X.</para>
-
-<para>To use pixmaps in GTK, we must first build a GdkPixmap structure using
-routines from the GDK layer. Pixmaps can either be created from
-in-memory data, or from data read from a file. We'll go through each
-of the calls to create a pixmap.</para>
-
-<programlisting role="C">
-GdkPixmap *gdk_bitmap_create_from_data( GdkWindow *window,
- gchar *data,
- gint width,
- gint height );
-</programlisting>
-
-<para>This routine is used to create a single-plane pixmap (2 colors) from
-data in memory. Each bit of the data represents whether that pixel is
-off or on. Width and height are in pixels. The GdkWindow pointer is to
-the current window, since a pixmap's resources are meaningful only in
-the context of the screen where it is to be displayed.</para>
-
-<programlisting role="C">
-GdkPixmap *gdk_pixmap_create_from_data( GdkWindow *window,
- gchar *data,
- gint width,
- gint height,
- gint depth,
- GdkColor *fg,
- GdkColor *bg );
-</programlisting>
-
-<para>This is used to create a pixmap of the given depth (number of colors) from
-the bitmap data specified. <literal>fg</literal> and <literal>bg</literal> are the foreground and
-background color to use.</para>
-
-<programlisting role="C">
-GdkPixmap *gdk_pixmap_create_from_xpm( GdkWindow *window,
- GdkBitmap **mask,
- GdkColor *transparent_color,
- const gchar *filename );
-</programlisting>
-
-<para>XPM format is a readable pixmap representation for the X Window
-System. It is widely used and many different utilities are available
-for creating image files in this format. The file specified by
-filename must contain an image in that format and it is loaded into
-the pixmap structure. The mask specifies which bits of the pixmap are
-opaque. All other bits are colored using the color specified by
-transparent_color. An example using this follows below.</para>
-
-<programlisting role="C">
-GdkPixmap *gdk_pixmap_create_from_xpm_d( GdkWindow *window,
- GdkBitmap **mask,
- GdkColor *transparent_color,
- gchar **data );
-</programlisting>
-
-<para>Small images can be incorporated into a program as data in the XPM
-format. A pixmap is created using this data, instead of reading it
-from a file. An example of such data is</para>
-
-<programlisting role="C">
-/* XPM */
-static const char * xpm_data[] = {
-"16 16 3 1",
-" c None",
-". c #000000000000",
-"X c #FFFFFFFFFFFF",
-" ",
-" ...... ",
-" .XXX.X. ",
-" .XXX.XX. ",
-" .XXX.XXX. ",
-" .XXX..... ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" ......... ",
-" ",
-" "};
-</programlisting>
-
-<para>When we're done using a pixmap and not likely to reuse it again soon,
-it is a good idea to release the resource using
-gdk_pixmap_unref(). Pixmaps should be considered a precious resource,
-because they take up memory in the end-user's X server process. Even
-though the X client you write may run on a powerful "server" computer,
-the user may be running the X server on a small personal computer.</para>
-
-<para>Once we've created a pixmap, we can display it as a GTK widget. We
-must create a GTK pixmap widget to contain the GDK pixmap. This is
-done using</para>
-
-<programlisting role="C">
-GtkWidget *gtk_pixmap_new( GdkPixmap *pixmap,
- GdkBitmap *mask );
-</programlisting>
-
-<para>The other pixmap widget calls are</para>
-
-<programlisting role="C">
-guint gtk_pixmap_get_type( void );
-
-void gtk_pixmap_set( GtkPixmap *pixmap,
- GdkPixmap *val,
- GdkBitmap *mask );
-
-void gtk_pixmap_get( GtkPixmap *pixmap,
- GdkPixmap **val,
- GdkBitmap **mask);
-</programlisting>
-
-<para>gtk_pixmap_set is used to change the pixmap that the widget is currently
-managing. Val is the pixmap created using GDK.</para>
-
-<para>The following is an example of using a pixmap in a button.</para>
-
-<programlisting role="C">
-<!-- example-start pixmap pixmap.c -->
-
-#include <gtk/gtk.h>
-
-
-/* XPM data of Open-File icon */
-static const char * xpm_data[] = {
-"16 16 3 1",
-" c None",
-". c #000000000000",
-"X c #FFFFFFFFFFFF",
-" ",
-" ...... ",
-" .XXX.X. ",
-" .XXX.XX. ",
-" .XXX.XXX. ",
-" .XXX..... ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" .XXXXXXX. ",
-" ......... ",
-" ",
-" "};
-
-
-/* when invoked (via signal delete_event), terminates the application.
- */
-gint close_application( GtkWidget *widget,
- GdkEvent *event,
- gpointer data )
-{
- gtk_main_quit();
- return(FALSE);
-}
-
-
-/* is invoked when the button is clicked. It just prints a message.
- */
-void button_clicked( GtkWidget *widget,
- gpointer data ) {
- g_print( "button clicked\n" );
-}
-
-int main( int argc,
- char *argv[] )
-{
- /* GtkWidget is the storage type for widgets */
- GtkWidget *window, *pixmapwid, *button;
- GdkPixmap *pixmap;
- GdkBitmap *mask;
- GtkStyle *style;
-
- /* create the main window, and attach delete_event signal to terminating
- the application */
- gtk_init( &argc, &argv );
- window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
- gtk_signal_connect( GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (close_application), NULL );
- gtk_container_set_border_width( GTK_CONTAINER (window), 10 );
- gtk_widget_show( window );
-
- /* now for the pixmap from gdk */
- style = gtk_widget_get_style( window );
- pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
- &style->bg[GTK_STATE_NORMAL],
- (gchar **)xpm_data );
-
- /* a pixmap widget to contain the pixmap */
- pixmapwid = gtk_pixmap_new( pixmap, mask );
- gtk_widget_show( pixmapwid );
-
- /* a button to contain the pixmap widget */
- button = gtk_button_new();
- gtk_container_add( GTK_CONTAINER(button), pixmapwid );
- gtk_container_add( GTK_CONTAINER(window), button );
- gtk_widget_show( button );
-
- gtk_signal_connect( GTK_OBJECT(button), "clicked",
- GTK_SIGNAL_FUNC(button_clicked), NULL );
-
- /* show the window */
- gtk_main ();
-
- return 0;
-}
-<!-- example-end -->
-</programlisting>
-
-<para>To load a file from an XPM data file called icon0.xpm in the current
-directory, we would have created the pixmap thus</para>
-
-<programlisting role="C">
- /* load a pixmap from a file */
- pixmap = gdk_pixmap_create_from_xpm( window->window, &mask,
- &style->bg[GTK_STATE_NORMAL],
- "./icon0.xpm" );
- pixmapwid = gtk_pixmap_new( pixmap, mask );
- gtk_widget_show( pixmapwid );
- gtk_container_add( GTK_CONTAINER(window), pixmapwid );
-</programlisting>
-
-<para>A disadvantage of using pixmaps is that the displayed object is always
-rectangular, regardless of the image. We would like to create desktops
-and applications with icons that have more natural shapes. For
-example, for a game interface, we would like to have round buttons to
-push. The way to do this is using shaped windows.</para>
-
-<para>A shaped window is simply a pixmap where the background pixels are
-transparent. This way, when the background image is multi-colored, we
-don't overwrite it with a rectangular, non-matching border around our
-icon. The following example displays a full wheelbarrow image on the
-desktop.</para>
-
-<programlisting role="C">
-<!-- example-start wheelbarrow wheelbarrow.c -->
-
-#include <gtk/gtk.h>
-
-/* XPM */
-static char * WheelbarrowFull_xpm[] = {
-"48 48 64 1",
-" c None",
-". c #DF7DCF3CC71B",
-"X c #965875D669A6",
-"o c #71C671C671C6",
-"O c #A699A289A699",
-"+ c #965892489658",
-"@ c #8E38410330C2",
-"# c #D75C7DF769A6",
-"$ c #F7DECF3CC71B",
-"% c #96588A288E38",
-"& c #A69992489E79",
-"* c #8E3886178E38",
-"= c #104008200820",
-"- c #596510401040",
-"; c #C71B30C230C2",
-": c #C71B9A699658",
-"> c #618561856185",
-", c #20811C712081",
-"< c #104000000000",
-"1 c #861720812081",
-"2 c #DF7D4D344103",
-"3 c #79E769A671C6",
-"4 c #861782078617",
-"5 c #41033CF34103",
-"6 c #000000000000",
-"7 c #49241C711040",
-"8 c #492445144924",
-"9 c #082008200820",
-"0 c #69A618611861",
-"q c #B6DA71C65144",
-"w c #410330C238E3",
-"e c #CF3CBAEAB6DA",
-"r c #71C6451430C2",
-"t c #EFBEDB6CD75C",
-"y c #28A208200820",
-"u c #186110401040",
-"i c #596528A21861",
-"p c #71C661855965",
-"a c #A69996589658",
-"s c #30C228A230C2",
-"d c #BEFBA289AEBA",
-"f c #596545145144",
-"g c #30C230C230C2",
-"h c #8E3882078617",
-"j c #208118612081",
-"k c #38E30C300820",
-"l c #30C2208128A2",
-"z c #38E328A238E3",
-"x c #514438E34924",
-"c c #618555555965",
-"v c #30C2208130C2",
-"b c #38E328A230C2",
-"n c #28A228A228A2",
-"m c #41032CB228A2",
-"M c #104010401040",
-"N c #492438E34103",
-"B c #28A2208128A2",
-"V c #A699596538E3",
-"C c #30C21C711040",
-"Z c #30C218611040",
-"A c #965865955965",
-"S c #618534D32081",
-"D c #38E31C711040",
-"F c #082000000820",
-" ",
-" .XoO ",
-" +@#$%o& ",
-" *=-;#::o+ ",
-" >,<12#:34 ",
-" 45671#:X3 ",
-" +89<02qwo ",
-"e* >,67;ro ",
-"ty> 459@>+&& ",
-"$2u+ ><ipas8* ",
-"%$;=* *3:.Xa.dfg> ",
-"Oh$;ya *3d.a8j,Xe.d3g8+ ",
-" Oh$;ka *3d$a8lz,,xxc:.e3g54 ",
-" Oh$;kO *pd$%svbzz,sxxxxfX..&wn> ",
-" Oh$@mO *3dthwlsslszjzxxxxxxx3:td8M4 ",
-" Oh$@g& *3d$XNlvvvlllm,mNwxxxxxxxfa.:,B* ",
-" Oh$@,Od.czlllllzlmmqV@V#V@fxxxxxxxf:%j5& ",
-" Oh$1hd5lllslllCCZrV#r#:#2AxxxxxxxxxcdwM* ",
-" OXq6c.%8vvvllZZiqqApA:mq:Xxcpcxxxxxfdc9* ",
-" 2r<6gde3bllZZrVi7S@SV77A::qApxxxxxxfdcM ",
-" :,q-6MN.dfmZZrrSS:#riirDSAX@Af5xxxxxfevo",
-" +A26jguXtAZZZC7iDiCCrVVii7Cmmmxxxxxx%3g",
-" *#16jszN..3DZZZZrCVSA2rZrV7Dmmwxxxx&en",
-" p2yFvzssXe:fCZZCiiD7iiZDiDSSZwwxx8e*>",
-" OA1<jzxwwc:$d%NDZZZZCCCZCCZZCmxxfd.B ",
-" 3206Bwxxszx%et.eaAp77m77mmmf3&eeeg* ",
-" @26MvzxNzvlbwfpdettttttttttt.c,n& ",
-" *;16=lsNwwNwgsvslbwwvccc3pcfu<o ",
-" p;<69BvwwsszslllbBlllllllu<5+ ",
-" OS0y6FBlvvvzvzss,u=Blllj=54 ",
-" c1-699Blvlllllu7k96MMMg4 ",
-" *10y8n6FjvllllB<166668 ",
-" S-kg+>666<M<996-y6n<8* ",
-" p71=4 m69996kD8Z-66698&& ",
-" &i0ycm6n4 ogk17,0<6666g ",
-" N-k-<> >=01-kuu666> ",
-" ,6ky& &46-10ul,66, ",
-" Ou0<> o66y<ulw<66& ",
-" *kk5 >66By7=xu664 ",
-" <<M4 466lj<Mxu66o ",
-" *>> +66uv,zN666* ",
-" 566,xxj669 ",
-" 4666FF666> ",
-" >966666M ",
-" oM6668+ ",
-" *4 ",
-" ",
-" "};
-
-
-/* When invoked (via signal delete_event), terminates the application */
-gint close_application( GtkWidget *widget,
- GdkEvent *event,
- gpointer data )
-{
- gtk_main_quit();
- return(FALSE);
-}
-
-int main (int argc,
- char *argv[] )
-{
- /* GtkWidget is the storage type for widgets */
- GtkWidget *window, *pixmap, *fixed;
- GdkPixmap *gdk_pixmap;
- GdkBitmap *mask;
- GtkStyle *style;
- GdkGC *gc;
-
- /* Create the main window, and attach delete_event signal to terminate
- * the application. Note that the main window will not have a titlebar
- * since we're making it a popup. */
- gtk_init (&argc, &argv);
- window = gtk_window_new( GTK_WINDOW_POPUP );
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (close_application), NULL);
- gtk_widget_show (window);
-
- /* Now for the pixmap and the pixmap widget */
- style = gtk_widget_get_default_style();
- gc = style->black_gc;
- gdk_pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
- &style->bg[GTK_STATE_NORMAL],
- WheelbarrowFull_xpm );
- pixmap = gtk_image_new_from_pixmap (gdk_pixmap, mask);
- gtk_widget_show( pixmap );
-
- /* To display the pixmap, we use a fixed widget to place the pixmap */
- fixed = gtk_fixed_new();
- gtk_widget_set_size_request (fixed, 200, 200);
- gtk_fixed_put( GTK_FIXED(fixed), pixmap, 0, 0 );
- gtk_container_add( GTK_CONTAINER(window), fixed );
- gtk_widget_show( fixed );
-
- /* This masks out everything except for the image itself */
- gtk_widget_shape_combine_mask( window, mask, 0, 0 );
-
- /* show the window */
- /*gtk_widget_set_uposition( window, 20, 400 );*/
- gtk_widget_show( window );
- gtk_main ();
-
- return 0;
-}
-<!-- example-end -->
-</programlisting>
-
-<para>To make the wheelbarrow image sensitive, we could attach the button
-press event signal to make it do something. The following few lines
-would make the picture sensitive to a mouse button being pressed which
-makes the application terminate.</para>
-
-<programlisting role="C">
- gtk_widget_set_events( window,
- gtk_widget_get_events( window ) |
- GDK_BUTTON_PRESS_MASK );
-
- gtk_signal_connect( GTK_OBJECT(window), "button_press_event",
- GTK_SIGNAL_FUNC(close_application), NULL );
-</programlisting>
-
+<para>The more complicated _new_with_buttons() variant allows to set one or
+more of the following flags.</para>
+
+<variablelist>
+<varlistentry>
+<term><literal>GTK_DIALOG_MODAL</literal></term>
+<listitem><para>make the dialog modal.
+</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_DIALOG_DESTROY_WITH_PARENT</literal></term>
+<listitem><para>ensures that the dialog window is destroyed together with the specified
+parent.</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_DIALOG_NO_SEPARATOR</literal></term>
+<listitem><para>omits the separator between the vbox and the action_area.
+</para></listitem>
+</varlistentry>
+</variablelist>
</sect1>
<!-- ----------------------------------------------------------------- -->
<programlisting role="C">
void gtk_ruler_set_range( GtkRuler *ruler,
- gfloat lower,
- gfloat upper,
- gfloat position,
- gfloat max_size );
+ gdouble lower,
+ gdouble upper,
+ gdouble position,
+ gdouble max_size );
</programlisting>
<para>The lower and upper arguments define the extent of the ruler, and
<programlisting role="C">
#define EVENT_METHOD(i, x) GTK_WIDGET_GET_CLASS(i)->x
- gtk_signal_connect_object( GTK_OBJECT(area), "motion_notify_event",
- (GtkSignalFunc)EVENT_METHOD(ruler, motion_notify_event),
- GTK_OBJECT(ruler) );
+ g_signal_connect_swapped (G_OBJECT (area), "motion_notify_event",
+ G_CALLBACK (EVENT_METHOD (ruler, motion_notify_event)),
+ G_OBJECT (ruler));
</programlisting>
<para>The following example creates a drawing area with a horizontal ruler
vertical ruler spans from 0 to 400 with a mark every 100 pixels.
Placement of the drawing area and the rulers is done using a table.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/rulers.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start rulers rulers.c -->
#include <gtk/gtk.h>
-#define EVENT_METHOD(i, x) GTK_WIDGET_GET_CLASS(i)->x
+#define EVENT_METHOD(i, x) GTK_WIDGET_GET_CLASS(i)->x
#define XSIZE 600
#define YSIZE 400
GdkEvent *event,
gpointer data )
{
- gtk_main_quit();
+ gtk_main_quit ();
return FALSE;
}
GtkWidget *window, *table, *area, *hrule, *vrule;
/* Initialize GTK and create the main window */
- gtk_init( &argc, &argv );
+ gtk_init (&argc, &argv);
- window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC( close_application ), NULL);
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (close_application), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Create a table for placing the ruler and the drawing area */
- table = gtk_table_new( 3, 2, FALSE );
- gtk_container_add( GTK_CONTAINER(window), table );
+ table = gtk_table_new (3, 2, FALSE);
+ gtk_container_add (GTK_CONTAINER (window), table);
- area = gtk_drawing_area_new();
+ area = gtk_drawing_area_new ();
gtk_widget_set_size_request (GTK_WIDGET (area), XSIZE, YSIZE);
- gtk_table_attach( GTK_TABLE(table), area, 1, 2, 1, 2,
- GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0 );
- gtk_widget_set_events( area, GDK_POINTER_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK );
+ gtk_table_attach (GTK_TABLE (table), area, 1, 2, 1, 2,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_set_events (area, GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK);
/* The horizontal ruler goes on top. As the mouse moves across the
* drawing area, a motion_notify_event is passed to the
* appropriate event handler for the ruler. */
- hrule = gtk_hruler_new();
- gtk_ruler_set_metric( GTK_RULER(hrule), GTK_PIXELS );
- gtk_ruler_set_range( GTK_RULER(hrule), 7, 13, 0, 20 );
- g_signal_connect_swapped( GTK_OBJECT(area), "motion_notify_event",
- (GtkSignalFunc)EVENT_METHOD(hrule,
- motion_notify_event),
- GTK_OBJECT(hrule) );
- gtk_table_attach( GTK_TABLE(table), hrule, 1, 2, 0, 1,
- GTK_EXPAND|GTK_SHRINK|GTK_FILL, GTK_FILL, 0, 0 );
+ hrule = gtk_hruler_new ();
+ gtk_ruler_set_metric (GTK_RULER (hrule), GTK_PIXELS);
+ gtk_ruler_set_range (GTK_RULER (hrule), 7, 13, 0, 20);
+ g_signal_connect_swapped (G_OBJECT (area), "motion_notify_event",
+ G_CALLBACK (EVENT_METHOD (hrule, motion_notify_event)),
+ G_OBJECT (hrule));
+ gtk_table_attach (GTK_TABLE (table), hrule, 1, 2, 0, 1,
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, GTK_FILL, 0, 0);
/* The vertical ruler goes on the left. As the mouse moves across
* the drawing area, a motion_notify_event is passed to the
* appropriate event handler for the ruler. */
- vrule = gtk_vruler_new();
- gtk_ruler_set_metric( GTK_RULER(vrule), GTK_PIXELS );
- gtk_ruler_set_range( GTK_RULER(vrule), 0, YSIZE, 10, YSIZE );
- g_signal_connect_swapped( GTK_OBJECT(area), "motion_notify_event",
- (GtkSignalFunc)EVENT_METHOD(vrule,
- motion_notify_event),
- GTK_OBJECT(vrule) );
- gtk_table_attach( GTK_TABLE(table), vrule, 0, 1, 1, 2,
- GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0 );
+ vrule = gtk_vruler_new ();
+ gtk_ruler_set_metric (GTK_RULER (vrule), GTK_PIXELS);
+ gtk_ruler_set_range (GTK_RULER (vrule), 0, YSIZE, 10, YSIZE );
+ g_signal_connect_swapped (G_OBJECT (area), "motion_notify_event",
+ G_CALLBACK (EVENT_METHOD (vrule, motion_notify_event)),
+ G_OBJECT (vrule));
+ gtk_table_attach (GTK_TABLE (table), vrule, 0, 1, 1, 2,
+ GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0);
/* Now show everything */
- gtk_widget_show( area );
- gtk_widget_show( hrule );
- gtk_widget_show( vrule );
- gtk_widget_show( table );
- gtk_widget_show( window );
- gtk_main();
+ gtk_widget_show (area);
+ gtk_widget_show (hrule);
+ gtk_widget_show (vrule);
+ gtk_widget_show (table);
+ gtk_widget_show (window);
+ gtk_main ();
return 0;
}
<programlisting role="C">
guint gtk_statusbar_push( GtkStatusbar *statusbar,
guint context_id,
- gchar *text );
+ const gchar *text );
void gtk_statusbar_pop( GtkStatusbar *statusbar)
guint context_id );
guint message_id );
</programlisting>
-<para>The first, gtk_statusbar_push, is used to add a new message to the
+<para>The first, gtk_statusbar_push(), is used to add a new message to the
statusbar. It returns a Message Identifier, which can be passed later
to the function gtk_statusbar_remove to remove the message with the
given Message and Context Identifiers from the statusbar's stack.</para>
-<para>The function gtk_statusbar_pop removes the message highest in the
+<para>The function gtk_statusbar_pop() removes the message highest in the
stack with the given Context Identifier.</para>
+<para>In addition to messages, statusbars may also display a resize grip, which
+can be dragged with the mouse to resize the toplevel window containing the statusbar,
+similar to dragging the window frame. The following functions control the display
+of the resize grip.</para>
+
+<programlisting role="C">
+void gtk_statusbar_set_has_resize_grip( GtkStatusbar *statusbar,
+ gboolean setting );
+
+gboolean gtk_statusbar_get_has_resize_grip( GtkStatusbar *statusbar );
+</programlisting>
+
<para>The following example creates a statusbar and two buttons, one for
pushing items onto the statusbar, and one for popping the last item
back off.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/statusbar.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start statusbar statusbar.c -->
static int count = 1;
char buff[20];
- g_snprintf(buff, 20, "Item %d", count++);
- gtk_statusbar_push( GTK_STATUSBAR(status_bar), GPOINTER_TO_INT(data), buff);
+ g_snprintf (buff, 20, "Item %d", count++);
+ gtk_statusbar_push (GTK_STATUSBAR (status_bar), GPOINTER_TO_INT (data), buff);
return;
}
void pop_item( GtkWidget *widget,
gpointer data )
{
- gtk_statusbar_pop( GTK_STATUSBAR(status_bar), GPOINTER_TO_INT(data) );
+ gtk_statusbar_pop (GTK_STATUSBAR (status_bar), GPOINTER_TO_INT (data));
return;
}
gtk_init (&argc, &argv);
/* create a new window */
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (GTK_WIDGET (window), 200, 100);
- gtk_window_set_title(GTK_WINDOW (window), "GTK Statusbar Example");
- g_signal_connect(GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (exit), NULL);
+ gtk_window_set_title (GTK_WINDOW (window), "GTK Statusbar Example");
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (exit), NULL);
- vbox = gtk_vbox_new(FALSE, 1);
- gtk_container_add(GTK_CONTAINER(window), vbox);
- gtk_widget_show(vbox);
+ vbox = gtk_vbox_new (FALSE, 1);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+ gtk_widget_show (vbox);
- status_bar = gtk_statusbar_new();
+ status_bar = gtk_statusbar_new ();
gtk_box_pack_start (GTK_BOX (vbox), status_bar, TRUE, TRUE, 0);
gtk_widget_show (status_bar);
context_id = gtk_statusbar_get_context_id(
- GTK_STATUSBAR(status_bar), "Statusbar example");
+ GTK_STATUSBAR (status_bar), "Statusbar example");
+
+ button = gtk_button_new_with_label ("push item");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (push_item), GINT_TO_POINTER (context_id));
+ gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 2);
+ gtk_widget_show (button);
+
+ button = gtk_button_new_with_label ("pop last item");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (pop_item), GINT_TO_POINTER (context_id));
+ gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 2);
+ gtk_widget_show (button);
- button = gtk_button_new_with_label("push item");
- g_signal_connect(GTK_OBJECT(button), "clicked",
- GTK_SIGNAL_FUNC (push_item), GINT_TO_POINTER(context_id) );
- gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 2);
- gtk_widget_show(button);
+ /* always display the window as the last step so it all splashes on
+ * the screen at once. */
+ gtk_widget_show (window);
- button = gtk_button_new_with_label("pop last item");
- g_signal_connect(GTK_OBJECT(button), "clicked",
- GTK_SIGNAL_FUNC (pop_item), GINT_TO_POINTER(context_id) );
- gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 2);
- gtk_widget_show(button);
+ gtk_main ();
- /* always display the window as the last step so it all splashes on
+ return 0;
+}
<!-- example-end -->
</programlisting>
text box. The text may be set with function calls that allow new text
to replace, prepend or append the current contents of the Entry widget.</para>
-<para>There are two functions for creating Entry widgets:</para>
+<para>Create a new Entry widget with the following function.</para>
<programlisting role="C">
GtkWidget *gtk_entry_new( void );
-
-GtkWidget *gtk_entry_new_with_max_length( guint16 max );
</programlisting>
-<para>The first just creates a new Entry widget, whilst the second creates a
-new Entry and sets a limit on the length of the text within the Entry.</para>
-
-<para>There are several functions for altering the text which is currently
+<para>The next function alters the text which is currently
within the Entry widget.</para>
<programlisting role="C">
void gtk_entry_set_text( GtkEntry *entry,
const gchar *text );
-
-void gtk_entry_append_text( GtkEntry *entry,
- const gchar *text );
-
-void gtk_entry_prepend_text( GtkEntry *entry,
- const gchar *text );
</programlisting>
-<para>The function gtk_entry_set_text sets the contents of the Entry widget,
-replacing the current contents. The functions gtk_entry_append_text
-and gtk_entry_prepend_text allow the current contents to be appended
-and prepended to.</para>
-
-<para>The next function allows the current insertion point to be set.</para>
-
-<programlisting role="C">
-void gtk_entry_set_position( GtkEntry *entry,
- gint position );
-</programlisting>
+<para>The function gtk_entry_set_text() sets the contents of the Entry widget,
+replacing the current contents. Note that the class Entry implements the Editable
+interface (yes, gobject supports Java-like interfaces) which contains some more
+functions for manipulating the contents.
+ </para>
<para>The contents of the Entry can be retrieved by using a call to the
following function. This is useful in the callback functions described below.</para>
<programlisting role="C">
-gchar *gtk_entry_get_text( GtkEntry *entry );
+const gchar *gtk_entry_get_text( GtkEntry *entry );
</programlisting>
<para>The value returned by this function is used internally, and must not
-be freed using either free() or g_free()</para>
+be freed using either free() or g_free().</para>
<para>If we don't want the contents of the Entry to be changed by someone typing
into it, we can change its editable state.</para>
<programlisting role="C">
-void gtk_entry_set_editable( GtkEntry *entry,
- gboolean editable );
+void gtk_editable_set_editable( GtkEditable *entry,
+ gboolean editable );
</programlisting>
<para>The function above allows us to toggle the editable state of the
text in an Entry, making it easy for the user to remove it.</para>
<programlisting role="C">
-void gtk_entry_select_region( GtkEntry *entry,
- gint start,
- gint end );
+void gtk_editable_select_region( GtkEditable *entry,
+ gint start,
+ gint end );
</programlisting>
<para>If we want to catch when the user has entered text, we can connect to
<para>The following code is an example of using an Entry widget.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/entry.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start entry entry.c -->
GtkWidget *entry )
{
const gchar *entry_text;
- entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
+ entry_text = gtk_entry_get_text (GTK_ENTRY (entry));
printf("Entry contents: %s\n", entry_text);
}
GtkWidget *entry )
{
gtk_editable_set_editable (GTK_EDITABLE (entry),
- GTK_TOGGLE_BUTTON (checkbutton)->active);
+ GTK_TOGGLE_BUTTON (checkbutton)->active);
}
void entry_toggle_visibility( GtkWidget *checkbutton,
GtkWidget *entry )
{
- gtk_entry_set_visibility(GTK_ENTRY(entry),
- GTK_TOGGLE_BUTTON(checkbutton)->active);
+ gtk_entry_set_visibility (GTK_ENTRY (entry),
+ GTK_TOGGLE_BUTTON (checkbutton)->active);
}
int main( int argc,
gtk_init (&argc, &argv);
/* create a new window */
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (GTK_WIDGET (window), 200, 100);
- gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
- g_signal_connect(GTK_OBJECT (window), "delete_event",
- (GtkSignalFunc) exit, NULL);
+ gtk_window_set_title (GTK_WINDOW (window), "GTK Entry");
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect_swapped (G_OBJECT (window), "delete_event",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
entry = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (entry), 50);
- g_signal_connect(GTK_OBJECT(entry), "activate",
- GTK_SIGNAL_FUNC(enter_callback),
- entry);
+ g_signal_connect (G_OBJECT (entry), "activate",
+ G_CALLBACK (enter_callback),
+ (gpointer) entry);
gtk_entry_set_text (GTK_ENTRY (entry), "hello");
- tmp_pos = GTK_ENTRY (entry)->text_length;
+ tmp_pos = GTK_ENTRY (entry)->text_length;
gtk_editable_insert_text (GTK_EDITABLE (entry), " world", -1, &tmp_pos);
gtk_editable_select_region (GTK_EDITABLE (entry),
- 0, GTK_ENTRY(entry)->text_length);
+ 0, GTK_ENTRY (entry)->text_length);
gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
gtk_widget_show (entry);
gtk_container_add (GTK_CONTAINER (vbox), hbox);
gtk_widget_show (hbox);
- check = gtk_check_button_new_with_label("Editable");
+ check = gtk_check_button_new_with_label ("Editable");
gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
- g_signal_connect (GTK_OBJECT(check), "toggled",
- GTK_SIGNAL_FUNC(entry_toggle_editable), entry);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
+ g_signal_connect (G_OBJECT (check), "toggled",
+ G_CALLBACK (entry_toggle_editable), (gpointer) entry);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
gtk_widget_show (check);
- check = gtk_check_button_new_with_label("Visible");
+ check = gtk_check_button_new_with_label ("Visible");
gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
- g_signal_connect (GTK_OBJECT(check), "toggled",
- GTK_SIGNAL_FUNC(entry_toggle_visibility), entry);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
+ g_signal_connect (G_OBJECT (check), "toggled",
+ G_CALLBACK (entry_toggle_visibility), (gpointer) entry);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
gtk_widget_show (check);
- button = gtk_button_new_with_label ("Close");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC(exit),
- GTK_OBJECT (window));
+ button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
- gtk_widget_show(window);
+ gtk_widget_show (window);
gtk_main();
+
return 0;
}
<!-- example-end -->
function, which illustrates the information that it holds:</para>
<programlisting role="C">
-GtkObject *gtk_adjustment_new( gfloat value,
- gfloat lower,
- gfloat upper,
- gfloat step_increment,
- gfloat page_increment,
- gfloat page_size );
+GtkObject *gtk_adjustment_new( gdouble value,
+ gdouble lower,
+ gdouble upper,
+ gdouble step_increment,
+ gdouble page_increment,
+ gdouble page_size );
</programlisting>
<para>These attributes of an Adjustment are used by the Spin Button in the
<programlisting role="C">
GtkWidget *gtk_spin_button_new( GtkAdjustment *adjustment,
- gfloat climb_rate,
+ gdouble climb_rate,
guint digits );
</programlisting>
<programlisting role="C">
void gtk_spin_button_configure( GtkSpinButton *spin_button,
GtkAdjustment *adjustment,
- gfloat climb_rate,
+ gdouble climb_rate,
guint digits );
</programlisting>
<programlisting role="C">
void gtk_spin_button_set_value( GtkSpinButton *spin_button,
- gfloat value );
+ gdouble value );
</programlisting>
<para>The current value of a Spin Button can be retrieved as either a
floating point or integer value with the following functions:</para>
<programlisting role="C">
-gfloat gtk_spin_button_get_value_as_float( GtkSpinButton *spin_button );
+gdouble gtk_spin_button_get_value ( GtkSpinButton *spin_button );
gint gtk_spin_button_get_value_as_int( GtkSpinButton *spin_button );
</programlisting>
-<para>If you want to alter the value of a Spin Value relative to its current
+<para>If you want to alter the value of a Spin Button relative to its current
value, then the following function can be used:</para>
<programlisting role="C">
void gtk_spin_button_spin( GtkSpinButton *spin_button,
GtkSpinType direction,
- gfloat increment );
+ gdouble increment );
</programlisting>
<para>The <literal>direction</literal> parameter can take one of the following values:</para>
GtkSpinButtonUpdatePolicy policy );
</programlisting>
-<para><!-- TODO: find out what this does - TRG --></para>
-
<para>The possible values of <literal>policy</literal> are either <literal>GTK_UPDATE_ALWAYS</literal> or
<literal>GTK_UPDATE_IF_VALID</literal>.</para>
<para>In case of <literal>GTK_UPDATE_ALWAYS</literal> we ignore errors while converting
text into a numeric value.</para>
-<para>The appearance of the buttons used in a Spin Button can be changed
-using the following function:</para>
-
-<programlisting role="C">
-void gtk_spin_button_set_shadow_type( GtkSpinButton *spin_button,
- GtkShadowType shadow_type );
-</programlisting>
-
-<para>As usual, the <literal>shadow_type</literal> can be one of:</para>
-
-<programlisting role="C">
- GTK_SHADOW_IN
- GTK_SHADOW_OUT
- GTK_SHADOW_ETCHED_IN
- GTK_SHADOW_ETCHED_OUT
-</programlisting>
-
<para>Finally, you can explicitly request that a Spin Button update itself:</para>
<programlisting role="C">
<para>It's example time again.</para>
-<programlisting role="C">
-<!-- example-start spinbutton spinbutton.c -->
-
-#include <stdio.h>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/spinbutton.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
+<programlisting role="C">
+<!-- example-start spinbutton spinbutton.c -->
+
+#include <stdio.h>
#include <gtk/gtk.h>
static GtkWidget *spinner1;
void toggle_snap( GtkWidget *widget,
GtkSpinButton *spin )
{
- gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
+ gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
}
void toggle_numeric( GtkWidget *widget,
GtkSpinButton *spin )
{
- gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
+ gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
}
void change_digits( GtkWidget *widget,
if (GPOINTER_TO_INT (data) == 1)
sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
else
- sprintf (buf, "%0.*f", spin->digits,
+ sprintf (buf, "%0.*f", spin->digits,
gtk_spin_button_get_value (spin));
gtk_label_set_text (label, buf);
}
GtkAdjustment *adj;
/* Initialise GTK */
- gtk_init(&argc, &argv);
+ gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_main_quit),
- NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
gtk_window_set_title (GTK_WINDOW (window), "Spin Button");
adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 5, 1, 1, 0);
spinner2 = gtk_spin_button_new (adj, 0.0, 0);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner2), TRUE);
- g_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (change_digits),
- (gpointer) spinner2);
+ g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (change_digits),
+ (gpointer) spinner2);
gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (toggle_snap),
- spinner1);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (toggle_snap),
+ (gpointer) spinner1);
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
button = gtk_check_button_new_with_label ("Numeric only input mode");
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (toggle_numeric),
- spinner1);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (toggle_numeric),
+ (gpointer) spinner1);
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
button = gtk_button_new_with_label ("Value as Int");
g_object_set_data (G_OBJECT (button), "user_data", val_label);
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (get_value),
- GINT_TO_POINTER (1));
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (get_value),
+ GINT_TO_POINTER (1));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
button = gtk_button_new_with_label ("Value as Float");
g_object_set_data (G_OBJECT (button), "user_data", val_label);
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (get_value),
- GINT_TO_POINTER (2));
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (get_value),
+ GINT_TO_POINTER (2));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
button = gtk_button_new_with_label ("Close");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
gtk_widget_show_all (window);
return 0;
}
+
<!-- example-end -->
</programlisting>
box, this is done by manipulating the <literal>entry</literal> widget directly:</para>
<programlisting role="C">
- gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), "My String.");
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo)->entry), "My String.");
</programlisting>
<para>To set the values in the popdown list, one uses the function:</para>
<para>Before you can do this, you have to assemble a GList of the strings
that you want. GList is a linked list implementation that is part of
-<link linkend="ch-GLib">GLib</link>, a library supporing GTK. For the
+<link linkend="ch-GLib">GLib</link>, a library supporting GTK. For the
moment, the quick and dirty explanation is that you need to set up a
GList pointer, set it equal to NULL, then append strings to it with</para>
</programlisting>
<para>It is important that you set the initial GList pointer to NULL. The
-value returned from the g_list_append function must be used as the new
+value returned from the g_list_append() function must be used as the new
pointer to the GList.</para>
<para>Here's a typical code segment for creating a set of options:</para>
<programlisting role="C">
- GList *glist=NULL;
+ GList *glist = NULL;
- glist = g_list_append(glist, "String 1");
- glist = g_list_append(glist, "String 2");
- glist = g_list_append(glist, "String 3");
- glist = g_list_append(glist, "String 4");
+ glist = g_list_append (glist, "String 1");
+ glist = g_list_append (glist, "String 2");
+ glist = g_list_append (glist, "String 3");
+ glist = g_list_append (glist, "String 4");
- gtk_combo_set_popdown_strings( GTK_COMBO(combo), glist) ;
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), glist);
/* can free glist now, combo takes a copy */
</programlisting>
<programlisting role="C">
void gtk_combo_set_use_arrows( GtkCombo *combo,
- gint val );
+ gboolean val );
void gtk_combo_set_use_arrows_always( GtkCombo *combo,
- gint val );
+ gboolean val );
void gtk_combo_set_case_sensitive( GtkCombo *combo,
- gint val );
+ gboolean val );
</programlisting>
-<para><literal>gtk_combo_set_use_arrows()</literal> lets the user change the value in the
+<para>gtk_combo_set_use_arrows() lets the user change the value in the
entry using the up/down arrow keys. This doesn't bring up the list, but
rather replaces the current text in the entry with the next list entry
(up or down, as your key choice indicates). It does this by searching
the first item and arrow-up).</para>
<para>If the current value in the entry is not in the list, then the
-function of <literal>gtk_combo_set_use_arrows()</literal> is disabled.</para>
+function of gtk_combo_set_use_arrows() is disabled.</para>
-<para><literal>gtk_combo_set_use_arrows_always()</literal> similarly allows the use the
+<para>gtk_combo_set_use_arrows_always() similarly allows the use the
the up/down arrow keys to cycle through the choices in the dropdown
list, except that it wraps around the values in the list, completely
disabling the use of the up and down arrow keys for changing focus.</para>
-<para><literal>gtk_combo_set_case_sensitive()</literal> toggles whether or not GTK
+<para>gtk_combo_set_case_sensitive() toggles whether or not GTK
searches for entries in a case sensitive manner. This is used when the
Combo widget is asked to find a value from the list using the current
entry in the text box. This completion can be performed in either a
all that remains is being able to get data from the combo box. This is
relatively straightforward. The majority of the time, all you are
going to care about getting data from is the entry. The entry is
-accessed simply by <literal>GTK_ENTRY(GTK_COMBO(combo)->entry)</literal>. The
+accessed simply by <literal>GTK_ENTRY (GTK_COMBO (combo)->entry)</literal>. The
two principal things that you are going to want to do with it are
-attach to the activate signal, which indicates that the user has
+connect to the activate signal, which indicates that the user has
pressed the Return or Enter key, and read the text. The first is
accomplished using something like:</para>
<programlisting role="C">
- gtk_signal_connect(GTK_OBJECT(GTK_COMB(combo)->entry), "activate",
- GTK_SIGNAL_FUNC (my_callback_function), my_data);
+ g_signal_connect (G_OBJECT (GTK_COMBO (combo)->entry), "activate",
+ G_CALLBACK (my_callback_function), (gpointer) my_data);
</programlisting>
<para>Getting the text at any arbitrary time is accomplished by simply using
the entry function:</para>
<programlisting role="C">
-gchar *gtk_entry_get_text(GtkEntry *entry);
+gchar *gtk_entry_get_text( GtkEntry *entry );
</programlisting>
<para>Such as:</para>
<programlisting role="C">
- char *string;
+ gchar *string;
- string = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
+ string = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (combo)->entry));
</programlisting>
<para>That's about all there is to it. There is a function</para>
<programlisting role="C">
-void gtk_combo_disable_activate(GtkCombo *combo);
+void gtk_combo_disable_activate( GtkCombo *combo );
</programlisting>
<para>that will disable the activate signal on the entry widget in the combo
<para>Creating a GtkCalendar widget is a simple as: </para>
<programlisting role="C">
-GtkWidget *gtk_calendar_new();
+GtkWidget *gtk_calendar_new( void );
</programlisting>
<para>There might be times where you need to change a lot of information
<programlisting role="C">
void gtk_calendar_freeze( GtkCalendar *Calendar );
-void gtk_calendar_thaw ( GtkCalendar *Calendar );
+void gtk_calendar_thaw( GtkCalendar *Calendar );
</programlisting>
<para>They work just like the freeze/thaw functions of every other
<para>The <literal>flags</literal> argument can be formed by combining either of the
following five options using the logical bitwise OR (|) operation:</para>
-<itemizedlist>
-<listitem><simpara> GTK_CALENDAR_SHOW_HEADING - this option specifies that
-the month and year should be shown when drawing the calendar.</simpara>
-</listitem>
-
-<listitem><simpara> GTK_CALENDAR_SHOW_DAY_NAMES - this option specifies that the
-three letter descriptions should be displayed for each day (eg
-Mon,Tue, etc.).</simpara>
-</listitem>
-
-<listitem><simpara> GTK_CALENDAR_NO_MONTH_CHANGE - this option states that the user
+<variablelist>
+<varlistentry>
+<term><literal>GTK_CALENDAR_SHOW_HEADING</literal></term>
+<listitem><para>this option specifies that the month and year should be shown
+when drawing the calendar.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_CALENDAR_SHOW_DAY_NAMES</literal></term>
+<listitem><para>this option specifies that the three letter descriptions should
+be displayed for each day (eg Mon,Tue, etc.).</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_CALENDAR_NO_MONTH_CHANGE</literal></term>
+<listitem><para>this option states that the user
should not and can not change the currently displayed month. This can
be good if you only need to display a particular month such as if you
are displaying 12 calendar widgets for every month in a particular
-year.</simpara>
+year.</para>
</listitem>
-
-<listitem><simpara> GTK_CALENDAR_SHOW_WEEK_NUMBERS - this option specifies that the
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_CALENDAR_SHOW_WEEK_NUMBERS</literal></term>
+<listitem><para>this option specifies that the
number for each week should be displayed down the left side of the
-calendar. (eg. Jan 1 = Week 1,Dec 31 = Week 52).</simpara>
+calendar. (eg. Jan 1 = Week 1,Dec 31 = Week 52).</para>
</listitem>
-
-<listitem><simpara> GTK_CALENDAR_WEEK_START_MONDAY - this option states that the
+</varlistentry>
+<varlistentry>
+<term><literal>GTK_CALENDAR_WEEK_START_MONDAY</literal></term>
+<listitem><para>this option states that the
calander week will start on Monday instead of Sunday which is the
default. This only affects the order in which days are displayed from
-left to right.</simpara>
+left to right.</para>
</listitem>
-</itemizedlist>
+</varlistentry>
+</variablelist>
<para>The following functions are used to set the the currently displayed
date:</para>
<programlisting role="C">
GtkCalendar *calendar;
- calendar = gtk_calendar_new();
+ calendar = gtk_calendar_new ();
...
<para>That just leaves us with the need to put all of this together into
example code.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/calendar.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start calendar calendar.c -->
/*
time_t time;
memset (&tm, 0, sizeof (tm));
- gtk_calendar_get_date (GTK_CALENDAR(data->window),
+ gtk_calendar_get_date (GTK_CALENDAR (data->window),
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
tm.tm_year -= TM_YEAR_BASE;
- time = mktime(&tm);
- strftime (buffer, buff_len-1, "%x", gmtime(&time));
+ time = mktime (&tm);
+ strftime (buffer, buff_len-1, "%x", gmtime (&time));
}
void calendar_set_signal_strings( char *sig_str,
{
const gchar *prev_sig;
- prev_sig = gtk_label_get_text (GTK_LABEL (data->prev_sig));
- gtk_label_set_text (GTK_LABEL (data->prev2_sig), prev_sig);
+ prev_sig = gtk_label_get_text (GTK_LABEL (data->prev_sig));
+ gtk_label_set_text (GTK_LABEL (data->prev2_sig), prev_sig);
- prev_sig = gtk_label_get_text (GTK_LABEL (data->last_sig));
- gtk_label_set_text (GTK_LABEL (data->prev_sig), prev_sig);
- gtk_label_set_text (GTK_LABEL (data->last_sig), sig_str);
+ prev_sig = gtk_label_get_text (GTK_LABEL (data->last_sig));
+ gtk_label_set_text (GTK_LABEL (data->prev_sig), prev_sig);
+ gtk_label_set_text (GTK_LABEL (data->last_sig), sig_str);
}
void calendar_month_changed( GtkWidget *widget,
calendar_set_signal_strings (buffer, data);
memset (&tm, 0, sizeof (tm));
- gtk_calendar_get_date (GTK_CALENDAR(data->window),
+ gtk_calendar_get_date (GTK_CALENDAR (data->window),
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
tm.tm_year -= TM_YEAR_BASE;
- if(GTK_CALENDAR(data->window)->marked_date[tm.tm_mday-1] == 0) {
- gtk_calendar_mark_day(GTK_CALENDAR(data->window),tm.tm_mday);
- } else {
- gtk_calendar_unmark_day(GTK_CALENDAR(data->window),tm.tm_mday);
- }
+ if (GTK_CALENDAR (data->window)->marked_date[tm.tm_mday-1] == 0)
+ {
+ gtk_calendar_mark_day (GTK_CALENDAR (data->window), tm.tm_mday);
+ }
+ else
+ {
+ gtk_calendar_unmark_day (GTK_CALENDAR (data->window), tm.tm_mday);
+ }
}
void calendar_prev_month( GtkWidget *widget,
void calendar_set_flags( CalendarData *calendar )
{
gint i;
- gint options=0;
- for (i=0;i<5;i++)
+ gint options = 0;
+ for (i = 0; i < 5; i++)
if (calendar->settings[i])
{
options=options + (1<<i);
}
if (calendar->window)
- gtk_calendar_display_options (GTK_CALENDAR (calendar->window), options);
+ gtk_calendar_display_options (GTK_CALENDAR (calendar->window), options);
}
void calendar_toggle_flag( GtkWidget *toggle,
{
gint i;
gint j;
- j=0;
- for (i=0; i<5; i++)
- if (calendar->flag_checkboxes[i] == toggle)
+ j = 0;
+ for (i = 0; i < 5; i++)
+ if (calendar->flag_checkboxes[i] == toggle)
j = i;
- calendar->settings[j]=!calendar->settings[j];
- calendar_set_flags(calendar);
+ calendar->settings[j] = !calendar->settings[j];
+ calendar_set_flags (calendar);
}
GtkStyle *style;
PangoFontDescription *font_desc;
- calendar->font = gtk_font_selection_dialog_get_font_name(
- GTK_FONT_SELECTION_DIALOG (calendar->font_dialog));
- if (calendar->window)
+ calendar->font = gtk_font_selection_dialog_get_font_name (
+ GTK_FONT_SELECTION_DIALOG (calendar->font_dialog));
+ if (calendar->window)
{
- font_desc = pango_font_description_from_string (calendar->font);
+ font_desc = pango_font_description_from_string (calendar->font);
if (font_desc)
{
- style = gtk_style_copy (gtk_widget_get_style (calendar->window));
- style->font_desc = font_desc;
- gtk_widget_set_style (calendar->window, style);
+ style = gtk_style_copy (gtk_widget_get_style (calendar->window));
+ style->font_desc = font_desc;
+ gtk_widget_set_style (calendar->window, style);
}
}
}
{
GtkWidget *window;
- if (!calendar->font_dialog) {
+ if (!calendar->font_dialog) {
window = gtk_font_selection_dialog_new ("Font Selection Dialog");
- g_return_if_fail(GTK_IS_FONT_SELECTION_DIALOG(window));
- calendar->font_dialog = window;
+ g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (window));
+ calendar->font_dialog = window;
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_widget_destroyed),
- &calendar->font_dialog);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ (gpointer) &calendar->font_dialog);
- g_signal_connect (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->ok_button),
- "clicked", GTK_SIGNAL_FUNC(calendar_font_selection_ok),
- calendar);
- g_signal_connect_swapped (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->cancel_button),
+ g_signal_connect (G_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->ok_button),
+ "clicked", G_CALLBACK (calendar_font_selection_ok),
+ (gpointer) calendar);
+ g_signal_connect_swapped (G_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->cancel_button),
"clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT (calendar->font_dialog));
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (calendar->font_dialog));
}
- window=calendar->font_dialog;
+ window=calendar->font_dialog;
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show (window);
else
calendar_data.font = NULL;
calendar_data.font_dialog = NULL;
- for (i=0; i<5; i++) {
- calendar_data.settings[i]=0;
+ for (i = 0; i < 5; i++) {
+ calendar_data.settings[i] = 0;
}
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "GtkCalendar Example");
+ gtk_window_set_title (GTK_WINDOW (window), "GtkCalendar Example");
gtk_container_set_border_width (GTK_CONTAINER (window), 5);
- g_signal_connect(GTK_OBJECT(window), "destroy",
- GTK_SIGNAL_FUNC(gtk_main_quit),
- NULL);
- g_signal_connect(GTK_OBJECT(window), "delete-event",
- GTK_SIGNAL_FUNC(gtk_false),
- NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
+ g_signal_connect (G_OBJECT (window), "delete-event",
+ G_CALLBACK (gtk_false),
+ NULL);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
- vbox = gtk_vbox_new(FALSE, DEF_PAD);
+ vbox = gtk_vbox_new (FALSE, DEF_PAD);
gtk_container_add (GTK_CONTAINER (window), vbox);
/*
* The top part of the window, Calendar, flags and fontsel.
*/
- hbox = gtk_hbox_new(FALSE, DEF_PAD);
- gtk_box_pack_start (GTK_BOX(vbox), hbox, TRUE, TRUE, DEF_PAD);
- hbbox = gtk_hbutton_box_new();
- gtk_box_pack_start(GTK_BOX(hbox), hbbox, FALSE, FALSE, DEF_PAD);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox), GTK_BUTTONBOX_SPREAD);
+ hbox = gtk_hbox_new (FALSE, DEF_PAD);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, DEF_PAD);
+ hbbox = gtk_hbutton_box_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), hbbox, FALSE, FALSE, DEF_PAD);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX(hbbox), GTK_BUTTONBOX_SPREAD);
gtk_box_set_spacing (GTK_BOX (hbbox), 5);
/* Calendar widget */
- frame = gtk_frame_new("Calendar");
- gtk_box_pack_start(GTK_BOX(hbbox), frame, FALSE, TRUE, DEF_PAD);
- calendar=gtk_calendar_new();
+ frame = gtk_frame_new ("Calendar");
+ gtk_box_pack_start (GTK_BOX (hbbox), frame, FALSE, TRUE, DEF_PAD);
+ calendar=gtk_calendar_new ();
calendar_data.window = calendar;
- calendar_set_flags(&calendar_data);
- gtk_calendar_mark_day ( GTK_CALENDAR(calendar), 19);
- gtk_container_add( GTK_CONTAINER( frame), calendar);
- g_signal_connect (GTK_OBJECT (calendar), "month_changed",
- GTK_SIGNAL_FUNC (calendar_month_changed),
- &calendar_data);
- g_signal_connect (GTK_OBJECT (calendar), "day_selected",
- GTK_SIGNAL_FUNC (calendar_day_selected),
- &calendar_data);
- g_signal_connect (GTK_OBJECT (calendar), "day_selected_double_click",
- GTK_SIGNAL_FUNC (calendar_day_selected_double_click),
- &calendar_data);
- g_signal_connect (GTK_OBJECT (calendar), "prev_month",
- GTK_SIGNAL_FUNC (calendar_prev_month),
- &calendar_data);
- g_signal_connect (GTK_OBJECT (calendar), "next_month",
- GTK_SIGNAL_FUNC (calendar_next_month),
- &calendar_data);
- g_signal_connect (GTK_OBJECT (calendar), "prev_year",
- GTK_SIGNAL_FUNC (calendar_prev_year),
- &calendar_data);
- g_signal_connect (GTK_OBJECT (calendar), "next_year",
- GTK_SIGNAL_FUNC (calendar_next_year),
- &calendar_data);
+ calendar_set_flags (&calendar_data);
+ gtk_calendar_mark_day (GTK_CALENDAR (calendar), 19);
+ gtk_container_add( GTK_CONTAINER (frame), calendar);
+ g_signal_connect (G_OBJECT (calendar), "month_changed",
+ G_CALLBACK (calendar_month_changed),
+ (gpointer) &calendar_data);
+ g_signal_connect (G_OBJECT (calendar), "day_selected",
+ G_CALLBACK (calendar_day_selected),
+ (gpointer) &calendar_data);
+ g_signal_connect (G_OBJECT (calendar), "day_selected_double_click",
+ G_CALLBACK (calendar_day_selected_double_click),
+ (gpointer) &calendar_data);
+ g_signal_connect (G_OBJECT (calendar), "prev_month",
+ G_CALLBACK (calendar_prev_month),
+ (gpointer) &calendar_data);
+ g_signal_connect (G_OBJECT (calendar), "next_month",
+ G_CALLBACK (calendar_next_month),
+ (gpointer) &calendar_data);
+ g_signal_connect (G_OBJECT (calendar), "prev_year",
+ G_CALLBACK (calendar_prev_year),
+ (gpointer) &calendar_data);
+ g_signal_connect (G_OBJECT (calendar), "next_year",
+ G_CALLBACK (calendar_next_year),
+ (gpointer) &calendar_data);
separator = gtk_vseparator_new ();
gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 0);
- vbox2 = gtk_vbox_new(FALSE, DEF_PAD);
- gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, DEF_PAD);
+ vbox2 = gtk_vbox_new (FALSE, DEF_PAD);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, DEF_PAD);
/* Build the Right frame with the flags in */
- frame = gtk_frame_new("Flags");
- gtk_box_pack_start(GTK_BOX(vbox2), frame, TRUE, TRUE, DEF_PAD);
- vbox3 = gtk_vbox_new(TRUE, DEF_PAD_SMALL);
- gtk_container_add(GTK_CONTAINER(frame), vbox3);
+ frame = gtk_frame_new ("Flags");
+ gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, DEF_PAD);
+ vbox3 = gtk_vbox_new (TRUE, DEF_PAD_SMALL);
+ gtk_container_add (GTK_CONTAINER (frame), vbox3);
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 5; i++)
{
- toggle = gtk_check_button_new_with_label(flags[i].label);
- g_signal_connect (GTK_OBJECT (toggle),
- "toggled",
- GTK_SIGNAL_FUNC(calendar_toggle_flag),
- &calendar_data);
+ toggle = gtk_check_button_new_with_label (flags[i].label);
+ g_signal_connect (G_OBJECT (toggle),
+ "toggled",
+ G_CALLBACK (calendar_toggle_flag),
+ (gpointer) &calendar_data);
gtk_box_pack_start (GTK_BOX (vbox3), toggle, TRUE, TRUE, 0);
- calendar_data.flag_checkboxes[i]=toggle;
+ calendar_data.flag_checkboxes[i] = toggle;
}
/* Build the right font-button */
- button = gtk_button_new_with_label("Font...");
- g_signal_connect (GTK_OBJECT (button),
- "clicked",
- GTK_SIGNAL_FUNC(calendar_select_font),
- &calendar_data);
+ button = gtk_button_new_with_label ("Font...");
+ g_signal_connect (G_OBJECT (button),
+ "clicked",
+ G_CALLBACK (calendar_select_font),
+ (gpointer) &calendar_data);
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
/*
* Build the Signal-event part.
*/
- frame = gtk_frame_new("Signal events");
- gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, DEF_PAD);
+ frame = gtk_frame_new ("Signal events");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, DEF_PAD);
- vbox2 = gtk_vbox_new(TRUE, DEF_PAD_SMALL);
- gtk_container_add(GTK_CONTAINER(frame), vbox2);
+ vbox2 = gtk_vbox_new (TRUE, DEF_PAD_SMALL);
+ gtk_container_add (GTK_CONTAINER (frame), vbox2);
hbox = gtk_hbox_new (FALSE, 3);
gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 0);
bbox = gtk_hbutton_box_new ();
gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
button = gtk_button_new_with_label ("Close");
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_main_quit),
- NULL);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
gtk_container_add (GTK_CONTAINER (bbox), button);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
- gtk_widget_show_all(window);
+ gtk_widget_show_all (window);
}
{
gtk_init (&argc, &argv);
- create_calendar();
+ create_calendar ();
- gtk_main();
+ gtk_main ();
return 0;
}
explicitly through gtk_color_selection_set_color().</para>
<para>Lets have a look at what the color selection widget has to offer
-us. The widget comes in two flavours: gtk_color_selection and
-gtk_color_selection_dialog.</para>
+us. The widget comes in two flavours: GtkColorSelection and
+GtkColorSelectionDialog.</para>
<programlisting role="C">
GtkWidget *gtk_color_selection_new( void );
"Ok", "Cancel" and "Help". You can reach these buttons by accessing
the "ok_button", "cancel_button" and "help_button" widgets in the
ColorSelectionDialog structure,
-(i.e., <literal>GTK_COLOR_SELECTION_DIALOG(colorseldialog)->ok_button</literal>)).</para>
-
-<programlisting role="C">
-void gtk_color_selection_set_update_policy( GtkColorSelection *colorsel,
- GtkUpdateType policy );
-</programlisting>
-
-<para>This function sets the update policy. The default policy is
-<literal>GTK_UPDATE_CONTINUOUS</literal> which means that the current color is
-updated continuously when the user drags the sliders or presses the
-mouse and drags in the hue-saturation wheel or value bar. If you
-experience performance problems, you may want to set the policy to
-<literal>GTK_UPDATE_DISCONTINUOUS</literal> or <literal>GTK_UPDATE_DELAYED</literal>.</para>
+(i.e., <literal>GTK_COLOR_SELECTION_DIALOG (colorseldialog)->ok_button</literal>)).</para>
<programlisting role="C">
-void gtk_color_selection_set_opacity( GtkColorSelection *colorsel,
- gint use_opacity );
+void gtk_color_selection_set_has_opacity_control( GtkColorSelection *colorsel,
+ gboolean has_opacity );
</programlisting>
<para>The color selection widget supports adjusting the opacity of a color
(also known as the alpha channel). This is disabled by
-default. Calling this function with use_opacity set to TRUE enables
-opacity. Likewise, use_opacity set to FALSE will disable opacity.</para>
+default. Calling this function with has_opacity set to TRUE enables
+opacity. Likewise, has_opacity set to FALSE will disable opacity.</para>
<programlisting role="C">
-void gtk_color_selection_set_color( GtkColorSelection *colorsel,
- gdouble *color );
+void gtk_color_selection_set_current_color( GtkColorSelection *colorsel,
+ GdkColor *color );
+
+void gtk_color_selection_set_current_alpha( GtkColorSelection *colorsel,
+ guint16 alpha );
</programlisting>
-<para>You can set the current color explicitly by calling this function with
-a pointer to an array of colors (gdouble). The length of the array
-depends on whether opacity is enabled or not. Position 0 contains the
-red component, 1 is green, 2 is blue and opacity is at position 3
-(only if opacity is enabled, see
-gtk_color_selection_set_opacity()). All values are between 0.0 and
-1.0.</para>
+<para>You can set the current color explicitly by calling
+gtk_color_selection_set_current_color() with a pointer to a GdkColor.
+Setting the opacity (alpha channel) is done with
+gtk_color_selection_set_current_alpha(). The alpha value should be between
+0 (fully transparent) and 65636 (fully opaque).
+</para>
<programlisting role="C">
-void gtk_color_selection_get_color( GtkColorSelection *colorsel,
- gdouble *color );
+void gtk_color_selection_get_current_color( GtkColorSelection *colorsel,
+ GdkColor *color );
+
+void gtk_color_selection_get_current_alpha( GtkColorSelection *colorsel,
+ guint16 *alpha );
</programlisting>
<para>When you need to query the current color, typically when you've
-received a "color_changed" signal, you use this function. Color is a
-pointer to the array of colors to fill in. See the
-gtk_color_selection_set_color() function for the description of this
-array.</para>
+received a "color_changed" signal, you use these functions.</para>
<para><!-- Need to do a whole section on DnD - TRG
Drag and drop
changing the color in the color selection dialog changes the
background color.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/colorsel.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start colorsel colorsel.c -->
GtkWidget *colorseldlg = NULL;
GtkWidget *drawingarea = NULL;
+GdkColor color;
/* Color changed handler */
void color_changed_cb( GtkWidget *widget,
GtkColorSelection *colorsel )
{
- gdouble color[3];
- GdkColor gdk_color;
- GdkColormap *colormap;
-
- /* Get drawingarea colormap */
-
- colormap = gdk_window_get_colormap (drawingarea->window);
-
- /* Get current color */
-
- gtk_color_selection_get_color (colorsel,color);
-
- /* Fit to a unsigned 16 bit integer (0..65535) and
- * insert into the GdkColor structure */
-
- gdk_color.red = (guint16)(color[0]*65535.0);
- gdk_color.green = (guint16)(color[1]*65535.0);
- gdk_color.blue = (guint16)(color[2]*65535.0);
-
- /* Allocate color */
-
- gdk_color_alloc (colormap, &gdk_color);
-
- /* Set window background color */
-
- gdk_window_set_background (drawingarea->window, &gdk_color);
-
- /* Clear window */
+ GdkColor ncolor;
- gdk_window_clear (drawingarea->window);
+ gtk_color_selection_get_current_color (colorsel, &ncolor);
+ gtk_widget_modify_bg (drawingarea, GTK_STATE_NORMAL, &ncolor);
}
/* Drawingarea event handler */
gpointer client_data )
{
gint handled = FALSE;
- GtkWidget *colorsel;
+ gint response;
+ GtkColorSelection *colorsel;
/* Check if we've received a button pressed event */
- if (event->type == GDK_BUTTON_PRESS && colorseldlg == NULL)
+ if (event->type == GDK_BUTTON_PRESS)
{
- /* Yes, we have an event and there's no colorseldlg yet! */
-
handled = TRUE;
- /* Create color selection dialog */
-
- colorseldlg = gtk_color_selection_dialog_new("Select background color");
+ /* Create color selection dialog */
+ if (colorseldlg == NULL)
+ colorseldlg = gtk_color_selection_dialog_new ("Select background color");
/* Get the ColorSelection widget */
+ colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (colorseldlg)->colorsel);
- colorsel = GTK_COLOR_SELECTION_DIALOG(colorseldlg)->colorsel;
+ gtk_color_selection_set_previous_color (colorsel, &color);
+ gtk_color_selection_set_current_color (colorsel, &color);
+ gtk_color_selection_set_has_palette (colorsel, TRUE);
/* Connect to the "color_changed" signal, set the client-data
* to the colorsel widget */
-
- gtk_signal_connect(GTK_OBJECT(colorsel), "color_changed",
- (GtkSignalFunc)color_changed_cb, (gpointer)colorsel);
+ g_signal_connect (G_OBJECT (colorsel), "color_changed",
+ G_CALLBACK (color_changed_cb), (gpointer) colorsel);
/* Show the dialog */
+ response = gtk_dialog_run (GTK_DIALOG (colorseldlg));
+
+ if (response == GTK_RESPONSE_OK)
+ gtk_color_selection_get_current_color (colorsel, &color);
+ else
+ gtk_widget_modify_bg (drawingarea, GTK_STATE_NORMAL, &color);
- gtk_widget_show(colorseldlg);
+ gtk_widget_hide (colorseldlg);
}
return handled;
gpointer client_data )
{
gtk_main_quit ();
- return(TRUE);
+ return TRUE;
}
/* Main */
/* Initialize the toolkit, remove gtk-related commandline stuff */
- gtk_init (&argc,&argv);
+ gtk_init (&argc, &argv);
/* Create toplevel window, set title and policies */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW(window), "Color selection test");
- gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, TRUE);
+ gtk_window_set_title (GTK_WINDOW (window), "Color selection test");
+ gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, TRUE);
/* Attach to the "delete" and "destroy" events so we can exit */
- gtk_signal_connect (GTK_OBJECT(window), "delete_event",
- (GtkSignalFunc)destroy_window, (gpointer)window);
+ g_signal_connect (GTK_OBJECT (window), "delete_event",
+ GTK_SIGNAL_FUNC (destroy_window), (gpointer) window);
/* Create drawingarea, set size and catch button events */
drawingarea = gtk_drawing_area_new ();
+ color.red = 0;
+ color.blue = 65535;
+ color.green = 0;
+ gtk_widget_modify_bg (drawingarea, GTK_STATE_NORMAL, &color);
+
gtk_widget_set_size_request (GTK_WIDGET (drawingarea), 200, 200);
gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK);
g_signal_connect (GTK_OBJECT (drawingarea), "event",
- (GtkSignalFunc)area_event, (gpointer)drawingarea);
+ GTK_SIGNAL_FUNC (area_event), (gpointer) drawingarea);
/* Add drawingarea to window, then show them both */
- gtk_container_add (GTK_CONTAINER(window), drawingarea);
+ gtk_container_add (GTK_CONTAINER (window), drawingarea);
gtk_widget_show (drawingarea);
gtk_widget_show (window);
/* Satisfy grumpy compilers */
- return(0);
+ return 0;
}
<!-- example-end -->
</programlisting>
<para>To create a new file selection box use:</para>
<programlisting role="C">
-GtkWidget *gtk_file_selection_new( gchar *title );
+GtkWidget *gtk_file_selection_new( const gchar *title );
</programlisting>
<para>To set the filename, for example to bring up a specific directory, or
<programlisting role="C">
void gtk_file_selection_set_filename( GtkFileSelection *filesel,
- gchar *filename );
+ const gchar *filename );
</programlisting>
<para>To grab the text that the user has entered or clicked on, use this
<para>Most likely you will want to use the ok_button, cancel_button, and
help_button pointers in signaling their use.</para>
-<para>Included here is an example stolen from testgtk.c, modified to run on
-its own. As you will see, there is nothing much to creating a file
+<para>Included here is an example stolen from <filename>testgtk.c</filename>,
+modified to run on its own. As you will see, there is nothing much to creating a file
selection widget. While in this example the Help button appears on the
screen, it does nothing as there is not a signal attached to it.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/filesel.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start filesel filesel.c -->
g_print ("%s\n", gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)));
}
-void destroy( GtkWidget *widget,
- gpointer data )
-{
- gtk_main_quit ();
-}
-
int main( int argc,
char *argv[] )
{
/* Create a new file selection widget */
filew = gtk_file_selection_new ("File selection");
- g_signal_connect (GTK_OBJECT (filew), "destroy",
- GTK_SIGNAL_FUNC (destroy), &filew);
+ g_signal_connect (G_OBJECT (filew), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
/* Connect the ok_button to file_ok_sel function */
- g_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
- "clicked", GTK_SIGNAL_FUNC (file_ok_sel), filew );
+ g_signal_connect (G_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
+ "clicked", G_CALLBACK (file_ok_sel), (gpointer) filew);
/* Connect the cancel_button to destroy the widget */
- g_signal_connect_swapped (GTK_OBJECT (GTK_FILE_SELECTION
- (filew)->cancel_button),
- "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT (filew));
+ g_signal_connect_swapped (G_OBJECT (GTK_FILE_SELECTION (filew)->cancel_button),
+ "clicked", G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (filew));
/* Lets set the filename, as if this were a save dialog, and we are giving
a default filename */
gtk_file_selection_set_filename (GTK_FILE_SELECTION(filew),
"penguin.png");
- gtk_widget_show(filew);
+ gtk_widget_show (filew);
gtk_main ();
return 0;
}
<para>A child widget can then be added to this EventBox:</para>
<programlisting role="C">
- gtk_container_add( GTK_CONTAINER(event_box), child_widget );
+ gtk_container_add (GTK_CONTAINER (event_box), child_widget);
</programlisting>
<para>The following example demonstrates both uses of an EventBox - a label
mouse-click on the label causes the program to exit. Resizing the
window reveals varying amounts of the label.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/eventbox.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start eventbox eventbox.c -->
gtk_window_set_title (GTK_WINDOW (window), "Event Box");
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (exit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (exit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Create an EventBox and add it to our toplevel window */
event_box = gtk_event_box_new ();
- gtk_container_add (GTK_CONTAINER(window), event_box);
+ gtk_container_add (GTK_CONTAINER (window), event_box);
gtk_widget_show (event_box);
/* Create a long label */
/* And bind an action to it */
gtk_widget_set_events (event_box, GDK_BUTTON_PRESS_MASK);
- g_signal_connect (GTK_OBJECT(event_box), "button_press_event",
- GTK_SIGNAL_FUNC (exit), NULL);
+ g_signal_connect (G_OBJECT (event_box), "button_press_event",
+ G_CALLBACK (exit), NULL);
/* Yet one more thing you need an X window for ... */
gtk_widget_realize (event_box);
- gdk_window_set_cursor (event_box->window, gdk_cursor_new (GDK_HAND1));
+ gdk_window_set_cursor (event_box->window, gdk_cursor_new (GDK_HAND1));
gtk_widget_show (window);
</programlisting>
<para>The first function creates a new Alignment widget with the specified
-parameters. The second function allows the alignment paramters of an
+parameters. The second function allows the alignment parameters of an
exisiting Alignment widget to be altered.</para>
<para>All four alignment parameters are floating point numbers which can
<para>A child widget can be added to this Alignment widget using:</para>
<programlisting role="C">
- gtk_container_add( GTK_CONTAINER(alignment), child_widget );
+ gtk_container_add (GTK_CONTAINER (alignment), child_widget);
</programlisting>
<para>For an example of using an Alignment widget, refer to the example for
within it's window, relative to it's upper left hand corner. The
position of the widgets can be changed dynamically.</para>
-<para>There are only three functions associated with the fixed widget:</para>
+<para>There are only a few functions associated with the fixed widget:</para>
<programlisting role="C">
GtkWidget* gtk_fixed_new( void );
void gtk_fixed_put( GtkFixed *fixed,
GtkWidget *widget,
- gint16 x,
- gint16 y );
+ gint x,
+ gint y );
void gtk_fixed_move( GtkFixed *fixed,
GtkWidget *widget,
- gint16 x,
- gint16 y );
+ gint x,
+ gint y );
</programlisting>
-<para>The function <literal>gtk_fixed_new</literal> allows you to create a new Fixed
+<para>The function gtk_fixed_new() allows you to create a new Fixed
container.</para>
-<para><literal>gtk_fixed_put</literal> places <literal>widget</literal> in the container <literal>fixed</literal> at
+<para>gtk_fixed_put() places <literal>widget</literal> in the container <literal>fixed</literal> at
the position specified by <literal>x</literal> and <literal>y</literal>.</para>
-<para><literal>gtk_fixed_move</literal> allows the specified widget to be moved to a new
+<para>gtk_fixed_move() allows the specified widget to be moved to a new
position.</para>
+<programlisting role="C">
+void gtk_fixed_set_has_window( GtkFixed *fixed,
+ gboolean has_window );
+
+gboolean gtk_fixed_get_has_window( GtkFixed *fixed );
+</programlisting>
+
+<para>Normally, Fixed widgets don't have their own X window. Since this is
+different from the behaviour of Fixed widgets in earlier releases of GTK,
+the function gtk_fixed_set_has_window() allows the creation of Fixed widgets
+<emphasis>with</emphasis> their own window. It has to be called before
+realizing the widget.</para>
+
<para>The following example illustrates how to use the Fixed Container.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/fixed.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start fixed fixed.c -->
/* I'm going to be lazy and use some global variables to
* store the position of the widget within the fixed
* container */
-gint x=50;
-gint y=50;
+gint x = 50;
+gint y = 50;
/* This callback function moves the button to a new position
* in the Fixed container. */
void move_button( GtkWidget *widget,
GtkWidget *fixed )
{
- x = (x+30)%300;
- y = (y+50)%300;
- gtk_fixed_move( GTK_FIXED(fixed), widget, x, y);
+ x = (x + 30) % 300;
+ y = (y + 50) % 300;
+ gtk_fixed_move (GTK_FIXED (fixed), widget, x, y);
}
int main( int argc,
gint i;
/* Initialise GTK */
- gtk_init(&argc, &argv);
+ gtk_init (&argc, &argv);
/* Create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "Fixed Container");
+ gtk_window_set_title (GTK_WINDOW (window), "Fixed Container");
/* Here we connect the "destroy" event to a signal handler */
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Create a Fixed Container */
- fixed = gtk_fixed_new();
- gtk_container_add(GTK_CONTAINER(window), fixed);
- gtk_widget_show(fixed);
+ fixed = gtk_fixed_new ();
+ gtk_container_add (GTK_CONTAINER (window), fixed);
+ gtk_widget_show (fixed);
- for (i = 1 ; i <= 3 ; i++) {
+ for (i = 1 ; i <= 3 ; i++) {
/* Creates a new button with the label "Press me" */
button = gtk_button_new_with_label ("Press me");
/* When the button receives the "clicked" signal, it will call the
* function move_button() passing it the Fixed Container as its
* argument. */
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (move_button), fixed);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (move_button), (gpointer) fixed);
/* This packs the button into the fixed containers window. */
gtk_fixed_put (GTK_FIXED (fixed), button, i*50, i*50);
guint height );
</programlisting>
-<para>Layout containers are one of the very few widgets in the GTK widget
-set that actively repaint themselves on screen as they are changed
-using the above functions (the vast majority of widgets queue
-requests which are then processed when control returns to the
-<literal>gtk_main()</literal> function).</para>
-
-<para>When you want to make a large number of changes to a Layout container,
-you can use the following two functions to disable and re-enable this
-repainting functionality:</para>
-
-<programlisting role="C">
-void gtk_layout_freeze( GtkLayout *layout );
-
-void gtk_layout_thaw( GtkLayout *layout );
-</programlisting>
-
<para>The final four functions for use with Layout widgets are for
manipulating the horizontal and vertical adjustment widgets:</para>
<para>The following code example illustrates the use of the Frame widget.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/frame.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start frame frame.c -->
GtkWidget *frame;
/* Initialise GTK */
- gtk_init(&argc, &argv);
+ gtk_init (&argc, &argv);
/* Create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "Frame Example");
+ gtk_window_set_title (GTK_WINDOW (window), "Frame Example");
/* Here we connect the "destroy" event to a signal handler */
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_set_size_request (window, 300, 300);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Create a Frame */
- frame = gtk_frame_new(NULL);
- gtk_container_add(GTK_CONTAINER(window), frame);
+ frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (window), frame);
/* Set the frame's label */
- gtk_frame_set_label( GTK_FRAME(frame), "GTK Frame Widget" );
+ gtk_frame_set_label (GTK_FRAME (frame), "GTK Frame Widget");
/* Align the label at the right of the frame */
- gtk_frame_set_label_align( GTK_FRAME(frame), 1.0, 0.0);
+ gtk_frame_set_label_align (GTK_FRAME (frame), 1.0, 0.0);
/* Set the style of the frame */
- gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
- gtk_widget_show(frame);
+ gtk_widget_show (frame);
/* Display the window */
gtk_widget_show (window);
}
<!-- example-end -->
</programlisting>
-
</sect1>
<!-- ----------------------------------------------------------------- -->
gfloat xalign,
gfloat yalign,
gfloat ratio,
- gint obey_child);
+ gboolean obey_child);
</programlisting>
<para><literal>xalign</literal> and <literal>yalign</literal> specify alignment as with Alignment
-widgets. If <literal>obey_child</literal> is true, the aspect ratio of a child
+widgets. If <literal>obey_child</literal> is TRUE, the aspect ratio of a child
widget will match the aspect ratio of the ideal size it requests.
Otherwise, it is given by <literal>ratio</literal>.</para>
gfloat xalign,
gfloat yalign,
gfloat ratio,
- gint obey_child);
+ gboolean obey_child);
</programlisting>
<para>As an example, the following program uses an AspectFrame to present a
drawing area whose aspect ratio will always be 2:1, no matter how the
user resizes the top-level window.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/aspectframe.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start aspectframe aspectframe.c -->
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Create an aspect_frame and add it to our toplevel window */
2, /* xsize/ysize = 2 */
FALSE /* ignore child's aspect */);
- gtk_container_add (GTK_CONTAINER(window), aspect_frame);
+ gtk_container_add (GTK_CONTAINER (window), aspect_frame);
gtk_widget_show (aspect_frame);
/* Now add a child widget to the aspect frame */
/* Ask for a 200x200 window, but the AspectFrame will give us a 200x100
* window since we are forcing a 2x1 aspect ratio */
gtk_widget_set_size_request (drawing_area, 200, 200);
- gtk_container_add (GTK_CONTAINER(aspect_frame), drawing_area);
+ gtk_container_add (GTK_CONTAINER (aspect_frame), drawing_area);
gtk_widget_show (drawing_area);
gtk_widget_show (window);
the bottom portion the text of the email message. Most of the program
is pretty straightforward. A couple of points to note: text can't be
added to a Text widget until it is realized. This could be done by
-calling <literal>gtk_widget_realize()</literal>, but as a demonstration of an
+calling gtk_widget_realize(), but as a demonstration of an
alternate technique, we connect a handler to the "realize" signal to
add the text. Also, we need to add the <literal>GTK_SHRINK</literal> option to some
of the items in the table containing the text window and its
correct portions shrink instead of being pushed off the bottom of the
window.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/paned.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start paned paned.c -->
gtk_widget_show (tree_view);
/* Add some messages to the window */
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 10; i++) {
gchar *msg = g_strdup_printf ("Message #%d", i);
- gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model),
- &iter,
+ &iter,
0, msg,
-1);
g_free (msg);
{
GtkTextIter iter;
- gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
- gtk_text_buffer_insert (buffer, &iter,
+ gtk_text_buffer_insert (buffer, &iter,
"From: pathfinder@nasa.gov\n"
"To: mom@nasa.gov\n"
"Subject: Made it!\n"
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Paned Windows");
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_widget_set_size_request (GTK_WIDGET (window), 450, 400);
gtk_paned_add2 (GTK_PANED (vpaned), text);
gtk_widget_show (text);
gtk_widget_show (window);
+
gtk_main ();
+
return 0;
}
<!-- example-end -->
GtkWidget *child);
</programlisting>
-<para>Here is a simple example that packs a table eith 100 toggle buttons
+<para>Here is a simple example that packs a table with 100 toggle buttons
into a scrolled window. I've only commented on the parts that may be
new to you.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/scrolledwin.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start scrolledwin scrolledwin.c -->
void destroy( GtkWidget *widget,
gpointer data )
{
- gtk_main_quit();
+ gtk_main_quit ();
}
int main( int argc,
/* Create a new dialog window for the scrolled window to be
* packed into. */
window = gtk_dialog_new ();
- g_signal_connect (GTK_OBJECT (window), "destroy",
- (GtkSignalFunc) destroy, NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (destroy), NULL);
gtk_window_set_title (GTK_WINDOW (window), "GtkScrolledWindow example");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_widget_set_size_request (window, 300, 300);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
/* The dialog window is created with a vbox packed into it. */
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window,
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window,
TRUE, TRUE, 0);
gtk_widget_show (scrolled_window);
/* this simply creates a grid of toggle buttons on the table
* to demonstrate the scrolled window. */
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10; j++) {
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 10; j++) {
sprintf (buffer, "button (%d,%d)\n", i, j);
button = gtk_toggle_button_new_with_label (buffer);
gtk_table_attach_defaults (GTK_TABLE (table), button,
/* Add a "close" button to the bottom of the dialog */
button = gtk_button_new_with_label ("close");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
/* this makes it so the button is the default. */
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
/* This grabs this button to be the default button. Simply hitting
* the "Enter" key will cause this button to activate. */
GtkWidget *gtk_vbutton_box_new( void );
</programlisting>
-<para>The only attributes pertaining to button boxes effect how the buttons
-are laid out. You can change the spacing between the buttons with:</para>
-
-<programlisting role="C">
-void gtk_hbutton_box_set_spacing_default( gint spacing );
-
-void gtk_vbutton_box_set_spacing_default( gint spacing );
-</programlisting>
-
-<para>Similarly, the current spacing values can be queried using:</para>
-
-<programlisting role="C">
-gint gtk_hbutton_box_get_spacing_default( void );
-
-gint gtk_vbutton_box_get_spacing_default( void );
-</programlisting>
-
-<para>The second attribute that we can access effects the layout of the
-buttons within the box. It is set using one of:</para>
-
-<programlisting role="C">
-void gtk_hbutton_box_set_layout_default( GtkButtonBoxStyle layout );
-
-void gtk_vbutton_box_set_layout_default( GtkButtonBoxStyle layout );
-</programlisting>
-
-<para>The <literal>layout</literal> argument can take one of the following values:</para>
-
-<programlisting role="C">
- GTK_BUTTONBOX_DEFAULT_STYLE
- GTK_BUTTONBOX_SPREAD
- GTK_BUTTONBOX_EDGE
- GTK_BUTTONBOX_START
- GTK_BUTTONBOX_END
-</programlisting>
-
-<para>The current layout setting can be retrieved using:</para>
-
-<programlisting role="C">
-GtkButtonBoxStyle gtk_hbutton_box_get_layout_default( void );
-
-GtkButtonBoxStyle gtk_vbutton_box_get_layout_default( void );
-</programlisting>
-
<para>Buttons are added to a Button Box using the usual function:</para>
<programlisting role="C">
- gtk_container_add( GTK_CONTAINER(button_box), child_widget );
+ gtk_container_add (GTK_CONTAINER (button_box), child_widget);
</programlisting>
<para>Here's an example that illustrates all the different layout settings
for Button Boxes.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/buttonbox.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start buttonbox buttonbox.c -->
gtk_box_set_spacing (GTK_BOX (bbox), spacing);
/*gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), child_w, child_h);*/
- button = gtk_button_new_with_label ("OK");
+ button = gtk_button_new_from_stock (GTK_STOCK_OK);
gtk_container_add (GTK_CONTAINER (bbox), button);
- button = gtk_button_new_with_label ("Cancel");
+ button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
gtk_container_add (GTK_CONTAINER (bbox), button);
- button = gtk_button_new_with_label ("Help");
+ button = gtk_button_new_from_stock (GTK_STOCK_HELP);
gtk_container_add (GTK_CONTAINER (bbox), button);
- return(frame);
+ return frame;
}
int main( int argc,
GtkWidget *frame_vert;
/* Initialize GTK */
- gtk_init( &argc, &argv );
+ gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC(gtk_main_quit),
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit),
NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Enter the event loop */
gtk_main ();
- return(0);
+ return 0;
}
<!-- example-end -->
</programlisting>
following function:</para>
<programlisting role="C">
-GtkWidget *gtk_toolbar_new( GtkOrientation orientation,
- GtkToolbarStyle style );
-</programlisting>
-
-<para>where orientation may be one of:</para>
-
-<programlisting role="C">
- GTK_ORIENTATION_HORIZONTAL
- GTK_ORIENTATION_VERTICAL
-</programlisting>
-
-<para>and style one of:</para>
-
-<programlisting role="C">
- GTK_TOOLBAR_TEXT
- GTK_TOOLBAR_ICONS
- GTK_TOOLBAR_BOTH
+GtkWidget *gtk_toolbar_new( void );
</programlisting>
-<para>The style applies to all the buttons created with the `item' functions
-(not to buttons inserted into toolbar as separate widgets).</para>
-
<para>After creating a toolbar one can append, prepend and insert items
(that means simple text strings) or elements (that means any widget
types) into the toolbar. To describe an item we need a label text, a
gpointer user_data );
</programlisting>
-<para>If you want to use gtk_toolbar_insert_item, the only additional
+<para>If you want to use gtk_toolbar_insert_item(), the only additional
parameter which must be specified is the position in which the item
should be inserted, thus:</para>
gint position );
</programlisting>
-<para>While the size of the added space can be set globally for a
-whole toolbar with the function:</para>
-
-<programlisting role="C">
-void gtk_toolbar_set_space_size( GtkToolbar *toolbar,
- gint space_size) ;
-</programlisting>
-
<para>If it's required, the orientation of a toolbar and its style can be
changed "on the fly" using the following functions:</para>
<programlisting role="C">
#include <gtk/gtk.h>
-#include "gtk.xpm"
-
/* This function is connected to the Close button or
* closing the window from the WM */
gint delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
gtk_main_quit ();
- return(FALSE);
+ return FALSE;
}
</programlisting>
void radio_event (GtkWidget *widget, gpointer data)
{
if (GTK_TOGGLE_BUTTON (text_button)->active)
- gtk_toolbar_set_style(GTK_TOOLBAR ( data ), GTK_TOOLBAR_TEXT);
+ gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
else if (GTK_TOGGLE_BUTTON (icon_button)->active)
- gtk_toolbar_set_style(GTK_TOOLBAR ( data ), GTK_TOOLBAR_ICONS);
+ gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
else if (GTK_TOGGLE_BUTTON (both_button)->active)
- gtk_toolbar_set_style(GTK_TOOLBAR ( data ), GTK_TOOLBAR_BOTH);
+ gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
}
/* even easier, just check given toggle button and enable/disable
* tooltips */
void toggle_event (GtkWidget *widget, gpointer data)
{
- gtk_toolbar_set_tooltips (GTK_TOOLBAR ( data ),
+ gtk_toolbar_set_tooltips (GTK_TOOLBAR (data),
GTK_TOGGLE_BUTTON (widget)->active );
}
</programlisting>
the buttons) and an icon widget to put this icon in (but
we'll create a separate widget for each button) */
GtkWidget * toolbar;
- GdkPixmap * icon;
- GdkBitmap * mask;
GtkWidget * iconw;
/* this is called in all GTK application. */
/* create a new window with a given title, and nice size */
dialog = gtk_dialog_new ();
- gtk_window_set_title ( GTK_WINDOW ( dialog ) , "GTKToolbar Tutorial");
+ gtk_window_set_title (GTK_WINDOW (dialog), "GTKToolbar Tutorial");
gtk_widget_set_size_request (GTK_WIDGET (dialog), 600, 300);
- GTK_WINDOW ( dialog ) ->allow_shrink = TRUE;
+ GTK_WINDOW (dialog)->allow_shrink = TRUE;
/* typically we quit if someone tries to close us */
- g_signal_connect ( GTK_OBJECT ( dialog ), "delete_event",
- GTK_SIGNAL_FUNC ( delete_event ), NULL);
+ g_signal_connect (G_OBJECT (dialog), "delete_event",
+ G_CALLBACK (delete_event), NULL);
/* we need to realize the window because we use pixmaps for
* items on the toolbar in the context of it */
- gtk_widget_realize ( dialog );
+ gtk_widget_realize (dialog);
/* to make it nice we'll put the toolbar into the handle box,
* so that it can be detached from the main window */
handlebox = gtk_handle_box_new ();
- gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG(dialog)->vbox ),
- handlebox, FALSE, FALSE, 5 );
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ handlebox, FALSE, FALSE, 5);
</programlisting>
<para>The above should be similar to any other GTK application. Just
/* toolbar will be horizontal, with both icons and text, and
* with 5pxl spaces between items and finally,
* we'll also put it into our handlebox */
- toolbar = gtk_toolbar_new ( GTK_ORIENTATION_HORIZONTAL,
- GTK_TOOLBAR_BOTH );
- gtk_container_set_border_width ( GTK_CONTAINER ( toolbar ) , 5 );
- gtk_toolbar_set_space_size ( GTK_TOOLBAR ( toolbar ), 5 );
- gtk_container_add ( GTK_CONTAINER ( handlebox ) , toolbar );
-
- /* now we create icon with mask: we'll reuse it to create
- * icon widgets for toolbar items */
- icon = gdk_pixmap_create_from_xpm_d ( dialog->window, &mask,
- &dialog->style->white, gtk_xpm );
+ toolbar = gtk_toolbar_new ();
+ gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
+ gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH);
+ gtk_container_set_border_width (GTK_CONTAINER (toolbar), 5);
+ gtk_toolbar_set_space_size (GTK_TOOLBAR (toolbar), 5);
+ gtk_container_add (GTK_CONTAINER (handlebox), toolbar);
</programlisting>
<para>Well, what we do above is just a straightforward initialization of
-the toolbar widget and creation of a GDK pixmap with its mask. If you
-want to know something more about using pixmaps, refer to GDK
-documentation or to the <link linkend="sec-Pixmaps">Pixmaps</link> section
-earlier in this tutorial.</para>
+the toolbar widget.</para>
<programlisting role="C">
/* our first item is <close> button */
- iconw = gtk_pixmap_new ( icon, mask ); /* icon widget */
+ iconw = gtk_image_new_from_file ("gtk.xpm"); /* icon widget */
close_button =
- gtk_toolbar_append_item ( GTK_TOOLBAR (toolbar), /* our toolbar */
- "Close", /* button label */
- "Closes this app", /* this button's tooltip */
- "Private", /* tooltip private info */
- iconw, /* icon widget */
- GTK_SIGNAL_FUNC (delete_event), /* a signal */
- NULL );
- gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) ); /* space after item */
+ gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), /* our toolbar */
+ "Close", /* button label */
+ "Closes this app", /* this button's tooltip */
+ "Private", /* tooltip private info */
+ iconw, /* icon widget */
+ GTK_SIGNAL_FUNC (delete_event), /* a signal */
+ NULL);
+ gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); /* space after item */
</programlisting>
<para>In the above code you see the simplest case: adding a button to
-toolbar. Just before appending a new item, we have to construct a
-pixmap widget to serve as an icon for this item; this step will have
+toolbar. Just before appending a new item, we have to construct an
+image widget to serve as an icon for this item; this step will have
to be repeated for each new item. Just after the item we also add a
space, so the following items will not touch each other. As you see
-gtk_toolbar_append_item returns a pointer to our newly created button
+gtk_toolbar_append_item() returns a pointer to our newly created button
widget, so that we can work with it in the normal way.</para>
<programlisting role="C">
/* now, let's make our radio buttons group... */
- iconw = gtk_pixmap_new ( icon, mask );
- icon_button = gtk_toolbar_append_element(
- GTK_TOOLBAR(toolbar),
+ iconw = gtk_image_new_from_file ("gtk.xpm");
+ icon_button = gtk_toolbar_append_element (
+ GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, /* a type of element */
NULL, /* pointer to widget */
"Icon", /* label */
iconw, /* icon */
GTK_SIGNAL_FUNC (radio_event), /* signal */
toolbar); /* data for signal */
- gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
+ gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
</programlisting>
<para>Here we begin creating a radio buttons group. To do this we use
creating a radio group. In creating other radio buttons for this group
a pointer to the previous button in the group is required, so that a
list of buttons can be easily constructed (see the section on <link
-linkend="sec-RadioButtons"> Radio Buttons </link> earlier in this
+linkend="sec-RadioButtons">Radio Buttons</link> earlier in this
tutorial).</para>
<programlisting role="C">
/* following radio buttons refer to previous ones */
- iconw = gtk_pixmap_new ( icon, mask );
+ iconw = gtk_image_new_from_file ("gtk.xpm");
text_button =
- gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
- GTK_TOOLBAR_CHILD_RADIOBUTTON,
- icon_button,
- "Text",
- "Only texts in toolbar",
- "Private",
- iconw,
- GTK_SIGNAL_FUNC (radio_event),
- toolbar);
- gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
+ gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+ GTK_TOOLBAR_CHILD_RADIOBUTTON,
+ icon_button,
+ "Text",
+ "Only texts in toolbar",
+ "Private",
+ iconw,
+ GTK_SIGNAL_FUNC (radio_event),
+ toolbar);
+ gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
- iconw = gtk_pixmap_new ( icon, mask );
+ iconw = gtk_image_new_from_file ("gtk.xpm");
both_button =
- gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
- GTK_TOOLBAR_CHILD_RADIOBUTTON,
- text_button,
- "Both",
- "Icons and text in toolbar",
- "Private",
- iconw,
- GTK_SIGNAL_FUNC (radio_event),
- toolbar);
- gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_button),TRUE);
+ gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+ GTK_TOOLBAR_CHILD_RADIOBUTTON,
+ text_button,
+ "Both",
+ "Icons and text in toolbar",
+ "Private",
+ iconw,
+ GTK_SIGNAL_FUNC (radio_event),
+ toolbar);
+ gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (both_button), TRUE);
</programlisting>
<para>In the end we have to set the state of one of the buttons manually
<programlisting role="C">
/* here we have just a simple toggle button */
- iconw = gtk_pixmap_new ( icon, mask );
+ iconw = gtk_image_new_from_file ("gtk.xpm");
tooltips_button =
- gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
- GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
- NULL,
- "Tooltips",
- "Toolbar with or without tips",
- "Private",
- iconw,
- GTK_SIGNAL_FUNC (toggle_event),
- toolbar);
- gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tooltips_button),TRUE);
+ gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+ GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
+ NULL,
+ "Tooltips",
+ "Toolbar with or without tips",
+ "Private",
+ iconw,
+ GTK_SIGNAL_FUNC (toggle_event),
+ toolbar);
+ gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tooltips_button), TRUE);
</programlisting>
<para>A toggle button can be created in the obvious way (if one knows how to create
/* to pack a widget into toolbar, we only have to
* create it and append it with an appropriate tooltip */
entry = gtk_entry_new ();
- gtk_toolbar_append_widget( GTK_TOOLBAR (toolbar),
+ gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar),
entry,
"This is just an entry",
- "Private" );
+ "Private");
- /* well, it isn't created within thetoolbar, so we must still show it */
- gtk_widget_show ( entry );
+ /* well, it isn't created within the toolbar, so we must still show it */
+ gtk_widget_show (entry);
</programlisting>
<para>As you see, adding any kind of widget to a toolbar is simple. The
<programlisting role="C">
/* that's it ! let's show everything. */
- gtk_widget_show ( toolbar );
+ gtk_widget_show (toolbar);
gtk_widget_show (handlebox);
- gtk_widget_show ( dialog );
+ gtk_widget_show (dialog);
/* rest in gtk_main and wait for the fun to begin! */
gtk_main ();
<para>These next two functions are simple calls to move the notebook page
forward or backward. Simply provide the respective function call with
the notebook widget you wish to operate on. Note: When the NoteBook is
-currently on the last page, and gtk_notebook_next_page is called, the
+currently on the last page, and gtk_notebook_next_page() is called, the
notebook will wrap back to the first page. Likewise, if the NoteBook
-is on the first page, and gtk_notebook_prev_page is called, the
+is on the first page, and gtk_notebook_prev_page() is called, the
notebook will wrap to the last page.</para>
<programlisting role="C">
using this function, the notebook defaults to the first page.</para>
<programlisting role="C">
-void gtk_notebook_set_page( GtkNotebook *notebook,
- gint page_num );
+void gtk_notebook_set_current_page( GtkNotebook *notebook,
+ gint page_num );
</programlisting>
<para>The next two functions add or remove the notebook page tabs and the
<programlisting role="C">
void gtk_notebook_set_show_tabs( GtkNotebook *notebook,
- gboolean show_tabs);
+ gboolean show_tabs );
void gtk_notebook_set_show_border( GtkNotebook *notebook,
gboolean show_border );
<para><literal>show_tabs</literal>, <literal>show_border</literal> and <literal>scrollable</literal> can be either
TRUE or FALSE.</para>
-<para>Now let's look at an example, it is expanded from the testgtk.c code
+<para>Now let's look at an example, it is expanded from the
+<filename>testgtk.c</filename> code
that comes with the GTK distribution. This small program creates a
window with a notebook and six buttons. The notebook contains 11
pages, added in three different ways, appended, inserted, and
the tabs and border, remove a page, change pages in both a forward and
backward manner, and exit the program.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/notebook.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start notebook notebook.c -->
void rotate_book( GtkButton *button,
GtkNotebook *notebook )
{
- gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos +1) %4);
+ gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
}
/* Add/Remove the page tabs and the borders */
{
gint tval = FALSE;
gint bval = FALSE;
- if (notebook->show_tabs == 0)
+ if (notebook->show_tabs == 0)
tval = TRUE;
- if (notebook->show_border == 0)
+ if (notebook->show_border == 0)
bval = TRUE;
gtk_notebook_set_show_tabs (notebook, tval);
{
gint page;
- page = gtk_notebook_get_current_page(notebook);
+ page = gtk_notebook_get_current_page (notebook);
gtk_notebook_remove_page (notebook, page);
/* Need to refresh the widget --
This forces the widget to redraw itself. */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (delete), NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (delete), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
- table = gtk_table_new(3,6,FALSE);
+ table = gtk_table_new (3, 6, FALSE);
gtk_container_add (GTK_CONTAINER (window), table);
/* Create a new notebook, place the position of the tabs */
notebook = gtk_notebook_new ();
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
- gtk_table_attach_defaults(GTK_TABLE(table), notebook, 0,6,0,1);
- gtk_widget_show(notebook);
+ gtk_table_attach_defaults (GTK_TABLE (table), notebook, 0, 6, 0, 1);
+ gtk_widget_show (notebook);
/* Let's append a bunch of pages to the notebook */
- for (i=0; i < 5; i++) {
- sprintf(bufferf, "Append Frame %d", i+1);
- sprintf(bufferl, "Page %d", i+1);
+ for (i = 0; i < 5; i++) {
+ sprintf(bufferf, "Append Frame %d", i + 1);
+ sprintf(bufferl, "Page %d", i + 1);
frame = gtk_frame_new (bufferf);
gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), checkbutton, label, 2);
/* Now finally let's prepend pages to the notebook */
- for (i=0; i < 5; i++) {
- sprintf(bufferf, "Prepend Frame %d", i+1);
- sprintf(bufferl, "PPage %d", i+1);
+ for (i = 0; i < 5; i++) {
+ sprintf (bufferf, "Prepend Frame %d", i + 1);
+ sprintf (bufferl, "PPage %d", i + 1);
frame = gtk_frame_new (bufferf);
gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
gtk_widget_show (label);
label = gtk_label_new (bufferl);
- gtk_notebook_prepend_page (GTK_NOTEBOOK(notebook), frame, label);
+ gtk_notebook_prepend_page (GTK_NOTEBOOK (notebook), frame, label);
}
/* Set what page to start at (page 4) */
- gtk_notebook_set_current_page (GTK_NOTEBOOK(notebook), 3);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 3);
/* Create a bunch of buttons */
button = gtk_button_new_with_label ("close");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (delete), NULL);
- gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,1,2);
- gtk_widget_show(button);
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (delete), NULL);
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 1, 2);
+ gtk_widget_show (button);
button = gtk_button_new_with_label ("next page");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_notebook_next_page),
- GTK_OBJECT (notebook));
- gtk_table_attach_defaults(GTK_TABLE(table), button, 1,2,1,2);
- gtk_widget_show(button);
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_notebook_next_page),
+ G_OBJECT (notebook));
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 2, 1, 2);
+ gtk_widget_show (button);
button = gtk_button_new_with_label ("prev page");
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_notebook_prev_page),
- GTK_OBJECT (notebook));
- gtk_table_attach_defaults(GTK_TABLE(table), button, 2,3,1,2);
- gtk_widget_show(button);
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_notebook_prev_page),
+ G_OBJECT (notebook));
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 2, 3, 1, 2);
+ gtk_widget_show (button);
button = gtk_button_new_with_label ("tab position");
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (rotate_book),
- GTK_OBJECT(notebook));
- gtk_table_attach_defaults(GTK_TABLE(table), button, 3,4,1,2);
- gtk_widget_show(button);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (rotate_book),
+ (gpointer) notebook);
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 3, 4, 1, 2);
+ gtk_widget_show (button);
button = gtk_button_new_with_label ("tabs/border on/off");
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (tabsborder_book),
- GTK_OBJECT (notebook));
- gtk_table_attach_defaults(GTK_TABLE(table), button, 4,5,1,2);
- gtk_widget_show(button);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (tabsborder_book),
+ (gpointer) notebook);
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 4, 5, 1, 2);
+ gtk_widget_show (button);
button = gtk_button_new_with_label ("remove page");
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (remove_book),
- GTK_OBJECT(notebook));
- gtk_table_attach_defaults(GTK_TABLE(table), button, 5,6,1,2);
- gtk_widget_show(button);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (remove_book),
+ (gpointer) notebook);
+ gtk_table_attach_defaults (GTK_TABLE (table), button, 5, 6, 1, 2);
+ gtk_widget_show (button);
- gtk_widget_show(table);
- gtk_widget_show(window);
+ gtk_widget_show (table);
+ gtk_widget_show (window);
gtk_main ();
</chapter>
<!-- ***************************************************************** -->
-<chapter id="ch-CListWidget">
-<title>CList Widget</title>
+<chapter id="ch-MenuWidget">
+<title>Menu Widget</title>
+
+<para>There are two ways to create menus: there's the easy way, and there's
+the hard way. Both have their uses, but you can usually use the
+Itemfactory (the easy way). The "hard" way is to create all the menus
+using the calls directly. The easy way is to use the gtk_item_factory
+calls. This is much simpler, but there are advantages and
+disadvantages to each approach.</para>
+
+<para>The Itemfactory is much easier to use, and to add new menus to,
+although writing a few wrapper functions to create menus using the
+manual method could go a long way towards usability. With the
+Itemfactory, it is not possible to add images or the character '/' to
+the menus.</para>
<!-- ----------------------------------------------------------------- -->
+<sect1 id="sec-ManualMenuCreation">
+<title>Manual Menu Creation</title>
-<para>The CList widget has replaced the List widget (which is still
-available).</para>
+<para>In the true tradition of teaching, we'll show you the hard way
+first. <literal>:)</literal></para>
-<para>The CList widget is a multi-column list widget that is capable of
-handling literally thousands of rows of information. Each column can
-optionally have a title, which itself is optionally active, allowing
-us to bind a function to its selection.</para>
+<para>There are three widgets that go into making a menubar and submenus:</para>
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-CreatingACListWidget">
-<title>Creating a CList widget</title>
+<itemizedlist>
+<listitem><simpara>a menu item, which is what the user wants to select, e.g.,
+"Save"</simpara>
+</listitem>
+<listitem><simpara>a menu, which acts as a container for the menu items, and</simpara>
+</listitem>
+<listitem><simpara>a menubar, which is a container for each of the individual
+menus.</simpara>
+</listitem>
+</itemizedlist>
-<para>Creating a CList is quite straightforward, once you have learned
-about widgets in general. It provides the almost standard two ways,
-that is the hard way, and the easy way. But before we create it, there
-is one thing we should figure out beforehand: how many columns should
-it have?</para>
+<para>This is slightly complicated by the fact that menu item widgets are
+used for two different things. They are both the widgets that are
+packed into the menu, and the widget that is packed into the menubar,
+which, when selected, activates the menu.</para>
-<para>Not all columns have to be visible and can be used to store data that
-is related to a certain cell in the list.</para>
+<para>Let's look at the functions that are used to create menus and
+menubars. This first function is used to create a new menubar.</para>
<programlisting role="C">
-GtkWidget *gtk_clist_new ( gint columns );
-
-GtkWidget *gtk_clist_new_with_titles( gint columns,
- gchar *titles[] );
+GtkWidget *gtk_menu_bar_new( void );
</programlisting>
-<para>The first form is very straightforward, the second might require some
-explanation. Each column can have a title associated with it, and this
-title can be a label or a button that reacts when we click on it. If
-we use the second form, we must provide pointers to the title texts,
-and the number of pointers should equal the number of columns
-specified. Of course we can always use the first form, and manually
-add titles later.</para>
-
-<para>Note: The CList widget does not have its own scrollbars and should
-be placed within a ScrolledWindow widget if your require this
-functionality. This is a change from the GTK 1.0 implementation.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-ModesOfOperating">
-<title>Modes of operation</title>
-
-<para>There are several attributes that can be used to alter the behaviour of
-a CList. First there is</para>
-
-<programlisting role="C">
-void gtk_clist_set_selection_mode( GtkCList *clist,
- GtkSelectionMode mode );
-</programlisting>
-
-<para>which, as the name implies, sets the selection mode of the
-CList. The first argument is the CList widget, and the second
-specifies the cell selection mode (they are defined in gtkenums.h). At
-the time of this writing, the following modes are available to us:</para>
-
-<itemizedlist>
-<listitem><simpara> <literal>GTK_SELECTION_SINGLE</literal> - The selection is either NULL or contains
-a GList pointer for a single selected item.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>GTK_SELECTION_BROWSE</literal> - The selection is NULL if the list
-contains no widgets or insensitive ones only, otherwise it contains a
-GList pointer for one GList structure, and therefore exactly one list
-item.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>GTK_SELECTION_MULTIPLE</literal> - The selection is NULL if no list items
-are selected or a GList pointer for the first selected item. That in
-turn points to a GList structure for the second selected item and so
-on. This is currently the <emphasis>default</emphasis> for the CList widget.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>GTK_SELECTION_EXTENDED</literal> - The selection is always NULL.</simpara>
-</listitem>
-</itemizedlist>
-
-<para>Others might be added in later revisions of GTK.</para>
-
-<para>We can also define what the border of the CList widget should look
-like. It is done through</para>
-
-<programlisting role="C">
-void gtk_clist_set_shadow_type( GtkCList *clist,
- GtkShadowType border );
-</programlisting>
-
-<para>The possible values for the second argument are</para>
-
-<programlisting role="C">
- GTK_SHADOW_NONE
- GTK_SHADOW_IN
- GTK_SHADOW_OUT
- GTK_SHADOW_ETCHED_IN
- GTK_SHADOW_ETCHED_OUT
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-WorkingWithTitles">
-<title>Working with titles</title>
-
-<para>When you create a CList widget, you will also get a set of title
-buttons automatically. They live in the top of the CList window, and
-can act either as normal buttons that respond to being pressed, or
-they can be passive, in which case they are nothing more than a
-title. There are four different calls that aid us in setting the
-status of the title buttons.</para>
-
-<programlisting role="C">
-void gtk_clist_column_title_active( GtkCList *clist,
- gint column );
-
-void gtk_clist_column_title_passive( GtkCList *clist,
- gint column );
-
-void gtk_clist_column_titles_active( GtkCList *clist );
-
-void gtk_clist_column_titles_passive( GtkCList *clist );
-</programlisting>
-
-<para>An active title is one which acts as a normal button, a passive one is
-just a label. The first two calls above will activate/deactivate the
-title button above the specific column, while the last two calls
-activate/deactivate all title buttons in the supplied clist widget.</para>
-
-<para>But of course there are those cases when we don't want them at all,
-and so they can be hidden and shown at will using the following two
-calls.</para>
-
-<programlisting role="C">
-void gtk_clist_column_titles_show( GtkCList *clist );
-
-void gtk_clist_column_titles_hide( GtkCList *clist );
-</programlisting>
-
-<para>For titles to be really useful we need a mechanism to set and change
-them, and this is done using</para>
-
-<programlisting role="C">
-void gtk_clist_set_column_title( GtkCList *clist,
- gint column,
- gchar *title );
-</programlisting>
-
-<para>Note that only the title of one column can be set at a time, so if all
-the titles are known from the beginning, then I really suggest using
-gtk_clist_new_with_titles (as described above) to set them. It saves
-you coding time, and makes your program smaller. There are some cases
-where getting the job done the manual way is better, and that's when
-not all titles will be text. CList provides us with title buttons
-that can in fact incorporate whole widgets, for example a pixmap. It's
-all done through</para>
-
-<programlisting role="C">
-void gtk_clist_set_column_widget( GtkCList *clist,
- gint column,
- GtkWidget *widget );
-</programlisting>
-
-<para>which should require no special explanation.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-ManipulatingTheListItself">
-<title>Manipulating the list itself</title>
-
-<para>It is possible to change the justification for a column, and it is
-done through</para>
-
-<programlisting role="C">
-void gtk_clist_set_column_justification( GtkCList *clist,
- gint column,
- GtkJustification justification );
-</programlisting>
-
-<para>The GtkJustification type can take the following values:</para>
-
-<itemizedlist>
-<listitem><simpara><literal>GTK_JUSTIFY_LEFT</literal> - The text in the column will begin from the
-left edge.</simpara>
-</listitem>
-
-<listitem><simpara><literal>GTK_JUSTIFY_RIGHT</literal> - The text in the column will begin from the
-right edge.</simpara>
-</listitem>
-
-<listitem><simpara><literal>GTK_JUSTIFY_CENTER</literal> - The text is placed in the center of the
-column.</simpara>
-</listitem>
-
-<listitem><simpara><literal>GTK_JUSTIFY_FILL</literal> - The text will use up all available space in
-the column. It is normally done by inserting extra blank spaces
-between words (or between individual letters if it's a single
-word). Much in the same way as any ordinary WYSIWYG text editor.</simpara>
-</listitem>
-</itemizedlist>
-
-<para>The next function is a very important one, and should be standard in
-the setup of all CList widgets. When the list is created, the width
-of the various columns are chosen to match their titles, and since
-this is seldom the right width we have to set it using</para>
-
-<programlisting role="C">
-void gtk_clist_set_column_width( GtkCList *clist,
- gint column,
- gint width );
-</programlisting>
-
-<para>Note that the width is given in pixels and not letters. The same goes
-for the height of the cells in the columns, but as the default value
-is the height of the current font this isn't as critical to the
-application. Still, it is done through</para>
-
-<programlisting role="C">
-void gtk_clist_set_row_height( GtkCList *clist,
- gint height );
-</programlisting>
-
-<para>Again, note that the height is given in pixels.</para>
-
-<para>We can also move the list around without user interaction, however, it
-does require that we know what we are looking for. Or in other words,
-we need the row and column of the item we want to scroll to.</para>
-
-<programlisting role="C">
-void gtk_clist_moveto( GtkCList *clist,
- gint row,
- gint column,
- gfloat row_align,
- gfloat col_align );
-</programlisting>
-
-<para>The gfloat row_align is pretty important to understand. It's a value
-between 0.0 and 1.0, where 0.0 means that we should scroll the list so
-the row appears at the top, while if the value of row_align is 1.0,
-the row will appear at the bottom instead. All other values between
-0.0 and 1.0 are also valid and will place the row between the top and
-the bottom. The last argument, gfloat col_align works in the same way,
-though 0.0 marks left and 1.0 marks right instead.</para>
-
-<para>Depending on the application's needs, we don't have to scroll to an
-item that is already visible to us. So how do we know if it is
-visible? As usual, there is a function to find that out as well.</para>
-
-<programlisting role="C">
-GtkVisibility gtk_clist_row_is_visible( GtkCList *clist,
- gint row );
-</programlisting>
-
-<para>The return value is is one of the following:</para>
-
-<programlisting role="C">
- GTK_VISIBILITY_NONE
- GTK_VISIBILITY_PARTIAL
- GTK_VISIBILITY_FULL
-</programlisting>
-
-<para>Note that it will only tell us if a row is visible. Currently there is
-no way to determine this for a column. We can get partial information
-though, because if the return is <literal>GTK_VISIBILITY_PARTIAL</literal>, then
-some of it is hidden, but we don't know if it is the row that is being
-cut by the lower edge of the listbox, or if the row has columns that
-are outside.</para>
-
-<para>We can also change both the foreground and background colors of a
-particular row. This is useful for marking the row selected by the
-user, and the two functions that is used to do it are</para>
-
-<programlisting role="C">
-void gtk_clist_set_foreground( GtkCList *clist,
- gint row,
- GdkColor *color );
-
-void gtk_clist_set_background( GtkCList *clist,
- gint row,
- GdkColor *color );
-</programlisting>
-
-<para>Please note that the colors must have been previously allocated.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-AddingRowsToTheList">
-<title>Adding rows to the list</title>
-
-<para>We can add rows in three ways. They can be prepended or appended to
-the list using</para>
-
-<programlisting role="C">
-gint gtk_clist_prepend( GtkCList *clist,
- gchar *text[] );
-
-gint gtk_clist_append( GtkCList *clist,
- gchar *text[] );
-</programlisting>
-
-<para>The return value of these two functions indicate the index of the row
-that was just added. We can insert a row at a given place using</para>
-
-<programlisting role="C">
-void gtk_clist_insert( GtkCList *clist,
- gint row,
- gchar *text[] );
-</programlisting>
-
-<para>In these calls we have to provide a collection of pointers that are
-the texts we want to put in the columns. The number of pointers should
-equal the number of columns in the list. If the text[] argument is
-NULL, then there will be no text in the columns of the row. This is
-useful, for example, if we want to add pixmaps instead (something that
-has to be done manually).</para>
-
-<para>Also, please note that the numbering of both rows and columns start at 0.</para>
-
-<para>To remove an individual row we use</para>
-
-<programlisting role="C">
-void gtk_clist_remove( GtkCList *clist,
- gint row );
-</programlisting>
-
-<para>There is also a call that removes all rows in the list. This is a lot
-faster than calling gtk_clist_remove once for each row, which is the
-only alternative.</para>
-
-<programlisting role="C">
-void gtk_clist_clear( GtkCList *clist );
-</programlisting>
-
-<para>There are also two convenience functions that should be used when a
-lot of changes have to be made to the list. This is to prevent the
-list flickering while being repeatedly updated, which may be highly
-annoying to the user. So instead it is a good idea to freeze the list,
-do the updates to it, and finally thaw it which causes the list to be
-updated on the screen.</para>
-
-<programlisting role="C">
-void gtk_clist_freeze( GtkCList * clist );
-
-void gtk_clist_thaw( GtkCList * clist );
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-SettingTextAndPixmapsInTheCells">
-<title>Setting text and pixmaps in the cells</title>
-
-<para>A cell can contain a pixmap, text or both. To set them the following
-functions are used.</para>
-
-<programlisting role="C">
-void gtk_clist_set_text( GtkCList *clist,
- gint row,
- gint column,
- const gchar *text );
-
-void gtk_clist_set_pixmap( GtkCList *clist,
- gint row,
- gint column,
- GdkPixmap *pixmap,
- GdkBitmap *mask );
-
-void gtk_clist_set_pixtext( GtkCList *clist,
- gint row,
- gint column,
- gchar *text,
- guint8 spacing,
- GdkPixmap *pixmap,
- GdkBitmap *mask );
-</programlisting>
-
-<para>It's quite straightforward. All the calls have the CList as the first
-argument, followed by the row and column of the cell, followed by the
-data to be set. The <literal>spacing</literal> argument in gtk_clist_set_pixtext is
-the number of pixels between the pixmap and the beginning of the
-text. In all cases the data is copied into the widget.</para>
-
-<para>To read back the data, we instead use</para>
-
-<programlisting role="C">
-gint gtk_clist_get_text( GtkCList *clist,
- gint row,
- gint column,
- gchar **text );
-
-gint gtk_clist_get_pixmap( GtkCList *clist,
- gint row,
- gint column,
- GdkPixmap **pixmap,
- GdkBitmap **mask );
-
-gint gtk_clist_get_pixtext( GtkCList *clist,
- gint row,
- gint column,
- gchar **text,
- guint8 *spacing,
- GdkPixmap **pixmap,
- GdkBitmap **mask );
-</programlisting>
-
-<para>The returned pointers are all pointers to the data stored within the
-widget, so the referenced data should not be modified or released. It
-isn't necessary to read it all back in case you aren't interested. Any
-of the pointers that are meant for return values (all except the
-clist) can be NULL. So if we want to read back only the text from a
-cell that is of type pixtext, then we would do the following, assuming
-that clist, row and column already exist:</para>
-
-<programlisting role="C">
-gchar *mytext;
-
-gtk_clist_get_pixtext(clist, row, column, &mytext, NULL, NULL, NULL);
-</programlisting>
-
-<para>There is one more call that is related to what's inside a cell in the
-clist, and that's</para>
-
-<programlisting role="C">
-GtkCellType gtk_clist_get_cell_type( GtkCList *clist,
- gint row,
- gint column );
-</programlisting>
-
-<para>which returns the type of data in a cell. The return value is one of</para>
-
-<programlisting role="C">
- GTK_CELL_EMPTY
- GTK_CELL_TEXT
- GTK_CELL_PIXMAP
- GTK_CELL_PIXTEXT
- GTK_CELL_WIDGET
-</programlisting>
-
-<para>There is also a function that will let us set the indentation, both
-vertical and horizontal, of a cell. The indentation value is of type
-gint, given in pixels, and can be both positive and negative.</para>
-
-<programlisting role="C">
-void gtk_clist_set_shift( GtkCList *clist,
- gint row,
- gint column,
- gint vertical,
- gint horizontal );
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-StoringDataPointers">
-<title>Storing data pointers</title>
-
-<para>With a CList it is possible to set a data pointer for a row. This
-pointer will not be visible for the user, but is merely a convenience
-for the programmer to associate a row with a pointer to some
-additional data.</para>
-
-<para>The functions should be fairly self-explanatory by now.</para>
-
-<programlisting role="C">
-void gtk_clist_set_row_data( GtkCList *clist,
- gint row,
- gpointer data );
-
-oid gtk_clist_set_row_data_full( GtkCList *clist,
- gint row,
- gpointer data,
- GtkDestroyNotify destroy );
-
-gpointer gtk_clist_get_row_data( GtkCList *clist,
- gint row );
-
-gint gtk_clist_find_row_from_data( GtkCList *clist,
- gpointer data );
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-WorkingWithSelections">
-<title>Working with selections</title>
-
-<para>There are also functions available that let us force the (un)selection
-of a row. These are</para>
-
-<programlisting role="C">
-void gtk_clist_select_row( GtkCList *clist,
- gint row,
- gint column );
-
-void gtk_clist_unselect_row( GtkCList *clist,
- gint row,
- gint column );
-</programlisting>
-
-<para>And also a function that will take x and y coordinates (for example,
-read from the mousepointer), and map that onto the list, returning the
-corresponding row and column.</para>
-
-<programlisting role="C">
-gint gtk_clist_get_selection_info( GtkCList *clist,
- gint x,
- gint y,
- gint *row,
- gint *column );
-</programlisting>
-
-<para>When we detect something of interest (it might be movement of the
-pointer, a click somewhere in the list) we can read the pointer
-coordinates and find out where in the list the pointer is. Cumbersome?
-Luckily, there is a simpler way...</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-TheSignalsThatBringItTogether">
-<title>The signals that bring it together</title>
-
-<para>As with all other widgets, there are a few signals that can be used. The
-CList widget is derived from the Container widget, and so has all the
-same signals, but also adds the following:</para>
-
-<itemizedlist>
-<listitem><simpara>select_row - This signal will send the following information, in
-order: GtkCList *clist, gint row, gint column, GtkEventButton *event</simpara>
-</listitem>
-
-<listitem><simpara>unselect_row - When the user unselects a row, this signal is
-activated. It sends the same information as select_row<</simpara>
-</listitem>
-
-<listitem><simpara>click_column - Send GtkCList *clist, gint column</simpara>
-</listitem>
-</itemizedlist>
-
-<para>So if we want to connect a callback to select_row, the callback
-function would be declared like this</para>
-
-<programlisting role="C">
-void select_row_callback(GtkWidget *widget,
- gint row,
- gint column,
- GdkEventButton *event,
- gpointer data);
-</programlisting>
-
-<para>The callback is connected as usual with</para>
-
-<programlisting role="C">
-gtk_signal_connect(GTK_OBJECT( clist),
- "select_row",
- GTK_SIGNAL_FUNC(select_row_callback),
- NULL);
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-ACListExample">
-<title>A CList example</title>
-
-<programlisting role="C">
-<!-- example-start clist clist.c -->
-
-#include <gtk/gtk.h>
-
-/* User clicked the "Add List" button. */
-void button_add_clicked( gpointer data )
-{
- int indx;
-
- /* Something silly to add to the list. 4 rows of 2 columns each */
- gchar *drink[4][2] = { { "Milk", "3 Oz" },
- { "Water", "6 l" },
- { "Carrots", "2" },
- { "Snakes", "55" } };
-
- /* Here we do the actual adding of the text. It's done once for
- * each row.
- */
- for ( indx=0 ; indx < 4 ; indx++ )
- gtk_clist_append( (GtkCList *) data, drink[indx]);
-
- return;
-}
-
-/* User clicked the "Clear List" button. */
-void button_clear_clicked( gpointer data )
-{
- /* Clear the list using gtk_clist_clear. This is much faster than
- * calling gtk_clist_remove once for each row.
- */
- gtk_clist_clear( (GtkCList *) data);
-
- return;
-}
-
-/* The user clicked the "Hide/Show titles" button. */
-void button_hide_show_clicked( gpointer data )
-{
- /* Just a flag to remember the status. 0 = currently visible */
- static short int flag = 0;
-
- if (flag == 0)
- {
- /* Hide the titles and set the flag to 1 */
- gtk_clist_column_titles_hide((GtkCList *) data);
- flag++;
- }
- else
- {
- /* Show the titles and reset flag to 0 */
- gtk_clist_column_titles_show((GtkCList *) data);
- flag--;
- }
-
- return;
-}
-
-/* If we come here, then the user has selected a row in the list. */
-void selection_made( GtkWidget *clist,
- gint row,
- gint column,
- GdkEventButton *event,
- gpointer data )
-{
- gchar *text;
-
- /* Get the text that is stored in the selected row and column
- * which was clicked in. We will receive it as a pointer in the
- * argument text.
- */
- gtk_clist_get_text(GTK_CLIST(clist), row, column, &text);
-
- /* Just prints some information about the selected row */
- g_print("You selected row %d. More specifically you clicked in "
- "column %d, and the text in this cell is %s\n\n",
- row, column, text);
-
- return;
-}
-
-int main( int argc,
- gchar *argv[] )
-{
- GtkWidget *window;
- GtkWidget *vbox, *hbox;
- GtkWidget *scrolled_window, *clist;
- GtkWidget *button_add, *button_clear, *button_hide_show;
- gchar *titles[2] = { "Ingredients", "Amount" };
-
- gtk_init(&argc, &argv);
-
- window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_widget_set_size_request (GTK_WIDGET (window), 300, 150);
-
- gtk_window_set_title(GTK_WINDOW(window), "GtkCList Example");
- gtk_signal_connect(GTK_OBJECT(window),
- "destroy",
- GTK_SIGNAL_FUNC(gtk_main_quit),
- NULL);
-
- vbox=gtk_vbox_new(FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
- gtk_container_add(GTK_CONTAINER(window), vbox);
- gtk_widget_show(vbox);
-
- /* Create a scrolled window to pack the CList widget into */
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-
- gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
- gtk_widget_show (scrolled_window);
-
- /* Create the CList. For this example we use 2 columns */
- clist = gtk_clist_new_with_titles( 2, titles);
-
- /* When a selection is made, we want to know about it. The callback
- * used is selection_made, and its code can be found further down */
- gtk_signal_connect(GTK_OBJECT(clist), "select_row",
- GTK_SIGNAL_FUNC(selection_made),
- NULL);
-
- /* It isn't necessary to shadow the border, but it looks nice :) */
- gtk_clist_set_shadow_type (GTK_CLIST(clist), GTK_SHADOW_OUT);
-
- /* What however is important, is that we set the column widths as
- * they will never be right otherwise. Note that the columns are
- * numbered from 0 and up (to 1 in this case).
- */
- gtk_clist_set_column_width (GTK_CLIST(clist), 0, 150);
-
- /* Add the CList widget to the vertical box and show it. */
- gtk_container_add(GTK_CONTAINER(scrolled_window), clist);
- gtk_widget_show(clist);
-
- /* Create the buttons and add them to the window. See the button
- * tutorial for more examples and comments on this.
- */
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
- gtk_widget_show(hbox);
-
- button_add = gtk_button_new_with_label("Add List");
- button_clear = gtk_button_new_with_label("Clear List");
- button_hide_show = gtk_button_new_with_label("Hide/Show titles");
-
- gtk_box_pack_start(GTK_BOX(hbox), button_add, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), button_clear, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), button_hide_show, TRUE, TRUE, 0);
-
- /* Connect our callbacks to the three buttons */
- gtk_signal_connect_object(GTK_OBJECT(button_add), "clicked",
- GTK_SIGNAL_FUNC(button_add_clicked),
- (gpointer) clist);
- gtk_signal_connect_object(GTK_OBJECT(button_clear), "clicked",
- GTK_SIGNAL_FUNC(button_clear_clicked),
- (gpointer) clist);
- gtk_signal_connect_object(GTK_OBJECT(button_hide_show), "clicked",
- GTK_SIGNAL_FUNC(button_hide_show_clicked),
- (gpointer) clist);
-
- gtk_widget_show(button_add);
- gtk_widget_show(button_clear);
- gtk_widget_show(button_hide_show);
-
- /* The interface is completely set up so we show the window and
- * enter the gtk_main loop.
- */
- gtk_widget_show(window);
- gtk_main();
-
- return(0);
-}
-<!-- example-end -->
-</programlisting>
-
-</sect1>
-</chapter>
-
-<!-- ***************************************************************** -->
-<chapter id="ch-CTreeWidget">
-<title>CTree Widget</title>
-
-<!-- ----------------------------------------------------------------- -->
-<para>The CTree widget is derived from the CList widget. It is designed to
-display hierarchically-organised data. The tree is displayed
-vertically, and branches of the tree can be clapsed and expanded as
-required by the user.</para>
-
-<para>This section of the tutorial is under development.</para>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-CreatingACTree">
-<title>Creating a CTree</title>
-
-<para>A CTree, being derived from CList, can have multiple columns. These
-columns optionally have titles that are displayed along the top of
-the CTree widget. Hence there are two functions for creating a new
-CTree widget:</para>
-
-<programlisting role="C">
-GtkWidget *gtk_ctree_new_with_titles( gint columns,
- gint tree_column,
- gchar *titles[] );
-
-GtkWidget *gtk_ctree_new( gint columns,
- gint tree_column );
-</programlisting>
-
-<para>The <literal>columns</literal> argument specifies the number of columns that the
-CTree will contain. The <literal>tree_column</literal> argumnet specifies which of
-those columns is to contain the tree. Columns are numbered starting
-from 0.</para>
-
-<para>With the first funtion above, the <literal>titles</literal> argument contains an
-array of strings that contain the captions for the column headings. A
-typical code fragment using the <literal>gtk_ctree_new_with_titles()</literal>
-function would be:</para>
-
-<programlisting role="C">
- /* CTree column titles /*
- char *titles[] = { "Location" , "Description" };
- GtkWidget *ctree;
-
- ctree = gtk_ctree_new_with_titles(2, 0, titles);
-</programlisting>
-
-<para>This would create a new CTree with two columns entitled "Location"
-and "Description", with the first column containing the tree.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-AddingAndRemovingNodes">
-<title>Adding and Removing nodes</title>
-
-<para>The items in a CTree are termed <emphasis>nodes</emphasis>. Nodes are inserted
-into a CTree in such a way as to create a hierarchy (although the
-order of insertion is not critical). The following function is used to
-insert a node:</para>
-
-<programlisting role="C">
-GtkCTreeNode *gtk_ctree_insert_node( GtkCTree *ctree,
- GtkCTreeNode *parent,
- GtkCTreeNode *sibling,
- gchar *text[],
- guint8 spacing,
- GdkPixmap *pixmap_closed,
- GdkBitmap *mask_closed,
- GdkPixmap *pixmap_opened,
- GdkBitmap *mask_opened,
- gboolean is_leaf,
- gboolean expanded );
-</programlisting>
-
-<para>This function looks a little daunting, but that is merely due to the
-power of the CTreee widget. Not all of the parameters above are
-required.</para>
-
-<para>The CTree widget allows you to specify pixmaps to display in each
-node. For branch nodes, you can specify different pixmaps for when the
-branch is collapsed or expanded. This gives a nice visual feedback to
-the user, but it is optional so you don't have to specify pixmaps.</para>
-
-<para>Lets have a quick look at all of the parameters:</para>
-
-<itemizedlist>
-<listitem><simpara> <literal>ctree</literal> - the CTree widget we are manipulating</simpara>
-</listitem>
-
-<listitem><simpara> <literal>parent</literal> - the parent node of the one we are inserting. May
- be <literal>NULL</literal> for a root-level (i.e. initial)
- node.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>sibling</literal> - a sibling of the node we are inserting. May be
- <literal>NULL</literal> if there are no siblings.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>text</literal> - the textual contents of each column in the tree for
- this node. This array <emphasis>must</emphasis> have an entry
- for each column, even if it is an empty string.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>spacing</literal> - specifies the padding between the nodes pixmap
- and text elements, if a pixmap is provided</simpara>
-</listitem>
-
-<listitem><simpara> <literal>pixmap_closed</literal> - a pixmap to display for a collapsed branch
- node and for a leaf node.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>mask_closed</literal> - a bitmap mask for the above pixmap.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>pixmap_opened</literal> - a pixmap to display for an expanded
- branch node.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>mask_opened</literal> - a bitmap mask for the above pixmap.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>is_leaf</literal> - indicates whether this is a leaf or branch node.</simpara>
-</listitem>
-
-<listitem><simpara> <literal>expanded</literal> - indicates whether a branch node is initially
- expanded or collapsed.</simpara>
-</listitem>
-</itemizedlist>
-
-<para>An object pointer of type GtkCTreeNode is returned by the
-gtk_ctree_insert_node() function. This object pointer is used to
-reference the node when manipulating it. The node pointer is also
-supplied by many of the CTree signals to identify which node the
-signal pertains to.</para>
-
-<para>To remove a node for a CTree, the following function is provided:</para>
-
-<programlisting role="C">
-void gtk_ctree_remove_node( GtkCTree *ctree,
- GtkCTreeNode *node );
-</programlisting>
-
-<para>As you can see, you merely need to specify a CTree and the node to
-remove.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-SettingCTreeAttributes">
-<title>Setting CTree Attributes</title>
-
-<para>There are a number of functions that set options that pertain to a
-CTree instance as a whole (rather than to a particular node). The
-first group set padding attributes that effect how the widget is drawn:</para>
-
-<programlisting role="C">
-void gtk_ctree_set_indent( GtkCTree *ctree,
- gint indent );
-
-void gtk_ctree_set_spacing( GtkCTree *ctree,
- gint spacing );
-</programlisting>
-
-<para>The function <literal>gtk_ctree_set_indent()</literal> sets how far a new branch is
-indented in relation to it's parent. The default is 20.</para>
-
-<para>The function <literal>gtk_ctree_set_spacing()</literal> sets how far a node is
-horizontally padded from the vertical line that is drawn linking the
-nodes of each branch. The default is 5.</para>
-
-<para>The next two functions affect the style of the lines and expander that
-are drawn to represent the tree structure. An expander is a grpahical
-component that the user can select to expand and collapse a branch of
-the tree.</para>
-
-<programlisting role="C">
-void gtk_ctree_set_line_style( GtkCTree *ctree,
- GtkCTreeLineStyle line_style );
-
-void gtk_ctree_set_expander_style( GtkCTree *ctree,
- GtkCTreeExpanderStyle expander_style );
-</programlisting>
-
-<para>The function <literal>gtk_ctree_set_line_style()</literal> is used to select the style
-of line that is drawn between nodes of the tree. The parameter
-<literal>line_style</literal> can be one of:</para>
-
-<programlisting role="C">
- GTK_CTREE_LINES_NONE
- GTK_CTREE_LINES_SOLID
- GTK_CTREE_LINES_DOTTED
- GTK_CTREE_LINES_TABBED
-</programlisting>
-
-<para>The function <literal>gtk_ctree_set_expander_style()</literal> is used to select
-the style of branch expander, and the parameter <literal>expander_style</literal>
-can be one of:</para>
-
-<programlisting role="C">
- GTK_CTREE_EXPANDER_NONE
- GTK_CTREE_EXPANDER_SQUARE
- GTK_CTREE_EXPANDER_TRIANGLE
- GTK_CTREE_EXPANDER_CIRCULAR
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-UtilizingRowData">
-<title>Utilizing row data</title>
-
-<para>The CTree widget allows you to associate data with each node of the
-tree. This is most often used in callback functions, such as when a
-row is selected.</para>
-
-<para>Although only a single data element can be stored for each row, this
-data element can be any variable or data structure, which indirectly
-allows a set of data to be referenced.</para>
-
-<para>There are two functions for setting row data:</para>
-
-<programlisting role="C">
-void gtk_ctree_node_set_row_data( GtkCTree *ctree,
- GtkCTreeNode *node,
- gpointer data );
-
-void gtk_ctree_node_set_row_data_full( GtkCTree *ctree,
- GtkCTreeNode *node,
- gpointer data,
- GtkDestroyNotify destroy );
-</programlisting>
-
-<para>The function <literal>gtk_ctree_node_set_row_data()</literal> simply takes as
-arguments pointers to the CTree, node and data.</para>
-
-<para>The function <literal>gtk_ctree_node_set_row_data_full()</literal> takes an
-additional parameter, <literal>destroy</literal>. This parameter is a pointer to a
-function that will be called when the row is destroyed. Typically,
-this function would take responsibility for freeing the memory used by
-the row data. This function should take the form:</para>
-
-<programlisting role="C">
-void destroy_func( gpointer data );
-</programlisting>
-
-<para>The paramter passed to this function will be the row data.</para>
-
-</sect1>
-</chapter>
-
-<!-- ***************************************************************** -->
-<chapter id="ch-TreeWidget">
-<title>Tree Widget</title>
-
-<!-- ----------------------------------------------------------------- -->
-
-<para>The purpose of tree widgets is to display hierarchically-organized
-data. The Tree widget itself is a vertical container for widgets of
-type TreeItem. Tree itself is not terribly different from
-CList - both are derived directly from Container, and the
-Container methods work in the same way on Tree widgets as on
-CList widgets. The difference is that Tree widgets can be nested
-within other Tree widgets. We'll see how to do this shortly.</para>
-
-<para>The Tree widget has its own window, and defaults to a white
-background, as does CList. Also, most of the Tree methods work in
-the same way as the corresponding CList ones. However, Tree is
-not derived from CList, so you cannot use them interchangeably.</para>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-CreatingATree">
-<title>Creating a Tree</title>
-
-<para>A Tree is created in the usual way, using:</para>
-
-<programlisting role="C">
-GtkWidget *gtk_tree_new( void );
-</programlisting>
-
-<para>Like the CList widget, a Tree will simply keep growing as more
-items are added to it, as well as when subtrees are expanded. For
-this reason, they are almost always packed into a
-ScrolledWindow. You might want to use gtk_widget_set_size_request() on the
-scrolled window to ensure that it is big enough to see the tree's
-items, as the default size for ScrolledWindow is quite small.</para>
-
-<para>Now that you have a tree, you'll probably want to add some items to
-it. <link linkend="sec-TreeItemWidget">The Tree Item Widget</link> below
-explains the gory details of TreeItem. For now, it'll suffice to
-create one, using:</para>
-
-<programlisting role="C">
-GtkWidget *gtk_tree_item_new_with_label( gchar *label );
-</programlisting>
-
-<para>You can then add it to the tree using one of the following (see
-<link linkend="sec-TreeFunctionsAndMacros">Functions and Macros</link>
-below for more options):</para>
-
-<programlisting role="C">
-void gtk_tree_append( GtkTree *tree,
- GtkWidget *tree_item );
-
-void gtk_tree_prepend( GtkTree *tree,
- GtkWidget *tree_item );
-</programlisting>
-
-<para>Note that you must add items to a Tree one at a time - there is no
-equivalent to gtk_list_*_items().</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-AddingASubtree">
-<title>Adding a Subtree</title>
-
-<para>A subtree is created like any other Tree widget. A subtree is added
-to another tree beneath a tree item, using:</para>
-
-<programlisting role="C">
-void gtk_tree_item_set_subtree( GtkTreeItem *tree_item,
- GtkWidget *subtree );
-</programlisting>
-
-<para>You do not need to call gtk_widget_show() on a subtree before or after
-adding it to a TreeItem. However, you <emphasis>must</emphasis> have added the
-TreeItem in question to a parent tree before calling
-gtk_tree_item_set_subtree(). This is because, technically, the parent
-of the subtree is <emphasis>not</emphasis> the GtkTreeItem which "owns" it, but
-rather the GtkTree which holds that GtkTreeItem.</para>
-
-<para>When you add a subtree to a TreeItem, a plus or minus sign appears
-beside it, which the user can click on to "expand" or "collapse" it,
-meaning, to show or hide its subtree. TreeItems are collapsed by
-default. Note that when you collapse a TreeItem, any selected
-items in its subtree remain selected, which may not be what the user
-expects.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-HandlingTheSelectionList">
-<title>Handling the Selection List</title>
-
-<para>As with CList, the Tree type has a <literal>selection</literal> field, and
-it is possible to control the behaviour of the tree (somewhat) by
-setting the selection type using:</para>
-
-<programlisting role="C">
-void gtk_tree_set_selection_mode( GtkTree *tree,
- GtkSelectionMode mode );
-</programlisting>
-
-<para>The semantics associated with the various selection modes are
-described in the section on the CList widget. As with the CList
-widget, the "select_child", "unselect_child" (not really - see <link
-linkend="sec-TreeSignals">Signals</link> below for an explanation),
-and "selection_changed" signals are emitted when list items are
-selected or unselected. However, in order to take advantage of these
-signals, you need to know <emphasis>which</emphasis> Tree widget they will be
-emitted by, and where to find the list of selected items.</para>
-
-<para>This is a source of potential confusion. The best way to explain this
-is that though all Tree widgets are created equal, some are more equal
-than others. All Tree widgets have their own X window, and can
-therefore receive events such as mouse clicks (if their TreeItems or
-their children don't catch them first!). However, to make
-<literal>GTK_SELECTION_SINGLE</literal> and <literal>GTK_SELECTION_BROWSE</literal> selection
-types behave in a sane manner, the list of selected items is specific
-to the topmost Tree widget in a hierarchy, known as the "root tree".</para>
-
-<para>Thus, accessing the <literal>selection</literal> field directly in an arbitrary
-Tree widget is not a good idea unless you <emphasis>know</emphasis> it's the root
-tree. Instead, use the <literal>GTK_TREE_SELECTION_OLD (Tree)</literal> macro, which
-gives the root tree's selection list as a GList pointer. Of course,
-this list can include items that are not in the subtree in question if
-the selection type is <literal>GTK_SELECTION_MULTIPLE</literal>.</para>
-
-<para>Finally, the "select_child" (and "unselect_child", in theory) signals
-are emitted by all trees, but the "selection_changed" signal is only
-emitted by the root tree. Consequently, if you want to handle the
-"select_child" signal for a tree and all its subtrees, you will have
-to call gtk_signal_connect() for every subtree.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-TreeWidgetInternals">
-<title>Tree Widget Internals</title>
-
-<para>The Tree's struct definition looks like this:</para>
-
-<programlisting role="C">
-struct _GtkTree
-{
- GtkContainer container;
-
- GList *children;
-
- GtkTree* root_tree; /* owner of selection list */
- GtkWidget* tree_owner;
- GList *selection;
- guint level;
- guint indent_value;
- guint current_indent;
- guint selection_mode : 2;
- guint view_mode : 1;
- guint view_line : 1;
-};
-</programlisting>
-
-<para>The perils associated with accessing the <literal>selection</literal> field
-directly have already been mentioned. The other important fields of
-the struct can also be accessed with handy macros or class functions.
-<literal>GTK_IS_ROOT_TREE (Tree)</literal> returns a boolean value which
-indicates whether a tree is the root tree in a Tree hierarchy, while
-<literal>GTK_TREE_ROOT_TREE (Tree)</literal> returns the root tree, an object of
-type GtkTree (so, remember to cast it using <literal>GTK_WIDGET (Tree)</literal> if
-you want to use one of the gtk_widget_*() functions on it).</para>
-
-<para>Instead of directly accessing the children field of a Tree widget,
-it's probably best to cast it using >tt/GTK_CONTAINER (Tree)/, and
-pass it to the gtk_container_children() function. This creates a
-duplicate of the original list, so it's advisable to free it up using
-g_list_free() after you're done with it, or to iterate on it
-destructively, like this:</para>
-
-<programlisting role="C">
- children = gtk_container_children (GTK_CONTAINER (tree));
- while (children) {
- do_something_nice (GTK_TREE_ITEM (children->data));
- children = g_list_remove_link (children, children);
-}
-</programlisting>
-
-<para>The <literal>tree_owner</literal> field is defined only in subtrees, where it
-points to the TreeItem widget which holds the tree in question.
-The <literal>level</literal> field indicates how deeply nested a particular tree
-is; root trees have level 0, and each successive level of subtrees has
-a level one greater than the parent level. This field is set only
-after a Tree widget is actually mapped (i.e. drawn on the screen).</para>
-
-<!-- ----------------------------------------------------------------- -->
-<sect2 id="sec-TreeSignals">
-<title>Signals</title>
-
-<programlisting role="C">
-void selection_changed( GtkTree *tree );
-</programlisting>
-
-<para>This signal will be emitted whenever the <literal>selection</literal> field of a
-Tree has changed. This happens when a child of the Tree is
-selected or deselected.</para>
-
-<programlisting role="C">
-void select_child( GtkTree *tree,
- GtkWidget *child );
-</programlisting>
-
-<para>This signal is emitted when a child of the Tree is about to get
-selected. This happens on calls to gtk_tree_select_item(),
-gtk_tree_select_child(), on <emphasis>all</emphasis> button presses and calls to
-gtk_tree_item_toggle() and gtk_item_toggle(). It may sometimes be
-indirectly triggered on other occasions where children get added to or
-removed from the Tree.</para>
-
-<programlisting role="C">
-void unselect_child (GtkTree *tree,
- GtkWidget *child);
-</programlisting>
-
-<para>This signal is emitted when a child of the Tree is about to get
-deselected. As of GTK 1.0.4, this seems to only occur on calls to
-gtk_tree_unselect_item() or gtk_tree_unselect_child(), and perhaps on
-other occasions, but <emphasis>not</emphasis> when a button press deselects a
-child, nor on emission of the "toggle" signal by gtk_item_toggle().</para>
-
-</sect2>
-
-<!-- ----------------------------------------------------------------- -->
-<sect2 id="sec-TreeFunctionsAndMacros">
-<title>Functions and Macros</title>
-
-<programlisting role="C">
-guint gtk_tree_get_type( void );
-</programlisting>
-
-<para>Returns the "GtkTree" type identifier.</para>
-
-<programlisting role="C">
-GtkWidget* gtk_tree_new( void );
-</programlisting>
-
-<para>Create a new Tree object. The new widget is returned as a pointer to a
-GtkWidget object. NULL is returned on failure.</para>
-
-<programlisting role="C">
-void gtk_tree_append( GtkTree *tree,
- GtkWidget *tree_item );
-</programlisting>
-
-<para>Append a tree item to a Tree.</para>
-
-<programlisting role="C">
-void gtk_tree_prepend( GtkTree *tree,
- GtkWidget *tree_item );
-</programlisting>
-
-<para>Prepend a tree item to a Tree.</para>
-
-<programlisting role="C">
-void gtk_tree_insert( GtkTree *tree,
- GtkWidget *tree_item,
- gint position );
-</programlisting>
-
-<para>Insert a tree item into a Tree at the position in the list
-specified by <literal>position.</literal></para>
-
-<programlisting role="C">
-void gtk_tree_remove_items( GtkTree *tree,
- GList *items );
-</programlisting>
-
-<para>Remove a list of items (in the form of a GList *) from a Tree.
-Note that removing an item from a tree dereferences (and thus usually)
-destroys it <emphasis>and</emphasis> its subtree, if it has one, <emphasis>and</emphasis> all
-subtrees in that subtree. If you want to remove only one item, you
-can use gtk_container_remove().</para>
-
-<programlisting role="C">
-void gtk_tree_clear_items( GtkTree *tree,
- gint start,
- gint end );
-</programlisting>
-
-<para>Remove the items from position <literal>start</literal> to position <literal>end</literal>
-from a Tree. The same warning about dereferencing applies here, as
-gtk_tree_clear_items() simply constructs a list and passes it to
-gtk_tree_remove_items().</para>
-
-<programlisting role="C">
-void gtk_tree_select_item( GtkTree *tree,
- gint item );
-</programlisting>
-
-<para>Emits the "select_item" signal for the child at position
-<literal>item</literal>, thus selecting the child (unless you unselect it in a
-signal handler).</para>
-
-<programlisting role="C">
-void gtk_tree_unselect_item( GtkTree *tree,
- gint item );
-</programlisting>
-
-<para>Emits the "unselect_item" signal for the child at position
-<literal>item</literal>, thus unselecting the child.</para>
-
-<programlisting role="C">
-void gtk_tree_select_child( GtkTree *tree,
- GtkWidget *tree_item );
-</programlisting>
-
-<para>Emits the "select_item" signal for the child <literal>tree_item</literal>, thus
-selecting it.</para>
-
-<programlisting role="C">
-void gtk_tree_unselect_child( GtkTree *tree,
- GtkWidget *tree_item );
-</programlisting>
-
-<para>Emits the "unselect_item" signal for the child <literal>tree_item</literal>,
-thus unselecting it.</para>
-
-<programlisting role="C">
-gint gtk_tree_child_position( GtkTree *tree,
- GtkWidget *child );
-</programlisting>
-
-<para>Returns the position in the tree of <literal>child</literal>, unless
-<literal>child</literal> is not in the tree, in which case it returns -1.</para>
-
-<programlisting role="C">
-void gtk_tree_set_selection_mode( GtkTree *tree,
- GtkSelectionMode mode );
-</programlisting>
-
-<para>Sets the selection mode, which can be one of <literal>GTK_SELECTION_SINGLE</literal> (the
-default), <literal>GTK_SELECTION_BROWSE</literal>, <literal>GTK_SELECTION_MULTIPLE</literal>, or
-<literal>GTK_SELECTION_EXTENDED</literal>. This is only defined for root trees, which
-makes sense, since the root tree "owns" the selection. Setting it for
-subtrees has no effect at all; the value is simply ignored.</para>
-
-<programlisting role="C">
-void gtk_tree_set_view_mode( GtkTree *tree,
- GtkTreeViewMode mode );
-</programlisting>
-
-<para>Sets the "view mode", which can be either <literal>GTK_TREE_VIEW_LINE</literal> (the
-default) or <literal>GTK_TREE_VIEW_ITEM</literal>. The view mode propagates from a
-tree to its subtrees, and can't be set exclusively to a subtree (this
-is not exactly true - see the example code comments).</para>
-
-<para>The term "view mode" is rather ambiguous - basically, it controls the
-way the highlight is drawn when one of a tree's children is selected.
-If it's <literal>GTK_TREE_VIEW_LINE</literal>, the entire TreeItem widget is
-highlighted, while for <literal>GTK_TREE_VIEW_ITEM</literal>, only the child widget
-(i.e., usually the label) is highlighted.</para>
-
-<programlisting role="C">
-void gtk_tree_set_view_lines( GtkTree *tree,
- guint flag );
-</programlisting>
-
-<para>Controls whether connecting lines between tree items are drawn.
-<literal>flag</literal> is either TRUE, in which case they are, or FALSE, in
-which case they aren't.</para>
-
-<programlisting role="C">
-GtkTree *GTK_TREE (gpointer obj);
-</programlisting>
-
-<para>Cast a generic pointer to "GtkTree *".</para>
-
-<programlisting role="C">
-GtkTreeClass *GTK_TREE_CLASS (gpointer class);
-</programlisting>
-
-<para>Cast a generic pointer to "GtkTreeClass *".</para>
-
-<programlisting role="C">
-gint GTK_IS_TREE (gpointer obj);
-</programlisting>
-
-<para>Determine if a generic pointer refers to a "GtkTree" object.</para>
-
-<programlisting role="C">
-gint GTK_IS_ROOT_TREE (gpointer obj)
-</programlisting>
-
-<para>Determine if a generic pointer refers to a "GtkTree" object
-<emphasis>and</emphasis> is a root tree. Though this will accept any pointer, the
-results of passing it a pointer that does not refer to a Tree are
-undefined and possibly harmful.</para>
-
-<programlisting role="C">
-GtkTree *GTK_TREE_ROOT_TREE (gpointer obj)
-</programlisting>
-
-<para>Return the root tree of a pointer to a "GtkTree" object. The above
-warning applies.</para>
-
-<programlisting role="C">
-GList *GTK_TREE_SELECTION_OLD( gpointer obj)
-</programlisting>
-
-<para>Return the selection list of the root tree of a "GtkTree" object. The
-above warning applies here, too.</para>
-
-</sect2>
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-TreeItemWidget">
-<title>Tree Item Widget</title>
-
-<para>The TreeItem widget, like CListItem, is derived from Item,
-which in turn is derived from Bin. Therefore, the item itself is a
-generic container holding exactly one child widget, which can be of
-any type. The TreeItem widget has a number of extra fields, but
-the only one we need be concerned with is the <literal>subtree</literal> field.</para>
-
-<para>The definition for the TreeItem struct looks like this:</para>
-
-<programlisting role="C">
-struct _GtkTreeItem
-{
- GtkItem item;
-
- GtkWidget *subtree;
- GtkWidget *pixmaps_box;
- GtkWidget *plus_pix_widget, *minus_pix_widget;
-
- GList *pixmaps; /* pixmap node for this items color depth */
-
- guint expanded : 1;
-};
-</programlisting>
-
-<para>The <literal>pixmaps_box</literal> field is an EventBox which catches clicks on
-the plus/minus symbol which controls expansion and collapsing. The
-<literal>pixmaps</literal> field points to an internal data structure. Since
-you can always obtain the subtree of a TreeItem in a (relatively)
-type-safe manner with the <literal>GTK_TREE_ITEM_SUBTREE (Item)</literal> macro,
-it's probably advisable never to touch the insides of a TreeItem
-unless you <emphasis>really</emphasis> know what you're doing.</para>
-
-<para>Since it is directly derived from an Item it can be treated as such by
-using the <literal>GTK_ITEM (TreeItem)</literal> macro. A TreeItem usually holds a
-label, so the convenience function gtk_list_item_new_with_label() is
-provided. The same effect can be achieved using code like the
-following, which is actually copied verbatim from
-gtk_tree_item_new_with_label():</para>
-
-<programlisting role="C">
-tree_item = gtk_tree_item_new ();
-label_widget = gtk_label_new (label);
-gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
-
-gtk_container_add (GTK_CONTAINER (tree_item), label_widget);
-gtk_widget_show (label_widget);
-</programlisting>
-
-<para>As one is not forced to add a Label to a TreeItem, you could
-also add an HBox or an Arrow, or even a Notebook (though your
-app will likely be quite unpopular in this case) to the TreeItem.</para>
-
-<para>If you remove all the items from a subtree, it will be destroyed and
-unparented, unless you reference it beforehand, and the TreeItem
-which owns it will be collapsed. So, if you want it to stick around,
-do something like the following:</para>
-
-<programlisting role="C">
-gtk_widget_ref (tree);
-owner = GTK_TREE(tree)->tree_owner;
-gtk_container_remove (GTK_CONTAINER(tree), item);
-if (tree->parent == NULL){
- gtk_tree_item_expand (GTK_TREE_ITEM(owner));
- gtk_tree_item_set_subtree (GTK_TREE_ITEM(owner), tree);
-}
-else
- gtk_widget_unref (tree);
-</programlisting>
-
-<para>Finally, drag-n-drop <emphasis>does</emphasis> work with TreeItems. You just
-have to make sure that the TreeItem you want to make into a drag
-item or a drop site has not only been added to a Tree, but that
-each successive parent widget has a parent itself, all the way back to
-a toplevel or dialog window, when you call gtk_widget_dnd_drag_set()
-or gtk_widget_dnd_drop_set(). Otherwise, strange things will happen.</para>
-
-<!-- ----------------------------------------------------------------- -->
-<sect2>
-<title>Signals</title>
-
-<para>TreeItem inherits the "select", "deselect", and "toggle" signals
-from Item. In addition, it adds two signals of its own, "expand"
-and "collapse".</para>
-
-<programlisting role="C">
-void select( GtkItem *tree_item );
-</programlisting>
-
-<para>This signal is emitted when an item is about to be selected, either
-after it has been clicked on by the user, or when the program calls
-gtk_tree_item_select(), gtk_item_select(), or gtk_tree_select_child().</para>
-
-<programlisting role="C">
-void deselect( GtkItem *tree_item );
-</programlisting>
-
-<para>This signal is emitted when an item is about to be unselected, either
-after it has been clicked on by the user, or when the program calls
-gtk_tree_item_deselect() or gtk_item_deselect(). In the case of
-TreeItems, it is also emitted by gtk_tree_unselect_child(), and
-sometimes gtk_tree_select_child().</para>
-
-<programlisting role="C">
-void toggle( GtkItem *tree_item );
-</programlisting>
-
-<para>This signal is emitted when the program calls gtk_item_toggle(). The
-effect it has when emitted on a TreeItem is to call
-gtk_tree_select_child() (and never gtk_tree_unselect_child()) on the
-item's parent tree, if the item has a parent tree. If it doesn't,
-then the highlight is reversed on the item.</para>
-
-<programlisting role="C">
-void expand( GtkTreeItem *tree_item );
-</programlisting>
-
-<para>This signal is emitted when the tree item's subtree is about to be
-expanded, that is, when the user clicks on the plus sign next to the
-item, or when the program calls gtk_tree_item_expand().</para>
-
-<programlisting role="C">
-void collapse( GtkTreeItem *tree_item );
-</programlisting>
-
-<para>This signal is emitted when the tree item's subtree is about to be
-collapsed, that is, when the user clicks on the minus sign next to the
-item, or when the program calls gtk_tree_item_collapse().</para>
-
-</sect2>
-
-<!-- ----------------------------------------------------------------- -->
-<sect2>
-<title>Functions and Macros</title>
-
-<programlisting role="C">
-guint gtk_tree_item_get_type( void );
-</programlisting>
-
-<para>Returns the "GtkTreeItem" type identifier.</para>
-
-<programlisting role="C">
-GtkWidget* gtk_tree_item_new( void );
-</programlisting>
-
-<para>Create a new TreeItem object. The new widget is returned as a
-pointer to a GtkWidget object. NULL is returned on failure.</para>
-
-<programlisting role="C">
-GtkWidget* gtk_tree_item_new_with_label (gchar *label);
-</programlisting>
-
-<para>Create a new TreeItem object, having a single GtkLabel as the sole
-child. The new widget is returned as a pointer to a GtkWidget
-object. NULL is returned on failure.</para>
-
-<programlisting role="C">
-void gtk_tree_item_select( GtkTreeItem *tree_item );
-</programlisting>
-
-<para>This function is basically a wrapper around a call to
-<literal>gtk_item_select (GTK_ITEM (tree_item))</literal> which will emit the
-select signal.</para>
-
-<programlisting role="C">
-void gtk_tree_item_deselect( GtkTreeItem *tree_item );
-</programlisting>
-
-<para>This function is basically a wrapper around a call to
-gtk_item_deselect (GTK_ITEM (tree_item)) which will emit the deselect
-signal.</para>
-
-<programlisting role="C">
-void gtk_tree_item_set_subtree( GtkTreeItem *tree_item,
- GtkWidget *subtree );
-</programlisting>
-
-<para>This function adds a subtree to tree_item, showing it if tree_item is
-expanded, or hiding it if tree_item is collapsed. Again, remember that
-the tree_item must have already been added to a tree for this to work.</para>
-
-<programlisting role="C">
-void gtk_tree_item_remove_subtree( GtkTreeItem *tree_item );
-</programlisting>
-
-<para>This removes all of tree_item's subtree's children (thus unreferencing
-and destroying it, any of its children's subtrees, and so on...), then
-removes the subtree itself, and hides the plus/minus sign.</para>
-
-<programlisting role="C">
-void gtk_tree_item_expand( GtkTreeItem *tree_item );
-</programlisting>
-
-<para>This emits the "expand" signal on tree_item, which expands it.</para>
-
-<programlisting role="C">
-void gtk_tree_item_collapse( GtkTreeItem *tree_item );
-</programlisting>
-
-<para>This emits the "collapse" signal on tree_item, which collapses it.</para>
-
-<programlisting role="C">
-GtkTreeItem *GTK_TREE_ITEM (gpointer obj)
-</programlisting>
-
-<para>Cast a generic pointer to "GtkTreeItem *".</para>
-
-<programlisting role="C">
-GtkTreeItemClass *GTK_TREE_ITEM_CLASS (gpointer obj)
-</programlisting>
-
-<para>Cast a generic pointer to "GtkTreeItemClass".</para>
-
-<programlisting role="C">
-gint GTK_IS_TREE_ITEM (gpointer obj)
-</programlisting>
-
-<para>Determine if a generic pointer refers to a "GtkTreeItem" object.</para>
-
-<programlisting role="C">
-GtkWidget GTK_TREE_ITEM_SUBTREE (gpointer obj)
-</programlisting>
-
-<para>Returns a tree item's subtree (<literal>obj</literal> should point to a
-"GtkTreeItem" object).</para>
-
-</sect2>
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-TreeExample">
-<title>Tree Example</title>
-
-<para>This is somewhat like the tree example in testgtk.c, but a lot less
-complete (although much better commented). It puts up a window with a
-tree, and connects all the signals for the relevant objects, so you
-can see when they are emitted.</para>
-
-<programlisting role="C">
-<!-- example-start tree tree.c -->
-
-#define GTK_ENABLE_BROKEN
-#include <gtk/gtk.h>
-
-/* for all the GtkItem:: and GtkTreeItem:: signals */
-static void cb_itemsignal( GtkWidget *item,
- gchar *signame )
-{
- gchar *name;
- GtkLabel *label;
-
- /* It's a Bin, so it has one child, which we know to be a
- label, so get that */
- label = GTK_LABEL (GTK_BIN (item)->child);
- /* Get the text of the label */
- gtk_label_get (label, &name);
- /* Get the level of the tree which the item is in */
- g_print ("%s called for item %s->%p, level %d\n", signame, name,
- item, GTK_TREE (item->parent)->level);
-}
-
-/* Note that this is never called */
-static void cb_unselect_child( GtkWidget *root_tree,
- GtkWidget *child,
- GtkWidget *subtree )
-{
- g_print ("unselect_child called for root tree %p, subtree %p, child %p\n",
- root_tree, subtree, child);
-}
-
-/* Note that this is called every time the user clicks on an item,
- whether it is already selected or not. */
-static void cb_select_child (GtkWidget *root_tree, GtkWidget *child,
- GtkWidget *subtree)
-{
- g_print ("select_child called for root tree %p, subtree %p, child %p\n",
- root_tree, subtree, child);
-}
-
-static void cb_selection_changed( GtkWidget *tree )
-{
- GList *i;
-
- g_print ("selection_change called for tree %p\n", tree);
- g_print ("selected objects are:\n");
-
- i = GTK_TREE_SELECTION_OLD(tree);
- while (i){
- gchar *name;
- GtkLabel *label;
- GtkWidget *item;
-
- /* Get a GtkWidget pointer from the list node */
- item = GTK_WIDGET (i->data);
- label = GTK_LABEL (GTK_BIN (item)->child);
- gtk_label_get (label, &name);
- g_print ("\t%s on level %d\n", name, GTK_TREE
- (item->parent)->level);
- i = i->next;
- }
-}
-
-int main( int argc,
- char *argv[] )
-{
- GtkWidget *window, *scrolled_win, *tree;
- static gchar *itemnames[] = {"Foo", "Bar", "Baz", "Quux",
- "Maurice"};
- gint i;
-
- gtk_init (&argc, &argv);
-
- /* a generic toplevel window */
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_signal_connect (GTK_OBJECT(window), "delete_event",
- GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
- gtk_container_set_border_width (GTK_CONTAINER(window), 5);
-
- /* A generic scrolled window */
- scrolled_win = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_widget_set_size_request (scrolled_win, 150, 200);
- gtk_container_add (GTK_CONTAINER(window), scrolled_win);
- gtk_widget_show (scrolled_win);
-
- /* Create the root tree */
- tree = gtk_tree_new();
- g_print ("root tree is %p\n", tree);
- /* connect all GtkTree:: signals */
- gtk_signal_connect (GTK_OBJECT(tree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), tree);
- gtk_signal_connect (GTK_OBJECT(tree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), tree);
- gtk_signal_connect (GTK_OBJECT(tree), "selection_changed",
- GTK_SIGNAL_FUNC(cb_selection_changed), tree);
- /* Add it to the scrolled window */
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_win),
- tree);
- /* Set the selection mode */
- gtk_tree_set_selection_mode (GTK_TREE(tree),
- GTK_SELECTION_MULTIPLE);
- /* Show it */
- gtk_widget_show (tree);
-
- for (i = 0; i < 5; i++){
- GtkWidget *subtree, *item;
- gint j;
-
- /* Create a tree item */
- item = gtk_tree_item_new_with_label (itemnames[i]);
- /* Connect all GtkItem:: and GtkTreeItem:: signals */
- gtk_signal_connect (GTK_OBJECT(item), "select",
- GTK_SIGNAL_FUNC(cb_itemsignal), "select");
- gtk_signal_connect (GTK_OBJECT(item), "deselect",
- GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
- gtk_signal_connect (GTK_OBJECT(item), "toggle",
- GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
- gtk_signal_connect (GTK_OBJECT(item), "expand",
- GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
- gtk_signal_connect (GTK_OBJECT(item), "collapse",
- GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
- /* Add it to the parent tree */
- gtk_tree_append (GTK_TREE(tree), item);
- /* Show it - this can be done at any time */
- gtk_widget_show (item);
- /* Create this item's subtree */
- subtree = gtk_tree_new();
- g_print ("-> item %s->%p, subtree %p\n", itemnames[i], item,
- subtree);
-
- /* This is still necessary if you want these signals to be called
- for the subtree's children. Note that selection_change will be
- signalled for the root tree regardless. */
- gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), subtree);
- gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), subtree);
- /* This has absolutely no effect, because it is completely ignored
- in subtrees */
- gtk_tree_set_selection_mode (GTK_TREE(subtree),
- GTK_SELECTION_SINGLE);
- /* Neither does this, but for a rather different reason - the
- view_mode and view_line values of a tree are propagated to
- subtrees when they are mapped. So, setting it later on would
- actually have a (somewhat unpredictable) effect */
- gtk_tree_set_view_mode (GTK_TREE(subtree), GTK_TREE_VIEW_ITEM);
- /* Set this item's subtree - note that you cannot do this until
- AFTER the item has been added to its parent tree! */
- gtk_tree_item_set_subtree (GTK_TREE_ITEM(item), subtree);
-
- for (j = 0; j < 5; j++){
- GtkWidget *subitem;
-
- /* Create a subtree item, in much the same way */
- subitem = gtk_tree_item_new_with_label (itemnames[j]);
- /* Connect all GtkItem:: and GtkTreeItem:: signals */
- gtk_signal_connect (GTK_OBJECT(subitem), "select",
- GTK_SIGNAL_FUNC(cb_itemsignal), "select");
- gtk_signal_connect (GTK_OBJECT(subitem), "deselect",
- GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
- gtk_signal_connect (GTK_OBJECT(subitem), "toggle",
- GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
- gtk_signal_connect (GTK_OBJECT(subitem), "expand",
- GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
- gtk_signal_connect (GTK_OBJECT(subitem), "collapse",
- GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
- g_print ("-> -> item %s->%p\n", itemnames[j], subitem);
- /* Add it to its parent tree */
- gtk_tree_append (GTK_TREE(subtree), subitem);
- /* Show it */
- gtk_widget_show (subitem);
- }
- }
-
- /* Show the window and loop endlessly */
- gtk_widget_show (window);
- gtk_main();
- return 0;
-}
-<!-- example-end -->
-</programlisting>
-
-</sect1>
-</chapter>
-
-<!-- ***************************************************************** -->
-<chapter id="ch-MenuWidget">
-<title>Menu Widget</title>
-
-<para>There are two ways to create menus: there's the easy way, and there's
-the hard way. Both have their uses, but you can usually use the
-Itemfactory (the easy way). The "hard" way is to create all the menus
-using the calls directly. The easy way is to use the gtk_item_factory
-calls. This is much simpler, but there are advantages and
-disadvantages to each approach.</para>
-
-<para>The Itemfactory is much easier to use, and to add new menus to,
-although writing a few wrapper functions to create menus using the
-manual method could go a long way towards usability. With the
-Itemfactory, it is not possible to add images or the character '/' to
-the menus.</para>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-ManualMenuCreation">
-<title>Manual Menu Creation</title>
-
-<para>In the true tradition of teaching, we'll show you the hard way
-first. <literal>:)</></para>
-
-<para>There are three widgets that go into making a menubar and submenus:</para>
-
-<itemizedlist>
-<listitem><simpara>a menu item, which is what the user wants to select, e.g.,
-"Save"</simpara>
-</listitem>
-<listitem><simpara>a menu, which acts as a container for the menu items, and</simpara>
-</listitem>
-<listitem><simpara>a menubar, which is a container for each of the individual
-menus.</simpara>
-</listitem>
-</itemizedlist>
-
-<para>This is slightly complicated by the fact that menu item widgets are
-used for two different things. They are both the widgets that are
-packed into the menu, and the widget that is packed into the menubar,
-which, when selected, activates the menu.</para>
-
-<para>Let's look at the functions that are used to create menus and
-menubars. This first function is used to create a new menubar.</para>
-
-<programlisting role="C">
-GtkWidget *gtk_menu_bar_new( void );
-</programlisting>
-
-<para>This rather self explanatory function creates a new menubar. You use
-gtk_container_add to pack this into a window, or the box_pack
-functions to pack it into a box - the same as buttons.</para>
+<para>This rather self explanatory function creates a new menubar. You use
+gtk_container_add() to pack this into a window, or the box_pack
+functions to pack it into a box - the same as buttons.</para>
<programlisting role="C">
GtkWidget *gtk_menu_new( void );
</programlisting>
<para>This function returns a pointer to a new menu; it is never actually
-shown (with gtk_widget_show), it is just a container for the menu
+shown (with gtk_widget_show()), it is just a container for the menu
items. I hope this will become more clear when you look at the
example below.</para>
-<para>The next two calls are used to create menu items that are packed into
+<para>The next three calls are used to create menu items that are packed into
the menu (and menubar).</para>
<programlisting role="C">
GtkWidget *gtk_menu_item_new( void );
-</programlisting>
-<para>and</para>
-
-<programlisting role="C">
GtkWidget *gtk_menu_item_new_with_label( const char *label );
+
+GtkWidget *gtk_menu_item_new_with_mnemnonic( const char *label );
</programlisting>
<para>These calls are used to create the menu items that are to be
displayed. Remember to differentiate between a "menu" as created with
-gtk_menu_new and a "menu item" as created by the gtk_menu_item_new
+gtk_menu_new() and a "menu item" as created by the gtk_menu_item_new()
functions. The menu item will be an actual button with an associated
action, whereas a menu will be a container holding menu items.</para>
-<para>The gtk_menu_new_with_label and gtk_menu_new functions are just as
+<para>The gtk_menu_item_new_with_label() and gtk_menu_item_new() functions are just as
you'd expect after reading about the buttons. One creates a new menu
item with a label already packed into it, and the other just creates a
blank menu item.</para>
<para>Once you've created a menu item you have to put it into a menu. This
-is done using the function gtk_menu_append. In order to capture when
+is done using the function gtk_menu_shelll_append. In order to capture when
the item is selected by the user, we need to connect to the
<literal>activate</literal> signal in the usual way. So, if we wanted to create a
standard <literal>File</literal> menu, with the options <literal>Open</literal>, <literal>Save</literal>, and
quit_item = gtk_menu_item_new_with_label ("Quit");
/* Add them to the menu */
- gtk_menu_append (GTK_MENU (file_menu), open_item);
- gtk_menu_append (GTK_MENU (file_menu), save_item);
- gtk_menu_append (GTK_MENU (file_menu), quit_item);
+ gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), open_item);
+ gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), save_item);
+ gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), quit_item);
/* Attach the callback functions to the activate signal */
- gtk_signal_connect_object (GTK_OBJECT (open_item), "activate",
- GTK_SIGNAL_FUNC (menuitem_response),
- (gpointer) "file.open");
- gtk_signal_connect_object (GTK_OBJECT (save_item), "activate",
- GTK_SIGNAL_FUNC (menuitem_response),
- (gpointer) "file.save");
+ g_signal_connect_swapped (G_OBJECT (open_item), "activate",
+ G_CALLBACK (menuitem_response),
+ (gpointer) "file.open");
+ g_signal_connect_swapped (G_OBJECT (save_item), "activate",
+ G_CALLBACK (menuitem_response),
+ (gpointer) "file.save");
/* We can attach the Quit menu item to our exit function */
- gtk_signal_connect_object (GTK_OBJECT (quit_item), "activate",
- GTK_SIGNAL_FUNC (destroy),
- (gpointer) "file.quit");
+ g_signal_connect_swapped (G_OBJECT (quit_item), "activate",
+ G_CALLBACK (destroy),
+ (gpointer) "file.quit");
/* We do need to show menu items */
gtk_widget_show (open_item);
</listitem>
<listitem><simpara> Use multiple calls to gtk_menu_item_new() for each item you
-wish to have on your menu. And use gtk_menu_append() to put each of
+wish to have on your menu. And use gtk_menu_shell_append() to put each of
these new items on to the menu.</simpara>
</listitem>
<listitem><simpara>Bind that event handler to a widget with</simpara>
<programlisting role="C">
- gtk_signal_connect_object (GTK_OBJECT (widget), "event",
- GTK_SIGNAL_FUNC (handler),
- GTK_OBJECT (menu));
+ g_signal_connect_swapped (G_OBJECT (widget), "event",
+ G_CALLBACK (handler),
+ G_OBJECT (menu));
</programlisting>
<simpara>where <literal>widget</literal> is the widget you are binding to,
<literal>handler</literal> is the handling function, and <literal>menu</literal> is a menu
<para>That should about do it. Let's take a look at an example to help clarify.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/menu.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
<programlisting role="C">
<!-- example-start menu menu.c -->
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (GTK_WIDGET (window), 200, 100);
gtk_window_set_title (GTK_WINDOW (window), "GTK Menu Test");
- g_signal_connect (GTK_OBJECT (window), "delete_event",
- (GtkSignalFunc) gtk_main_quit, NULL);
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (gtk_main_quit), NULL);
/* Init the menu-widget, and remember -- never
* gtk_show_widget() the menu widget!!
menu = gtk_menu_new ();
/* Next we make a little loop that makes three menu-entries for "test-menu".
- * Notice the call to gtk_menu_append. Here we are adding a list of
+ * Notice the call to gtk_menu_shell_append. Here we are adding a list of
* menu items to our menu. Normally, we'd also catch the "clicked"
* signal on each of the menu items and setup a callback for it,
* but it's omitted here to save space. */
- for (i = 0; i < 3; i++)
+ for (i = 0; i < 3; i++)
{
/* Copy the names to the buf. */
sprintf (buf, "Test-undermenu - %d", i);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);
/* Do something interesting when the menuitem is selected */
- g_signal_connect_swapped (GTK_OBJECT (menu_items), "activate",
- GTK_SIGNAL_FUNC (menuitem_response), (gpointer) g_strdup (buf));
+ g_signal_connect_swapped (G_OBJECT (menu_items), "activate",
+ G_CALLBACK (menuitem_response),
+ (gpointer) g_strdup (buf));
/* Show the widget */
gtk_widget_show (menu_items);
/* Create a button to which to attach menu as a popup */
button = gtk_button_new_with_label ("press me");
- g_signal_connect_swapped (GTK_OBJECT (button), "event",
- GTK_SIGNAL_FUNC (button_press), GTK_OBJECT (menu));
+ g_signal_connect_swapped (G_OBJECT (button), "event",
+ G_CALLBACK (button_press),
+ G_OBJECT (menu));
gtk_box_pack_end (GTK_BOX (vbox), button, TRUE, TRUE, 2);
gtk_widget_show (button);
GdkEvent *event )
{
- if (event->type == GDK_BUTTON_PRESS) {
+ if (event->type == GDK_BUTTON_PRESS) {
GdkEventButton *bevent = (GdkEventButton *) event;
gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL,
- bevent->button, bevent->time);
+ bevent->button, bevent->time);
/* Tell calling code that we have handled this event; the buck
* stops here. */
return TRUE;
<para>Now that we've shown you the hard way, here's how you do it using the
gtk_item_factory calls.</para>
-</sect1>
+<para>ItemFactory creates a menu out of an array of ItemFactory entries. This
+means you can define your menu in its simplest form and then create the
+menu/menubar widgets with a minimum of function calls.</para>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-ItemFactoryExample">
-<title>Item Factory Example</title>
+<sect2 id="sec-ItemFactoryEntries">
+<title>ItemFactory entries</title>
-<para>Here is an example using the GTK item factory.</para>
+<para>At the core of ItemFactory is the ItemFactoryEntry. This structure defines
+one menu item, and when an array of these entries is defined a whole
+menu is formed. The ItemFactory entry struct definition looks like this:</para>
<programlisting role="C">
-<!-- example-start menu itemfactory.c -->
-
-#include <gtk/gtk.h>
-#include <strings.h>
-
-/* Obligatory basic callback */
-static void print_hello( GtkWidget *w,
- gpointer data )
+struct _GtkItemFactoryEntry
{
- g_message ("Hello, World!\n");
-}
+ gchar *path;
+ gchar *accelerator;
-/* This is the GtkItemFactoryEntry structure used to generate new menus.
- Item 1: The menu path. The letter after the underscore indicates an
- accelerator key once the menu is open.
- Item 2: The accelerator key for the entry
- Item 3: The callback function.
- Item 4: The callback action. This changes the parameters with
- which the function is called. The default is 0.
- Item 5: The item type, used to define what kind of an item it is.
- Here are the possible values:
-
- NULL -> "<Item>"
- "" -> "<Item>"
- "<Title>" -> create a title item
- "<Item>" -> create a simple item
- "<CheckItem>" -> create a check item
- "<ToggleItem>" -> create a toggle item
- "<RadioItem>" -> create a radio item
- <path> -> path of a radio item to link against
- "<Separator>" -> create a separator
- "<Branch>" -> create an item to hold sub items (optional)
- "<LastBranch>" -> create a right justified branch
-*/
+ GtkItemFactoryCallback callback;
+ guint callback_action;
-static GtkItemFactoryEntry menu_items[] = {
- { "/_File", NULL, NULL, 0, "<Branch>" },
- { "/File/_New", "<control>N", print_hello, 0, NULL },
- { "/File/_Open", "<control>O", print_hello, 0, NULL },
- { "/File/_Save", "<control>S", print_hello, 0, NULL },
- { "/File/Save _As", NULL, NULL, 0, NULL },
- { "/File/sep1", NULL, NULL, 0, "<Separator>" },
- { "/File/Quit", "<control>Q", gtk_main_quit, 0, NULL },
- { "/_Options", NULL, NULL, 0, "<Branch>" },
- { "/Options/Test", NULL, NULL, 0, NULL },
- { "/_Help", NULL, NULL, 0, "<LastBranch>" },
- { "/_Help/About", NULL, NULL, 0, NULL },
+ gchar *item_type;
};
+</programlisting>
+<para>Each field defines part of the menu item.</para>
-void get_main_menu( GtkWidget *window,
- GtkWidget **menubar )
-{
- GtkItemFactory *item_factory;
- GtkAccelGroup *accel_group;
- gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
-
- accel_group = gtk_accel_group_new ();
-
- /* This function initializes the item factory.
- Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
- or GTK_TYPE_OPTION_MENU.
- Param 2: The path of the menu.
- Param 3: A pointer to a gtk_accel_group. The item factory sets up
- the accelerator table while generating menus.
- */
+<para><literal>*path</literal> is a string which defines both the name and the
+path of a menu item, for example, "/File/Open" would be the name of a menu
+item which would come under the ItemFactory entry with path "/File". Note however
+that "/File/Open" would be displayed in the File menu as "Open". Also note
+since the forward slashes are used to define the path of the menu,
+they cannot be used as part of the name. A letter preceded by an underscore
+indicates an accelerator (shortcut) key once the menu is open.</para>
- item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
- accel_group);
+<para>
+<literal>*accelerator</literal> is a string that indicates a key combination
+that can be used as a shortcut to that menu item. The string can be made up
+of either a single character, or a combination of modifier keys with a single
+character. It is case insensitive.</para>
- /* This function generates the menu items. Pass the item factory,
- the number of items in the array, the array itself, and any
- callback data for the the menu items. */
- gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
- /* Attach the new accelerator group to the window. */
- gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
+<para>The available modifier keys are:</para>
- if (menubar)
- /* Finally, return the actual menu bar created by the item factory. */
- *menubar = gtk_item_factory_get_widget (item_factory, "<main>");
-}
+<programlisting role="C">
+"<ALT> - alt
+"<CTL>" or "<CTRL>" or "<CONTROL>" - control
+"<MOD1>" to "<MOD5>" - modn
+"<SHFT>" or "<SHIFT>" - shift
+</programlisting>
-int main( int argc,
- char *argv[] )
-{
- GtkWidget *window;
- GtkWidget *main_vbox;
- GtkWidget *menubar;
-
- gtk_init (&argc, &argv);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (gtk_main_quit),
- "WM destroy");
- gtk_window_set_title (GTK_WINDOW(window), "Item Factory");
- gtk_widget_set_size_request (GTK_WIDGET (window), 300, 200);
-
- main_vbox = gtk_vbox_new (FALSE, 1);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 1);
- gtk_container_add (GTK_CONTAINER (window), main_vbox);
- gtk_widget_show (main_vbox);
-
- get_main_menu (window, &menubar);
- gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
- gtk_widget_show (menubar);
-
- gtk_widget_show (window);
- gtk_main ();
-
- return 0;
-}
-<!-- example-end -->
+<para>Examples:</para>
+<programlisting role="C">
+"<ConTroL>a"
+"<SHFT><ALT><CONTROL>X"
</programlisting>
-<para>For now, there's only this example. An explanation and lots 'o' comments
-will follow later.</para>
+<para>
+<literal>callback</literal> is the function that is called when the menu item
+emits the "activate" signal. The form of the callback is described
+in the <link linkend="sec-ItemFactoryCallback">Callback Description</link>
+section.</para>
-</sect1>
-</chapter>
+<para>
+The value of <literal>callback_action</literal> is passed to the callback
+function. It also affects the function prototype, as shown
+in the <link linkend="sec-ItemFactoryCallback">Callback Description</link>
+section.</para>
-<!-- ***************************************************************** -->
-<chapter id="ch-TextWidget">
-<title>Text Widget</title>
+<para>
+<literal>item_type</literal> is a string that defines what type of widget is
+packed into the menu items container. It can be:</para>
-<para>The Text widget allows multiple lines of text to be displayed and
-edited. It supports both multi-colored and multi-font text, allowing
-them to be mixed in any way we wish. It also has a wide set of key
-based text editing commands, which are compatible with Emacs.</para>
+<programlisting role="C">
+NULL or "" or "<Item>" - create a simple item
+"<Title>" - create a title item
+"<CheckItem>" - create a check item
+"<ToggleItem>" - create a toggle item
+"<RadioItem>" - create a (root) radio item
+"Path" - create a sister radio item
+"<Tearoff>" - create a tearoff
+"<Separator>" - create a separator
+"<Branch>" - create an item to hold submenus (optional)
+"<LastBranch>" - create a right justified branch
+</programlisting>
-<para>The text widget supports full cut-and-paste facilities, including the
-use of double- and triple-click to select a word and a whole line,
-respectively.</para>
+<para>Note that <LastBranch> is only useful for one submenu of
+a menubar.</para>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-CreatingAndConfiguringATextBox">
-<title>Creating and Configuring a Text box</title>
+<sect3 id="sec-ItemFactoryCallback">
+<title>Callback Description</title>
-<para>There is only one function for creating a new Text widget.</para>
+<para>
+The callback for an ItemFactory entry can take two forms. If
+<literal>callback_action</literal> is zero, it is of the following
+form:</para>
<programlisting role="C">
-GtkWidget *gtk_text_new( GtkAdjustment *hadj,
- GtkAdjustment *vadj );
+void callback(void)
</programlisting>
-<para>The arguments allow us to give the Text widget pointers to Adjustments
-that can be used to track the viewing position of the widget. Passing
-NULL values to either or both of these arguments will cause the
-gtk_text_new function to create its own.</para>
+<para>otherwise it is of the form:</para>
<programlisting role="C">
-void gtk_text_set_adjustments( GtkText *text,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj );
+void callback(gpointer callback_data,
+ guint callback_action,
+ GtkWidget *widget)
</programlisting>
-<para>The above function allows the horizontal and vertical adjustments of a
-text widget to be changed at any time.</para>
+<para>
+<literal>callback_data</literal> is a pointer to an arbitrary piece of data and
+is set during the call to gtk_item_factory_create_items().</para>
+
+<para>
+<literal>callback_action</literal> is the same value as
+<literal>callback_action</literal> in the ItemFactory entry.</para>
+
+<para>
+<literal>*widget</literal> is a pointer to a menu item widget
+(described in <link linkend="sec-ManualMenuCreation">Manual Menu Creation</link>).
+</para>
+</sect3>
+
+<!-- ----------------------------------------------------------------- -->
+<sect3 id="sec-ItemFactoryEntryExamples">
+<title>ItemFactory entry examples</title>
-<para>The text widget will not automatically create its own scrollbars when
-the amount of text to be displayed is too long for the display
-window. We therefore have to create and add them to the display layout
-ourselves.</para>
+<para>Creating a simple menu item:</para>
<programlisting role="C">
- vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text)->vadj);
- gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
- gtk_widget_show (vscrollbar);
+GtkItemFactoryEntry entry = {"/_File/_Open...", "<CTRL>O", print_hello,
+ 0, "<Item>"};
</programlisting>
-<para>The above code snippet creates a new vertical scrollbar, and attaches
-it to the vertical adjustment of the text widget, <literal>text</literal>. It then
-packs it into a box in the normal way.</para>
-
-<para>Note, currently the Text widget does not support horizontal
-scrollbars.</para>
+<para>This will define a new simple menu entry "/File/Open" (displayed as "Open"),
+under the menu entry "/File". It has the accelerator (shortcut) control+'O'
+that when clicked calls the function print_hello(). print_hello() is of
+the form <literal>void print_hello(void)</literal> since the callback_action
+field is zero. When displayed the 'O' in "Open" will be underlined and if the
+menu item is visible on the screen pressing 'O' will activate the item. Note
+that "File/_Open" could also have been used as the path instead of
+"/_File/_Open".</para>
-<para>There are two main ways in which a Text widget can be used: to allow
-the user to edit a body of text, or to allow us to display multiple
-lines of text to the user. In order for us to switch between these
-modes of operation, the text widget has the following function:</para>
+<para>Creating an entry with a more complex callback:</para>
<programlisting role="C">
-void gtk_text_set_editable( GtkText *text,
- gint editable );
+GtkItemFactoryEntry entry = {"/_View/Display _FPS", NULL, print_state,
+ 7,"<CheckItem>"};
</programlisting>
-<para>The <literal>editable</literal> argument is a TRUE or FALSE value that specifies
-whether the user is permitted to edit the contents of the Text
-widget. When the text widget is editable, it will display a cursor at
-the current insertion point.</para>
+<para>This defines a new menu item displayed as "Display FPS" which is under
+the menu item "View". When clicked the function print_state() will be called.
+Since <literal>callback_action</literal> is not zero print_state() is of the
+form:</para>
+
+<programlisting role="C">
+void print_state(gpointer callback_data,
+ guint callback_action,
+ GtkWidget *widget)
+</programlisting>
-<para>You are not, however, restricted to just using the text widget in
-these two modes. You can toggle the editable state of the text widget
-at any time, and can insert text at any time.</para>
+<para>with <literal>callback_action</literal> equal to 7.</para>
-<para>The text widget wraps lines of text that are too long to fit onto a
-single line of the display window. Its default behaviour is to break
-words across line breaks. This can be changed using the next function:</para>
+<para>Creating a radio button set:</para>
<programlisting role="C">
-void gtk_text_set_word_wrap( GtkText *text,
- gint word_wrap );
+GtkItemFactoryEntry entry1 = {"/_View/_Low Resolution", NULL, change_resolution,
+ 1, "<RadioButton>"};
+GtkItemFactoryEntry entry2 = {"/_View/_High Resolution", NULL, change_resolution,
+ 2, "/View/Low Resolution"};
</programlisting>
-<para>Using this function allows us to specify that the text widget should
-wrap long lines on word boundaries. The <literal>word_wrap</literal> argument is a
-TRUE or FALSE value.</para>
+<para><literal>entry1</literal> defines a lone radio button that when toggled
+calls the function change_resolution() with the parameter
+<literal>callback_action</literal> equal to 1. change_resolution() is of
+the form:</para>
-</sect1>
+<programlisting role="C">
+void change_resolution(gpointer callback_data,
+ guint callback_action,
+ GtkWidget *widget)
+</programlisting>
+
+<para><literal>entry2</literal> defines a radio button that belongs to the
+radio group that entry1 belongs to. It calls the same function when toggled
+but with the parameter <literal>callback_action</literal> equal to 2. Note that
+the item_type of <literal>entry2</literal> is the path of entry1
+<emphasis>without</emphasis> the accelerators ('_'). If another radio button was
+required in the same group then it would be defined in the same way as
+<literal>entry2</literal> was with its <literal>item_type</literal> again
+equal to "/View/Low Resolution".</para>
+</sect3>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-TextManipulation">
-<title>Text Manipulation</title>
+<sect3 id="sec-ItemFactoryEntryArrays">
+<title>ItemFactoryEntry Arrays</title>
-<para>The current insertion point of a Text widget can be set using</para>
+<para>An ItemFactoryEntry on it's own however isn't useful. An array of
+entries is what's required to define a menu. Below is an example of how
+you'd declare this array.</para>
<programlisting role="C">
-void gtk_text_set_point( GtkText *text,
- guint index );
+static GtkItemFactoryEntry entries[] = {
+ { "/_File", NULL, NULL, 0, "<Branch>" },
+ { "/File/tear1", NULL, NULL, 0, "<Tearoff>" },
+ { "/File/_New", "<CTRL>N", new_file, 1, "<Item>" },
+ { "/File/_Open...", "<CTRL>O", open_file, 1, "<Item>" },
+ { "/File/sep1", NULL, NULL, 0, "<Seperator>" },
+ { "/File/_Quit", "<CTRL>Q", quit_program, 0, "<Item>"} };
</programlisting>
+</sect3>
+</sect2>
-<para>where <literal>index</literal> is the position to set the insertion point.</para>
+<!-- ----------------------------------------------------------------- -->
+<sect2 id="sec-ItemFactoryCreation">
+<title>Creating an ItemFactory</title>
-<para>Analogous to this is the function for getting the current insertion
-point:</para>
+<para>An array of GtkItemFactoryEntry items defines a menu. Once this
+array is defined then the item factory can be created. The function that
+does this is:</para>
<programlisting role="C">
-guint gtk_text_get_point( GtkText *text );
+GtkItemFactory* gtk_item_factory_new( GtkType container_type,
+ const gchar *path,
+ GtkAccelGroup *accel_group );
</programlisting>
-<para>A function that is useful in combination with the above two functions
-is</para>
+<para><literal>container_type</literal> can be one of:</para>
<programlisting role="C">
-guint gtk_text_get_length( GtkText *text );
+GTK_TYPE_MENU
+GTK_TYPE_MENU_BAR
+GTK_TYPE_OPTION_MENU
</programlisting>
-<para>which returns the current length of the Text widget. The length is the
-number of characters that are within the text block of the widget,
-including characters such as newline, which marks the end of
-lines.</para>
+<para><literal>container_type</literal> defines what type of menu
+you want, so when you extract it later it is either a menu (for pop-ups
+for instance), a menu bar, or an option menu (like a combo box but with
+a menu of pull downs).</para>
+
+<para><literal>path</literal> defines the path of the root of the menu.
+Basically it is a unique name for the root of the menu, it must be
+surrounded by "<>". This is important for the naming of the
+accelerators and should be unique. It should be unique both for each
+menu and between each program. For example in a program named 'foo', the
+main menu should be called "<FooMain>", and a pop-up menu
+"<FooImagePopUp>", or similar. What's important is that they're unique.</para>
+
+<para><literal>accel_group</literal> is a pointer to a gtk_accel_group. The
+item factory sets up the accelerator table while generating menus. New
+accelerator groups are generated by gtk_accel_group_new().</para>
-<para>In order to insert text at the current insertion point of a Text
-widget, the function gtk_text_insert is used, which also allows us to
-specify background and foreground colors and a font for the text.</para>
+<para>But this is just the first step. To convert the array of GtkItemFactoryEntry
+information into widgets the following function is used:</para>
<programlisting role="C">
-void gtk_text_insert( GtkText *text,
- GdkFont *font,
- GdkColor *fore,
- GdkColor *back,
- const char *chars,
- gint length );
+void gtk_item_factory_create_items( GtkItemFactory *ifactory,
+ guint n_entries,
+ GtkItemFactoryEntry *entries,
+ gpointer callback_data );
</programlisting>
-<para>Passing a value of <literal>NULL</literal> in as the value for the foreground color,
-background color or font will result in the values set within the
-widget style to be used. Using a value of <literal>-1</literal> for the length
-parameter will result in the whole of the text string given being
-inserted.</para>
+<para><literal>*ifactory</literal> a pointer to the above created item factory.</para>
+<para><literal>n_entries</literal> is the number of entries in the
+GtkItemFactoryEntry array.</para>
+<para><literal>*entries</literal> is a pointer to the GtkItemFactoryEntry array.</para>
+<para><literal>callback_data</literal> is what gets passed to all the callback functions
+for all the entries with callback_action != 0.</para>
-<para>The text widget is one of the few within GTK that redraws itself
-dynamically, outside of the gtk_main function. This means that all
-changes to the contents of the text widget take effect
-immediately. This may be undesirable when performing multiple changes
-to the text widget. In order to allow us to perform multiple updates
-to the text widget without it continuously redrawing, we can freeze
-the widget, which temporarily stops it from automatically redrawing
-itself every time it is changed. We can then thaw the widget after our
-updates are complete.</para>
-
-<para>The following two functions perform this freeze and thaw action:</para>
+<para>The accelerator group has now been formed, so you'll probably want
+to attach it to the window the menu is in:</para>
<programlisting role="C">
-void gtk_text_freeze( GtkText *text );
-
-void gtk_text_thaw( GtkText *text );
+void gtk_window_add_accel_group( GtkWindow *window,
+ GtkAccelGroup *accel_group);
</programlisting>
+</sect2>
+
+<!-- ----------------------------------------------------------------- -->
+<sect2 id="sec-UsingMenuandItems">
+<title>Making use of the menu and its menu items</title>
-<para>Text is deleted from the text widget relative to the current insertion
-point by the following two functions. The return value is a TRUE or
-FALSE indicator of whether the operation was successful.</para>
+<para>The last thing to do is make use of the menu. The following function
+extracts the relevant widgets from the ItemFactory:</para>
<programlisting role="C">
-gint gtk_text_backward_delete( GtkText *text,
- guint nchars );
-
-gint gtk_text_forward_delete ( GtkText *text,
- guint nchars );
+GtkWidget* gtk_item_factory_get_widget( GtkItemFactory *ifactory,
+ const gchar *path );
</programlisting>
-<para>If you want to retrieve the contents of the text widget, then the
-macro <literal>GTK_TEXT_INDEX(t, index)</literal> allows you to retrieve the
-character at position <literal>index</literal> within the text widget <literal>t</literal>.</para>
-
-<para>To retrieve larger blocks of text, we can use the function</para>
+<para>For instance if an ItemFactory has two entries "/File" and "/File/New",
+using a path of "/File" would retrieve a <emphasis>menu</emphasis> widget from the
+ItemFactory. Using a path of "/File/New" would retrieve a
+<emphasis>menu item</emphasis> widget. This makes it possible to set the initial state
+of menu items. For example to set the default radio
+item to the one with the path "/Shape/Oval" then the following code would
+be used:</para>
<programlisting role="C">
-gchar *gtk_editable_get_chars( GtkEditable *editable,
- gint start_pos,
- gint end_pos );
+gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory, "/Shape/Oval")),
+ TRUE);
</programlisting>
-<para>This is a function of the parent class of the text widget. A value of
--1 as <literal>end_pos</literal> signifies the end of the text. The index of the
-text starts at 0.</para>
+<para>Finally to retrieve the root of the menu use gtk_item_factory_get_item()
+with a path of "<main>" (or whatever path was used in
+gtk_item_factory_new()). In the case of the ItemFactory being created with
+type GTK_TYPE_MENU_BAR this returns a menu bar widget. With type GTK_TYPE_MENU
+a menu widget is returned. With type GTK_TYPE_OPTION_MENU an option menu
+widget is returned.</para>
-<para>The function allocates a new chunk of memory for the text block, so
-don't forget to free it with a call to g_free when you have finished
-with it.</para>
-
+<para><emphasis>Remember</emphasis> for an entry defined with path "/_File"
+the path here is actually "/File".</para>
+
+<para>Now you have a menubar or menu which can be manipulated in the same
+way as shown in the
+<link linkend="sec-ManualMenuCreation">Manual Menu Creation</link>
+section.</para>
+</sect2>
</sect1>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-KeyBoardShortcuts">
-<title>Keyboard Shortcuts</title>
-
-<para>The text widget has a number of pre-installed keyboard shortcuts for
-common editing, motion and selection functions. These are accessed
-using Control and Alt key combinations.</para>
+<sect1 id="sec-ItemFactoryExample">
+<title>Item Factory Example</title>
-<para>In addition to these, holding down the Control key whilst using cursor
-key movement will move the cursor by words rather than
-characters. Holding down Shift whilst using cursor movement will
-extend the selection.</para>
+<para>Here is an example using the GTK item factory.</para>
-<!-- ----------------------------------------------------------------- -->
-<sect2>
-<title>Motion Shortcuts</title>
+<programlisting role="C">
+/* example-start menu itemfactory.c */
-<itemizedlist spacing=compact>
-<listitem><simpara> Ctrl-A Beginning of line</simpara>
-</listitem>
-<listitem><simpara> Ctrl-E End of line</simpara>
-</listitem>
-<listitem><simpara> Ctrl-N Next Line</simpara>
-</listitem>
-<listitem><simpara> Ctrl-P Previous Line</simpara>
-</listitem>
-<listitem><simpara> Ctrl-B Backward one character</simpara>
-</listitem>
-<listitem><simpara> Ctrl-F Forward one character</simpara>
-</listitem>
-<listitem><simpara> Alt-B Backward one word</simpara>
-</listitem>
-<listitem><simpara> Alt-F Forward one word</simpara>
-</listitem>
-</itemizedlist>
+#include &lt;gtk/gtk.h&gt;
+#include &lt;strings.h&gt;
-</sect2>
+/* Obligatory basic callback */
+static void print_hello( GtkWidget *w,
+ gpointer data )
+{
+ g_message ("Hello, World!\n");
+}
-<!-- ----------------------------------------------------------------- -->
-<sect2>
-<title>Editing Shortcuts</title>
+/* For the check button */
+static void print_toggle(gpointer callback_data,
+ guint callback_action,
+ GtkWidget *menu_item)
+{
+ g_message ("Check button state - %d\n",
+ GTK_CHECK_MENU_ITEM(menu_item)-&gt;active);
+}
-<itemizedlist spacing=compact>
-<listitem><simpara> Ctrl-H Delete Backward Character (Backspace)</simpara>
-</listitem>
-<listitem><simpara> Ctrl-D Delete Forward Character (Delete)</simpara>
-</listitem>
-<listitem><simpara> Ctrl-W Delete Backward Word</simpara>
-</listitem>
-<listitem><simpara> Alt-D Delete Forward Word</simpara>
-</listitem>
-<listitem><simpara> Ctrl-K Delete to end of line</simpara>
-</listitem>
-<listitem><simpara> Ctrl-U Delete line</simpara>
-</listitem>
-</itemizedlist>
+/* For the radio buttons */
+static void print_selected(gpointer callback_data,
+ guint callback_action,
+ GtkWidget *menu_item)
+{
+ if(GTK_CHECK_MENU_ITEM(menu_item)-&gt;active)
+ g_message("Radio button %d selected\n", callback_action);
+}
-</sect2>
+/* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
+static GtkItemFactoryEntry menu_items[] = {
+ { "/_File", NULL, NULL, 0, "&lt;Branch&gt;" },
+ { "/File/_New", "&lt;control&gt;N", print_hello, 0, "<Item>" },
+ { "/File/_Open", "&lt;control&gt;O", print_hello, 0, "<Item>" },
+ { "/File/_Save", "&lt;control&gt;S", print_hello, 0, "<Item>" },
+ { "/File/Save _As", NULL, NULL, 0, "<Item>" },
+ { "/File/sep1", NULL, NULL, 0, "&lt;Separator&gt;" },
+ { "/File/Quit", "&lt;control&gt;Q", gtk_main_quit, 0, "<Item>" },
+ { "/_Options", NULL, NULL, 0, "&lt;Branch&gt;" },
+ { "/Options/tear", NULL, NULL, 0, "&lt;Tearoff&gt;" },
+ { "/Options/Check", NULL, print_toggle, 1, "&lt;CheckItem&gt;" },
+ { "/Options/sep", NULL, NULL, 0, "&lt;Separator&gt;" },
+ { "/Options/Rad1", NULL, print_selected, 1, "&lt;RadioItem&gt;" },
+ { "/Options/Rad2", NULL, print_selected, 2, "/Options/Rad1" },
+ { "/Options/Rad3", NULL, print_selected, 3, "/Options/Rad1" },
+ { "/_Help", NULL, NULL, 0, "&lt;LastBranch&gt;" },
+ { "/_Help/About", NULL, NULL, 0, "<Item>" },
+};
-<!-- ----------------------------------------------------------------- -->
-<sect2>
-<title>Selection Shortcuts</title>
+static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
-<itemizedlist spacing=compact>
-<listitem><simpara> Ctrl-X Cut to clipboard</simpara>
-</listitem>
-<listitem><simpara> Ctrl-C Copy to clipboard</simpara>
-</listitem>
-<listitem><simpara> Ctrl-V Paste from clipboard</simpara>
-</listitem>
-</itemizedlist>
+/* Returns a menubar widget made from the above menu */
+GtkWidget *get_menubar_menu( GtkWidget *window)
+{
+ GtkItemFactory *item_factory;
+ GtkAccelGroup *accel_group;
-</sect2>
-</sect1>
+ /* Make an accelerator group (shortcut keys) */
+ accel_group = gtk_accel_group_new ();
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-AGtkTextExample">
-<title>A GtkText Example</title>
+ /* Make an ItemFactory (that makes a menubar) */
+ item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "&lt;main&gt;",
+ accel_group);
-<programlisting role="C">
-<!-- example-start text text.c -->
+ /* This function generates the menu items. Pass the item factory,
+ the number of items in the array, the array itself, and any
+ callback data for the the menu items. */
+ gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
-/* text.c */
+ /* Attach the new accelerator group to the window. */
+ gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
-#define GTK_ENABLE_BROKEN
-#include <stdio.h>
-#include <gtk/gtk.h>
+ /* Finally, return the actual menu bar created by the item factory. */
+ return gtk_item_factory_get_widget (item_factory, "&lt;main&gt;");
+}
-void text_toggle_editable (GtkWidget *checkbutton,
- GtkWidget *text)
+/* Popup the menu when the popup button is pressed */
+static gint popup_cb(GtkWidget *widget, GdkEvent *event, GtkWidget *menu)
{
- gtk_text_set_editable(GTK_TEXT(text),
- GTK_TOGGLE_BUTTON(checkbutton)->active);
+ GdkEventButton *bevent = (GdkEventButton *)event;
+
+ /* Only take button presses */
+ if(event-&gt;type != GDK_BUTTON_PRESS)
+ return FALSE;
+
+ /* Show the menu */
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
+ NULL, NULL, bevent-&gt;button, bevent-&gt;time);
+
+ return TRUE;
}
-void text_toggle_word_wrap (GtkWidget *checkbutton,
- GtkWidget *text)
+/* Same as with get_menubar_menu() but just return a button with a signal to
+ call a popup menu */
+GtkWidget *get_popup_menu(void)
{
- gtk_text_set_word_wrap(GTK_TEXT(text),
- GTK_TOGGLE_BUTTON(checkbutton)->active);
+ GtkItemFactory *item_factory;
+ GtkWidget *button, *menu;
+
+ /* Same as before but don't bother with the accelerators */
+ item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "&lt;main&gt;",
+ NULL);
+ gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
+ menu = gtk_item_factory_get_widget(item_factory, "&lt;main&gt;");
+
+ /* Make a button to activate the popup menu */
+ button = gtk_button_new_with_label("Popup");
+ /* Make the menu popup when clicked */
+ g_signal_connect(G_OBJECT(button),
+ "event",
+ G_CALLBACK(popup_cb),
+ (gpointer) menu);
+
+ return button;
}
-void close_application( GtkWidget *widget,
- gpointer data )
+/* Same again but return an option menu */
+GtkWidget *get_option_menu(void)
{
- gtk_main_quit();
+ GtkItemFactory *item_factory;
+ GtkWidget *option_menu;
+
+ /* Same again, not bothering with the accelerators */
+ item_factory = gtk_item_factory_new (GTK_TYPE_OPTION_MENU, "&lt;main&gt;",
+ NULL);
+ gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
+ option_menu = gtk_item_factory_get_widget(item_factory, "&lt;main&gt;");
+
+ return option_menu;
}
+/* You have to start somewhere */
int main( int argc,
char *argv[] )
{
GtkWidget *window;
- GtkWidget *box1;
- GtkWidget *box2;
- GtkWidget *hbox;
- GtkWidget *button;
- GtkWidget *check;
- GtkWidget *separator;
- GtkWidget *table;
- GtkWidget *vscrollbar;
- GtkWidget *text;
- GdkColormap *cmap;
- GdkColor color;
- GdkFont *fixed_font;
-
- FILE *infile;
-
+ GtkWidget *main_vbox;
+ GtkWidget *menubar, *option_menu, *popup_button;
+
+ /* Initialize GTK */
gtk_init (&argc, &argv);
+ /* Make a window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_widget_set_size_request (window, 600, 500);
- gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
- gtk_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC(close_application),
- NULL);
- gtk_window_set_title (GTK_WINDOW (window), "Text Widget Example");
- gtk_container_set_border_width (GTK_CONTAINER (window), 0);
-
-
- box1 = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (window), box1);
- gtk_widget_show (box1);
-
-
- box2 = gtk_vbox_new (FALSE, 10);
- gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
- gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
- gtk_widget_show (box2);
-
-
- table = gtk_table_new (2, 2, FALSE);
- gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
- gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
- gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
- gtk_widget_show (table);
-
- /* Create the GtkText widget */
- text = gtk_text_new (NULL, NULL);
- gtk_text_set_editable (GTK_TEXT (text), TRUE);
- gtk_table_attach (GTK_TABLE (table), text, 0, 1, 0, 1,
- GTK_EXPAND | GTK_SHRINK | GTK_FILL,
- GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
- gtk_widget_show (text);
-
- /* Add a vertical scrollbar to the GtkText widget */
- vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
- gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
- GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
- gtk_widget_show (vscrollbar);
-
- /* Get the system color map and allocate the color red */
- cmap = gdk_colormap_get_system();
- color.red = 0xffff;
- color.green = 0;
- color.blue = 0;
- if (!gdk_color_alloc(cmap, &color)) {
- g_error("couldn't allocate color");
- }
-
- /* Load a fixed font */
- fixed_font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-140-*-*-*-*-*-*");
-
- /* Realizing a widget creates a window for it,
- * ready for us to insert some text */
- gtk_widget_realize (text);
-
- /* Freeze the text widget, ready for multiple updates */
- gtk_text_freeze (GTK_TEXT (text));
-
- /* Insert some colored text */
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
- "Supports ", -1);
- gtk_text_insert (GTK_TEXT (text), NULL, &color, NULL,
- "colored ", -1);
- gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
- "text and different ", -1);
- gtk_text_insert (GTK_TEXT (text), fixed_font, &text->style->black, NULL,
- "fonts\n\n", -1);
-
- /* Load the file text.c into the text window */
-
- infile = fopen("text.c", "r");
-
- if (infile) {
- char buffer[1024];
- int nchars;
-
- while (1)
- {
- nchars = fread(buffer, 1, 1024, infile);
- gtk_text_insert (GTK_TEXT (text), fixed_font, NULL,
- NULL, buffer, nchars);
-
- if (nchars < 1024)
- break;
- }
-
- fclose (infile);
- }
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
+ gtk_window_set_title (GTK_WINDOW(window), "Item Factory");
+ gtk_widget_set_size_request (GTK_WIDGET(window), 300, 200);
+
+ /* Make a vbox to put the three menus in */
+ main_vbox = gtk_vbox_new (FALSE, 1);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 1);
+ gtk_container_add (GTK_CONTAINER (window), main_vbox);
+
+ /* Get the three types of menu */
+ /* Note: all three menus are separately created, so they are not the
+ same menu */
+ menubar = get_menubar_menu (window);
+ popup_button = get_popup_menu();
+ option_menu = get_option_menu();
+
+ /* Pack it all together */
+ gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (main_vbox), popup_button, FALSE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (main_vbox), option_menu, FALSE, TRUE, 0);
- /* Thaw the text widget, allowing the updates to become visible */
- gtk_text_thaw (GTK_TEXT (text));
-
- hbox = gtk_hbutton_box_new ();
- gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- check = gtk_check_button_new_with_label("Editable");
- gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
- gtk_signal_connect (GTK_OBJECT(check), "toggled",
- GTK_SIGNAL_FUNC(text_toggle_editable), text);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
- gtk_widget_show (check);
- check = gtk_check_button_new_with_label("Wrap Words");
- gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
- gtk_signal_connect (GTK_OBJECT(check), "toggled",
- GTK_SIGNAL_FUNC(text_toggle_word_wrap), text);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
- gtk_widget_show (check);
-
- separator = gtk_hseparator_new ();
- gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
- gtk_widget_show (separator);
-
- box2 = gtk_vbox_new (FALSE, 10);
- gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
- gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
- gtk_widget_show (box2);
+ /* Show the widgets */
+ gtk_widget_show_all (window);
- button = gtk_button_new_with_label ("close");
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC(close_application),
- NULL);
- gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_widget_grab_default (button);
- gtk_widget_show (button);
-
- gtk_widget_show (window);
-
+ /* Finished! */
gtk_main ();
-
- return(0);
+
+ return(0);
}
-<!-- example-end -->
+/* example-end */
</programlisting>
</sect1>
from your time.</para>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-Curves">
-<title>Curves</title>
+<sect1 id="sec-AccelLabel">
+<title>Accel Label</title>
<para></para>
</sect1>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-DrawingArea">
-<title>Drawing Area</title>
+<sect1 id="sec-OptionMenu">
+<title>Option Menu</title>
<para></para>
</sect1>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-FontSelectionDialog">
-<title>Font Selection Dialog</title>
+<sect1 id="sec-MenuItems">
+<title>Menu Items</title>
<para></para>
-</sect1>
+<sect2 id="sec-CheckMenuItem">
+<title>Check Menu Item</title>
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GammaCurve">
-<title>Gamma Curve</title>
+<para></para>
+</sect2>
+
+<sect2 id="sec-RadioMenuItem">
+<title>Radio Menu Item</title>
+
+<para></para>
+</sect2>
+
+<sect2 id="sec-SeparatorMenuItem">
+<title>Separator Menu Item</title>
<para></para>
+</sect2>
+<sect2 id="sec-TearoffMenuItem">
+<title>Tearoff Menu Item</title>
+
+<para></para>
+</sect2>
</sect1>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-Image">
-<title>Image</title>
+<sect1 id="sec-Curves">
+<title>Curves</title>
<para></para>
</sect1>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-PlugsAndSockets">
-<title>Plugs and Sockets</title>
+<sect1 id="sec-DrawingArea">
+<title>Drawing Area</title>
<para></para>
</sect1>
<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-Preview">
-<title>Preview</title>
+<sect1 id="sec-FontSelectionDialog">
+<title>Font Selection Dialog</title>
<para></para>
-<!--
-
-<para>(This may need to be rewritten to follow the style of the rest of the tutorial)</para>
-
-<para><tscreen><verb></para>
-
-<para>Previews serve a number of purposes in GIMP/GTK. The most important one is
-this. High quality images may take up to tens of megabytes of memory - easily!
-Any operation on an image that big is bound to take a long time. If it takes
-you 5-10 trial-and-errors (i.e., 10-20 steps, since you have to revert after
-you make an error) to choose the desired modification, it make take you
-literally hours to make the right one - if you don't run out of memory
-first. People who have spent hours in color darkrooms know the feeling.
-Previews to the rescue!</para>
-
-<para>But the annoyance of the delay is not the only issue. Oftentimes it is
-helpful to compare the Before and After versions side-by-side or at least
-back-to-back. If you're working with big images and 10 second delays,
-obtaining the Before and After impressions is, to say the least, difficult.
-For 30M images (4"x6", 600dpi, 24 bit) the side-by-side comparison is right
-out for most people, while back-to-back is more like back-to-1001, 1002,
-..., 1010-back! Previews to the rescue!</para>
-
-<para>But there's more. Previews allow for side-by-side pre-previews. In other
-words, you write a plug-in (e.g., the filterpack simulation) which would have
-a number of here's-what-it-would-look-like-if-you-were-to-do-this previews.
-An approach like this acts as a sort of a preview palette and is very
-effective for subtle changes. Let's go previews!</para>
-
-<para>There's more. For certain plug-ins real-time image-specific human
-intervention maybe necessary. In the SuperNova plug-in, for example, the
-user is asked to enter the coordinates of the center of the future
-supernova. The easiest way to do this, really, is to present the user with a
-preview and ask him to interactively select the spot. Let's go previews!</para>
-
-<para>Finally, a couple of misc uses. One can use previews even when not working
-with big images. For example, they are useful when rendering complicated
-patterns. (Just check out the venerable Diffraction plug-in + many other
-ones!) As another example, take a look at the colormap rotation plug-in
-(work in progress). You can also use previews for little logos inside you
-plug-ins and even for an image of yourself, The Author. Let's go previews!</para>
-
-<para>When Not to Use Previews</para>
-
-<para>Don't use previews for graphs, drawing, etc. GDK is much faster for that. Use
-previews only for rendered images!</para>
-
-<para>Let's go previews!</para>
-
-<para>You can stick a preview into just about anything. In a vbox, an hbox, a
-table, a button, etc. But they look their best in tight frames around them.
-Previews by themselves do not have borders and look flat without them. (Of
-course, if the flat look is what you want...) Tight frames provide the
-necessary borders.</para>
-
-<para> [Image][Image]</para>
-
-<para>Previews in many ways are like any other widgets in GTK (whatever that
-means) except they possess an additional feature: they need to be filled with
-some sort of an image! First, we will deal exclusively with the GTK aspect
-of previews and then we'll discuss how to fill them.</para>
-
-<para>GtkWidget *preview!</para>
-
-<para>Without any ado:</para>
-
-<para> /* Create a preview widget,
- set its size, an show it */
-GtkWidget *preview;
-preview=gtk_preview_new(GTK_PREVIEW_COLOR)
- /*Other option:
- GTK_PREVIEW_GRAYSCALE);*/
-gtk_preview_size (GTK_PREVIEW (preview), WIDTH, HEIGHT);
-gtk_widget_show(preview);
-my_preview_rendering_function(preview);</para>
-
-<para>Oh yeah, like I said, previews look good inside frames, so how about:</para>
-
-<para>GtkWidget *create_a_preview(int Width,
- int Height,
- int Colorfulness)
-{
- GtkWidget *preview;
- GtkWidget *frame;
-
- frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- gtk_container_set_border_width (GTK_CONTAINER(frame),0);
- gtk_widget_show(frame);</para>
-
-<para> preview=gtk_preview_new (Colorfulness?GTK_PREVIEW_COLOR
- :GTK_PREVIEW_GRAYSCALE);
- gtk_preview_size (GTK_PREVIEW (preview), Width, Height);
- gtk_container_add(GTK_CONTAINER(frame),preview);
- gtk_widget_show(preview);</para>
-
-<para> my_preview_rendering_function(preview);
- return frame;
-}</para>
-
-<para>That's my basic preview. This routine returns the "parent" frame so you can
-place it somewhere else in your interface. Of course, you can pass the
-parent frame to this routine as a parameter. In many situations, however,
-the contents of the preview are changed continually by your application. In
-this case you may want to pass a pointer to the preview to a
-"create_a_preview()" and thus have control of it later.</para>
-
-<para>One more important note that may one day save you a lot of time. Sometimes
-it is desirable to label you preview. For example, you may label the preview
-containing the original image as "Original" and the one containing the
-modified image as "Less Original". It might occur to you to pack the
-preview along with the appropriate label into a vbox. The unexpected caveat
-is that if the label is wider than the preview (which may happen for a
-variety of reasons unforseeable to you, from the dynamic decision on the
-size of the preview to the size of the font) the frame expands and no longer
-fits tightly over the preview. The same problem can probably arise in other
-situations as well.</para>
-
-<para> [Image]</para>
-
-<para>The solution is to place the preview and the label into a 2x1 table and by
-attaching them with the following parameters (this is one possible variations
-of course. The key is no GTK_FILL in the second attachment):</para>
-
-<para>gtk_table_attach(GTK_TABLE(table),label,0,1,0,1,
- 0,
- GTK_EXPAND|GTK_FILL,
- 0,0);
-gtk_table_attach(GTK_TABLE(table),frame,0,1,1,2,
- GTK_EXPAND,
- GTK_EXPAND,
- 0,0);</para>
+</sect1>
-<para>
-And here's the result:</para>
+<!-- ----------------------------------------------------------------- -->
+<sect1 id="sec-MessageDialog">
+<title>Message Dialog</title>
-<para> [Image]</para>
+<para></para>
-<para>Misc</para>
+</sect1>
-<para>Making a preview clickable is achieved most easily by placing it in a
-button. It also adds a nice border around the preview and you may not even
-need to place it in a frame. See the Filter Pack Simulation plug-in for an
-example.</para>
+<!-- ----------------------------------------------------------------- -->
+<sect1 id="sec-GammaCurve">
+<title>Gamma Curve</title>
-<para>This is pretty much it as far as GTK is concerned.</para>
+<para></para>
-<para>Filling In a Preview</para>
+</sect1>
-<para>In order to familiarize ourselves with the basics of filling in previews,
-let's create the following pattern (contrived by trial and error):</para>
+<!-- ----------------------------------------------------------------- -->
+<sect1 id="sec-Image">
+<title>Image</title>
-<para> [Image]</para>
+<para></para>
-<para>void
-my_preview_rendering_function(GtkWidget *preview)
-{
-#define SIZE 100
-#define HALF (SIZE/2)</para>
-
-<para> guchar *row=(guchar *) malloc(3*SIZE); /* 3 bits per dot */
- gint i, j; /* Coordinates */
- double r, alpha, x, y;</para>
-
-<para> if (preview==NULL) return; /* I usually add this when I want */
- /* to avoid silly crashes. You */
- /* should probably make sure that */
- /* everything has been nicely */
- /* initialized! */
- for (j=0; j < ABS(cos(2*alpha)) ) { /* Are we inside the shape? */
- /* glib.h contains ABS(x). */
- row[i*3+0] = sqrt(1-r)*255; /* Define Red */
- row[i*3+1] = 128; /* Define Green */
- row[i*3+2] = 224; /* Define Blue */
- } /* "+0" is for alignment! */
- else {
- row[i*3+0] = r*255;
- row[i*3+1] = ABS(sin((float)i/SIZE*2*PI))*255;
- row[i*3+2] = ABS(sin((float)j/SIZE*2*PI))*255;
- }
- }
- gtk_preview_draw_row( GTK_PREVIEW(preview),row,0,j,SIZE);
- /* Insert "row" into "preview" starting at the point with */
- /* coordinates (0,j) first column, j_th row extending SIZE */
- /* pixels to the right */
- }</para>
-
-<para> free(row); /* save some space */
- gtk_widget_draw(preview,NULL); /* what does this do? */
- gdk_flush(); /* or this? */
-}</para>
-
-<para>Non-GIMP users can have probably seen enough to do a lot of things already.
-For the GIMP users I have a few pointers to add.</para>
-
-<para>Image Preview</para>
-
-<para>It is probably wise to keep a reduced version of the image around with just
-enough pixels to fill the preview. This is done by selecting every n'th
-pixel where n is the ratio of the size of the image to the size of the
-preview. All further operations (including filling in the previews) are then
-performed on the reduced number of pixels only. The following is my
-implementation of reducing the image. (Keep in mind that I've had only basic
-C!)</para>
-
-<para>(UNTESTED CODE ALERT!!!)</para>
-
-<para>typedef struct {
- gint width;
- gint height;
- gint bbp;
- guchar *rgb;
- guchar *mask;
-} ReducedImage;</para>
-
-<para>enum {
- SELECTION_ONLY,
- SELECTION_IN_CONTEXT,
- ENTIRE_IMAGE
-};</para>
-
-<para>ReducedImage *Reduce_The_Image(GDrawable *drawable,
- GDrawable *mask,
- gint LongerSize,
- gint Selection)
-{
- /* This function reduced the image down to the the selected preview size */
- /* The preview size is determine by LongerSize, i.e., the greater of the */
- /* two dimensions. Works for RGB images only! */
- gint RH, RW; /* Reduced height and reduced width */
- gint width, height; /* Width and Height of the area being reduced */
- gint bytes=drawable->bpp;
- ReducedImage *temp=(ReducedImage *)malloc(sizeof(ReducedImage));</para>
-
-<para> guchar *tempRGB, *src_row, *tempmask, *src_mask_row,R,G,B;
- gint i, j, whichcol, whichrow, x1, x2, y1, y2;
- GPixelRgn srcPR, srcMask;
- gint NoSelectionMade=TRUE; /* Assume that we're dealing with the entire */
- /* image. */</para>
-
-<para> gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
- width = x2-x1;
- height = y2-y1;
- /* If there's a SELECTION, we got its bounds!)</para>
-
-<para> if (width != drawable->width && height != drawable->height)
- NoSelectionMade=FALSE;
- /* Become aware of whether the user has made an active selection */
- /* This will become important later, when creating a reduced mask. */</para>
-
-<para> /* If we want to preview the entire image, overrule the above! */
- /* Of course, if no selection has been made, this does nothing! */
- if (Selection==ENTIRE_IMAGE) {
- x1=0;
- x2=drawable->width;
- y1=0;
- y2=drawable->height;
- }</para>
-
-<para> /* If we want to preview a selection with some surrounding area we */
- /* have to expand it a little bit. Consider it a bit of a riddle. */
- if (Selection==SELECTION_IN_CONTEXT) {
- x1=MAX(0, x1-width/2.0);
- x2=MIN(drawable->width, x2+width/2.0);
- y1=MAX(0, y1-height/2.0);
- y2=MIN(drawable->height, y2+height/2.0);
- }</para>
-
-<para> /* How we can determine the width and the height of the area being */
- /* reduced. */
- width = x2-x1;
- height = y2-y1;</para>
-
-<para> /* The lines below determine which dimension is to be the longer */
- /* side. The idea borrowed from the supernova plug-in. I suspect I */
- /* could've thought of it myself, but the truth must be told. */
- /* Plagiarism stinks! */
- if (width>height) {
- RW=LongerSize;
- RH=(float) height * (float) LongerSize/ (float) width;
- }
- else {
- RH=LongerSize;
- RW=(float)width * (float) LongerSize/ (float) height;
- }</para>
-
-<para> /* The entire image is stretched into a string! */
- tempRGB = (guchar *) malloc(RW*RH*bytes);
- tempmask = (guchar *) malloc(RW*RH);</para>
-
-<para> gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height,
- FALSE, FALSE);
- gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height,
- FALSE, FALSE);</para>
-
-<para> /* Grab enough to save a row of image and a row of mask. */
- src_row = (guchar *) malloc (width*bytes);
- src_mask_row = (guchar *) malloc (width);</para>
-
-<para> for (i=0; i < RH; i++) {
- whichrow=(float)i*(float)height/(float)RH;
- gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y1+whichrow, width);
- gimp_pixel_rgn_get_row (&srcMask, src_mask_row, x1, y1+whichrow, width);</para>
-
-<para> for (j=0; j < RW; j++) {
- whichcol=(float)j*(float)width/(float)RW;</para>
-
-<para> /* No selection made = each point is completely selected! */
- if (NoSelectionMade)
- tempmask[i*RW+j]=255;
- else
- tempmask[i*RW+j]=src_mask_row[whichcol];</para>
+</sect1>
-<para> /* Add the row to the one long string which now contains the image! */
- tempRGB[i*RW*bytes+j*bytes+0]=src_row[whichcol*bytes+0];
- tempRGB[i*RW*bytes+j*bytes+1]=src_row[whichcol*bytes+1];
- tempRGB[i*RW*bytes+j*bytes+2]=src_row[whichcol*bytes+2];</para>
+<!-- ----------------------------------------------------------------- -->
+<sect1 id="sec-PlugsAndSockets">
+<title>Plugs and Sockets</title>
-<para> /* Hold on to the alpha as well */
- if (bytes==4)
- tempRGB[i*RW*bytes+j*bytes+3]=src_row[whichcol*bytes+3];
- }
- }
- temp->bpp=bytes;
- temp->width=RW;
- temp->height=RH;
- temp->rgb=tempRGB;
- temp->mask=tempmask;
- return temp;
-}</para>
-
-<para>The following is a preview function which used the same ReducedImage type!
-Note that it uses fakes transparency (if one is present by means of
-fake_transparency which is defined as follows:</para>
-
-<para>gint fake_transparency(gint i, gint j)
-{
- if ( ((i%20)- 10) * ((j%20)- 10)>0 )
- return 64;
- else
- return 196;
-}</para>
+<para></para>
-<para>Now here's the preview function:</para>
+</sect1>
-<para>void
-my_preview_render_function(GtkWidget *preview,
- gint changewhat,
- gint changewhich)
-{
- gint Inten, bytes=drawable->bpp;
- gint i, j, k;
- float partial;
- gint RW=reduced->width;
- gint RH=reduced->height;
- guchar *row=malloc(bytes*RW);;</para>
+<!-- ----------------------------------------------------------------- -->
+<sect1 id="sec-TreeView">
+<title>Tree View</title>
-<para>
- for (i=0; i < RH; i++) {
- for (j=0; j < RW; j++) {</para>
+<para></para>
-<para> row[j*3+0] = reduced->rgb[i*RW*bytes + j*bytes + 0];
- row[j*3+1] = reduced->rgb[i*RW*bytes + j*bytes + 1];
- row[j*3+2] = reduced->rgb[i*RW*bytes + j*bytes + 2];</para>
+</sect1>
-<para> if (bytes==4)
- for (k=0; k<3; k++) {
- float transp=reduced->rgb[i*RW*bytes+j*bytes+3]/255.0;
- row[3*j+k]=transp*a[3*j+k]+(1-transp)*fake_transparency(i,j);
- }
- }
- gtk_preview_draw_row( GTK_PREVIEW(preview),row,0,i,RW);
- }</para>
-
-<para> free(a);
- gtk_widget_draw(preview,NULL);
- gdk_flush();
-}</para>
-
-<para>Applicable Routines</para>
-
-<para>guint gtk_preview_get_type (void);
-/* No idea */
-void gtk_preview_uninit (void);
-/* No idea */
-GtkWidget* gtk_preview_new (GtkPreviewType type);
-/* Described above */
-void gtk_preview_size (GtkPreview *preview,
- gint width,
- gint height);
-/* Allows you to resize an existing preview. */
-/* Apparently there's a bug in GTK which makes */
-/* this process messy. A way to clean up a mess */
-/* is to manually resize the window containing */
-/* the preview after resizing the preview. */</para>
-
-<para>void gtk_preview_put (GtkPreview *preview,
- GdkWindow *window,
- GdkGC *gc,
- gint srcx,
- gint srcy,
- gint destx,
- gint desty,
- gint width,
- gint height);
-/* No idea */</para>
-
-<para>void gtk_preview_put_row (GtkPreview *preview,
- guchar *src,
- guchar *dest,
- gint x,
- gint y,
- gint w);
-/* No idea */</para>
-
-<para>void gtk_preview_draw_row (GtkPreview *preview,
- guchar *data,
- gint x,
- gint y,
- gint w);
-/* Described in the text */</para>
-
-<para>void gtk_preview_set_expand (GtkPreview *preview,
- gint expand);
-/* No idea */</para>
-
-<para>/* No clue for any of the below but */
-/* should be standard for most widgets */
-void gtk_preview_set_gamma (double gamma);
-void gtk_preview_set_color_cube (guint nred_shades,
- guint ngreen_shades,
- guint nblue_shades,
- guint ngray_shades);
-void gtk_preview_set_install_cmap (gint install_cmap);
-void gtk_preview_set_reserved (gint nreserved);
-GdkVisual* gtk_preview_get_visual (void);
-GdkColormap* gtk_preview_get_cmap (void);
-GtkPreviewInfo* gtk_preview_get_info (void);</para>
-
-<para>That's all, folks!</para>
-
-<para></verb></tscreen></para>
+<!-- ----------------------------------------------------------------- -->
+<sect1 id="sec-TextView">
+<title>Text View</title>
--->
+<para></para>
</sect1>
</chapter>
<para>(Maybe I should make a whole section on accelerators.)</para>
<programlisting role="C">
-void gtk_widget_install_accelerator( GtkWidget *widget,
- GtkAcceleratorTable *table,
- gchar *signal_name,
- gchar key,
- guint8 modifiers );
-
-void gtk_widget_remove_accelerator ( GtkWidget *widget,
- GtkAcceleratorTable *table,
- gchar *signal_name);
-
void gtk_widget_activate( GtkWidget *widget );
void gtk_widget_set_name( GtkWidget *widget,
gchar *gtk_widget_get_name( GtkWidget *widget );
void gtk_widget_set_sensitive( GtkWidget *widget,
- gint sensitive );
+ gboolean sensitive );
void gtk_widget_set_style( GtkWidget *widget,
GtkStyle *style );
GtkStyle *gtk_widget_get_default_style( void );
-void gtk_widget_set_uposition( GtkWidget *widget,
- gint x,
- gint y );
-
void gtk_widget_set_size_request ( GtkWidget *widget,
gint width,
gint height );
<title>Connecting and Disconnecting Signal Handlers</title>
<programlisting role="C">
-guint gtk_signal_connect( GtkObject *object,
- const gchar *name,
- GtkSignalFunc func,
- gpointer func_data );
+gulong g_signal_connect( GObject *object,
+ const gchar *name,
+ GCallback func,
+ gpointer func_data );
-guint gtk_signal_connect_after( GtkObject *object,
- const gchar *name,
- GtkSignalFunc func,
- gpointer func_data );
+gulong g_signal_connect_after( GObject *object,
+ const gchar *name,
+ GCallback func,
+ gpointer func_data );
-guint gtk_signal_connect_object( GtkObject *object,
+gulong g_signal_connect_swapped( GObject *object,
const gchar *name,
- GtkSignalFunc func,
- GtkObject *slot_object );
-
-guint gtk_signal_connect_object_after( GtkObject *object,
- const gchar *name,
- GtkSignalFunc func,
- GtkObject *slot_object );
-
-guint gtk_signal_connect_full( GtkObject *object,
- const gchar *name,
- GtkSignalFunc func,
- GtkCallbackMarshal marshal,
- gpointer data,
- GtkDestroyNotify destroy_func,
- gint object_signal,
- gint after );
-
-guint gtk_signal_connect_interp( GtkObject *object,
- const gchar *name,
- GtkCallbackMarshal func,
- gpointer data,
- GtkDestroyNotify destroy_func,
- gint after );
-
-void gtk_signal_connect_object_while_alive( GtkObject *object,
- const gchar *signal,
- GtkSignalFunc func,
- GtkObject *alive_object );
-
-void gtk_signal_connect_while_alive( GtkObject *object,
- const gchar *signal,
- GtkSignalFunc func,
- gpointer func_data,
- GtkObject *alive_object );
-
-void gtk_signal_disconnect( GtkObject *object,
- guint handler_id );
-
-void gtk_signal_disconnect_by_func( GtkObject *object,
- GtkSignalFunc func,
- gpointer data );
+ GCallback func,
+ GObject *slot_object );
+
+void g_signal_handler_disconnect( GObject *object,
+ gulong handler_id );
+
+void g_signal_handlers_disconnect_by_func( GObject *object,
+ GCallback func,
+ gpointer data );
</programlisting>
</sect2>
<title>Blocking and Unblocking Signal Handlers</title>
<programlisting role="C">
-void gtk_signal_handler_block( GtkObject *object,
- guint handler_id);
-
-void gtk_signal_handler_block_by_func( GtkObject *object,
- GtkSignalFunc func,
- gpointer data );
-
-void gtk_signal_handler_block_by_data( GtkObject *object,
- gpointer data );
+void g_signal_handler_block( GObject *object,
+ gulong handler_id);
-void gtk_signal_handler_unblock( GtkObject *object,
- guint handler_id );
+void g_signal_handlers_block_by_func( GObject *object,
+ GCallback func,
+ gpointer data );
-void gtk_signal_handler_unblock_by_func( GtkObject *object,
- GtkSignalFunc func,
- gpointer data );
+void g_signal_handler_unblock( GObject *object,
+ gulong handler_id );
-void gtk_signal_handler_unblock_by_data( GtkObject *object,
- gpointer data );
+void g_signal_handler_unblock_by_func( GObject *object,
+ GCallback func,
+ gpointer data );
</programlisting>
</sect2>
<title>Emitting and Stopping Signals</title>
<programlisting role="C">
-void gtk_signal_emit( GtkObject *object,
- guint signal_id,
- ... );
-
-void gtk_signal_emit_by_name( GtkObject *object,
- const gchar *name,
- ... );
-
-void gtk_signal_emitv( GtkObject *object,
- guint signal_id,
- GtkArg *params );
-
-void gtk_signal_emitv_by_name( GtkObject *object,
- const gchar *name,
- GtkArg *params );
+void g_signal_emit( GObject *object,
+ guint signal_id,
+ ... );
-guint gtk_signal_n_emissions( GtkObject *object,
- guint signal_id );
+void g_signal_emit_by_name( GObject *object,
+ const gchar *name,
+ ... );
-guint gtk_signal_n_emissions_by_name( GtkObject *object,
- const gchar *name );
+void g_signal_emitv( const GValue *instance_and_params,
+ guint signal_id,
+ GQuark detail,
+ GValue *return_value );
-void gtk_signal_emit_stop( GtkObject *object,
- guint signal_id );
+void g_signal_stop_emission( GObject *object,
+ guint signal_id,
+ GQuark detail );
-void gtk_signal_emit_stop_by_name( GtkObject *object,
- const gchar *name );
+void g_signal_stop_emission_by_name( GObject *object,
+ const gchar *detailed_signal );
</programlisting>
</sect2>
</sect1>
</chapter>
+<!-- continue GTK+ 2.0 review here -->
+
<!-- ***************************************************************** -->
<chapter id="ch-ManagingSelections">
<title>Managing Selections</title>
process, you call:</para>
<programlisting role="C">
-gint gtk_selection_convert( GtkWidget *widget,
- GdkAtom selection,
- GdkAtom target,
- guint32 time );
+gboolean gtk_selection_convert( GtkWidget *widget,
+ GdkAtom selection,
+ GdkAtom target,
+ guint32 time );
</programlisting>
<para>This <emphasis>converts</emphasis> the selection into the form specified by
selection, or if you requested a target that the application didn't
support. The buffer is actually guaranteed to be one byte longer than
<literal>length</literal>; the extra byte will always be zero, so it isn't
-necessary to make a copy of strings just to null terminate them.</para>
+necessary to make a copy of strings just to nul-terminate them.</para>
<para>In the following example, we retrieve the special target "TARGETS",
which is a list of all targets into which the selection can be
gpointer data )
{
static GdkAtom targets_atom = GDK_NONE;
+ GtkWidget *window = (GtkWidget *)data;
/* Get the atom corresponding to the string "TARGETS" */
if (targets_atom == GDK_NONE)
targets_atom = gdk_atom_intern ("TARGETS", FALSE);
/* And request the "TARGETS" target for the primary selection */
- gtk_selection_convert (widget, GDK_SELECTION_PRIMARY, targets_atom,
+ gtk_selection_convert (window, GDK_SELECTION_PRIMARY, targets_atom,
GDK_CURRENT_TIME);
}
int i;
/* **** IMPORTANT **** Check to see if retrieval succeeded */
- if (selection_data->length < 0)
+ if (selection_data->length < 0)
{
g_print ("Selection retrieval failed\n");
return;
}
/* Make sure we got the data in the expected form */
- if (selection_data->type != GDK_SELECTION_TYPE_ATOM)
+ if (selection_data->type != GDK_SELECTION_TYPE_ATOM)
{
g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
return;
}
/* Print out the atoms we received */
- atoms = (GdkAtom *)selection_data->data;
+ atoms = (GdkAtom *)selection_data->data;
item_list = NULL;
- for (i=0; i<selection_data->length/sizeof(GdkAtom); i++)
+ for (i = 0; i < selection_data->length / sizeof(GdkAtom); i++)
{
char *name;
name = gdk_atom_name (atoms[i]);
gtk_window_set_title (GTK_WINDOW (window), "Event Box");
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (exit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (exit), NULL);
/* Create a button the user can click to get targets */
button = gtk_button_new_with_label ("Get Targets");
gtk_container_add (GTK_CONTAINER (window), button);
- g_signal_connect (GTK_OBJECT(button), "clicked",
- GTK_SIGNAL_FUNC (get_targets), NULL);
- g_signal_connect (GTK_OBJECT(button), "selection_received",
- GTK_SIGNAL_FUNC (selection_received), NULL);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (get_targets), (gpointer) window);
+ g_signal_connect (G_OBJECT (window), "selection_received",
+ G_CALLBACK (selection_received), NULL);
gtk_widget_show (button);
gtk_widget_show (window);
<literal>data</literal>, and <literal>length</literal>. (The <literal>format</literal> field is actually
important here - the X server uses it to figure out whether the data
needs to be byte-swapped or not. Usually it will be 8 - <emphasis>i.e.</emphasis> a
-character - or 32 - <emphasis>i.e.</emphasis> a. integer.) This is done by calling the
+character - or 32 - <emphasis>i.e.</emphasis> an integer.) This is done by calling the
function:</para>
<programlisting role="C">
calling:</para>
<programlisting role="C">
-gint gtk_selection_owner_set( GtkWidget *widget,
- GdkAtom selection,
- guint32 time );
+gboolean gtk_selection_owner_set( GtkWidget *widget,
+ GdkAtom selection,
+ guint32 time );
</programlisting>
<para>If another application claims ownership of the selection, you will
#include <stdlib.h>
#include <gtk/gtk.h>
#include <time.h>
+#include <string.h>
+
+GtkWidget *selection_button;
+GtkWidget *selection_widget;
/* Callback when the user toggles the selection */
void selection_toggled( GtkWidget *widget,
gint *have_selection )
{
- if (GTK_TOGGLE_BUTTON(widget)->active)
+ if (GTK_TOGGLE_BUTTON (widget)->active)
{
- *have_selection = gtk_selection_owner_set (widget,
+ *have_selection = gtk_selection_owner_set (selection_widget,
GDK_SELECTION_PRIMARY,
GDK_CURRENT_TIME);
/* if claiming the selection failed, we return the button to
the out state */
if (!*have_selection)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
}
else
{
{
/* Before clearing the selection by setting the owner to NULL,
we check if we are the actual owner */
- if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
+ if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY,
GDK_CURRENT_TIME);
*have_selection = FALSE;
gint *have_selection )
{
*have_selection = FALSE;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (selection_button), FALSE);
return TRUE;
}
gchar *timestr;
time_t current_time;
- current_time = time(NULL);
- timestr = asctime (localtime(&current_time));
+ current_time = time (NULL);
+ timestr = asctime (localtime (&current_time));
/* When we return a single string, it should not be null terminated.
That will be done for us */
gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
- 8, timestr, strlen(timestr));
+ 8, timestr, strlen (timestr));
}
int main( int argc,
char *argv[] )
{
GtkWidget *window;
- GtkWidget *selection_button;
static int have_selection = FALSE;
gtk_window_set_title (GTK_WINDOW (window), "Event Box");
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (exit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (exit), NULL);
/* Create a toggle button to act as the selection */
+ selection_widget = gtk_invisible_new ();
selection_button = gtk_toggle_button_new_with_label ("Claim Selection");
gtk_container_add (GTK_CONTAINER (window), selection_button);
gtk_widget_show (selection_button);
- g_signal_connect (GTK_OBJECT(selection_button), "toggled",
- GTK_SIGNAL_FUNC (selection_toggled), &have_selection);
- g_signal_connect (GTK_OBJECT(selection_button), "selection_clear_event",
- GTK_SIGNAL_FUNC (selection_clear), &have_selection);
+ g_signal_connect (G_OBJECT (selection_button), "toggled",
+ G_CALLBACK (selection_toggled), (gpointer) &have_selection);
+ g_signal_connect (G_OBJECT (selection_widget), "selection_clear_event",
+ G_CALLBACK (selection_clear), (gpointer) &have_selection);
- gtk_selection_add_target (selection_button,
+ gtk_selection_add_target (selection_widget,
GDK_SELECTION_PRIMARY,
GDK_SELECTION_TYPE_STRING,
1);
- g_signal_connect (GTK_OBJECT(selection_button), "selection_get",
- GTK_SIGNAL_FUNC (selection_handle), &have_selection);
+ g_signal_connect (G_OBJECT (selection_widget), "selection_get",
+ G_CALLBACK (selection_handle), (gpointer) &have_selection);
gtk_widget_show (selection_button);
gtk_widget_show (window);
three buttons in a row, column, or on one of the diagonals are
depressed. </para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/tictactoe.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
</sect2>
<!-- ----------------------------------------------------------------- -->
<programlisting role="C">
<!-- example-start tictactoe tictactoe.h -->
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
#ifndef __TICTACTOE_H__
#define __TICTACTOE_H__
+
#include <gdk/gdk.h>
#include <gtk/gtkvbox.h>
+
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void (* tictactoe) (Tictactoe *ttt);
};
-GType tictactoe_get_type (void);
+GtkType tictactoe_get_type (void);
GtkWidget* tictactoe_new (void);
void tictactoe_clear (Tictactoe *ttt);
#endif /* __cplusplus */
#endif /* __TICTACTOE_H__ */
+
<!-- example-end -->
</programlisting>
create an analog dial widget with a pointer that the user can drag to
set the value.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/gtkdial.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
</sect2>
<!-- ----------------------------------------------------------------- -->
support routines which makes getting extended information, such as
pressure and tilt, from such devices quite easy.</para>
+<para>
+<inlinemediaobject>
+<imageobject>
+<imagedata fileref="images/scribble.png" format="png">
+</imageobject>
+</inlinemediaobject>
+</para>
+
</sect1>
<!-- ----------------------------------------------------------------- -->
<para>The GTK Tutorial is Copyright (C) 1997 Ian Main. </para>
-<para>Copyright (C) 1998-1999 Tony Gale.</para>
+<para>Copyright (C) 1998-2002 Tony Gale.</para>
<para>Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
ggint,
gpointer);
void GtkEditable::activate (GtkEditable *,
- gpointer);
-void GtkEditable::set-editable (GtkEditable *,
- gboolean,
- gpointer);
-void GtkEditable::move-cursor (GtkEditable *,
- ggint,
- ggint,
- gpointer);
-void GtkEditable::move-word (GtkEditable *,
- ggint,
- gpointer);
-void GtkEditable::move-page (GtkEditable *,
- ggint,
- ggint,
- gpointer);
-void GtkEditable::move-to-row (GtkEditable *,
- ggint,
- gpointer);
-void GtkEditable::move-to-column (GtkEditable *,
- ggint,
- gpointer);
-void GtkEditable::kill-char (GtkEditable *,
- ggint,
- gpointer);
-void GtkEditable::kill-word (GtkEditable *,
- ggint,
- gpointer);
-void GtkEditable::kill-line (GtkEditable *,
- ggint,
- gpointer);
-void GtkEditable::cut-clipboard (GtkEditable *,
- gpointer);
-void GtkEditable::copy-clipboard (GtkEditable *,
- gpointer);
-void GtkEditable::paste-clipboard (GtkEditable *,
- gpointer);
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkTipsQuery">
-<title>GtkTipsQuery</title>
-
-<programlisting role="C">
-void GtkTipsQuery::start-query (GtkTipsQuery *,
- gpointer);
-void GtkTipsQuery::stop-query (GtkTipsQuery *,
- gpointer);
-void GtkTipsQuery::widget-entered (GtkTipsQuery *,
- GtkWidget *,
- GtkString *,
- GtkString *,
- gpointer);
-gboolean GtkTipsQuery::widget-selected (GtkTipsQuery *,
- GtkWidget *,
- GtkString *,
- GtkString *,
- GdkEvent *,
- gpointer);
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkCList">
-<title>GtkCList</title>
-
-<programlisting role="C">
-void GtkCList::select-row (GtkCList *,
- ggint,
- ggint,
- GdkEvent *,
- gpointer);
-void GtkCList::unselect-row (GtkCList *,
+ gpointer);
+void GtkEditable::set-editable (GtkEditable *,
+ gboolean,
+ gpointer);
+void GtkEditable::move-cursor (GtkEditable *,
+ ggint,
+ ggint,
+ gpointer);
+void GtkEditable::move-word (GtkEditable *,
+ ggint,
+ gpointer);
+void GtkEditable::move-page (GtkEditable *,
ggint,
ggint,
- GdkEvent *,
gpointer);
-void GtkCList::row-move (GtkCList *,
- ggint,
- ggint,
- gpointer);
-void GtkCList::click-column (GtkCList *,
+void GtkEditable::move-to-row (GtkEditable *,
+ ggint,
+ gpointer);
+void GtkEditable::move-to-column (GtkEditable *,
+ ggint,
+ gpointer);
+void GtkEditable::kill-char (GtkEditable *,
ggint,
gpointer);
-void GtkCList::resize-column (GtkCList *,
- ggint,
- ggint,
- gpointer);
-void GtkCList::toggle-focus-row (GtkCList *,
- gpointer);
-void GtkCList::select-all (GtkCList *,
- gpointer);
-void GtkCList::unselect-all (GtkCList *,
+void GtkEditable::kill-word (GtkEditable *,
+ ggint,
gpointer);
-void GtkCList::undo-selection (GtkCList *,
- gpointer);
-void GtkCList::start-selection (GtkCList *,
- gpointer);
-void GtkCList::end-selection (GtkCList *,
- gpointer);
-void GtkCList::toggle-add-mode (GtkCList *,
- gpointer);
-void GtkCList::extend-selection (GtkCList *,
- GtkScrollType,
- ggfloat,
- gboolean,
+void GtkEditable::kill-line (GtkEditable *,
+ ggint,
+ gpointer);
+void GtkEditable::cut-clipboard (GtkEditable *,
gpointer);
-void GtkCList::scroll-vertical (GtkCList *,
- GtkScrollType,
- ggfloat,
- gpointer);
-void GtkCList::scroll-horizontal (GtkCList *,
- GtkScrollType,
- ggfloat,
+void GtkEditable::copy-clipboard (GtkEditable *,
gpointer);
-void GtkCList::abort-column-resize (GtkCList *,
- gpointer);
+void GtkEditable::paste-clipboard (GtkEditable *,
+ gpointer);
</programlisting>
</sect1>
</sect1>
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkTree">
-<title>GtkTree</title>
-
-<programlisting role="C">
-void GtkTree::selection-changed (GtkTree *,
- gpointer);
-void GtkTree::select-child (GtkTree *,
- GtkWidget *,
- gpointer);
-void GtkTree::unselect-child (GtkTree *,
- GtkWidget *,
- gpointer);
-</programlisting>
-
-</sect1>
-
<!-- ----------------------------------------------------------------- -->
<sect1 id="sec-GtkButton">
<title>GtkButton</title>
</sect1>
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkListItem">
-<title>GtkListItem</title>
-
-<programlisting role="C">
-void GtkListItem::toggle-focus-row (GtkListItem *,
- gpointer);
-void GtkListItem::select-all (GtkListItem *,
- gpointer);
-void GtkListItem::unselect-all (GtkListItem *,
- gpointer);
-void GtkListItem::undo-selection (GtkListItem *,
- gpointer);
-void GtkListItem::start-selection (GtkListItem *,
- gpointer);
-void GtkListItem::end-selection (GtkListItem *,
- gpointer);
-void GtkListItem::toggle-add-mode (GtkListItem *,
- gpointer);
-void GtkListItem::extend-selection (GtkListItem *,
- GtkEnum,
- ggfloat,
- gboolean,
- gpointer);
-void GtkListItem::scroll-vertical (GtkListItem *,
- GtkEnum,
- ggfloat,
- gpointer);
-void GtkListItem::scroll-horizontal (GtkListItem *,
- GtkEnum,
- ggfloat,
- gpointer);
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkTreeItem">
-<title>GtkTreeItem</title>
-
-<programlisting role="C">
-void GtkTreeItem::collapse (GtkTreeItem *,
- gpointer);
-void GtkTreeItem::expand (GtkTreeItem *,
- gpointer);
-</programlisting>
-
-</sect1>
-
<!-- ----------------------------------------------------------------- -->
<sect1 id="sec-GtkCheckMenuItem">
<title>GtkCheckMenuItem</title>
</sect1>
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkCTree">
-<title>GtkCTree</title>
-
-<programlisting role="C">
-void GtkCTree::tree-select-row (GtkCTree *,
- GtkCTreeNode *,
- ggint,
- gpointer);
-void GtkCTree::tree-unselect-row (GtkCTree *,
- GtkCTreeNode *,
- ggint,
- gpointer);
-void GtkCTree::tree-expand (GtkCTree *,
- GtkCTreeNode *,
- gpointer);
-void GtkCTree::tree-collapse (GtkCTree *,
- ggpointer,
- gpointer);
-void GtkCTree::tree-move (GtkCTree *,
- GtkCTreeNode *,
- GtkCTreeNode *,
- GtkCTreeNode *,
- gpointer);
-void GtkCTree::change-focus-row-expansion (GtkCTree *,
- GtkCTreeExpansionType,
- gpointer);
-</programlisting>
-
-</sect1>
-
<!-- ----------------------------------------------------------------- -->
<sect1 id="sec-GtkCurve">
<title>GtkCurve</title>
G_TYPE_NONE, 0, NULL);
- class->tictactoe = NULL;
+ class->tictactoe = NULL;
}
static void
gint i,j;
table = gtk_table_new (3, 3, TRUE);
- gtk_container_add (GTK_CONTAINER(ttt), table);
+ gtk_container_add (GTK_CONTAINER (ttt), table);
gtk_widget_show (table);
- for (i=0;i<3; i++)
- for (j=0;j<3; j++)
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
{
- ttt->buttons[i][j] = gtk_toggle_button_new ();
- gtk_table_attach_defaults (GTK_TABLE(table), ttt->buttons[i][j],
+ ttt->buttons[i][j] = gtk_toggle_button_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), ttt->buttons[i][j],
i, i+1, j, j+1);
- g_signal_connect (GTK_OBJECT (ttt->buttons[i][j]), "toggled",
- GTK_SIGNAL_FUNC (tictactoe_toggle), ttt);
- gtk_widget_set_size_request (ttt->buttons[i][j], 20, 20);
- gtk_widget_show (ttt->buttons[i][j]);
+ g_signal_connect (G_OBJECT (ttt->buttons[i][j]), "toggled",
+ G_CALLBACK (tictactoe_toggle), (gpointer) ttt);
+ gtk_widget_set_size_request (ttt->buttons[i][j], 20, 20);
+ gtk_widget_show (ttt->buttons[i][j]);
}
}
{
int i,j;
- for (i=0;i<3;i++)
- for (j=0;j<3;j++)
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
{
- g_signal_handlers_block_by_func (GTK_OBJECT(ttt->buttons[i][j]), NULL, ttt);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
- FALSE);
- g_signal_handlers_unblock_by_func (GTK_OBJECT(ttt->buttons[i][j]), NULL, ttt);
+ g_signal_handlers_block_by_func (G_OBJECT (ttt->buttons[i][j]),
+ NULL, ttt);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
+ FALSE);
+ g_signal_handlers_unblock_by_func (G_OBJECT (ttt->buttons[i][j]),
+ NULL, ttt);
}
}
int success, found;
- for (k=0; k<8; k++)
+ for (k = 0; k < 8; k++)
{
success = TRUE;
found = FALSE;
- for (i=0;i<3;i++)
+ for (i = 0; i < 3; i++)
{
success = success &&
- GTK_TOGGLE_BUTTON(ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
+ GTK_TOGGLE_BUTTON (ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
found = found ||
- ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
+ ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
}
if (success && found)
{
- g_signal_emit (GTK_OBJECT (ttt),
- tictactoe_signals[TICTACTOE_SIGNAL], 0);
+ g_signal_emit (G_OBJECT (ttt),
+ tictactoe_signals[TICTACTOE_SIGNAL], 0);
break;
}
}
gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (exit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (exit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_container_add (GTK_CONTAINER (window), ttt);
gtk_widget_show (ttt);
- g_signal_connect (GTK_OBJECT (ttt), "tictactoe",
- GTK_SIGNAL_FUNC (win), NULL);
+ g_signal_connect (G_OBJECT (ttt), "tictactoe",
+ G_CALLBACK (win), NULL);
gtk_widget_show (window);
parent_class = gtk_type_class (gtk_widget_get_type ());
- object_class->destroy = gtk_dial_destroy;
+ object_class->destroy = gtk_dial_destroy;
- widget_class->realize = gtk_dial_realize;
- widget_class->expose_event = gtk_dial_expose;
- widget_class->size_request = gtk_dial_size_request;
- widget_class->size_allocate = gtk_dial_size_allocate;
- widget_class->button_press_event = gtk_dial_button_press;
- widget_class->button_release_event = gtk_dial_button_release;
- widget_class->motion_notify_event = gtk_dial_motion_notify;
+ widget_class->realize = gtk_dial_realize;
+ widget_class->expose_event = gtk_dial_expose;
+ widget_class->size_request = gtk_dial_size_request;
+ widget_class->size_allocate = gtk_dial_size_allocate;
+ widget_class->button_press_event = gtk_dial_button_press;
+ widget_class->button_release_event = gtk_dial_button_release;
+ widget_class->motion_notify_event = gtk_dial_motion_notify;
}
static void
gtk_dial_init (GtkDial *dial)
{
- dial->button = 0;
- dial->policy = GTK_UPDATE_CONTINUOUS;
- dial->timer = 0;
- dial->radius = 0;
- dial->pointer_width = 0;
- dial->angle = 0.0;
- dial->old_value = 0.0;
- dial->old_lower = 0.0;
- dial->old_upper = 0.0;
- dial->adjustment = NULL;
+ dial->button = 0;
+ dial->policy = GTK_UPDATE_CONTINUOUS;
+ dial->timer = 0;
+ dial->radius = 0;
+ dial->pointer_width = 0;
+ dial->angle = 0.0;
+ dial->old_value = 0.0;
+ dial->old_lower = 0.0;
+ dial->old_upper = 0.0;
+ dial->adjustment = NULL;
}
GtkWidget*
dial = GTK_DIAL (object);
- if (dial->adjustment)
- g_object_unref (GTK_OBJECT (dial->adjustment));
+ if (dial->adjustment)
+ {
+ g_object_unref (GTK_OBJECT (dial->adjustment));
+ dial->adjustment = NULL;
+ }
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
GtkAdjustment*
g_return_val_if_fail (dial != NULL, NULL);
g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);
- return dial->adjustment;
+ return dial->adjustment;
}
void
g_return_if_fail (dial != NULL);
g_return_if_fail (GTK_IS_DIAL (dial));
- dial->policy = policy;
+ dial->policy = policy;
}
void
g_return_if_fail (dial != NULL);
g_return_if_fail (GTK_IS_DIAL (dial));
- if (dial->adjustment)
+ if (dial->adjustment)
{
- g_signal_handlers_disconnect_by_func (GTK_OBJECT (dial->adjustment), NULL, (gpointer) dial);
- g_object_unref (GTK_OBJECT (dial->adjustment));
+ g_signal_handlers_disconnect_by_func (GTK_OBJECT (dial->adjustment), NULL, (gpointer) dial);
+ g_object_unref (GTK_OBJECT (dial->adjustment));
}
- dial->adjustment = adjustment;
- g_object_ref (GTK_OBJECT (dial->adjustment));
+ dial->adjustment = adjustment;
+ g_object_ref (GTK_OBJECT (dial->adjustment));
g_signal_connect (GTK_OBJECT (adjustment), "changed",
- GTK_SIGNAL_FUNC (gtk_dial_adjustment_changed),
- (gpointer) dial);
+ GTK_SIGNAL_FUNC (gtk_dial_adjustment_changed),
+ (gpointer) dial);
g_signal_connect (GTK_OBJECT (adjustment), "value_changed",
- GTK_SIGNAL_FUNC (gtk_dial_adjustment_value_changed),
- (gpointer) dial);
+ GTK_SIGNAL_FUNC (gtk_dial_adjustment_value_changed),
+ (gpointer) dial);
- dial->old_value = adjustment->value;
- dial->old_lower = adjustment->lower;
- dial->old_upper = adjustment->upper;
+ dial->old_value = adjustment->value;
+ dial->old_lower = adjustment->lower;
+ dial->old_upper = adjustment->upper;
gtk_dial_update (dial);
}
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
dial = GTK_DIAL (widget);
- attributes.x = widget->allocation.x;
- attributes.y = widget->allocation.y;
- attributes.width = widget->allocation.width;
- attributes.height = widget->allocation.height;
+ attributes.x = widget->allocation.x;
+ attributes.y = widget->allocation.y;
+ attributes.width = widget->allocation.width;
+ attributes.height = widget->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.event_mask = gtk_widget_get_events (widget) |
attributes.colormap = gtk_widget_get_colormap (widget);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
- widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+ widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
- widget->style = gtk_style_attach (widget->style, widget->window);
+ widget->style = gtk_style_attach (widget->style, widget->window);
- gdk_window_set_user_data (widget->window, widget);
+ gdk_window_set_user_data (widget->window, widget);
- gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+ gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
}
static void
gtk_dial_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
- requisition->width = DIAL_DEFAULT_SIZE;
- requisition->height = DIAL_DEFAULT_SIZE;
+ requisition->width = DIAL_DEFAULT_SIZE;
+ requisition->height = DIAL_DEFAULT_SIZE;
}
static void
g_return_if_fail (GTK_IS_DIAL (widget));
g_return_if_fail (allocation != NULL);
- widget->allocation = *allocation;
+ widget->allocation = *allocation;
dial = GTK_DIAL (widget);
if (GTK_WIDGET_REALIZED (widget))
{
- gdk_window_move_resize (widget->window,
- allocation->x, allocation->y,
- allocation->width, allocation->height);
+ gdk_window_move_resize (widget->window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
}
- dial->radius = MIN(allocation->width,allocation->height) * 0.45;
- dial->pointer_width = dial->radius / 5;
+ dial->radius = MIN (allocation->width, allocation->height) * 0.45;
+ dial->pointer_width = dial->radius / 5;
}
static gint
g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- if (event->count > 0)
+ if (event->count > 0)
return FALSE;
dial = GTK_DIAL (widget);
-/* gdk_window_clear_area (widget->window,
+/* gdk_window_clear_area (widget->window,
0, 0,
- widget->allocation.width,
- widget->allocation.height);
+ widget->allocation.width,
+ widget->allocation.height);
*/
- xc = widget->allocation.width/2;
- yc = widget->allocation.height/2;
+ xc = widget->allocation.width / 2;
+ yc = widget->allocation.height / 2;
- upper = dial->adjustment->upper;
- lower = dial->adjustment->lower;
+ upper = dial->adjustment->upper;
+ lower = dial->adjustment->lower;
/* Erase old pointer */
- s = sin(dial->last_angle);
- c = cos(dial->last_angle);
- dial->last_angle = dial->angle;
-
- points[0].x = xc + s*dial->pointer_width/2;
- points[0].y = yc + c*dial->pointer_width/2;
- points[1].x = xc + c*dial->radius;
- points[1].y = yc - s*dial->radius;
- points[2].x = xc - s*dial->pointer_width/2;
- points[2].y = yc - c*dial->pointer_width/2;
- points[3].x = xc - c*dial->radius/10;
- points[3].y = yc + s*dial->radius/10;
+ s = sin (dial->last_angle);
+ c = cos (dial->last_angle);
+ dial->last_angle = dial->angle;
+
+ points[0].x = xc + s*dial->pointer_width/2;
+ points[0].y = yc + c*dial->pointer_width/2;
+ points[1].x = xc + c*dial->radius;
+ points[1].y = yc - s*dial->radius;
+ points[2].x = xc - s*dial->pointer_width/2;
+ points[2].y = yc - c*dial->pointer_width/2;
+ points[3].x = xc - c*dial->radius/10;
+ points[3].y = yc + s*dial->radius/10;
points[4].x = points[0].x;
points[4].y = points[0].y;
blankstyle = gtk_style_new ();
- blankstyle->bg_gc[GTK_STATE_NORMAL] =
- widget->style->bg_gc[GTK_STATE_NORMAL];
- blankstyle->dark_gc[GTK_STATE_NORMAL] =
- widget->style->bg_gc[GTK_STATE_NORMAL];
- blankstyle->light_gc[GTK_STATE_NORMAL] =
- widget->style->bg_gc[GTK_STATE_NORMAL];
- blankstyle->black_gc =
- widget->style->bg_gc[GTK_STATE_NORMAL];
+ blankstyle->bg_gc[GTK_STATE_NORMAL] =
+ widget->style->bg_gc[GTK_STATE_NORMAL];
+ blankstyle->dark_gc[GTK_STATE_NORMAL] =
+ widget->style->bg_gc[GTK_STATE_NORMAL];
+ blankstyle->light_gc[GTK_STATE_NORMAL] =
+ widget->style->bg_gc[GTK_STATE_NORMAL];
+ blankstyle->black_gc =
+ widget->style->bg_gc[GTK_STATE_NORMAL];
gtk_paint_polygon (blankstyle,
- widget->window,
+ widget->window,
GTK_STATE_NORMAL,
GTK_SHADOW_OUT,
NULL,
points, 5,
FALSE);
- g_object_unref(blankstyle);
+ g_object_unref (blankstyle);
/* Draw ticks */
if ((upper - lower) == 0)
return FALSE;
- increment = (100*M_PI)/(dial->radius*dial->radius);
+ increment = (100*M_PI) / (dial->radius*dial->radius);
inc = (upper - lower);
- while (inc < 100) inc *=10;
- while (inc >= 1000) inc /=10;
+ while (inc < 100) inc *= 10;
+ while (inc >= 1000) inc /= 10;
last = -1;
- for (i=0; i<=inc; i++)
+ for (i = 0; i <= inc; i++)
{
- theta = ((gfloat)i*M_PI/(18*inc/24.) - M_PI/6.);
+ theta = ((gfloat)i*M_PI / (18*inc/24.) - M_PI/6.);
- if ((theta - last) < (increment))
+ if ((theta - last) < (increment))
continue;
last = theta;
- s = sin(theta);
- c = cos(theta);
+ s = sin (theta);
+ c = cos (theta);
- tick_length = (i%(inc/10) == 0) ? dial->pointer_width : dial->pointer_width/2;
+ tick_length = (i%(inc/10) == 0) ? dial->pointer_width : dial->pointer_width / 2;
- gdk_draw_line (widget->window,
- widget->style->fg_gc[widget->state],
- xc + c*(dial->radius - tick_length),
- yc - s*(dial->radius - tick_length),
- xc + c*dial->radius,
- yc - s*dial->radius);
+ gdk_draw_line (widget->window,
+ widget->style->fg_gc[widget->state],
+ xc + c*(dial->radius - tick_length),
+ yc - s*(dial->radius - tick_length),
+ xc + c*dial->radius,
+ yc - s*dial->radius);
}
/* Draw pointer */
- s = sin(dial->angle);
- c = cos(dial->angle);
- dial->last_angle = dial->angle;
-
- points[0].x = xc + s*dial->pointer_width/2;
- points[0].y = yc + c*dial->pointer_width/2;
- points[1].x = xc + c*dial->radius;
- points[1].y = yc - s*dial->radius;
- points[2].x = xc - s*dial->pointer_width/2;
- points[2].y = yc - c*dial->pointer_width/2;
- points[3].x = xc - c*dial->radius/10;
- points[3].y = yc + s*dial->radius/10;
+ s = sin (dial->angle);
+ c = cos (dial->angle);
+ dial->last_angle = dial->angle;
+
+ points[0].x = xc + s*dial->pointer_width/2;
+ points[0].y = yc + c*dial->pointer_width/2;
+ points[1].x = xc + c*dial->radius;
+ points[1].y = yc - s*dial->radius;
+ points[2].x = xc - s*dial->pointer_width/2;
+ points[2].y = yc - c*dial->pointer_width/2;
+ points[3].x = xc - c*dial->radius/10;
+ points[3].y = yc + s*dial->radius/10;
points[4].x = points[0].x;
points[4].y = points[0].y;
- gtk_paint_polygon (widget->style,
- widget->window,
+ gtk_paint_polygon (widget->style,
+ widget->window,
GTK_STATE_NORMAL,
GTK_SHADOW_OUT,
NULL,
the point where the mouse was pressed from the line passing through
the pointer */
- dx = event->x - widget->allocation.width / 2;
- dy = widget->allocation.height / 2 - event->y;
+ dx = event->x - widget->allocation.width / 2;
+ dy = widget->allocation.height / 2 - event->y;
- s = sin(dial->angle);
- c = cos(dial->angle);
+ s = sin (dial->angle);
+ c = cos (dial->angle);
d_parallel = s*dy + c*dx;
- d_perpendicular = fabs(s*dx - c*dy);
+ d_perpendicular = fabs (s*dx - c*dy);
- if (!dial->button &&
- (d_perpendicular < dial->pointer_width/2) &&
- (d_parallel > - dial->pointer_width))
+ if (!dial->button &&
+ (d_perpendicular < dial->pointer_width/2) &&
+ (d_parallel > - dial->pointer_width))
{
gtk_grab_add (widget);
- dial->button = event->button;
+ dial->button = event->button;
- gtk_dial_update_mouse (dial, event->x, event->y);
+ gtk_dial_update_mouse (dial, event->x, event->y);
}
return FALSE;
dial = GTK_DIAL (widget);
- if (dial->button == event->button)
+ if (dial->button == event->button)
{
gtk_grab_remove (widget);
- dial->button = 0;
+ dial->button = 0;
- if (dial->policy == GTK_UPDATE_DELAYED)
- gtk_timeout_remove (dial->timer);
+ if (dial->policy == GTK_UPDATE_DELAYED)
+ gtk_timeout_remove (dial->timer);
- if ((dial->policy != GTK_UPDATE_CONTINUOUS) &&
- (dial->old_value != dial->adjustment->value))
- g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+ if ((dial->policy != GTK_UPDATE_CONTINUOUS) &&
+ (dial->old_value != dial->adjustment->value))
+ g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
}
return FALSE;
dial = GTK_DIAL (widget);
- if (dial->button != 0)
+ if (dial->button != 0)
{
- x = event->x;
- y = event->y;
+ x = event->x;
+ y = event->y;
- if (event->is_hint || (event->window != widget->window))
- gdk_window_get_pointer (widget->window, &x, &y, &mods);
+ if (event->is_hint || (event->window != widget->window))
+ gdk_window_get_pointer (widget->window, &x, &y, &mods);
- switch (dial->button)
+ switch (dial->button)
{
case 1:
mask = GDK_BUTTON1_MASK;
g_return_val_if_fail (dial != NULL, FALSE);
g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE);
- if (dial->policy == GTK_UPDATE_DELAYED)
- g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+ if (dial->policy == GTK_UPDATE_DELAYED)
+ g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
return FALSE;
}
g_return_if_fail (dial != NULL);
g_return_if_fail (GTK_IS_DIAL (dial));
- xc = GTK_WIDGET(dial)->allocation.width / 2;
- yc = GTK_WIDGET(dial)->allocation.height / 2;
+ xc = GTK_WIDGET(dial)->allocation.width / 2;
+ yc = GTK_WIDGET(dial)->allocation.height / 2;
- old_value = dial->adjustment->value;
- dial->angle = atan2(yc-y, x-xc);
+ old_value = dial->adjustment->value;
+ dial->angle = atan2(yc-y, x-xc);
- if (dial->angle < -M_PI/2.)
- dial->angle += 2*M_PI;
+ if (dial->angle < -M_PI/2.)
+ dial->angle += 2*M_PI;
- if (dial->angle < -M_PI/6)
- dial->angle = -M_PI/6;
+ if (dial->angle < -M_PI/6)
+ dial->angle = -M_PI/6;
- if (dial->angle > 7.*M_PI/6.)
- dial->angle = 7.*M_PI/6.;
+ if (dial->angle > 7.*M_PI/6.)
+ dial->angle = 7.*M_PI/6.;
- dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) *
- (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.);
+ dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) *
+ (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.);
- if (dial->adjustment->value != old_value)
+ if (dial->adjustment->value != old_value)
{
- if (dial->policy == GTK_UPDATE_CONTINUOUS)
+ if (dial->policy == GTK_UPDATE_CONTINUOUS)
{
- g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+ g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
}
else
{
gtk_widget_queue_draw (GTK_WIDGET (dial));
- if (dial->policy == GTK_UPDATE_DELAYED)
+ if (dial->policy == GTK_UPDATE_DELAYED)
{
- if (dial->timer)
- gtk_timeout_remove (dial->timer);
+ if (dial->timer)
+ gtk_timeout_remove (dial->timer);
- dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
+ dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
(GtkFunction) gtk_dial_timer,
(gpointer) dial);
}
g_return_if_fail (dial != NULL);
g_return_if_fail (GTK_IS_DIAL (dial));
- new_value = dial->adjustment->value;
+ new_value = dial->adjustment->value;
- if (new_value < dial->adjustment->lower)
- new_value = dial->adjustment->lower;
+ if (new_value < dial->adjustment->lower)
+ new_value = dial->adjustment->lower;
- if (new_value > dial->adjustment->upper)
- new_value = dial->adjustment->upper;
+ if (new_value > dial->adjustment->upper)
+ new_value = dial->adjustment->upper;
- if (new_value != dial->adjustment->value)
+ if (new_value != dial->adjustment->value)
{
- dial->adjustment->value = new_value;
- g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+ dial->adjustment->value = new_value;
+ g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
}
- dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. /
- (dial->adjustment->upper - dial->adjustment->lower);
+ dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. /
+ (dial->adjustment->upper - dial->adjustment->lower);
gtk_widget_queue_draw (GTK_WIDGET (dial));
}
dial = GTK_DIAL (data);
- if ((dial->old_value != adjustment->value) ||
- (dial->old_lower != adjustment->lower) ||
- (dial->old_upper != adjustment->upper))
+ if ((dial->old_value != adjustment->value) ||
+ (dial->old_lower != adjustment->lower) ||
+ (dial->old_upper != adjustment->upper))
{
gtk_dial_update (dial);
- dial->old_value = adjustment->value;
- dial->old_lower = adjustment->lower;
- dial->old_upper = adjustment->upper;
+ dial->old_value = adjustment->value;
+ dial->old_lower = adjustment->lower;
+ dial->old_upper = adjustment->upper;
}
}
dial = GTK_DIAL (data);
- if (dial->old_value != adjustment->value)
+ if (dial->old_value != adjustment->value)
{
gtk_dial_update (dial);
- dial->old_value = adjustment->value;
+ dial->old_value = adjustment->value;
}
}
<!-- example-end -->
<programlisting role="C">
<!-- example-start gtkdial dial_test.c -->
+
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
{
char buffer[16];
- sprintf(buffer,"%4.2f",adjustment->value);
+ sprintf(buffer,"%4.2f",adjustment->value);
gtk_label_set_text (GTK_LABEL (label), buffer);
}
gtk_window_set_title (GTK_WINDOW (window), "Dial");
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (exit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (exit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
vbox = gtk_vbox_new (FALSE, 5);
gtk_container_add (GTK_CONTAINER (window), vbox);
- gtk_widget_show(vbox);
+ gtk_widget_show (vbox);
frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (vbox), frame);
gtk_widget_show (frame);
- adjustment = GTK_ADJUSTMENT(gtk_adjustment_new (0, 0, 100, 0.01, 0.1, 0));
+ adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 100, 0.01, 0.1, 0));
- dial = gtk_dial_new(adjustment);
- gtk_dial_set_update_policy (GTK_DIAL(dial), GTK_UPDATE_DELAYED);
+ dial = gtk_dial_new (adjustment);
+ gtk_dial_set_update_policy (GTK_DIAL (dial), GTK_UPDATE_DELAYED);
/* gtk_widget_set_size_request (dial, 100, 100); */
gtk_container_add (GTK_CONTAINER (frame), dial);
gtk_widget_show (dial);
- label = gtk_label_new("0.00");
- gtk_box_pack_end (GTK_BOX(vbox), label, 0, 0, 0);
+ label = gtk_label_new ("0.00");
+ gtk_box_pack_end (GTK_BOX (vbox), label, 0, 0, 0);
gtk_widget_show (label);
- g_signal_connect (GTK_OBJECT(adjustment), "value_changed",
- GTK_SIGNAL_FUNC (value_changed), label);
+ g_signal_connect (G_OBJECT (adjustment), "value_changed",
+ G_CALLBACK (value_changed), (gpointer) label);
gtk_widget_show (window);
* Boston, MA 02111-1307, USA.
*/
+#include <stdlib.h>
#include <gtk/gtk.h>
/* Backing pixmap for drawing area */
GdkEventConfigure *event )
{
if (pixmap)
- g_object_unref(pixmap);
+ g_object_unref (pixmap);
- pixmap = gdk_pixmap_new(widget->window,
- widget->allocation.width,
- widget->allocation.height,
- -1);
+ pixmap = gdk_pixmap_new (widget->window,
+ widget->allocation.width,
+ widget->allocation.height,
+ -1);
gdk_draw_rectangle (pixmap,
- widget->style->white_gc,
+ widget->style->white_gc,
TRUE,
0, 0,
- widget->allocation.width,
- widget->allocation.height);
+ widget->allocation.width,
+ widget->allocation.height);
return TRUE;
}
static gint expose_event( GtkWidget *widget,
GdkEventExpose *event )
{
- gdk_draw_drawable(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- pixmap,
- event->area.x, event->area.y,
- event->area.x, event->area.y,
- event->area.width, event->area.height);
+ gdk_draw_drawable (widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
return FALSE;
}
update_rect.width = 10;
update_rect.height = 10;
gdk_draw_rectangle (pixmap,
- widget->style->black_gc,
+ widget->style->black_gc,
TRUE,
update_rect.x, update_rect.y,
update_rect.width, update_rect.height);
static gint button_press_event( GtkWidget *widget,
GdkEventButton *event )
{
- if (event->button == 1 && pixmap != NULL)
- draw_brush (widget, event->x, event->y);
+ if (event->button == 1 && pixmap != NULL)
+ draw_brush (widget, event->x, event->y);
return TRUE;
}
int x, y;
GdkModifierType state;
- if (event->is_hint)
- gdk_window_get_pointer (event->window, &x, &y, &state);
+ if (event->is_hint)
+ gdk_window_get_pointer (event->window, &x, &y, &state);
else
{
- x = event->x;
- y = event->y;
- state = event->state;
+ x = event->x;
+ y = event->y;
+ state = event->state;
}
if (state & GDK_BUTTON1_MASK && pixmap != NULL)
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (quit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (quit), NULL);
/* Create the drawing area */
/* Signals used to handle backing pixmap */
- g_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
- (GtkSignalFunc) expose_event, NULL);
- g_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
- (GtkSignalFunc) configure_event, NULL);
+ g_signal_connect (G_OBJECT (drawing_area), "expose_event",
+ G_CALLBACK (expose_event), NULL);
+ g_signal_connect (G_OBJECT (drawing_area),"configure_event",
+ G_CALLBACK (configure_event), NULL);
/* Event signals */
- g_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
- (GtkSignalFunc) motion_notify_event, NULL);
- g_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
- (GtkSignalFunc) button_press_event, NULL);
+ g_signal_connect (G_OBJECT (drawing_area), "motion_notify_event",
+ G_CALLBACK (motion_notify_event), NULL);
+ g_signal_connect (G_OBJECT (drawing_area), "button_press_event",
+ G_CALLBACK (button_press_event), NULL);
gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK
button = gtk_button_new_with_label ("Quit");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
gtk_widget_show (button);
gtk_widget_show (window);
configure_event (GtkWidget *widget, GdkEventConfigure *event)
{
if (pixmap)
- g_object_unref(pixmap);
+ g_object_unref (pixmap);
- pixmap = gdk_pixmap_new(widget->window,
- widget->allocation.width,
- widget->allocation.height,
- -1);
+ pixmap = gdk_pixmap_new (widget->window,
+ widget->allocation.width,
+ widget->allocation.height,
+ -1);
gdk_draw_rectangle (pixmap,
- widget->style->white_gc,
+ widget->style->white_gc,
TRUE,
0, 0,
- widget->allocation.width,
- widget->allocation.height);
+ widget->allocation.width,
+ widget->allocation.height);
return TRUE;
}
static gint
expose_event (GtkWidget *widget, GdkEventExpose *event)
{
- gdk_draw_drawable(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- pixmap,
- event->area.x, event->area.y,
- event->area.x, event->area.y,
- event->area.width, event->area.height);
+ gdk_draw_drawable (widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
return FALSE;
}
switch (source)
{
case GDK_SOURCE_MOUSE:
- gc = widget->style->dark_gc[GTK_WIDGET_STATE (widget)];
+ gc = widget->style->dark_gc[GTK_WIDGET_STATE (widget)];
break;
case GDK_SOURCE_PEN:
- gc = widget->style->black_gc;
+ gc = widget->style->black_gc;
break;
case GDK_SOURCE_ERASER:
- gc = widget->style->white_gc;
+ gc = widget->style->white_gc;
break;
default:
- gc = widget->style->light_gc[GTK_WIDGET_STATE (widget)];
+ gc = widget->style->light_gc[GTK_WIDGET_STATE (widget)];
}
update_rect.x = x - 10 * pressure;
static void
print_button_press (GdkDevice *device)
{
- g_print("Button press on device '%s'\n", device->name);
+ g_print ("Button press on device '%s'\n", device->name);
}
static gint
button_press_event (GtkWidget *widget, GdkEventButton *event)
{
- print_button_press (event->device);
+ print_button_press (event->device);
- if (event->button == 1 && pixmap != NULL) {
+ if (event->button == 1 && pixmap != NULL) {
gdouble pressure;
gdk_event_get_axis ((GdkEvent *)event, GDK_AXIS_PRESSURE, &pressure);
- draw_brush (widget, event->device->source, event->x, event->y, pressure);
+ draw_brush (widget, event->device->source, event->x, event->y, pressure);
}
return TRUE;
gdouble pressure;
GdkModifierType state;
- if (event->is_hint)
+ if (event->is_hint)
{
- gdk_device_get_state (event->device, event->window, NULL, &state);
+ gdk_device_get_state (event->device, event->window, NULL, &state);
gdk_event_get_axis ((GdkEvent *)event, GDK_AXIS_X, &x);
gdk_event_get_axis ((GdkEvent *)event, GDK_AXIS_Y, &y);
gdk_event_get_axis ((GdkEvent *)event, GDK_AXIS_PRESSURE, &pressure);
}
else
{
- x = event->x;
- y = event->y;
+ x = event->x;
+ y = event->y;
gdk_event_get_axis ((GdkEvent *)event, GDK_AXIS_PRESSURE, &pressure);
- state = event->state;
+ state = event->state;
}
if (state & GDK_BUTTON1_MASK && pixmap != NULL)
- draw_brush (widget, event->device->source, x, y, pressure);
+ draw_brush (widget, event->device->source, x, y, pressure);
return TRUE;
}
{
inputd = gtk_input_dialog_new();
- g_signal_connect (GTK_OBJECT(inputd), "destroy",
- (GtkSignalFunc)input_dialog_destroy, &inputd);
- g_signal_connect_swapped (GTK_OBJECT(GTK_INPUT_DIALOG(inputd)->close_button),
- "clicked",
- (GtkSignalFunc)gtk_widget_hide,
- GTK_OBJECT(inputd));
- gtk_widget_hide ( GTK_INPUT_DIALOG(inputd)->save_button);
+ g_signal_connect (G_OBJECT (inputd), "destroy",
+ G_CALLBACK (input_dialog_destroy), (gpointer) &inputd);
+ g_signal_connect_swapped (G_OBJECT (GTK_INPUT_DIALOG (inputd)->close_button),
+ "clicked",
+ G_CALLBACK (gtk_widget_hide),
+ G_OBJECT (inputd));
+ gtk_widget_hide (GTK_INPUT_DIALOG (inputd)->save_button);
gtk_widget_show (inputd);
}
else
{
- if (!GTK_WIDGET_MAPPED(inputd))
- gtk_widget_show(inputd);
+ if (!GTK_WIDGET_MAPPED (inputd))
+ gtk_widget_show (inputd);
else
- gdk_window_raise(inputd->window);
+ gdk_window_raise (inputd->window);
}
}
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
- g_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (quit), NULL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (quit), NULL);
/* Create the drawing area */
/* Signals used to handle backing pixmap */
- g_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
- (GtkSignalFunc) expose_event, NULL);
- g_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
- (GtkSignalFunc) configure_event, NULL);
+ g_signal_connect (G_OBJECT (drawing_area), "expose_event",
+ G_CALLBACK (expose_event), NULL);
+ g_signal_connect (G_OBJECT(drawing_area),"configure_event",
+ G_CALLBACK (configure_event), NULL);
/* Event signals */
- g_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
- (GtkSignalFunc) motion_notify_event, NULL);
- g_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
- (GtkSignalFunc) button_press_event, NULL);
+ g_signal_connect (G_OBJECT (drawing_area), "motion_notify_event",
+ G_CALLBACK (motion_notify_event), NULL);
+ g_signal_connect (G_OBJECT (drawing_area), "button_press_event",
+ G_CALLBACK (button_press_event), NULL);
gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK
button = gtk_button_new_with_label ("Input Dialog");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
- g_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (create_input_dialog), NULL);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (create_input_dialog), NULL);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Quit");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
- g_signal_connect_swapped (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT (window));
+ g_signal_connect_swapped (G_OBJECT (button), "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (window));
gtk_widget_show (button);
gtk_widget_show (window);
</sect2>
</sect1>
-</appendix>
-
-<!-- ***************************************************************** -->
-<appendix id="app-ListWidget">
-<title>List Widget</title>
-
-<para>NOTE: The List widget has been superseded by the CList widget. It is
-detailed here just for completeness.</para>
-
-<para>The List widget is designed to act as a vertical container for
-widgets that should be of the type ListItem.</para>
-
-<para>A List widget has its own window to receive events and its own
-background color which is usually white. As it is directly derived
-from a Container it can be treated as such by using the
-GTK_CONTAINER(List) macro, see the Container widget for more on
-this. One should already be familiar with the usage of a GList and
-its related functions g_list_*() to be able to use the List widget
-to it full extent.</para>
-
-<para>There is one field inside the structure definition of the List
-widget that will be of greater interest to us, this is:</para>
-
-<programlisting role="C">
-struct _GtkList
-{
- ...
- GList *selection;
- guint selection_mode;
- ...
-};
-</programlisting>
-
-<para>The selection field of a List points to a linked list of all items
-that are currently selected, or NULL if the selection is empty. So to
-learn about the current selection we read the GTK_LIST()->selection
-field, but do not modify it since the internal fields are maintained
-by the gtk_list_*() functions.</para>
-
-<para>The selection_mode of the List determines the selection facilities
-of a List and therefore the contents of the GTK_LIST()->selection
-field. The selection_mode may be one of the following:</para>
-
-<itemizedlist>
-<listitem><simpara> <literal>GTK_SELECTION_SINGLE</literal> - The selection is either NULL
- or contains a GList pointer
- for a single selected item.</simpara>
-</listitem>
-<listitem><simpara> <literal>GTK_SELECTION_BROWSE</literal> - The selection is NULL if the list
- contains no widgets or insensitive
- ones only, otherwise it contains
- a GList pointer for one GList
- structure, and therefore exactly
- one list item.</simpara>
-</listitem>
-<listitem><simpara> <literal>GTK_SELECTION_MULTIPLE</literal> - The selection is NULL if no list
- items are selected or a GList pointer
- for the first selected item. That
- in turn points to a GList structure
- for the second selected item and so
- on.</simpara>
-</listitem>
-<listitem><simpara> <literal>GTK_SELECTION_EXTENDED</literal> - The selection is always NULL.</simpara>
-</listitem>
-</itemizedlist>
-
-<para>The default is <literal>GTK_SELECTION_MULTIPLE</literal>.</para>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-SelectionSignals">
-<title>Signals</title>
-
-<programlisting role="C">
-void selection_changed( GtkList *list );
-</programlisting>
-
-<para>This signal will be invoked whenever the selection field of a List
-has changed. This happens when a child of thekList got selected or
-deselected.</para>
-
-<programlisting role="C">
-void select_child( GtkList *list,
- GtkWidget *child);
-</programlisting>
-
-<para>This signal is invoked when a child of the List is about to get
-selected. This happens mainly on calls to gtk_list_select_item(),
-gtk_list_select_child(), button presses and sometimes indirectly
-triggered on some else occasions where children get added to or
-removed from the List.</para>
-
-<programlisting role="C">
-void unselect_child( GtkList *list,
- GtkWidget *child );
-</programlisting>
-
-<para>This signal is invoked when a child of the List is about to get
-deselected. This happens mainly on calls to gtk_list_unselect_item(),
-gtk_list_unselect_child(), button presses and sometimes indirectly
-triggered on some else occasions where children get added to or
-removed from the List.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkListFunctions">
-<title>Functions</title>
-
-<programlisting role="C">
-guint gtk_list_get_type( void );
-</programlisting>
-
-<para>Returns the "GtkList" type identifier.</para>
-
-<programlisting role="C">
-GtkWidget *gtk_list_new( void );
-</programlisting>
-
-<para>Create a new List object. The new widget is returned as a pointer
-to a GtkWidget object. NULL is returned on failure.</para>
-
-<programlisting role="C">
-void gtk_list_insert_items( GtkList *list,
- GList *items,
- gint position );
-</programlisting>
-
-<para>Insert list items into the list, starting at <literal>position</literal>.
-<literal>items</literal> is a doubly linked list where each nodes data pointer is
-expected to point to a newly created ListItem. The GList nodes of
-<literal>items</literal> are taken over by the list.</para>
-
-<programlisting role="C">
-void gtk_list_append_items( GtkList *list,
- GList *items);
-</programlisting>
-
-<para>Insert list items just like gtk_list_insert_items() at the end of the
-list. The GList nodes of <literal>items</literal> are taken over by the list.</para>
-
-<programlisting role="C">
-void gtk_list_prepend_items( GtkList *list,
- GList *items);
-</programlisting>
-
-<para>Insert list items just like gtk_list_insert_items() at the very
-beginning of the list. The GList nodes of <literal>items</literal> are taken over by
-the list.</para>
-
-<programlisting role="C">
-void gtk_list_remove_items( GtkList *list,
- GList *items);
-</programlisting>
-
-<para>Remove list items from the list. <literal>items</literal> is a doubly linked list
-where each nodes data pointer is expected to point to a direct child
-of list. It is the callers responsibility to make a call to
-g_list_free(items) afterwards. Also the caller has to destroy the list
-items himself.</para>
-
-<programlisting role="C">
-void gtk_list_clear_items( GtkList *list,
- gint start,
- gint end );
-</programlisting>
-
-<para>Remove and destroy list items from the list. A widget is affected if
-its current position within the list is in the range specified by
-<literal>start</literal> and <literal>end</literal>.</para>
-
-<programlisting role="C">
-void gtk_list_select_item( GtkList *list,
- gint item );
-</programlisting>
-
-<para>Invoke the select_child signal for a list item specified through its
-current position within the list.</para>
-
-<programlisting role="C">
-void gtk_list_unselect_item( GtkList *list,
- gint item);
-</programlisting>
-
-<para>Invoke the unselect_child signal for a list item specified through its
-current position within the list.</para>
-
-<programlisting role="C">
-void gtk_list_select_child( GtkList *list,
- GtkWidget *child);
-</programlisting>
-
-<para>Invoke the select_child signal for the specified child.</para>
-
-<programlisting role="C">
-void gtk_list_unselect_child( GtkList *list,
- GtkWidget *child);
-</programlisting>
-
-<para>Invoke the unselect_child signal for the specified child.</para>
-
-<programlisting role="C">
-gint gtk_list_child_position( GtkList *list,
- GtkWidget *child);
-</programlisting>
-
-<para>Return the position of <literal>child</literal> within the list. "-1" is returned on
-failure.</para>
-
-<programlisting role="C">
-void gtk_list_set_selection_mode( GtkList *list,
- GtkSelectionMode mode );
-</programlisting>
-
-<para>Set the selection mode MODE which can be of GTK_SELECTION_SINGLE,
-GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE or
-GTK_SELECTION_EXTENDED.</para>
-
-<programlisting role="C">
-GtkList *GTK_LIST( gpointer obj );
-</programlisting>
-
-<para>Cast a generic pointer to "GtkList *".</para>
-
-<programlisting role="C">
-GtkListClass *GTK_LIST_CLASS( gpointer class);
-</programlisting>
-
-<para>Cast a generic pointer to "GtkListClass *". </para>
-
-<programlisting role="C">
-gint GTK_IS_LIST( gpointer obj);
-</programlisting>
-
-<para>Determine if a generic pointer refers to a "GtkList" object.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkListExample">
-<title>Example</title>
-
-<para>Following is an example program that will print out the changes of the
-selection of a List, and lets you "arrest" list items into a prison
-by selecting them with the rightmost mouse button.</para>
-
-<programlisting role="C">
-<!-- example-start list list.c -->
-
-/* Include the GTK header files
- * Include stdio.h, we need that for the printf() function
- */
-#include <gtk/gtk.h>
-#include <stdio.h>
-
-/* This is our data identification string to store
- * data in list items
- */
-const gchar *list_item_data_key="list_item_data";
-
-
-/* prototypes for signal handler that we are going to connect
- * to the List widget
- */
-static void sigh_print_selection( GtkWidget *gtklist,
- gpointer func_data);
-
-static void sigh_button_event( GtkWidget *gtklist,
- GdkEventButton *event,
- GtkWidget *frame );
-
-
-/* Main function to set up the user interface */
-
-gint main( int argc,
- gchar *argv[] )
-{
- GtkWidget *separator;
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *scrolled_window;
- GtkWidget *frame;
- GtkWidget *gtklist;
- GtkWidget *button;
- GtkWidget *list_item;
- GList *dlist;
- guint i;
- gchar buffer[64];
-
-
- /* Initialize GTK (and subsequently GDK) */
-
- gtk_init(&argc, &argv);
-
-
- /* Create a window to put all the widgets in
- * connect gtk_main_quit() to the "destroy" event of
- * the window to handle window manager close-window-events
- */
- window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "GtkList Example");
- g_signal_connect(GTK_OBJECT(window),
- "destroy",
- GTK_SIGNAL_FUNC(gtk_main_quit),
- NULL);
-
-
- /* Inside the window we need a box to arrange the widgets
- * vertically */
- vbox=gtk_vbox_new(FALSE, 5);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
- gtk_container_add(GTK_CONTAINER(window), vbox);
- gtk_widget_show(vbox);
-
- /* This is the scrolled window to put the List widget inside */
- scrolled_window=gtk_scrolled_window_new(NULL, NULL);
- gtk_widget_set_size_request (scrolled_window, 250, 150);
- gtk_container_add(GTK_CONTAINER(vbox), scrolled_window);
- gtk_widget_show(scrolled_window);
-
- /* Create thekList widget.
- * Connect the sigh_print_selection() signal handler
- * function to the "selection_changed" signal of the List
- * to print out the selected items each time the selection
- * has changed */
- gtklist=gtk_list_new();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
- gtklist);
- gtk_widget_show(gtklist);
- gtk_signal_connect(GTK_OBJECT(gtklist),
- "selection_changed",
- GTK_SIGNAL_FUNC(sigh_print_selection),
- NULL);
-
- /* We create a "Prison" to put a list item in ;) */
- frame=gtk_frame_new("Prison");
- gtk_widget_set_size_request (frame, 200, 50);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 5);
- gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(vbox), frame);
- gtk_widget_show(frame);
-
- /* Connect the sigh_button_event() signal handler to the List
- * which will handle the "arresting" of list items
- */
- gtk_signal_connect(GTK_OBJECT(gtklist),
- "button_release_event",
- GTK_SIGNAL_FUNC(sigh_button_event),
- frame);
-
- /* Create a separator */
- separator=gtk_hseparator_new();
- gtk_container_add(GTK_CONTAINER(vbox), separator);
- gtk_widget_show(separator);
-
- /* Finally create a button and connect its "clicked" signal
- * to the destruction of the window */
- button=gtk_button_new_with_label("Close");
- gtk_container_add(GTK_CONTAINER(vbox), button);
- gtk_widget_show(button);
- gtk_signal_connect_object(GTK_OBJECT(button),
- "clicked",
- GTK_SIGNAL_FUNC(gtk_widget_destroy),
- GTK_OBJECT(window));
-
-
- /* Now we create 5 list items, each having its own
- * label and add them to the List using gtk_container_add()
- * Also we query the text string from the label and
- * associate it with the list_item_data_key for each list item
- */
- for (i=0; i<5; i++) {
- GtkWidget *label;
- gchar *string;
-
- sprintf(buffer, "ListItemContainer with Label #%d", i);
- label=gtk_label_new(buffer);
- list_item=gtk_list_item_new();
- gtk_container_add(GTK_CONTAINER(list_item), label);
- gtk_widget_show(label);
- gtk_container_add(GTK_CONTAINER(gtklist), list_item);
- gtk_widget_show(list_item);
- gtk_label_get(GTK_LABEL(label), &string);
- gtk_object_set_data(GTK_OBJECT(list_item),
- list_item_data_key,
- string);
- }
- /* Here, we are creating another 5 labels, this time
- * we use gtk_list_item_new_with_label() for the creation
- * we can't query the text string from the label because
- * we don't have the labels pointer and therefore
- * we just associate the list_item_data_key of each
- * list item with the same text string.
- * For adding of the list items we put them all into a doubly
- * linked list (GList), and then add them by a single call to
- * gtk_list_append_items().
- * Because we use g_list_prepend() to put the items into the
- * doubly linked list, their order will be descending (instead
- * of ascending when using g_list_append())
- */
- dlist=NULL;
- for (; i<10; i++) {
- sprintf(buffer, "List Item with Label %d", i);
- list_item=gtk_list_item_new_with_label(buffer);
- dlist=g_list_prepend(dlist, list_item);
- gtk_widget_show(list_item);
- gtk_object_set_data(GTK_OBJECT(list_item),
- list_item_data_key,
- "ListItem with integrated Label");
- }
- gtk_list_append_items(GTK_LIST(gtklist), dlist);
-
- /* Finally we want to see the window, don't we? ;) */
- gtk_widget_show(window);
-
- /* Fire up the main event loop of gtk */
- gtk_main();
-
- /* We get here after gtk_main_quit() has been called which
- * happens if the main window gets destroyed
- */
- return(0);
-}
-
-/* This is the signal handler that got connected to button
- * press/release events of the List
- */
-void sigh_button_event( GtkWidget *gtklist,
- GdkEventButton *event,
- GtkWidget *frame )
-{
- /* We only do something if the third (rightmost mouse button
- * was released
- */
- if (event->type==GDK_BUTTON_RELEASE &&
- event->button==3) {
- GList *dlist, *free_list;
- GtkWidget *new_prisoner;
-
- /* Fetch the currently selected list item which
- * will be our next prisoner ;)
- */
- dlist=GTK_LIST(gtklist)->selection;
- if (dlist)
- new_prisoner=GTK_WIDGET(dlist->data);
- else
- new_prisoner=NULL;
-
- /* Look for already imprisoned list items, we
- * will put them back into the list.
- * Remember to free the doubly linked list that
- * gtk_container_children() returns
- */
- dlist=gtk_container_children(GTK_CONTAINER(frame));
- free_list=dlist;
- while (dlist) {
- GtkWidget *list_item;
-
- list_item=dlist->data;
-
- gtk_widget_reparent(list_item, gtklist);
-
- dlist=dlist->next;
- }
- g_list_free(free_list);
-
- /* If we have a new prisoner, remove him from the
- * List and put him into the frame "Prison".
- * We need to unselect the item first.
- */
- if (new_prisoner) {
- GList static_dlist;
-
- static_dlist.data=new_prisoner;
- static_dlist.next=NULL;
- static_dlist.prev=NULL;
-
- gtk_list_unselect_child(GTK_LIST(gtklist),
- new_prisoner);
- gtk_widget_reparent(new_prisoner, frame);
- }
- }
-}
-
-/* This is the signal handler that gets called if List
- * emits the "selection_changed" signal
- */
-void sigh_print_selection( GtkWidget *gtklist,
- gpointer func_data )
-{
- GList *dlist;
-
- /* Fetch the doubly linked list of selected items
- * of the List, remember to treat this as read-only!
- */
- dlist=GTK_LIST(gtklist)->selection;
-
- /* If there are no selected items there is nothing more
- * to do than just telling the user so
- */
- if (!dlist) {
- g_print("Selection cleared\n");
- return;
- }
- /* Ok, we got a selection and so we print it
- */
- g_print("The selection is a ");
-
- /* Get the list item from the doubly linked list
- * and then query the data associated with list_item_data_key.
- * We then just print it */
- while (dlist) {
- GtkObject *list_item;
- gchar *item_data_string;
-
- list_item=GTK_OBJECT(dlist->data);
- item_data_string=g_object_get_data(G_OBJECT (list_item),
- list_item_data_key);
- g_print("%s ", item_data_string);
-
- dlist=dlist->next;
- }
- g_print("\n");
-}
-<!-- example-end -->
-</programlisting>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-ListItemWidget">
-<title>List Item Widget</title>
-
-<para>The ListItem widget is designed to act as a container holding up to
-one child, providing functions for selection/deselection just like the
-List widget requires them for its children.</para>
-
-<para>A ListItem has its own window to receive events and has its own
-background color which is usually white.</para>
-
-<para>As it is directly derived from an Item it can be treated as such by
-using the GTK_ITEM(ListItem) macro, see the Item widget for more on
-this. Usually a ListItem just holds a label to identify, e.g., a
-filename within a List -- therefore the convenience function
-gtk_list_item_new_with_label() is provided. The same effect can be
-achieved by creating a Label on its own, setting its alignment to
-xalign=0 and yalign=0.5 with a subsequent container addition to the
-ListItem.</para>
-
-<para>As one is not forced to add a GtkLabel to a GtkListItem, you could
-also add a GtkVBox or a GtkArrow etc. to the GtkListItem.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkListItemSignals">
-<title>Signals</title>
-
-<para>A GtkListItem does not create new signals on its own, but inherits
-the signals of a Item.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkListItemFunctions">
-<title>Functions</title>
-
-<programlisting role="C">
-guint gtk_list_item_get_type( void );
-</programlisting>
-
-<para>Returns the "GtkListItem" type identifier.</para>
-
-<programlisting role="C">
-GtkWidget *gtk_list_item_new( void );
-</programlisting>
-
-<para>Create a new ListItem object. The new widget is returned as a
-pointer to a GtkWidget object. NULL is returned on failure.</para>
-
-<programlisting role="C">
-GtkWidget *gtk_list_item_new_with_label( gchar *label );
-</programlisting>
-
-<para>Create a new ListItem object, having a single GtkLabel as the sole
-child. The new widget is returned as a pointer to a GtkWidget
-object. NULL is returned on failure.</para>
-
-<programlisting role="C">
-void gtk_list_item_select( GtkListItem *list_item );
-</programlisting>
-
-<para>This function is basically a wrapper around a call to gtk_item_select
-(GTK_ITEM (list_item)) which will emit the select signal. *Note
-GtkItem::, for more info.</para>
-
-<programlisting role="C">
-void gtk_list_item_deselect( GtkListItem *list_item );
-</programlisting>
-
-<para>This function is basically a wrapper around a call to
-gtk_item_deselect (GTK_ITEM (list_item)) which will emit the deselect
-signal. *Note GtkItem::, for more info.</para>
-
-<programlisting role="C">
-GtkListItem *GTK_LIST_ITEM( gpointer obj );
-</programlisting>
-
-<para>Cast a generic pointer to "GtkListItem *".</para>
-
-<programlisting role="C">
-GtkListItemClass *GTK_LIST_ITEM_CLASS( gpointer class );
-</programlisting>
-
-<para>Cast a generic pointer to GtkListItemClass*. *Note Standard Macros::,
-for more info.</para>
-
-<programlisting role="C">
-gint GTK_IS_LIST_ITEM( gpointer obj );
-</programlisting>
-
-<para>Determine if a generic pointer refers to a `GtkListItem' object.
-*Note Standard Macros::, for more info.</para>
-
-</sect1>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1 id="sec-GtkListItemExample">
-<title>Example</title>
-
-<para>Please see the List example on this, which covers the usage of a
-ListItem as well.</para>
-
-</sect1>
</appendix>
</book>