[empathy] When no video is received or sent we show contacts' avatars instead of showing



commit 72720c392da5917088cc95a5fc5dd4e7ce56a4d1
Author: Jonathan Tellier <jonathan tellier gmail com>
Date:   Wed May 20 13:49:02 2009 -0400

    When no video is received or sent we show contacts' avatars instead of showing
    black widgets.
---
 libempathy-gtk/empathy-video-widget.c |    4 +-
 libempathy-gtk/empathy-video-widget.h |    3 +
 src/empathy-call-window.c             |  146 +++++++++++++++++++++++++++++++--
 3 files changed, 143 insertions(+), 10 deletions(-)

diff --git a/libempathy-gtk/empathy-video-widget.c b/libempathy-gtk/empathy-video-widget.c
index 4c7bee9..7647b84 100644
--- a/libempathy-gtk/empathy-video-widget.c
+++ b/libempathy-gtk/empathy-video-widget.c
@@ -263,14 +263,14 @@ empathy_video_widget_class_init (
   param_spec = g_param_spec_int ("min-width",
     "min-width",
     "Minimal width of the widget",
-    0, G_MAXINT, 320,
+    0, G_MAXINT, EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH,
     G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class, PROP_MIN_WIDTH, param_spec);
 
   param_spec = g_param_spec_int ("min-height",
     "min-height",
     "Minimal height of the widget",
-    0, G_MAXINT, 240,
+    0, G_MAXINT, EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT,
     G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class, PROP_MIN_HEIGHT, param_spec);
 
diff --git a/libempathy-gtk/empathy-video-widget.h b/libempathy-gtk/empathy-video-widget.h
index da17a6f..cfdd035 100644
--- a/libempathy-gtk/empathy-video-widget.h
+++ b/libempathy-gtk/empathy-video-widget.h
@@ -21,6 +21,9 @@
 #ifndef __EMPATHY_VIDEO_WIDGET_H__
 #define __EMPATHY_VIDEO_WIDGET_H__
 
+#define EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH 320
+#define EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT 240
+
 #include <glib-object.h>
 #include <gst/gst.h>
 #include <gtk/gtk.h>
diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c
index ceab7d0..58119d8 100644
--- a/src/empathy-call-window.c
+++ b/src/empathy-call-window.c
@@ -1,6 +1,6 @@
 /*
  * empathy-call-window.c - Source for EmpathyCallWindow
- * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008-2009 Collabora Ltd.
  * @author Sjoerd Simons <sjoerd simons collabora co uk>
  *
  * This library is free software; you can redistribute it and/or
@@ -31,7 +31,9 @@
 
 #include <telepathy-farsight/channel.h>
 
+#include <libempathy/empathy-tp-contact-factory.h>
 #include <libempathy/empathy-utils.h>
+#include <libempathy-gtk/empathy-avatar-image.h>
 #include <libempathy-gtk/empathy-video-widget.h>
 #include <libempathy-gtk/empathy-audio-src.h>
 #include <libempathy-gtk/empathy-audio-sink.h>
@@ -49,6 +51,14 @@
 #define CONTENT_HBOX_SPACING 3
 #define CONTENT_HBOX_CHILDREN_PACKING_PADDING 3
 
+#define SELF_VIDEO_SECTION_WIDTH 160
+#define SELF_VIDEO_SECTION_HEIGTH 120
+
+/* The avatar's default width and height are set to the same value because we
+   want a square icon. */
+#define REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT
+#define REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT
+
 G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW)
 
 /* signal enum */
@@ -79,6 +89,8 @@ struct _EmpathyCallWindowPriv
   GtkUIManager *ui_manager;
   GtkWidget *video_output;
   GtkWidget *video_preview;
+  GtkWidget *remote_user_avatar_widget;
+  GtkWidget *self_user_avatar_widget;
   GtkWidget *sidebar;
   GtkWidget *sidebar_button;
   GtkWidget *statusbar;
@@ -512,6 +524,8 @@ empathy_call_window_init (EmpathyCallWindow *self)
   GtkWidget *h;
   GtkWidget *arrow;
   GtkWidget *page;
+  GtkWidget *remote_user_output_frame, *self_user_output_frame;
+  GtkWidget *remote_user_output_hbox, *self_user_output_hbox;
   GstBus *bus;
   gchar *filename;
 
