]> Pileus Git - ~andy/gtk/blob - gtk/gtktooltips.c
Revert name change
[~andy/gtk] / gtk / gtktooltips.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdio.h>
32
33 #undef GTK_DISABLE_DEPRECATED
34
35 #include "gtklabel.h"
36 #include "gtkmain.h"
37 #include "gtkmenuitem.h"
38 #include "gtkprivate.h"
39 #include "gtkwidget.h"
40 #include "gtkwindow.h"
41 #include "gtkstyle.h"
42 #include "gtktooltips.h"
43 #include "gtkintl.h"
44 #include "gtkalias.h"
45
46
47 #define DEFAULT_DELAY 500           /* Default delay in ms */
48 #define STICKY_DELAY 0              /* Delay before popping up next tip
49                                      * if we're sticky
50                                      */
51 #define STICKY_REVERT_DELAY 1000    /* Delay before sticky tooltips revert
52                                      * to normal
53                                      */
54 #define GTK_TOOLTIPS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TOOLTIPS, GtkTooltipsPrivate))
55
56 typedef struct _GtkTooltipsPrivate GtkTooltipsPrivate;
57
58 struct _GtkTooltipsPrivate
59 {
60   GHashTable *tips_data_table;
61 };
62
63
64 static void gtk_tooltips_finalize          (GObject         *object);
65 static void gtk_tooltips_destroy           (GtkObject       *object);
66
67 static void gtk_tooltips_destroy_data      (GtkTooltipsData *tooltipsdata);
68
69 static void gtk_tooltips_widget_remove     (GtkWidget       *widget,
70                                             gpointer         data);
71
72 static const gchar  tooltips_data_key[] = "_GtkTooltipsData";
73 static const gchar  tooltips_info_key[] = "_GtkTooltipsInfo";
74
75 G_DEFINE_TYPE (GtkTooltips, gtk_tooltips, GTK_TYPE_OBJECT)
76
77 static void
78 gtk_tooltips_class_init (GtkTooltipsClass *class)
79 {
80   GtkObjectClass *object_class = (GtkObjectClass *) class;
81   GObjectClass *gobject_class = (GObjectClass *) class;
82
83   gobject_class->finalize = gtk_tooltips_finalize;
84
85   object_class->destroy = gtk_tooltips_destroy;
86
87   g_type_class_add_private (gobject_class, sizeof (GtkTooltipsPrivate));
88 }
89
90 static void
91 gtk_tooltips_init (GtkTooltips *tooltips)
92 {
93   GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
94
95   tooltips->tip_window = NULL;
96   tooltips->active_tips_data = NULL;
97   tooltips->tips_data_list = NULL;
98
99   tooltips->delay = DEFAULT_DELAY;
100   tooltips->enabled = TRUE;
101   tooltips->timer_tag = 0;
102   tooltips->use_sticky_delay = FALSE;
103   tooltips->last_popdown.tv_sec = -1;
104   tooltips->last_popdown.tv_usec = -1;
105
106   private->tips_data_table =
107     g_hash_table_new_full (NULL, NULL, NULL,
108                            (GDestroyNotify) gtk_tooltips_destroy_data);
109
110   gtk_tooltips_force_window (tooltips);
111 }
112
113 static void
114 gtk_tooltips_finalize (GObject *object)
115 {
116   GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (object);
117
118   g_hash_table_destroy (private->tips_data_table);
119
120   G_OBJECT_CLASS (gtk_tooltips_parent_class)->finalize (object);
121 }
122
123 GtkTooltips *
124 gtk_tooltips_new (void)
125 {
126   return g_object_new (GTK_TYPE_TOOLTIPS, NULL);
127 }
128
129 static void
130 gtk_tooltips_destroy_data (GtkTooltipsData *tooltipsdata)
131 {
132   g_free (tooltipsdata->tip_text);
133   g_free (tooltipsdata->tip_private);
134
135   g_signal_handlers_disconnect_by_func (tooltipsdata->widget,
136                                         gtk_tooltips_widget_remove,
137                                         tooltipsdata);
138
139   g_object_set_data (G_OBJECT (tooltipsdata->widget), I_(tooltips_data_key), NULL);
140   g_object_unref (tooltipsdata->widget);
141   g_free (tooltipsdata);
142 }
143
144 static void
145 gtk_tooltips_destroy (GtkObject *object)
146 {
147   GtkTooltips *tooltips = GTK_TOOLTIPS (object);
148   GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
149
150   if (tooltips->tip_window)
151     {
152       gtk_widget_destroy (tooltips->tip_window);
153       tooltips->tip_window = NULL;
154     }
155
156   g_hash_table_remove_all (private->tips_data_table);
157
158   GTK_OBJECT_CLASS (gtk_tooltips_parent_class)->destroy (object);
159 }
160
161 void
162 gtk_tooltips_force_window (GtkTooltips *tooltips)
163 {
164   g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
165
166   if (!tooltips->tip_window)
167     {
168       tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP);
169       g_signal_connect (tooltips->tip_window,
170                         "destroy",
171                         G_CALLBACK (gtk_widget_destroyed),
172                         &tooltips->tip_window);
173
174       tooltips->tip_label = gtk_label_new (NULL);
175       gtk_container_add (GTK_CONTAINER (tooltips->tip_window),
176                          tooltips->tip_label);
177     }
178 }
179
180 void
181 gtk_tooltips_enable (GtkTooltips *tooltips)
182 {
183   g_return_if_fail (tooltips != NULL);
184
185   tooltips->enabled = TRUE;
186 }
187
188 void
189 gtk_tooltips_disable (GtkTooltips *tooltips)
190 {
191   g_return_if_fail (tooltips != NULL);
192
193   tooltips->enabled = FALSE;
194 }
195
196 void
197 gtk_tooltips_set_delay (GtkTooltips *tooltips,
198                         guint         delay)
199 {
200   g_return_if_fail (tooltips != NULL);
201
202   tooltips->delay = delay;
203 }
204
205 GtkTooltipsData*
206 gtk_tooltips_data_get (GtkWidget       *widget)
207 {
208   g_return_val_if_fail (widget != NULL, NULL);
209
210   return g_object_get_data (G_OBJECT (widget), tooltips_data_key);
211 }
212
213 void
214 gtk_tooltips_set_tip (GtkTooltips *tooltips,
215                       GtkWidget   *widget,
216                       const gchar *tip_text,
217                       const gchar *tip_private)
218 {
219   GtkTooltipsData *tooltipsdata;
220
221   g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
222   g_return_if_fail (widget != NULL);
223
224   tooltipsdata = gtk_tooltips_data_get (widget);
225
226   if (!tip_text)
227     {
228       if (tooltipsdata)
229         gtk_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata);
230       return;
231     }
232   
233   if (tooltips->active_tips_data 
234       && tooltipsdata
235       && tooltips->active_tips_data->widget == widget
236       && GTK_WIDGET_DRAWABLE (tooltips->active_tips_data->widget))
237     {
238       g_free (tooltipsdata->tip_text);
239       g_free (tooltipsdata->tip_private);
240
241       tooltipsdata->tip_text = g_strdup (tip_text);
242       tooltipsdata->tip_private = g_strdup (tip_private);
243     }
244   else 
245     {
246       g_object_ref (widget);
247       
248       if (tooltipsdata)
249         gtk_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata);
250       
251       tooltipsdata = g_new0 (GtkTooltipsData, 1);
252       
253       tooltipsdata->tooltips = tooltips;
254       tooltipsdata->widget = widget;
255
256       tooltipsdata->tip_text = g_strdup (tip_text);
257       tooltipsdata->tip_private = g_strdup (tip_private);
258
259       g_hash_table_insert (GTK_TOOLTIPS_GET_PRIVATE (tooltips)->tips_data_table,
260                            widget, tooltipsdata);
261
262       g_object_set_data (G_OBJECT (widget), I_(tooltips_data_key),
263                          tooltipsdata);
264
265       g_signal_connect (widget, "destroy",
266                         G_CALLBACK (gtk_tooltips_widget_remove),
267                         tooltipsdata);
268     }
269
270   gtk_widget_set_tooltip_text (widget, tip_text);
271 }
272
273 static void
274 gtk_tooltips_widget_remove (GtkWidget *widget,
275                             gpointer   data)
276 {
277   GtkTooltipsData *tooltipsdata = (GtkTooltipsData*) data;
278   GtkTooltips *tooltips = tooltipsdata->tooltips;
279   GtkTooltipsPrivate *private = GTK_TOOLTIPS_GET_PRIVATE (tooltips);
280
281   g_hash_table_remove (private->tips_data_table, tooltipsdata->widget);
282 }
283
284 /**
285  * gtk_tooltips_get_info_from_tip_window:
286  * @tip_window: a #GtkWindow 
287  * @tooltips: the return location for the tooltips which are displayed 
288  *    in @tip_window, or %NULL
289  * @current_widget: the return location for the widget whose tooltips 
290  *    are displayed, or %NULL
291  * 
292  * Determines the tooltips and the widget they belong to from the window in 
293  * which they are displayed. 
294  *
295  * This function is mostly intended for use by accessibility technologies;
296  * applications should have little use for it.
297  * 
298  * Return value: %TRUE if @tip_window is displaying tooltips, otherwise %FALSE.
299  *
300  * Since: 2.4
301  *
302  * Deprecated: 2.12:
303  **/
304 gboolean
305 gtk_tooltips_get_info_from_tip_window (GtkWindow    *tip_window,
306                                        GtkTooltips **tooltips,
307                                        GtkWidget   **current_widget)
308 {
309   GtkTooltips  *current_tooltips;  
310   gboolean has_tips;
311
312   g_return_val_if_fail (GTK_IS_WINDOW (tip_window), FALSE);
313
314   current_tooltips = g_object_get_data (G_OBJECT (tip_window), tooltips_info_key);
315
316   has_tips = current_tooltips != NULL;
317
318   if (tooltips)
319     *tooltips = current_tooltips;
320   if (current_widget)
321     *current_widget = (has_tips && current_tooltips->active_tips_data) ? current_tooltips->active_tips_data->widget : NULL;
322
323   return has_tips;
324 }
325
326 #define __GTK_TOOLTIPS_C__
327 #include "gtkaliasdef.c"