couple dialog tweaks



Hi,

Patch for:
  http://bugzilla.gnome.org/show_bug.cgi?id=50537

jrb suggests Ctrl-w to close the dialog, and
gtk_dialog_set_has_separator() to optionally have/not have a separator
in the dialog. Idea is that you would turn off the separator for
dialogs containing a notebook or frame.

Havoc

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.1777
diff -u -u -r1.1777 ChangeLog
--- ChangeLog	2001/03/05 20:07:07	1.1777
+++ ChangeLog	2001/03/05 21:16:31
@@ -1,3 +1,20 @@
+2001-03-05  Havoc Pennington  <hp redhat com>
+
+	* gtk/gtkdialog.c (gtk_dialog_key_press): support Ctrl-w to close
+	the dialog. This and the existing Esc binding should probably go
+	through the accel system, but that is an orthogonal issue.
+
+	* gtk/testgtk.c (create_dialog): beef up the dialog test slightly
+
+	* gtk/gtkdialog.c (gtk_dialog_set_has_separator): new function
+	(gtk_dialog_get_has_separator): new function
+        (run_delete_handler): fix to not emit "response" signal
+	because we already did in the delete event handler installed
+	at dialog creation time.
+	
+	* gtk/gtkdialog.h: add a has_separator property,
+	add GTK_DIALOG_NO_SEPARATOR flag
+
 Mon Mar  5 15:07:05 2001  Jonathan Blandford  <jrb redhat com>
 
 	* gtk/gtktreeview.c: Apply patch from John Margaglione to add
Index: gtk/gtkdialog.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkdialog.c,v
retrieving revision 1.18
diff -u -u -r1.18 gtkdialog.c
--- gtk/gtkdialog.c	2001/03/05 15:09:02	1.18
+++ gtk/gtkdialog.c	2001/03/05 21:16:31
@@ -32,6 +32,7 @@
 #include "gtksignal.h"
 #include "gdkkeysyms.h"
 #include "gtkmain.h"
+#include "gtkintl.h"
 
 static void gtk_dialog_class_init (GtkDialogClass *klass);
 static void gtk_dialog_init       (GtkDialog      *dialog);
@@ -46,8 +47,23 @@
                                              GdkEventAny *event,
                                              gpointer     user_data);
 
+static void gtk_dialog_set_property      (GObject          *object,
+                                          guint             prop_id,
+                                          const GValue     *value,
+                                          GParamSpec       *pspec,
+                                          const gchar      *trailer);
+static void gtk_dialog_get_property      (GObject          *object,
+                                          guint             prop_id,
+                                          GValue           *value,
+                                          GParamSpec       *pspec,
+                                          const gchar      *trailer);
 
 enum {
+  PROP_0,
+  PROP_HAS_SEPARATOR
+};
+
+enum {
   RESPONSE,
   LAST_SIGNAL
 };