@@ -555,13 +569,28 @@ empathy_call_window_init (EmpathyCallWindow *self)
 
   gst_bus_add_watch (bus, empathy_call_window_bus_message, self);
 
+  remote_user_output_frame = gtk_frame_new (NULL);
+  gtk_widget_set_size_request (remote_user_output_frame,
+      EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH, EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT);
+  remote_user_output_hbox = gtk_hbox_new (FALSE, 0);
+
+  priv->remote_user_avatar_widget = gtk_image_new ();
+  gtk_box_pack_start (GTK_BOX (remote_user_output_hbox),
+      priv->remote_user_avatar_widget, TRUE, TRUE, 0);
+
   priv->video_output = empathy_video_widget_new (bus);
-  gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->video_output,
-                      TRUE, TRUE, CONTENT_HBOX_CHILDREN_PACKING_PADDING);
+  gtk_box_pack_start (GTK_BOX (remote_user_output_hbox),
+      priv->video_output, TRUE, TRUE, 0);
+
+  gtk_container_add (GTK_CONTAINER (remote_user_output_frame),
+      remote_user_output_hbox);
+
   gtk_widget_add_events (priv->video_output,
       GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
   g_signal_connect (G_OBJECT (priv->video_output), "button-press-event",
       G_CALLBACK (empathy_call_window_video_button_press_cb), self);
+  gtk_box_pack_start (GTK_BOX (priv->content_hbox), remote_user_output_frame,
+      TRUE, TRUE, CONTENT_HBOX_CHILDREN_PACKING_PADDING);
 
   priv->video_tee = gst_element_factory_make ("tee", NULL);
   gst_object_ref (priv->video_tee);
@@ -571,9 +600,26 @@ empathy_call_window_init (EmpathyCallWindow *self)
   gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->vbox,
                       FALSE, FALSE, CONTENT_HBOX_CHILDREN_PACKING_PADDING);
 
-  priv->video_preview = empathy_video_widget_new_with_size (bus, 160, 120);
+  self_user_output_frame = gtk_frame_new (NULL);
+  gtk_widget_set_size_request (self_user_output_frame, SELF_VIDEO_SECTION_WIDTH,
+      SELF_VIDEO_SECTION_HEIGTH);
+  self_user_output_hbox = gtk_hbox_new (FALSE, 0);
+
+  priv->self_user_avatar_widget = gtk_image_new ();
+  gtk_box_pack_start (GTK_BOX (self_user_output_hbox),
+      priv->self_user_avatar_widget, TRUE, TRUE, 0);
+
+  priv->video_preview = empathy_video_widget_new_with_size (bus,
+      SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH);
   g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL);
-  gtk_box_pack_start (GTK_BOX (priv->vbox), priv->video_preview, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (self_user_output_hbox), priv->video_preview,
+      TRUE, TRUE, 0);
+
+  gtk_container_add (GTK_CONTAINER (self_user_output_frame),
+      self_user_output_hbox);
+
+  gtk_box_pack_start (GTK_BOX (priv->vbox), self_user_output_frame, FALSE,
+      FALSE, 0);
 
   priv->video_input = empathy_video_src_new ();
   gst_object_ref (priv->video_input);
@@ -651,6 +697,30 @@ empathy_call_window_init (EmpathyCallWindow *self)
   g_free (filename);
 }
 
+/* Instead of specifying a width and a height, we specify only one size. That's
+   because we want a square avatar icon.  */
+static void
+init_contact_avatar_with_size (EmpathyContact *contact, GtkWidget *image_widget,
+    gint size)
+{
+
+  GdkPixbuf *pixbuf_avatar;
+
+  if (contact != NULL)
+    {
+      pixbuf_avatar = empathy_pixbuf_avatar_from_contact_scaled (contact,
+        size, size);
+    }
+
+  if (pixbuf_avatar == NULL)
+    {
+      pixbuf_avatar = empathy_pixbuf_from_icon_name_sized ("stock_person",
+          size);
+    }
+
+  gtk_image_set_from_pixbuf (GTK_IMAGE (image_widget), pixbuf_avatar);
+}
+
 static void
 set_window_title (EmpathyCallWindow *self)
 {
@@ -665,13 +735,35 @@ set_window_title (EmpathyCallWindow *self)
 
 static void
 contact_name_changed_cb (EmpathyContact *contact,
-                         GParamSpec *pspec,
-                         EmpathyCallWindow *self)
+    GParamSpec *pspec, EmpathyCallWindow *self)
 {
   set_window_title (self);
 }
 
 static void
