Convenience functions



Here's an implementation of the convenience handlers we discussed.
(#56859). While implementing them, I became uncertain whether
most of these changes make sense:

 * gtk_handler_make_widget_[in]sensitive() are just going to
   be very rare functions to use. You use them a total of 3
   times in Beast, in doing fairly exotic things.

 * gtk_handler_hide_toplevel() can almost always be replaced
   with something like 
   g_signal_connect_swapped (button, signal, G_CALLBACK (gtk_widget_hide), window);

 * gtk_window_show_at_idle() is more useful than the previous
   two, but does strike me as failing the test for convenience
   functions of "will people who need it know it exists and use it?"

 * Deprecating gtk_widget_destroyed and adding gtk_handler_nullify_pointer(),
   strikes me as deprecating a commonly used function for no good reason,
   and adding something that isn't much better.

   I'd like to leave gtk_widget_destroyed undeprecated, since it is going
   to work perfectly well for the forseeable future, and add something
   like my second patch - a clear-pointer facility that works 
   whereever g_object_weak_ref does. 

   Suggestions for better names that

      g_object_weak_pointer()
      g_object_weak_pointer_remove() 

   are appreciated. 
    
      g_object_setup_weak_pointer()
      g_object_remove_weak_pointer()
  
   are clearer and nicely verb/noun, but long for a common operation.

So, anyways, for the last one I feel fairly strongly that something in
GObject is better than the gtk_handler_nullify_pointer().

As far as the other three go, I'll leave it to your decision.

I'd prefer not to add make_widget_[in]sensitive - I couldn't even come
up with a decent example for the docs. The other two are I'm
indifferent to:I certainly wouldn't add them based on my own needs,
but they probably don't do active harm.

Regards,
                                        Owen


Index: gtk/Makefile.am
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/Makefile.am,v
retrieving revision 1.176
diff -u -r1.176 Makefile.am
--- gtk/Makefile.am	2001/06/19 12:54:09	1.176
+++ gtk/Makefile.am	2001/07/07 02:56:54
@@ -146,6 +146,7 @@
 	gtkstyle.h		\
 	gtkstatusbar.h		\
 	gtkstock.h		\
+	gtkstockhandlers.h	\
 	gtktable.h		\
 	gtktearoffmenuitem.h    \
 	gtktextbuffer.h		\
@@ -301,6 +302,7 @@
 	gtksizegroup.c		\
 	gtkspinbutton.c		\
 	gtkstock.c		\
+	gtkstockhandlers.c	\
 	gtkstyle.c		\
 	gtkstatusbar.c		\
 	gtktable.c		\
Index: gtk/gtk.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtk.h,v
retrieving revision 1.52
diff -u -r1.52 gtk.h
--- gtk/gtk.h	2001/06/19 12:54:09	1.52
+++ gtk/gtk.h	2001/07/07 02:56:54
@@ -128,6 +128,7 @@
 #include <gtk/gtksocket.h>
 #include <gtk/gtkspinbutton.h>
 #include <gtk/gtkstock.h>
+#include <gtk/gtkstockhandlers.h>
 #include <gtk/gtkstyle.h>
 #include <gtk/gtkstatusbar.h>
 #include <gtk/gtktable.h>
@@ -157,6 +158,7 @@
 #include <gtk/gtkvscale.h>
 #include <gtk/gtkvscrollbar.h>
 #include <gtk/gtkvseparator.h>
+#include <gtk/gtkwidget.h>
 #include <gtk/gtkwidget.h>
 #include <gtk/gtkwindow.h>
 
Index: gtk/gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.168
diff -u -r1.168 gtkmain.c
--- gtk/gtkmain.c	2001/07/03 14:14:28	1.168
+++ gtk/gtkmain.c	2001/07/07 02:56:55
@@ -964,18 +964,6 @@
   g_list_free_1 (tmp_list);
 }
 