@@ -83,16 +99,29 @@
 static void
 gtk_dialog_class_init (GtkDialogClass *class)
 {
+  GObjectClass *gobject_class;
   GtkObjectClass *object_class;
   GtkWidgetClass *widget_class;
-  
-  object_class = (GtkObjectClass*) class;
-  widget_class = (GtkWidgetClass*) class;
+
+  gobject_class = G_OBJECT_CLASS (class);
+  object_class = GTK_OBJECT_CLASS (class);
+  widget_class = GTK_WIDGET_CLASS (class);
 
   parent_class = g_type_class_peek_parent (class);
+
+  gobject_class->set_property = gtk_dialog_set_property;
+  gobject_class->get_property = gtk_dialog_get_property;
   
   widget_class->key_press_event = gtk_dialog_key_press;
 
+  g_object_class_install_property (gobject_class,
+                                   PROP_HAS_SEPARATOR,
+                                   g_param_spec_boolean ("has_separator",
+							 _("Has separator"),
+							 _("The dialog has a separator bar above its buttons"),
+                                                         TRUE,
+                                                         G_PARAM_READWRITE));
+  
   dialog_signals[RESPONSE] =
     gtk_signal_new ("response",
                     GTK_RUN_LAST,
@@ -106,8 +135,6 @@
 static void
 gtk_dialog_init (GtkDialog *dialog)
 {
-  GtkWidget *separator;
-
   /* To avoid breaking old code that prevents destroy on delete event
    * by connecting a handler, we have to have the FIRST signal
    * connection on the dialog.
@@ -136,14 +163,61 @@
                     FALSE, TRUE, 0);
   gtk_widget_show (dialog->action_area);
 
-  separator = gtk_hseparator_new ();
-  gtk_box_pack_end (GTK_BOX (dialog->vbox), separator, FALSE, TRUE, 0);
-  gtk_widget_show (separator);
+  dialog->separator = gtk_hseparator_new ();
+  gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->separator, FALSE, TRUE, 0);
+  gtk_widget_show (dialog->separator);
 
   gtk_window_set_type_hint (GTK_WINDOW (dialog),
 			    GDK_WINDOW_TYPE_HINT_DIALOG);
 }
 
+
+static void 
+gtk_dialog_set_property (GObject      *object,
+                         guint         prop_id,
+                         const GValue *value,
+                         GParamSpec   *pspec,
+                         const gchar  *trailer)
+{
+  GtkDialog *dialog;
+  
+  dialog = GTK_DIALOG (object);
+  
+  switch (prop_id)
+    {
+    case PROP_HAS_SEPARATOR:
+      gtk_dialog_set_has_separator (dialog, g_value_get_boolean (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void 
+gtk_dialog_get_property (GObject     *object,
+                         guint        prop_id,
+                         GValue      *value,
+                         GParamSpec  *pspec,
+                         const gchar *trailer)
+{
+  GtkDialog *dialog;
+  
+  dialog = GTK_DIALOG (object);
+  
+  switch (prop_id)
+    {
+    case PROP_HAS_SEPARATOR:
+      g_value_set_boolean (value, dialog->separator != NULL);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
 static gint
 gtk_dialog_delete_event_handler (GtkWidget   *widget,
                                  GdkEventAny *event,
@@ -169,10 +243,11 @@
   if (GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, key))
     return TRUE;
 
-  if (key->keyval != GDK_Escape)
+  if (! ((key->keyval == GDK_Escape) ||
+         (key->keyval == GDK_w && (key->state & GDK_CONTROL_MASK))))
     return FALSE;
 
-  /* Synthesize delete_event on key press. */
+  /* Synthesize delete_event to close dialog. */
   g_object_ref (G_OBJECT (event.window));
   
   gtk_main_do_event ((GdkEvent*)&event);
@@ -209,6 +284,9 @@
   if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
     gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
 
+  if (flags & GTK_DIALOG_NO_SEPARATOR)
+    gtk_dialog_set_has_separator (dialog, FALSE);
+  
   return GTK_WIDGET (dialog);
 }
 
@@ -233,7 +311,7 @@
  * enumeration. If the user clicks one of these dialog buttons,
  * #GtkDialog will emit the "response" signal with the corresponding
  * response ID. If a #GtkDialog receives the "delete_event" signal, it
- * will emit "response" with a response ID of GTK_RESPONSE_NONE.
+ * will emit "response" with a response ID of GTK_RESPONSE_DELETE_EVENT.
  * However, destroying a dialog does not emit the "response" signal;
  * so be careful relying on "response" when using
  * the GTK_DIALOG_DESTROY_WITH_PARENT flag. Buttons are from left to right,
@@ -537,6 +615,43 @@
   g_list_free (children);
 }
 
+void
+gtk_dialog_set_has_separator (GtkDialog *dialog,
+                              gboolean   setting)
+{
+  g_return_if_fail (GTK_IS_DIALOG (dialog));
+
+  /* this might fail if we get called before _init() somehow */
+  g_assert (dialog->vbox != NULL);
+  
+  if (setting && dialog->separator == NULL)
+    {
+      dialog->separator = gtk_hseparator_new ();
+      gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->separator, FALSE, TRUE, 0);
+
+      /* The app programmer could screw this up, but, their own fault.
+       * Moves the separator just above the action area.
+       */
+      gtk_box_reorder_child (GTK_BOX (dialog->vbox), dialog->separator, 1);
+      gtk_widget_show (dialog->separator);
+    }
+  else if (!setting && dialog->separator != NULL)
+    {
+      gtk_widget_destroy (dialog->separator);
+      dialog->separator = NULL;
+    }
+
+  g_object_notify (G_OBJECT (dialog), "has_separator");
+}
+
+gboolean
+gtk_dialog_get_has_separator (GtkDialog *dialog)
+{
+  g_return_val_if_fail (GTK_IS_DIALOG (dialog), FALSE);
+
+  return dialog->separator != NULL;
+}
+
 /**
  * gtk_dialog_response:
  * @dialog: a #GtkDialog
@@ -603,9 +718,6 @@
   RunInfo *ri = data;
     
   shutdown_loop (ri);
-
-  /* emit response signal */
-  gtk_dialog_response (dialog, GTK_RESPONSE_NONE);
   
   return TRUE; /* Do not destroy */
 }
