[telepathy-doc/master] Add a PresenceChooser widget that decodes Statuses

Danielle Madeley danielle.madeley at collabora.co.uk
Wed Nov 4 22:26:27 PST 2009


---
 docs/examples/gtk_presence_app/Makefile.am        |    1 +
 docs/examples/gtk_presence_app/presence-chooser.c |  116 +++++++++++++++++++++
 docs/examples/gtk_presence_app/presence-chooser.h |   44 ++++++++
 docs/examples/gtk_presence_app/presence-widget.c  |   27 +++---
 4 files changed, 174 insertions(+), 14 deletions(-)
 create mode 100644 docs/examples/gtk_presence_app/presence-chooser.c
 create mode 100644 docs/examples/gtk_presence_app/presence-chooser.h

diff --git a/docs/examples/gtk_presence_app/Makefile.am b/docs/examples/gtk_presence_app/Makefile.am
index b5dc428..2009214 100644
--- a/docs/examples/gtk_presence_app/Makefile.am
+++ b/docs/examples/gtk_presence_app/Makefile.am
@@ -6,6 +6,7 @@ noinst_PROGRAMS = example
 example_SOURCES = \
 	presence-window.c presence-window.h \
 	presence-widget.c presence-widget.h \
+	presence-chooser.c presence-chooser.h \
 	example.c
 
 include $(top_srcdir)/docs/rsync-dist.make
diff --git a/docs/examples/gtk_presence_app/presence-chooser.c b/docs/examples/gtk_presence_app/presence-chooser.c
new file mode 100644
index 0000000..df618f1
--- /dev/null
+++ b/docs/examples/gtk_presence_app/presence-chooser.c
@@ -0,0 +1,116 @@
+/*
+ * presence-chooser.c
+ *
+ * PresenceChooser
+ *
+ * Authors:
+ *    Danielle Madeley <danielle.madeley at collabora.co.uk>
+ */
+
+#include "presence-chooser.h"
+
+#define GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_PRESENCE_CHOOSER, PresenceChooserPrivate))
+
+G_DEFINE_TYPE (PresenceChooser, presence_chooser, GTK_TYPE_COMBO_BOX_ENTRY);
+
+/* provided by presence-widget.c */
+extern const char *presence_icons[];
+
+typedef struct _PresenceChooserPrivate PresenceChooserPrivate;
+struct _PresenceChooserPrivate
+{
+  GtkListStore *store;
+};
+
+enum /* columns */
+{
+  ICON_NAME,
+  PRESENCE_TYPE,
+  STATUS,
+  CAN_HAVE_MESSAGE,
+  STATUS_MESSAGE,
+  N_COLUMNS
+};
+
+static void
+presence_chooser_class_init (PresenceChooserClass *class)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+  g_type_class_add_private (gobject_class, sizeof (PresenceChooserPrivate));
+}
+
+static void
+presence_chooser_init (PresenceChooser *self)
+{
+  PresenceChooserPrivate *priv = GET_PRIVATE (self);
+
+  priv->store = gtk_list_store_new (N_COLUMNS,
+      G_TYPE_STRING,  /* ICON_NAME */
+      G_TYPE_UINT,    /* PRESENCE_TYPE */
+      G_TYPE_STRING,  /* STATUS */
+      G_TYPE_BOOLEAN, /* CAN_HAVE_MESSAGE */
+      G_TYPE_STRING   /* STATUS_MESSAGE */
+    );
+
+  gtk_combo_box_set_model (GTK_COMBO_BOX (self), GTK_TREE_MODEL (priv->store));
+
+  gtk_cell_layout_clear (GTK_CELL_LAYOUT (self));
+
+  GtkCellRenderer *renderer;
+  renderer = gtk_cell_renderer_pixbuf_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, FALSE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
+      "icon-name", ICON_NAME,
+      NULL);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
+      "text", STATUS_MESSAGE,
+      NULL);
+}
+
+void
+presence_chooser_set_statuses (PresenceChooser *self,
+                               GHashTable *statuses)
+{
+  g_return_if_fail (IS_PRESENCE_CHOOSER (self));
+  g_return_if_fail (statuses != NULL);
+
+  PresenceChooserPrivate *priv = GET_PRIVATE (self);
+
+  gtk_list_store_clear (priv->store);
+
+  GHashTableIter iter;
+  gpointer k, v;
+
+  g_hash_table_iter_init (&iter, statuses);
+  while (g_hash_table_iter_next (&iter, &k, &v))
+    {
+      char *status = k;
+      GValueArray *array = v;
+
+      guint type = g_value_get_uint (g_value_array_get_nth (array, 0));
+      gboolean set_on_self = g_value_get_boolean (
+          g_value_array_get_nth (array, 1));
+      gboolean can_have_message = g_value_get_boolean (
+          g_value_array_get_nth (array, 2));
+
+      if (!set_on_self) continue;
+
+      gtk_list_store_insert_with_values (priv->store, NULL, -1,
+          ICON_NAME, presence_icons[type],
+          PRESENCE_TYPE, type,
+          STATUS, status,
+          CAN_HAVE_MESSAGE, can_have_message,
+          STATUS_MESSAGE, status,
+          -1);
+    }
+}
+
+GtkWidget *
+presence_chooser_new (void)
+{
+  return g_object_new (TYPE_PRESENCE_CHOOSER, NULL);
+}
diff --git a/docs/examples/gtk_presence_app/presence-chooser.h b/docs/examples/gtk_presence_app/presence-chooser.h
new file mode 100644
index 0000000..ffc17c0
--- /dev/null
+++ b/docs/examples/gtk_presence_app/presence-chooser.h
@@ -0,0 +1,44 @@
+/*
+ * presence-chooser.h
+ *
+ * PresenceChooser
+ *
+ * Authors:
+ *    Danielle Madeley <danielle.madeley at collabora.co.uk>
+ */
+
+#ifndef __PRESENCE_CHOOSER_H__
+#define __PRESENCE_CHOOSER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_PRESENCE_CHOOSER	(presence_chooser_get_type ())
+#define PRESENCE_CHOOSER(obj)	(G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PRESENCE_CHOOSER, PresenceChooser))
+#define PRESENCE_CHOOSER_CLASS(obj)	(G_TYPE_CHECK_CLASS_CAST ((obj), TYPE_PRESENCE_CHOOSER, PresenceChooserClass))
+#define IS_PRESENCE_CHOOSER(obj)	(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PRESENCE_CHOOSER))
+#define IS_PRESENCE_CHOOSER_CLASS(obj)	(G_TYPE_CHECK_CLASS_TYPE ((obj), TYPE_PRESENCE_CHOOSER))
+#define PRESENCE_CHOOSER_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PRESENCE_CHOOSER, PresenceChooserClass))
+
+typedef struct _PresenceChooser PresenceChooser;
+typedef struct _PresenceChooserClass PresenceChooserClass;
+
+struct _PresenceChooser
+{
+  GtkComboBoxEntry parent;
+};
+
+struct _PresenceChooserClass
+{
+  GtkComboBoxEntryClass parent_class;
+};
+
+GType presence_chooser_get_type (void);
+void presence_chooser_set_statuses (PresenceChooser *self,
+                                    GHashTable *statuses);
+GtkWidget *presence_chooser_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/docs/examples/gtk_presence_app/presence-widget.c b/docs/examples/gtk_presence_app/presence-widget.c
index 81dbe79..719ed43 100644
--- a/docs/examples/gtk_presence_app/presence-widget.c
+++ b/docs/examples/gtk_presence_app/presence-widget.c
@@ -13,6 +13,7 @@
 #include <telepathy-glib/gtypes.h>
 
 #include "presence-widget.h"
