[ekiga] Roster: Use animation to display status changes.
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga] Roster: Use animation to display status changes.
- Date: Sun, 7 Oct 2012 17:59:07 +0000 (UTC)
commit fbddebd55866fa3ce706f68f4905e5c1be34936c
Author: Damien Sandras <dsandras beip be>
Date: Sun Oct 7 19:58:07 2012 +0200
Roster: Use animation to display status changes.
A bit like pidgin does. No time to explain the rationale, Victoria
is crying grmmpf.
lib/engine/gui/gtk-frontend/roster-view-gtk.cpp | 116 ++++++++++++++++++++---
1 files changed, 101 insertions(+), 15 deletions(-)
---
diff --git a/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp b/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp
index 605f388..74023a6 100644
--- a/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp
+++ b/lib/engine/gui/gtk-frontend/roster-view-gtk.cpp
@@ -38,6 +38,7 @@
#include <algorithm>
#include <iostream>
#include <vector>
+#include <ctime>
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
@@ -66,6 +67,15 @@ struct _RosterViewGtkPrivate
gboolean show_offline_contacts;
};
+typedef struct _StatusIconInfo {
+
+ GtkTreeModel *model;
+ GtkTreeIter *iter;
+ std::string new_presence;
+ int cpt;
+
+} StatusIconInfo;
+
/* the different type of things which will appear in the view */
enum {
@@ -104,9 +114,10 @@ enum {
COLUMN_PRESENTITY,
COLUMN_NAME,
COLUMN_STATUS,
- COLUMN_PRESENCE,
+ COLUMN_PRESENCE_ICON,
COLUMN_ACTIVE,
COLUMN_GROUP_NAME,
+ COLUMN_PRESENCE,
COLUMN_OFFLINE,
COLUMN_NUMBER
};
@@ -117,6 +128,14 @@ enum {
//static void dump_model_content (GtkTreeModel* model);
/*
+ * Time out callbacks
+ */
+static int roster_view_gtk_icon_blink_cb (gpointer data);
+
+static void status_icon_info_delete (gpointer info);
+
+
+/*
* Helpers
*/
@@ -439,8 +458,47 @@ static void roster_view_gtk_set_core (RosterViewGtk* self,
// g_print ("(empty model)\n");
// }
-/* Implementation of the helpers */
+/* Implementation of the timer callbacks */
+static int
+roster_view_gtk_icon_blink_cb (gpointer data)
+{
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ StatusIconInfo *info = (StatusIconInfo*) data;
+ time_t now = time (0);
+ tm *ltm = localtime (&now);
+
+ std::string icon = "avatar-default";
+ if (info->cpt == 0) {
+ gtk_tree_store_set (GTK_TREE_STORE (info->model), info->iter,
+ COLUMN_PRESENCE_ICON, "exit",
+ -1);
+ }
+ else if (ltm->tm_sec % 5 == 0 && info->cpt > 3) {
+ if (info->new_presence != "unknown")
+ icon = "user-" + info->new_presence;
+ gtk_tree_store_set (GTK_TREE_STORE (info->model), info->iter,
+ COLUMN_PRESENCE_ICON, icon.c_str (),
+ -1);
+ return FALSE;
+ }
+
+ info->cpt++;
+ return TRUE;
+}
+
+static void status_icon_info_delete (gpointer data)
+{
+ g_return_if_fail (data != NULL);
+ StatusIconInfo *info = (StatusIconInfo*) data;
+
+ gtk_tree_iter_free (info->iter);
+
+ delete info;
+}
+
+/* Implementation of the helpers */
static void
on_clicked_show_heap_menu (Ekiga::Heap* heap,
GdkEventButton* event)
@@ -944,6 +1002,7 @@ on_presentity_added (RosterViewGtk* self,
GtkTreeIter filtered_iter;
bool active = false;
bool away = false;
+ gchar *old_presence = NULL;
gboolean should_emit = FALSE;
roster_view_gtk_find_iter_for_heap (self, heap, &heap_iter);
@@ -966,19 +1025,45 @@ on_presentity_added (RosterViewGtk* self,
if (gtk_tree_selection_iter_is_selected (selection, &filtered_iter))
should_emit = TRUE;
- std::string icon = "avatar-default";
- if (presentity->get_presence () != "unknown")
- icon = "user-" + presentity->get_presence ();
+ // Find out what our presence was
+ gtk_tree_model_get (GTK_TREE_MODEL (self->priv->store), &iter,
+ COLUMN_PRESENCE, &old_presence,
+ -1);
+ if (old_presence && presentity->get_presence () != old_presence
+ && presentity->get_presence () != "unknown" && presentity->get_presence () != "offline"
+ && (!strcmp (old_presence, "unknown") || !strcmp (old_presence, "offline"))) {
+
+ StatusIconInfo *info = new StatusIconInfo ();
+ info->model = GTK_TREE_MODEL (self->priv->store);
+ info->iter = gtk_tree_iter_copy (&iter);
+ info->new_presence = presentity->get_presence ();
+ info->cpt = 0;
+
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 1, roster_view_gtk_icon_blink_cb,
+ (gpointer) info, (GDestroyNotify) status_icon_info_delete);
+ }
+ else {
+
+ if (!old_presence || old_presence != presentity->get_presence ()) {
+ std::string icon = "avatar-default";
+ if (presentity->get_presence () != "unknown")
+ icon = "user-" + presentity->get_presence ();
+ gtk_tree_store_set (self->priv->store, &iter,
+ COLUMN_PRESENCE_ICON, icon.c_str (),
+ -1);
+ }
+ }
gtk_tree_store_set (self->priv->store, &iter,
- COLUMN_TYPE, TYPE_PRESENTITY,
- COLUMN_OFFLINE, active,
- COLUMN_HEAP, heap.get (),
- COLUMN_PRESENTITY, presentity.get (),
- COLUMN_NAME, presentity->get_name ().c_str (),
- COLUMN_STATUS, presentity->get_status ().c_str (),
- COLUMN_PRESENCE, icon.c_str (),
- COLUMN_ACTIVE, (!active || away) ? "gray" : "black",
- -1);
+ COLUMN_TYPE, TYPE_PRESENTITY,
+ COLUMN_OFFLINE, active,
+ COLUMN_HEAP, heap.get (),
+ COLUMN_PRESENTITY, presentity.get (),
+ COLUMN_NAME, presentity->get_name ().c_str (),
+ COLUMN_STATUS, presentity->get_status ().c_str (),
+ COLUMN_PRESENCE, presentity->get_presence ().c_str (),
+ COLUMN_ACTIVE, (!active || away) ? "gray" : "black",
+ -1);
+ g_free (old_presence);
}
GtkTreeModel* model = gtk_tree_view_get_model (self->priv->tree_view);
@@ -1348,6 +1433,7 @@ roster_view_gtk_init (G_GNUC_UNUSED RosterViewGtk* self)
G_TYPE_STRING, // presence
G_TYPE_STRING, // color if active
G_TYPE_STRING, // group name (invisible)
+ G_TYPE_STRING, // presence
G_TYPE_BOOLEAN); // offline
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->priv->store),
@@ -1416,7 +1502,7 @@ roster_view_gtk_init (G_GNUC_UNUSED RosterViewGtk* self)
gtk_tree_view_column_pack_start (col, renderer, FALSE);
gtk_tree_view_column_add_attribute (col, renderer,
"icon-name",
- COLUMN_PRESENCE);
+ COLUMN_PRESENCE_ICON);
gtk_tree_view_column_set_cell_data_func (col, renderer,
show_cell_data_func, GINT_TO_POINTER (TYPE_PRESENTITY), NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]