[gtk+/composite-templates: 3/18] Made GtkDialog and GtkMessageDialog composite widgets using gtk_container_class_set_template().
- From: Juan Pablo Ugarte <jpu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/composite-templates: 3/18] Made GtkDialog and GtkMessageDialog composite widgets using gtk_container_class_set_template().
- Date: Tue, 31 Jul 2012 12:13:47 +0000 (UTC)
commit 92616286568000ba100344af3adf63b2e6c8e14a
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Mon Jun 7 14:44:17 2010 -0400
Made GtkDialog and GtkMessageDialog composite widgets using gtk_container_class_set_template().
gtk/gtkdialog.c | 172 +++++++++++++++++++++++-----
gtk/gtkmessagedialog.c | 291 ++++++++++++++++++++++++++++++------------------
2 files changed, 327 insertions(+), 136 deletions(-)
---
diff --git a/gtk/gtkdialog.c b/gtk/gtkdialog.c
index b88ca5f..ba888c3 100644
--- a/gtk/gtkdialog.c
+++ b/gtk/gtkdialog.c
@@ -195,9 +195,6 @@ static ResponseData * get_response_data (GtkWidget *widget,
gboolean create);
static void gtk_dialog_buildable_interface_init (GtkBuildableIface *iface);
-static GObject * gtk_dialog_buildable_get_internal_child (GtkBuildable *buildable,
- GtkBuilder *builder,
- const gchar *childname);
static gboolean gtk_dialog_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
@@ -211,9 +208,44 @@ static void gtk_dialog_buildable_custom_finished (GtkBuildable *buildab
gpointer user_data);
+static const gchar *gtk_dialog_template =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<interface>"
+ " <requires lib=\"gtk+\" version=\"2.20\"/>"
+ " <child>"
+ " <object class=\"GtkVBox\" id=\"vbox\">"
+ " <property name=\"visible\">True</property>"
+ " <child>"
+ " <object class=\"GtkHSeparator\" id=\"separator\">"
+ " <property name=\"visible\">True</property>"
+ " </object>"
+ " <packing>"
+ " <property name=\"expand\">False</property>"
+ " <property name=\"pack_type\">end</property>"
+ " <property name=\"position\">1</property>"
+ " </packing>"
+ " </child>"
+ " <child>"
+ " <object class=\"GtkHButtonBox\" id=\"action-area\">"
+ " <property name=\"visible\">True</property>"
+ " <property name=\"layout_style\">end</property>"
+ " </object>"
+ " <packing>"
+ " <property name=\"expand\">False</property>"
+ " <property name=\"pack_type\">end</property>"
+ " <property name=\"position\">0</property>"
+ " </packing>"
+ " </child>"
+ " </object>"
+ " </child>"
+ "</interface>";
+
enum {
PROP_0,
- PROP_HAS_SEPARATOR
+ PROP_HAS_SEPARATOR,
+ PROP_SEPARATOR,
+ PROP_VBOX,
+ PROP_ACTION_AREA
};
enum {
@@ -248,6 +280,51 @@ gtk_dialog_class_init (GtkDialogClass *class)
g_type_class_add_private (gobject_class, sizeof (GtkDialogPrivate));
/**
+ * GtkDialog:separator:
+ *
+ * The separator above the action buttons.
+ *
+ * Since: 3.0
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SEPARATOR,
+ gtk_param_spec_composite ("separator",
+ P_("Separator"),
+ P_("The separator above the action buttons"),
+ GTK_TYPE_SEPARATOR,
+ GTK_PARAM_WRITABLE));
+
+ /**
+ * GtkDialog:vbox:
+ *
+ * The dialog content area.
+ *
+ * Since: 3.0
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_VBOX,
+ gtk_param_spec_composite ("vbox",
+ P_("Content Area"),
+ P_("The dialog content area"),
+ GTK_TYPE_BOX,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * GtkDialog:action-area:
+ *
+ * The dialog action area.
+ *
+ * Since: 3.0
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_ACTION_AREA,
+ gtk_param_spec_composite ("action-area",
+ P_("Action Area"),
+ P_("The dialog action area"),
+ GTK_TYPE_BUTTON_BOX,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /**
* GtkDialog::response:
* @dialog: the object on which the signal is emitted
* @response_id: the response ID
@@ -333,6 +410,8 @@ gtk_dialog_class_init (GtkDialogClass *class)
binding_set = gtk_binding_set_by_class (class);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
+
+ gtk_container_class_set_template (GTK_CONTAINER_CLASS (class), gtk_dialog_template);
}
static void
@@ -384,19 +463,6 @@ gtk_dialog_init (GtkDialog *dialog)
G_CALLBACK (gtk_dialog_delete_event_handler),
NULL);
- priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add (GTK_CONTAINER (dialog), priv->vbox);
- gtk_widget_show (priv->vbox);
-
- priv->action_area = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
-
- gtk_button_box_set_layout (GTK_BUTTON_BOX (priv->action_area),
- GTK_BUTTONBOX_END);
-
- gtk_box_pack_end (GTK_BOX (priv->vbox), priv->action_area,
- FALSE, TRUE, 0);
- gtk_widget_show (priv->action_area);
-
gtk_window_set_type_hint (GTK_WINDOW (dialog),
GDK_WINDOW_TYPE_HINT_DIALOG);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT);
@@ -410,26 +476,72 @@ static void
gtk_dialog_buildable_interface_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
- iface->get_internal_child = gtk_dialog_buildable_get_internal_child;
iface->custom_tag_start = gtk_dialog_buildable_custom_tag_start;
iface->custom_finished = gtk_dialog_buildable_custom_finished;
}
-static GObject *
-gtk_dialog_buildable_get_internal_child (GtkBuildable *buildable,
- GtkBuilder *builder,
- const gchar *childname)
+static void
+gtk_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GtkDialogPrivate *priv = GTK_DIALOG (buildable)->priv;
+ 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;
- if (strcmp (childname, "vbox") == 0)
- return G_OBJECT (priv->vbox);
- else if (strcmp (childname, "action_area") == 0)
- return G_OBJECT (priv->action_area);
+ case PROP_SEPARATOR:
+ dialog->separator = g_value_get_object (value);
+ break;
+
+ case PROP_VBOX:
+ dialog->vbox = g_value_get_object (value);
+ break;
+
+ case PROP_ACTION_AREA:
+ dialog->action_area = g_value_get_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
- return parent_buildable_iface->get_internal_child (buildable,
- builder,
- childname);
+static void
+gtk_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkDialog *dialog;
+
+ dialog = GTK_DIALOG (object);
+
+ switch (prop_id)
+ {
+ case PROP_HAS_SEPARATOR:
+ g_value_set_boolean (value, dialog->separator != NULL);
+ break;
+
+ case PROP_VBOX:
+ g_value_set_object (value, dialog->vbox);
+ break;
+
+ case PROP_ACTION_AREA:
+ g_value_set_object (value, dialog->action_area);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
static gboolean
diff --git a/gtk/gtkmessagedialog.c b/gtk/gtkmessagedialog.c
index 7934280..3b5b60f 100644
--- a/gtk/gtkmessagedialog.c
+++ b/gtk/gtkmessagedialog.c
@@ -100,33 +100,102 @@
struct _GtkMessageDialogPrivate
{
- GtkWidget *image;
- GtkWidget *label;
- GtkWidget *message_area; /* vbox for the primary and secondary labels, and any extra content from the caller */
- GtkWidget *secondary_label;
-
- guint has_primary_markup : 1;
- guint has_secondary_text : 1;
- guint message_type : 3;
+ GtkWidget *secondary_label;
+ guint message_type : 3;
+ guint buttons_type : 3;
+ guint has_primary_markup : 1;
+ guint has_secondary_text : 1;
};
-static void gtk_message_dialog_style_updated (GtkWidget *widget);
-
-static void gtk_message_dialog_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_message_dialog_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void gtk_message_dialog_add_buttons (GtkMessageDialog *message_dialog,
- GtkButtonsType buttons);
-static void gtk_message_dialog_buildable_interface_init (GtkBuildableIface *iface);
-static GObject * gtk_message_dialog_buildable_get_internal_child (GtkBuildable *buildable,
- GtkBuilder *builder,
- const gchar *childname);
-
+static void gtk_message_dialog_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+static GObject *gtk_message_dialog_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params);
+static void gtk_message_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_message_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_message_dialog_add_buttons (GtkMessageDialog *message_dialog,
+ GtkButtonsType buttons);
+
+static const gchar *gtk_message_dialog_template =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<interface>"
+ " <requires lib=\"gtk+\" version=\"2.20\"/>"
+ " <child internal-child=\"vbox\">"
+ " <object class=\"GtkVBox\" id=\"vbox\">"
+ " <property name=\"spacing\">14</property>"
+ " <child>"
+ " <object class=\"GtkHBox\" id=\"hbox1\">"
+ " <property name=\"visible\">True</property>"
+ " <property name=\"border_width\">5</property>"
+ " <property name=\"spacing\">12</property>"
+ " <child>"
+ " <object class=\"GtkImage\" id=\"image\">"
+ " <property name=\"visible\">True</property>"
+ " <property name=\"yalign\">0</property>"
+ " <property name=\"icon-size\">6</property>"
+ " </object>"
+ " <packing>"
+ " <property name=\"expand\">False</property>"
+ " <property name=\"fill\">False</property>"
+ " <property name=\"position\">0</property>"
+ " </packing>"
+ " </child>"
+ " <child>"
+ " <object class=\"GtkVBox\" id=\"vbox1\">"
+ " <property name=\"visible\">True</property>"
+ " <property name=\"spacing\">12</property>"
+ " <child>"
+ " <object class=\"GtkLabel\" id=\"label\">"
+ " <property name=\"visible\">True</property>"
+ " <property name=\"xalign\">0</property>"
+ " <property name=\"yalign\">0</property>"
+ " <property name=\"label\" translatable=\"yes\">primary message</property>"
+ " <property name=\"wrap\">True</property>"
+ " <property name=\"selectable\">True</property>"
+ " </object>"
+ " <packing>"
+ " <property name=\"expand\">False</property>"
+ " <property name=\"fill\">False</property>"
+ " <property name=\"position\">0</property>"
+ " </packing>"
+ " </child>"
+ " <child>"
+ " <object class=\"GtkLabel\" id=\"secondary-label\">"
+ " <property name=\"visible\">False</property>"
+ " <property name=\"no_show_all\">True</property>"
+ " <property name=\"xalign\">0</property>"
+ " <property name=\"yalign\">0</property>"
+ " <property name=\"label\" translatable=\"yes\">secondary message</property>"
+ " <property name=\"wrap\">True</property>"
+ " <property name=\"selectable\">True</property>"
+ " </object>"
+ " <packing>"
+ " <property name=\"position\">1</property>"
+ " </packing>"
+ " </child>"
+ " </object>"
+ " <packing>"
+ " <property name=\"position\">1</property>"
+ " </packing>"
+ " </child>"
+ " </object>"
+ " </child>"
+ " </object>"
+ " </child>"
+ " <child internal-child=\"action-area\">"
+ " <object class=\"GtkHButtonBox\" id=\"action-area\">"
+ " <property name=\"border_width\">5</property>"
+ " <property name=\"spacing\">6</property>"
+ " </object>"
+ " </child>"
+ "</interface>";
enum {
PROP_0,
@@ -137,7 +206,8 @@ enum {
PROP_SECONDARY_TEXT,
PROP_SECONDARY_USE_MARKUP,
PROP_IMAGE,
- PROP_MESSAGE_AREA
+ PROP_LABEL,
+ PROP_SECONDARY_LABEL
};
G_DEFINE_TYPE_WITH_CODE (GtkMessageDialog, gtk_message_dialog, GTK_TYPE_DIALOG,
@@ -180,6 +250,7 @@ gtk_message_dialog_class_init (GtkMessageDialogClass *class)
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_ALERT);
+ gobject_class->constructor = gtk_message_dialog_constructor;
gobject_class->set_property = gtk_message_dialog_set_property;
gobject_class->get_property = gtk_message_dialog_get_property;
@@ -206,7 +277,7 @@ gtk_message_dialog_class_init (GtkMessageDialogClass *class)
P_("The type of message"),
GTK_TYPE_MESSAGE_TYPE,
GTK_MESSAGE_INFO,
- GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_BUTTONS,
g_param_spec_enum ("buttons",
@@ -288,38 +359,52 @@ gtk_message_dialog_class_init (GtkMessageDialogClass *class)
*/
g_object_class_install_property (gobject_class,
PROP_IMAGE,
- g_param_spec_object ("image",
- P_("Image"),
- P_("The image"),
- GTK_TYPE_WIDGET,
- GTK_PARAM_READWRITE));
+ gtk_param_spec_composite ("image",
+ P_("Image"),
+ P_("The image"),
+ GTK_TYPE_WIDGET,
+ GTK_PARAM_READWRITE));
+
/**
- * GtkMessageDialog:message-area:
+ * GtkMessageDialog:label:
+ *
+ * The message label for this dialog.
*
- * The #GtkVBox that corresponds to the message area of this dialog. See
- * gtk_message_dialog_get_message_area() for a detailed description of this
- * area.
+ * Since: 3.0
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_LABEL,
+ gtk_param_spec_composite ("label",
+ P_("Label"),
+ P_("The label"),
+ GTK_TYPE_LABEL,
+ GTK_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * GtkMessageDialog:secondary-label:
+ *
+ * The secondary message label for this dialog.
*
- * Since: 2.22
+ * Since: 3.0
*/
g_object_class_install_property (gobject_class,
- PROP_MESSAGE_AREA,
- g_param_spec_object ("message-area",
- P_("Message area"),
- P_("GtkVBox that holds the dialog's primary and secondary labels"),
- GTK_TYPE_WIDGET,
- GTK_PARAM_READABLE));
-
- g_type_class_add_private (gobject_class, sizeof (GtkMessageDialogPrivate));
+ PROP_SECONDARY_LABEL,
+ gtk_param_spec_composite ("secondary-label",
+ P_("Secondary Label"),
+ P_("The secondary message label"),
+ GTK_TYPE_LABEL,
+ GTK_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (gobject_class,
+ sizeof (GtkMessageDialogPrivate));
+
+ gtk_container_class_set_template (GTK_CONTAINER_CLASS (class), gtk_message_dialog_template);
}
static void
gtk_message_dialog_init (GtkMessageDialog *dialog)
{
- GtkWidget *hbox;
- GtkDialog *message_dialog = GTK_DIALOG (dialog);
- GtkWidget *action_area, *content_area;
GtkMessageDialogPrivate *priv;
dialog->priv = G_TYPE_INSTANCE_GET_PRIVATE (dialog,
@@ -327,64 +412,14 @@ gtk_message_dialog_init (GtkMessageDialog *dialog)
GtkMessageDialogPrivate);
priv = dialog->priv;
- content_area = gtk_dialog_get_content_area (message_dialog);
- action_area = gtk_dialog_get_action_area (message_dialog);
-
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
gtk_window_set_title (GTK_WINDOW (dialog), "");
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE);
priv->has_primary_markup = FALSE;
priv->has_secondary_text = FALSE;
- priv->secondary_label = gtk_label_new (NULL);
- gtk_widget_set_no_show_all (priv->secondary_label, TRUE);
-
- priv->label = gtk_label_new (NULL);
- priv->image = gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG);
- gtk_widget_set_halign (priv->image, GTK_ALIGN_CENTER);
- gtk_widget_set_valign (priv->image, GTK_ALIGN_START);
-
- gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
- gtk_label_set_selectable (GTK_LABEL (priv->label), TRUE);
- gtk_widget_set_halign (priv->label, GTK_ALIGN_START);
- gtk_widget_set_valign (priv->label, GTK_ALIGN_START);
-
- gtk_label_set_line_wrap (GTK_LABEL (priv->secondary_label), TRUE);
- gtk_label_set_selectable (GTK_LABEL (priv->secondary_label), TRUE);
- gtk_widget_set_halign (priv->secondary_label, GTK_ALIGN_START);
- gtk_widget_set_valign (priv->secondary_label, GTK_ALIGN_START);
-
- gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.0);
- gtk_misc_set_alignment (GTK_MISC (priv->secondary_label), 0.0, 0.0);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
- priv->message_area = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-
- gtk_box_pack_start (GTK_BOX (priv->message_area), priv->label,
- FALSE, FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (priv->message_area), priv->secondary_label,
- TRUE, TRUE, 0);
-
- gtk_box_pack_start (GTK_BOX (hbox), priv->image,
- FALSE, FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (hbox), priv->message_area,
- TRUE, TRUE, 0);
-
- gtk_box_pack_start (GTK_BOX (content_area),
- hbox,
- FALSE, FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
- gtk_box_set_spacing (GTK_BOX (content_area), 14); /* 14 + 2 * 5 = 24 */
- gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
- gtk_box_set_spacing (GTK_BOX (action_area), 6);
-
- gtk_message_dialog_style_updated (GTK_WIDGET (dialog));
-
- gtk_widget_show_all (hbox);
}
static void
@@ -469,6 +504,30 @@ setup_type (GtkMessageDialog *dialog,
}
}
+static GObject *
+gtk_message_dialog_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ GtkMessageDialog *dialog;
+ GtkMessageDialogPrivate *priv;
+
+ object =
+ G_OBJECT_CLASS (gtk_message_dialog_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_params);
+
+ dialog = GTK_MESSAGE_DIALOG (object);
+ priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
+
+ /* Setup widget's now that they've been built */
+ setup_type (dialog, priv->message_type);
+ gtk_message_dialog_add_buttons (dialog, priv->buttons_type);
+
+ return object;
+}
+
static void
gtk_message_dialog_set_property (GObject *object,
guint prop_id,
@@ -481,10 +540,17 @@ gtk_message_dialog_set_property (GObject *object,
switch (prop_id)
{
case PROP_MESSAGE_TYPE:
- setup_type (dialog, g_value_get_enum (value));
+
+ if (dialog->image)
+ setup_type (dialog, g_value_get_enum (value));
+ else
+ /* Deffer assignment at construct time until image is built */
+ priv->message_type = g_value_get_enum (value);
+
break;
+
case PROP_BUTTONS:
- gtk_message_dialog_add_buttons (dialog, g_value_get_enum (value));
+ priv->buttons_type = g_value_get_enum (value);
break;
case PROP_TEXT:
if (priv->has_primary_markup)
@@ -529,6 +595,12 @@ gtk_message_dialog_set_property (GObject *object,
case PROP_IMAGE:
gtk_message_dialog_set_image (dialog, g_value_get_object (value));
break;
+ case PROP_LABEL:
+ dialog->label = g_value_get_object (value);
+ break;
+ case PROP_SECONDARY_LABEL:
+ priv->secondary_label = g_value_get_object (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -742,12 +814,19 @@ gtk_message_dialog_set_image (GtkMessageDialog *dialog,
gtk_widget_set_valign (image, GTK_ALIGN_START);
}
- priv->message_type = GTK_MESSAGE_OTHER;
-
- parent = gtk_widget_get_parent (priv->image);
- gtk_container_add (GTK_CONTAINER (parent), image);
- gtk_container_remove (GTK_CONTAINER (parent), priv->image);
- gtk_box_reorder_child (GTK_BOX (parent), image, 0);
+ /* Only change the message type and the image if
+ * the image is not already in the dialog (which is
+ * the case when GtkBuilder builds the image).
+ */
+ if (dialog->image && dialog->image != image)
+ {
+ priv->message_type = GTK_MESSAGE_OTHER;
+
+ parent = dialog->image->parent;
+ gtk_container_add (GTK_CONTAINER (parent), image);
+ gtk_container_remove (GTK_CONTAINER (parent), dialog->image);
+ gtk_box_reorder_child (GTK_BOX (parent), image, 0);
+ }
priv->image = image;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]