From 639c8cac7aba86a3ac4ddedc0273c0b52dfcc769 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 21 Feb 2002 00:40:16 +0000 Subject: [PATCH] screenshots of examples. * docs/tutorial/images/*.png: screenshots of examples. * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add screenshots, fix chapters 1-4 for GTK+ 2.0. * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. --- ChangeLog | 9 + ChangeLog.pre-2-0 | 9 + ChangeLog.pre-2-10 | 9 + ChangeLog.pre-2-2 | 9 + ChangeLog.pre-2-4 | 9 + ChangeLog.pre-2-6 | 9 + ChangeLog.pre-2-8 | 9 + demos/gtk-demo/Makefile.am | 1 + docs/tutorial/gtk-tut.sgml | 4457 ++++--------------------- docs/tutorial/images/arrow.png | Bin 0 -> 3802 bytes docs/tutorial/images/aspectframe.png | Bin 0 -> 5163 bytes docs/tutorial/images/base.png | Bin 0 -> 4462 bytes docs/tutorial/images/buttonbox.png | Bin 0 -> 23400 bytes docs/tutorial/images/buttons.png | Bin 0 -> 5269 bytes docs/tutorial/images/calendar.png | Bin 0 -> 11252 bytes docs/tutorial/images/colorsel.png | Bin 0 -> 28063 bytes docs/tutorial/images/entry.png | Bin 0 -> 5273 bytes docs/tutorial/images/eventbox.png | Bin 0 -> 3673 bytes docs/tutorial/images/filesel.png | Bin 0 -> 11063 bytes docs/tutorial/images/fixed.png | Bin 0 -> 5653 bytes docs/tutorial/images/frame.png | Bin 0 -> 5827 bytes docs/tutorial/images/gtkdial.png | Bin 0 -> 4758 bytes docs/tutorial/images/helloworld.png | Bin 0 -> 3264 bytes docs/tutorial/images/helloworld2.png | Bin 0 -> 3911 bytes docs/tutorial/images/label.png | Bin 0 -> 17358 bytes docs/tutorial/images/menu.png | Bin 0 -> 4857 bytes docs/tutorial/images/notebook.png | Bin 0 -> 8005 bytes docs/tutorial/images/packbox1.png | Bin 0 -> 10366 bytes docs/tutorial/images/packbox2.png | Bin 0 -> 9302 bytes docs/tutorial/images/paned.png | Bin 0 -> 12050 bytes docs/tutorial/images/progressbar.png | Bin 0 -> 6135 bytes docs/tutorial/images/radiobuttons.png | Bin 0 -> 3936 bytes docs/tutorial/images/rangewidgets.png | Bin 0 -> 9284 bytes docs/tutorial/images/rulers.png | Bin 0 -> 8466 bytes docs/tutorial/images/scribble.png | Bin 0 -> 5533 bytes docs/tutorial/images/scrolledwin.png | Bin 0 -> 7745 bytes docs/tutorial/images/spinbutton.png | Bin 0 -> 8515 bytes docs/tutorial/images/statusbar.png | Bin 0 -> 5155 bytes docs/tutorial/images/table.png | Bin 0 -> 4395 bytes docs/tutorial/images/tictactoe.png | Bin 0 -> 3100 bytes 40 files changed, 701 insertions(+), 3820 deletions(-) create mode 100644 docs/tutorial/images/arrow.png create mode 100644 docs/tutorial/images/aspectframe.png create mode 100644 docs/tutorial/images/base.png create mode 100644 docs/tutorial/images/buttonbox.png create mode 100644 docs/tutorial/images/buttons.png create mode 100644 docs/tutorial/images/calendar.png create mode 100644 docs/tutorial/images/colorsel.png create mode 100644 docs/tutorial/images/entry.png create mode 100644 docs/tutorial/images/eventbox.png create mode 100644 docs/tutorial/images/filesel.png create mode 100644 docs/tutorial/images/fixed.png create mode 100644 docs/tutorial/images/frame.png create mode 100644 docs/tutorial/images/gtkdial.png create mode 100644 docs/tutorial/images/helloworld.png create mode 100644 docs/tutorial/images/helloworld2.png create mode 100644 docs/tutorial/images/label.png create mode 100644 docs/tutorial/images/menu.png create mode 100644 docs/tutorial/images/notebook.png create mode 100644 docs/tutorial/images/packbox1.png create mode 100644 docs/tutorial/images/packbox2.png create mode 100644 docs/tutorial/images/paned.png create mode 100644 docs/tutorial/images/progressbar.png create mode 100644 docs/tutorial/images/radiobuttons.png create mode 100644 docs/tutorial/images/rangewidgets.png create mode 100644 docs/tutorial/images/rulers.png create mode 100644 docs/tutorial/images/scribble.png create mode 100644 docs/tutorial/images/scrolledwin.png create mode 100644 docs/tutorial/images/spinbutton.png create mode 100644 docs/tutorial/images/statusbar.png create mode 100644 docs/tutorial/images/table.png create mode 100644 docs/tutorial/images/tictactoe.png diff --git a/ChangeLog b/ChangeLog index 003fad356..319a018d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2002-02-21 Matthias Clasen + + * docs/tutorial/images/*.png: screenshots of examples. + + * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add + screenshots, fix chapters 1-4 for GTK+ 2.0. + + * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. + Thu Feb 21 00:31:41 2002 Soeren Sandmann * gtk/gtkspinbutton.c: Many cleanups and fixes. Draw exclusively diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 003fad356..319a018d0 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,12 @@ +2002-02-21 Matthias Clasen + + * docs/tutorial/images/*.png: screenshots of examples. + + * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add + screenshots, fix chapters 1-4 for GTK+ 2.0. + + * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. + Thu Feb 21 00:31:41 2002 Soeren Sandmann * gtk/gtkspinbutton.c: Many cleanups and fixes. Draw exclusively diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 003fad356..319a018d0 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,12 @@ +2002-02-21 Matthias Clasen + + * docs/tutorial/images/*.png: screenshots of examples. + + * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add + screenshots, fix chapters 1-4 for GTK+ 2.0. + + * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. + Thu Feb 21 00:31:41 2002 Soeren Sandmann * gtk/gtkspinbutton.c: Many cleanups and fixes. Draw exclusively diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 003fad356..319a018d0 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,12 @@ +2002-02-21 Matthias Clasen + + * docs/tutorial/images/*.png: screenshots of examples. + + * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add + screenshots, fix chapters 1-4 for GTK+ 2.0. + + * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. + Thu Feb 21 00:31:41 2002 Soeren Sandmann * gtk/gtkspinbutton.c: Many cleanups and fixes. Draw exclusively diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 003fad356..319a018d0 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,12 @@ +2002-02-21 Matthias Clasen + + * docs/tutorial/images/*.png: screenshots of examples. + + * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add + screenshots, fix chapters 1-4 for GTK+ 2.0. + + * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. + Thu Feb 21 00:31:41 2002 Soeren Sandmann * gtk/gtkspinbutton.c: Many cleanups and fixes. Draw exclusively diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 003fad356..319a018d0 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,12 @@ +2002-02-21 Matthias Clasen + + * docs/tutorial/images/*.png: screenshots of examples. + + * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add + screenshots, fix chapters 1-4 for GTK+ 2.0. + + * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. + Thu Feb 21 00:31:41 2002 Soeren Sandmann * gtk/gtkspinbutton.c: Many cleanups and fixes. Draw exclusively diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 003fad356..319a018d0 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,12 @@ +2002-02-21 Matthias Clasen + + * docs/tutorial/images/*.png: screenshots of examples. + + * docs/tutorial/gtk-tut.sgml: remove deprecated widgets, add + screenshots, fix chapters 1-4 for GTK+ 2.0. + + * demos/gtk-demo/Makefile.am (INCLUDES): add -DGDK_PIXBUF_DISABLE_DEPRECATED. + Thu Feb 21 00:31:41 2002 Soeren Sandmann * gtk/gtkspinbutton.c: Many cleanups and fixes. Draw exclusively diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index 3b6918f43..021f74320 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -29,6 +29,7 @@ INCLUDES = @STRIP_BEGIN@ \ -I$(top_builddir)/gdk \ -DG_DISABLE_DEPRECATED \ -DGDK_DISABLE_DEPRECATED \ + -DGDK_PIXBUF_DISABLE_DEPRECATED \ -DGTK_DISABLE_DEPRECATED \ @GTK_DEBUG_FLAGS@ \ @GTK_DEP_CFLAGS@ \ diff --git a/docs/tutorial/gtk-tut.sgml b/docs/tutorial/gtk-tut.sgml index 3923b620b..0261a65e0 100755 --- a/docs/tutorial/gtk-tut.sgml +++ b/docs/tutorial/gtk-tut.sgml @@ -1,9 +1,12 @@ - + + +]> - March 1st 2001 - GTK+ 1.2 Tutorial + February 20, 2002 + GTK+ 2.0 Tutorial Tony @@ -13,9 +16,12 @@ Ian Main + + & the GTK team + - This is a tutorial on how to use GTK (the GIMP Toolkit) through its C + This is a tutorial on how to use GTK (the GIMP Toolkit) through its C interface. @@ -37,8 +43,10 @@ now been used in a large number of software projects, including the 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: +(Xlib in the case of the X windows system), and gdk-pixbuf, a library for +client-side image manipulation. + +The primary authors of GTK are: Peter Mattis @@ -52,6 +60,17 @@ jmacd@xcf.berkeley.edu +GTK is currently maintained by: + + + Owen Taylor +otaylor@redhat.com + + Tim Janik +timj@gtk.org + + + 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 @@ -61,13 +80,23 @@ functions). 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. +versions, such as g_malloc() that has enhanced debugging utilities. + +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. + + +As the last component, GTK uses the Pango library for internationalized +text output. + 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 @@ -115,11 +144,12 @@ improved. Please see the section on Contributing Getting Started 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 ftp.gtk.org. You can also view +other sources of GTK information on http://www.gtk.org/. GTK -uses GNU autoconf for configuration. Once untar'd, type ./configure ---help to see a list of options. +uses GNU autoconf for configuration. Once untar'd, type +./configure --help to see a list of options. The GTK source distribution also contains the complete source to all of the examples used in this tutorial, along with Makefiles to aid @@ -129,6 +159,14 @@ compilation. program possible. This program will create a 200x200 pixel window and has no way of exiting except to be killed by using the shell. + + + + + + + + @@ -153,14 +191,14 @@ int main( int argc, You can compile the above program with gcc using: -gcc base.c -o base `gtk-config --cflags --libs` +gcc base.c -o base `pkg-config --cflags --libs gtk-2.0` The meaning of the unusual compilation options is explained below in Compiling Hello World. -All programs will of course include gtk/gtk.h which declares the -variables, functions, structures, etc. that will be used in your GTK +All programs will of course include gtk/gtk.h which +declares the variables, functions, structures, etc. that will be used in your GTK application. The next line: @@ -169,12 +207,11 @@ application. gtk_init (&argc, &argv); -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 +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: @@ -237,6 +274,14 @@ occur. In our simple example, however, events are ignored. Now for a program with a widget (a button). It's the classic hello world a la GTK. + + + + + + + + @@ -350,18 +395,21 @@ int main( int argc, To compile use: -gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \ - `gtk-config --libs` +gcc -Wall -g helloworld.c -o helloworld `pkg-config --cflags gtk-2.0` \ + `pkg-config --libs gtk-2.0` -This uses the program gtk-config, which comes with GTK. This -program "knows" what compiler switches are needed to compile programs -that use GTK. gtk-config --cflags will output a list of include -directories for the compiler to look in, and gtk-config --libs +This uses the program pkg-config, which can be obtained from +www.freedesktop.org. This program +reads the .pc which comes with GTK to determine what +compiler switches are needed to compile programs that use GTK. +pkg-config --cflags gtk+-2.0 will output a list of include +directories for the compiler to look in, and +pkg-config --libs gtk+-2.0 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 -`gtk-config --cflags --libs`. +pkg-config --cflags --libs gtk+-2.0. Note that the type of single quote used in the compile command above is significant. @@ -369,31 +417,44 @@ is significant. The libraries that are usually linked in are: -The GTK library (-lgtk), the widget library, based on top of GDK. +The GTK library (-lgtk), the widget library, +based on top of GDK. + + +The GDK library (-lgdk), the Xlib wrapper. + + +The gdk-pixbuf library (-lgdk_pixbuf), the image +manipulation library. -The GDK library (-lgdk), the Xlib wrapper. +The Pango library (-lpango) for internationalized +text. -The gmodule library (-lgmodule), which is used to load run time -extensions. +The gobject library (-lgobject), containing the +type system on which GTK is based. -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 +The gmodule library (-lgmodule), which is used +to load run time extensions. + + +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 GLib for details. -The Xlib library (-lX11) which is used by GDK. +The Xlib library (-lX11) which is used by GDK. -The Xext library (-lXext). This contains code for shared memory -pixmaps and other X extensions. +The Xext library (-lXext). This contains code +for shared memory pixmaps and other X extensions. -The math library (-lm). This is used by GTK for various -purposes. +The math library (-lm). This is used by GTK +for various purposes. @@ -403,9 +464,16 @@ purposes. Theory of Signals and Callbacks + +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. + + Before we look in detail at helloworld, 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. This passing of control is done using the idea of "signals". (Note @@ -423,10 +491,10 @@ catch these signals and call the appropriate function. This is done by using a function such as: -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 ); where the first argument is the widget which will be emitting the @@ -444,23 +512,22 @@ void callback_func( GtkWidget *widget, 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. +argument to the g_signal_connect() function as shown above. 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. +different calling parameters. Another call used in the helloworld example, is: -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 ); -gtk_signal_connect_object() is the same as gtk_signal_connect() except +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 @@ -470,14 +537,14 @@ void callback_func( GtkObject *object ); 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 helloworld example. 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. @@ -498,6 +565,8 @@ also be attached to these events. These events are: button_release_event + scroll_event + motion_notify_event delete_event @@ -536,24 +605,18 @@ also be attached to these events. These events are: proximity_out_event - drag_begin_event - - drag_request_event - - drag_end_event - - drop_enter_event + visibility_notify_event - drop_leave_event + client_event - drop_data_available_event + no_expose_event - other_event + window_state_event 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 name parameter. The callback function for events has a slightly different form than that for signals: @@ -564,8 +627,8 @@ gint callback_func( GtkWidget *widget, gpointer callback_data ); -GdkEvent is a C union structure whose type will depend upon which -of the above events has occurred. In order for us to tell which event +GdkEvent is a C union 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 type member that reflects the event being issued. The other components of the event structure will depend upon the type of the @@ -595,30 +658,31 @@ event. Possible values for the type are: 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 So, to connect a callback function to one of these events we would use something like: -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); This assumes that button is a Button widget. Now, when the mouse is over the button and a mouse button is pressed, the function -button_press_callback will be called. This function may be -declared as: +button_press_callback() will be called. This function may be declared as: static gint button_press_callback( GtkWidget *widget, @@ -635,12 +699,39 @@ should be propagated further by the GTK event handling 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 -Advanced Event and Signal Handling for more details on this -propagation process. +Advanced Event and Signal Handling +for more details on this propagation process. For details on the GdkEvent data types, see the appendix entitled GDK Event Types. +The GDK selection and drag-and-drop APIs also emit a number of events which +are reflected in GTK by the signals. See Signals on the source widget and Signals on the destination widget +for details on the signatures of the callback functions for these signals: + + + selection_received + + selection_get + + drag_begin_event + + drag_end_event + + drag_data_delete + + drag_motion + + drag_drop + + drag_data_get + + drag_data_received + + + @@ -715,7 +806,7 @@ GtkWidget. These are used below to create a window and a button. GtkWidget *button; -Here is our gtk_init again. As before, this initializes the toolkit, +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, @@ -741,15 +832,15 @@ kill the window, or when we use the gtk_widget_destroy() call passing in the window widget as the object to destroy. The second is emitted when, in the "delete_event" handler, we return FALSE. -The GTK_OBJECT and GTK_SIGNAL_FUNC are macros that perform -type casting and checking for us, as well as aid the readability of +The G_OBJECT and G_CALLBACK are macros +that perform type casting and checking for us, as well as aid the readability of the code. - g_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC (delete_event), NULL); - g_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); This next function is used to set an attribute of a container object. @@ -780,8 +871,8 @@ NULL to the hello() callback function. Obviously, the "clicked" signal is emitted when we click the button with our mouse pointer. - g_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (hello), NULL); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (hello), NULL); We are also going to use this button to exit our program. This will @@ -791,14 +882,13 @@ it calls the first hello() callback function, and then this one in the 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(). +GtkWidget *widget as an argument, we use the g_signal_connect_swapped() +function here instead of straight g_signal_connect(). - 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 is a packing call, which will be explained in depth later on in @@ -872,17 +962,18 @@ callback, exiting GTK. 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. 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). +all defined in glib/glib.h (which gets included from +gtk.h). 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. @@ -891,16 +982,16 @@ is an object. More on Signal Handlers -Lets take another look at the gtk_signal_connect declaration. +Lets take another look at the gtk_signal_connect() declaration. -gint g_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 ); -Notice the gint return value? This is a tag that identifies your +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. @@ -908,8 +999,8 @@ in the order they were attached. This tag allows you to remove this callback from the list by using: -void gtk_signal_disconnect( GtkObject *object, - gint id ); +void g_signal_handler_disconnect( gpointer object, + gulong id ); So, by passing in the widget you wish to remove the handler from, and @@ -917,29 +1008,23 @@ the tag returned by one of the signal_connect functions, you can disconnect a signal handler. 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. -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 ); @@ -952,6 +1037,14 @@ void gtk_signal_handler_unblock_by_data( GtkObject *object, better examples of callbacks. This will also introduce us to our next topic, packing widgets. + + + + + + + + @@ -1059,11 +1152,6 @@ button that will exit the program. You may also wish to play with the options to gtk_box_pack_start() while reading the next section. Try resizing the window, and observe the behavior. -Just as a side note, there is another useful define for -gtk_window_new() - GTK_WINDOW_DIALOG. This interacts with the -window manager a little differently and should be used for transient -windows. - @@ -1073,7 +1161,7 @@ windows. When creating an application, you'll want to put more than one widget inside a window. Our first helloworld 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. @@ -1124,7 +1212,7 @@ different styles. - + @@ -1134,14 +1222,14 @@ call to gtk_box_pack is shorthand for the call to pack each of the 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). -This is the declaration of the gtk_box_pack_start function. +This is the declaration of the gtk_box_pack_start() function. void gtk_box_pack_start( GtkBox *box, GtkWidget *child, - gint expand, - gint fill, - gint padding ); + gboolean expand, + gboolean fill, + guint padding ); The first argument is the box you are packing the object into, the @@ -1155,7 +1243,7 @@ allotted to it (TRUE); or the box is shrunk to just fit the widgets (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. +of gtk_box_pack_start() or gtk_box_pack_end(). The fill argument to the gtk_box_pack functions control whether the extra space is allocated to the objects themselves (TRUE), or as extra @@ -1165,14 +1253,14 @@ if the expand argument is also TRUE. When creating a new box, the function looks like this: -GtkWidget *gtk_hbox_new (gint homogeneous, - gint spacing); +GtkWidget *gtk_hbox_new ( gboolean homogeneous, + gint spacing ); -The homogeneous argument to gtk_hbox_new (and the same for -gtk_vbox_new) controls whether each object in the box has the same +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 expand argument was always turned on. What's the difference between spacing (set when the box is created) @@ -1183,7 +1271,7 @@ following figure should make it clearer: - + @@ -1216,11 +1304,11 @@ gint delete_event( GtkWidget *widget, /* 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; @@ -1487,7 +1575,7 @@ int main( int argc, gtk_main (); /* Control returns here when gtk_main_quit() is called, but not when - * gtk_exit is used. */ + * exit() is used. */ return 0; } @@ -1506,12 +1594,12 @@ extremely useful in certain situations. Using tables, we create a grid that we can place widgets in. The widgets may take up as many spaces as we specify. -The first thing to look at, of course, is the gtk_table_new function: +The first thing to look at, of course, is the gtk_table_new() function: -GtkWidget *gtk_table_new( gint rows, - gint columns, - gint homogeneous ); +GtkWidget *gtk_table_new( guint rows, + guint columns, + gboolean homogeneous ); The first argument is the number of rows to make in the table, while @@ -1540,16 +1628,16 @@ and columns = 2, the layout would look something like this: To place a widget into a box, use the following function: -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 ); The first argument ("table") is the table you've created and the @@ -1557,7 +1645,7 @@ second ("child") the widget you wish to place in the table. 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 only, left_attach would be = 1, right_attach = 2, top_attach = 1, bottom_attach = 2. @@ -1570,40 +1658,50 @@ be bitwise OR'ed together to allow multiple options. These options are: - -GTK_FILL - If the table box is larger than the widget, and + + +GTK_FILL +If the table box is larger than the widget, and GTK_FILL is specified, the widget will expand to use all the room -available. +available. + -GTK_SHRINK - If the table widget was allocated less space + +GTK_SHRINK +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 GTK_SHRINK is specified, the widgets will shrink -with the table. +with the table. + -GTK_EXPAND - This will cause the table to expand to use up -any remaining space in the window. + +GTK_EXPAND +This will cause the table to expand to use up +any remaining space in the window. - + + Padding is just like in boxes, creating a clear area around the widget specified in pixels. -gtk_table_attach() has a LOT of options. So, there's a shortcut: +gtk_table_attach() has a lot of options. +So, there's a shortcut: 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 ); -The X and Y options default to GTK_FILL | GTK_EXPAND, and X and Y -padding are set to 0. The rest of the arguments are identical to the +The X and Y options default to GTK_FILL | GTK_EXPAND, +and X and Y padding are set to 0. The rest of the arguments are identical to the previous function. We also have gtk_table_set_row_spacing() and @@ -1612,16 +1710,16 @@ the specified row or column. void gtk_table_set_row_spacing( GtkTable *table, - gint row, - gint spacing ); + guint row, + guint spacing ); and void gtk_table_set_col_spacing ( GtkTable *table, - gint column, - gint spacing ); + guint column, + guint spacing ); Note that for columns, the space goes to the right of the column, and @@ -1631,14 +1729,14 @@ for rows, the space goes below the row. void gtk_table_set_row_spacings( GtkTable *table, - gint spacing ); + guint spacing ); And, void gtk_table_set_col_spacings( GtkTable *table, - gint spacing ); + guint spacing ); Note that with these calls, the last row and last column do not get @@ -1658,7 +1756,7 @@ Which means it should look something like this: - + @@ -1776,7 +1874,7 @@ int main( int argc, The general steps to creating a widget in GTK are: - gtk_*_new - one of various functions to create a new widget. + gtk_*_new() - one of various functions to create a new widget. These are all detailed in this section. @@ -1813,6 +1911,7 @@ is always done using macros that both test the ability to cast the given item, and perform the cast. Some common ones you will see are: + G_OBJECT (object) GTK_WIDGET (widget) GTK_OBJECT (object) GTK_SIGNAL_FUNC (function) @@ -1826,15 +1925,15 @@ examples, and can usually tell when to use them simply by looking at the function's declaration. 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 -GTK_OBJECT() macro. +G_OBJECT() macro. For example: -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); This casts the button into an object, and provides a cast for the @@ -1848,8 +1947,9 @@ containers. 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. +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. @@ -1857,18 +1957,19 @@ learn how a widget works just by looking at the function declarations. Widget Hierarchy -For your reference, here is the class hierarchy tree used to implement widgets. +For your reference, here is the class hierarchy tree used to implement +widgets. (Deprecated widgets and auxiliary classes have been omitted.) +GObject + | GtkObject +GtkWidget | +GtkMisc | | +GtkLabel - | | | +GtkAccelLabel - | | | `GtkTipsQuery + | | | `GtkAccelLabel | | +GtkArrow - | | +GtkImage - | | `GtkPixmap + | | `GtkImage | +GtkContainer | | +GtkBin | | | +GtkAlignment @@ -1881,18 +1982,18 @@ learn how a widget works just by looking at the function declarations. | | | | `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 @@ -1904,34 +2005,31 @@ learn how a widget works just by looking at the function declarations. | | | | `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 @@ -1945,13 +2043,17 @@ learn how a widget works just by looking at the function declarations. | +GtkSeparator | | +GtkHSeparator | | `GtkVSeparator + | +GtkInvisible | +GtkPreview - | `GtkProgress - | `GtkProgressBar - +GtkData - | +GtkAdjustment - | `GtkTooltips - `GtkItemFactory + | `GtkProgressBar + +GtkAdjustment + +GtkCellRenderer + | +GtkCellRendererPixbuf + | +GtkCellRendererText + | +GtkCellRendererToggle + +GtkItemFactory + +GtkTooltips + `GtkTreeViewColumn @@ -1969,13 +2071,20 @@ GtkAlignment GtkArrow GtkBin GtkBox +GtkButton +GtkCheckButton +GtkFixed GtkImage -GtkItem GtkLabel -GtkPixmap +GtkMenuItem +GtkNotebook +GtkPaned +GtkRadioButton +GtkRange GtkScrolledWindow GtkSeparator GtkTable +GtkToolbar GtkAspectFrame GtkFrame GtkVBox @@ -1986,12 +2095,14 @@ GtkHSeparator 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. +is the testgtk program that comes with GTK. It can be found in +tests/testgtk.c. + + The Button Widget @@ -2014,6 +2125,14 @@ 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. + + + + + + + + @@ -2330,6 +2449,14 @@ the second will emit its "toggled" signal (to report becoming active). The following example creates a radio button group with three buttons. + + + + + + + + @@ -2957,6 +3084,14 @@ 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. + + + + + + + + @@ -3352,6 +3487,14 @@ first two characters and eight and ninth characters. makes use of the Frame widget to better demonstrate the label styles. You can ignore this for now as the Frame widget is explained later on. + + + + + + + + @@ -3503,6 +3646,14 @@ point. The shadow_type argument may take one of these values: Here's a brief example to illustrate their use. + + + + + + + + @@ -3890,6 +4041,14 @@ gtk_progress_bar_update function in the same manner. Here is an example of the progress bar, updated using timeouts. This code also shows you how to reset the Progress Bar. + + + + + + + + @@ -4706,6 +4865,14 @@ ruler spans from 7 to 13 with a mark every 100 pixels, while the 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. + + + + + + + + @@ -4844,6 +5011,14 @@ stack with the given Context Identifier. pushing items onto the statusbar, and one for popping the last item back off. + + + + + + + + @@ -5021,6 +5196,14 @@ removed. The following code is an example of using an Entry widget. + + + + + + + + @@ -5367,6 +5550,14 @@ void gtk_spin_button_update( GtkSpinButton *spin_button ); It's example time again. + + + + + + + + @@ -5927,6 +6118,14 @@ and are: That just leaves us with the need to put all of this together into example code. + + + + + + + + /* @@ -6463,6 +6662,14 @@ drawing area. Clicking on it opens a color selection dialog, and changing the color in the color selection dialog changes the background color. + + + + + + + + @@ -6663,6 +6870,14 @@ 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. + + + + + + + + @@ -6754,6 +6969,14 @@ is created that is clipped to a small box, and set up so that a mouse-click on the label causes the program to exit. Resizing the window reveals varying amounts of the label. + + + + + + + + @@ -6894,6 +7117,14 @@ position. The following example illustrates how to use the Fixed Container. + + + + + + + + @@ -7107,6 +7338,14 @@ void gtk_frame_set_shadow_type( GtkFrame *frame, The following code example illustrates the use of the Frame widget. + + + + + + + + @@ -7202,6 +7441,14 @@ void gtk_aspect_frame_set( GtkAspectFrame *aspect_frame, drawing area whose aspect ratio will always be 2:1, no matter how the user resizes the top-level window. + + + + + + + + @@ -7296,6 +7543,14 @@ scrollbars, so that when the bottom portion is made smaller, the correct portions shrink instead of being pushed off the bottom of the window. + + + + + + + + @@ -7546,6 +7801,14 @@ void gtk_scrolled_window_add_with_viewport( GtkScrolledWindow *scrolled_window, into a scrolled window. I've only commented on the parts that may be new to you. + + + + + + + + @@ -7718,6 +7981,14 @@ GtkButtonBoxStyle gtk_vbutton_box_get_layout_default( void ); Here's an example that illustrates all the different layout settings for Button Boxes. + + + + + + + + @@ -8434,6 +8705,14 @@ prepended. The buttons allow you rotate the tab positions, add/remove the tabs and border, remove a page, change pages in both a forward and backward manner, and exit the program. + + + + + + + + @@ -8621,1870 +8900,21 @@ GTK applications. - -CList Widget - - + +Menu Widget -The CList widget has replaced the List widget (which is still -available). +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. -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. - - - -Creating a CList widget - -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? - -Not all columns have to be visible and can be used to store data that -is related to a certain cell in the list. - - -GtkWidget *gtk_clist_new ( gint columns ); - -GtkWidget *gtk_clist_new_with_titles( gint columns, - gchar *titles[] ); - - -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. - -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. - - - - - -Modes of operation - -There are several attributes that can be used to alter the behaviour of -a CList. First there is - - -void gtk_clist_set_selection_mode( GtkCList *clist, - GtkSelectionMode mode ); - - -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: - - - GTK_SELECTION_SINGLE - The selection is either NULL or contains -a GList pointer for a single selected item. - - - GTK_SELECTION_BROWSE - 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. - - - GTK_SELECTION_MULTIPLE - 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 default for the CList widget. - - - GTK_SELECTION_EXTENDED - The selection is always NULL. - - - -Others might be added in later revisions of GTK. - -We can also define what the border of the CList widget should look -like. It is done through - - -void gtk_clist_set_shadow_type( GtkCList *clist, - GtkShadowType border ); - - -The possible values for the second argument are - - - GTK_SHADOW_NONE - GTK_SHADOW_IN - GTK_SHADOW_OUT - GTK_SHADOW_ETCHED_IN - GTK_SHADOW_ETCHED_OUT - - - - - - -Working with titles - -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. - - -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 ); - - -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. - -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. - - -void gtk_clist_column_titles_show( GtkCList *clist ); - -void gtk_clist_column_titles_hide( GtkCList *clist ); - - -For titles to be really useful we need a mechanism to set and change -them, and this is done using - - -void gtk_clist_set_column_title( GtkCList *clist, - gint column, - gchar *title ); - - -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 - - -void gtk_clist_set_column_widget( GtkCList *clist, - gint column, - GtkWidget *widget ); - - -which should require no special explanation. - - - - - -Manipulating the list itself - -It is possible to change the justification for a column, and it is -done through - - -void gtk_clist_set_column_justification( GtkCList *clist, - gint column, - GtkJustification justification ); - - -The GtkJustification type can take the following values: - - -GTK_JUSTIFY_LEFT - The text in the column will begin from the -left edge. - - -GTK_JUSTIFY_RIGHT - The text in the column will begin from the -right edge. - - -GTK_JUSTIFY_CENTER - The text is placed in the center of the -column. - - -GTK_JUSTIFY_FILL - 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. - - - -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 - - -void gtk_clist_set_column_width( GtkCList *clist, - gint column, - gint width ); - - -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 - - -void gtk_clist_set_row_height( GtkCList *clist, - gint height ); - - -Again, note that the height is given in pixels. - -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. - - -void gtk_clist_moveto( GtkCList *clist, - gint row, - gint column, - gfloat row_align, - gfloat col_align ); - - -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. - -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. - - -GtkVisibility gtk_clist_row_is_visible( GtkCList *clist, - gint row ); - - -The return value is is one of the following: - - - GTK_VISIBILITY_NONE - GTK_VISIBILITY_PARTIAL - GTK_VISIBILITY_FULL - - -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 GTK_VISIBILITY_PARTIAL, 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. - -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 - - -void gtk_clist_set_foreground( GtkCList *clist, - gint row, - GdkColor *color ); - -void gtk_clist_set_background( GtkCList *clist, - gint row, - GdkColor *color ); - - -Please note that the colors must have been previously allocated. - - - - - -Adding rows to the list - -We can add rows in three ways. They can be prepended or appended to -the list using - - -gint gtk_clist_prepend( GtkCList *clist, - gchar *text[] ); - -gint gtk_clist_append( GtkCList *clist, - gchar *text[] ); - - -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 - - -void gtk_clist_insert( GtkCList *clist, - gint row, - gchar *text[] ); - - -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). - -Also, please note that the numbering of both rows and columns start at 0. - -To remove an individual row we use - - -void gtk_clist_remove( GtkCList *clist, - gint row ); - - -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. - - -void gtk_clist_clear( GtkCList *clist ); - - -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. - - -void gtk_clist_freeze( GtkCList * clist ); - -void gtk_clist_thaw( GtkCList * clist ); - - - - - - -Setting text and pixmaps in the cells - -A cell can contain a pixmap, text or both. To set them the following -functions are used. - - -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 ); - - -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 spacing 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. - -To read back the data, we instead use - - -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 ); - - -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: - - -gchar *mytext; - -gtk_clist_get_pixtext(clist, row, column, &mytext, NULL, NULL, NULL); - - -There is one more call that is related to what's inside a cell in the -clist, and that's - - -GtkCellType gtk_clist_get_cell_type( GtkCList *clist, - gint row, - gint column ); - - -which returns the type of data in a cell. The return value is one of - - - GTK_CELL_EMPTY - GTK_CELL_TEXT - GTK_CELL_PIXMAP - GTK_CELL_PIXTEXT - GTK_CELL_WIDGET - - -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. - - -void gtk_clist_set_shift( GtkCList *clist, - gint row, - gint column, - gint vertical, - gint horizontal ); - - - - - - -Storing data pointers - -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. - -The functions should be fairly self-explanatory by now. - - -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 ); - - - - - - -Working with selections - -There are also functions available that let us force the (un)selection -of a row. These are - - -void gtk_clist_select_row( GtkCList *clist, - gint row, - gint column ); - -void gtk_clist_unselect_row( GtkCList *clist, - gint row, - gint column ); - - -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. - - -gint gtk_clist_get_selection_info( GtkCList *clist, - gint x, - gint y, - gint *row, - gint *column ); - - -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... - - - - - -The signals that bring it together - -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: - - -select_row - This signal will send the following information, in -order: GtkCList *clist, gint row, gint column, GtkEventButton *event - - -unselect_row - When the user unselects a row, this signal is -activated. It sends the same information as select_row< - - -click_column - Send GtkCList *clist, gint column - - - -So if we want to connect a callback to select_row, the callback -function would be declared like this - - -void select_row_callback(GtkWidget *widget, - gint row, - gint column, - GdkEventButton *event, - gpointer data); - - -The callback is connected as usual with - - -gtk_signal_connect(GTK_OBJECT( clist), - "select_row", - GTK_SIGNAL_FUNC(select_row_callback), - NULL); - - - - - - -A CList example - - - - -#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"); - g_signal_connect (G_OBJECT (window), "destroy", - G_CALLBACK (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 */ - g_signal_connect (G_OBJECT (clist), "select_row", - G_CALLBACK (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 */ - g_signal_connect_swapped (G_OBJECT (button_add), "clicked", - G_CALLBACK (button_add_clicked), - clist); - g_signal_connect_swapped (G_OBJECT (button_clear), "clicked", - G_CALLBACK (button_clear_clicked), - clist); - g_signal_connect_swapped (G_OBJECT (button_hide_show), "clicked", - G_CALLBACK (button_hide_show_clicked), - 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; -} - - - - - - - - -CTree Widget - - -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. - -This section of the tutorial is under development. - - - -Creating a CTree - -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: - - -GtkWidget *gtk_ctree_new_with_titles( gint columns, - gint tree_column, - gchar *titles[] ); - -GtkWidget *gtk_ctree_new( gint columns, - gint tree_column ); - - -The columns argument specifies the number of columns that the -CTree will contain. The tree_column argumnet specifies which of -those columns is to contain the tree. Columns are numbered starting -from 0. - -With the first funtion above, the titles argument contains an -array of strings that contain the captions for the column headings. A -typical code fragment using the gtk_ctree_new_with_titles() -function would be: - - - /* CTree column titles /* - char *titles[] = { "Location" , "Description" }; - GtkWidget *ctree; - - ctree = gtk_ctree_new_with_titles(2, 0, titles); - - -This would create a new CTree with two columns entitled "Location" -and "Description", with the first column containing the tree. - - - - - -Adding and Removing nodes - -The items in a CTree are termed nodes. 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: - - -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 ); - - -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. - -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. - -Lets have a quick look at all of the parameters: - - - ctree - the CTree widget we are manipulating - - - parent - the parent node of the one we are inserting. May - be NULL for a root-level (i.e. initial) - node. - - - sibling - a sibling of the node we are inserting. May be - NULL if there are no siblings. - - - text - the textual contents of each column in the tree for - this node. This array must have an entry - for each column, even if it is an empty string. - - - spacing - specifies the padding between the nodes pixmap - and text elements, if a pixmap is provided - - - pixmap_closed - a pixmap to display for a collapsed branch - node and for a leaf node. - - - mask_closed - a bitmap mask for the above pixmap. - - - pixmap_opened - a pixmap to display for an expanded - branch node. - - - mask_opened - a bitmap mask for the above pixmap. - - - is_leaf - indicates whether this is a leaf or branch node. - - - expanded - indicates whether a branch node is initially - expanded or collapsed. - - - -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. - -To remove a node for a CTree, the following function is provided: - - -void gtk_ctree_remove_node( GtkCTree *ctree, - GtkCTreeNode *node ); - - -As you can see, you merely need to specify a CTree and the node to -remove. - - - - - -Setting CTree Attributes - -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: - - -void gtk_ctree_set_indent( GtkCTree *ctree, - gint indent ); - -void gtk_ctree_set_spacing( GtkCTree *ctree, - gint spacing ); - - -The function gtk_ctree_set_indent() sets how far a new branch is -indented in relation to it's parent. The default is 20. - -The function gtk_ctree_set_spacing() 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. - -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. - - -void gtk_ctree_set_line_style( GtkCTree *ctree, - GtkCTreeLineStyle line_style ); - -void gtk_ctree_set_expander_style( GtkCTree *ctree, - GtkCTreeExpanderStyle expander_style ); - - -The function gtk_ctree_set_line_style() is used to select the style -of line that is drawn between nodes of the tree. The parameter -line_style can be one of: - - - GTK_CTREE_LINES_NONE - GTK_CTREE_LINES_SOLID - GTK_CTREE_LINES_DOTTED - GTK_CTREE_LINES_TABBED - - -The function gtk_ctree_set_expander_style() is used to select -the style of branch expander, and the parameter expander_style -can be one of: - - - GTK_CTREE_EXPANDER_NONE - GTK_CTREE_EXPANDER_SQUARE - GTK_CTREE_EXPANDER_TRIANGLE - GTK_CTREE_EXPANDER_CIRCULAR - - - - - - -Utilizing row data - -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. - -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. - -There are two functions for setting row data: - - -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 ); - - -The function gtk_ctree_node_set_row_data() simply takes as -arguments pointers to the CTree, node and data. - -The function gtk_ctree_node_set_row_data_full() takes an -additional parameter, destroy. 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: - - -void destroy_func( gpointer data ); - - -The paramter passed to this function will be the row data. - - - - - - -Tree Widget - - - -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. - -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. - - - -Creating a Tree - -A Tree is created in the usual way, using: - - -GtkWidget *gtk_tree_new( void ); - - -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. - -Now that you have a tree, you'll probably want to add some items to -it. The Tree Item Widget below -explains the gory details of TreeItem. For now, it'll suffice to -create one, using: - - -GtkWidget *gtk_tree_item_new_with_label( gchar *label ); - - -You can then add it to the tree using one of the following (see -Functions and Macros -below for more options): - - -void gtk_tree_append( GtkTree *tree, - GtkWidget *tree_item ); - -void gtk_tree_prepend( GtkTree *tree, - GtkWidget *tree_item ); - - -Note that you must add items to a Tree one at a time - there is no -equivalent to gtk_list_*_items(). - - - - - -Adding a Subtree - -A subtree is created like any other Tree widget. A subtree is added -to another tree beneath a tree item, using: - - -void gtk_tree_item_set_subtree( GtkTreeItem *tree_item, - GtkWidget *subtree ); - - -You do not need to call gtk_widget_show() on a subtree before or after -adding it to a TreeItem. However, you must 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 not the GtkTreeItem which "owns" it, but -rather the GtkTree which holds that GtkTreeItem. - -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. - - - - - -Handling the Selection List - -As with CList, the Tree type has a selection field, and -it is possible to control the behaviour of the tree (somewhat) by -setting the selection type using: - - -void gtk_tree_set_selection_mode( GtkTree *tree, - GtkSelectionMode mode ); - - -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 Signals 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 which Tree widget they will be -emitted by, and where to find the list of selected items. - -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 -GTK_SELECTION_SINGLE and GTK_SELECTION_BROWSE 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". - -Thus, accessing the selection field directly in an arbitrary -Tree widget is not a good idea unless you know it's the root -tree. Instead, use the GTK_TREE_SELECTION_OLD (Tree) 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 GTK_SELECTION_MULTIPLE. - -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. - - - - - -Tree Widget Internals - -The Tree's struct definition looks like this: - - -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; -}; - - -The perils associated with accessing the selection field -directly have already been mentioned. The other important fields of -the struct can also be accessed with handy macros or class functions. -GTK_IS_ROOT_TREE (Tree) returns a boolean value which -indicates whether a tree is the root tree in a Tree hierarchy, while -GTK_TREE_ROOT_TREE (Tree) returns the root tree, an object of -type GtkTree (so, remember to cast it using GTK_WIDGET (Tree) if -you want to use one of the gtk_widget_*() functions on it). - -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: - - - children = gtk_container_children (GTK_CONTAINER (tree)); - while (children) { - do_something_nice (GTK_TREE_ITEM (children->data)); - children = g_list_remove_link (children, children); -} - - -The tree_owner field is defined only in subtrees, where it -points to the TreeItem widget which holds the tree in question. -The level 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). - - - -Signals - - -void selection_changed( GtkTree *tree ); - - -This signal will be emitted whenever the selection field of a -Tree has changed. This happens when a child of the Tree is -selected or deselected. - - -void select_child( GtkTree *tree, - GtkWidget *child ); - - -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 all 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. - - -void unselect_child (GtkTree *tree, - GtkWidget *child); - - -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 not when a button press deselects a -child, nor on emission of the "toggle" signal by gtk_item_toggle(). - - - - - -Functions and Macros - - -guint gtk_tree_get_type( void ); - - -Returns the "GtkTree" type identifier. - - -GtkWidget* gtk_tree_new( void ); - - -Create a new Tree object. The new widget is returned as a pointer to a -GtkWidget object. NULL is returned on failure. - - -void gtk_tree_append( GtkTree *tree, - GtkWidget *tree_item ); - - -Append a tree item to a Tree. - - -void gtk_tree_prepend( GtkTree *tree, - GtkWidget *tree_item ); - - -Prepend a tree item to a Tree. - - -void gtk_tree_insert( GtkTree *tree, - GtkWidget *tree_item, - gint position ); - - -Insert a tree item into a Tree at the position in the list -specified by position. - - -void gtk_tree_remove_items( GtkTree *tree, - GList *items ); - - -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 and its subtree, if it has one, and all -subtrees in that subtree. If you want to remove only one item, you -can use gtk_container_remove(). - - -void gtk_tree_clear_items( GtkTree *tree, - gint start, - gint end ); - - -Remove the items from position start to position end -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(). - - -void gtk_tree_select_item( GtkTree *tree, - gint item ); - - -Emits the "select_item" signal for the child at position -item, thus selecting the child (unless you unselect it in a -signal handler). - - -void gtk_tree_unselect_item( GtkTree *tree, - gint item ); - - -Emits the "unselect_item" signal for the child at position -item, thus unselecting the child. - - -void gtk_tree_select_child( GtkTree *tree, - GtkWidget *tree_item ); - - -Emits the "select_item" signal for the child tree_item, thus -selecting it. - - -void gtk_tree_unselect_child( GtkTree *tree, - GtkWidget *tree_item ); - - -Emits the "unselect_item" signal for the child tree_item, -thus unselecting it. - - -gint gtk_tree_child_position( GtkTree *tree, - GtkWidget *child ); - - -Returns the position in the tree of child, unless -child is not in the tree, in which case it returns -1. - - -void gtk_tree_set_selection_mode( GtkTree *tree, - GtkSelectionMode mode ); - - -Sets the selection mode, which can be one of GTK_SELECTION_SINGLE (the -default), GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE, or -GTK_SELECTION_EXTENDED. 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. - - -void gtk_tree_set_view_mode( GtkTree *tree, - GtkTreeViewMode mode ); - - -Sets the "view mode", which can be either GTK_TREE_VIEW_LINE (the -default) or GTK_TREE_VIEW_ITEM. 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). - -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 GTK_TREE_VIEW_LINE, the entire TreeItem widget is -highlighted, while for GTK_TREE_VIEW_ITEM, only the child widget -(i.e., usually the label) is highlighted. - - -void gtk_tree_set_view_lines( GtkTree *tree, - guint flag ); - - -Controls whether connecting lines between tree items are drawn. -flag is either TRUE, in which case they are, or FALSE, in -which case they aren't. - - -GtkTree *GTK_TREE (gpointer obj); - - -Cast a generic pointer to "GtkTree *". - - -GtkTreeClass *GTK_TREE_CLASS (gpointer class); - - -Cast a generic pointer to "GtkTreeClass *". - - -gint GTK_IS_TREE (gpointer obj); - - -Determine if a generic pointer refers to a "GtkTree" object. - - -gint GTK_IS_ROOT_TREE (gpointer obj) - - -Determine if a generic pointer refers to a "GtkTree" object -and 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. - - -GtkTree *GTK_TREE_ROOT_TREE (gpointer obj) - - -Return the root tree of a pointer to a "GtkTree" object. The above -warning applies. - - -GList *GTK_TREE_SELECTION_OLD( gpointer obj) - - -Return the selection list of the root tree of a "GtkTree" object. The -above warning applies here, too. - - - - - - -Tree Item Widget - -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 subtree field. - -The definition for the TreeItem struct looks like this: - - -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; -}; - - -The pixmaps_box field is an EventBox which catches clicks on -the plus/minus symbol which controls expansion and collapsing. The -pixmaps 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 GTK_TREE_ITEM_SUBTREE (Item) macro, -it's probably advisable never to touch the insides of a TreeItem -unless you really know what you're doing. - -Since it is directly derived from an Item it can be treated as such by -using the GTK_ITEM (TreeItem) 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(): - - -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); - - -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. - -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: - - -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); - - -Finally, drag-n-drop does 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. - - - -Signals - -TreeItem inherits the "select", "deselect", and "toggle" signals -from Item. In addition, it adds two signals of its own, "expand" -and "collapse". - - -void select( GtkItem *tree_item ); - - -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(). - - -void deselect( GtkItem *tree_item ); - - -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(). - - -void toggle( GtkItem *tree_item ); - - -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. - - -void expand( GtkTreeItem *tree_item ); - - -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(). - - -void collapse( GtkTreeItem *tree_item ); - - -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(). - - - - - -Functions and Macros - - -guint gtk_tree_item_get_type( void ); - - -Returns the "GtkTreeItem" type identifier. - - -GtkWidget* gtk_tree_item_new( void ); - - -Create a new TreeItem object. The new widget is returned as a -pointer to a GtkWidget object. NULL is returned on failure. - - -GtkWidget* gtk_tree_item_new_with_label (gchar *label); - - -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. - - -void gtk_tree_item_select( GtkTreeItem *tree_item ); - - -This function is basically a wrapper around a call to -gtk_item_select (GTK_ITEM (tree_item)) which will emit the -select signal. - - -void gtk_tree_item_deselect( GtkTreeItem *tree_item ); - - -This function is basically a wrapper around a call to -gtk_item_deselect (GTK_ITEM (tree_item)) which will emit the deselect -signal. - - -void gtk_tree_item_set_subtree( GtkTreeItem *tree_item, - GtkWidget *subtree ); - - -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. - - -void gtk_tree_item_remove_subtree( GtkTreeItem *tree_item ); - - -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. - - -void gtk_tree_item_expand( GtkTreeItem *tree_item ); - - -This emits the "expand" signal on tree_item, which expands it. - - -void gtk_tree_item_collapse( GtkTreeItem *tree_item ); - - -This emits the "collapse" signal on tree_item, which collapses it. - - -GtkTreeItem *GTK_TREE_ITEM (gpointer obj) - - -Cast a generic pointer to "GtkTreeItem *". - - -GtkTreeItemClass *GTK_TREE_ITEM_CLASS (gpointer obj) - - -Cast a generic pointer to "GtkTreeItemClass". - - -gint GTK_IS_TREE_ITEM (gpointer obj) - - -Determine if a generic pointer refers to a "GtkTreeItem" object. - - -GtkWidget GTK_TREE_ITEM_SUBTREE (gpointer obj) - - -Returns a tree item's subtree (obj should point to a -"GtkTreeItem" object). - - - - - - -Tree Example - -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. - - - - -#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); - g_signal_connect (G_OBJECT (window), "delete_event", - G_CALLBACK (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 */ - g_signal_connect (G_OBJECT (tree), "select_child", - G_CALLBACK (cb_select_child), tree); - g_signal_connect (G_OBJECT (tree), "unselect_child", - G_CALLBACK (cb_unselect_child), tree); - g_signal_connect (G_OBJECT(tree), "selection_changed", - G_CALLBACK(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 */ - g_signal_connect (G_OBJECT (item), "select", - G_CALLBACK (cb_itemsignal), "select"); - g_signal_connect (G_OBJECT (item), "deselect", - G_CALLBACK (cb_itemsignal), "deselect"); - g_signal_connect (G_OBJECT (item), "toggle", - G_CALLBACK (cb_itemsignal), "toggle"); - g_signal_connect (G_OBJECT (item), "expand", - G_CALLBACK (cb_itemsignal), "expand"); - g_signal_connect (G_OBJECT (item), "collapse", - G_CALLBACK (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. */ - g_signal_connect (G_OBJECT (subtree), "select_child", - G_CALLBACK (cb_select_child), subtree); - g_signal_connect (G_OBJECT (subtree), "unselect_child", - G_CALLBACK (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 */ - g_signal_connect (G_OBJECT (subitem), "select", - G_CALLBACK (cb_itemsignal), "select"); - g_signal_connect (G_OBJECT (subitem), "deselect", - G_CALLBACK (cb_itemsignal), "deselect"); - g_signal_connect (G_OBJECT (subitem), "toggle", - G_CALLBACK (cb_itemsignal), "toggle"); - g_signal_connect (G_OBJECT (subitem), "expand", - G_CALLBACK (cb_itemsignal), "expand"); - g_signal_connect (G_OBJECT (subitem), "collapse", - G_CALLBACK (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; -} - - - - - - - - -Menu Widget - -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. - -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. +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. @@ -10714,6 +9144,14 @@ by a menu bar, as shown in the sample code. That should about do it. Let's take a look at an example to help clarify. + + + + + + + + @@ -10952,509 +9390,48 @@ void get_main_menu( GtkWidget *window, /* Attach the new accelerator group to the window. */ gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); - if (menubar) - /* Finally, return the actual menu bar created by the item factory. */ - *menubar = gtk_item_factory_get_widget (item_factory, "<main>"); -} - -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 (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); - - 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; -} - - - -For now, there's only this example. An explanation and lots 'o' comments -will follow later. - - - - - - -Text Widget - -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. - -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. - - - -Creating and Configuring a Text box - -There is only one function for creating a new Text widget. - - -GtkWidget *gtk_text_new( GtkAdjustment *hadj, - GtkAdjustment *vadj ); - - -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. - - -void gtk_text_set_adjustments( GtkText *text, - GtkAdjustment *hadj, - GtkAdjustment *vadj ); - - -The above function allows the horizontal and vertical adjustments of a -text widget to be changed at any time. - -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. - - - vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text)->vadj); - gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0); - gtk_widget_show (vscrollbar); - - -The above code snippet creates a new vertical scrollbar, and attaches -it to the vertical adjustment of the text widget, text. It then -packs it into a box in the normal way. - -Note, currently the Text widget does not support horizontal -scrollbars. - -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: - - -void gtk_text_set_editable( GtkText *text, - gint editable ); - - -The editable 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. - -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. - -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: - - -void gtk_text_set_word_wrap( GtkText *text, - gint word_wrap ); - - -Using this function allows us to specify that the text widget should -wrap long lines on word boundaries. The word_wrap argument is a -TRUE or FALSE value. - - - - - -Text Manipulation - -The current insertion point of a Text widget can be set using - - -void gtk_text_set_point( GtkText *text, - guint index ); - - -where index is the position to set the insertion point. - -Analogous to this is the function for getting the current insertion -point: - - -guint gtk_text_get_point( GtkText *text ); - - -A function that is useful in combination with the above two functions -is - - -guint gtk_text_get_length( GtkText *text ); - - -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. - -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. - - -void gtk_text_insert( GtkText *text, - GdkFont *font, - GdkColor *fore, - GdkColor *back, - const char *chars, - gint length ); - - -Passing a value of NULL 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 -1 for the length -parameter will result in the whole of the text string given being -inserted. - -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. - -The following two functions perform this freeze and thaw action: - - -void gtk_text_freeze( GtkText *text ); - -void gtk_text_thaw( GtkText *text ); - - -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. - - -gint gtk_text_backward_delete( GtkText *text, - guint nchars ); - -gint gtk_text_forward_delete ( GtkText *text, - guint nchars ); - - -If you want to retrieve the contents of the text widget, then the -macro GTK_TEXT_INDEX(t, index) allows you to retrieve the -character at position index within the text widget t. - -To retrieve larger blocks of text, we can use the function - - -gchar *gtk_editable_get_chars( GtkEditable *editable, - gint start_pos, - gint end_pos ); - - -This is a function of the parent class of the text widget. A value of --1 as end_pos signifies the end of the text. The index of the -text starts at 0. - -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. - - - - - -Keyboard Shortcuts - -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. - -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. - - - -Motion Shortcuts - - - Ctrl-A Beginning of line - - Ctrl-E End of line - - Ctrl-N Next Line - - Ctrl-P Previous Line - - Ctrl-B Backward one character - - Ctrl-F Forward one character - - Alt-B Backward one word - - Alt-F Forward one word - - - - - - - -Editing Shortcuts - - - Ctrl-H Delete Backward Character (Backspace) - - Ctrl-D Delete Forward Character (Delete) - - Ctrl-W Delete Backward Word - - Alt-D Delete Forward Word - - Ctrl-K Delete to end of line - - Ctrl-U Delete line - - - - - - - -Selection Shortcuts - - - Ctrl-X Cut to clipboard - - Ctrl-C Copy to clipboard - - Ctrl-V Paste from clipboard - - - - - - - - -A GtkText Example - - - - -#define GTK_ENABLE_BROKEN -#include <stdio.h> -#include <gtk/gtk.h> - -void text_toggle_editable (GtkWidget *checkbutton, - GtkWidget *text) -{ - gtk_text_set_editable (GTK_TEXT (text), - GTK_TOGGLE_BUTTON (checkbutton)->active); -} - -void text_toggle_word_wrap (GtkWidget *checkbutton, - GtkWidget *text) -{ - gtk_text_set_word_wrap (GTK_TEXT (text), - GTK_TOGGLE_BUTTON (checkbutton)->active); -} - -void close_application( GtkWidget *widget, - gpointer data ) -{ - gtk_main_quit (); + if (menubar) + /* Finally, return the actual menu bar created by the item factory. */ + *menubar = gtk_item_factory_get_widget (item_factory, "<main>"); } 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; - - gtk_init (&argc, &argv); - - 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); - g_signal_connect (G_OBJECT (window), "destroy", - G_CALLBACK (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)); + GtkWidget *main_vbox; + GtkWidget *menubar; - /* 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); + gtk_init (&argc, &argv); - /* Load the file text.c into the text window */ - - infile = fopen ("text.c", "r"); + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + 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); - 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); - } - - /* Thaw the text widget, allowing the updates to become visible */ - gtk_text_thaw (GTK_TEXT (text)); + 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); - 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); - g_signal_connect (G_OBJECT (check), "toggled", - G_CALLBACK (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); - g_signal_connect (G_OBJECT (check), "toggled", - G_CALLBACK (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); + get_main_menu (window, &menubar); + gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0); + gtk_widget_show (menubar); - button = gtk_button_new_with_label ("close"); - g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (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); gtk_main (); - return 0; + return 0; } +For now, there's only this example. An explanation and lots 'o' comments +will follow later. + @@ -11478,503 +9455,121 @@ widget, please consider writing a tutorial on it so others may benefit from your time. - -Curves + +Accel Label - -Drawing Area + +Option Menu - -Font Selection Dialog + +Menu Items - + +Check Menu Item - - -Gamma Curve + + + + +Radio Menu Item + + + + + +Separator Menu Item + + +Tearoff Menu Item + + + - -Image + +Curves - -Plugs and Sockets + +Drawing Area - -Preview + +Font Selection Dialog - + +Message Dialog - [Image] + -Misc + -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. + + +Gamma Curve -This is pretty much it as far as GTK is concerned. + -Filling In a Preview + -In order to familiarize ourselves with the basics of filling in previews, -let's create the following pattern (contrived by trial and error): + + +Image - [Image] + -void -my_preview_rendering_function(GtkWidget *preview) -{ -#define SIZE 100 -#define HALF (SIZE/2) - - guchar *row=(guchar *) malloc(3*SIZE); /* 3 bits per dot */ - gint i, j; /* Coordinates */ - double r, alpha, x, y; - - 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 */ - } - - free(row); /* save some space */ - gtk_widget_draw(preview,NULL); /* what does this do? */ - gdk_flush(); /* or this? */ -} - -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. - -Image Preview - -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!) - -(UNTESTED CODE ALERT!!!) - -typedef struct { - gint width; - gint height; - gint bbp; - guchar *rgb; - guchar *mask; -} ReducedImage; - -enum { - SELECTION_ONLY, - SELECTION_IN_CONTEXT, - ENTIRE_IMAGE -}; - -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)); - - 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. */ - - 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!) - - 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. */ - - /* 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; - } - - /* 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); - } - - /* How we can determine the width and the height of the area being */ - /* reduced. */ - width = x2-x1; - height = y2-y1; - - /* 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; - } - - /* The entire image is stretched into a string! */ - tempRGB = (guchar *) malloc(RW*RH*bytes); - tempmask = (guchar *) malloc(RW*RH); - - gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, - FALSE, FALSE); - gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height, - FALSE, FALSE); - - /* 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); - - 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); - - for (j=0; j < RW; j++) { - whichcol=(float)j*(float)width/(float)RW; - - /* No selection made = each point is completely selected! */ - if (NoSelectionMade) - tempmask[i*RW+j]=255; - else - tempmask[i*RW+j]=src_mask_row[whichcol]; + - /* 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]; + + +Plugs and Sockets - /* 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; -} - -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: - -gint fake_transparency(gint i, gint j) -{ - if ( ((i%20)- 10) * ((j%20)- 10)>0 ) - return 64; - else - return 196; -} + -Now here's the preview function: + -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);; + + +Tree View - - for (i=0; i < RH; i++) { - for (j=0; j < RW; j++) { + - 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]; + - 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); - } - - free(a); - gtk_widget_draw(preview,NULL); - gdk_flush(); -} - -Applicable Routines - -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. */ - -void gtk_preview_put (GtkPreview *preview, - GdkWindow *window, - GdkGC *gc, - gint srcx, - gint srcy, - gint destx, - gint desty, - gint width, - gint height); -/* No idea */ - -void gtk_preview_put_row (GtkPreview *preview, - guchar *src, - guchar *dest, - gint x, - gint y, - gint w); -/* No idea */ - -void gtk_preview_draw_row (GtkPreview *preview, - guchar *data, - gint x, - gint y, - gint w); -/* Described in the text */ - -void gtk_preview_set_expand (GtkPreview *preview, - gint expand); -/* No idea */ - -/* 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); - -That's all, folks! - - + + +Text View ---> + @@ -13859,6 +11454,14 @@ widget, a 3x3 array of toggle buttons which triggers a signal when all three buttons in a row, column, or on one of the diagonals are depressed. + + + + + + + + @@ -14378,6 +11981,14 @@ on the screen and interact with events. As an example of this, we'll create an analog dial widget with a pointer that the user can drag to set the value. + + + + + + + + @@ -15298,6 +12909,14 @@ support for XInput devices, such as drawing tablets. GTK provides support routines which makes getting extended information, such as pressure and tilt, from such devices quite easy. + + + + + + + + @@ -16582,89 +14201,6 @@ void GtkEditable::paste-clipboard (GtkEditable *, - - -GtkTipsQuery - - -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); - - - - - - -GtkCList - - -void GtkCList::select-row (GtkCList *, - ggint, - ggint, - GdkEvent *, - gpointer); -void GtkCList::unselect-row (GtkCList *, - ggint, - ggint, - GdkEvent *, - gpointer); -void GtkCList::row-move (GtkCList *, - ggint, - ggint, - gpointer); -void GtkCList::click-column (GtkCList *, - 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 *, - 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, - gpointer); -void GtkCList::scroll-vertical (GtkCList *, - GtkScrollType, - ggfloat, - gpointer); -void GtkCList::scroll-horizontal (GtkCList *, - GtkScrollType, - ggfloat, - gpointer); -void GtkCList::abort-column-resize (GtkCList *, - gpointer); - - - - GtkNotebook @@ -16731,23 +14267,6 @@ void GtkToolbar::style-changed (GtkToolbar *, - - -GtkTree - - -void GtkTree::selection-changed (GtkTree *, - gpointer); -void GtkTree::select-child (GtkTree *, - GtkWidget *, - gpointer); -void GtkTree::unselect-child (GtkTree *, - GtkWidget *, - gpointer); - - - - GtkButton @@ -16833,55 +14352,6 @@ void GtkMenuItem::activate-item (GtkMenuItem *, - - -GtkListItem - - -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); - - - - - - -GtkTreeItem - - -void GtkTreeItem::collapse (GtkTreeItem *, - gpointer); -void GtkTreeItem::expand (GtkTreeItem *, - gpointer); - - - - GtkCheckMenuItem @@ -16929,40 +14399,9 @@ void GtkStatusbar::text-pushed (GtkStatusbar *, GtkString *, gpointer); void GtkStatusbar::text-popped (GtkStatusbar *, - gguint, - GtkString *, - gpointer); - - - - - - -GtkCTree - - -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); + gguint, + GtkString *, + gpointer); @@ -19115,627 +16554,5 @@ main (int argc, char *argv[]) - - - - -List Widget - -NOTE: The List widget has been superseded by the CList widget. It is -detailed here just for completeness. - -The List widget is designed to act as a vertical container for -widgets that should be of the type ListItem. - -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. - -There is one field inside the structure definition of the List -widget that will be of greater interest to us, this is: - - -struct _GtkList -{ - ... - GList *selection; - guint selection_mode; - ... -}; - - -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. - -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: - - - GTK_SELECTION_SINGLE - The selection is either NULL - or contains a GList pointer - for a single selected item. - - GTK_SELECTION_BROWSE - 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. - - GTK_SELECTION_MULTIPLE - 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. - - GTK_SELECTION_EXTENDED - The selection is always NULL. - - - -The default is GTK_SELECTION_MULTIPLE. - - - -Signals - - -void selection_changed( GtkList *list ); - - -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. - - -void select_child( GtkList *list, - GtkWidget *child); - - -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. - - -void unselect_child( GtkList *list, - GtkWidget *child ); - - -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. - - - - - -Functions - - -guint gtk_list_get_type( void ); - - -Returns the "GtkList" type identifier. - - -GtkWidget *gtk_list_new( void ); - - -Create a new List object. The new widget is returned as a pointer -to a GtkWidget object. NULL is returned on failure. - - -void gtk_list_insert_items( GtkList *list, - GList *items, - gint position ); - - -Insert list items into the list, starting at position. -items is a doubly linked list where each nodes data pointer is -expected to point to a newly created ListItem. The GList nodes of -items are taken over by the list. - - -void gtk_list_append_items( GtkList *list, - GList *items); - - -Insert list items just like gtk_list_insert_items() at the end of the -list. The GList nodes of items are taken over by the list. - - -void gtk_list_prepend_items( GtkList *list, - GList *items); - - -Insert list items just like gtk_list_insert_items() at the very -beginning of the list. The GList nodes of items are taken over by -the list. - - -void gtk_list_remove_items( GtkList *list, - GList *items); - - -Remove list items from the list. items 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. - - -void gtk_list_clear_items( GtkList *list, - gint start, - gint end ); - - -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 -start and end. - - -void gtk_list_select_item( GtkList *list, - gint item ); - - -Invoke the select_child signal for a list item specified through its -current position within the list. - - -void gtk_list_unselect_item( GtkList *list, - gint item); - - -Invoke the unselect_child signal for a list item specified through its -current position within the list. - - -void gtk_list_select_child( GtkList *list, - GtkWidget *child); - - -Invoke the select_child signal for the specified child. - - -void gtk_list_unselect_child( GtkList *list, - GtkWidget *child); - - -Invoke the unselect_child signal for the specified child. - - -gint gtk_list_child_position( GtkList *list, - GtkWidget *child); - - -Return the position of child within the list. "-1" is returned on -failure. - - -void gtk_list_set_selection_mode( GtkList *list, - GtkSelectionMode mode ); - - -Set the selection mode MODE which can be of GTK_SELECTION_SINGLE, -GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE or -GTK_SELECTION_EXTENDED. - - -GtkList *GTK_LIST( gpointer obj ); - - -Cast a generic pointer to "GtkList *". - - -GtkListClass *GTK_LIST_CLASS( gpointer class); - - -Cast a generic pointer to "GtkListClass *". - - -gint GTK_IS_LIST( gpointer obj); - - -Determine if a generic pointer refers to a "GtkList" object. - - - - - -Example - -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. - - - - -#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 (G_OBJECT (window), "destroy", - G_CALLBACK (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); - g_signal_connect (G_OBJECT (gtklist), "selection_changed", - G_CALLBACK (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 - */ - g_signal_connect (G_OBJECT (gtklist), "button_release_event", - G_CALLBACK (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); - g_signal_connect_swapped (G_OBJECT (button), "clicked", - G_CALLBACK (gtk_widget_destroy), - 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); - g_object_set_data (G_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); - g_object_set_data (G_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) { - const gchar *item_data_string; - - item_data_string = g_object_get_data (G_OBJECT (dlist->data), - list_item_data_key); - g_print("%s ", item_data_string); - - dlist = dlist->next; - } - g_print ("\n"); -} - - - - - - - -List Item Widget - -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. - -A ListItem has its own window to receive events and has its own -background color which is usually white. - -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. - -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. - - - - - -Signals - -A GtkListItem does not create new signals on its own, but inherits -the signals of a Item. - - - - - -Functions - - -guint gtk_list_item_get_type( void ); - - -Returns the "GtkListItem" type identifier. - - -GtkWidget *gtk_list_item_new( void ); - - -Create a new ListItem object. The new widget is returned as a -pointer to a GtkWidget object. NULL is returned on failure. - - -GtkWidget *gtk_list_item_new_with_label( gchar *label ); - - -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. - - -void gtk_list_item_select( GtkListItem *list_item ); - - -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. - - -void gtk_list_item_deselect( GtkListItem *list_item ); - - -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. - - -GtkListItem *GTK_LIST_ITEM( gpointer obj ); - - -Cast a generic pointer to "GtkListItem *". - - -GtkListItemClass *GTK_LIST_ITEM_CLASS( gpointer class ); - - -Cast a generic pointer to GtkListItemClass*. *Note Standard Macros::, -for more info. - - -gint GTK_IS_LIST_ITEM( gpointer obj ); - - -Determine if a generic pointer refers to a `GtkListItem' object. -*Note Standard Macros::, for more info. - - - - - -Example - -Please see the List example on this, which covers the usage of a -ListItem as well. - - diff --git a/docs/tutorial/images/arrow.png b/docs/tutorial/images/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..b7e3e93edf584a3d9bb25e06ba980625cb176676 GIT binary patch literal 3802 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 H<@^5t#-@)d literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/aspectframe.png b/docs/tutorial/images/aspectframe.png new file mode 100644 index 0000000000000000000000000000000000000000..7edcb99b2bbc6373eee02688773c37d8a852a70a GIT binary patch literal 5163 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 H*YJM;bCsp- literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/base.png b/docs/tutorial/images/base.png new file mode 100644 index 0000000000000000000000000000000000000000..5b7f0187e3ba0c08e0d6c15c221b0497b484fe4a GIT binary patch literal 4462 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/buttons.png b/docs/tutorial/images/buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..edd6422f370e8f1e05258fb64ef04c29272e1bfe GIT binary patch literal 5269 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/colorsel.png b/docs/tutorial/images/colorsel.png new file mode 100644 index 0000000000000000000000000000000000000000..4772bb34ea342eed4b6637adc1f48e82d1194d2f GIT binary patch literal 28063 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 F{{up-VV3{^ literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/eventbox.png b/docs/tutorial/images/eventbox.png new file mode 100644 index 0000000000000000000000000000000000000000..e1810c44a087c47b221bf2984ab728c9750439ab GIT binary patch literal 3673 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 F_&>WDPfY*- literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/filesel.png b/docs/tutorial/images/filesel.png new file mode 100644 index 0000000000000000000000000000000000000000..bfd520e255f5e8fe07440f5373a8647e60e6fc73 GIT binary patch literal 11063 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 V{L3p1<>$1@)yr;9^%nzw`40u~Yw7?1 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/gtkdial.png b/docs/tutorial/images/gtkdial.png new file mode 100644 index 0000000000000000000000000000000000000000..bf313e5f67677fc400967bd1a821d98aeba2f59c GIT binary patch literal 4758 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/menu.png b/docs/tutorial/images/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..895e65e2e5a1f59223a050cb8d20855e83ce79f5 GIT binary patch literal 4857 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 K09Wffz4$NI451nT literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/notebook.png b/docs/tutorial/images/notebook.png new file mode 100644 index 0000000000000000000000000000000000000000..7560d78717860e3641f3f16c070a4a8ede1de9b1 GIT binary patch literal 8005 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/packbox1.png b/docs/tutorial/images/packbox1.png new file mode 100644 index 0000000000000000000000000000000000000000..fd0b5e2fd4189ac317d8b90d8fb435572ca14b86 GIT binary patch literal 10366 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 YkHiF?6r~CH?|#(LG|(u%Vg2xb07nLMg8%>k literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/packbox2.png b/docs/tutorial/images/packbox2.png new file mode 100644 index 0000000000000000000000000000000000000000..3e6c1b9dae2282d4e515a5f788e1384b4c252975 GIT binary patch literal 9302 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

