Patch adding gtk_tooltips_set_tip_widget() -- use a widget as tooltip



Please consider the attached patch, which adds a
gtk_tooltips_set_tip_widget() call to the GtkTooltips API.

As the name says, it allows to use a widget as tooltip. This feature
has been lacking for too long, and would be extremely useful for
applets, notification icons and the like.

Regards,
Jean-Yves Lefort

-- 
Jean-Yves Lefort

jylefort brutele be
http://lefort.be.eu.org/
--- gtk/gtktooltips.c.orig	Wed Oct 27 13:26:32 2004
+++ gtk/gtktooltips.c	Wed Oct 27 14:49:51 2004
@@ -51,6 +51,12 @@
 static void gtk_tooltips_init              (GtkTooltips      *tooltips);
 static void gtk_tooltips_destroy           (GtkObject        *object);
 
+static void gtk_tooltips_set_tip_real      (GtkTooltips      *tooltips,
+					    GtkWidget        *widget,
+					    const gchar      *tip_text,
+					    const gchar      *tip_private,
+					    GtkWidget        *tip_widget);
+
 static void gtk_tooltips_event_handler     (GtkWidget   *widget,
                                             GdkEvent    *event);
 static void gtk_tooltips_widget_unmap      (GtkWidget   *widget,
@@ -70,6 +76,7 @@
 static GtkObjectClass *parent_class;
 static const gchar  *tooltips_data_key = "_GtkTooltipsData";
 static const gchar  *tooltips_info_key = "_GtkTooltipsInfo";
+static const gchar  *tooltips_widget_key = "_GtkTooltipsWidget";
 
 GType
 gtk_tooltips_get_type (void)
@@ -148,6 +155,7 @@
 					tooltipsdata);
 
   g_object_set_data (G_OBJECT (tooltipsdata->widget), tooltips_data_key, NULL);
+  g_object_set_data (G_OBJECT (tooltipsdata->widget), tooltips_widget_key, NULL);
   g_object_unref (tooltipsdata->widget);
   g_free (tooltipsdata);
 }
@@ -177,6 +185,8 @@
       
       gtk_widget_destroy (tooltips->tip_window);
       tooltips->tip_window = NULL;
+
+      g_object_unref (tooltips->tip_label);
     }
 }
 
@@ -250,7 +260,6 @@
       gtk_tooltips_update_screen (tooltips, TRUE);
       gtk_widget_set_app_paintable (tooltips->tip_window, TRUE);
       gtk_window_set_resizable (GTK_WINDOW (tooltips->tip_window), FALSE);
-      gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips");
       gtk_container_set_border_width (GTK_CONTAINER (tooltips->tip_window), 4);
 
       g_signal_connect_swapped (tooltips->tip_window,
@@ -261,10 +270,10 @@
       tooltips->tip_label = gtk_label_new (NULL);
       gtk_label_set_line_wrap (GTK_LABEL (tooltips->tip_label), TRUE);
       gtk_misc_set_alignment (GTK_MISC (tooltips->tip_label), 0.5, 0.5);
-      gtk_widget_show (tooltips->tip_label);
-      
-      gtk_container_add (GTK_CONTAINER (tooltips->tip_window), tooltips->tip_label);
 
+      g_object_ref (tooltips->tip_label);
+      gtk_object_sink (GTK_OBJECT (tooltips->tip_label));
+      
       g_signal_connect (tooltips->tip_window,
 			"destroy",
 			G_CALLBACK (gtk_widget_destroyed),
@@ -307,11 +316,20 @@
   return g_object_get_data (G_OBJECT (widget), tooltips_data_key);
 }
 
-void
-gtk_tooltips_set_tip (GtkTooltips *tooltips,
-		      GtkWidget   *widget,
-		      const gchar *tip_text,
-		      const gchar *tip_private)
+GtkWidget*
+gtk_tooltips_tip_widget_get (GtkWidget *widget)
+{
+  g_return_val_if_fail (widget != NULL, NULL);
+
+  return g_object_get_data (G_OBJECT (widget), tooltips_widget_key);
+}
+
+static void
+gtk_tooltips_set_tip_real (GtkTooltips *tooltips,
+			   GtkWidget   *widget,
+			   const gchar *tip_text,
+			   const gchar *tip_private,
+			   GtkWidget   *tip_widget)
 {
   GtkTooltipsData *tooltipsdata;
 
@@ -320,7 +338,7 @@
 
   tooltipsdata = gtk_tooltips_data_get (widget);
 
-  if (!tip_text)
+  if (! (tip_text || tip_widget))
     {
       if (tooltipsdata)
 	gtk_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata);
@@ -336,6 +354,15 @@
 
       tooltipsdata->tip_text = g_strdup (tip_text);
       tooltipsdata->tip_private = g_strdup (tip_private);
+
+      if (tip_widget)
+	{
+	  g_object_ref (tip_widget);
+	  gtk_object_sink (GTK_OBJECT (tip_widget));
+	  g_object_set_data_full (G_OBJECT (widget), tooltips_widget_key, tip_widget, g_object_unref);
+	}
+      else
+	g_object_set_data (G_OBJECT (widget), tooltips_widget_key, NULL);
       
       gtk_tooltips_draw_tips (tooltips);
     }
@@ -363,6 +390,13 @@
       g_object_set_data (G_OBJECT (widget), tooltips_data_key,
                          tooltipsdata);
 
+      if (tip_widget)
+	{
+	  g_object_ref (tip_widget);
+	  gtk_object_sink (GTK_OBJECT (tip_widget));
+	  g_object_set_data_full (G_OBJECT (widget), tooltips_widget_key, tip_widget, g_object_unref);
+	}
+      
       g_signal_connect (widget, "unmap",
 			G_CALLBACK (gtk_tooltips_widget_unmap),
 			tooltipsdata);
@@ -377,6 +411,29 @@
     }
 }
 
