2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006, 2007 Nokia Corporation, all rights reserved.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@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 can be used to display a short, timed notification
30 * or information to the user. It can communicate that a
31 * task has been finished or the application state has changed.
32 * Banners should be used only to display non-critical pieces of
41 #include "hildon-banner.h"
42 #include <gtk/gtkhbox.h>
43 #include <gtk/gtkimage.h>
44 #include <gtk/gtkicontheme.h>
47 #include <X11/Xatom.h>
48 #include "hildon-defines.h"
49 #include "hildon-banner-private.h"
51 /* position relative to the screen */
53 #define HILDON_BANNER_WINDOW_X 30
55 #define HILDON_BANNER_WINDOW_Y 73
57 #define HILDON_BANNER_WINDOW_FULLSCREEN_Y 20
61 #define HILDON_BANNER_PROGRESS_WIDTH 104
63 #define HILDON_BANNER_LABEL_MAX_TIMED 375
65 #define HILDON_BANNER_LABEL_MAX_PROGRESS 375 /*265*/
69 #define HILDON_BANNER_DEFAULT_TIMEOUT 3000
73 #define HILDON_BANNER_DEFAULT_ICON "qgn_note_infoprint"
75 #define HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION "qgn_indi_pball_a"
85 static GtkWidget* global_timed_banner = NULL;
88 get_current_app_window (void);
91 check_fullscreen_state (Window window);
94 hildon_banner_timed_quark (void);
97 hildon_banner_bind_label_style (HildonBanner *self,
101 hildon_banner_timeout (gpointer data);
104 hildon_banner_clear_timeout (HildonBanner *self);
107 hildon_banner_ensure_timeout (HildonBanner *self);
110 hildon_banner_set_property (GObject *object,
116 hildon_banner_get_property (GObject *object,
122 hildon_banner_destroy (GtkObject *object);
125 hildon_banner_real_get_instance (GObject *window,
129 hildon_banner_constructor (GType type,
130 guint n_construct_params,
131 GObjectConstructParam *construct_params);
134 hildon_banner_finalize (GObject *object);
137 hildon_banner_map_event (GtkWidget *widget,
141 force_to_wrap_truncated (HildonBanner *banner);
144 hildon_banner_check_position (GtkWidget *widget);
147 hildon_banner_realize (GtkWidget *widget);
150 hildon_banner_class_init (HildonBannerClass *klass);
153 hildon_banner_init (HildonBanner *self);
156 hildon_banner_ensure_child (HildonBanner *self,
157 GtkWidget *user_widget,
160 const gchar *first_property,
164 hildon_banner_get_instance_for_widget (GtkWidget *widget,
167 static GtkWindowClass* parent_class = NULL;
170 * hildon_banner_get_type:
172 * Initializes and returns the type of a hildon banner.
174 * @Returns: GType of #HildonBanner
177 hildon_banner_get_type (void)
179 static GType banner_type = 0;
183 static const GTypeInfo banner_info = {
184 sizeof (HildonBannerClass),
185 NULL, /* base_init */
186 NULL, /* base_finalize */
187 (GClassInitFunc) hildon_banner_class_init,
188 NULL, /* class_finalize */
189 NULL, /* class_data */
190 sizeof (HildonBanner),
192 (GInstanceInitFunc) hildon_banner_init,
194 banner_type = g_type_register_static (GTK_TYPE_WINDOW,
195 "HildonBanner", &banner_info, 0 );
200 /* copy/paste from old infoprint implementation: Use matchbox
201 properties to find the topmost application window */
203 get_current_app_window (void)
210 Atom atom_current_app_window = gdk_x11_get_xatom_by_name ("_MB_CURRENT_APP_WINDOW");
212 Window win_result = None;
213 guchar *data_return = NULL;
215 status = XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW (),
216 atom_current_app_window, 0L, 16L,
217 0, XA_WINDOW, &realType, &format,
221 if (status == Success && realType == XA_WINDOW && format == 32 && n == 1 && data_return != NULL)
223 win_result = ((Window*) data_return)[0];
232 /* Checks if a window is in fullscreen state or not. This
233 information is needed when banners are positioned on screen.
234 copy/paste from old infoprint implementation. */
236 check_fullscreen_state (Window window)
240 int format, status, i;
241 guchar *data_return = NULL;
244 Atom atom_window_state = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
245 Atom atom_fullscreen = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_FULLSCREEN");
250 /* in some cases XGetWindowProperty seems to generate BadWindow,
251 so at the moment this function does not always work perfectly */
252 gdk_error_trap_push ();
253 status = XGetWindowProperty (GDK_DISPLAY (), window,
254 atom_window_state, 0L, 1000000L,
255 0, XA_ATOM, &realType, &format,
256 &n, &extra, &data_return);
260 if (gdk_error_trap_pop ())
263 if (status == Success && realType == XA_ATOM && format == 32 && n > 0)
265 for (i=0; i < n; i++)
266 if (((Atom*)data_return)[i] && ((Atom*)data_return)[i] == atom_fullscreen)
268 if (data_return) XFree (data_return);
280 hildon_banner_timed_quark (void)
282 static GQuark quark = 0;
284 if (G_UNLIKELY(quark == 0))
285 quark = g_quark_from_static_string ("hildon-banner-timed");
290 /* Set the label name to make the correct rc-style attached into it */
292 hildon_banner_bind_label_style (HildonBanner *self,
295 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
298 GtkWidget *label = priv->label;
300 /* Too bad that we cannot really reset the widget name */
301 gtk_widget_set_name (label, name ? name : g_type_name (GTK_WIDGET_TYPE (label)));
304 /* In timeout function we automatically destroy timed banners */
306 hildon_banner_timeout (gpointer data)
310 gboolean continue_timeout = FALSE;
312 GDK_THREADS_ENTER ();
314 g_assert (HILDON_IS_BANNER (data));
316 widget = GTK_WIDGET (data);
317 g_object_ref (widget);
319 /* If the banner is currently visible (it normally should),
320 we simulate clicking the close button of the window.
321 This allows applications to reuse the banner by prevent
323 if (GTK_WIDGET_DRAWABLE (widget))
325 event = gdk_event_new (GDK_DELETE);
326 event->any.window = g_object_ref (widget->window);
327 event->any.send_event = FALSE;
328 continue_timeout = gtk_widget_event (widget, event);
329 gdk_event_free (event);
332 if (! continue_timeout)
333 gtk_widget_destroy (widget);
335 g_object_unref (widget);
337 GDK_THREADS_LEAVE ();
339 return continue_timeout;
343 hildon_banner_clear_timeout (HildonBanner *self)
345 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
348 if (priv->timeout_id != 0) {
349 g_source_remove (priv->timeout_id);
350 priv->timeout_id = 0;
358 hildon_banner_ensure_timeout (HildonBanner *self)
360 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
363 if (priv->timeout_id == 0 && priv->is_timed && priv->timeout > 0)
364 priv->timeout_id = g_timeout_add (priv->timeout,
365 hildon_banner_timeout, self);
369 hildon_banner_set_property (GObject *object,
376 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
382 priv->timeout = g_value_get_uint (value);
386 priv->is_timed = g_value_get_boolean (value);
388 /* Timed and progress notifications have different
389 pixel size values for text.
390 We force to use requisition size for timed banners
391 in order to avoid resize problems when reusing the
392 window (see bug #24339) */
393 geom.max_width = priv->is_timed ? -1
394 : HILDON_BANNER_LABEL_MAX_PROGRESS;
395 geom.max_height = -1;
396 gtk_window_set_geometry_hints (GTK_WINDOW (object),
397 priv->label, &geom, GDK_HINT_MAX_SIZE);
400 case PROP_PARENT_WINDOW:
401 window = g_value_get_object (value);
403 g_object_remove_weak_pointer(G_OBJECT (priv->parent), (gpointer) &priv->parent);
406 gtk_window_set_transient_for (GTK_WINDOW (object), (GtkWindow *) window);
407 priv->parent = (GtkWindow *) window;
410 gtk_window_set_destroy_with_parent (GTK_WINDOW (object), TRUE);
411 g_object_add_weak_pointer(G_OBJECT (window), (gpointer) &priv->parent);
417 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
423 hildon_banner_get_property (GObject *object,
428 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
434 g_value_set_uint (value, priv->timeout);
438 g_value_set_boolean (value, priv->is_timed);
441 case PROP_PARENT_WINDOW:
442 g_value_set_object (value, gtk_window_get_transient_for (GTK_WINDOW (object)));
446 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
452 hildon_banner_destroy (GtkObject *object)
454 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
458 GObject *parent_window = (GObject *) priv->parent;
460 g_assert (HILDON_IS_BANNER (object));
461 self = HILDON_BANNER (object);
463 /* Drop possible global pointer. That can hold reference to us */
464 if ((gpointer) object == (gpointer) global_timed_banner) {
465 global_timed_banner = NULL;
466 g_object_unref (object);
469 /* Remove the data from parent window for timed banners. Those hold reference */
470 if (priv->is_timed && parent_window != NULL) {
471 g_object_set_qdata (parent_window, hildon_banner_timed_quark (), NULL);
474 (void) hildon_banner_clear_timeout (self);
476 if (GTK_OBJECT_CLASS (parent_class)->destroy)
477 GTK_OBJECT_CLASS (parent_class)->destroy (object);
480 /* Search a previous banner instance */
482 hildon_banner_real_get_instance (GObject *window,
486 /* If we have a parent window, the previous instance is stored there */
488 return g_object_get_qdata(window, hildon_banner_timed_quark ());
491 /* System notification instance is stored into global pointer */
492 return (GObject *) global_timed_banner;
495 /* Non-timed banners are normal (non-singleton) objects */
499 /* By overriding constructor we force timed banners to be
500 singletons for each window */
502 hildon_banner_constructor (GType type,
503 guint n_construct_params,
504 GObjectConstructParam *construct_params)
506 GObject *banner, *window = NULL;
507 gboolean timed = FALSE;
510 /* Search banner type information from parameters in order
511 to locate the possible previous banner instance. */
512 for (i = 0; i < n_construct_params; i++)
514 if (strcmp(construct_params[i].pspec->name, "parent-window") == 0)
515 window = g_value_get_object (construct_params[i].value);
516 else if (strcmp(construct_params[i].pspec->name, "is-timed") == 0)
517 timed = g_value_get_boolean (construct_params[i].value);
520 /* Try to get a previous instance if such exists */
521 banner = hildon_banner_real_get_instance (window, timed);
524 /* We have to create a new banner */
525 banner = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_params, construct_params);
527 /* Store the newly created singleton instance either into parent
528 window data or into global variables. */
531 g_object_set_qdata_full (G_OBJECT (window), hildon_banner_timed_quark (),
532 g_object_ref (banner), g_object_unref);
534 g_assert (global_timed_banner == NULL);
535 global_timed_banner = g_object_ref (banner);
540 /* FIXME: This is a hack! We have to manually freeze
541 notifications. This is normally done by g_object_init, but we
542 are not going to call that. g_object_newv will otherwise give
543 a critical like this:
545 GLIB CRITICAL ** GLib-GObject - g_object_notify_queue_thaw:
546 assertion `nqueue->freeze_count > 0' failed */
548 g_object_freeze_notify (banner);
551 /* We restart possible timeouts for each new timed banner request */
552 if (timed && hildon_banner_clear_timeout (HILDON_BANNER (banner)))
553 hildon_banner_ensure_timeout (HILDON_BANNER(banner));
559 hildon_banner_finalize (GObject *object)
561 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
564 g_object_remove_weak_pointer(G_OBJECT (priv->parent), (gpointer) &priv->parent);
567 G_OBJECT_CLASS (parent_class)->finalize (object);
570 /* We start the timer for timed notifications after the window appears on screen */
572 hildon_banner_map_event (GtkWidget *widget,
575 gboolean result = FALSE;
577 if (GTK_WIDGET_CLASS (parent_class)->map_event)
578 result = GTK_WIDGET_CLASS (parent_class)->map_event (widget, event);
580 hildon_banner_ensure_timeout (HILDON_BANNER(widget));
586 /* force to wrap truncated label by setting explicit size request
587 * see N#27000 and G#329646 */
589 force_to_wrap_truncated (HildonBanner *banner)
593 int width_text, width_max;
595 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (banner);
598 label = GTK_LABEL (priv->label);
600 layout = gtk_label_get_layout (label);
601 width_text = PANGO_PIXELS(pango_layout_get_width (layout));
602 /* = width to which the lines of the PangoLayout should be wrapped */
604 width_max = priv->is_timed ? HILDON_BANNER_LABEL_MAX_TIMED
605 : HILDON_BANNER_LABEL_MAX_PROGRESS;
607 if (width_text >= width_max) {
608 /* explicitly request maximum size to force wrapping */
609 PangoRectangle logical;
611 pango_layout_set_width (layout, width_max * PANGO_SCALE);
612 pango_layout_get_extents (layout, NULL, &logical);
614 width = PANGO_PIXELS (logical.width);
617 /* use fixed width when wrapping or natural one otherwise */
618 gtk_widget_set_size_request (GTK_WIDGET (label), width, -1);
623 hildon_banner_check_position (GtkWidget *widget)
628 force_to_wrap_truncated (HILDON_BANNER(widget)); /* see N#27000 and G#329646 */
630 gtk_widget_size_request (widget, &req);
637 x = gdk_screen_width() - HILDON_BANNER_WINDOW_X - req.width;
638 y = check_fullscreen_state (get_current_app_window ()) ?
639 HILDON_BANNER_WINDOW_FULLSCREEN_Y : HILDON_BANNER_WINDOW_Y;
641 gtk_window_move (GTK_WINDOW (widget), x, y);
645 hildon_banner_realize (GtkWidget *widget)
647 /* We let the parent to init widget->window before we need it */
648 if (GTK_WIDGET_CLASS (parent_class)->realize)
649 GTK_WIDGET_CLASS (parent_class)->realize (widget);
651 /* We use special hint to turn the banner into information notification. */
652 gdk_window_set_type_hint (widget->window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);
654 hildon_banner_check_position (widget);
658 hildon_banner_class_init (HildonBannerClass *klass)
660 GObjectClass *object_class;
661 GtkWidgetClass *widget_class;
663 object_class = G_OBJECT_CLASS (klass);
664 widget_class = GTK_WIDGET_CLASS (klass);
665 parent_class = g_type_class_peek_parent (klass);
667 /* Append private structure to class. This is more elegant than
668 on g_new based approach */
669 g_type_class_add_private (klass, sizeof (HildonBannerPrivate));
671 /* Override virtual methods */
672 object_class->constructor = hildon_banner_constructor;
673 object_class->finalize = hildon_banner_finalize;
674 object_class->set_property = hildon_banner_set_property;
675 object_class->get_property = hildon_banner_get_property;
676 GTK_OBJECT_CLASS (klass)->destroy = hildon_banner_destroy;
677 widget_class->map_event = hildon_banner_map_event;
678 widget_class->realize = hildon_banner_realize;
680 /* Install properties.
681 We need construct properties for singleton purposes */
684 * HildonBanner:parent-window:
686 * The window for which the banner will be singleton.
689 g_object_class_install_property (object_class, PROP_PARENT_WINDOW,
690 g_param_spec_object ("parent-window",
692 "The window for which the banner will be singleton",
693 GTK_TYPE_WINDOW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
696 * HildonBanner:is-timed:
698 * Whether the banner is timed and goes away automatically.
701 g_object_class_install_property (object_class, PROP_IS_TIMED,
702 g_param_spec_boolean ("is-timed",
704 "Whether or not the notification goes away automatically "
705 "after the specified time has passed",
706 FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
709 * HildonBanner:timeout:
711 * The time before making the banner banner go away. This needs
712 * to be adjusted before the banner is mapped to the screen.
715 g_object_class_install_property (object_class, PROP_TIMEOUT,
716 g_param_spec_uint ("timeout",
718 "The time before making the banner banner go away",
721 HILDON_BANNER_DEFAULT_TIMEOUT,
722 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
726 hildon_banner_init (HildonBanner *self)
728 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
733 /* Initialize the common layout inside banner */
734 priv->layout = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
736 priv->label = g_object_new (GTK_TYPE_LABEL, NULL);
737 gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
739 gtk_container_set_border_width (GTK_CONTAINER (priv->layout), HILDON_MARGIN_DEFAULT);
740 gtk_container_add (GTK_CONTAINER (self), priv->layout);
741 gtk_box_pack_start (GTK_BOX (priv->layout), priv->label, TRUE, TRUE, 0);
743 gtk_window_set_accept_focus (GTK_WINDOW (self), FALSE);
746 /* Makes sure that icon/progress item contains the desired type
747 of item. If possible, tries to avoid creating a new widget but
748 reuses the existing one */
750 hildon_banner_ensure_child (HildonBanner *self,
751 GtkWidget *user_widget,
754 const gchar *first_property,
759 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
763 widget = priv->main_item;
764 va_start (args, first_property);
766 /* Reuse existing widget if possible */
767 if (! user_widget && G_TYPE_CHECK_INSTANCE_TYPE (widget, type))
769 g_object_set_valist (G_OBJECT (widget), first_property, args);
773 /* We have to abandon old content widget */
775 gtk_container_remove (GTK_CONTAINER (priv->layout), widget);
777 /* Use user provided widget or create a new one */
778 priv->main_item = widget = user_widget ?
779 user_widget : GTK_WIDGET (g_object_new_valist(type, first_property, args));
780 gtk_box_pack_start (GTK_BOX (priv->layout), widget, TRUE, TRUE, 0);
783 /* We make sure that the widget exists in desired position. Different
784 banners place this child widget to different places */
785 gtk_box_reorder_child (GTK_BOX (priv->layout), widget, pos);
789 /* Creates a new banner instance or uses an existing one */
791 hildon_banner_get_instance_for_widget (GtkWidget *widget,
796 window = widget ? gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW) : NULL;
797 return g_object_new (HILDON_TYPE_BANNER, "parent-window", window, "is-timed", timed, NULL);
801 * hildon_banner_show_information:
802 * @widget: the #GtkWidget that is the owner of the banner
803 * @icon_name: the name of icon to use. Can be %NULL for default icon
804 * @text: Text to display
806 * This function creates and displays an information banner that
807 * automatically goes away after certain time period. For each window
808 * in your application there can only be one timed banner, so if you
809 * spawn a new banner before the earlier one has timed out, the
810 * previous one will be replaced.
812 * Returns: The newly created banner
816 hildon_banner_show_information (GtkWidget *widget,
817 const gchar *icon_name,
820 HildonBanner *banner;
822 g_return_val_if_fail (icon_name == NULL || icon_name[0] != 0, NULL);
823 g_return_val_if_fail (text != NULL, NULL);
826 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
827 hildon_banner_ensure_child (banner, NULL, 0, GTK_TYPE_IMAGE,
828 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
829 "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
833 hildon_banner_set_text (banner, text);
834 hildon_banner_bind_label_style (banner, NULL);
836 /* Show the banner, since caller cannot do that */
837 gtk_widget_show_all (GTK_WIDGET (banner));
839 return (GtkWidget *) banner;
843 * hildon_banner_show_informationf:
844 * @widget: the #GtkWidget that is the owner of the banner
845 * @icon_name: the name of icon to use. Can be %NULL for default icon
846 * @format: a printf-like format string
847 * @Varargs: arguments for the format string
849 * A helper function for #hildon_banner_show_information with
852 * Returns: the newly created banner
855 hildon_banner_show_informationf (GtkWidget *widget,
856 const gchar *icon_name,
860 g_return_val_if_fail (format != NULL, NULL);
866 va_start (args, format);
867 message = g_strdup_vprintf (format, args);
870 banner = hildon_banner_show_information (widget, icon_name, message);
878 * hildon_banner_show_information_with_markup:
879 * @widget: the #GtkWidget that wants to display banner
880 * @icon_name: the name of icon to use. Can be %NULL for default icon.
881 * @markup: a markup string to display (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
883 * This function creates and displays an information banner that
884 * automatically goes away after certain time period. For each window
885 * in your application there can only be one timed banner, so if you
886 * spawn a new banner before the earlier one has timed out, the
887 * previous one will be replaced.
889 * Returns: the newly created banner
893 hildon_banner_show_information_with_markup (GtkWidget *widget,
894 const gchar *icon_name,
897 HildonBanner *banner;
899 g_return_val_if_fail (icon_name == NULL || icon_name[0] != 0, NULL);
900 g_return_val_if_fail (markup != NULL, NULL);
903 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
905 hildon_banner_ensure_child (banner, NULL, 0, GTK_TYPE_IMAGE,
906 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
907 "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
911 hildon_banner_set_markup (banner, markup);
912 hildon_banner_bind_label_style (banner, NULL);
914 /* Show the banner, since caller cannot do that */
915 gtk_widget_show_all (GTK_WIDGET (banner));
917 return (GtkWidget *) banner;
921 * hildon_banner_show_animation:
922 * @widget: the #GtkWidget that wants to display banner
923 * @animation_name: The progress animation to use. You usually can just
924 * pass %NULL for the default animation.
925 * @text: the text to display.
927 * Shows an animated progress notification. It's recommended not to try
928 * to show more than one progress notification at a time, since
929 * they will appear on top of each other. You can use progress
930 * notifications with timed banners. In this case the banners are
931 * located so that you can somehow see both.
933 * Please note that banners are destroyed automatically once the
934 * window they are attached to is closed. The pointer that you
935 * receive with this function do not contain additional references,
936 * so it can become invalid without warning (this is true for
937 * all toplevel windows in gtk). To make sure that the banner do not disapear
938 * automatically, you can separately ref the return value (this
939 * doesn't prevent the banner from disappearing, but the object it just
940 * not finalized). In this case you have to call both #gtk_widget_destroy
941 * followed by #g_object_unref (in this order).
943 * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
944 * once you are done with the banner.
948 hildon_banner_show_animation (GtkWidget *widget,
949 const gchar *animation_name,
952 HildonBanner *banner;
955 GtkWidget *image_widget;
956 const gchar *filename;
958 g_return_val_if_fail (animation_name == NULL || animation_name[0] != 0, NULL);
959 g_return_val_if_fail (text != NULL, NULL);
961 /* Find out which animation to use */
962 theme = gtk_icon_theme_get_default ();
963 info = gtk_icon_theme_lookup_icon (theme, animation_name ? /* FIXME: consider using: gtk_icon_theme_load_icon() */
964 animation_name : HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION,
965 HILDON_ICON_SIZE_NOTE, 0);
967 /* Try to load animation. One could try to optimize this
968 to avoid loading the default animation during each call */
970 filename = gtk_icon_info_get_filename (info);
971 image_widget = gtk_image_new_from_file (filename);
972 gtk_icon_info_free (info);
974 g_warning ("Icon theme lookup for icon failed!");
979 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
980 hildon_banner_ensure_child (banner, image_widget, 0,
981 GTK_TYPE_IMAGE, "yalign", 0.0, NULL);
983 hildon_banner_set_text (banner, text);
984 hildon_banner_bind_label_style (banner, NULL);
987 gtk_widget_show_all (GTK_WIDGET (banner));
989 return (GtkWidget *) banner;
993 * hildon_banner_show_progress:
994 * @widget: the #GtkWidget that wants to display banner
995 * @bar: Progressbar to use. You usually can just pass %NULL, unless
996 * you want somehow customized progress bar.
997 * @text: text to display.
999 * Shows progress notification. See #hildon_banner_show_animation
1000 * for more information.
1002 * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
1003 * once you are done with the banner.
1007 hildon_banner_show_progress (GtkWidget *widget,
1008 GtkProgressBar *bar,
1011 HildonBanner *banner;
1012 HildonBannerPrivate *priv;
1014 g_return_val_if_fail (bar == NULL || GTK_IS_PROGRESS_BAR (bar), NULL);
1015 g_return_val_if_fail (text != NULL, NULL);
1018 /* Prepare banner */
1019 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
1020 priv = HILDON_BANNER_GET_PRIVATE (banner);
1022 hildon_banner_ensure_child (banner, (GtkWidget *) bar, -1, GTK_TYPE_PROGRESS_BAR, NULL);
1024 gtk_widget_set_size_request (priv->main_item,
1025 HILDON_BANNER_PROGRESS_WIDTH, -1);
1027 hildon_banner_set_text (banner, text);
1028 hildon_banner_bind_label_style (banner, NULL);
1030 /* Show the banner */
1031 gtk_widget_show_all (GTK_WIDGET (banner));
1033 return GTK_WIDGET (banner);
1037 * hildon_banner_set_text:
1038 * @self: a #HildonBanner widget
1039 * @text: a new text to display in banner
1041 * Sets the text that is displayed in the banner.
1045 hildon_banner_set_text (HildonBanner *self,
1049 HildonBannerPrivate *priv;
1050 const gchar *existing_text;
1052 g_return_if_fail (HILDON_IS_BANNER (self));
1054 priv = HILDON_BANNER_GET_PRIVATE (self);
1057 label = GTK_LABEL (priv->label);
1058 existing_text = gtk_label_get_text (label);
1060 if (existing_text != NULL &&
1062 strcmp (existing_text, text) != 0)
1063 gtk_label_set_text (label, text);
1065 hildon_banner_check_position (GTK_WIDGET (self));
1069 * hildon_banner_set_markup:
1070 * @self: a #HildonBanner widget
1071 * @markup: a new text with Pango markup to display in the banner
1073 * Sets the text with markup that is displayed in the banner.
1077 hildon_banner_set_markup (HildonBanner *self,
1078 const gchar *markup)
1081 HildonBannerPrivate *priv;
1083 g_return_if_fail (HILDON_IS_BANNER (self));
1085 priv = HILDON_BANNER_GET_PRIVATE (self);
1088 label = GTK_LABEL (priv->label);
1089 gtk_label_set_markup (label, markup);
1091 hildon_banner_check_position (GTK_WIDGET(self));
1095 * hildon_banner_set_fraction:
1096 * @self: a #HildonBanner widget
1097 * @fraction: #gdouble
1099 * The fraction is the completion of progressbar,
1100 * the scale is from 0.0 to 1.0.
1101 * Sets the amount of fraction the progressbar has.
1105 hildon_banner_set_fraction (HildonBanner *self,
1108 HildonBannerPrivate *priv;
1110 g_return_if_fail (HILDON_IS_BANNER (self));
1111 priv = HILDON_BANNER_GET_PRIVATE (self);
1114 g_return_if_fail (GTK_IS_PROGRESS_BAR (priv->main_item));
1115 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->main_item), fraction);
1119 * hildon_banner_set_timeout:
1120 * @self: a #HildonBanner widget
1121 * @timeout: timeout to set in miliseconds.
1123 * Sets the timeout on the banner. After the given amount of miliseconds
1124 * has elapsed the banner will go away. Note that settings this only makes
1125 * sense on the banners that are timed and that have not been yet displayed
1130 hildon_banner_set_timeout (HildonBanner *self,
1133 HildonBannerPrivate *priv;
1135 g_return_if_fail (HILDON_IS_BANNER (self));
1136 priv = HILDON_BANNER_GET_PRIVATE (self);
1139 priv->timeout = timeout;
1143 * hildon_banner_set_icon:
1144 * @self: a #HildonBanner widget
1145 * @icon_name: the name of icon to use. Can be %NULL for default icon
1147 * Sets the icon to be used in the banner.
1151 hildon_banner_set_icon (HildonBanner *self,
1152 const gchar *icon_name)
1154 HildonBannerPrivate *priv;
1156 g_return_if_fail (HILDON_IS_BANNER (self));
1157 priv = HILDON_BANNER_GET_PRIVATE (self);
1160 hildon_banner_ensure_child (self, NULL, 0, GTK_TYPE_IMAGE,
1161 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
1162 "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
1168 * hildon_banner_set_icon_from_file:
1169 * @self: a #HildonBanner widget
1170 * @icon_file: the filename of icon to use. Can be %NULL for default icon
1172 * Sets the icon from its filename to be used in the banner.
1176 hildon_banner_set_icon_from_file (HildonBanner *self,
1177 const gchar *icon_file)
1179 HildonBannerPrivate *priv;
1181 g_return_if_fail (HILDON_IS_BANNER (self));
1182 priv = HILDON_BANNER_GET_PRIVATE (self);
1185 if (icon_file != NULL) {
1186 hildon_banner_ensure_child (self, NULL, 0, GTK_TYPE_IMAGE,
1187 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
1192 hildon_banner_ensure_child (self, NULL, 0, GTK_TYPE_IMAGE,
1193 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
1194 "icon-name", HILDON_BANNER_DEFAULT_ICON,