/* By overriding constructor we force timed banners to be singletons for each window */ static GObject* hildon_banner_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params) { GObject *banner, *window = NULL; gboolean timed = FALSE; guint i; /* Search banner type information from parameters in order to locate the possible previous banner instance. */ for (i = 0; i < n_construct_params; i++) { if (strcmp(construct_params[i].pspec->name, "parent-window") == 0) window = g_value_get_object (construct_params[i].value); else if (strcmp(construct_params[i].pspec->name, "is-timed") == 0) timed = g_value_get_boolean (construct_params[i].value); } /* Try to get a previous instance if such exists */ banner = hildon_banner_real_get_instance (window, timed); if (! banner) { /* We have to create a new banner */ banner = G_OBJECT_CLASS (hildon_banner_parent_class)->constructor (type, n_construct_params, construct_params); /* Store the newly created singleton instance either into parent window data or into global variables. */ if (timed) { if (window) { g_object_set_qdata_full (G_OBJECT (window), hildon_banner_timed_quark (), g_object_ref (banner), g_object_unref); } else { g_assert (global_timed_banner == NULL); global_timed_banner = g_object_ref (banner); } } } else { /* FIXME: This is a hack! We have to manually freeze notifications. This is normally done by g_object_init, but we are not going to call that. g_object_newv will otherwise give a critical like this: GLIB CRITICAL ** GLib-GObject - g_object_notify_queue_thaw: assertion `nqueue->freeze_count > 0' failed */ g_object_freeze_notify (banner); } /* We restart possible timeouts for each new timed banner request */ if (timed && hildon_banner_clear_timeout (HILDON_BANNER (banner))) hildon_banner_ensure_timeout (HILDON_BANNER(banner)); return banner; }
static void hildon_banner_destroy (GtkObject *object) { HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (object); g_assert (priv); HildonBanner *self; GObject *parent_window = (GObject *) priv->parent; g_assert (HILDON_IS_BANNER (object)); self = HILDON_BANNER (object); /* Drop possible global pointer. That can hold reference to us */ if ((gpointer) object == (gpointer) global_timed_banner) { global_timed_banner = NULL; g_object_unref (object); } /* Remove the data from parent window for timed banners. Those hold reference */ if (priv->is_timed && parent_window != NULL) { g_object_set_qdata (parent_window, hildon_banner_timed_quark (), NULL); } if (!priv->is_timed && priv->parent) { hildon_gtk_window_set_progress_indicator (priv->parent, 0); } (void) hildon_banner_clear_timeout (self); if (GTK_OBJECT_CLASS (hildon_banner_parent_class)->destroy) GTK_OBJECT_CLASS (hildon_banner_parent_class)->destroy (object); }
extern "C" void on_lock_info(GtkDasherControl *pDasherControl, gpointer pLockInfo, gpointer pUserData) { // TODO: signals are connected after the Dasher control is created, // which is too late to receive notification about intial training // etc. DasherLockInfo *pInfo = (DasherLockInfo *)pLockInfo; #ifndef WITH_MAEMO gtk_label_set_text(m_pLockMessage, pInfo->szMessage); gtk_progress_bar_set_fraction(m_pLockProgress, pInfo->iPercent / 100.0); if(pInfo->bLock) gtk_widget_show(GTK_WIDGET(m_pLockWindow)); else gtk_widget_hide(GTK_WIDGET(m_pLockWindow)); #else if(pInfo->bLock) { if(!m_pLockWindow) m_pLockWindow = hildon_banner_show_progress(NULL, NULL, pInfo->szMessage); hildon_banner_set_fraction(HILDON_BANNER(m_pLockWindow), pInfo->iPercent / 100.0); } else { if(m_pLockWindow) gtk_widget_destroy(GTK_WIDGET(m_pLockWindow)); m_pLockWindow = 0; } #endif // Keep the GTK interface responsive while(gtk_events_pending()) gtk_main_iteration(); }
END_TEST /* ----- Test case for show_progress -----*/ /** * Purpose: Check creation of new banner with progress bar with regular values. * Cases considered: * - Create new progress banner with standard progress bar and "" as text. * - Create new progress banner with NULL progress bar and TEST_STRING as text. */ START_TEST (test_show_progress_regular) { gchar * text=NULL; GtkProgressBar * progress_bar = NULL; HildonBanner * hildon_banner = NULL; progress_bar = GTK_PROGRESS_BAR(gtk_progress_bar_new()); /*Test 1: Create progress banner with TEST_STRING as text and basic progress_bar. */ text = TEST_STRING; hildon_banner = HILDON_BANNER(hildon_banner_show_progress(b_window,progress_bar,text)); fail_if(!HILDON_IS_BANNER(hildon_banner), "hildon-banner: hildon_banner_show_progress failed creating banner."); hildon_banner_set_text(hildon_banner,text); hildon_banner_set_fraction(hildon_banner,0.5); gtk_widget_destroy(GTK_WIDGET(hildon_banner)); hildon_banner = NULL; /*Test 2: Create progress banner with "" as text and NULL progress_bar. */ text = ""; hildon_banner = HILDON_BANNER(hildon_banner_show_progress(b_window,NULL,text)); fail_if(!HILDON_IS_BANNER(hildon_banner), "hildon-banner: hildon_banner_show_progress failed creating banner."); hildon_banner_set_text(hildon_banner,text); hildon_banner_set_fraction(hildon_banner,0.2); gtk_widget_destroy(GTK_WIDGET(hildon_banner)); }
static void screen_size_changed (GdkScreen *screen, GtkWindow *banner) { if (GTK_WIDGET_VISIBLE (banner)) { HildonBanner *hbanner = HILDON_BANNER (banner); hildon_banner_bind_style (hbanner); reshow_banner (hbanner); } }
/* We start the timer for timed notifications after the window appears on screen */ static gboolean hildon_banner_map_event (GtkWidget *widget, GdkEventAny *event) { gboolean result = FALSE; if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->map_event) result = GTK_WIDGET_CLASS (hildon_banner_parent_class)->map_event (widget, event); hildon_banner_ensure_timeout (HILDON_BANNER(widget)); return result; }
END_TEST /** * Purpose: Check creation of new banner with progress bar with invalid values * Cases considered: * - Create new progress banner with NULL text. * - Create new progress banner with NULL window. */ START_TEST (test_show_progress_invalid) { gchar * text=NULL; GtkProgressBar * progress_bar = NULL; HildonBanner * hildon_banner = NULL; progress_bar = GTK_PROGRESS_BAR(gtk_progress_bar_new()); /*Test 1: Create progress banner with TEST_STRING as text and basic progress_bar. */ text = TEST_STRING; hildon_banner = HILDON_BANNER(hildon_banner_show_progress(b_window,progress_bar,NULL)); /* NULL text avoid create correct banner. */ fail_if(HILDON_IS_BANNER(hildon_banner), "hildon-banner: hildon_banner_show_progress failed creating banner."); /*Test 2: Create progress banner with TEST_STRING as text, NULL progress_bar and NULL window */ text = TEST_STRING; hildon_banner = HILDON_BANNER(hildon_banner_show_progress(NULL,NULL,text)); fail_if(!HILDON_IS_BANNER(hildon_banner), "hildon-banner: hildon_banner_show_progress failed creating banner."); hildon_banner_set_text(hildon_banner,text); hildon_banner_set_fraction(hildon_banner,0.2); gtk_widget_destroy(GTK_WIDGET(hildon_banner)); }
END_TEST /** * Purpose: Check creation of new animation banner with invalid values * Cases considered: * - Create an animation banner with NULL text. * - Create an animation banner with NULL window. */ START_TEST (test_show_animation_invalid) { gchar * animation_name=NULL; gchar * text=NULL; HildonBanner * hildon_banner = NULL; /*Test 1: Create an animation banner with NULL text. */ hildon_banner = HILDON_BANNER(hildon_banner_show_animation(b_window,NULL,NULL)); fail_if(HILDON_IS_BANNER(hildon_banner), "hildon-banner: hildon_banner_show_animation failed creating banner."); hildon_banner = NULL; /*Test 2: Create an animation banner with NULL window. */ text=""; animation_name = "dummy"; hildon_banner = HILDON_BANNER(hildon_banner_show_animation(NULL,animation_name,text)); fail_if(!HILDON_IS_BANNER(hildon_banner), "hildon-banner: hildon_banner_show_animation failed creating banner."); hildon_banner_set_text(hildon_banner,text); gtk_widget_destroy(GTK_WIDGET(hildon_banner)); }
static void hildon_banner_realize (GtkWidget *widget) { GdkWindow *gdkwin; GdkScreen *screen; GdkAtom atom; guint32 portrait = 1; const gchar *notification_type = "_HILDON_NOTIFICATION_TYPE_BANNER"; HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (widget); g_assert (priv); /* We let the parent to init widget->window before we need it */ if (GTK_WIDGET_CLASS (hildon_banner_parent_class)->realize) GTK_WIDGET_CLASS (hildon_banner_parent_class)->realize (widget); /* We use special hint to turn the banner into information notification. */ gdk_window_set_type_hint (widget->window, GDK_WINDOW_TYPE_HINT_NOTIFICATION); gtk_window_set_transient_for (GTK_WINDOW (widget), (GtkWindow *) priv->parent); gdkwin = widget->window; /* Set the _HILDON_NOTIFICATION_TYPE property so Matchbox places the window correctly */ atom = gdk_atom_intern ("_HILDON_NOTIFICATION_TYPE", FALSE); gdk_property_change (gdkwin, atom, gdk_x11_xatom_to_atom (XA_STRING), 8, GDK_PROP_MODE_REPLACE, (gpointer) notification_type, strlen (notification_type)); /* HildonBanner supports portrait mode */ atom = gdk_atom_intern ("_HILDON_PORTRAIT_MODE_SUPPORT", FALSE); gdk_property_change (gdkwin, atom, gdk_x11_xatom_to_atom (XA_CARDINAL), 32, GDK_PROP_MODE_REPLACE, (gpointer) &portrait, 1); /* Manage override flag */ if ((priv->require_override_dnd)&&(!priv->overrides_dnd)) { hildon_banner_set_override_flag (HILDON_BANNER (widget)); priv->overrides_dnd = TRUE; } screen = gtk_widget_get_screen (widget); g_signal_connect (screen, "size-changed", G_CALLBACK (screen_size_changed), widget); }