From 603a41f42439d9a2eb49b7251e2bf4acaa5e8b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erick=20P=C3=A9rez=20Castellanos?= Date: Sun, 26 May 2013 22:46:10 -0400 Subject: [PATCH] Removed internal copy of Notification widget. Use GdNotification --- src/Makefile.am | 5 +- src/gtk-notification.c | 953 ----------------------------------------- src/gtk-notification.h | 65 --- 3 files changed, 1 insertion(+), 1022 deletions(-) delete mode 100644 src/gtk-notification.c delete mode 100644 src/gtk-notification.h diff --git a/src/Makefile.am b/src/Makefile.am index 1f2fc7f2..f0105c61 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -57,10 +57,7 @@ gnome_calendar_SOURCES = \ gcal-manager.c \ gcal-manager.h \ gcal-utils.c \ - gcal-utils.h \ - gtk-notification.c \ - gtk-notification.h - + gcal-utils.h gnome_calendar_LDFLAGS = \ -Wl,--export-dynamic diff --git a/src/gtk-notification.c b/src/gtk-notification.c deleted file mode 100644 index 76e065e8..00000000 --- a/src/gtk-notification.c +++ /dev/null @@ -1,953 +0,0 @@ -/* -*- mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * gtk-notification.c - * Copyright (C) Erick Pérez Castellanos 2011 - * - gtk-notification.c 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 3 of the License, or - * (at your option) any later version. - * - * gtk-notification.c 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 program. If not, see ."; - */ - -#include "gtk-notification.h" - -/** - * SECTION:gtknotification - * @short_description: Report notification messages to the user - * @include: gtk/gtk.h - * @see_also: #GtkStatusbar, #GtkMessageDialog, #GtkInfoBar - * - * #GtkNotification is a widget made for showing notifications to - * the user, allowing them to close the notification or wait for it - * to time out. - * - * #GtkNotification provides one signal (#GtkNotification::dismissed), for when the notification - * times out or is closed. - * - */ - -#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB -#define SHADOW_OFFSET_X 2 -#define SHADOW_OFFSET_Y 3 -#define ANIMATION_TIME 200 /* msec */ -#define ANIMATION_STEP 40 /* msec */ - -enum { - PROP_0, - PROP_TIMEOUT, - PROP_SHOW_CLOSE_BUTTON -}; - -struct _GtkNotificationPrivate { - GtkWidget *close_button; - gboolean show_close_button; - - GdkWindow *bin_window; - - int animate_y; /* from 0 to allocation.height */ - gboolean waiting_for_viewable; - gboolean revealed; - gboolean dismissed; - gboolean sent_dismissed; - guint animate_timeout; - - guint timeout; - guint timeout_source_id; -}; - -enum { - DISMISSED, - LAST_SIGNAL -}; - -static guint notification_signals[LAST_SIGNAL] = { 0 }; - -static gboolean gtk_notification_draw (GtkWidget *widget, - cairo_t *cr); -static void gtk_notification_get_preferred_width (GtkWidget *widget, - gint *minimum_size, - gint *natural_size); -static void gtk_notification_get_preferred_height_for_width (GtkWidget *widget, - gint width, - gint *minimum_height, - gint *natural_height); -static void gtk_notification_get_preferred_height (GtkWidget *widget, - gint *minimum_size, - gint *natural_size); -static void gtk_notification_get_preferred_width_for_height (GtkWidget *widget, - gint height, - gint *minimum_width, - gint *natural_width); -static void gtk_notification_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean gtk_notification_timeout_cb (gpointer user_data); -static void gtk_notification_style_updated (GtkWidget *widget); -static void gtk_notification_show (GtkWidget *widget); -static void gtk_notification_add (GtkContainer *container, - GtkWidget *child); - -/* signals handlers */ -static void gtk_notification_close_button_clicked_cb (GtkWidget *widget, - gpointer user_data); - -G_DEFINE_TYPE(GtkNotification, gtk_notification, GTK_TYPE_BIN); - -static void -gtk_notification_init (GtkNotification *notification) -{ - GtkWidget *close_button_image; - GtkStyleContext *context; - GtkNotificationPrivate *priv; - - context = gtk_widget_get_style_context (GTK_WIDGET (notification)); - gtk_style_context_add_class (context, "app-notification"); - - - gtk_widget_set_halign (GTK_WIDGET (notification), GTK_ALIGN_CENTER); - gtk_widget_set_valign (GTK_WIDGET (notification), GTK_ALIGN_START); - - gtk_widget_set_has_window (GTK_WIDGET (notification), TRUE); - - gtk_widget_push_composite_child (); - - priv = notification->priv = - G_TYPE_INSTANCE_GET_PRIVATE (notification, - GTK_TYPE_NOTIFICATION, - GtkNotificationPrivate); - - priv->animate_y = 0; - priv->close_button = gtk_button_new (); - gtk_widget_set_parent (priv->close_button, GTK_WIDGET (notification)); - gtk_widget_show (priv->close_button); - g_object_set (priv->close_button, - "relief", GTK_RELIEF_NONE, - "focus-on-click", FALSE, - NULL); - g_signal_connect (priv->close_button, - "clicked", - G_CALLBACK (gtk_notification_close_button_clicked_cb), - notification); - close_button_image = gtk_image_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_BUTTON); - gtk_button_set_image (GTK_BUTTON (notification->priv->close_button), close_button_image); - - gtk_widget_pop_composite_child (); - - priv->timeout_source_id = 0; -} - -static void -gtk_notification_finalize (GObject *object) -{ - GtkNotification *notification; - GtkNotificationPrivate *priv; - - g_return_if_fail (GTK_IS_NOTIFICATION (object)); - - notification = GTK_NOTIFICATION (object); - priv = notification->priv; - - if (priv->animate_timeout != 0) - g_source_remove (priv->animate_timeout); - - if (priv->timeout_source_id != 0) - g_source_remove (priv->timeout_source_id); - - G_OBJECT_CLASS (gtk_notification_parent_class)->finalize (object); -} - -static void -gtk_notification_destroy (GtkWidget *widget) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - - if (!priv->sent_dismissed) - { - g_signal_emit (notification, notification_signals[DISMISSED], 0); - priv->sent_dismissed = TRUE; - } - - if (priv->close_button) - { - gtk_widget_unparent (priv->close_button); - priv->close_button = NULL; - } - - GTK_WIDGET_CLASS (gtk_notification_parent_class)->destroy (widget); -} - -static void -gtk_notification_realize (GtkWidget *widget) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - GtkBin *bin = GTK_BIN (widget); - GtkAllocation allocation; - GtkStyleContext *context; - GtkWidget *child; - GdkWindow *window; - GdkWindowAttr attributes; - gint attributes_mask; - - gtk_widget_set_realized (widget, TRUE); - - gtk_widget_get_allocation (widget, &allocation); - - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - - attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - - window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, notification); - - attributes.x = 0; - attributes.y = attributes.height + priv->animate_y; - attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_VISIBILITY_NOTIFY_MASK; - - priv->bin_window = gdk_window_new (window, &attributes, attributes_mask); - gdk_window_set_user_data (priv->bin_window, notification); - - child = gtk_bin_get_child (bin); - if (child) - gtk_widget_set_parent_window (child, priv->bin_window); - gtk_widget_set_parent_window (priv->close_button, priv->bin_window); - - context = gtk_widget_get_style_context (widget); - gtk_style_context_set_background (context, window); - gtk_style_context_set_background (context, priv->bin_window); - - gdk_window_show (priv->bin_window); -} - -static void -gtk_notification_unrealize (GtkWidget *widget) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - - gdk_window_set_user_data (priv->bin_window, NULL); - gdk_window_destroy (priv->bin_window); - priv->bin_window = NULL; - - GTK_WIDGET_CLASS (gtk_notification_parent_class)->unrealize (widget); -} - -static int -animation_target (GtkNotification *notification) -{ - GtkNotificationPrivate *priv = notification->priv; - GtkAllocation allocation; - - if (priv->revealed) { - gtk_widget_get_allocation (GTK_WIDGET (notification), &allocation); - return allocation.height; - } else { - return 0; - } -} - -static gboolean -animation_timeout_cb (gpointer user_data) -{ - GtkNotification *notification = GTK_NOTIFICATION (user_data); - GtkNotificationPrivate *priv = notification->priv; - GtkAllocation allocation; - int target, delta; - - target = animation_target (notification); - - if (priv->animate_y != target) { - gtk_widget_get_allocation (GTK_WIDGET (notification), &allocation); - - delta = allocation.height * ANIMATION_STEP / ANIMATION_TIME; - - if (priv->revealed) - priv->animate_y += delta; - else - priv->animate_y -= delta; - - priv->animate_y = CLAMP (priv->animate_y, 0, allocation.height); - - if (priv->bin_window != NULL) - gdk_window_move (priv->bin_window, - 0, - -allocation.height + priv->animate_y); - return TRUE; - } - - if (priv->dismissed && priv->animate_y == 0) - gtk_widget_destroy (GTK_WIDGET (notification)); - - priv->animate_timeout = 0; - return FALSE; -} - -static void -start_animation (GtkNotification *notification) -{ - GtkNotificationPrivate *priv = notification->priv; - int target; - - if (priv->animate_timeout != 0) - return; /* Already running */ - - target = animation_target (notification); - if (priv->animate_y != target) - notification->priv->animate_timeout = - gdk_threads_add_timeout (ANIMATION_STEP, - animation_timeout_cb, - notification); -} - -static void -gtk_notification_show (GtkWidget *widget) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - - GTK_WIDGET_CLASS (gtk_notification_parent_class)->show (widget); - priv->revealed = TRUE; - 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) -{ - GtkNotification *notification = GTK_NOTIFICATION (object); - - g_return_if_fail (GTK_IS_NOTIFICATION (object)); - - switch (prop_id) { - case PROP_TIMEOUT: - 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; - } -} - -static void -gtk_notification_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - 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; - } -} - -static void -gtk_notification_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - GtkBin *bin = GTK_BIN (container); - GtkNotification *notification = GTK_NOTIFICATION (container); - GtkNotificationPrivate *priv = notification->priv; - GtkWidget *child; - - child = gtk_bin_get_child (bin); - if (child) - (* callback) (child, callback_data); - - if (include_internals) - (* callback) (priv->close_button, callback_data); -} - -static gboolean -gtk_notification_visibility_notify_event (GtkWidget *widget, - GdkEventVisibility *event) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - - if (priv->waiting_for_viewable) - { - start_animation (notification); - priv->waiting_for_viewable = FALSE; - } - - if (notification->priv->timeout_source_id == 0) - notification->priv->timeout_source_id = - gdk_threads_add_timeout (notification->priv->timeout * 1000, - gtk_notification_timeout_cb, - widget); - - return FALSE; -} - -static void -gtk_notification_class_init (GtkNotificationClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); - - object_class->finalize = gtk_notification_finalize; - object_class->set_property = gtk_notification_set_property; - 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; - widget_class->get_preferred_height = gtk_notification_get_preferred_height; - widget_class->get_preferred_width_for_height = gtk_notification_get_preferred_width_for_height; - widget_class->size_allocate = gtk_notification_size_allocate; - widget_class->draw = gtk_notification_draw; - widget_class->realize = gtk_notification_realize; - widget_class->unrealize = gtk_notification_unrealize; - widget_class->style_updated = gtk_notification_style_updated; - widget_class->visibility_notify_event = gtk_notification_visibility_notify_event; - - container_class->add = gtk_notification_add; - container_class->forall = gtk_notification_forall; - gtk_container_class_handle_border_width (container_class); - - - /** - * GtkNotification:timeout: - * - * The time it takes to hide the widget, in seconds. - * - * Since: 0.1 - */ - g_object_class_install_property (object_class, - PROP_TIMEOUT, - g_param_spec_uint("timeout", "timeout", - "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), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkNotificationClass, dismissed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - g_type_class_add_private (object_class, sizeof (GtkNotificationPrivate)); -} - -static void -draw_shadow_box (cairo_t *cr, GdkRectangle rect, int left_border, int right_border, - int bottom_border, double inner_alpha) -{ - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - double x0, x1, x2, x3; - double y0, y2, y3; - - cairo_save (cr); - - x0 = rect.x; - x1 = rect.x + left_border; - x2 = rect.x + rect.width - right_border; - x3 = rect.x + rect.width; - - y0 = rect.y; - y2 = rect.y + rect.height - bottom_border; - y3 = rect.y + rect.height; - - /* Bottom border */ - - pattern = cairo_pattern_create_linear(0, y2, 0, y3); - - cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, inner_alpha); - cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, 0.0); - - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - cairo_rectangle(cr, x1, y2, x2 - x1, y3 - y2); - cairo_fill(cr); - - /* Left border */ - - pattern = cairo_pattern_create_linear(x0, 0, x1, 0); - - cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, 0.0); - cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, inner_alpha); - - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - cairo_rectangle(cr, x0, y0, x1 - x0, y2 - y0); - cairo_fill(cr); - - /* Right border */ - - pattern = cairo_pattern_create_linear(x2, 0, x3, 0); - - cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, inner_alpha); - cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, 0.0); - - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - cairo_rectangle(cr, x2, y0, x3 - x2, y2 - y0); - cairo_fill(cr); - - /* SW corner */ - - pattern = cairo_pattern_create_radial(0, 0, 0, 0.0, 0, 1.0); - cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, inner_alpha); - cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, 0.0); - - cairo_matrix_init_scale (&matrix, 1.0 / left_border, 1.0 / bottom_border); - cairo_matrix_translate (&matrix, - x1, -y2); - cairo_pattern_set_matrix (pattern, &matrix); - - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - cairo_rectangle(cr, x0, y2, x1 - x0, y3 - y2); - cairo_fill(cr); - - /* SE corner */ - - pattern = cairo_pattern_create_radial(0, 0, 0, 0, 0, 1.0); - cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0.0, 0, 0, inner_alpha); - cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0.0, 0, 0, 0.0); - - cairo_matrix_init_scale (&matrix, 1.0 / left_border, 1.0 / bottom_border); - cairo_matrix_translate (&matrix, - x2, -y2); - cairo_pattern_set_matrix (pattern, &matrix); - - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - cairo_rectangle(cr, x2, y2, x3 - x2, y3 - y2); - cairo_fill(cr); - - cairo_restore (cr); -} - -static void -get_padding_and_border (GtkNotification *notification, - GtkBorder *border) -{ - GtkStyleContext *context; - GtkStateFlags state; - GtkBorder tmp; - - context = gtk_widget_get_style_context (GTK_WIDGET (notification)); - state = gtk_widget_get_state_flags (GTK_WIDGET (notification)); - - gtk_style_context_get_padding (context, state, border); - - gtk_style_context_get_border (context, state, &tmp); - border->top += tmp.top; - border->right += tmp.right; - border->bottom += tmp.bottom; - border->left += tmp.left; -} - -static gboolean -gtk_notification_draw (GtkWidget *widget, cairo_t *cr) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - GtkStyleContext *context; - GdkRectangle rect; - int inner_radius; - - if (gtk_cairo_should_draw_window (cr, priv->bin_window)) - { - gtk_widget_get_allocation (widget, &rect); - - context = gtk_widget_get_style_context(widget); - - inner_radius = 5; - draw_shadow_box (cr, rect, SHADOW_OFFSET_X + inner_radius, SHADOW_OFFSET_X + inner_radius, - SHADOW_OFFSET_Y + inner_radius, 0.8); - - gtk_style_context_save (context); - gtk_render_background (context, cr, - SHADOW_OFFSET_X, 0, - gtk_widget_get_allocated_width (widget) - 2 *SHADOW_OFFSET_X, - gtk_widget_get_allocated_height (widget) - SHADOW_OFFSET_Y); - gtk_render_frame (context,cr, - SHADOW_OFFSET_X, 0, - gtk_widget_get_allocated_width (widget) - 2 *SHADOW_OFFSET_X, - gtk_widget_get_allocated_height (widget) - SHADOW_OFFSET_Y); - - gtk_style_context_restore (context); - - if (GTK_WIDGET_CLASS (gtk_notification_parent_class)->draw) - GTK_WIDGET_CLASS (gtk_notification_parent_class)->draw(widget, cr); - } - - return FALSE; -} - -static void -gtk_notification_add (GtkContainer *container, - GtkWidget *child) -{ - GtkBin *bin = GTK_BIN (container); - GtkNotification *notification = GTK_NOTIFICATION (bin); - GtkNotificationPrivate *priv = notification->priv; - - g_return_if_fail (gtk_bin_get_child (bin) == NULL); - - gtk_widget_set_parent_window (child, priv->bin_window); - - GTK_CONTAINER_CLASS (gtk_notification_parent_class)->add (container, child); -} - - -static void -gtk_notification_get_preferred_width (GtkWidget *widget, gint *minimum_size, gint *natural_size) -{ - 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; - - get_padding_and_border (notification, &padding); - - minimum = 0; - natural = 0; - - child = gtk_bin_get_child (bin); - if (child && gtk_widget_get_visible (child)) - { - gtk_widget_get_preferred_width (child, - &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; - - if (minimum_size) - *minimum_size = minimum; - - if (natural_size) - *natural_size = natural; -} - -static void -gtk_notification_get_preferred_width_for_height (GtkWidget *widget, - gint height, - gint *minimum_width, - gint *natural_width) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - GtkBin *bin = GTK_BIN (widget); - gint child_min, child_nat, child_height; - GtkWidget *child; - GtkBorder padding; - gint minimum, natural; - - get_padding_and_border (notification, &padding); - - minimum = 0; - natural = 0; - - child_height = height - SHADOW_OFFSET_Y - padding.top - padding.bottom; - - child = gtk_bin_get_child (bin); - if (child && gtk_widget_get_visible (child)) - { - gtk_widget_get_preferred_width_for_height (child, 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; - - if (minimum_width) - *minimum_width = minimum; - - if (natural_width) - *natural_width = natural; -} - -static void -gtk_notification_get_preferred_height_for_width (GtkWidget *widget, - gint width, - 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, child_width, button_width = 0; - GtkWidget *child; - GtkBorder padding; - gint minimum = 0, natural = 0; - - get_padding_and_border (notification, &padding); - - 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 - button_width - - 2 * SHADOW_OFFSET_X - padding.left - padding.right; - - gtk_widget_get_preferred_height_for_width (child, child_width, - &child_min, &child_nat); - minimum = MAX (minimum, child_min); - natural = MAX (natural, child_nat); - } - - minimum += padding.top + padding.bottom + SHADOW_OFFSET_Y; - natural += padding.top + padding.bottom + SHADOW_OFFSET_Y; - - if (minimum_height) - *minimum_height = minimum; - - if (natural_height) - *natural_height = natural; -} - -static void -gtk_notification_get_preferred_height (GtkWidget *widget, gint *minimum_height, gint *natural_height) -{ - gint width; - - gtk_notification_get_preferred_width (widget, &width, NULL); - gtk_notification_get_preferred_height_for_width (widget, width, - minimum_height, natural_height); -} - -static void -gtk_notification_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - GtkBin *bin = GTK_BIN (widget); - GtkAllocation child_allocation; - GtkBorder padding; - GtkRequisition button_req; - GtkWidget *child; - - gtk_widget_set_allocation (widget, allocation); - - /* If somehow the notification changes while not hidden - and we're not animating, immediately follow the resize */ - if (priv->animate_y > 0 && - !priv->animate_timeout) - priv->animate_y = allocation->height; - - get_padding_and_border (notification, &padding); - - if (gtk_widget_get_realized (widget)) - { - gdk_window_move_resize (gtk_widget_get_window (widget), - allocation->x, - allocation->y, - allocation->width, - allocation->height); - gdk_window_move_resize (priv->bin_window, - 0, - -allocation->height + priv->animate_y, - allocation->width, - allocation->height); - } - - child_allocation.x = SHADOW_OFFSET_X + padding.left; - child_allocation.y = padding.top; - - 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); - - 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); - } -} - -static gboolean -gtk_notification_timeout_cb (gpointer user_data) -{ - GtkNotification *notification = GTK_NOTIFICATION (user_data); - - gtk_notification_dismiss (notification); - - return FALSE; -} - -static void -gtk_notification_style_updated (GtkWidget *widget) -{ - GTK_WIDGET_CLASS (gtk_notification_parent_class)->style_updated (widget); - - if (gtk_widget_get_realized (widget)) - { - GtkStyleContext *context; - GtkNotification *notification = GTK_NOTIFICATION (widget); - GtkNotificationPrivate *priv = notification->priv; - - context = gtk_widget_get_style_context (widget); - gtk_style_context_set_background (context, priv->bin_window); - gtk_style_context_set_background (context, gtk_widget_get_window (widget)); - } -} - -void -gtk_notification_set_timeout (GtkNotification *notification, - guint timeout_msec) -{ - GtkNotificationPrivate *priv = notification->priv; - - priv->timeout = timeout_msec; - 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) -{ - GtkNotificationPrivate *priv = notification->priv; - - if (notification->priv->timeout_source_id) - { - g_source_remove (notification->priv->timeout_source_id); - notification->priv->timeout_source_id = 0; - } - - priv->dismissed = TRUE; - priv->revealed = FALSE; - start_animation (notification); -} - -static void -gtk_notification_close_button_clicked_cb (GtkWidget *widget, gpointer user_data) -{ - GtkNotification *notification = GTK_NOTIFICATION (user_data); - - gtk_notification_dismiss (notification); -} - -GtkWidget * -gtk_notification_new (void) -{ - return g_object_new (GTK_TYPE_NOTIFICATION, NULL); -} diff --git a/src/gtk-notification.h b/src/gtk-notification.h deleted file mode 100644 index bc471ec1..00000000 --- a/src/gtk-notification.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * gtk-notification.c - * Copyright (C) Erick Pérez Castellanos 2011 - * - gtk-notification.c 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 3 of the License, or - * (at your option) any later version. - * - * gtk-notification.c 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 program. If not, see ."; - */ - -#ifndef _GTK_NOTIFICATION_H_ -#define _GTK_NOTIFICATION_H_ - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_NOTIFICATION (gtk_notification_get_type ()) -#define GTK_NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_NOTIFICATION, GtkNotification)) -#define GTK_NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_NOTIFICATION, GtkNotificationClass)) -#define GTK_IS_NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_NOTIFICATION)) -#define GTK_IS_NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_NOTIFICATION)) -#define GTK_NOTIFICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_NOTIFICATION, GtkNotificationClass)) - -typedef struct _GtkNotificationPrivate GtkNotificationPrivate; -typedef struct _GtkNotificationClass GtkNotificationClass; -typedef struct _GtkNotification GtkNotification; - -struct _GtkNotificationClass { - GtkBinClass parent_class; - - /* Signals */ - void (*dismissed) (GtkNotification *self); -}; - -struct _GtkNotification { - GtkBin parent_instance; - - /*< private > */ - GtkNotificationPrivate *priv; -}; - -GType gtk_notification_get_type (void) G_GNUC_CONST; - -GtkWidget *gtk_notification_new (void); -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_ */