-gboolean
-gtk_true (void)
-{
-  return TRUE;
-}
-
-gboolean
-gtk_false (void)
-{
-  return FALSE;
-}
-
 static GtkWindowGroup *
 gtk_main_get_window_group (GtkWidget   *widget)
 {
Index: gtk/gtkmain.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.h,v
retrieving revision 1.39
diff -u -r1.39 gtkmain.h
--- gtk/gtkmain.h	2001/06/14 20:41:43	1.39
+++ gtk/gtkmain.h	2001/07/07 02:56:55
@@ -123,9 +123,6 @@
 /* gtk_main_iteration() calls gtk_main_iteration_do(TRUE) */
 gboolean   gtk_main_iteration_do   (gboolean blocking);
 
-gboolean   gtk_true		   (void) G_GNUC_CONST;
-gboolean   gtk_false		   (void) G_GNUC_CONST;
-
 void	   gtk_grab_add		   (GtkWidget	       *widget);
 GtkWidget* gtk_grab_get_current	   (void);
 void	   gtk_grab_remove	   (GtkWidget	       *widget);
Index: gtk/gtkstockhandlers.c
===================================================================
RCS file: gtkstockhandlers.c
diff -N gtkstockhandlers.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkstockhandlers.c	Fri Jul  6 22:56:55 2001
@@ -0,0 +1,119 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gtkstockhandlers.c: Convenience functions for connecting to signals.
+ * Copyright (C) 2001 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "gtkstockhandlers.h"
+
+gboolean
+gtk_true (void)
+{
+  return TRUE;
+}
+
+gboolean
+gtk_false (void)
+{
+  return FALSE;
+}
+
+/**
+ * gtk_handler_make_widget_sensitive:
+ * @widget: a #GtkWidget
+ * 
+ * Makes @widget sensitive as if gtk_widget_set_sensitive (widget,
+ * %TRUE) were called. This is a convenience handler which can, for
+ * example, be connected to a signal on another object using
+ * g_signal_connect_swapped().  For normal (non-callback) uses, you
+ * should use gtk_widget_set_sensitive().
+ **/
+void
+gtk_handler_make_widget_sensitive (GtkWidget *widget)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  
+  gtk_widget_set_sensitive (widget, TRUE);
+}
+
+/**
+ * gtk_handler_make_widget_insensitive:
+ * @widget: a #GtkWidget
+ * 
+ * Makes @widget insensitive as if gtk_widget_set_sensitive (widget,
+ * %FALSE) were called. This is a convenience handler which can, for
+ * example, be connected to a signal on another object using
+ * g_signal_connect_swapped().  For normal (non-callback) uses, you
+ * should use gtk_widget_set_sensitive().
+ **/
+void
+gtk_handler_make_widget_insensitive (GtkWidget *widget)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  
+  gtk_widget_set_sensitive (widget, FALSE);
+}
+
+/**
+ * gtk_handler_nullify_pointer:
+ * @pointer_loc: address of pointer a variable
+ * 
+ * Sets * pointer_loc to NULL if @pointer_loc != NULL.  It's intended
+ * to be used as a callback connected to the "destroy" signal of a
+ * widget. You connect gtk_widget_destroyed() as a signal handler
+ * using g_signal_connect_swapped(), and pass the address of your
+ * widget variable as the data. Then when the widget is destroyed, the
+ * variable will be set to NULL. Useful for example to avoid multiple
+ * copies of the same dialog.
+ **/
+void
+gtk_handler_nullify_pointer (gpointer *pointer_loc)
+{
+  if (pointer_loc)
+    *pointer_loc = NULL;
+}
+
+/**
+ * gtk_handler_hide_toplevel:
+ * @widget: a #GtkWidget
+ * 
+ * Hides the toplevel that a widget is in. This is a convenience
+ * signal handler and is useful, for example, to connect to the
+ * the "clicked" signal for a close button on a dialog where actions
+ * take place immediately.
+ **/
+void
+gtk_handler_hide_toplevel (GtkWidget *widget)
+{
+  GtkWidget *toplevel;
+  
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  
+  toplevel = gtk_widget_get_toplevel (widget);
+
+  if (GTK_WIDGET_TOPLEVEL (toplevel))
+    gtk_widget_hide (toplevel);
+}
Index: gtk/gtkstockhandlers.h
===================================================================
RCS file: gtkstockhandlers.h
diff -N gtkstockhandlers.h
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkstockhandlers.h	Fri Jul  6 22:56:55 2001
@@ -0,0 +1,49 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gtkstockhandlers.h: Convenience functions for connecting to signals.
+ * Copyright (C) 2001 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __GTK_STOCK_HANDLERS_H__
+#define __GTK_STOCK_HANDLERS_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+gboolean   gtk_true		   (void) G_GNUC_CONST;
+gboolean   gtk_false		   (void) G_GNUC_CONST;
+
+void     gtk_handler_make_widget_sensitive   (GtkWidget *widget);
+void     gtk_handler_make_widget_insensitive (GtkWidget *widget);
+void     gtk_handler_nullify_pointer         (gpointer  *pointer_loc);
+void     gtk_handler_hide_toplevel           (GtkWidget *widget);
+
+
+G_END_DECLS
+
+#endif /* __GTK_STOCK_HANDLERS_H__ */
+
Index: gtk/gtkwidget.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.h,v
retrieving revision 1.116
diff -u -r1.116 gtkwidget.h
--- gtk/gtkwidget.h	2001/07/05 02:58:34	1.116
+++ gtk/gtkwidget.h	2001/07/07 02:56:57
@@ -444,9 +444,9 @@
 GtkWidget* gtk_widget_ref		  (GtkWidget	       *widget);
 void	   gtk_widget_unref		  (GtkWidget	       *widget);
 void	   gtk_widget_destroy		  (GtkWidget	       *widget);
+#ifndef GTK_DISABLE_DEPRECATED
 void	   gtk_widget_destroyed		  (GtkWidget	       *widget,
 					   GtkWidget	      **widget_pointer);