+contact_avatar_changed_cb (EmpathyContact *contact,
+    GParamSpec *pspec, GtkWidget *avatar_widget)
+{
+  init_contact_avatar_with_size (contact, avatar_widget,
+      avatar_widget->allocation.height);
+}
+
+static void
+empathy_call_window_got_self_contact_cb (EmpathyTpContactFactory *factory,
+    EmpathyContact *contact, const GError *error, gpointer user_data,
+    GObject *weak_object)
+{
+  EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+  init_contact_avatar_with_size (contact, priv->self_user_avatar_widget,
+      MIN (SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH));
+
+  g_signal_connect (contact, "notify::avatar",
+      G_CALLBACK (contact_avatar_changed_cb), priv->self_user_avatar_widget);
+}
+
+static void
 empathy_call_window_constructed (GObject *object)
 {
   EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object);
@@ -683,16 +775,49 @@ empathy_call_window_constructed (GObject *object)
 
   if (priv->contact != NULL)
     {
+      TpConnection *connection;
+      EmpathyTpContactFactory *factory;
+
       set_window_title (self);
 
       g_signal_connect (priv->contact, "notify::name",
           G_CALLBACK (contact_name_changed_cb), self);
+      g_signal_connect (priv->contact, "notify::avatar",
+          G_CALLBACK (contact_avatar_changed_cb),
+          priv->remote_user_avatar_widget);
+
+      /* Retreiving the self avatar */
+      connection = empathy_contact_get_connection (priv->contact);
+      factory = empathy_tp_contact_factory_dup_singleton(connection);
+      empathy_tp_contact_factory_get_from_handle (factory,
+          tp_connection_get_self_handle (connection),
+          empathy_call_window_got_self_contact_cb, self, NULL, NULL);
+
+      g_object_unref (factory);
     }
   else
     {
       g_warning ("call handler doesn't have a contact");
       gtk_window_set_title (GTK_WINDOW (self), _("Call"));
+
+      /* Since we can't access the remote contact, we can't get a connection
+         to it and can't get the self contact (and its avatar). This means
+         that we have to manually set the self avatar. */
+      init_contact_avatar_with_size (NULL, priv->self_user_avatar_widget,
+          MIN (SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH));
     }
+
+  init_contact_avatar_with_size (priv->contact,
+      priv->remote_user_avatar_widget, MIN (REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH,
+      REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT));
+
+  /* We hide the self avatar. It will be shown if a problem is
+     encountered when we try to send video. As for the remote avatar, it
+     is shown by default and will be hidden when we receive video from
+     the remote side. */
+  gtk_widget_hide (priv->self_user_avatar_widget);
+  gtk_widget_hide (priv->video_output);
+  gtk_widget_show (priv->remote_user_avatar_widget);
 }
 
 static void empathy_call_window_dispose (GObject *object);
@@ -1034,6 +1159,8 @@ empathy_call_window_src_added_cb (EmpathyCallHandler *handler,
         pad = empathy_call_window_get_audio_sink_pad (self);
         break;
       case TP_MEDIA_STREAM_TYPE_VIDEO:
+        gtk_widget_hide (priv->remote_user_avatar_widget);
+        gtk_widget_show (priv->video_output);
         pad = empathy_call_window_get_video_sink_pad (self);
         break;
       default:
@@ -1068,7 +1195,7 @@ empathy_call_window_sink_added_cb (EmpathyCallHandler *handler,
       case TP_MEDIA_STREAM_TYPE_VIDEO:
         if (priv->video_input != NULL)
           {
-            pad =  gst_element_get_request_pad (priv->video_tee, "src%d");
+            pad = gst_element_get_request_pad (priv->video_tee, "src%d");
             gst_pad_link (pad, sink);
           }
         break;
@@ -1137,6 +1264,9 @@ empathy_call_window_remove_video_input (EmpathyCallWindow *self)
   priv->video_input = NULL;
   g_object_unref (priv->video_tee);
   priv->video_tee = NULL;
+
+  gtk_widget_hide (priv->video_preview);
+  gtk_widget_show (priv->self_user_avatar_widget);
 }
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]