o4 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/progressbar.png b/docs/tutorial/images/progressbar.png new file mode 100644 index 0000000000000000000000000000000000000000..ed961d2ab021ec769e7aba70be84b5979d9a3c2a GIT binary patch literal 6135 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/rangewidgets.png b/docs/tutorial/images/rangewidgets.png new file mode 100644 index 0000000000000000000000000000000000000000..f207f8b564e2164dd3c661b9b95fec7456ee1eb9 GIT binary patch literal 9284 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 B$@2gJ literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/rulers.png b/docs/tutorial/images/rulers.png new file mode 100644 index 0000000000000000000000000000000000000000..3aafbfb3cceb32f28c8b8430d7443f1019822f17 GIT binary patch literal 8466 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/scrolledwin.png b/docs/tutorial/images/scrolledwin.png new file mode 100644 index 0000000000000000000000000000000000000000..43fff3b36958dc71588faa2096b4dc87792496de GIT binary patch literal 7745 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 literal 0 HcmV?d00001 diff --git a/docs/tutorial/images/tictactoe.png b/docs/tutorial/images/tictactoe.png new file mode 100644 index 0000000000000000000000000000000000000000..633e3599bd68e10053abea9721f4a8cd76e88e24 GIT binary patch literal 3100 zcmai$c{tSV8pnT@vgaN9nr#Zzq>v>`VlXqZhLL3uvae;lj7lYukbPf9me5!RV{4eQ zldO>$rc<(nAxks1INozz=Q{6o{y684=lNdu_1xEefA0JH&l6{1X3WDW#t8rb4;%)y zI#!3{p#h~d}l9*Daqar2Wt&`$!0N{*VqY(@$0L6K~OfD zhv<$j_c^k@BWEX^&E#!n*WeS}smU2S)@Fa?+$n+bryqk|O%Cvej|i4nncgSdr6bZD z1FIx`u$NHW6Aw1ty)R9O9Bx?*JB%D&&%>+@UnX4&%_8dj z-j2(?W^t_~rbgS3n3MS6SLAi2CFep}@7z-E{>h;mL#NGkGnUbA*>~!OtR~eu$M+9G z1-3}$~Ax15;BiGme}2d?=gDtHs^&?JlZrma8hy_OBCLeFQR_o*Q!dh80vC4hn!dJtX{mGTK|87TP{>Q_#@<;e0rlJdKx<@lDf+JBC)BRO9>$R-z@1sj1 zhHVv2M&GV1l>G5sB2H>fekV8qDgh6VdVh~CXpw0?y{YKi{JQSZ!UtN_S6>W7#kgh4 ze_T0J$*;sddkLxZ`A%Yh#5Emrd|Kljv?8d--Z+Uz4-H-CQ5f@Jl{i zVyfI$=^sN=wikGtr3MIcl5meKAH_OT%sbOIvBTTQ>xJ1zKbNcoNIb5Iq}SKEl~jX}QS^u4U|8IFPV*NlK@-(>gKp z#;AGOC1!Gj?Znk(82Rgf`r>!zVNJ$l`l38v=123-u5H7ogoWaz1cfAb>yMhxFj63{ ztU}SC=dNIZ`qYLF^cT?}w#*P9YwLg+-&(dJiuDE}?f5XsxUecf}Rh zDr@cCM(8FmJ%N-<9JnN~{ayn8JcC|2@nq^#=$R9)+dPGoxiy!i^_6nwbmdNjY<&Mi z$#TP-B9l)(ZRT)6Q8?v-ho1@Aq)*GLt1C8^!(g{EYGDfGBiPZ4l3>0BO$qTK zzwA;dAbF_}VhY5ywYDASz6oD*y4tYwBcoPOkrMmng-dm{unZjiBQfk57JoGbJRe+t zF8>xl+A&i{Dy|INzEa-=&%g^Nd0|X0E;p6oMDZqJd5z}AmL5~exDzJh&@UxtT~4ZI z#kw-p6>Yo}QfQ=40N8s5pa_T$>8&Sl>;!F#_||>>>}4{d4b(^xh;X_xdl=TLG4zkFrSn zdO_?!baIC1K8)tglkOkLquv?+XWM57`xS!EW|PZ#o$Ou12)v*}qvpz=$&H4#9k=x% z1_kF$LrFO%z9kmnd1lq^CL)VTXLYYN$qTlRAy=IdsG|fG+mQ~Uo-#j?5T?is_;gqW zd+~UM4pI9^HH7qngU$Y5CzZ5+Z#|4DpIQj)w)Le|a&{+wp(J(zk3}qyVu%tv24;O~ z$QHsr+G1p5QL)jPF!1cb_qs3nr=P!Ovu_mC(R_dy78z@Aa9q8nbNH^t3Snmnu0_ta zrLh8(lLJC~$k06E*p3^J7_Oy1th*JcLusC~>O@MJ^B^B&y*{Wy&)nEm{GjUQOLX

XZJ>>6H?jmiO$@(b(=i zx_4a>Xcg&s`aR58WgmC>154w|?MBvkm{oxfxOq}0keWj)P@W1q^j-hOKYxeZinP{D zKvc;k59rxSCeIU3s{lw&RItK?V4zQFgF?<(QHhb7Eh~g zq-tl%1W)%?KUuE}nQ?i=jqy0?&?wZDh~ug65t0RDf8o{Zg*lLg9(tdcv@E@s_THGD zNwRP(ycco!r0yQ~mfj`q=H38s{2uORyf?|o_T0YU8GL2nAP!CN^)xW?rPIkNz7TpM zuBVrcNtFpcP=y`vBk`*miQMm8Fa<~=fFAJ_3VdszYz`z+JrJNb2E$4X{C@r zYqWT9N~vFK;@v@;$=T8DOcWV1Ge?h#={p#4raB?c@)yqbjmB^49aYk>D8g%eg)VxD zQ7EYejT_5MvzR50LJIIz)W?-PSGs?=J!cd^Ovg`;s)mxISu-qEG{rBfJ`a+x3vab_ zo~znYMP32^*jV|PLFMWO{Y{hxA(04RN2dv#vg#~vMfvS`K zTE#$o8od!XhH8Fw=ckqOgPkkJBBL$pPjW#R!ewj85LLp?=K1|^*et>(dg1$yq7&qz zTfBiW3Z(iE{$3zyBGyxj5OyeYlWKuC04b9UYHdJUMK%$nEb=sjEYO=k0Dt zwzwg}WGbR3Jwc;dO#G7l)T8Zn;S3W=8L~y;%CP-|j5+a00AdNT-DyM(!%Indu>i!cUCqZ;zry(>*e