-#ifndef GTK_DISABLE_DEPRECATED
 void	   gtk_widget_set		  (GtkWidget	       *widget,
 					   const gchar         *first_property_name,
 					   ...);
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.134
diff -u -r1.134 gtkwindow.c
--- gtk/gtkwindow.c	2001/07/02 05:03:21	1.134
+++ gtk/gtkwindow.c	2001/07/07 02:56:58
@@ -3974,3 +3974,50 @@
       return default_group;
     }
 }
+
+static gboolean
+show_at_idle_show (gpointer data)
+{
+  gtk_widget_show (data);
+
+  return FALSE;
+}
+
+static void
+show_at_idle_destroyed (GtkWidget *widget,
+			gpointer   data)
+{
+  g_source_destroy (data);
+}
+
+/**
+ * gtk_window_show_at_idle:
+ * @window: a #GtkWindow
+ * 
+ * A convenience function to display @window on the screen
+ * as soon as current operation finish and the application
+ * returns to the main loop. You might use this function
+ * if you were executing a complex sequence of callbacks
+ * to hide one or more windows, and once that was finished,
+ * you wanted to pop up another window. By using
+ * gtk_window_show_at_idle(), instead of gtk_widget_show(),
+ * you don't need to worry about showing the new window
+ * after all other windows are hidden, and still can
+ * be sure that the space being occupied by the old windows
+ * is available for placing the new window.
+ **/
+void
+gtk_window_show_at_idle (GtkWindow *window)
+{
+  GSource *source;
+
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  source = g_idle_source_new ();
+  g_source_attach (source, NULL);
+  g_source_set_callback (source, show_at_idle_show, window, NULL);
+  g_source_unref (source);
+
+  g_signal_connect (G_OBJECT (window), "destroyed",
+		    show_at_idle_destroyed, source);
+}
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/glib/gobject/ChangeLog,v
retrieving revision 1.128
diff -u -r1.128 ChangeLog
--- ChangeLog	2001/07/02 05:15:29	1.128
+++ ChangeLog	2001/07/07 03:11:41
@@ -1,3 +1,9 @@
+Fri Jul  6 23:10:48 2001  Owen Taylor  <otaylor redhat com>
+
+	* gobject.[ch]: Add g_object_weak_pointer(),
+	g_object_remove_weak_pointer(), as a replacement for the
+	old gtk_signal_connect (object, "destroy", gtk_widget_destroyed, &object);
+
 Mon Jul  2 07:17:47 2001  Tim Janik  <timj gtk org>
 
 	* gobject.c (g_object_weak_ref): 
Index: gobject.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.c,v
retrieving revision 1.39
diff -u -r1.39 gobject.c
--- gobject.c	2001/07/02 05:15:29	1.39
+++ gobject.c	2001/07/07 03:11:41
@@ -1262,6 +1262,54 @@
     g_warning (G_STRLOC ": couldn't find weak ref %p(%p)", notify, data);
 }
 
+void 
+weak_pointer_notify (gpointer data)
+{
+  gpointer *location = data;
+  
+  *location = NULL;
+}
+
+/**
+ * g_object_weak_pointer:
+ * @object: a #GObject
+ * @location: a pointer to pointer.
+ * 
+ * Sets up a weak reference so that when @object
+ * is finalized or explicitely destroyed, %NULL is
+ * stored in * location 
+ *
+ * This is typically used to maintain a pointer
+ * to @object that is cleared when @object goes away.
+ **/
+void
+g_object_weak_pointer (GObject  *object,
+		       gpointer *location)
+{
+  g_return_if_fail (G_IS_OBJECT (object));
+  g_return_if_fail (location != NULL);
+
+  g_object_weak_ref (object, weak_pointer_notify, location);
+}
+
+/**
+ * g_object_weak_pointer_remove:
+ * @object: a #GObject
+ * @location: the location passed to a previous call to
+ *            g_object_weak_pointer.
+ * 
+ * Remove a weak reference set up by g_object_weak_pointer().
+ **/
+void
+g_object_weak_pointer_remove (GObject  *object,
+			      gpointer *location)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (location != NULL);
+
+  g_object_weak_unref (object, weak_pointer_notify, location);
+}
+
 gpointer
 g_object_ref (gpointer _object)
 {
Index: gobject.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.h,v
retrieving revision 1.16
diff -u -r1.16 gobject.h
--- gobject.h	2001/07/02 05:02:13	1.16
+++ gobject.h	2001/07/07 03:11:41
@@ -154,6 +154,10 @@
 void	    g_object_weak_unref		      (GObject	      *object,
 					       GWeakNotify     notify,
 					       gpointer	       data);
+void        g_object_weak_pointer             (GObject        *object,
+					       gpointer       *location);
+void        g_object_weak_pointer_remove      (GObject        *object,
+					       gpointer       *location);
 gpointer    g_object_get_qdata                (GObject        *object,
 					       GQuark          quark);
 void        g_object_set_qdata                (GObject        *object,


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