+#include "presence-chooser.h"
 
 #define GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_PRESENCE_WIDGET, PresenceWidgetPrivate))
 
@@ -27,6 +28,7 @@ struct _PresenceWidgetPrivate
   GtkWidget *enabled_check;
   GtkWidget *status_icon;
   GtkWidget *status_message;
+  GtkWidget *chooser;
 
   gint updating_ui_lock;
 };
@@ -38,7 +40,7 @@ enum /* properties */
 };
 
 /* presence icons */
-static const char *presence_icons[NUM_TP_CONNECTION_PRESENCE_TYPES] = {
+const char *presence_icons[NUM_TP_CONNECTION_PRESENCE_TYPES] = {
     "empathy-offline",
     "empathy-offline",
     "empathy-available",
@@ -50,18 +52,6 @@ static const char *presence_icons[NUM_TP_CONNECTION_PRESENCE_TYPES] = {
     "empathy-offline",
 };
 
-static const char *default_messages[NUM_TP_CONNECTION_PRESENCE_TYPES] = {
-    "Unset",
-    "Offline",
-    "Available",
-    "Away",
-    "Extended Away",
-    "Hidden",
-    "Busy",
-    "Unknown",
-    "Error"
-};
-
 static void
 presence_widget_get_property (GObject    *self,
                               guint       prop_id,
@@ -151,7 +141,7 @@ _notify_status_message (PresenceWidget *self,
   if (strlen (msg) == 0)
     {
       TpConnectionPresenceType presence = tp_account_get_presence (account);
-      msg = default_messages[presence];
+      msg = tp_account_get_status (account);
     }
 
   gtk_label_set_text (GTK_LABEL (priv->status_message), msg);
@@ -178,6 +168,8 @@ _get_property_statuses (TpProxy      *conn,
   priv->statuses = g_hash_table_ref (g_value_get_boxed (value));
 
   // FIXME: do I need to hold onto this?
+  presence_chooser_set_statuses (PRESENCE_CHOOSER (priv->chooser),
+                                 priv->statuses);
 }
 
 static void
@@ -319,6 +311,7 @@ presence_widget_init (PresenceWidget *self)
   gtk_container_add (GTK_CONTAINER (self), table);
   gtk_container_set_border_width (GTK_CONTAINER (table), 3);
   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
+  gtk_table_set_row_spacings (GTK_TABLE (table), 3);
 
   priv->status_icon = gtk_image_new ();
   gtk_table_attach (GTK_TABLE (table), priv->status_icon,
@@ -326,8 +319,14 @@ presence_widget_init (PresenceWidget *self)
       GTK_FILL, GTK_FILL, 0, 0);
 
   priv->status_message = gtk_label_new ("");
+  gtk_misc_set_alignment (GTK_MISC (priv->status_message), 0., 0.5);
   gtk_table_attach (GTK_TABLE (table), priv->status_message,
       1, 2, 0, 1,
+      GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
+
+  priv->chooser = presence_chooser_new ();
+  gtk_table_attach (GTK_TABLE (table), priv->chooser,
+      0, 2, 1, 2,
       GTK_FILL, GTK_FILL, 0, 0);
 
   gtk_widget_show (priv->enabled_check);
-- 
1.5.6.5




More information about the telepathy-commits mailing list