]> Pileus Git - ~andy/gtk/blob - tests/testtooltips.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / tests / testtooltips.c
1 /* testtooltips.c: Test application for GTK+ >= 2.12 tooltips code
2  *
3  * Copyright (C) 2006-2007  Imendio AB
4  * Contact: Kristian Rietveld <kris@imendio.com>
5  *
6  * This work is provided "as is"; redistribution and modification
7  * in whole or in part, in any medium, physical or electronic is
8  * permitted without restriction.
9  *
10  * This work is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * In no event shall the authors or contributors be liable for any
15  * direct, indirect, incidental, special, exemplary, or consequential
16  * damages (including, but not limited to, procurement of substitute
17  * goods or services; loss of use, data, or profits; or business
18  * interruption) however caused and on any theory of liability, whether
19  * in contract, strict liability, or tort (including negligence or
20  * otherwise) arising in any way out of the use of this software, even
21  * if advised of the possibility of such damage.
22  */
23
24 #include <gtk/gtk.h>
25
26 static gboolean
27 query_tooltip_cb (GtkWidget  *widget,
28                   gint        x,
29                   gint        y,
30                   gboolean    keyboard_tip,
31                   GtkTooltip *tooltip,
32                   gpointer    data)
33 {
34   gtk_tooltip_set_markup (tooltip, gtk_button_get_label (GTK_BUTTON (widget)));
35   gtk_tooltip_set_icon_from_stock (tooltip, GTK_STOCK_DELETE,
36                                    GTK_ICON_SIZE_MENU);
37
38   return TRUE;
39 }
40
41 static gboolean
42 query_tooltip_custom_cb (GtkWidget  *widget,
43                          gint        x,
44                          gint        y,
45                          gboolean    keyboard_tip,
46                          GtkTooltip *tooltip,
47                          gpointer    data)
48 {
49   GdkRGBA color = { 0, 0, 1, 1 };
50   GtkWindow *window = gtk_widget_get_tooltip_window (widget);
51
52   gtk_widget_override_background_color (GTK_WIDGET (window), 0, &color);
53
54   return TRUE;
55 }
56
57 static gboolean
58 query_tooltip_text_view_cb (GtkWidget  *widget,
59                             gint        x,
60                             gint        y,
61                             gboolean    keyboard_tip,
62                             GtkTooltip *tooltip,
63                             gpointer    data)
64 {
65   GtkTextTag *tag = data;
66   GtkTextIter iter;
67   GtkTextView *text_view = GTK_TEXT_VIEW (widget);
68   GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view);
69
70   if (keyboard_tip)
71     {
72       gint offset;
73
74       g_object_get (buffer, "cursor-position", &offset, NULL);
75       gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
76     }
77   else
78     {
79       gint bx, by, trailing;
80
81       gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_TEXT,
82                                              x, y, &bx, &by);
83       gtk_text_view_get_iter_at_position (text_view, &iter, &trailing, bx, by);
84     }
85
86   if (gtk_text_iter_has_tag (&iter, tag))
87     gtk_tooltip_set_text (tooltip, "Tooltip on text tag");
88   else
89    return FALSE;
90
91   return TRUE;
92 }
93
94 static gboolean
95 query_tooltip_tree_view_cb (GtkWidget  *widget,
96                             gint        x,
97                             gint        y,
98                             gboolean    keyboard_tip,
99                             GtkTooltip *tooltip,
100                             gpointer    data)
101 {
102   GtkTreeIter iter;
103   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
104   GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
105   GtkTreePath *path = NULL;
106   gchar *tmp;
107   gchar *pathstring;
108
109   char buffer[512];
110
111   if (!gtk_tree_view_get_tooltip_context (tree_view, &x, &y,
112                                           keyboard_tip,
113                                           &model, &path, &iter))
114     return FALSE;
115
116   gtk_tree_model_get (model, &iter, 0, &tmp, -1);
117   pathstring = gtk_tree_path_to_string (path);
118
119   g_snprintf (buffer, 511, "<b>Path %s:</b> %s", pathstring, tmp);
120   gtk_tooltip_set_markup (tooltip, buffer);
121
122   gtk_tree_view_set_tooltip_row (tree_view, tooltip, path);
123
124   gtk_tree_path_free (path);
125   g_free (pathstring);
126   g_free (tmp);
127
128   return TRUE;
129 }
130
131 static GtkTreeModel *
132 create_model (void)
133 {
134   GtkTreeStore *store;
135   GtkTreeIter iter;
136
137   store = gtk_tree_store_new (1, G_TYPE_STRING);
138
139   /* A tree store with some random words ... */
140   gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
141                                      0, "File Manager", -1);
142   gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
143                                      0, "Gossip", -1);
144   gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
145                                      0, "System Settings", -1);
146   gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
147                                      0, "The GIMP", -1);
148   gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
149                                      0, "Terminal", -1);
150   gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
151                                      0, "Word Processor", -1);
152
153   return GTK_TREE_MODEL (store);
154 }
155
156 static void
157 selection_changed_cb (GtkTreeSelection *selection,
158                       GtkWidget        *tree_view)
159 {
160   gtk_widget_trigger_tooltip_query (tree_view);
161 }
162
163 static struct Rectangle
164 {
165   gint x;
166   gint y;
167   gfloat r;
168   gfloat g;
169   gfloat b;
170   const char *tooltip;
171 }
172 rectangles[] =
173 {
174   { 10, 10, 0.0, 0.0, 0.9, "Blue box!" },
175   { 200, 170, 1.0, 0.0, 0.0, "Red thing" },
176   { 100, 50, 0.8, 0.8, 0.0, "Yellow thing" }
177 };
178
179 static gboolean
180 query_tooltip_drawing_area_cb (GtkWidget  *widget,
181                                gint        x,
182                                gint        y,
183                                gboolean    keyboard_tip,
184                                GtkTooltip *tooltip,
185                                gpointer    data)
186 {
187   gint i;
188
189   if (keyboard_tip)
190     return FALSE;
191
192   for (i = 0; i < G_N_ELEMENTS (rectangles); i++)
193     {
194       struct Rectangle *r = &rectangles[i];
195
196       if (r->x < x && x < r->x + 50
197           && r->y < y && y < r->y + 50)
198         {
199           gtk_tooltip_set_markup (tooltip, r->tooltip);
200           return TRUE;
201         }
202     }
203
204   return FALSE;
205 }
206
207 static gboolean
208 drawing_area_draw (GtkWidget *drawing_area,
209                    cairo_t   *cr,
210                    gpointer   data)
211 {
212   gint i;
213
214   cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
215   cairo_paint (cr);
216
217   for (i = 0; i < G_N_ELEMENTS (rectangles); i++)
218     {
219       struct Rectangle *r = &rectangles[i];
220
221       cairo_rectangle (cr, r->x, r->y, 50, 50);
222       cairo_set_source_rgb (cr, r->r, r->g, r->b);
223       cairo_stroke (cr);
224
225       cairo_rectangle (cr, r->x, r->y, 50, 50);
226       cairo_set_source_rgba (cr, r->r, r->g, r->b, 0.5);
227       cairo_fill (cr);
228     }
229
230   return FALSE;
231 }
232
233 static gboolean
234 query_tooltip_label_cb (GtkWidget  *widget,
235                         gint        x,
236                         gint        y,
237                         gboolean    keyboard_tip,
238                         GtkTooltip *tooltip,
239                         gpointer    data)
240 {
241   GtkWidget *custom = data;
242
243   gtk_tooltip_set_custom (tooltip, custom);
244
245   return TRUE;
246 }
247
248 int
249 main (int argc, char *argv[])
250 {
251   GtkWidget *window;
252   GtkWidget *box;
253   GtkWidget *drawing_area;
254   GtkWidget *button;
255   GtkWidget *label;
256
257   GtkWidget *tooltip_window;
258   GtkWidget *tooltip_button;
259
260   GtkWidget *tree_view;
261   GtkTreeViewColumn *column;
262
263   GtkWidget *text_view;
264   GtkTextBuffer *buffer;
265   GtkTextIter iter;
266   GtkTextTag *tag;
267
268   gchar *text, *markup;
269
270   gtk_init (&argc, &argv);
271
272   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
273   gtk_window_set_title (GTK_WINDOW (window), "Tooltips test");
274   gtk_container_set_border_width (GTK_CONTAINER (window), 10);
275   g_signal_connect (window, "delete_event",
276                     G_CALLBACK (gtk_main_quit), NULL);
277
278   box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
279   gtk_container_add (GTK_CONTAINER (window), box);
280
281   /* A check button using the tooltip-markup property */
282   button = gtk_check_button_new_with_label ("This one uses the tooltip-markup property");
283   gtk_widget_set_tooltip_text (button, "Hello, I am a static tooltip.");
284   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
285
286   text = gtk_widget_get_tooltip_text (button);
287   markup = gtk_widget_get_tooltip_markup (button);
288   g_assert (g_str_equal ("Hello, I am a static tooltip.", text));
289   g_assert (g_str_equal ("Hello, I am a static tooltip.", markup));
290   g_free (text); g_free (markup);
291
292   /* A check button using the query-tooltip signal */
293   button = gtk_check_button_new_with_label ("I use the query-tooltip signal");
294   g_object_set (button, "has-tooltip", TRUE, NULL);
295   g_signal_connect (button, "query-tooltip",
296                     G_CALLBACK (query_tooltip_cb), NULL);
297   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
298
299   /* A label */
300   button = gtk_label_new ("I am just a label");
301   gtk_label_set_selectable (GTK_LABEL (button), FALSE);
302   gtk_widget_set_tooltip_text (button, "Label & and tooltip");
303   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
304
305   text = gtk_widget_get_tooltip_text (button);
306   markup = gtk_widget_get_tooltip_markup (button);
307   g_assert (g_str_equal ("Label & and tooltip", text));
308   g_assert (g_str_equal ("Label &amp; and tooltip", markup));
309   g_free (text); g_free (markup);
310
311   /* A selectable label */
312   button = gtk_label_new ("I am a selectable label");
313   gtk_label_set_selectable (GTK_LABEL (button), TRUE);
314   gtk_widget_set_tooltip_markup (button, "<b>Another</b> Label tooltip");
315   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
316
317   text = gtk_widget_get_tooltip_text (button);
318   markup = gtk_widget_get_tooltip_markup (button);
319   g_assert (g_str_equal ("Another Label tooltip", text));
320   g_assert (g_str_equal ("<b>Another</b> Label tooltip", markup));
321   g_free (text); g_free (markup);
322
323   /* Another one, with a custom tooltip window */
324   button = gtk_check_button_new_with_label ("This one has a custom tooltip window!");
325   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
326
327   tooltip_window = gtk_window_new (GTK_WINDOW_POPUP);
328   tooltip_button = gtk_label_new ("blaat!");
329   gtk_container_add (GTK_CONTAINER (tooltip_window), tooltip_button);
330   gtk_widget_show (tooltip_button);
331
332   gtk_widget_set_tooltip_window (button, GTK_WINDOW (tooltip_window));
333   g_signal_connect (button, "query-tooltip",
334                     G_CALLBACK (query_tooltip_custom_cb), NULL);
335   g_object_set (button, "has-tooltip", TRUE, NULL);
336
337   /* An insensitive button */
338   button = gtk_button_new_with_label ("This one is insensitive");
339   gtk_widget_set_sensitive (button, FALSE);
340   g_object_set (button, "tooltip-text", "Insensitive!", NULL);
341   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
342
343   /* Testcases from Kris without a tree view don't exist. */
344   tree_view = gtk_tree_view_new_with_model (create_model ());
345   gtk_widget_set_size_request (tree_view, 200, 240);
346
347   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
348                                                0, "Test",
349                                                gtk_cell_renderer_text_new (),
350                                                "text", 0,
351                                                NULL);
352
353   g_object_set (tree_view, "has-tooltip", TRUE, NULL);
354   g_signal_connect (tree_view, "query-tooltip",
355                     G_CALLBACK (query_tooltip_tree_view_cb), NULL);
356   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
357                     "changed", G_CALLBACK (selection_changed_cb), tree_view);
358
359   /* Set a tooltip on the column */
360   column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 0);
361   gtk_tree_view_column_set_clickable (column, TRUE);
362   g_object_set (gtk_tree_view_column_get_button (column), "tooltip-text", "Header", NULL);
363
364   gtk_box_pack_start (GTK_BOX (box), tree_view, FALSE, FALSE, 2);
365
366   /* And a text view for Matthias */
367   buffer = gtk_text_buffer_new (NULL);
368
369   gtk_text_buffer_get_end_iter (buffer, &iter);
370   gtk_text_buffer_insert (buffer, &iter, "Hello, the text ", -1);
371
372   tag = gtk_text_buffer_create_tag (buffer, "bold", NULL);
373   g_object_set (tag, "weight", PANGO_WEIGHT_BOLD, NULL);
374
375   gtk_text_buffer_get_end_iter (buffer, &iter);
376   gtk_text_buffer_insert_with_tags (buffer, &iter, "in bold", -1, tag, NULL);
377
378   gtk_text_buffer_get_end_iter (buffer, &iter);
379   gtk_text_buffer_insert (buffer, &iter, " has a tooltip!", -1);
380
381   text_view = gtk_text_view_new_with_buffer (buffer);
382   gtk_widget_set_size_request (text_view, 200, 50);
383
384   g_object_set (text_view, "has-tooltip", TRUE, NULL);
385   g_signal_connect (text_view, "query-tooltip",
386                     G_CALLBACK (query_tooltip_text_view_cb), tag);
387
388   gtk_box_pack_start (GTK_BOX (box), text_view, FALSE, FALSE, 2);
389
390   /* Drawing area */
391   drawing_area = gtk_drawing_area_new ();
392   gtk_widget_set_size_request (drawing_area, 320, 240);
393   g_object_set (drawing_area, "has-tooltip", TRUE, NULL);
394   g_signal_connect (drawing_area, "draw",
395                     G_CALLBACK (drawing_area_draw), NULL);
396   g_signal_connect (drawing_area, "query-tooltip",
397                     G_CALLBACK (query_tooltip_drawing_area_cb), NULL);
398   gtk_box_pack_start (GTK_BOX (box), drawing_area, FALSE, FALSE, 2);
399
400   button = gtk_label_new ("Custom tooltip I");
401   label = gtk_label_new ("See, custom");
402   g_object_ref_sink (label);
403   g_object_set (button, "has-tooltip", TRUE, NULL);
404   g_signal_connect (button, "query-tooltip",
405                     G_CALLBACK (query_tooltip_label_cb), label);
406   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 2);
407
408   button = gtk_label_new ("Custom tooltip II");
409   label = gtk_label_new ("See, custom, too");
410   g_object_ref_sink (label);
411   g_object_set (button, "has-tooltip", TRUE, NULL);
412   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 2);
413   g_signal_connect (button, "query-tooltip",
414                     G_CALLBACK (query_tooltip_label_cb), label);
415
416   /* Done! */
417   gtk_widget_show_all (window);
418
419   gtk_main ();
420
421   return 0;
422 }