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>
63 #undef HILDON_DISABLE_DEPRECATED
65 #include "hildon-banner.h"
66 #include "hildon-banner-private.h"
67 #include "hildon-defines.h"
69 /* position relative to the screen */
71 #define HILDON_BANNER_WINDOW_X 0
73 #define HILDON_BANNER_WINDOW_Y 73
75 #define HILDON_BANNER_WINDOW_FULLSCREEN_Y 20
79 #define HILDON_BANNER_PROGRESS_WIDTH 104
81 #define HILDON_BANNER_LABEL_MAX_TIMED \
82 (800 - ((HILDON_MARGIN_TRIPLE) * 2))
84 #define HILDON_BANNER_LABEL_MAX_PROGRESS 375 /*265*/
88 #define HILDON_BANNER_DEFAULT_TIMEOUT 3000
92 #define HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION "qgn_indi_pball_a"
102 static GtkWidget* global_timed_banner = NULL;
105 get_current_app_window (void);
108 check_fullscreen_state (Window window);
111 hildon_banner_timed_quark (void);
114 hildon_banner_bind_style (HildonBanner *self,
118 hildon_banner_timeout (gpointer data);
121 hildon_banner_clear_timeout (HildonBanner *self);
124 hildon_banner_ensure_timeout (HildonBanner *self);
127 hildon_banner_set_property (GObject *object,
133 hildon_banner_get_property (GObject *object,
139 hildon_banner_destroy (GtkObject *object);
142 hildon_banner_real_get_instance (GObject *window,
146 hildon_banner_constructor (GType type,
147 guint n_construct_params,
148 GObjectConstructParam *construct_params);
151 hildon_banner_finalize (GObject *object);
154 hildon_banner_button_press_event (GtkWidget* widget,
155 GdkEventButton* event);
158 hildon_banner_map_event (GtkWidget *widget,
161 hildon_banner_reset_wrap_state (HildonBanner *banner);
164 force_to_wrap_truncated (HildonBanner *banner);
167 hildon_banner_check_position (GtkWidget *widget);
170 hildon_banner_realize (GtkWidget *widget);
173 hildon_banner_class_init (HildonBannerClass *klass);
176 hildon_banner_init (HildonBanner *self);
179 hildon_banner_ensure_child (HildonBanner *self,
180 GtkWidget *user_widget,
183 const gchar *first_property,
187 hildon_banner_get_instance_for_widget (GtkWidget *widget,
190 G_DEFINE_TYPE (HildonBanner, hildon_banner, GTK_TYPE_WINDOW)
192 /* copy/paste from old infoprint implementation: Use matchbox
193 properties to find the topmost application window */
195 get_current_app_window (void)
202 Atom atom_current_app_window = gdk_x11_get_xatom_by_name ("_MB_CURRENT_APP_WINDOW");
204 Window win_result = None;
205 guchar *data_return = NULL;
207 status = XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW (),
208 atom_current_app_window, 0L, 16L,
209 0, XA_WINDOW, &realType, &format,
213 if (status == Success && realType == XA_WINDOW && format == 32 && n == 1 && data_return != NULL)
215 win_result = ((Window*) data_return)[0];
224 /* Checks if a window is in fullscreen state or not. This
225 information is needed when banners are positioned on screen.
226 copy/paste from old infoprint implementation. */
228 check_fullscreen_state (Window window)
232 int format, status, i;
233 guchar *data_return = NULL;
236 Atom atom_window_state = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
237 Atom atom_fullscreen = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_FULLSCREEN");
242 /* in some cases XGetWindowProperty seems to generate BadWindow,
243 so at the moment this function does not always work perfectly */
244 gdk_error_trap_push ();
245 status = XGetWindowProperty (GDK_DISPLAY (), window,
246 atom_window_state, 0L, 1000000L,
247 0, XA_ATOM, &realType, &format,
248 &n, &extra, &data_return);
252 if (gdk_error_trap_pop ())
255 if (status == Success && realType == XA_ATOM && format == 32 && n > 0)
257 for (i=0; i < n; i++)
258 if (((Atom*)data_return)[i] && ((Atom*)data_return)[i] == atom_fullscreen)
260 if (data_return) XFree (data_return);
272 hildon_banner_timed_quark (void)
274 static GQuark quark = 0;
276 if (G_UNLIKELY(quark == 0))
277 quark = g_quark_from_static_string ("hildon-banner-timed");
282 /* Set the widget and label name to make the correct rc-style attached into them */
284 hildon_banner_bind_style (HildonBanner *self,
285 const gchar *name_sufix)
287 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
292 name = g_strconcat ("HildonBannerLabel-", name_sufix, NULL);
293 gtk_widget_set_name (priv->label, name);
296 name = g_strconcat ("HildonBanner-", name_sufix, NULL);
297 gtk_widget_set_name (GTK_WIDGET (self), name);
301 /* In timeout function we automatically destroy timed banners */
303 simulate_close (GtkWidget* widget)
305 gboolean result = FALSE;
307 /* If the banner is currently visible (it normally should),
308 we simulate clicking the close button of the window.
309 This allows applications to reuse the banner by prevent
311 if (GTK_WIDGET_DRAWABLE (widget))
313 GdkEvent *event = gdk_event_new (GDK_DELETE);
314 event->any.window = g_object_ref (widget->window);
315 event->any.send_event = FALSE;
316 result = gtk_widget_event (widget, event);
317 gdk_event_free (event);
324 hildon_banner_timeout (gpointer data)
327 gboolean continue_timeout = FALSE;
329 GDK_THREADS_ENTER ();
331 g_assert (HILDON_IS_BANNER (data));
333 widget = GTK_WIDGET (data);
334 g_object_ref (widget);
336 continue_timeout = simulate_close (widget);
338 if (! continue_timeout) {
339 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (data);
340 priv->timeout_id = 0;
341 gtk_widget_destroy (widget);
344 g_object_unref (widget);
346 GDK_THREADS_LEAVE ();
348 return continue_timeout;
352 hildon_banner_clear_timeout (HildonBanner *self)
354 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
357 if (priv->timeout_id != 0) {
358 g_source_remove (priv->timeout_id);
359 priv->timeout_id = 0;
367 hildon_banner_ensure_timeout (HildonBanner *self)
369 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
372 if (priv->timeout_id == 0 && priv->is_timed && priv->timeout > 0)
373 priv->timeout_id = g_timeout_add (priv->timeout,
374 hildon_banner_timeout, self);
378 hildon_banner_set_property (GObject *object,
384 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
390 priv->timeout = g_value_get_uint (value);
394 priv->is_timed = g_value_get_boolean (value);
397 case PROP_PARENT_WINDOW:
398 window = g_value_get_object (value);
400 g_object_remove_weak_pointer(G_OBJECT (priv->parent), (gpointer) &priv->parent);
403 gtk_window_set_transient_for (GTK_WINDOW (object), (GtkWindow *) window);
404 priv->parent = (GtkWindow *) window;
407 gtk_window_set_destroy_with_parent (GTK_WINDOW (object), TRUE);
408 g_object_add_weak_pointer(G_OBJECT (window), (gpointer) &priv->parent);
414 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
420 hildon_banner_get_property (GObject *object,
425 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
431 g_value_set_uint (value, priv->timeout);
435 g_value_set_boolean (value, priv->is_timed);
438 case PROP_PARENT_WINDOW:
439 g_value_set_object (value, gtk_window_get_transient_for (GTK_WINDOW (object)));
443 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
449 hildon_banner_destroy (GtkObject *object)
451 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
455 GObject *parent_window = (GObject *) priv->parent;
457 g_assert (HILDON_IS_BANNER (object));
458 self = HILDON_BANNER (object);
460 /* Drop possible global pointer. That can hold reference to us */
461 if ((gpointer) object == (gpointer) global_timed_banner) {
462 global_timed_banner = NULL;
463 g_object_unref (object);
466 /* Remove the data from parent window for timed banners. Those hold reference */
467 if (priv->is_timed && parent_window != NULL) {
468 g_object_set_qdata (parent_window, hildon_banner_timed_quark (), NULL);
471 (void) hildon_banner_clear_timeout (self);
473 if (GTK_OBJECT_CLASS (hildon_banner_parent_class)->destroy)
474 GTK_OBJECT_CLASS (hildon_banner_parent_class)->destroy (object);
477 /* Search a previous banner instance */
479 hildon_banner_real_get_instance (GObject *window,
483 /* If we have a parent window, the previous instance is stored there */
485 return g_object_get_qdata(window, hildon_banner_timed_quark ());
488 /* System notification instance is stored into global pointer */
489 return (GObject *) global_timed_banner;
492 /* Non-timed banners are normal (non-singleton) objects */
496 /* By overriding constructor we force timed banners to be
497 singletons for each window */
499 hildon_banner_constructor (GType type,
500 guint n_construct_params,
501 GObjectConstructParam *construct_params)
503 GObject *banner, *window = NULL;
504 gboolean timed = FALSE;
507 /* Search banner type information from parameters in order
508 to locate the possible previous banner instance. */
509 for (i = 0; i < n_construct_params; i++)
511 if (strcmp(construct_params[i].pspec->name, "parent-window") == 0)
512 window = g_value_get_object (construct_params[i].value);
513 else if (strcmp(construct_params[i].pspec->name, "is-timed") == 0)
514 timed = g_value_get_boolean (construct_params[i].value);
517 /* Try to get a previous instance if such exists */
518 banner = hildon_banner_real_get_instance (window, timed);
521 /* We have to create a new banner */
522 banner = G_OBJECT_CLASS (hildon_banner_parent_class)->constructor (type, n_construct_params, construct_params);
524 /* Store the newly created singleton instance either into parent
525 window data or into global variables. */
528 g_object_set_qdata_full (G_OBJECT (window), hildon_banner_timed_quark (),
529 g_object_ref (banner), g_object_unref);
531 g_assert (global_timed_banner == NULL);
532 global_timed_banner = g_object_ref (banner);
537 /* FIXME: This is a hack! We have to manually freeze
538 notifications. This is normally done by g_object_init, but we
539 are not going to call that. g_object_newv will otherwise give
540 a critical like this:
542 GLIB CRITICAL ** GLib-GObject - g_object_notify_queue_thaw:
543 assertion `nqueue->freeze_count > 0' failed */
545 g_object_freeze_notify (banner);
546 hildon_banner_reset_wrap_state (HILDON_BANNER (banner));
549 /* We restart possible timeouts for each new timed banner request */
550 if (timed && hildon_banner_clear_timeout (HILDON_BANNER (banner)))
551 hildon_banner_ensure_timeout (HILDON_BANNER(banner));
557 hildon_banner_finalize (GObject *object)
559 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
562 g_object_remove_weak_pointer(G_OBJECT (priv->parent), (gpointer) &priv->parent);
565 G_OBJECT_CLASS (hildon_banner_parent_class)->finalize (object);
569 hildon_banner_button_press_event (GtkWidget* widget,
570 GdkEventButton* event)
572 gboolean result = simulate_close (widget);
575 /* signal emission not stopped - basically behave like
576 * gtk_main_do_event() for a delete event, but just hide the
577 * banner instead of destroying it, as it is already meant to
578 * be destroyed by hildon_banner_timeout() (if it's timed) or
579 * the application (if it's not). */
580 gtk_widget_hide (widget);
586 #if defined(MAEMO_GTK)
588 hildon_banner_map (GtkWidget *widget)
590 if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->map) {
591 /* Make the banner temporary _before_ mapping it, to avoid closing
592 * other temporary windows */
593 gtk_window_set_is_temporary (GTK_WINDOW (widget), TRUE);
595 GTK_WIDGET_CLASS (hildon_banner_parent_class)->map (widget);
597 /* Make the banner non-temporary _after_ mapping it, to avoid
598 * being closed by other non-temporary windows */
599 gtk_window_set_is_temporary (GTK_WINDOW (widget), FALSE);
604 /* We start the timer for timed notifications after the window appears on screen */
606 hildon_banner_map_event (GtkWidget *widget,
609 gboolean result = FALSE;
611 if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->map_event)
612 result = GTK_WIDGET_CLASS (hildon_banner_parent_class)->map_event (widget, event);
614 hildon_banner_ensure_timeout (HILDON_BANNER(widget));
620 hildon_banner_reset_wrap_state (HildonBanner *banner)
623 HildonBannerPrivate *priv;
625 priv = HILDON_BANNER_GET_PRIVATE (banner);
628 layout = gtk_label_get_layout (GTK_LABEL (priv->label));
630 pango_layout_set_width (layout, -1);
631 priv->has_been_wrapped = FALSE;
632 priv->has_been_truncated = FALSE;
634 gtk_widget_set_size_request (priv->label, -1, -1);
635 gtk_widget_set_size_request (GTK_WIDGET (banner), -1, -1);
638 /* force to wrap truncated label by setting explicit size request
639 * see N#27000 and G#329646 */
641 force_to_wrap_truncated (HildonBanner *banner)
645 int width_text, width_max;
648 PangoRectangle logical;
649 GtkRequisition requisition;
650 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (banner);
652 g_return_if_fail (priv);
654 label = GTK_LABEL (priv->label);
656 layout = gtk_label_get_layout (label);
658 pango_layout_get_extents (layout, NULL, &logical);
659 width_text = PANGO_PIXELS (logical.width);
661 width_max = priv->is_timed ? HILDON_BANNER_LABEL_MAX_TIMED
662 : HILDON_BANNER_LABEL_MAX_PROGRESS;
664 /* If the width of the label is going to exceed the maximum allowed
665 * width, enforce the maximum allowed width now.
667 if (priv->has_been_wrapped
668 || width_text >= width_max
669 || pango_layout_is_wrapped (layout)) {
670 /* Force wrapping by setting the maximum size */
673 priv->has_been_wrapped = TRUE;
676 /* Make the label update its layout; and update our layout pointer
677 * because the layout will be cleared and refreshed.
679 gtk_widget_set_size_request (GTK_WIDGET (label), width, height);
680 gtk_widget_size_request (GTK_WIDGET (label), &requisition);
682 layout = gtk_label_get_layout (label);
684 /* If the layout has now been wrapped and exceeds 3 lines, we truncate
685 * the rest of the label according to spec.
687 if (priv->has_been_truncated
688 || (pango_layout_is_wrapped (layout)
689 && pango_layout_get_line_count (layout) > 3)) {
692 pango_layout_get_extents (layout, NULL, &logical);
693 lines = pango_layout_get_line_count (layout);
695 /* This calculation assumes that the same font is used
696 * throughout the banner -- this is usually the case on maemo
698 * FIXME: Pango >= 1.20 has pango_layout_set_height().
700 height = (PANGO_PIXELS (logical.height) * 3) / lines + 1;
701 priv->has_been_truncated = TRUE;
704 /* Set the new width/height if applicable */
705 gtk_widget_set_size_request (GTK_WIDGET (label), width, height);
710 hildon_banner_check_position (GtkWidget *widget)
715 gtk_widget_set_size_request (widget, gdk_screen_width (), -1);
717 force_to_wrap_truncated (HILDON_BANNER(widget)); /* see N#27000 and G#329646 */
719 gtk_widget_size_request (widget, &req);
726 x = HILDON_BANNER_WINDOW_X;
728 y = check_fullscreen_state (get_current_app_window ()) ?
729 HILDON_BANNER_WINDOW_FULLSCREEN_Y : HILDON_BANNER_WINDOW_Y;
731 gtk_window_move (GTK_WINDOW (widget), x, y);
735 hildon_banner_realize (GtkWidget *widget)
739 const gchar *notification_type = "_HILDON_NOTIFICATION_TYPE_BANNER";
740 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (widget);
743 /* We let the parent to init widget->window before we need it */
744 if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->realize)
745 GTK_WIDGET_CLASS (hildon_banner_parent_class)->realize (widget);
747 /* We use special hint to turn the banner into information notification. */
748 gdk_window_set_type_hint (widget->window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);
749 gtk_window_set_transient_for (GTK_WINDOW (widget), (GtkWindow *) priv->parent);
751 hildon_banner_check_position (widget);
753 /* Set the _HILDON_NOTIFICATION_TYPE property so Matchbox places the window correctly */
754 display = gdk_drawable_get_display (widget->window);
755 atom = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_NOTIFICATION_TYPE");
756 XChangeProperty (GDK_WINDOW_XDISPLAY (widget->window), GDK_WINDOW_XID (widget->window),
757 atom, XA_STRING, 8, PropModeReplace, (guchar *) notification_type,
758 strlen (notification_type));
762 hildon_banner_class_init (HildonBannerClass *klass)
764 GObjectClass *object_class;
765 GtkWidgetClass *widget_class;
767 object_class = G_OBJECT_CLASS (klass);
768 widget_class = GTK_WIDGET_CLASS (klass);
770 /* Append private structure to class. This is more elegant than
771 on g_new based approach */
772 g_type_class_add_private (klass, sizeof (HildonBannerPrivate));
774 /* Override virtual methods */
775 object_class->constructor = hildon_banner_constructor;
776 object_class->finalize = hildon_banner_finalize;
777 object_class->set_property = hildon_banner_set_property;
778 object_class->get_property = hildon_banner_get_property;
779 GTK_OBJECT_CLASS (klass)->destroy = hildon_banner_destroy;
780 widget_class->map_event = hildon_banner_map_event;
781 widget_class->realize = hildon_banner_realize;
782 widget_class->button_press_event = hildon_banner_button_press_event;
783 #if defined(MAEMO_GTK)
784 widget_class->map = hildon_banner_map;
787 /* Install properties.
788 We need construct properties for singleton purposes */
791 * HildonBanner:parent-window:
793 * The window for which the banner will be singleton.
796 g_object_class_install_property (object_class, PROP_PARENT_WINDOW,
797 g_param_spec_object ("parent-window",
799 "The window for which the banner will be singleton",
800 GTK_TYPE_WINDOW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
803 * HildonBanner:is-timed:
805 * Whether the banner is timed and goes away automatically.
808 g_object_class_install_property (object_class, PROP_IS_TIMED,
809 g_param_spec_boolean ("is-timed",
811 "Whether or not the notification goes away automatically "
812 "after the specified time has passed",
813 FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
816 * HildonBanner:timeout:
818 * The time before making the banner banner go away. This needs
819 * to be adjusted before the banner is mapped to the screen.
822 g_object_class_install_property (object_class, PROP_TIMEOUT,
823 g_param_spec_uint ("timeout",
825 "The time before making the banner banner go away",
828 HILDON_BANNER_DEFAULT_TIMEOUT,
829 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
833 hildon_banner_init (HildonBanner *self)
835 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
840 /* Initialize the common layout inside banner */
841 priv->layout = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
843 priv->label = g_object_new (GTK_TYPE_LABEL, NULL);
844 gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
845 gtk_label_set_line_wrap_mode (GTK_LABEL (priv->label), PANGO_WRAP_WORD_CHAR);
847 gtk_container_set_border_width (GTK_CONTAINER (priv->layout), HILDON_MARGIN_DEFAULT);
848 gtk_container_add (GTK_CONTAINER (self), priv->layout);
849 gtk_box_pack_start (GTK_BOX (priv->layout), priv->label, TRUE, TRUE, 0);
851 gtk_window_set_accept_focus (GTK_WINDOW (self), FALSE);
853 hildon_banner_reset_wrap_state (self);
855 gtk_widget_add_events (GTK_WIDGET (self), GDK_BUTTON_PRESS_MASK);
858 /* Makes sure that icon/progress item contains the desired type
859 of item. If possible, tries to avoid creating a new widget but
860 reuses the existing one */
862 hildon_banner_ensure_child (HildonBanner *self,
863 GtkWidget *user_widget,
866 const gchar *first_property,
871 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
875 widget = priv->main_item;
876 va_start (args, first_property);
878 /* Reuse existing widget if possible */
879 if (! user_widget && G_TYPE_CHECK_INSTANCE_TYPE (widget, type))
881 g_object_set_valist (G_OBJECT (widget), first_property, args);
885 /* We have to abandon old content widget */
887 gtk_container_remove (GTK_CONTAINER (priv->layout), widget);
889 /* Use user provided widget or create a new one */
890 priv->main_item = widget = user_widget ?
891 user_widget : GTK_WIDGET (g_object_new_valist(type, first_property, args));
892 gtk_box_pack_start (GTK_BOX (priv->layout), widget, TRUE, TRUE, 0);
895 /* We make sure that the widget exists in desired position. Different
896 banners place this child widget to different places */
897 gtk_box_reorder_child (GTK_BOX (priv->layout), widget, pos);
901 /* Creates a new banner instance or uses an existing one */
903 hildon_banner_get_instance_for_widget (GtkWidget *widget,
908 window = widget ? gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW) : NULL;
909 return g_object_new (HILDON_TYPE_BANNER, "parent-window", window, "is-timed", timed, NULL);
913 * hildon_banner_show_information:
914 * @widget: the #GtkWidget that is the owner of the banner
915 * @icon_name: since Hildon 2.2 this parameter is not used anymore and
916 * any value that you pass will be ignored
917 * @text: Text to display
919 * This function creates and displays an information banner that
920 * automatically goes away after certain time period. For each window
921 * in your application there can only be one timed banner, so if you
922 * spawn a new banner before the earlier one has timed out, the
923 * previous one will be replaced.
925 * Returns: The newly created banner
929 hildon_banner_show_information (GtkWidget *widget,
930 const gchar *icon_name,
933 HildonBanner *banner;
935 g_return_val_if_fail (text != NULL, NULL);
938 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
940 hildon_banner_set_text (banner, text);
941 hildon_banner_bind_style (banner, "information");
943 /* Show the banner, since caller cannot do that */
944 gtk_widget_show_all (GTK_WIDGET (banner));
946 return (GtkWidget *) banner;
950 * hildon_banner_show_informationf:
951 * @widget: the #GtkWidget that is the owner of the banner
952 * @icon_name: since Hildon 2.2 this parameter is not used anymore and
953 * any value that you pass will be ignored
954 * @format: a printf-like format string
955 * @Varargs: arguments for the format string
957 * A helper function for #hildon_banner_show_information with
960 * Returns: the newly created banner
963 hildon_banner_show_informationf (GtkWidget *widget,
964 const gchar *icon_name,
968 g_return_val_if_fail (format != NULL, NULL);
974 va_start (args, format);
975 message = g_strdup_vprintf (format, args);
978 banner = hildon_banner_show_information (widget, icon_name, message);
986 * hildon_banner_show_information_with_markup:
987 * @widget: the #GtkWidget that wants to display banner
988 * @icon_name: since Hildon 2.2 this parameter is not used anymore and
989 * any value that you pass will be ignored
990 * @markup: a markup string to display (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
992 * This function creates and displays an information banner that
993 * automatically goes away after certain time period. For each window
994 * in your application there can only be one timed banner, so if you
995 * spawn a new banner before the earlier one has timed out, the
996 * previous one will be replaced.
998 * Returns: the newly created banner
1002 hildon_banner_show_information_with_markup (GtkWidget *widget,
1003 const gchar *icon_name,
1004 const gchar *markup)
1006 HildonBanner *banner;
1008 g_return_val_if_fail (icon_name == NULL || icon_name[0] != 0, NULL);
1009 g_return_val_if_fail (markup != NULL, NULL);
1011 /* Prepare banner */
1012 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
1014 hildon_banner_set_markup (banner, markup);
1015 hildon_banner_bind_style (banner, "information");
1017 /* Show the banner, since caller cannot do that */
1018 gtk_widget_show_all (GTK_WIDGET (banner));
1020 return (GtkWidget *) banner;
1024 * hildon_banner_show_animation:
1025 * @widget: the #GtkWidget that wants to display banner
1026 * @animation_name: since Hildon 2.2 this parameter is not used
1027 * anymore and any value that you pass will be
1029 * @text: the text to display.
1031 * Shows an animated progress notification. It's recommended not to try
1032 * to show more than one progress notification at a time, since
1033 * they will appear on top of each other. You can use progress
1034 * notifications with timed banners. In this case the banners are
1035 * located so that you can somehow see both.
1037 * Please note that banners are destroyed automatically once the
1038 * window they are attached to is closed. The pointer that you receive
1039 * with this function does not contain additional references, so it
1040 * can become invalid without warning (this is true for all toplevel
1041 * windows in gtk). To make sure that the banner does not disappear
1042 * automatically, you can separately ref the return value (this
1043 * doesn't prevent the banner from disappearing, just the object from
1044 * being finalized). In this case you have to call both
1045 * gtk_widget_destroy() followed by g_object_unref() (in this order).
1047 * Returns: a #HildonBanner widget. You must call gtk_widget_destroy()
1048 * once you are done with the banner.
1050 * Deprecated: Hildon 2.2: use
1051 * hildon_gtk_window_set_progress_indicator() instead.
1054 hildon_banner_show_animation (GtkWidget *widget,
1055 const gchar *animation_name,
1058 HildonBanner *banner;
1059 GtkIconTheme *theme;
1061 GtkWidget *image_widget;
1062 const gchar *filename;
1064 g_return_val_if_fail (text != NULL, NULL);
1066 /* Find out which animation to use */
1067 theme = gtk_icon_theme_get_default ();
1068 info = gtk_icon_theme_lookup_icon (theme, HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION,
1069 HILDON_ICON_SIZE_STYLUS, 0);
1071 /* Try to load animation. One could try to optimize this
1072 to avoid loading the default animation during each call */
1074 filename = gtk_icon_info_get_filename (info);
1075 image_widget = gtk_image_new_from_file (filename);
1076 gtk_icon_info_free (info);
1078 g_warning ("Icon theme lookup for icon failed!");
1079 image_widget = NULL;
1082 /* Prepare banner */
1083 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
1084 hildon_banner_ensure_child (banner, image_widget, 0,
1085 GTK_TYPE_IMAGE, "yalign", 0.0, NULL);
1087 hildon_banner_set_text (banner, text);
1088 hildon_banner_bind_style (banner, "animation");
1091 gtk_widget_show_all (GTK_WIDGET (banner));
1093 return (GtkWidget *) banner;
1097 * hildon_banner_show_progress:
1098 * @widget: the #GtkWidget that wants to display banner
1099 * @bar: Progressbar to use. You usually can just pass %NULL, unless
1100 * you want somehow customized progress bar.
1101 * @text: text to display.
1103 * Shows progress notification. See #hildon_banner_show_animation
1104 * for more information.
1106 * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
1107 * once you are done with the banner.
1109 * Deprecated: Hildon 2.2: use hildon_gtk_window_set_progress_indicator() instead.
1112 hildon_banner_show_progress (GtkWidget *widget,
1113 GtkProgressBar *bar,
1116 HildonBanner *banner;
1117 HildonBannerPrivate *priv;
1119 g_return_val_if_fail (bar == NULL || GTK_IS_PROGRESS_BAR (bar), NULL);
1120 g_return_val_if_fail (text != NULL, NULL);
1123 /* Prepare banner */
1124 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
1125 priv = HILDON_BANNER_GET_PRIVATE (banner);
1127 hildon_banner_ensure_child (banner, (GtkWidget *) bar, -1, GTK_TYPE_PROGRESS_BAR, NULL);
1129 gtk_widget_set_size_request (priv->main_item,
1130 HILDON_BANNER_PROGRESS_WIDTH, -1);
1132 hildon_banner_set_text (banner, text);
1133 hildon_banner_bind_style (banner, "progress");
1135 /* Show the banner */
1136 gtk_widget_show_all (GTK_WIDGET (banner));
1138 return GTK_WIDGET (banner);
1142 * hildon_banner_set_text:
1143 * @self: a #HildonBanner widget
1144 * @text: a new text to display in banner
1146 * Sets the text that is displayed in the banner.
1150 hildon_banner_set_text (HildonBanner *self,
1154 HildonBannerPrivate *priv;
1155 const gchar *existing_text;
1157 g_return_if_fail (HILDON_IS_BANNER (self));
1159 priv = HILDON_BANNER_GET_PRIVATE (self);
1162 label = GTK_LABEL (priv->label);
1163 existing_text = gtk_label_get_text (label);
1165 if (existing_text != NULL &&
1167 strcmp (existing_text, text) != 0) {
1168 gtk_label_set_text (label, text);
1169 hildon_banner_reset_wrap_state (self);
1172 hildon_banner_check_position (GTK_WIDGET (self));
1176 * hildon_banner_set_markup:
1177 * @self: a #HildonBanner widget
1178 * @markup: a new text with Pango markup to display in the banner
1180 * Sets the text with markup that is displayed in the banner.
1184 hildon_banner_set_markup (HildonBanner *self,
1185 const gchar *markup)
1188 HildonBannerPrivate *priv;
1190 g_return_if_fail (HILDON_IS_BANNER (self));
1192 priv = HILDON_BANNER_GET_PRIVATE (self);
1195 label = GTK_LABEL (priv->label);
1196 gtk_label_set_markup (label, markup);
1198 hildon_banner_reset_wrap_state (self);
1200 hildon_banner_check_position (GTK_WIDGET(self));
1204 * hildon_banner_set_fraction:
1205 * @self: a #HildonBanner widget
1206 * @fraction: #gdouble
1208 * The fraction is the completion of progressbar,
1209 * the scale is from 0.0 to 1.0.
1210 * Sets the amount of fraction the progressbar has.
1212 * Note that this method only has effect if @self was created with
1213 * hildon_banner_show_progress()
1217 hildon_banner_set_fraction (HildonBanner *self,
1220 HildonBannerPrivate *priv;
1222 g_return_if_fail (HILDON_IS_BANNER (self));
1223 priv = HILDON_BANNER_GET_PRIVATE (self);
1226 g_return_if_fail (GTK_IS_PROGRESS_BAR (priv->main_item));
1227 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->main_item), fraction);
1231 * hildon_banner_set_timeout:
1232 * @self: a #HildonBanner widget
1233 * @timeout: timeout to set in miliseconds.
1235 * Sets the timeout on the banner. After the given amount of miliseconds
1236 * has elapsed the banner will go away. Note that settings this only makes
1237 * sense on the banners that are timed and that have not been yet displayed
1240 * Note that this method only has effect if @self is an information
1241 * banner (created using hildon_banner_show_information() and
1245 hildon_banner_set_timeout (HildonBanner *self,
1248 HildonBannerPrivate *priv;
1250 g_return_if_fail (HILDON_IS_BANNER (self));
1251 priv = HILDON_BANNER_GET_PRIVATE (self);
1254 priv->timeout = timeout;
1258 * hildon_banner_set_icon:
1259 * @self: a #HildonBanner widget
1260 * @icon_name: the name of icon to use. Can be %NULL for default icon
1262 * Sets the icon to be used in the banner.
1264 * Deprecated: This function does nothing. As of hildon 2.2, hildon
1265 * banners don't allow changing their icons.
1268 hildon_banner_set_icon (HildonBanner *self,
1269 const gchar *icon_name)
1274 * hildon_banner_set_icon_from_file:
1275 * @self: a #HildonBanner widget
1276 * @icon_file: the filename of icon to use. Can be %NULL for default icon
1278 * Sets the icon from its filename to be used in the banner.
1280 * Deprecated: This function does nothing. As of hildon 2.2, hildon
1281 * banners don't allow changing their icons.
1284 hildon_banner_set_icon_from_file (HildonBanner *self,
1285 const gchar *icon_file)