+void
+gtk_tooltips_set_tip (GtkTooltips *tooltips,
+		      GtkWidget   *widget,
+		      const gchar *tip_text,
+		      const gchar *tip_private)
+{
+  g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
+  g_return_if_fail (widget != NULL);
+
+  gtk_tooltips_set_tip_real (tooltips, widget, tip_text, tip_private, NULL);
+}
+
+void
+gtk_tooltips_set_tip_widget (GtkTooltips *tooltips,
+			     GtkWidget   *widget,
+			     GtkWidget   *tip_widget)
+{
+  g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
+  g_return_if_fail (widget != NULL);
+
+  gtk_tooltips_set_tip_real (tooltips, widget, NULL, NULL, tip_widget);
+}
+
 static gint
 gtk_tooltips_paint_window (GtkTooltips *tooltips)
 {
@@ -399,6 +456,8 @@
   GtkStyle *style;
   gint x, y, w, h;
   GtkTooltipsData *data;
+  GtkWidget *tip_widget;
+  GtkWidget *child;
   gboolean keyboard_mode;
   GdkScreen *screen;
   GdkScreen *pointer_screen;
@@ -424,9 +483,24 @@
   screen = gtk_widget_get_screen (widget);
 
   data = tooltips->active_tips_data;
+  tip_widget = gtk_tooltips_tip_widget_get (data->widget);
 
-  gtk_label_set_text (GTK_LABEL (tooltips->tip_label), data->tip_text);
+  if (tip_widget)
+    gtk_widget_set_name (tooltips->tip_window, "gtk-custom-tooltips");
+  else
+    {
+      gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips");
+      gtk_label_set_text (GTK_LABEL (tooltips->tip_label), data->tip_text);
+      tip_widget = tooltips->tip_label;
+    }
 
+  child = GTK_BIN (tooltips->tip_window)->child;
+  if (child)
+    gtk_container_remove (GTK_CONTAINER (tooltips->tip_window), child);
+
+  gtk_container_add (GTK_CONTAINER (tooltips->tip_window), tip_widget);
+  gtk_widget_show (tip_widget);
+  
   gtk_widget_size_request (tooltips->tip_window, &requisition);
   w = requisition.width;
   h = requisition.height;
--- gtk/gtktooltips.h.orig	Wed Oct 27 13:26:39 2004
+++ gtk/gtktooltips.h	Wed Oct 27 13:56:05 2004
@@ -97,7 +97,11 @@
 					    GtkWidget	  *widget,
 					    const gchar   *tip_text,
 					    const gchar   *tip_private);
+void             gtk_tooltips_set_tip_widget (GtkTooltips *tooltips,
+					      GtkWidget   *widget,
+					      GtkWidget   *tip_widget);
 GtkTooltipsData* gtk_tooltips_data_get	   (GtkWidget	  *widget);
+GtkWidget*       gtk_tooltips_tip_widget_get (GtkWidget   *widget);
 void             gtk_tooltips_force_window (GtkTooltips   *tooltips);
 
 

Attachment: pgpkHiOMZWEU0.pgp
Description: PGP signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]