2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006, 2007 Nokia Corporation, all rights reserved.
6 * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * SECTION:hildon-banner
27 * @short_description: A widget used to display timed notifications.
29 * #HildonBanner is a small, pop-up window that can be used to display
30 * a short, timed notification or information to the user. It can
31 * communicate that a task has been finished or that the application
34 * Hildon provides convenient funtions to create and show banners. To
35 * create and show information banners you can use
36 * hildon_banner_show_information(), hildon_banner_show_informationf()
37 * or hildon_banner_show_information_with_markup().
39 * Two more kinds of banners are maintained for backward compatibility
40 * but are no longer recommended in Hildon 2.2. These are the animated
41 * banner (created with hildon_banner_show_animation()) and the
42 * progress banner (created with hildon_banner_show_progress()). See
43 * hildon_gtk_window_set_progress_indicator() for the preferred way of
44 * showing progress notifications in Hildon 2.2.
46 * Information banners dissapear automatically after a certain
47 * period. This is stored in the #HildonBanner:timeout property (in
48 * miliseconds), and can be changed using hildon_banner_set_timeout().
50 * Note that #HildonBanner<!-- -->s should only be used to display
51 * non-critical pieces of information.
59 #include <X11/Xatom.h>
62 #undef HILDON_DISABLE_DEPRECATED
64 #include "hildon-banner.h"
65 #include "hildon-banner-private.h"
66 #include "hildon-defines.h"
68 /* position relative to the screen */
70 #define HILDON_BANNER_WINDOW_X 0
72 #define HILDON_BANNER_WINDOW_Y HILDON_WINDOW_TITLEBAR_HEIGHT
76 #define HILDON_BANNER_PROGRESS_WIDTH 104
78 #define HILDON_BANNER_LABEL_MAX_TIMED \
79 (800 - ((HILDON_MARGIN_TRIPLE) * 2))
81 #define HILDON_BANNER_LABEL_MAX_PROGRESS 375 /*265*/
85 #define HILDON_BANNER_DEFAULT_TIMEOUT 3000
89 #define HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION "indicator_update"
91 /* animation related stuff */
93 #define HILDON_BANNER_ANIMATION_FRAMERATE ((float)1000/150)
95 #define HILDON_BANNER_ANIMATION_TMPL "indicator_update%d"
97 #define HILDON_BANNER_ANIMATION_NFRAMES 8
107 static GtkWidget* global_timed_banner = NULL;
110 hildon_banner_timed_quark (void);
113 hildon_banner_bind_style (HildonBanner *self,
117 hildon_banner_timeout (gpointer data);
120 hildon_banner_clear_timeout (HildonBanner *self);
123 hildon_banner_ensure_timeout (HildonBanner *self);
126 hildon_banner_set_property (GObject *object,
132 hildon_banner_get_property (GObject *object,
138 hildon_banner_destroy (GtkObject *object);
141 hildon_banner_real_get_instance (GObject *window,
145 hildon_banner_constructor (GType type,
146 guint n_construct_params,
147 GObjectConstructParam *construct_params);
150 hildon_banner_finalize (GObject *object);
153 hildon_banner_button_press_event (GtkWidget* widget,
154 GdkEventButton* event);
157 hildon_banner_map_event (GtkWidget *widget,
160 hildon_banner_reset_wrap_state (HildonBanner *banner);
163 force_to_wrap_truncated (HildonBanner *banner);
166 hildon_banner_check_position (GtkWidget *widget);
169 hildon_banner_realize (GtkWidget *widget);
172 hildon_banner_class_init (HildonBannerClass *klass);
175 hildon_banner_init (HildonBanner *self);
178 hildon_banner_ensure_child (HildonBanner *self,
179 GtkWidget *user_widget,
182 const gchar *first_property,
186 hildon_banner_get_instance_for_widget (GtkWidget *widget,
189 G_DEFINE_TYPE (HildonBanner, hildon_banner, GTK_TYPE_WINDOW)
192 hildon_banner_timed_quark (void)
194 static GQuark quark = 0;
196 if (G_UNLIKELY(quark == 0))
197 quark = g_quark_from_static_string ("hildon-banner-timed");
202 /* Set the widget and label name to make the correct rc-style attached into them */
204 hildon_banner_bind_style (HildonBanner *self,
205 const gchar *name_sufix)
207 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
212 name = g_strconcat ("HildonBannerLabel-", name_sufix, NULL);
213 gtk_widget_set_name (priv->label, name);
216 name = g_strconcat ("HildonBanner-", name_sufix, NULL);
217 gtk_widget_set_name (GTK_WIDGET (self), name);
221 /* In timeout function we automatically destroy timed banners */
223 simulate_close (GtkWidget* widget)
225 gboolean result = FALSE;
227 /* If the banner is currently visible (it normally should),
228 we simulate clicking the close button of the window.
229 This allows applications to reuse the banner by prevent
231 if (GTK_WIDGET_DRAWABLE (widget))
233 GdkEvent *event = gdk_event_new (GDK_DELETE);
234 event->any.window = g_object_ref (widget->window);
235 event->any.send_event = FALSE;
236 result = gtk_widget_event (widget, event);
237 gdk_event_free (event);
244 hildon_banner_timeout (gpointer data)
247 gboolean continue_timeout = FALSE;
249 GDK_THREADS_ENTER ();
251 g_assert (HILDON_IS_BANNER (data));
253 widget = GTK_WIDGET (data);
254 g_object_ref (widget);
256 continue_timeout = simulate_close (widget);
258 if (! continue_timeout) {
259 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (data);
260 priv->timeout_id = 0;
261 gtk_widget_destroy (widget);
264 g_object_unref (widget);
266 GDK_THREADS_LEAVE ();
268 return continue_timeout;
272 hildon_banner_clear_timeout (HildonBanner *self)
274 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
277 if (priv->timeout_id != 0) {
278 g_source_remove (priv->timeout_id);
279 priv->timeout_id = 0;
287 hildon_banner_ensure_timeout (HildonBanner *self)
289 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
292 if (priv->timeout_id == 0 && priv->is_timed && priv->timeout > 0)
293 priv->timeout_id = g_timeout_add (priv->timeout,
294 hildon_banner_timeout, self);
298 hildon_banner_set_property (GObject *object,
304 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
310 priv->timeout = g_value_get_uint (value);
314 priv->is_timed = g_value_get_boolean (value);
317 case PROP_PARENT_WINDOW:
318 window = g_value_get_object (value);
320 g_object_remove_weak_pointer(G_OBJECT (priv->parent), (gpointer) &priv->parent);
323 gtk_window_set_transient_for (GTK_WINDOW (object), (GtkWindow *) window);
324 priv->parent = (GtkWindow *) window;
327 gtk_window_set_destroy_with_parent (GTK_WINDOW (object), TRUE);
328 g_object_add_weak_pointer(G_OBJECT (window), (gpointer) &priv->parent);
334 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
340 hildon_banner_get_property (GObject *object,
345 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
351 g_value_set_uint (value, priv->timeout);
355 g_value_set_boolean (value, priv->is_timed);
358 case PROP_PARENT_WINDOW:
359 g_value_set_object (value, gtk_window_get_transient_for (GTK_WINDOW (object)));
363 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
369 hildon_banner_destroy (GtkObject *object)
371 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
375 GObject *parent_window = (GObject *) priv->parent;
377 g_assert (HILDON_IS_BANNER (object));
378 self = HILDON_BANNER (object);
380 /* Drop possible global pointer. That can hold reference to us */
381 if ((gpointer) object == (gpointer) global_timed_banner) {
382 global_timed_banner = NULL;
383 g_object_unref (object);
386 /* Remove the data from parent window for timed banners. Those hold reference */
387 if (priv->is_timed && parent_window != NULL) {
388 g_object_set_qdata (parent_window, hildon_banner_timed_quark (), NULL);
391 (void) hildon_banner_clear_timeout (self);
393 if (GTK_OBJECT_CLASS (hildon_banner_parent_class)->destroy)
394 GTK_OBJECT_CLASS (hildon_banner_parent_class)->destroy (object);
397 /* Search a previous banner instance */
399 hildon_banner_real_get_instance (GObject *window,
403 /* If we have a parent window, the previous instance is stored there */
405 return g_object_get_qdata(window, hildon_banner_timed_quark ());
408 /* System notification instance is stored into global pointer */
409 return (GObject *) global_timed_banner;
412 /* Non-timed banners are normal (non-singleton) objects */
416 /* By overriding constructor we force timed banners to be
417 singletons for each window */
419 hildon_banner_constructor (GType type,
420 guint n_construct_params,
421 GObjectConstructParam *construct_params)
423 GObject *banner, *window = NULL;
424 gboolean timed = FALSE;
427 /* Search banner type information from parameters in order
428 to locate the possible previous banner instance. */
429 for (i = 0; i < n_construct_params; i++)
431 if (strcmp(construct_params[i].pspec->name, "parent-window") == 0)
432 window = g_value_get_object (construct_params[i].value);
433 else if (strcmp(construct_params[i].pspec->name, "is-timed") == 0)
434 timed = g_value_get_boolean (construct_params[i].value);
437 /* Try to get a previous instance if such exists */
438 banner = hildon_banner_real_get_instance (window, timed);
441 /* We have to create a new banner */
442 banner = G_OBJECT_CLASS (hildon_banner_parent_class)->constructor (type, n_construct_params, construct_params);
444 /* Store the newly created singleton instance either into parent
445 window data or into global variables. */
448 g_object_set_qdata_full (G_OBJECT (window), hildon_banner_timed_quark (),
449 g_object_ref (banner), g_object_unref);
451 g_assert (global_timed_banner == NULL);
452 global_timed_banner = g_object_ref (banner);
457 /* FIXME: This is a hack! We have to manually freeze
458 notifications. This is normally done by g_object_init, but we
459 are not going to call that. g_object_newv will otherwise give
460 a critical like this:
462 GLIB CRITICAL ** GLib-GObject - g_object_notify_queue_thaw:
463 assertion `nqueue->freeze_count > 0' failed */
465 g_object_freeze_notify (banner);
466 hildon_banner_reset_wrap_state (HILDON_BANNER (banner));
469 /* We restart possible timeouts for each new timed banner request */
470 if (timed && hildon_banner_clear_timeout (HILDON_BANNER (banner)))
471 hildon_banner_ensure_timeout (HILDON_BANNER(banner));
477 hildon_banner_finalize (GObject *object)
479 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
482 g_object_remove_weak_pointer(G_OBJECT (priv->parent), (gpointer) &priv->parent);
485 G_OBJECT_CLASS (hildon_banner_parent_class)->finalize (object);
489 hildon_banner_button_press_event (GtkWidget* widget,
490 GdkEventButton* event)
492 gboolean result = simulate_close (widget);
495 /* signal emission not stopped - basically behave like
496 * gtk_main_do_event() for a delete event, but just hide the
497 * banner instead of destroying it, as it is already meant to
498 * be destroyed by hildon_banner_timeout() (if it's timed) or
499 * the application (if it's not). */
500 gtk_widget_hide (widget);
506 #if defined(MAEMO_GTK)
508 hildon_banner_map (GtkWidget *widget)
510 if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->map) {
511 /* Make the banner temporary _before_ mapping it, to avoid closing
512 * other temporary windows */
513 gtk_window_set_is_temporary (GTK_WINDOW (widget), TRUE);
515 GTK_WIDGET_CLASS (hildon_banner_parent_class)->map (widget);
517 /* Make the banner non-temporary _after_ mapping it, to avoid
518 * being closed by other non-temporary windows */
519 gtk_window_set_is_temporary (GTK_WINDOW (widget), FALSE);
521 hildon_banner_check_position (widget);
526 /* We start the timer for timed notifications after the window appears on screen */
528 hildon_banner_map_event (GtkWidget *widget,
531 gboolean result = FALSE;
533 if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->map_event)
534 result = GTK_WIDGET_CLASS (hildon_banner_parent_class)->map_event (widget, event);
536 hildon_banner_ensure_timeout (HILDON_BANNER(widget));
542 hildon_banner_reset_wrap_state (HildonBanner *banner)
545 HildonBannerPrivate *priv;
547 priv = HILDON_BANNER_GET_PRIVATE (banner);
550 layout = gtk_label_get_layout (GTK_LABEL (priv->label));
552 pango_layout_set_width (layout, -1);
553 priv->has_been_wrapped = FALSE;
554 priv->has_been_truncated = FALSE;
556 gtk_widget_set_size_request (priv->label, -1, -1);
557 gtk_widget_set_size_request (GTK_WIDGET (banner), -1, -1);
560 /* force to wrap truncated label by setting explicit size request
561 * see N#27000 and G#329646 */
563 force_to_wrap_truncated (HildonBanner *banner)
567 int width_text, width_max;
570 PangoRectangle logical;
571 GtkRequisition requisition;
572 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (banner);
574 g_return_if_fail (priv);
576 label = GTK_LABEL (priv->label);
578 layout = gtk_label_get_layout (label);
580 pango_layout_get_extents (layout, NULL, &logical);
581 width_text = PANGO_PIXELS (logical.width);
583 width_max = priv->is_timed ? HILDON_BANNER_LABEL_MAX_TIMED
584 : HILDON_BANNER_LABEL_MAX_PROGRESS;
586 /* If the width of the label is going to exceed the maximum allowed
587 * width, enforce the maximum allowed width now.
589 if (priv->has_been_wrapped
590 || width_text >= width_max
591 || pango_layout_is_wrapped (layout)) {
592 /* Force wrapping by setting the maximum size */
595 priv->has_been_wrapped = TRUE;
598 /* Make the label update its layout; and update our layout pointer
599 * because the layout will be cleared and refreshed.
601 gtk_widget_set_size_request (GTK_WIDGET (label), width, height);
602 gtk_widget_size_request (GTK_WIDGET (label), &requisition);
604 layout = gtk_label_get_layout (label);
606 /* If the layout has now been wrapped and exceeds 3 lines, we truncate
607 * the rest of the label according to spec.
609 if (priv->has_been_truncated
610 || (pango_layout_is_wrapped (layout)
611 && pango_layout_get_line_count (layout) > 3)) {
614 pango_layout_get_extents (layout, NULL, &logical);
615 lines = pango_layout_get_line_count (layout);
617 /* This calculation assumes that the same font is used
618 * throughout the banner -- this is usually the case on maemo
620 * FIXME: Pango >= 1.20 has pango_layout_set_height().
622 height = (PANGO_PIXELS (logical.height) * 3) / lines + 1;
623 priv->has_been_truncated = TRUE;
626 /* Set the new width/height if applicable */
627 gtk_widget_set_size_request (GTK_WIDGET (label), width, height);
632 hildon_banner_check_position (GtkWidget *widget)
637 gtk_widget_set_size_request (widget, gdk_screen_width (), -1);
639 force_to_wrap_truncated (HILDON_BANNER(widget)); /* see N#27000 and G#329646 */
641 gtk_widget_size_request (widget, &req);
648 x = HILDON_BANNER_WINDOW_X;
650 y = HILDON_BANNER_WINDOW_Y;
652 gtk_window_move (GTK_WINDOW (widget), x, y);
656 hildon_banner_realize (GtkWidget *widget)
660 guint32 portrait = 1;
661 const gchar *notification_type = "_HILDON_NOTIFICATION_TYPE_BANNER";
662 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (widget);
665 /* We let the parent to init widget->window before we need it */
666 if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->realize)
667 GTK_WIDGET_CLASS (hildon_banner_parent_class)->realize (widget);
669 /* We use special hint to turn the banner into information notification. */
670 gdk_window_set_type_hint (widget->window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);
671 gtk_window_set_transient_for (GTK_WINDOW (widget), (GtkWindow *) priv->parent);
673 hildon_banner_check_position (widget);
675 gdkwin = widget->window;
677 /* Set the _HILDON_NOTIFICATION_TYPE property so Matchbox places the window correctly */
678 atom = gdk_atom_intern ("_HILDON_NOTIFICATION_TYPE", FALSE);
679 gdk_property_change (gdkwin, atom, gdk_x11_xatom_to_atom (XA_STRING), 8, GDK_PROP_MODE_REPLACE,
680 (gpointer) notification_type, strlen (notification_type));
682 /* HildonBanner supports portrait mode */
683 atom = gdk_atom_intern ("_HILDON_PORTRAIT_MODE_SUPPORT", FALSE);
684 gdk_property_change (gdkwin, atom, gdk_x11_xatom_to_atom (XA_CARDINAL), 32,
685 GDK_PROP_MODE_REPLACE, (gpointer) &portrait, 1);
689 hildon_banner_class_init (HildonBannerClass *klass)
691 GObjectClass *object_class;
692 GtkWidgetClass *widget_class;
694 object_class = G_OBJECT_CLASS (klass);
695 widget_class = GTK_WIDGET_CLASS (klass);
697 /* Append private structure to class. This is more elegant than
698 on g_new based approach */
699 g_type_class_add_private (klass, sizeof (HildonBannerPrivate));
701 /* Override virtual methods */
702 object_class->constructor = hildon_banner_constructor;
703 object_class->finalize = hildon_banner_finalize;
704 object_class->set_property = hildon_banner_set_property;
705 object_class->get_property = hildon_banner_get_property;
706 GTK_OBJECT_CLASS (klass)->destroy = hildon_banner_destroy;
707 widget_class->map_event = hildon_banner_map_event;
708 widget_class->realize = hildon_banner_realize;
709 widget_class->button_press_event = hildon_banner_button_press_event;
710 #if defined(MAEMO_GTK)
711 widget_class->map = hildon_banner_map;
714 /* Install properties.
715 We need construct properties for singleton purposes */
718 * HildonBanner:parent-window:
720 * The window for which the banner will be singleton.
723 g_object_class_install_property (object_class, PROP_PARENT_WINDOW,
724 g_param_spec_object ("parent-window",
726 "The window for which the banner will be singleton",
727 GTK_TYPE_WINDOW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
730 * HildonBanner:is-timed:
732 * Whether the banner is timed and goes away automatically.
735 g_object_class_install_property (object_class, PROP_IS_TIMED,
736 g_param_spec_boolean ("is-timed",
738 "Whether or not the notification goes away automatically "
739 "after the specified time has passed",
740 FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
743 * HildonBanner:timeout:
745 * The time before making the banner banner go away. This needs
746 * to be adjusted before the banner is mapped to the screen.
749 g_object_class_install_property (object_class, PROP_TIMEOUT,
750 g_param_spec_uint ("timeout",
752 "The time before making the banner banner go away",
755 HILDON_BANNER_DEFAULT_TIMEOUT,
756 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
760 hildon_banner_init (HildonBanner *self)
762 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
767 /* Initialize the common layout inside banner */
768 priv->layout = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
770 priv->label = g_object_new (GTK_TYPE_LABEL, NULL);
771 gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
772 gtk_label_set_line_wrap_mode (GTK_LABEL (priv->label), PANGO_WRAP_WORD_CHAR);
774 gtk_container_set_border_width (GTK_CONTAINER (priv->layout), HILDON_MARGIN_DEFAULT);
775 gtk_container_add (GTK_CONTAINER (self), priv->layout);
776 gtk_box_pack_start (GTK_BOX (priv->layout), priv->label, TRUE, TRUE, 0);
778 gtk_window_set_accept_focus (GTK_WINDOW (self), FALSE);
780 hildon_banner_reset_wrap_state (self);
782 gtk_widget_add_events (GTK_WIDGET (self), GDK_BUTTON_PRESS_MASK);
785 /* Makes sure that icon/progress item contains the desired type
786 of item. If possible, tries to avoid creating a new widget but
787 reuses the existing one */
789 hildon_banner_ensure_child (HildonBanner *self,
790 GtkWidget *user_widget,
793 const gchar *first_property,
798 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
802 widget = priv->main_item;
803 va_start (args, first_property);
805 /* Reuse existing widget if possible */
806 if (! user_widget && G_TYPE_CHECK_INSTANCE_TYPE (widget, type))
808 g_object_set_valist (G_OBJECT (widget), first_property, args);
812 /* We have to abandon old content widget */
814 gtk_container_remove (GTK_CONTAINER (priv->layout), widget);
816 /* Use user provided widget or create a new one */
817 priv->main_item = widget = user_widget ?
818 user_widget : GTK_WIDGET (g_object_new_valist(type, first_property, args));
819 gtk_box_pack_start (GTK_BOX (priv->layout), widget, TRUE, TRUE, 0);
822 /* We make sure that the widget exists in desired position. Different
823 banners place this child widget to different places */
824 gtk_box_reorder_child (GTK_BOX (priv->layout), widget, pos);
828 /* Creates a new banner instance or uses an existing one */
830 hildon_banner_get_instance_for_widget (GtkWidget *widget,
835 window = widget ? gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW) : NULL;
836 return g_object_new (HILDON_TYPE_BANNER, "parent-window", window, "is-timed", timed, NULL);
840 hildon_banner_create_animation (void)
843 GdkPixbufSimpleAnim *anim;
846 GError *error = NULL;
850 anim = gdk_pixbuf_simple_anim_new (HILDON_ICON_PIXEL_SIZE_STYLUS,
851 HILDON_ICON_PIXEL_SIZE_STYLUS,
852 HILDON_BANNER_ANIMATION_FRAMERATE);
853 gdk_pixbuf_simple_anim_set_loop (anim, TRUE);
854 theme = gtk_icon_theme_get_default ();
856 for (i = 1; i <= HILDON_BANNER_ANIMATION_NFRAMES; i++) {
857 icon_name = g_strdup_printf (HILDON_BANNER_ANIMATION_TMPL, i);
858 frame = gtk_icon_theme_load_icon (theme, icon_name, HILDON_ICON_PIXEL_SIZE_STYLUS,
862 g_warning ("Icon theme lookup for icon `%s' failed: %s",
863 icon_name, error->message);
864 g_error_free (error);
867 gdk_pixbuf_simple_anim_add_frame (anim, frame);
870 g_object_unref (frame);
874 image = gtk_image_new_from_animation (GDK_PIXBUF_ANIMATION (anim));
875 g_object_unref (anim);
881 * hildon_banner_show_information:
882 * @widget: the #GtkWidget that is the owner of the banner
883 * @icon_name: since Hildon 2.2 this parameter is not used anymore and
884 * any value that you pass will be ignored
885 * @text: Text to display
887 * This function creates and displays an information banner that
888 * automatically goes away after certain time period. For each window
889 * in your application there can only be one timed banner, so if you
890 * spawn a new banner before the earlier one has timed out, the
891 * previous one will be replaced.
893 * Returns: The newly created banner
897 hildon_banner_show_information (GtkWidget *widget,
898 const gchar *icon_name,
901 HildonBanner *banner;
903 g_return_val_if_fail (text != NULL, NULL);
906 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
908 hildon_banner_set_text (banner, text);
909 hildon_banner_bind_style (banner, "information");
911 /* Show the banner, since caller cannot do that */
912 gtk_widget_show_all (GTK_WIDGET (banner));
914 return (GtkWidget *) banner;
918 * hildon_banner_show_informationf:
919 * @widget: the #GtkWidget that is the owner of the banner
920 * @icon_name: since Hildon 2.2 this parameter is not used anymore and
921 * any value that you pass will be ignored
922 * @format: a printf-like format string
923 * @Varargs: arguments for the format string
925 * A helper function for #hildon_banner_show_information with
928 * Returns: the newly created banner
931 hildon_banner_show_informationf (GtkWidget *widget,
932 const gchar *icon_name,
936 g_return_val_if_fail (format != NULL, NULL);
942 va_start (args, format);
943 message = g_strdup_vprintf (format, args);
946 banner = hildon_banner_show_information (widget, icon_name, message);
954 * hildon_banner_show_information_with_markup:
955 * @widget: the #GtkWidget that wants to display banner
956 * @icon_name: since Hildon 2.2 this parameter is not used anymore and
957 * any value that you pass will be ignored
958 * @markup: a markup string to display (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
960 * This function creates and displays an information banner that
961 * automatically goes away after certain time period. For each window
962 * in your application there can only be one timed banner, so if you
963 * spawn a new banner before the earlier one has timed out, the
964 * previous one will be replaced.
966 * Returns: the newly created banner
970 hildon_banner_show_information_with_markup (GtkWidget *widget,
971 const gchar *icon_name,
974 HildonBanner *banner;
976 g_return_val_if_fail (icon_name == NULL || icon_name[0] != 0, NULL);
977 g_return_val_if_fail (markup != NULL, NULL);
980 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
982 hildon_banner_set_markup (banner, markup);
983 hildon_banner_bind_style (banner, "information");
985 /* Show the banner, since caller cannot do that */
986 gtk_widget_show_all (GTK_WIDGET (banner));
988 return (GtkWidget *) banner;
992 * hildon_banner_show_animation:
993 * @widget: the #GtkWidget that wants to display banner
994 * @animation_name: since Hildon 2.2 this parameter is not used
995 * anymore and any value that you pass will be
997 * @text: the text to display.
999 * Shows an animated progress notification. It's recommended not to try
1000 * to show more than one progress notification at a time, since
1001 * they will appear on top of each other. You can use progress
1002 * notifications with timed banners. In this case the banners are
1003 * located so that you can somehow see both.
1005 * Please note that banners are destroyed automatically once the
1006 * window they are attached to is closed. The pointer that you receive
1007 * with this function does not contain additional references, so it
1008 * can become invalid without warning (this is true for all toplevel
1009 * windows in gtk). To make sure that the banner does not disappear
1010 * automatically, you can separately ref the return value (this
1011 * doesn't prevent the banner from disappearing, just the object from
1012 * being finalized). In this case you have to call both
1013 * gtk_widget_destroy() followed by g_object_unref() (in this order).
1015 * Returns: a #HildonBanner widget. You must call gtk_widget_destroy()
1016 * once you are done with the banner.
1018 * Deprecated: Hildon 2.2: use
1019 * hildon_gtk_window_set_progress_indicator() instead.
1022 hildon_banner_show_animation (GtkWidget *widget,
1023 const gchar *animation_name,
1026 HildonBanner *banner;
1027 GtkWidget *image_widget;
1029 g_return_val_if_fail (text != NULL, NULL);
1031 image_widget = hildon_banner_create_animation ();
1033 /* Prepare banner */
1034 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
1035 hildon_banner_ensure_child (banner, image_widget, 0,
1036 GTK_TYPE_IMAGE, "yalign", 0.0, NULL);
1038 hildon_banner_set_text (banner, text);
1039 hildon_banner_bind_style (banner, "animation");
1042 gtk_widget_show_all (GTK_WIDGET (banner));
1044 return (GtkWidget *) banner;
1048 * hildon_banner_show_progress:
1049 * @widget: the #GtkWidget that wants to display banner
1050 * @bar: Progressbar to use. You usually can just pass %NULL, unless
1051 * you want somehow customized progress bar.
1052 * @text: text to display.
1054 * Shows progress notification. See #hildon_banner_show_animation
1055 * for more information.
1057 * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
1058 * once you are done with the banner.
1060 * Deprecated: Hildon 2.2: use hildon_gtk_window_set_progress_indicator() instead.
1063 hildon_banner_show_progress (GtkWidget *widget,
1064 GtkProgressBar *bar,
1067 HildonBanner *banner;
1068 HildonBannerPrivate *priv;
1070 g_return_val_if_fail (bar == NULL || GTK_IS_PROGRESS_BAR (bar), NULL);
1071 g_return_val_if_fail (text != NULL, NULL);
1074 /* Prepare banner */
1075 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
1076 priv = HILDON_BANNER_GET_PRIVATE (banner);
1078 hildon_banner_ensure_child (banner, (GtkWidget *) bar, -1, GTK_TYPE_PROGRESS_BAR, NULL);
1080 gtk_widget_set_size_request (priv->main_item,
1081 HILDON_BANNER_PROGRESS_WIDTH, -1);
1083 hildon_banner_set_text (banner, text);
1084 hildon_banner_bind_style (banner, "progress");
1086 /* Show the banner */
1087 gtk_widget_show_all (GTK_WIDGET (banner));
1089 return GTK_WIDGET (banner);
1093 * hildon_banner_set_text:
1094 * @self: a #HildonBanner widget
1095 * @text: a new text to display in banner
1097 * Sets the text that is displayed in the banner.
1101 hildon_banner_set_text (HildonBanner *self,
1105 HildonBannerPrivate *priv;
1106 const gchar *existing_text;
1108 g_return_if_fail (HILDON_IS_BANNER (self));
1110 priv = HILDON_BANNER_GET_PRIVATE (self);
1113 label = GTK_LABEL (priv->label);
1114 existing_text = gtk_label_get_text (label);
1116 if (existing_text != NULL &&
1118 strcmp (existing_text, text) != 0) {
1119 gtk_label_set_text (label, text);
1120 hildon_banner_reset_wrap_state (self);
1123 hildon_banner_check_position (GTK_WIDGET (self));
1127 * hildon_banner_set_markup:
1128 * @self: a #HildonBanner widget
1129 * @markup: a new text with Pango markup to display in the banner
1131 * Sets the text with markup that is displayed in the banner.
1135 hildon_banner_set_markup (HildonBanner *self,
1136 const gchar *markup)
1139 HildonBannerPrivate *priv;
1141 g_return_if_fail (HILDON_IS_BANNER (self));
1143 priv = HILDON_BANNER_GET_PRIVATE (self);
1146 label = GTK_LABEL (priv->label);
1147 gtk_label_set_markup (label, markup);
1149 hildon_banner_reset_wrap_state (self);
1151 hildon_banner_check_position (GTK_WIDGET(self));
1155 * hildon_banner_set_fraction:
1156 * @self: a #HildonBanner widget
1157 * @fraction: #gdouble
1159 * The fraction is the completion of progressbar,
1160 * the scale is from 0.0 to 1.0.
1161 * Sets the amount of fraction the progressbar has.
1163 * Note that this method only has effect if @self was created with
1164 * hildon_banner_show_progress()
1168 hildon_banner_set_fraction (HildonBanner *self,
1171 HildonBannerPrivate *priv;
1173 g_return_if_fail (HILDON_IS_BANNER (self));
1174 priv = HILDON_BANNER_GET_PRIVATE (self);
1177 g_return_if_fail (GTK_IS_PROGRESS_BAR (priv->main_item));
1178 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->main_item), fraction);
1182 * hildon_banner_set_timeout:
1183 * @self: a #HildonBanner widget
1184 * @timeout: timeout to set in miliseconds.
1186 * Sets the timeout on the banner. After the given amount of miliseconds
1187 * has elapsed the banner will go away. Note that settings this only makes
1188 * sense on the banners that are timed and that have not been yet displayed
1191 * Note that this method only has effect if @self is an information
1192 * banner (created using hildon_banner_show_information() and
1196 hildon_banner_set_timeout (HildonBanner *self,
1199 HildonBannerPrivate *priv;
1201 g_return_if_fail (HILDON_IS_BANNER (self));
1202 priv = HILDON_BANNER_GET_PRIVATE (self);
1205 priv->timeout = timeout;
1209 * hildon_banner_set_icon:
1210 * @self: a #HildonBanner widget
1211 * @icon_name: the name of icon to use. Can be %NULL for default icon
1213 * Sets the icon to be used in the banner.
1215 * Deprecated: This function does nothing. As of hildon 2.2, hildon
1216 * banners don't allow changing their icons.
1219 hildon_banner_set_icon (HildonBanner *self,
1220 const gchar *icon_name)
1225 * hildon_banner_set_icon_from_file:
1226 * @self: a #HildonBanner widget
1227 * @icon_file: the filename of icon to use. Can be %NULL for default icon
1229 * Sets the icon from its filename to be used in the banner.
1231 * Deprecated: This function does nothing. As of hildon 2.2, hildon
1232 * banners don't allow changing their icons.
1235 hildon_banner_set_icon_from_file (HildonBanner *self,
1236 const gchar *icon_file)