~canonical-dx-team/ubuntu/maverick/gtk+2.0/menuproxy

« back to all changes in this revision

Viewing changes to docs/reference/gtk/tree_widget.sgml

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-05-04 12:24:25 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20070504122425-0m8midgzrp40y8w2
Tags: 2.10.12-1ubuntu1
* Sync with Debian
* New upstream version:
  Fixed bugs:
  - 379414 file chooser warnings when changing path in the entry
  - 418585 GtkFileChooserDefault sizing code is not DPI independent
  - 419568 Crash in search if start with special letter
  - 435062 build dies with icon cache validation
  - 379399 Segfault to call gtk_print_operation_run twice.
  - 387889 cups backend has problems when there are too many printers
  - 418531 invalid read to gtkicontheme.c gtk_icon_theme_lookup_icon...
  - 423916 crash in color scheme code
  - 424042 Segmentation fault while quickly pressing Alt+arrows
  - 415260 Protect against negative indices when setting values in G...
  - 419171 XGetVisualInfo() may not set nxvisuals
  - 128852 Gdk cursors don't look good on win32
  - 344657 Ctrl-H doesn't toggle "Show Hidden Files" setting
  - 345345 PrintOperation::paginate is not emitted for class handler
  - 347567 GtkPrintOperation::end-print is not emitted if it's cance...
  - 369112 gtk_ui_manager_add_ui should accept unnamed separator
  - 392015 Selected menu item invisible on Windows Vista
  - 399253 MS-Windows Theme Bottom Tab placement rendering glitches
  - 399425 gtk_input_dialog_fill_axes() adds child to gtkscrolledwin...
  - 403251 [patch] little memory leak in GtkPrintJob
  - 403267 [patch] memory leak in GtkPageSetupUnixDialog
  - 403470 MS-Windows Theme tab placement other than on top leaks a ...
  - 404506 Windows system fonts that have multi-byte font names cann...
  - 405089 Incorrect window placement for GtkEventBox private window
  - 405515 Minor leak in gtkfilesystemmodel.c
  - 405539 gdk_pixbuf_save() for PNG saver can return FALSE without ...
  - 415681 gdk_window_clear_area includes an extra line and column o...
  - 418219 GtkRecentChooser should apply filter before sorting and c...
  - 418403 Scroll to printer after selecting it from settings
  - 421985 _gtk_print_operation_platform_backend_launch_preview
  - 421990 gtk_print_job_get_surface
  - 421993 gtk_print_operation_init
  - 423064 Conditional jump or move depends on uninitialised value(s...
  - 423722 Fix printing header in gtk-demo
  - 424168 gtk_print_operation_run on async preview
  - 425655 Don't install gtk+-unix-print-2.0.pc on non-UNIX platforms
  - 425786 GDK segfaults if XineramaQueryScreens fails
  - 428665 Lpr Backend gets stuck in infinite loop during gtk_enumer...
  - 429902 GtkPrintOperation leaks cairo contextes
  - 431997 First delay of GdkPixbufAnimationIter is wrong
  - 433242 Inconsistent scroll arrow position calculations
  - 433972 Placing gtk.Expander inside a gtk.TextView() changes gtk....
  - 434261 _gtk_toolbar_elide_underscores incorrectly handles some s...
  - 383354 ctrl-L should make 'Location' entry disappear
  - 418673 gtk_recent_manager_add_item
  - 429732 gtk_accel_group_finalize accesses invalid memory
  - 435028 WM_CLIENT_LEADER is wrong on the leader_window
  - 431067 Background of the header window is not updated
  - 338843 add recent files support inside the ui manager
  - 148535 add drop shadow to menus, tooltips, etc. under Windows XP
* debian/control.in:
  - Conflicts on ubuntulooks (<= 0.9.11-1)
* debian/patches/15_default-fallback-icon-theme.patch:
  - patch from Debian, fallback on gnome icon theme

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<refentry id="TreeWidget" revision="20 Mar 2002">
 
2
  <refmeta>
 
3
    <refentrytitle>Tree and List Widget Overview</refentrytitle>
 
4
    <manvolnum>3</manvolnum>
 
5
    <refmiscinfo>GTK Library</refmiscinfo>
 
6
  </refmeta>
 
7
 
 
8
  <refnamediv>
 
9
    <refname>Tree and List Widget Overview</refname>
 
10
    <refpurpose>Overview of #GtkTreeModel, #GtkTreeView, and other 
 
11
    associated widgets</refpurpose>
 
12
  </refnamediv>
 
13
 
 
14
  <refsect1>
 
15
    <title>Overview</title>
 
16
    <para>
 
17
      To create a tree or list in GTK+, use the #GtkTreeModel interface in
 
18
      conjunction with the #GtkTreeView widget.  This widget is
 
19
      designed around a <firstterm>Model/View/Controller</firstterm>
 
20
      design and consists of four major parts:
 
21
      <simplelist>
 
22
        <member>The tree view widget (<structname>GtkTreeView</structname>)</member>
 
23
        <member>The view column (<structname>GtkTreeViewColumn</structname>)</member>
 
24
        <member>The cell renderers (<structname>GtkCellRenderer</structname> etc.)</member>
 
25
        <member>The model interface (<structname>GtkTreeModel</structname>)</member>
 
26
      </simplelist>
 
27
      The <emphasis>View</emphasis> is composed of the first three
 
28
        objects, while the last is the <emphasis>Model</emphasis>.  One
 
29
        of the prime benefits of the MVC design is that multiple views
 
30
        can be created of a single model.  For example, a model mapping
 
31
        the file system could be created for a file manager.  Many views
 
32
        could be created to display various parts of the file system,
 
33
        but only one copy need be kept in memory.
 
34
    </para>
 
35
    <para>
 
36
        The purpose of the cell renderers is to provide extensibility to the
 
37
        widget and to allow multiple ways of rendering the same type of data.
 
38
        For example, consider how to render a boolean variable.  Should it
 
39
        render it as a string of "True" or "False", "On" or "Off", or should
 
40
        it be rendered as a checkbox?
 
41
    </para>
 
42
  </refsect1>
 
43
  <refsect1>
 
44
    <title>Creating a model</title>
 
45
    <para>
 
46
      GTK+ provides two simple models that can be used: the #GtkListStore
 
47
      and the #GtkTreeStore.  GtkListStore is used to model list widgets, 
 
48
      while the GtkTreeStore models trees.  It is possible to develop a new 
 
49
      type of model, but the existing models should be satisfactory for all 
 
50
      but the most specialized of situations.  Creating the model is quite 
 
51
      simple:
 
52
    </para>
 
53
      <informalexample><programlisting><![CDATA[
 
54
GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
 
55
]]></programlisting></informalexample>
 
56
    <para>
 
57
      This creates a list store with two columns: a string column and a boolean
 
58
      column.  Typically the 2 is never passed directly like that; usually an
 
59
      enum is created wherein the different columns are enumerated, followed by
 
60
      a token that represents the total number of columns.  The next example will
 
61
      illustrate this, only using a tree store instead of a list store. Creating
 
62
      a tree store operates almost exactly the same.
 
63
    </para>
 
64
    <informalexample><programlisting><![CDATA[
 
65
enum
 
66
{
 
67
   TITLE_COLUMN,
 
68
   AUTHOR_COLUMN,
 
69
   CHECKED_COLUMN,
 
70
   N_COLUMNS
 
71
};
 
72
 
 
73
GtkTreeStore *store = gtk_tree_store_new (N_COLUMNS,       /* Total number of columns */
 
74
                                          G_TYPE_STRING,   /* Book title              */
 
75
                                          G_TYPE_STRING,   /* Author                  */
 
76
                                          G_TYPE_BOOLEAN); /* Is checked out?         */
 
77
]]></programlisting></informalexample>
 
78
    <para>
 
79
      Adding data to the model is done using gtk_tree_store_set() or 
 
80
      gtk_list_store_set(), depending upon which sort of model was
 
81
      created.  To do this, a #GtkTreeIter must be acquired.  The iterator 
 
82
      points to the location where data will be added.
 
83
    </para>
 
84
    <para>
 
85
      Once an iterator has been acquired, gtk_tree_store_set() is used to
 
86
      apply data to the part of the model that the iterator points to.  
 
87
      Consider the following example:
 
88
    </para>
 
89
    <informalexample><programlisting><![CDATA[
 
90
GtkTreeIter   iter;
 
91
 
 
92
gtk_tree_store_append (store, &iter, NULL);  /* Acquire an iterator */
 
93
 
 
94
gtk_tree_store_set (store, &iter,
 
95
                    TITLE_COLUMN, "The Principle of Reason",
 
96
                    AUTHOR_COLUMN, "Martin Heidegger",
 
97
                    CHECKED_COLUMN, FALSE,
 
98
                    -1);
 
99
]]></programlisting></informalexample>
 
100
 
 
101
  <para>
 
102
    Notice that the last argument is -1.  This is always done because
 
103
    this is a variable-argument function and it needs to know when to stop
 
104
    processing arguments.  It can be used to set the data in any or all
 
105
    columns in a given row.
 
106
  </para>
 
107
  <para>
 
108
    The third argument to gtk_tree_store_append() is the parent iterator.  It
 
109
    is used to add a row to a GtkTreeStore as a child of an existing row.  This
 
110
    means that the new row will only be visible when its parent is visible and
 
111
    in its expanded state.  Consider the following example:
 
112
  </para>
 
113
  <informalexample><programlisting><![CDATA[
 
114
GtkTreeIter iter1;  /* Parent iter */
 
115
GtkTreeIter iter2;  /* Child iter  */
 
116
 
 
117
gtk_tree_store_append (store, &iter1, NULL);  /* Acquire a top-level iterator */
 
118
gtk_tree_store_set (store, &iter1,
 
119
                    TITLE_COLUMN, "The Art of Computer Programming",
 
120
                    AUTHOR_COLUMN, "Donald E. Knuth",
 
121
                    CHECKED_COLUMN, FALSE,
 
122
                    -1);
 
123
 
 
124
gtk_tree_store_append (store, &iter2, &iter1);  /* Acquire a child iterator */
 
125
gtk_tree_store_set (store, &iter2,
 
126
                    TITLE_COLUMN, "Volume 1: Fundamental Algorithms",
 
127
                    -1);
 
128
 
 
129
gtk_tree_store_append (store, &iter2, &iter1);
 
130
gtk_tree_store_set (store, &iter2,
 
131
                    TITLE_COLUMN, "Volume 2: Seminumerical Algorithms",
 
132
                    -1);
 
133
 
 
134
gtk_tree_store_append (store, &iter2, &iter1);
 
135
gtk_tree_store_set (store, &iter2,
 
136
                    TITLE_COLUMN, "Volume 3: Sorting and Searching",
 
137
                    -1);
 
138
]]></programlisting></informalexample>
 
139
  </refsect1>
 
140
 
 
141
  <refsect1>
 
142
    <title>Creating the view component</title>
 
143
    <para>
 
144
      While there are several different models to choose from, there is
 
145
      only one view widget to deal with.  It works with either the list
 
146
      or the tree store.  Setting up a #GtkTreeView is not a difficult
 
147
      matter.  It needs a #GtkTreeModel to know where to retrieve its data 
 
148
      from.
 
149
    </para>
 
150
    <informalexample><programlisting><![CDATA[
 
151
GtkWidget *tree;
 
152
 
 
153
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
 
154
]]></programlisting></informalexample>
 
155
 
 
156
    <refsect2>
 
157
      <title>Columns and cell renderers</title>
 
158
      <para>
 
159
        Once the #GtkTreeView widget has a model, it will need to know how 
 
160
        to display the model.  It does this with columns and cell renderers.
 
161
      </para>
 
162
      <para>
 
163
        Cell renderers are used to draw the data in the tree model in a
 
164
        way.  There are a number of cell renderers that come with GTK+ 2.x,
 
165
        including the #GtkCellRendererText, #GtkCellRendererPixbuf and
 
166
        the #GtkCellRendererToggle.
 
167
        It is relatively easy to write a custom renderer.
 
168
      </para>
 
169
      <para>
 
170
        A #GtkTreeViewColumn is the object that GtkTreeView uses to organize 
 
171
        the vertical columns in the tree view.  It needs to know the name of 
 
172
        the column to label for the user, what type of cell renderer to use, 
 
173
        and which piece of data to retrieve from the model for a given row.
 
174
      </para>
 
175
      <informalexample><programlisting>
 
176
GtkCellRenderer *renderer;
 
177
GtkTreeViewColumn *column;
 
178
 
 
179
renderer = gtk_cell_renderer_text_new (<!-- -->);
 
180
column = gtk_tree_view_column_new_with_attributes ("Author",
 
181
                                                   renderer,
 
182
                                                   "text", AUTHOR_COLUMN,
 
183
                                                   NULL);
 
184
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
 
185
</programlisting></informalexample>
 
186
      <para>
 
187
       At this point, all the steps in creating a displayable tree have been
 
188
       covered.  The model is created, data is stored in it, a tree view is
 
189
       created and columns are added to it.
 
190
      </para>
 
191
    </refsect2>
 
192
 
 
193
    <refsect2>
 
194
      <title>Selection handling</title>
 
195
      <para>
 
196
        Most applications will need to not only deal with displaying data, but 
 
197
        also receiving input events from users.  To do this, simply get a 
 
198
        reference to a selection object and connect to the "changed" signal.
 
199
      </para>
 
200
      <informalexample><programlisting><![CDATA[
 
201
/* Prototype for selection handler callback */
 
202
static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
 
203
 
 
204
/* Setup the selection handler */
 
205
GtkTreeSelection *select;
 
206
 
 
207
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
 
208
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
 
209
g_signal_connect (G_OBJECT (select), "changed",
 
210
                  G_CALLBACK (tree_selection_changed_cb),
 
211
                  NULL);
 
212
]]></programlisting></informalexample>
 
213
        <para>
 
214
          Then to retrieve data for the row selected:
 
215
        </para>
 
216
        <informalexample><programlisting><![CDATA[
 
217
static void
 
218
tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
 
219
{
 
220
        GtkTreeIter iter;
 
221
        GtkTreeModel *model;
 
222
        gchar *author;
 
223
 
 
224
        if (gtk_tree_selection_get_selected (selection, &model, &iter))
 
225
        {
 
226
                gtk_tree_model_get (model, &iter, AUTHOR_COLUMN, &author, -1);
 
227
 
 
228
                g_print ("You selected a book by %s\n", author);
 
229
 
 
230
                g_free (author);
 
231
        }
 
232
}
 
233
]]></programlisting></informalexample>
 
234
    </refsect2>
 
235
  </refsect1>
 
236
 
 
237
  <refsect1>
 
238
    <title>Simple Example</title>
 
239
    <para>
 
240
      Here is a simple example of using a #GtkTreeView widget in context 
 
241
      of the other widgets.  It simply creates a simple model and view, 
 
242
      and puts them together.  Note that the model is never populated 
 
243
      with data &mdash; that is left as an exercise for the reader.  
 
244
      More information can be found on this in the #GtkTreeModel section.
 
245
      <informalexample><programlisting>
 
246
enum
 
247
{
 
248
   TITLE_COLUMN,
 
249
   AUTHOR_COLUMN,
 
250
   CHECKED_COLUMN,
 
251
   N_COLUMNS
 
252
};
 
253
 
 
254
void
 
255
setup_tree (void)
 
256
{
 
257
   GtkTreeStore *store;
 
258
   GtkWidget *tree;
 
259
   GtkTreeViewColumn *column;
 
260
   GtkCellRenderer *renderer;
 
261
 
 
262
   /* Create a model.  We are using the store model for now, though we
 
263
    * could use any other GtkTreeModel */
 
264
   store = gtk_tree_store_new (N_COLUMNS,
 
265
                               G_TYPE_STRING,
 
266
                               G_TYPE_STRING,
 
267
                               G_TYPE_BOOLEAN);
 
268
 
 
269
   /* custom function to fill the model with data */
 
270
   populate_tree_model (store);
 
271
 
 
272
   /* Create a view */
 
273
   tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
 
274
 
 
275
   /* The view now holds a reference.  We can get rid of our own
 
276
    * reference */
 
277
   g_object_unref (G_OBJECT (store));
 
278
 
 
279
   /* Create a cell render and arbitrarily make it red for demonstration
 
280
    * purposes */
 
281
   renderer = gtk_cell_renderer_text_new (<!-- -->);
 
282
   g_object_set (G_OBJECT (renderer),
 
283
                 "foreground", "red",
 
284
                 NULL);
 
285
 
 
286
   /* Create a column, associating the "text" attribute of the
 
287
    * cell_renderer to the first column of the model */
 
288
   column = gtk_tree_view_column_new_with_attributes ("Author", renderer,
 
289
                                                      "text", AUTHOR_COLUMN,
 
290
                                                      NULL);
 
291
 
 
292
   /* Add the column to the view. */
 
293
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
 
294
 
 
295
   /* Second column.. title of the book. */
 
296
   renderer = gtk_cell_renderer_text_new (<!-- -->);
 
297
   column = gtk_tree_view_column_new_with_attributes ("Title",
 
298
                                                      renderer,
 
299
                                                      "text", TITLE_COLUMN,
 
300
                                                      NULL);
 
301
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
 
302
 
 
303
   /* Last column.. whether a book is checked out. */
 
304
   renderer = gtk_cell_renderer_toggle_new (<!-- -->);
 
305
   column = gtk_tree_view_column_new_with_attributes ("Checked out",
 
306
                                                      renderer,
 
307
                                                      "active", CHECKED_COLUMN,
 
308
                                                      NULL);
 
309
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
 
310
 
 
311
   /* Now we can manipulate the view just like any other GTK widget */
 
312
   ...
 
313
}
 
314
      </programlisting></informalexample>
 
315
    </para>
 
316
  </refsect1>
 
317
</refentry>