summaryrefslogtreecommitdiff
path: root/gtk/gtkmessagedialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkmessagedialog.c')
-rw-r--r--gtk/gtkmessagedialog.c256
1 files changed, 151 insertions, 105 deletions
diff --git a/gtk/gtkmessagedialog.c b/gtk/gtkmessagedialog.c
index 284c01862b..9261b49980 100644
--- a/gtk/gtkmessagedialog.c
+++ b/gtk/gtkmessagedialog.c
@@ -100,29 +100,33 @@
struct _GtkMessageDialogPrivate
{
- GtkWidget *label;
- GtkWidget *secondary_label;
- GtkWidget *image;
- GtkWidget *message_area;
- guint message_type : 3;
- guint buttons_type : 3;
- guint has_primary_markup : 1;
- guint has_secondary_text : 1;
+ 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;
};
-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 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);
+
enum {
PROP_0,
@@ -136,45 +140,46 @@ enum {
PROP_MESSAGE_AREA
};
-G_DEFINE_TYPE (GtkMessageDialog, gtk_message_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE_WITH_CODE (GtkMessageDialog, gtk_message_dialog, GTK_TYPE_DIALOG,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ gtk_message_dialog_buildable_interface_init))
+
+static GtkBuildableIface *parent_buildable_iface;
static void
-gtk_message_dialog_style_updated (GtkWidget *widget)
+gtk_message_dialog_buildable_interface_init (GtkBuildableIface *iface)
{
- GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (widget);
- GtkWidget *parent;
- gint border_width;
-
- parent = gtk_widget_get_parent (gtk_message_dialog_get_image (dialog));
-
- if (parent)
- {
- gtk_widget_style_get (widget, "message-border",
- &border_width, NULL);
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+ iface->get_internal_child = gtk_message_dialog_buildable_get_internal_child;
+ iface->custom_tag_start = parent_buildable_iface->custom_tag_start;
+ iface->custom_finished = parent_buildable_iface->custom_finished;
+}
- gtk_container_set_border_width (GTK_CONTAINER (parent),
- MAX (0, border_width - 7));
- }
+static GObject *
+gtk_message_dialog_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname)
+{
+ if (strcmp (childname, "message_area") == 0)
+ return G_OBJECT (gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (buildable)));
- GTK_WIDGET_CLASS (gtk_message_dialog_parent_class)->style_updated (widget);
+ return parent_buildable_iface->get_internal_child (buildable, builder, childname);
}
+
static void
gtk_message_dialog_class_init (GtkMessageDialogClass *class)
{
- GtkContainerClass *container_class;
GtkWidgetClass *widget_class;
GObjectClass *gobject_class;
- gobject_class = G_OBJECT_CLASS (class);
widget_class = GTK_WIDGET_CLASS (class);
- container_class = GTK_CONTAINER_CLASS (class);
-
+ gobject_class = G_OBJECT_CLASS (class);
+
widget_class->style_updated = gtk_message_dialog_style_updated;
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;
@@ -201,7 +206,7 @@ gtk_message_dialog_class_init (GtkMessageDialogClass *class)
P_("The type of message"),
GTK_TYPE_MESSAGE_TYPE,
GTK_MESSAGE_INFO,
- GTK_PARAM_READWRITE));
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_BUTTONS,
g_param_spec_enum ("buttons",
@@ -289,28 +294,32 @@ gtk_message_dialog_class_init (GtkMessageDialogClass *class)
GTK_TYPE_WIDGET,
GTK_PARAM_READWRITE));
- g_type_class_add_private (gobject_class, sizeof (GtkMessageDialogPrivate));
+ /**
+ * GtkMessageDialog:message-area:
+ *
+ * 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: 2.22
+ */
+ 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));
- gtk_container_class_set_template_from_resource (container_class,
- "/org/gtk/libgtk/gtkmessagedialog.ui");
-
- gtk_container_class_declare_internal_child (container_class, TRUE,
- G_STRUCT_OFFSET (GtkMessageDialogPrivate, label),
- "label");
- gtk_container_class_declare_internal_child (container_class, TRUE,
- G_STRUCT_OFFSET (GtkMessageDialogPrivate, secondary_label),
- "secondary_label");
- gtk_container_class_declare_internal_child (container_class, TRUE,
- G_STRUCT_OFFSET (GtkMessageDialogPrivate, image),
- "image");
- gtk_container_class_declare_internal_child (container_class, TRUE,
- G_STRUCT_OFFSET (GtkMessageDialogPrivate, message_area),
- "action_area");
+ g_type_class_add_private (gobject_class, sizeof (GtkMessageDialogPrivate));
}
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,
@@ -318,14 +327,64 @@ 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
@@ -413,30 +472,6 @@ 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 = dialog->priv;
-
- /* 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,
@@ -449,17 +484,10 @@ gtk_message_dialog_set_property (GObject *object,
switch (prop_id)
{
case PROP_MESSAGE_TYPE:
-
- if (priv->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);
-
+ setup_type (dialog, g_value_get_enum (value));
break;
-
case PROP_BUTTONS:
- priv->buttons_type = g_value_get_enum (value);
+ gtk_message_dialog_add_buttons (dialog, g_value_get_enum (value));
break;
case PROP_TEXT:
if (priv->has_primary_markup)
@@ -504,6 +532,7 @@ gtk_message_dialog_set_property (GObject *object,
case PROP_IMAGE:
gtk_message_dialog_set_image (dialog, g_value_get_object (value));
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -547,6 +576,9 @@ gtk_message_dialog_get_property (GObject *object,
case PROP_IMAGE:
g_value_set_object (value, priv->image);
break;
+ case PROP_MESSAGE_AREA:
+ g_value_set_object (value, priv->message_area);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -713,19 +745,12 @@ gtk_message_dialog_set_image (GtkMessageDialog *dialog,
gtk_widget_set_valign (image, GTK_ALIGN_START);
}
- /* 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 (priv->image && priv->image != image)
- {
- 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);
- }
+ 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);
priv->image = image;
@@ -969,3 +994,24 @@ gtk_message_dialog_add_buttons (GtkMessageDialog* message_dialog,
g_object_notify (G_OBJECT (message_dialog), "buttons");
}
+
+static void
+gtk_message_dialog_style_updated (GtkWidget *widget)
+{
+ GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (widget);
+ GtkWidget *parent;
+ gint border_width;
+
+ parent = gtk_widget_get_parent (gtk_message_dialog_get_image (dialog));
+
+ if (parent)
+ {
+ gtk_widget_style_get (widget, "message-border",
+ &border_width, NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (parent),
+ MAX (0, border_width - 7));
+ }
+
+ GTK_WIDGET_CLASS (gtk_message_dialog_parent_class)->style_updated (widget);
+}