diff options
author | BST 1998 Tony Gale <gale@gtk.org> | 1998-06-25 08:57:29 +0000 |
---|---|---|
committer | Tony Gale <gale@src.gnome.org> | 1998-06-25 08:57:29 +0000 |
commit | 713cecba4cdf7004d19871b21d2c978ab292984c (patch) | |
tree | 55e4b01f18cd7d453ed13bacd1559d5b1dcb3795 | |
parent | e5e47e68798d7a0ff111fae8d55734ab70ca2530 (diff) | |
download | gtk+-713cecba4cdf7004d19871b21d2c978ab292984c.tar.gz |
add section on GtkCList widget, contributed by Stefan Mars
Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: add section on GtkCList widget, contributed by Stefan Mars <mars@lysator.liu.se>
* examples/clist/clist.c examples/clist/Makefile: example code
for GtkCList widget from the Tutorial
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 7 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 7 | ||||
-rw-r--r-- | docs/gtk_tut.sgml | 721 | ||||
-rw-r--r-- | docs/tutorial/gtk_tut.sgml | 721 | ||||
-rw-r--r-- | examples/clist/Makefile | 8 | ||||
-rw-r--r-- | examples/clist/clist.c | 173 |
11 files changed, 1660 insertions, 12 deletions
@@ -1,3 +1,10 @@ +Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org> + + * docs/gtk_tut.sgml: add section on GtkCList widget, contributed + by Stefan Mars <mars@lysator.liu.se> + * examples/clist/clist.c examples/clist/Makefile: example code + for GtkCList widget from the Tutorial + Wed Jun 24 16:38:02 1998 Tim Janik <timj@gtk.org> * gtk/gtkbin.c (gtk_bin_remove): do not avoid to queue for a resize diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 9438fe3c08..c0adc68102 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,10 @@ +Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org> + + * docs/gtk_tut.sgml: add section on GtkCList widget, contributed + by Stefan Mars <mars@lysator.liu.se> + * examples/clist/clist.c examples/clist/Makefile: example code + for GtkCList widget from the Tutorial + Wed Jun 24 16:38:02 1998 Tim Janik <timj@gtk.org> * gtk/gtkbin.c (gtk_bin_remove): do not avoid to queue for a resize diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9438fe3c08..c0adc68102 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,10 @@ +Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org> + + * docs/gtk_tut.sgml: add section on GtkCList widget, contributed + by Stefan Mars <mars@lysator.liu.se> + * examples/clist/clist.c examples/clist/Makefile: example code + for GtkCList widget from the Tutorial + Wed Jun 24 16:38:02 1998 Tim Janik <timj@gtk.org> * gtk/gtkbin.c (gtk_bin_remove): do not avoid to queue for a resize diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 9438fe3c08..c0adc68102 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,10 @@ +Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org> + + * docs/gtk_tut.sgml: add section on GtkCList widget, contributed + by Stefan Mars <mars@lysator.liu.se> + * examples/clist/clist.c examples/clist/Makefile: example code + for GtkCList widget from the Tutorial + Wed Jun 24 16:38:02 1998 Tim Janik <timj@gtk.org> * gtk/gtkbin.c (gtk_bin_remove): do not avoid to queue for a resize diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 9438fe3c08..c0adc68102 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,10 @@ +Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org> + + * docs/gtk_tut.sgml: add section on GtkCList widget, contributed + by Stefan Mars <mars@lysator.liu.se> + * examples/clist/clist.c examples/clist/Makefile: example code + for GtkCList widget from the Tutorial + Wed Jun 24 16:38:02 1998 Tim Janik <timj@gtk.org> * gtk/gtkbin.c (gtk_bin_remove): do not avoid to queue for a resize diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 9438fe3c08..c0adc68102 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,10 @@ +Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org> + + * docs/gtk_tut.sgml: add section on GtkCList widget, contributed + by Stefan Mars <mars@lysator.liu.se> + * examples/clist/clist.c examples/clist/Makefile: example code + for GtkCList widget from the Tutorial + Wed Jun 24 16:38:02 1998 Tim Janik <timj@gtk.org> * gtk/gtkbin.c (gtk_bin_remove): do not avoid to queue for a resize diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 9438fe3c08..c0adc68102 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,10 @@ +Thu Jun 25 07:53:51 BST 1998 Tony Gale <gale@gtk.org> + + * docs/gtk_tut.sgml: add section on GtkCList widget, contributed + by Stefan Mars <mars@lysator.liu.se> + * examples/clist/clist.c examples/clist/Makefile: example code + for GtkCList widget from the Tutorial + Wed Jun 24 16:38:02 1998 Tim Janik <timj@gtk.org> * gtk/gtkbin.c (gtk_bin_remove): do not avoid to queue for a resize diff --git a/docs/gtk_tut.sgml b/docs/gtk_tut.sgml index ba5535225e..fe93a7cbac 100644 --- a/docs/gtk_tut.sgml +++ b/docs/gtk_tut.sgml @@ -10,7 +10,7 @@ name="<imain@gtk.org>"></tt>, Tony Gale <tt><htmlurl url="mailto:gale@gtk.org" name="<gale@gtk.org>"></tt> -<date>June 2nd, 1998 +<date>June 24th, 1998 <!-- ***************************************************************** --> <sect>Introduction @@ -4374,9 +4374,719 @@ main (int argc, char *argv[]) } /* example-end */ </verb></tscreen> - + <!-- ***************************************************************** --> -<sect> List Widgets +<sect>CList Widget +<!-- ***************************************************************** --> + +<!-- ----------------------------------------------------------------- --> +<p> +The GtkCList widget has replaced the GtkList widget (which is still +available). + +The GtkCList 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 it's selection. + +<!-- ----------------------------------------------------------------- --> +<sect1>Creating a GtkCList widget +<p> +Creating a GtkCList 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. + +<tscreen><verb> +GtkWidget *gtk_clist_new ( gint columns ); + +GtkWidget *gtk_clist_new_with_titles( gint columns, + gchar *titles[] ); +</verb></tscreen> + +The first form is very straight forward, 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. + +<!-- ----------------------------------------------------------------- --> +<sect1>Modes of operation +<p> +There are several attributes that can be used to alter the behaviour of +a GtkCList. First there is + +<tscreen><verb> +void gtk_clist_set_selection_mode( GtkCList *clist, + GtkSelectionMode mode ); +</verb></tscreen> + +which, as the name implies, sets the selection mode of the GtkCList. The first +argument is the GtkCList 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: + +<itemize> +<item> GTK_SELECTION_SINGLE - The selection is either NULL or contains a GList +pointer for a single selected item. + +<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. + +<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 <bf>default</bf> for the GtkCList widget. + +<item> GTK_SELECTION_EXTENDED - The selection is always NULL. +</itemize> + +Others might be added in later revisions of GTK. + +Then there is + +<tscreen><verb> +void gtk_clist_set_policy (GtkCList * clist, + GtkPolicyType vscrollbar_policy, + GtkPolicyType hscrollbar_policy); +</verb></tscreen> + +which defines what happens to the scrollbars. The following values are possible +for both the vertical and the horizontal scrollbar: + +<itemize> +<item> GTK_POLICY_ALWAYS - The scrollbar will always be there. + +<item> GTK_POLICY_AUTOMATIC - The scrollbar will be there only when the number +of items in the GtkCList exceeds the number that can be shown in the widget. +</itemize> + +We can also define what the border of the GtkCList widget should look like. It is +done through + +<tscreen><verb> +void gtk_clist_set_border( GtkCList *clist, + GtkShadowType border ); +</verb></tscreen> + +And the possible values for the second argument are + +<itemize> +<item> GTK_SHADOW_NONE + +<item> GTK_SHADOW_IN + +<item> GTK_SHADOW_OUT + +<item> GTK_SHADOW_ETCHED_IN + +<item> GTK_SHADOW_ETCHED_OUT +</itemize> + +<!-- ----------------------------------------------------------------- --> +<sect1>Working with titles +<p> +When you create a GtkCList 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. + +<tscreen><verb> +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 ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_column_titles_show( GtkCList *clist ); + +void gtk_clist_column_titles_hide( GtkCList *clist ); +</verb></tscreen> + +For titles to be really useful we need a mechanism to set and change them, +and this is done using + +<tscreen><verb> +void gtk_clist_set_column_title( GtkCList *clist, + gint column, + gchar *title ); +</verb></tscreen> + +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. 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. GtkCList provides us with title buttons that can in fact +incorporate whole widgets, for example a pixmap. It's all done through + +<tscreen><verb> +void gtk_clist_set_column_widget( GtkCList *clist, + gint column, + GtkWidget *widget ); +</verb></tscreen> + +which should require no special explanation. + +<!-- ----------------------------------------------------------------- --> +<sect1>Manipulating the list itself +<p> +It is possible to change the justification for a column, and it is done through + +<tscreen><verb> +void gtk_clist_set_column_justification( GtkCList *clist, + gint column, + GtkJustification justification ); +</verb></tscreen> + +The GtkJustification type can take the following values: + +<itemize> +<item>GTK_JUSTIFY_LEFT - The text in the column will begin from the left edge. + +<item>GTK_JUSTIFY_RIGHT - The text in the column will begin from the right edge. + +<item>GTK_JUSTIFY_CENTER - The text is placed in the center of the column. + +<item>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 inidvidual letters of it's a single word). Much in the same way as +any ordinary WYSIWYG text editor. +</itemize> + +The next function is a very important one, and should be standard in the setup +of all GtkCList 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 + +<tscreen><verb> +void gtk_clist_set_column_width( GtkCList *clist, + gint column, + gint width ); +</verb></tscreen> + +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 + +<tscreen><verb> +void gtk_clist_set_row_height( GtkCList *clist, + gint height ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_moveto( GtkCList *clist, + gint row, + gint column, + gfloat row_align, + gfloat col_align ); +</verb></tscreen> + +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. + +<tscreen><verb> +GtkVisibility gtk_clist_row_is_visible( GtkCList *clist, + gint row ); +</verb></tscreen> + +The return value is is one of the following: + +<itemize> +<item>GTK_VISIBILITY_NONE + +<item>GTK_VISIBILITY_PARTIAL + +<item>GTK_VISIBILITY_FULL +</itemize> + +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 + +<tscreen><verb> +void gtk_clist_set_foreground( GtkCList *clist, + gint row, + GdkColor *color ); + +void gtk_clist_set_background( GtkCList *clist, + gint row, + GdkColor *color ); +</verb></tscreen> + +Please note that the colors must have been previously allocated. + +<!-- ----------------------------------------------------------------- --> +<sect1>Adding rows to the list +<p> +We can add rows in two ways. They can be appended at the end to the list using + +<tscreen><verb> +gint gtk_clist_append( GtkCList *clist, + gchar *text[] ); +</verb></tscreen> + +or we can insert a row at a given place using + +<tscreen><verb> +void gtk_clist_insert( GtkCList *clist, + gint row, + gchar *text[] ); +</verb></tscreen> + +In both 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 + +<tscreen><verb> +void gtk_clist_remove( GtkCList *clist, + gint row ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_clear( GtkCList *clist ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_freeze( GtkCList * clist ); + +void gtk_clist_thaw( GtkCList * clist ); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>Setting text and pixmaps in the cells +<p> +A cell can contain a pixmap, text or both. To set them the following +functions are used. + +<tscreen><verb> +void gtk_clist_set_text( GtkCList *clist, + gint row, + gint column, + 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 ); +</verb></tscreen> + +It's quite straightforward. All the calls have the GtkCList as the first +argument, followed by the row and column of the cell, follwed by the data to be +set. The gint8 spacing argument in gtk_clist_set_pixtext is the number of pixels +between the pixmap and the beginning of the text. + +To read back the data, we instead use + +<tscreen><verb> +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 ); +</verb></tscreen> + +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: + +<tscreen><verb> +gchar *mytext; + +gtk_clist_get_pixtext(clist, row, column, &mytext, NULL, NULL, NULL); +</verb></tscreen> + +There is one more call that is related to what's inside a cell in the +clist, and that's + +<tscreen><verb> +GtkCellType gtk_clist_get_cell_type( GtkCList *clist, + gint row, + gint column ); +</verb></tscreen> + +which returns the type of data in a cell. The return value is one of + +<itemize> +<item>GTK_CELL_EMPTY + +<item>GTK_CELL_TEXT + +<item>GTK_CELL_PIXMAP + +<item>GTK_CELL_PIXTEXT + +<item>GTK_CELL_WIDGET +</itemize> + +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. + +<tscreen><verb> +void gtk_clist_set_shift( GtkCList *clist, + gint row, + gint column, + gint vertical, + gint horizontal ); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>Storing data pointers +<p> +With a GtkCList it is possible to set a data pointer for a row. This +pointer will not be visible for the user, but is merely a convinience for +the programmer to associate a row with a pointer to some additional data. + +The functions should be fairly self-explanatory by now + +<tscreen><verb> +void gtk_clist_set_row_data( GtkCList *clist, + gint row, + gpointer data ); + +void 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 ); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>Working with selections +<p> +There are also functions available that let us force the (un)selection +of a row. These are + +<tscreen><verb> +void gtk_clist_select_row( GtkCList *clist, + gint row, + gint column ); + +void gtk_clist_unselect_row( GtkCList *clist, + gint row, + gint column ); +</verb></tscreen> + +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. + +<tscreen><verb> +gint gtk_clist_get_selection_info( GtkCList *clist, + gint x, + gint y, + gint *row, + gint *column ); +</verb></tscreen> + +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 more simple way... + +<!-- ----------------------------------------------------------------- --> +<sect1>The signals that bring it together +<p> +As with all other widgets, there are a few signals that can be used. The +GtkCList widget is derived from the GtkContainer widget, and so has all the +same signals, but also the adds following: + +<itemize> +<item>select_row - This signal will send the following information, in +order: GtkCList *clist, gint row, gint column, GtkEventButton *event + +<item>unselect_row - When the user unselects a row, this signal is activated. It +sends the same information as select_row + +<item>click_column - Send GtkCList *clist, gint column +</itemize> + +So if we want to connect a callback to select_row, the callback function would +be declared like this + +<tscreen><verb> +void select_row_callback(GtkWidget *widget, + gint row, + gint column, + GdkEventButton *event, + gpointer data); +</verb></tscreen> + +The callback is connected as usual with + +<tscreen><verb> +gtk_signal_connect(GTK_OBJECT( clist), + "select_row" + GTK_SIGNAL_FUNC(select_row_callback), + NULL); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>A GtkCList example +<p> + +<tscreen><verb> +/* example-start clist clist.c */ + +#include <gtk/gtk.h> +#include <glib.h> + +/* These are just the prototypes of the various callbacks */ +void button_add_clicked( GtkWidget *button, gpointer data); +void button_clear_clicked( GtkWidget *button, gpointer data); +void button_hide_show_clicked( GtkWidget *button, gpointer data); +void selection_made( GtkWidget *clist, gint row, gint column, + GdkEventButton *event, gpointer data); + +gint main (int argc, gchar *argv[]) +{ + GtkWidget *window; + GtkWidget *vbox, *hbox; + GtkWidget *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_usize(GTK_WIDGET(window), 300, 150); + + gtk_window_set_title(GTK_WINDOW(window), "GtkCList Example"); + gtk_signal_connect(GTK_OBJECT(window), + "destroy", + GTK_SIGNAL_FUNC(gtk_main_quit), + NULL); + + vbox=gtk_vbox_new(FALSE, 5); + gtk_container_border_width(GTK_CONTAINER(vbox), 5); + gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_widget_show(vbox); + + /* Create the GtkCList. 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 it's code can be found further down */ + gtk_signal_connect(GTK_OBJECT(clist), "select_row", + GTK_SIGNAL_FUNC(selection_made), + NULL); + + /* It isn't necessary to shadow the border, but it looks nice :) */ + gtk_clist_set_border(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); + + /* Scollbars _only when needed_ */ + gtk_clist_set_policy(GTK_CLIST(clist), GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + /* Add the GtkCList widget to the vertical box and show it. */ + gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0); + gtk_widget_show(clist); + + /* Create the buttons and add them to the window. See the button + * tutorial for more examples and comments on this. + */ + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + gtk_widget_show(hbox); + + button_add = gtk_button_new_with_label("Add List"); + button_clear = gtk_button_new_with_label("Clear List"); + button_hide_show = gtk_button_new_with_label("Hide/Show titles"); + + gtk_box_pack_start(GTK_BOX(hbox), button_add, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), button_clear, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), button_hide_show, TRUE, TRUE, 0); + + /* Connect our callbacks to the three buttons */ + gtk_signal_connect_object(GTK_OBJECT(button_add), "clicked", + GTK_SIGNAL_FUNC(button_add_clicked), + (gpointer) clist); + gtk_signal_connect_object(GTK_OBJECT(button_clear), "clicked", + GTK_SIGNAL_FUNC(button_clear_clicked), + (gpointer) clist); + gtk_signal_connect_object(GTK_OBJECT(button_hide_show), "clicked", + GTK_SIGNAL_FUNC(button_hide_show_clicked), + (gpointer) clist); + + gtk_widget_show(button_add); + gtk_widget_show(button_clear); + gtk_widget_show(button_hide_show); + + /* The interface is completely set up so we show the window and + * enter the gtk_main loop. + */ + gtk_widget_show(window); + gtk_main(); + + return 0; +} + +/* User clicked the "Add List" button. */ +void button_add_clicked( GtkWidget *button, 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( GtkWidget *button, 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( GtkWidget *button, 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; +} +/* example-end */ +</verb></tscreen> + +<!-- ***************************************************************** --> +<sect> List Widget <!-- ***************************************************************** --> <p> NOTE: The GtkList widget has been superseded by the GtkCList widget. @@ -5879,9 +6589,6 @@ from your time. <sect1> Fixed Container <p> <!-- ----------------------------------------------------------------- --> -<sect1> CList -<p> -<!-- ----------------------------------------------------------------- --> <sect1> Range Controls <p> <!-- ----------------------------------------------------------------- --> @@ -6557,6 +7264,8 @@ void input_callback( gpointer data, GdkInputCondition condition ); </verb></tscreen> +Where <tt/source/ and <tt/condition/ are as specified above. + <!-- ----------------------------------------------------------------- --> <sect1>Idle Functions <p> diff --git a/docs/tutorial/gtk_tut.sgml b/docs/tutorial/gtk_tut.sgml index ba5535225e..fe93a7cbac 100644 --- a/docs/tutorial/gtk_tut.sgml +++ b/docs/tutorial/gtk_tut.sgml @@ -10,7 +10,7 @@ name="<imain@gtk.org>"></tt>, Tony Gale <tt><htmlurl url="mailto:gale@gtk.org" name="<gale@gtk.org>"></tt> -<date>June 2nd, 1998 +<date>June 24th, 1998 <!-- ***************************************************************** --> <sect>Introduction @@ -4374,9 +4374,719 @@ main (int argc, char *argv[]) } /* example-end */ </verb></tscreen> - + <!-- ***************************************************************** --> -<sect> List Widgets +<sect>CList Widget +<!-- ***************************************************************** --> + +<!-- ----------------------------------------------------------------- --> +<p> +The GtkCList widget has replaced the GtkList widget (which is still +available). + +The GtkCList 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 it's selection. + +<!-- ----------------------------------------------------------------- --> +<sect1>Creating a GtkCList widget +<p> +Creating a GtkCList 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. + +<tscreen><verb> +GtkWidget *gtk_clist_new ( gint columns ); + +GtkWidget *gtk_clist_new_with_titles( gint columns, + gchar *titles[] ); +</verb></tscreen> + +The first form is very straight forward, 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. + +<!-- ----------------------------------------------------------------- --> +<sect1>Modes of operation +<p> +There are several attributes that can be used to alter the behaviour of +a GtkCList. First there is + +<tscreen><verb> +void gtk_clist_set_selection_mode( GtkCList *clist, + GtkSelectionMode mode ); +</verb></tscreen> + +which, as the name implies, sets the selection mode of the GtkCList. The first +argument is the GtkCList 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: + +<itemize> +<item> GTK_SELECTION_SINGLE - The selection is either NULL or contains a GList +pointer for a single selected item. + +<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. + +<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 <bf>default</bf> for the GtkCList widget. + +<item> GTK_SELECTION_EXTENDED - The selection is always NULL. +</itemize> + +Others might be added in later revisions of GTK. + +Then there is + +<tscreen><verb> +void gtk_clist_set_policy (GtkCList * clist, + GtkPolicyType vscrollbar_policy, + GtkPolicyType hscrollbar_policy); +</verb></tscreen> + +which defines what happens to the scrollbars. The following values are possible +for both the vertical and the horizontal scrollbar: + +<itemize> +<item> GTK_POLICY_ALWAYS - The scrollbar will always be there. + +<item> GTK_POLICY_AUTOMATIC - The scrollbar will be there only when the number +of items in the GtkCList exceeds the number that can be shown in the widget. +</itemize> + +We can also define what the border of the GtkCList widget should look like. It is +done through + +<tscreen><verb> +void gtk_clist_set_border( GtkCList *clist, + GtkShadowType border ); +</verb></tscreen> + +And the possible values for the second argument are + +<itemize> +<item> GTK_SHADOW_NONE + +<item> GTK_SHADOW_IN + +<item> GTK_SHADOW_OUT + +<item> GTK_SHADOW_ETCHED_IN + +<item> GTK_SHADOW_ETCHED_OUT +</itemize> + +<!-- ----------------------------------------------------------------- --> +<sect1>Working with titles +<p> +When you create a GtkCList 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. + +<tscreen><verb> +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 ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_column_titles_show( GtkCList *clist ); + +void gtk_clist_column_titles_hide( GtkCList *clist ); +</verb></tscreen> + +For titles to be really useful we need a mechanism to set and change them, +and this is done using + +<tscreen><verb> +void gtk_clist_set_column_title( GtkCList *clist, + gint column, + gchar *title ); +</verb></tscreen> + +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. 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. GtkCList provides us with title buttons that can in fact +incorporate whole widgets, for example a pixmap. It's all done through + +<tscreen><verb> +void gtk_clist_set_column_widget( GtkCList *clist, + gint column, + GtkWidget *widget ); +</verb></tscreen> + +which should require no special explanation. + +<!-- ----------------------------------------------------------------- --> +<sect1>Manipulating the list itself +<p> +It is possible to change the justification for a column, and it is done through + +<tscreen><verb> +void gtk_clist_set_column_justification( GtkCList *clist, + gint column, + GtkJustification justification ); +</verb></tscreen> + +The GtkJustification type can take the following values: + +<itemize> +<item>GTK_JUSTIFY_LEFT - The text in the column will begin from the left edge. + +<item>GTK_JUSTIFY_RIGHT - The text in the column will begin from the right edge. + +<item>GTK_JUSTIFY_CENTER - The text is placed in the center of the column. + +<item>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 inidvidual letters of it's a single word). Much in the same way as +any ordinary WYSIWYG text editor. +</itemize> + +The next function is a very important one, and should be standard in the setup +of all GtkCList 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 + +<tscreen><verb> +void gtk_clist_set_column_width( GtkCList *clist, + gint column, + gint width ); +</verb></tscreen> + +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 + +<tscreen><verb> +void gtk_clist_set_row_height( GtkCList *clist, + gint height ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_moveto( GtkCList *clist, + gint row, + gint column, + gfloat row_align, + gfloat col_align ); +</verb></tscreen> + +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. + +<tscreen><verb> +GtkVisibility gtk_clist_row_is_visible( GtkCList *clist, + gint row ); +</verb></tscreen> + +The return value is is one of the following: + +<itemize> +<item>GTK_VISIBILITY_NONE + +<item>GTK_VISIBILITY_PARTIAL + +<item>GTK_VISIBILITY_FULL +</itemize> + +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 + +<tscreen><verb> +void gtk_clist_set_foreground( GtkCList *clist, + gint row, + GdkColor *color ); + +void gtk_clist_set_background( GtkCList *clist, + gint row, + GdkColor *color ); +</verb></tscreen> + +Please note that the colors must have been previously allocated. + +<!-- ----------------------------------------------------------------- --> +<sect1>Adding rows to the list +<p> +We can add rows in two ways. They can be appended at the end to the list using + +<tscreen><verb> +gint gtk_clist_append( GtkCList *clist, + gchar *text[] ); +</verb></tscreen> + +or we can insert a row at a given place using + +<tscreen><verb> +void gtk_clist_insert( GtkCList *clist, + gint row, + gchar *text[] ); +</verb></tscreen> + +In both 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 + +<tscreen><verb> +void gtk_clist_remove( GtkCList *clist, + gint row ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_clear( GtkCList *clist ); +</verb></tscreen> + +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. + +<tscreen><verb> +void gtk_clist_freeze( GtkCList * clist ); + +void gtk_clist_thaw( GtkCList * clist ); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>Setting text and pixmaps in the cells +<p> +A cell can contain a pixmap, text or both. To set them the following +functions are used. + +<tscreen><verb> +void gtk_clist_set_text( GtkCList *clist, + gint row, + gint column, + 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 ); +</verb></tscreen> + +It's quite straightforward. All the calls have the GtkCList as the first +argument, followed by the row and column of the cell, follwed by the data to be +set. The gint8 spacing argument in gtk_clist_set_pixtext is the number of pixels +between the pixmap and the beginning of the text. + +To read back the data, we instead use + +<tscreen><verb> +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 ); +</verb></tscreen> + +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: + +<tscreen><verb> +gchar *mytext; + +gtk_clist_get_pixtext(clist, row, column, &mytext, NULL, NULL, NULL); +</verb></tscreen> + +There is one more call that is related to what's inside a cell in the +clist, and that's + +<tscreen><verb> +GtkCellType gtk_clist_get_cell_type( GtkCList *clist, + gint row, + gint column ); +</verb></tscreen> + +which returns the type of data in a cell. The return value is one of + +<itemize> +<item>GTK_CELL_EMPTY + +<item>GTK_CELL_TEXT + +<item>GTK_CELL_PIXMAP + +<item>GTK_CELL_PIXTEXT + +<item>GTK_CELL_WIDGET +</itemize> + +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. + +<tscreen><verb> +void gtk_clist_set_shift( GtkCList *clist, + gint row, + gint column, + gint vertical, + gint horizontal ); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>Storing data pointers +<p> +With a GtkCList it is possible to set a data pointer for a row. This +pointer will not be visible for the user, but is merely a convinience for +the programmer to associate a row with a pointer to some additional data. + +The functions should be fairly self-explanatory by now + +<tscreen><verb> +void gtk_clist_set_row_data( GtkCList *clist, + gint row, + gpointer data ); + +void 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 ); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>Working with selections +<p> +There are also functions available that let us force the (un)selection +of a row. These are + +<tscreen><verb> +void gtk_clist_select_row( GtkCList *clist, + gint row, + gint column ); + +void gtk_clist_unselect_row( GtkCList *clist, + gint row, + gint column ); +</verb></tscreen> + +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. + +<tscreen><verb> +gint gtk_clist_get_selection_info( GtkCList *clist, + gint x, + gint y, + gint *row, + gint *column ); +</verb></tscreen> + +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 more simple way... + +<!-- ----------------------------------------------------------------- --> +<sect1>The signals that bring it together +<p> +As with all other widgets, there are a few signals that can be used. The +GtkCList widget is derived from the GtkContainer widget, and so has all the +same signals, but also the adds following: + +<itemize> +<item>select_row - This signal will send the following information, in +order: GtkCList *clist, gint row, gint column, GtkEventButton *event + +<item>unselect_row - When the user unselects a row, this signal is activated. It +sends the same information as select_row + +<item>click_column - Send GtkCList *clist, gint column +</itemize> + +So if we want to connect a callback to select_row, the callback function would +be declared like this + +<tscreen><verb> +void select_row_callback(GtkWidget *widget, + gint row, + gint column, + GdkEventButton *event, + gpointer data); +</verb></tscreen> + +The callback is connected as usual with + +<tscreen><verb> +gtk_signal_connect(GTK_OBJECT( clist), + "select_row" + GTK_SIGNAL_FUNC(select_row_callback), + NULL); +</verb></tscreen> + +<!-- ----------------------------------------------------------------- --> +<sect1>A GtkCList example +<p> + +<tscreen><verb> +/* example-start clist clist.c */ + +#include <gtk/gtk.h> +#include <glib.h> + +/* These are just the prototypes of the various callbacks */ +void button_add_clicked( GtkWidget *button, gpointer data); +void button_clear_clicked( GtkWidget *button, gpointer data); +void button_hide_show_clicked( GtkWidget *button, gpointer data); +void selection_made( GtkWidget *clist, gint row, gint column, + GdkEventButton *event, gpointer data); + +gint main (int argc, gchar *argv[]) +{ + GtkWidget *window; + GtkWidget *vbox, *hbox; + GtkWidget *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_usize(GTK_WIDGET(window), 300, 150); + + gtk_window_set_title(GTK_WINDOW(window), "GtkCList Example"); + gtk_signal_connect(GTK_OBJECT(window), + "destroy", + GTK_SIGNAL_FUNC(gtk_main_quit), + NULL); + + vbox=gtk_vbox_new(FALSE, 5); + gtk_container_border_width(GTK_CONTAINER(vbox), 5); + gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_widget_show(vbox); + + /* Create the GtkCList. 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 it's code can be found further down */ + gtk_signal_connect(GTK_OBJECT(clist), "select_row", + GTK_SIGNAL_FUNC(selection_made), + NULL); + + /* It isn't necessary to shadow the border, but it looks nice :) */ + gtk_clist_set_border(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); + + /* Scollbars _only when needed_ */ + gtk_clist_set_policy(GTK_CLIST(clist), GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + /* Add the GtkCList widget to the vertical box and show it. */ + gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0); + gtk_widget_show(clist); + + /* Create the buttons and add them to the window. See the button + * tutorial for more examples and comments on this. + */ + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + gtk_widget_show(hbox); + + button_add = gtk_button_new_with_label("Add List"); + button_clear = gtk_button_new_with_label("Clear List"); + button_hide_show = gtk_button_new_with_label("Hide/Show titles"); + + gtk_box_pack_start(GTK_BOX(hbox), button_add, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), button_clear, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), button_hide_show, TRUE, TRUE, 0); + + /* Connect our callbacks to the three buttons */ + gtk_signal_connect_object(GTK_OBJECT(button_add), "clicked", + GTK_SIGNAL_FUNC(button_add_clicked), + (gpointer) clist); + gtk_signal_connect_object(GTK_OBJECT(button_clear), "clicked", + GTK_SIGNAL_FUNC(button_clear_clicked), + (gpointer) clist); + gtk_signal_connect_object(GTK_OBJECT(button_hide_show), "clicked", + GTK_SIGNAL_FUNC(button_hide_show_clicked), + (gpointer) clist); + + gtk_widget_show(button_add); + gtk_widget_show(button_clear); + gtk_widget_show(button_hide_show); + + /* The interface is completely set up so we show the window and + * enter the gtk_main loop. + */ + gtk_widget_show(window); + gtk_main(); + + return 0; +} + +/* User clicked the "Add List" button. */ +void button_add_clicked( GtkWidget *button, 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( GtkWidget *button, 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( GtkWidget *button, 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; +} +/* example-end */ +</verb></tscreen> + +<!-- ***************************************************************** --> +<sect> List Widget <!-- ***************************************************************** --> <p> NOTE: The GtkList widget has been superseded by the GtkCList widget. @@ -5879,9 +6589,6 @@ from your time. <sect1> Fixed Container <p> <!-- ----------------------------------------------------------------- --> -<sect1> CList -<p> -<!-- ----------------------------------------------------------------- --> <sect1> Range Controls <p> <!-- ----------------------------------------------------------------- --> @@ -6557,6 +7264,8 @@ void input_callback( gpointer data, GdkInputCondition condition ); </verb></tscreen> +Where <tt/source/ and <tt/condition/ are as specified above. + <!-- ----------------------------------------------------------------- --> <sect1>Idle Functions <p> diff --git a/examples/clist/Makefile b/examples/clist/Makefile new file mode 100644 index 0000000000..d9836f7af3 --- /dev/null +++ b/examples/clist/Makefile @@ -0,0 +1,8 @@ + +CC = gcc + +clist: clist.c + $(CC) `gtk-config --cflags` `gtk-config --libs` clist.c -o clist + +clean: + rm -f *.o clist diff --git a/examples/clist/clist.c b/examples/clist/clist.c new file mode 100644 index 0000000000..2d766a13d7 --- /dev/null +++ b/examples/clist/clist.c @@ -0,0 +1,173 @@ +/* example-start clist clist.c */ + +#include <gtk/gtk.h> +#include <glib.h> + +/* These are just the prototypes of the various callbacks */ +void button_add_clicked( GtkWidget *button, gpointer data); +void button_clear_clicked( GtkWidget *button, gpointer data); +void button_hide_show_clicked( GtkWidget *button, gpointer data); +void selection_made( GtkWidget *clist, gint row, gint column, + GdkEventButton *event, gpointer data); + +gint main (int argc, gchar *argv[]) +{ + GtkWidget *window; + GtkWidget *vbox, *hbox; + GtkWidget *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_usize(GTK_WIDGET(window), 300, 150); + + gtk_window_set_title(GTK_WINDOW(window), "GtkCList Example"); + gtk_signal_connect(GTK_OBJECT(window), + "destroy", + GTK_SIGNAL_FUNC(gtk_main_quit), + NULL); + + vbox=gtk_vbox_new(FALSE, 5); + gtk_container_border_width(GTK_CONTAINER(vbox), 5); + gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_widget_show(vbox); + + /* Create the GtkCList. 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 it's code can be found further down */ + gtk_signal_connect(GTK_OBJECT(clist), "select_row", + GTK_SIGNAL_FUNC(selection_made), + NULL); + + /* It isn't necessary to shadow the border, but it looks nice :) */ + gtk_clist_set_border(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); + + /* Scollbars _only when needed_ */ + gtk_clist_set_policy(GTK_CLIST(clist), GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + /* Add the GtkCList widget to the vertical box and show it. */ + gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0); + gtk_widget_show(clist); + + /* Create the buttons and add them to the window. See the button + * tutorial for more examples and comments on this. + */ + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + gtk_widget_show(hbox); + + button_add = gtk_button_new_with_label("Add List"); + button_clear = gtk_button_new_with_label("Clear List"); + button_hide_show = gtk_button_new_with_label("Hide/Show titles"); + + gtk_box_pack_start(GTK_BOX(hbox), button_add, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), button_clear, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), button_hide_show, TRUE, TRUE, 0); + + /* Connect our callbacks to the three buttons */ + gtk_signal_connect_object(GTK_OBJECT(button_add), "clicked", + GTK_SIGNAL_FUNC(button_add_clicked), + (gpointer) clist); + gtk_signal_connect_object(GTK_OBJECT(button_clear), "clicked", + GTK_SIGNAL_FUNC(button_clear_clicked), + (gpointer) clist); + gtk_signal_connect_object(GTK_OBJECT(button_hide_show), "clicked", + GTK_SIGNAL_FUNC(button_hide_show_clicked), + (gpointer) clist); + + gtk_widget_show(button_add); + gtk_widget_show(button_clear); + gtk_widget_show(button_hide_show); + + /* The interface is completely set up so we show the window and + * enter the gtk_main loop. + */ + gtk_widget_show(window); + gtk_main(); + + return 0; +} + +/* User clicked the "Add List" button. */ +void button_add_clicked( GtkWidget *button, 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( GtkWidget *button, 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( GtkWidget *button, 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; +} +/* example-end */ |