Index: gtk/gtkdialog.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkdialog.h,v
retrieving revision 1.11
diff -u -u -r1.11 gtkdialog.h
--- gtk/gtkdialog.h	2001/01/09 17:45:33	1.11
+++ gtk/gtkdialog.h	2001/03/05 21:16:31
@@ -39,9 +39,9 @@
 /* Parameters for dialog construction */
 typedef enum
 {
-  GTK_DIALOG_MODAL,              /* call gtk_window_set_modal (win, TRUE) */
-  GTK_DIALOG_DESTROY_WITH_PARENT /* call gtk_window_set_destroy_with_parent () */
-
+  GTK_DIALOG_MODAL,               /* call gtk_window_set_modal (win, TRUE) */
+  GTK_DIALOG_DESTROY_WITH_PARENT, /* call gtk_window_set_destroy_with_parent () */
+  GTK_DIALOG_NO_SEPARATOR         /* no separator bar above buttons */
 } GtkDialogFlags;
 
 /* Convenience enum to use for response_id's.  Positive values are
@@ -99,6 +99,9 @@
 
   GtkWidget *vbox;
   GtkWidget *action_area;
+
+  /*< private >*/
+  GtkWidget *separator;
 };
 
 struct _GtkDialogClass
@@ -133,6 +136,10 @@
                                         gboolean   setting);
 void gtk_dialog_set_default_response   (GtkDialog *dialog,
                                         gint       response_id);
+
+void     gtk_dialog_set_has_separator (GtkDialog *dialog,
+                                       gboolean   setting);
+gboolean gtk_dialog_get_has_separator (GtkDialog *dialog);
 
 /* Emit response signal */
 void gtk_dialog_response           (GtkDialog *dialog,
Index: gtk/testgtk.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/testgtk.c,v
retrieving revision 1.222
diff -u -u -r1.222 testgtk.c
--- gtk/testgtk.c	2001/03/02 20:02:17	1.222
+++ gtk/testgtk.c	2001/03/05 21:16:31
@@ -6139,6 +6139,22 @@
     gtk_widget_destroy (*label);
 }
 
+#define RESPONSE_TOGGLE_SEPARATOR 1
+
+static void
+print_response (GtkWidget *dialog,
+                gint       response_id,
+                gpointer   data)
+{
+  g_print ("response signal received (%d)\n", response_id);
+
+  if (response_id == RESPONSE_TOGGLE_SEPARATOR)
+    {
+      gtk_dialog_set_has_separator (GTK_DIALOG (dialog),
+                                    !gtk_dialog_get_has_separator (GTK_DIALOG (dialog)));
+    }
+}
+
 static void
 create_dialog (void)
 {
@@ -6147,15 +6163,24 @@
 
   if (!dialog_window)
     {
+      /* This is a terrible example; it's much simpler to create
+       * dialogs than this. Don't use testgtk for example code,
+       * use gtk-demo ;-)
+       */
+      
       dialog_window = gtk_dialog_new ();
 
+      gtk_signal_connect (GTK_OBJECT (dialog_window),
+                          "response",
+                          GTK_SIGNAL_FUNC (print_response),
+                          NULL);
+      
       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
 			  GTK_SIGNAL_FUNC(gtk_widget_destroyed),
 			  &dialog_window);
 
       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
-      gtk_widget_set_usize (dialog_window, 200, 110);
 
       button = gtk_button_new_with_label ("OK");
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
@@ -6174,6 +6199,15 @@
       gtk_widget_show (button);
 
       label = NULL;
+      
+      button = gtk_button_new_with_label ("Separator");
+
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+
+      gtk_dialog_add_action_widget (GTK_DIALOG (dialog_window),
+                                    button,
+                                    RESPONSE_TOGGLE_SEPARATOR);
+      gtk_widget_show (button);
     }
 
   if (!GTK_WIDGET_VISIBLE (dialog_window))




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