2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006 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
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_map_event (GtkWidget *widget,
138 force_to_wrap_truncated (HildonBanner *banner);
141 hildon_banner_check_position (GtkWidget *widget);
144 hildon_banner_realize (GtkWidget *widget);
147 hildon_banner_class_init (HildonBannerClass *klass);
150 hildon_banner_init (HildonBanner *self);
153 hildon_banner_ensure_child (HildonBanner *self,
154 GtkWidget *user_widget,
157 const gchar *first_property,
161 hildon_banner_get_instance_for_widget (GtkWidget *widget,
164 static GtkWindowClass* parent_class = NULL;
167 * hildon_banner_get_type:
169 * Initializes and returns the type of a hildon banner.
171 * @Returns: GType of #HildonBanner
174 hildon_banner_get_type (void)
176 static GType banner_type = 0;
180 static const GTypeInfo banner_info = {
181 sizeof (HildonBannerClass),
182 NULL, /* base_init */
183 NULL, /* base_finalize */
184 (GClassInitFunc) hildon_banner_class_init,
185 NULL, /* class_finalize */
186 NULL, /* class_data */
187 sizeof (HildonBanner),
189 (GInstanceInitFunc) hildon_banner_init,
191 banner_type = g_type_register_static (GTK_TYPE_WINDOW,
192 "HildonBanner", &banner_info, 0 );
197 /* copy/paste from old infoprint implementation: Use matchbox
198 properties to find the topmost application window */
200 get_current_app_window (void)
207 Atom atom_current_app_window = gdk_x11_get_xatom_by_name ("_MB_CURRENT_APP_WINDOW");
209 Window win_result = None;
210 guchar *data_return = NULL;
212 status = XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW (),
213 atom_current_app_window, 0L, 16L,
214 0, XA_WINDOW, &realType, &format,
218 if (status == Success && realType == XA_WINDOW && format == 32 && n == 1 && data_return != NULL)
220 win_result = ((Window*) data_return)[0];
229 /* Checks if a window is in fullscreen state or not. This
230 information is needed when banners are positioned on screen.
231 copy/paste from old infoprint implementation. */
233 check_fullscreen_state (Window window)
237 int format, status, i;
238 guchar *data_return = NULL;
241 Atom atom_window_state = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
242 Atom atom_fullscreen = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_FULLSCREEN");
247 /* in some cases XGetWindowProperty seems to generate BadWindow,
248 so at the moment this function does not always work perfectly */
249 gdk_error_trap_push ();
250 status = XGetWindowProperty (GDK_DISPLAY (), window,
251 atom_window_state, 0L, 1000000L,
252 0, XA_ATOM, &realType, &format,
253 &n, &extra, &data_return);
257 if (gdk_error_trap_pop ())
260 if (status == Success && realType == XA_ATOM && format == 32 && n > 0)
262 for (i=0; i < n; i++)
263 if (((Atom*)data_return)[i] && ((Atom*)data_return)[i] == atom_fullscreen)
265 if (data_return) XFree (data_return);
277 hildon_banner_timed_quark (void)
279 static GQuark quark = 0;
281 if (G_UNLIKELY(quark == 0))
282 quark = g_quark_from_static_string ("hildon-banner-timed");
287 /* Set the label name to make the correct rc-style attached into it */
289 hildon_banner_bind_label_style (HildonBanner *self,
292 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
295 GtkWidget *label = priv->label;
297 /* Too bad that we cannot really reset the widget name */
298 gtk_widget_set_name (label, name ? name : g_type_name (GTK_WIDGET_TYPE (label)));
301 /* In timeout function we automatically destroy timed banners */
303 hildon_banner_timeout (gpointer data)
307 gboolean continue_timeout = FALSE;
309 GDK_THREADS_ENTER ();
311 g_assert (HILDON_IS_BANNER (data));
313 widget = GTK_WIDGET (data);
314 g_object_ref (widget);
316 /* If the banner is currently visible (it normally should),
317 we simulate clicking the close button of the window.
318 This allows applications to reuse the banner by prevent
320 if (GTK_WIDGET_DRAWABLE (widget))
322 event = gdk_event_new (GDK_DELETE);
323 event->any.window = g_object_ref (widget->window);
324 event->any.send_event = FALSE;
325 continue_timeout = gtk_widget_event (widget, event);
326 gdk_event_free (event);
329 if (! continue_timeout)
330 gtk_widget_destroy (widget);
332 g_object_unref (widget);
334 GDK_THREADS_LEAVE ();
336 return continue_timeout;
340 hildon_banner_clear_timeout (HildonBanner *self)
342 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
345 if (priv->timeout_id != 0) {
346 g_source_remove (priv->timeout_id);
347 priv->timeout_id = 0;
355 hildon_banner_ensure_timeout (HildonBanner *self)
357 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
360 if (priv->timeout_id == 0 && priv->is_timed && priv->timeout > 0)
361 priv->timeout_id = g_timeout_add (priv->timeout,
362 hildon_banner_timeout, self);
366 hildon_banner_set_property (GObject *object,
373 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
379 priv->timeout = g_value_get_uint (value);
383 priv->is_timed = g_value_get_boolean (value);
385 /* Timed and progress notifications have different
386 pixel size values for text.
387 We force to use requisition size for timed banners
388 in order to avoid resize problems when reusing the
389 window (see bug #24339) */
390 geom.max_width = priv->is_timed ? -1
391 : HILDON_BANNER_LABEL_MAX_PROGRESS;
392 geom.max_height = -1;
393 gtk_window_set_geometry_hints (GTK_WINDOW (object),
394 priv->label, &geom, GDK_HINT_MAX_SIZE);
397 case PROP_PARENT_WINDOW:
398 window = g_value_get_object (value);
400 gtk_window_set_transient_for (GTK_WINDOW (object), (GtkWindow *) window);
401 priv->parent = (GtkWindow *) window;
404 gtk_window_set_destroy_with_parent (GTK_WINDOW (object), TRUE);
409 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
415 hildon_banner_get_property (GObject *object,
420 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
426 g_value_set_uint (value, priv->timeout);
430 g_value_set_boolean (value, priv->is_timed);
433 case PROP_PARENT_WINDOW:
434 g_value_set_object (value, gtk_window_get_transient_for (GTK_WINDOW (object)));
438 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
444 hildon_banner_destroy (GtkObject *object)
446 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object);
450 GObject *parent_window = (GObject *) priv->parent;
452 g_assert (HILDON_IS_BANNER (object));
453 self = HILDON_BANNER (object);
455 /* Drop possible global pointer. That can hold reference to us */
456 if ((gpointer) object == (gpointer) global_timed_banner) {
457 global_timed_banner = NULL;
458 g_object_unref (object);
461 /* Remove the data from parent window for timed banners. Those hold reference */
462 if (priv->is_timed && parent_window != NULL) {
463 g_object_set_qdata (parent_window, hildon_banner_timed_quark (), NULL);
466 (void) hildon_banner_clear_timeout (self);
468 if (GTK_OBJECT_CLASS (parent_class)->destroy)
469 GTK_OBJECT_CLASS (parent_class)->destroy (object);
472 /* Search a previous banner instance */
474 hildon_banner_real_get_instance (GObject *window,
478 /* If we have a parent window, the previous instance is stored there */
480 return g_object_get_qdata(window, hildon_banner_timed_quark ());
483 /* System notification instance is stored into global pointer */
484 return (GObject *) global_timed_banner;
487 /* Non-timed banners are normal (non-singleton) objects */
491 /* By overriding constructor we force timed banners to be
492 singletons for each window */
494 hildon_banner_constructor (GType type,
495 guint n_construct_params,
496 GObjectConstructParam *construct_params)
498 GObject *banner, *window = NULL;
499 gboolean timed = FALSE;
502 /* Search banner type information from parameters in order
503 to locate the possible previous banner instance. */
504 for (i = 0; i < n_construct_params; i++)
506 if (strcmp(construct_params[i].pspec->name, "parent-window") == 0)
507 window = g_value_get_object (construct_params[i].value);
508 else if (strcmp(construct_params[i].pspec->name, "is-timed") == 0)
509 timed = g_value_get_boolean (construct_params[i].value);
512 /* Try to get a previous instance if such exists */
513 banner = hildon_banner_real_get_instance (window, timed);
516 /* We have to create a new banner */
517 banner = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_params, construct_params);
519 /* Store the newly created singleton instance either into parent
520 window data or into global variables. */
523 g_object_set_qdata_full (G_OBJECT (window), hildon_banner_timed_quark (),
524 g_object_ref (banner), g_object_unref);
526 g_assert (global_timed_banner == NULL);
527 global_timed_banner = g_object_ref (banner);
532 /* FIXME: This is a hack! We have to manually freeze
533 notifications. This is normally done by g_object_init, but we
534 are not going to call that. g_object_newv will otherwise give
535 a critical like this:
537 GLIB CRITICAL ** GLib-GObject - g_object_notify_queue_thaw:
538 assertion `nqueue->freeze_count > 0' failed */
540 g_object_freeze_notify (banner);
543 /* We restart possible timeouts for each new timed banner request */
544 if (timed && hildon_banner_clear_timeout (HILDON_BANNER (banner)))
545 hildon_banner_ensure_timeout (HILDON_BANNER(banner));
550 /* We start the timer for timed notifications after the window appears on screen */
552 hildon_banner_map_event (GtkWidget *widget,
555 gboolean result = FALSE;
557 if (GTK_WIDGET_CLASS (parent_class)->map_event)
558 result = GTK_WIDGET_CLASS (parent_class)->map_event (widget, event);
560 hildon_banner_ensure_timeout (HILDON_BANNER(widget));
566 /* force to wrap truncated label by setting explicit size request
567 * see N#27000 and G#329646 */
569 force_to_wrap_truncated (HildonBanner *banner)
573 int width_text, width_max;
575 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (banner);
578 label = GTK_LABEL (priv->label);
580 layout = gtk_label_get_layout (label);
581 width_text = PANGO_PIXELS(pango_layout_get_width (layout));
582 /* = width to which the lines of the PangoLayout should be wrapped */
584 width_max = priv->is_timed ? HILDON_BANNER_LABEL_MAX_TIMED
585 : HILDON_BANNER_LABEL_MAX_PROGRESS;
587 if (width_text >= width_max) {
588 /* explicitly request maximum size to force wrapping */
589 PangoRectangle logical;
591 pango_layout_set_width (layout, width_max * PANGO_SCALE);
592 pango_layout_get_extents (layout, NULL, &logical);
594 width = PANGO_PIXELS (logical.width);
597 /* use fixed width when wrapping or natural one otherwise */
598 gtk_widget_set_size_request (GTK_WIDGET (label), width, -1);
603 hildon_banner_check_position (GtkWidget *widget)
608 force_to_wrap_truncated (HILDON_BANNER(widget)); /* see N#27000 and G#329646 */
610 gtk_widget_size_request (widget, &req);
617 x = gdk_screen_width() - HILDON_BANNER_WINDOW_X - req.width;
618 y = check_fullscreen_state (get_current_app_window ()) ?
619 HILDON_BANNER_WINDOW_FULLSCREEN_Y : HILDON_BANNER_WINDOW_Y;
621 gtk_window_move (GTK_WINDOW (widget), x, y);
625 hildon_banner_realize (GtkWidget *widget)
627 /* We let the parent to init widget->window before we need it */
628 if (GTK_WIDGET_CLASS (parent_class)->realize)
629 GTK_WIDGET_CLASS (parent_class)->realize (widget);
631 /* We use special hint to turn the banner into information notification. */
632 gdk_window_set_type_hint (widget->window, GDK_WINDOW_TYPE_HINT_MESSAGE);
634 hildon_banner_check_position (widget);
638 hildon_banner_class_init (HildonBannerClass *klass)
640 GObjectClass *object_class;
641 GtkWidgetClass *widget_class;
643 object_class = G_OBJECT_CLASS (klass);
644 widget_class = GTK_WIDGET_CLASS (klass);
645 parent_class = g_type_class_peek_parent (klass);
647 /* Append private structure to class. This is more elegant than
648 on g_new based approach */
649 g_type_class_add_private (klass, sizeof (HildonBannerPrivate));
651 /* Override virtual methods */
652 object_class->constructor = hildon_banner_constructor;
653 object_class->set_property = hildon_banner_set_property;
654 object_class->get_property = hildon_banner_get_property;
655 GTK_OBJECT_CLASS (klass)->destroy = hildon_banner_destroy;
656 widget_class->map_event = hildon_banner_map_event;
657 widget_class->realize = hildon_banner_realize;
659 /* Install properties.
660 We need construct properties for singleton purposes */
663 * HildonBanner:parent-window:
665 * The window for which the banner will be singleton.
668 g_object_class_install_property (object_class, PROP_PARENT_WINDOW,
669 g_param_spec_object ("parent-window",
671 "The window for which the banner will be singleton",
672 GTK_TYPE_WINDOW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
675 * HildonBanner:is-timed:
677 * Whether the banner is timed and goes away automatically.
680 g_object_class_install_property (object_class, PROP_IS_TIMED,
681 g_param_spec_boolean ("is-timed",
683 "Whether or not the notification goes away automatically "
684 "after the specified time has passed",
685 FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
688 * HildonBanner:timeout:
690 * The time before making the banner banner go away. This needs
691 * to be adjusted before the banner is mapped to the screen.
694 g_object_class_install_property (object_class, PROP_TIMEOUT,
695 g_param_spec_uint ("timeout",
697 "The time before making the banner banner go away",
700 HILDON_BANNER_DEFAULT_TIMEOUT,
701 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
705 hildon_banner_init (HildonBanner *self)
707 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
712 /* Initialize the common layout inside banner */
713 priv->layout = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
715 priv->label = g_object_new (GTK_TYPE_LABEL, NULL);
716 gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
718 gtk_container_set_border_width (GTK_CONTAINER (priv->layout), HILDON_MARGIN_DEFAULT);
719 gtk_container_add (GTK_CONTAINER (self), priv->layout);
720 gtk_box_pack_start (GTK_BOX (priv->layout), priv->label, TRUE, TRUE, 0);
722 gtk_window_set_accept_focus (GTK_WINDOW (self), FALSE);
725 /* Makes sure that icon/progress item contains the desired type
726 of item. If possible, tries to avoid creating a new widget but
727 reuses the existing one */
729 hildon_banner_ensure_child (HildonBanner *self,
730 GtkWidget *user_widget,
733 const gchar *first_property,
738 HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (self);
742 widget = priv->main_item;
743 va_start (args, first_property);
745 /* Reuse existing widget if possible */
746 if (! user_widget && G_TYPE_CHECK_INSTANCE_TYPE (widget, type))
748 g_object_set_valist (G_OBJECT (widget), first_property, args);
752 /* We have to abandon old content widget */
754 gtk_container_remove (GTK_CONTAINER (priv->layout), widget);
756 /* Use user provided widget or create a new one */
757 priv->main_item = widget = user_widget ?
758 user_widget : GTK_WIDGET (g_object_new_valist(type, first_property, args));
759 gtk_box_pack_start (GTK_BOX (priv->layout), widget, TRUE, TRUE, 0);
762 /* We make sure that the widget exists in desired position. Different
763 banners place this child widget to different places */
764 gtk_box_reorder_child (GTK_BOX (priv->layout), widget, pos);
768 /* Creates a new banner instance or uses an existing one */
770 hildon_banner_get_instance_for_widget (GtkWidget *widget,
775 window = widget ? gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW) : NULL;
776 return g_object_new (HILDON_TYPE_BANNER, "parent-window", window, "is-timed", timed, NULL);
780 * hildon_banner_show_information:
781 * @widget: the #GtkWidget that is the owner of the banner
782 * @icon_name: the name of icon to use. Can be %NULL for default icon
783 * @text: Text to display
785 * This function creates and displays an information banner that
786 * automatically goes away after certain time period. For each window
787 * in your application there can only be one timed banner, so if you
788 * spawn a new banner before the earlier one has timed out, the
789 * previous one will be replaced.
791 * Returns: The newly created banner
795 hildon_banner_show_information (GtkWidget *widget,
796 const gchar *icon_name,
799 HildonBanner *banner;
801 g_return_val_if_fail (icon_name == NULL || icon_name[0] != 0, NULL);
802 g_return_val_if_fail (text != NULL, NULL);
805 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
806 hildon_banner_ensure_child (banner, NULL, 0, GTK_TYPE_IMAGE,
807 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
808 "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
812 hildon_banner_set_text (banner, text);
813 hildon_banner_bind_label_style (banner, NULL);
815 /* Show the banner, since caller cannot do that */
816 gtk_widget_show_all (GTK_WIDGET (banner));
818 return (GtkWidget *) banner;
822 * hildon_banner_show_informationf:
823 * @widget: the #GtkWidget that is the owner of the banner
824 * @icon_name: the name of icon to use. Can be %NULL for default icon
825 * @format: a printf-like format string
826 * @Varargs: arguments for the format string
828 * A helper function for #hildon_banner_show_information with
831 * Returns: the newly created banner
834 hildon_banner_show_informationf (GtkWidget *widget,
835 const gchar *icon_name,
839 g_return_val_if_fail (format != NULL, NULL);
845 va_start (args, format);
846 message = g_strdup_vprintf (format, args);
849 banner = hildon_banner_show_information (widget, icon_name, message);
857 * hildon_banner_show_information_with_markup:
858 * @widget: the #GtkWidget that wants to display banner
859 * @icon_name: the name of icon to use. Can be %NULL for default icon.
860 * @markup: a markup string to display (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
862 * This function creates and displays an information banner that
863 * automatically goes away after certain time period. For each window
864 * in your application there can only be one timed banner, so if you
865 * spawn a new banner before the earlier one has timed out, the
866 * previous one will be replaced.
868 * Returns: the newly created banner
872 hildon_banner_show_information_with_markup (GtkWidget *widget,
873 const gchar *icon_name,
876 HildonBanner *banner;
878 g_return_val_if_fail (icon_name == NULL || icon_name[0] != 0, NULL);
879 g_return_val_if_fail (markup != NULL, NULL);
882 banner = hildon_banner_get_instance_for_widget (widget, TRUE);
884 hildon_banner_ensure_child (banner, NULL, 0, GTK_TYPE_IMAGE,
885 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
886 "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
890 hildon_banner_set_markup (banner, markup);
891 hildon_banner_bind_label_style (banner, NULL);
893 /* Show the banner, since caller cannot do that */
894 gtk_widget_show_all (GTK_WIDGET (banner));
896 return (GtkWidget *) banner;
900 * hildon_banner_show_animation:
901 * @widget: the #GtkWidget that wants to display banner
902 * @animation_name: The progress animation to use. You usually can just
903 * pass %NULL for the default animation.
904 * @text: the text to display.
906 * Shows an animated progress notification. It's recommended not to try
907 * to show more than one progress notification at a time, since
908 * they will appear on top of each other. You can use progress
909 * notifications with timed banners. In this case the banners are
910 * located so that you can somehow see both.
912 * Please note that banners are destroyed automatically once the
913 * window they are attached to is closed. The pointer that you
914 * receive with this function do not contain additional references,
915 * so it can become invalid without warning (this is true for
916 * all toplevel windows in gtk). To make sure that the banner do not disapear
917 * automatically, you can separately ref the return value (this
918 * doesn't prevent the banner from disappearing, but the object it just
919 * not finalized). In this case you have to call both #gtk_widget_destroy
920 * followed by #g_object_unref (in this order).
922 * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
923 * once you are done with the banner.
927 hildon_banner_show_animation (GtkWidget *widget,
928 const gchar *animation_name,
931 HildonBanner *banner;
934 GtkWidget *image_widget;
935 const gchar *filename;
937 g_return_val_if_fail (animation_name == NULL || animation_name[0] != 0, NULL);
938 g_return_val_if_fail (text != NULL, NULL);
940 /* Find out which animation to use */
941 theme = gtk_icon_theme_get_default ();
942 info = gtk_icon_theme_lookup_icon (theme, animation_name ? /* FIXME: consider using: gtk_icon_theme_load_icon() */
943 animation_name : HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION,
944 HILDON_ICON_SIZE_NOTE, 0);
946 /* Try to load animation. One could try to optimize this
947 to avoid loading the default animation during each call */
949 filename = gtk_icon_info_get_filename (info);
950 image_widget = gtk_image_new_from_file (filename);
951 gtk_icon_info_free (info);
953 g_warning ("Icon theme lookup for icon failed!");
958 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
959 hildon_banner_ensure_child (banner, image_widget, 0,
960 GTK_TYPE_IMAGE, "yalign", 0.0, NULL);
962 hildon_banner_set_text (banner, text);
963 hildon_banner_bind_label_style (banner, NULL);
966 gtk_widget_show_all (GTK_WIDGET (banner));
968 return (GtkWidget *) banner;
972 * hildon_banner_show_progress:
973 * @widget: the #GtkWidget that wants to display banner
974 * @bar: Progressbar to use. You usually can just pass %NULL, unless
975 * you want somehow customized progress bar.
976 * @text: text to display.
978 * Shows progress notification. See #hildon_banner_show_animation
979 * for more information.
981 * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
982 * once you are done with the banner.
986 hildon_banner_show_progress (GtkWidget *widget,
990 HildonBanner *banner;
991 HildonBannerPrivate *priv;
993 g_return_val_if_fail (bar == NULL || GTK_IS_PROGRESS_BAR (bar), NULL);
994 g_return_val_if_fail (text != NULL, NULL);
998 banner = hildon_banner_get_instance_for_widget (widget, FALSE);
999 priv = HILDON_BANNER_GET_PRIVATE (banner);
1001 hildon_banner_ensure_child (banner, (GtkWidget *) bar, -1, GTK_TYPE_PROGRESS_BAR, NULL);
1003 gtk_widget_set_size_request (priv->main_item,
1004 HILDON_BANNER_PROGRESS_WIDTH, -1);
1006 hildon_banner_set_text (banner, text);
1007 hildon_banner_bind_label_style (banner, NULL);
1009 /* Show the banner */
1010 gtk_widget_show_all (GTK_WIDGET (banner));
1012 return GTK_WIDGET (banner);
1016 * hildon_banner_set_text:
1017 * @self: a #HildonBanner widget
1018 * @text: a new text to display in banner
1020 * Sets the text that is displayed in the banner.
1024 hildon_banner_set_text (HildonBanner *self,
1028 HildonBannerPrivate *priv;
1030 g_return_if_fail (HILDON_IS_BANNER (self));
1032 priv = HILDON_BANNER_GET_PRIVATE (self);
1035 label = GTK_LABEL (priv->label);
1036 gtk_label_set_text (label, text);
1038 hildon_banner_check_position (GTK_WIDGET (self));
1042 * hildon_banner_set_markup:
1043 * @self: a #HildonBanner widget
1044 * @markup: a new text with Pango markup to display in the banner
1046 * Sets the text with markup that is displayed in the banner.
1050 hildon_banner_set_markup (HildonBanner *self,
1051 const gchar *markup)
1054 HildonBannerPrivate *priv;
1056 g_return_if_fail (HILDON_IS_BANNER (self));
1058 priv = HILDON_BANNER_GET_PRIVATE (self);
1061 label = GTK_LABEL (priv->label);
1062 gtk_label_set_markup (label, markup);
1064 hildon_banner_check_position (GTK_WIDGET(self));
1068 * hildon_banner_set_fraction:
1069 * @self: a #HildonBanner widget
1070 * @fraction: #gdouble
1072 * The fraction is the completion of progressbar,
1073 * the scale is from 0.0 to 1.0.
1074 * Sets the amount of fraction the progressbar has.
1078 hildon_banner_set_fraction (HildonBanner *self,
1081 HildonBannerPrivate *priv;
1083 g_return_if_fail (HILDON_IS_BANNER (self));
1084 priv = HILDON_BANNER_GET_PRIVATE (self);
1087 g_return_if_fail (GTK_IS_PROGRESS_BAR (priv->main_item));
1088 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->main_item), fraction);
1092 * hildon_banner_set_timeout:
1093 * @self: a #HildonBanner widget
1094 * @timeout: timeout to set in miliseconds.
1096 * Sets the timeout on the banner. After the given amount of miliseconds
1097 * has elapsed the banner will go away. Note that settings this only makes
1098 * sense on the banners that are timed and that have not been yet displayed
1103 hildon_banner_set_timeout (HildonBanner *self,
1106 HildonBannerPrivate *priv;
1108 g_return_if_fail (HILDON_IS_BANNER (self));
1109 priv = HILDON_BANNER_GET_PRIVATE (self);
1112 priv->timeout = timeout;
1116 * hildon_banner_set_icon:
1117 * @self: a #HildonBanner widget
1118 * @icon_name: the name of icon to use. Can be %NULL for default icon
1120 * Sets the icon to be used in the banner.
1124 hildon_banner_set_icon (HildonBanner *self,
1125 const gchar *icon_name)
1127 HildonBannerPrivate *priv;
1129 g_return_if_fail (HILDON_IS_BANNER (self));
1130 priv = HILDON_BANNER_GET_PRIVATE (self);
1133 hildon_banner_ensure_child (self, NULL, 0, GTK_TYPE_IMAGE,
1134 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
1135 "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
1141 * hildon_banner_set_icon_from_file:
1142 * @self: a #HildonBanner widget
1143 * @icon_file: the filename of icon to use. Can be %NULL for default icon
1145 * Sets the icon from its filename to be used in the banner.
1149 hildon_banner_set_icon_from_file (HildonBanner *self,
1150 const gchar *icon_file)
1152 HildonBannerPrivate *priv;
1154 g_return_if_fail (HILDON_IS_BANNER (self));
1155 priv = HILDON_BANNER_GET_PRIVATE (self);
1158 if (icon_file != NULL) {
1159 hildon_banner_ensure_child (self, NULL, 0, GTK_TYPE_IMAGE,
1160 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
1165 hildon_banner_ensure_child (self, NULL, 0, GTK_TYPE_IMAGE,
1166 "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
1167 "icon-name", HILDON_BANNER_DEFAULT_ICON,