diff --git a/src/gtk-notification.c b/src/gtk-notification.c index a88fd70d..3ea9f27f 100644 --- a/src/gtk-notification.c +++ b/src/gtk-notification.c @@ -42,11 +42,13 @@ enum { PROP_0, - PROP_TIMEOUT + PROP_TIMEOUT, + PROP_SHOW_CLOSE_BUTTON }; struct _GtkNotificationPrivate { GtkWidget *close_button; + gboolean show_close_button; GdkWindow *bin_window; @@ -106,7 +108,7 @@ gtk_notification_init (GtkNotification *notification) GtkNotificationPrivate *priv; context = gtk_widget_get_style_context (GTK_WIDGET (notification)); - gtk_style_context_add_class (context, "contacts-notification"); + gtk_style_context_add_class (context, "app-notification"); gtk_widget_set_halign (GTK_WIDGET (notification), GTK_ALIGN_CENTER); @@ -326,6 +328,17 @@ gtk_notification_show (GtkWidget *widget) priv->waiting_for_viewable = TRUE; } +static void +gtk_notification_hide (GtkWidget *widget) +{ + GtkNotification *notification = GTK_NOTIFICATION (widget); + GtkNotificationPrivate *priv = notification->priv; + + GTK_WIDGET_CLASS (gtk_notification_parent_class)->hide (widget); + priv->revealed = FALSE; + priv->waiting_for_viewable = FALSE; +} + static void gtk_notification_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -338,6 +351,10 @@ gtk_notification_set_property (GObject *object, guint prop_id, const GValue *val gtk_notification_set_timeout (notification, g_value_get_uint (value)); break; + case PROP_SHOW_CLOSE_BUTTON: + gtk_notification_set_show_close_button (notification, + g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -347,15 +364,16 @@ gtk_notification_set_property (GObject *object, guint prop_id, const GValue *val static void gtk_notification_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - GtkNotification *notification; - - g_return_if_fail (GTK_IS_NOTIFICATION (object)); - notification = GTK_NOTIFICATION (object); + GtkNotification *notification = GTK_NOTIFICATION (object); switch (prop_id) { case PROP_TIMEOUT: g_value_set_uint (value, notification->priv->timeout); break; + case PROP_SHOW_CLOSE_BUTTON: + g_value_set_boolean (value, + notification->priv->show_close_button); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -415,6 +433,7 @@ gtk_notification_class_init (GtkNotificationClass *klass) object_class->get_property = gtk_notification_get_property; widget_class->show = gtk_notification_show; + widget_class->hide = gtk_notification_hide; widget_class->destroy = gtk_notification_destroy; widget_class->get_preferred_width = gtk_notification_get_preferred_width; widget_class->get_preferred_height_for_width = gtk_notification_get_preferred_height_for_width; @@ -445,6 +464,12 @@ gtk_notification_class_init (GtkNotificationClass *klass) "The time it takes to hide the widget, in seconds", 0, G_MAXUINT, 10, GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_SHOW_CLOSE_BUTTON, + g_param_spec_boolean("show-close-button", "show-close-button", + "Whether to show a stock close button that dismisses the notification", + TRUE, + GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT)); notification_signals[DISMISSED] = g_signal_new ("dismissed", G_OBJECT_CLASS_TYPE (klass), @@ -652,11 +677,13 @@ gtk_notification_get_preferred_width (GtkWidget *widget, gint *minimum_size, gin natural += child_nat; } - gtk_widget_get_preferred_width (priv->close_button, - &child_min, &child_nat); - minimum += child_min; - natural += child_nat; - + if (priv->show_close_button) + { + gtk_widget_get_preferred_width (priv->close_button, + &child_min, &child_nat); + minimum += child_min; + natural += child_nat; + } minimum += padding.left + padding.right + 2 * SHADOW_OFFSET_X; natural += padding.left + padding.right + 2 * SHADOW_OFFSET_X; @@ -698,10 +725,13 @@ gtk_notification_get_preferred_width_for_height (GtkWidget *widget, natural += child_nat; } - gtk_widget_get_preferred_width_for_height (priv->close_button, child_height, - &child_min, &child_nat); - minimum += child_min; - natural += child_nat; + if (priv->show_close_button) + { + gtk_widget_get_preferred_width_for_height (priv->close_button, child_height, + &child_min, &child_nat); + minimum += child_min; + natural += child_nat; + } minimum += padding.left + padding.right + 2 * SHADOW_OFFSET_X; natural += padding.left + padding.right + 2 * SHADOW_OFFSET_X; @@ -722,22 +752,26 @@ gtk_notification_get_preferred_height_for_width (GtkWidget *widget, GtkNotification *notification = GTK_NOTIFICATION (widget); GtkNotificationPrivate *priv = notification->priv; GtkBin *bin = GTK_BIN (widget); - gint child_min, child_nat, child_width, button_width; + gint child_min, child_nat, child_width, button_width = 0; GtkWidget *child; GtkBorder padding; - gint minimum, natural; + gint minimum = 0, natural = 0; get_padding_and_border (notification, &padding); - gtk_widget_get_preferred_height (priv->close_button, - &minimum, &natural); - gtk_widget_get_preferred_width (priv->close_button, - NULL, &button_width); + if (priv->show_close_button) + { + gtk_widget_get_preferred_height (priv->close_button, + &minimum, &natural); + gtk_widget_get_preferred_width (priv->close_button, + NULL, &button_width); + } child = gtk_bin_get_child (bin); if (child && gtk_widget_get_visible (child)) { - child_width = width - 2 * SHADOW_OFFSET_X - padding.left - padding.top - button_width; + child_width = width - button_width - + 2 * SHADOW_OFFSET_X - padding.left - padding.right; gtk_widget_get_preferred_height_for_width (child, child_width, &child_min, &child_nat); @@ -745,8 +779,8 @@ gtk_notification_get_preferred_height_for_width (GtkWidget *widget, natural = MAX (natural, child_nat); } - minimum += padding.top + padding.top + SHADOW_OFFSET_Y; - natural += padding.top + padding.top + SHADOW_OFFSET_Y; + minimum += padding.top + padding.bottom + SHADOW_OFFSET_Y; + natural += padding.top + padding.bottom + SHADOW_OFFSET_Y; if (minimum_height) *minimum_height = minimum; @@ -758,36 +792,11 @@ gtk_notification_get_preferred_height_for_width (GtkWidget *widget, static void gtk_notification_get_preferred_height (GtkWidget *widget, gint *minimum_height, gint *natural_height) { - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - GtkBin *bin = GTK_BIN (widget); - gint child_min, child_nat; - GtkWidget *child; - GtkBorder padding; - gint minimum, natural; + gint width; - get_padding_and_border (notification, &padding); - - gtk_widget_get_preferred_height (priv->close_button, - &minimum, &natural); - - child = gtk_bin_get_child (bin); - if (child && gtk_widget_get_visible (child)) - { - gtk_widget_get_preferred_height (child, - &child_min, &child_nat); - minimum = MAX (minimum, child_min); - natural = MAX (natural, child_nat); - } - - minimum += padding.top + padding.top + SHADOW_OFFSET_Y; - natural += padding.top + padding.top + SHADOW_OFFSET_Y; - - if (minimum_height) - *minimum_height = minimum; - - if (natural_height) - *natural_height = natural; + gtk_notification_get_preferred_width (widget, &width, NULL); + gtk_notification_get_preferred_height_for_width (widget, width, + minimum_height, natural_height); } static void @@ -799,8 +808,8 @@ gtk_notification_size_allocate (GtkWidget *widget, GtkBin *bin = GTK_BIN (widget); GtkAllocation child_allocation; GtkBorder padding; + GtkRequisition button_req; GtkWidget *child; - int button_width; gtk_widget_set_allocation (widget, allocation); @@ -828,20 +837,29 @@ gtk_notification_size_allocate (GtkWidget *widget, child_allocation.x = SHADOW_OFFSET_X + padding.left; child_allocation.y = padding.top; - child_allocation.height = MAX (1, allocation->height - SHADOW_OFFSET_Y - padding.top - padding.bottom); - gtk_widget_get_preferred_width_for_height (priv->close_button, child_allocation.height, - NULL, &button_width); - child_allocation.width = MAX (1, allocation->width - 2 * SHADOW_OFFSET_X - padding.left - padding.right - button_width); + if (priv->show_close_button) + gtk_widget_get_preferred_size (priv->close_button, &button_req, NULL); + else + button_req.width = button_req.height = 0; + + child_allocation.height = MAX (1, allocation->height - SHADOW_OFFSET_Y - padding.top - padding.bottom); + child_allocation.width = MAX (1, (allocation->width - button_req.width - + 2 * SHADOW_OFFSET_X - padding.left - padding.right)); child = gtk_bin_get_child (bin); if (child && gtk_widget_get_visible (child)) gtk_widget_size_allocate (child, &child_allocation); - child_allocation.x += child_allocation.width; - child_allocation.width = button_width; + if (priv->show_close_button) + { + child_allocation.x += child_allocation.width; + child_allocation.width = button_req.width; + child_allocation.y += (child_allocation.height - button_req.height) / 2; + child_allocation.height = button_req.height; - gtk_widget_size_allocate (priv->close_button, &child_allocation); + gtk_widget_size_allocate (priv->close_button, &child_allocation); + } } static gboolean @@ -881,6 +899,29 @@ gtk_notification_set_timeout (GtkNotification *notification, g_object_notify (G_OBJECT (notification), "timeout"); } +void +gtk_notification_set_show_close_button (GtkNotification *notification, + gboolean show_close_button) +{ + GtkNotificationPrivate *priv = notification->priv; + + if (show_close_button != priv->show_close_button) + { + priv->show_close_button = show_close_button; + + gtk_widget_set_visible (priv->close_button, show_close_button); + gtk_widget_queue_resize (GTK_WIDGET (notification)); + + g_object_notify (G_OBJECT (notification), "show-close-button"); + } +} + +gboolean +gtk_notification_get_show_close_button (GtkNotification *notification) +{ + return notification->priv->show_close_button; +} + void gtk_notification_dismiss (GtkNotification *notification) { @@ -900,7 +941,7 @@ gtk_notification_dismiss (GtkNotification *notification) static void gtk_notification_close_button_clicked_cb (GtkWidget *widget, gpointer user_data) { - GtkNotification *notification = GTK_NOTIFICATION(user_data); + GtkNotification *notification = GTK_NOTIFICATION (user_data); gtk_notification_dismiss (notification); } diff --git a/src/gtk-notification.h b/src/gtk-notification.h index 67ecc864..6a33354c 100644 --- a/src/gtk-notification.h +++ b/src/gtk-notification.h @@ -56,6 +56,10 @@ void gtk_notification_set_timeout (GtkNotification *notification, guint timeout_msec); void gtk_notification_dismiss (GtkNotification *notification); +gboolean gtk_notification_get_show_close_button (GtkNotification *notification); +void gtk_notification_set_show_close_button (GtkNotification *notification, + gboolean show_close_button); + G_END_DECLS #endif /* _GTK_NOTIFICATION_H_ */