[empathy] Make topic label expand and wrap nicely
- From: Xavier Claessens <xclaesse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [empathy] Make topic label expand and wrap nicely
- Date: Fri, 2 Apr 2010 08:58:55 +0000 (UTC)
commit 0df6dd7c16289086ed9e3744edbe6db109219da9
Author: Xavier Claessens <xclaesse gmail com>
Date: Thu Mar 4 00:47:17 2010 +0100
Make topic label expand and wrap nicely
libempathy-gtk/empathy-chat.c | 93 +++++++++++++++++++++++++++++++++++++++-
libempathy-gtk/empathy-chat.ui | 12 +----
2 files changed, 95 insertions(+), 10 deletions(-)
---
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 9027200..d3a7df6 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -92,6 +92,7 @@ typedef struct {
TpHandleType handle_type;
gint contacts_width;
gboolean has_input_vscroll;
+ gint topic_width;
GtkWidget *widget;
GtkWidget *hpaned;
@@ -100,6 +101,7 @@ typedef struct {
GtkWidget *scrolled_window_input;
GtkWidget *scrolled_window_contacts;
GtkWidget *hbox_topic;
+ GtkWidget *expander_topic;
GtkWidget *label_topic;
GtkWidget *contact_list_view;
GtkWidget *info_bar_vbox;
@@ -1197,6 +1199,82 @@ chat_send_error_cb (EmpathyTpChat *tp_chat,
g_free (str);
}
+/* WARNING: EXPLICIT CONTENT, keep away childrens!
+ *
+ * When a GtkLabel is set to wrap, it assume and hardcoded width. To change
+ * that width we have to set a size request on the label... but that's not
+ * possible because we want the window to be able to shrink, so we MUST request
+ * width of 1. Note that the height of a wrapping label depends on its width.
+ *
+ * To work around that, here is what happens:
+ * 1) size-request is first called, an hardcoded small width is requested by
+ * GtkLabel, which means also a too big height. We do nothing.
+ * 2) size-allocate is called with the full width available, that's the width
+ * we really want to make wrap the label. We save that width and restart a
+ * size-request/size-allocate round.
+ * 3) size-request is called a 2nd time, now we can tell the pango layout its
+ * width (we can't do that in step 2 because GtkLabel::size-request recreate
+ * the layout each time). When the layout has its width, we can know the
+ * height of the label and set its requisition. The width request is set to
+ * 1px to make sure the window can shrink, the layout will fill all the
+ * available width anyway.
+ */
+static void
+chat_topic_label_size_request_cb (GtkLabel *label,
+ GtkRequisition *requisition,
+ EmpathyChat *chat)
+{
+ EmpathyChatPriv *priv = GET_PRIV (chat);
+
+ if (gtk_label_get_line_wrap (label) && priv->topic_width > 0) {
+ PangoLayout *layout;
+ PangoRectangle rect;
+ gint ypad;
+
+ layout = gtk_label_get_layout (label);
+ pango_layout_set_width (layout, priv->topic_width * PANGO_SCALE);
+ pango_layout_get_extents (layout, NULL, &rect);
+ gtk_misc_get_padding (GTK_MISC (label), NULL, &ypad);
+
+ requisition->width = 1;
+ requisition->height = PANGO_PIXELS (rect.height) + ypad * 2;
+ }
+}
+
+static void
+chat_topic_label_size_allocate_cb (GtkLabel *label,
+ GtkAllocation *allocation,
+ EmpathyChat *chat)
+{
+ EmpathyChatPriv *priv = GET_PRIV (chat);
+
+ if (!gtk_label_get_line_wrap (label)) {
+ priv->topic_width = -1;
+ return;
+ }
+
+ if (priv->topic_width != allocation->width) {
+ priv->topic_width = allocation->width;
+ gtk_widget_queue_resize (GTK_WIDGET (label));
+ }
+}
+
+static void
+chat_topic_expander_activate_cb (GtkExpander *expander,
+ GParamSpec *param_spec,
+ EmpathyChat *chat)
+{
+ EmpathyChatPriv *priv = GET_PRIV (chat);
+
+ if (gtk_expander_get_expanded (expander)) {
+ gtk_label_set_ellipsize (GTK_LABEL (priv->label_topic), PANGO_ELLIPSIZE_NONE);
+ gtk_label_set_line_wrap (GTK_LABEL (priv->label_topic), TRUE);
+ } else {
+ gtk_label_set_ellipsize (GTK_LABEL (priv->label_topic), PANGO_ELLIPSIZE_END);
+ gtk_label_set_line_wrap (GTK_LABEL (priv->label_topic), FALSE);
+ }
+}
+
static void
chat_property_changed_cb (EmpathyTpChat *tp_chat,
const gchar *name,
@@ -1213,11 +1291,16 @@ chat_property_changed_cb (EmpathyTpChat *tp_chat,
if (EMP_STR_EMPTY (priv->subject)) {
gtk_widget_hide (priv->hbox_topic);
} else {
+ gchar *markup_topic;
gchar *markup_text;
- markup_text = empathy_add_link_markup (priv->subject);
+ markup_topic = empathy_add_link_markup (priv->subject);
+ markup_text = g_strdup_printf ("<span weight=\"bold\">%s</span> %s",
+ _("Topic:"), markup_topic);
+
gtk_label_set_markup (GTK_LABEL (priv->label_topic), markup_text);
g_free (markup_text);
+ g_free (markup_topic);
gtk_widget_show (priv->hbox_topic);
}
@@ -2213,10 +2296,18 @@ chat_create_ui (EmpathyChat *chat)
"scrolled_window_chat", &priv->scrolled_window_chat,
"scrolled_window_input", &priv->scrolled_window_input,
"hbox_topic", &priv->hbox_topic,
+ "expander_topic", &priv->expander_topic,
"label_topic", &priv->label_topic,
"scrolled_window_contacts", &priv->scrolled_window_contacts,
"info_bar_vbox", &priv->info_bar_vbox,
NULL);
+
+ empathy_builder_connect (gui, chat,
+ "expander_topic", "notify::expanded", chat_topic_expander_activate_cb,
+ "label_topic", "size-allocate", chat_topic_label_size_allocate_cb,
+ "label_topic", "size-request", chat_topic_label_size_request_cb,
+ NULL);
+
g_free (filename);
/* Add message view. */
diff --git a/libempathy-gtk/empathy-chat.ui b/libempathy-gtk/empathy-chat.ui
index de82fdd..436c8db 100644
--- a/libempathy-gtk/empathy-chat.ui
+++ b/libempathy-gtk/empathy-chat.ui
@@ -88,14 +88,9 @@
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
- <object class="GtkLabel" id="label80">
+ <object class="GtkExpander" id="expander_topic">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Topic:</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
+ <property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
@@ -109,10 +104,9 @@
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="use_markup">True</property>
- <property name="wrap">True</property>
+ <property name="wrap">False</property>
<property name="selectable">True</property>
<property name="ellipsize">end</property>
- <property name="single_line_mode">True</property>
</object>
<packing>
<property name="position">1</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]