[Xfce4-commits] <postler:master> Message list improvements, implement CellRendererConvo
Christian Dywan
noreply at xfce.org
Wed Jul 6 21:12:01 CEST 2011
Updating branch refs/heads/master
to 7ed2f88d54b62d74dad68e0a0e8c75ca98ca0de1 (commit)
from b8a9cb8a1c656f2da0effb7cc7c131efa4e853c6 (commit)
commit 7ed2f88d54b62d74dad68e0a0e8c75ca98ca0de1
Author: Lucas Baudin <xapantu at gmail.com>
Date: Wed Jul 6 15:55:48 2011 +0200
Message list improvements, implement CellRendererConvo
Fixes: https://bugs.launchpad.net/postler/+bug/806391
postler/postler-cellrendererconvo.vala | 280 ++++++++++++++++++++++++++++++++
postler/postler-messages.vala | 41 ++----
2 files changed, 291 insertions(+), 30 deletions(-)
diff --git a/postler/postler-cellrendererconvo.vala b/postler/postler-cellrendererconvo.vala
new file mode 100644
index 0000000..e636f26
--- /dev/null
+++ b/postler/postler-cellrendererconvo.vala
@@ -0,0 +1,280 @@
+/*
+ Copyright (C) 2011 Lucas Baudin <xapantu at gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#if !HAVE_GTK3
+public struct Gdk.RGBA {
+ double red;
+ double green;
+ double blue;
+ double alpha;
+}
+namespace Gdk {
+ static void cairo_set_source_rgba (Cairo.Context cr, Gdk.RGBA color) {
+ cr.set_source_rgba (color.red, color.green, color.blue, color.alpha);
+ }
+}
+#endif
+
+public class Postler.CellRendererConvo : Gtk.CellRenderer {
+
+ public string subject { set; get; }
+ public string date { set; get; }
+ public string sender { set; get; }
+ public string text { set; get; }
+ public int unread { set; get; }
+ public bool message_unread = false;
+ public bool flagged = false;
+
+ double sender_height = 0.0;
+ double subject_height = 0.0;
+
+ public CellRendererConvo () {
+ }
+
+ /**
+ * Draw a rounded rectangle.
+ *
+ * This function only draws the shape, it doesn't fill or stroke it. It is
+ * a copy paste from the Cairo website.
+ *
+ * @param cr a valid Cairo context
+ * @param x x coord
+ * @param y y coord
+ * @param w the width of the rounded rectangle
+ * @param h the height of the rounded rectangle
+ **/
+ static void rounded (Cairo.Context cr, double x, double y, double w, double h) {
+ double r = 5;
+ cr.move_to (x + r, y); // Move to A
+ cr.line_to (x + w - r, y); // Straight line to B
+ cr.curve_to (x + w, y, x + w, y, x + w, y + r); // Curve to C, Control points are both at Q
+ cr.line_to (x + w, y + h - r); // Move to D
+ cr.curve_to (x + w, y + h, x + w, y + h, x + w - r,y + h); // Curve to E
+ cr.line_to (x + r, y + h); // Line to F
+ cr.curve_to (x, y + h, x, y + h, x, y + h - r); // Curve to G
+ cr.line_to (x, y + r); // Line to H
+ cr.curve_to (x, y, x, y, x + r, y); // Curve to A double a = x;
+ cr.close_path ();
+ }
+
+ /**
+ * Get the width of the layout, in pixel.
+ *
+ * @param layout a valid pango layout
+ * @return the width of the layout.
+ **/
+ static double get_layout_width (Pango.Layout layout) {
+ Pango.Rectangle rect = Pango.Rectangle ();
+ layout.get_extents (out rect, null);
+ return Pango.units_to_double (rect.width);
+ }
+
+ /**
+ * Get the height of the layout, in pixel.
+ *
+ * @param layout a valid pango layout
+ * @return the height of the layout.
+ **/
+ static double get_layout_height (Pango.Layout layout) {
+ Pango.Rectangle rect = Pango.Rectangle();
+ layout.get_extents(out rect, null);
+ return Pango.units_to_double(rect.height);
+ }
+
+ /**
+ * Function called by gtk to determine the size request of the cell.
+ **/
+ public override void get_size (Gtk.Widget widget, Gdk.Rectangle? cell_area,
+ out int x_offset, out int y_offset,
+ out int width, out int height) {
+ height = (int)get_height (widget);
+ width = 250; /* Hardcoded, maybe it should be configurable */
+ }
+
+ /**
+ * Utility function to get the system link color, which is a Gdk.Color,
+ * we convert it to Gdk.RGBA to use it easily with cairo.
+ *
+ * @param style a valid StyleContext, we'll extract the Gdk.Color of the
+ * link from it.
+ *
+ * @return a Gdk.RGBA, which contains the link color
+ **/
+#if HAVE_GTK3
+ static Gdk.RGBA get_link_color (Gtk.StyleContext style) {
+#else
+ static Gdk.RGBA get_link_color (Gtk.Style style) {
+#endif
+ Gdk.Color? link_color_ = Gdk.Color();
+#if HAVE_GTK3
+ Value g_value = Value (typeof (Gdk.Color));
+ style.get_style_property ("link-color", g_value);
+ link_color_ = (Gdk.Color?)g_value.get_boxed ();
+#else
+ style.lookup_color ("link_color", out link_color_);
+#endif
+ Gdk.RGBA link_color = gdk_color_to_rgba (link_color_);
+ return link_color;
+ }
+
+ static Gdk.RGBA gdk_color_to_rgba (Gdk.Color color)
+ {
+ Gdk.RGBA link_color = Gdk.RGBA ();
+ link_color.red = ((double)color.red) / 0xFFFF;
+ link_color.green = ((double)color.green) / 0xFFFF;
+ link_color.blue = ((double)color.blue) / 0xFFFF;
+ link_color.alpha = 1.0;
+ return link_color;
+ }
+
+ /**
+ * Function called by gtk to draw the cell content.
+ **/
+#if HAVE_GTK3
+ public override void render (Cairo.Context cr, Gtk.Widget widget,
+ Gdk.Rectangle background_area, Gdk.Rectangle area,
+ Gtk.CellRendererState flags) {
+#else
+ public override void render (Gdk.Window draw, Gtk.Widget widget,
+ Gdk.Rectangle background_area, Gdk.Rectangle area,
+ Gdk.Rectangle expose_area, Gtk.CellRendererState flags) {
+#endif
+ Pango.Layout? layout = null;
+#if HAVE_GTK3
+ Gtk.StyleContext style = widget.get_style_context();
+#else
+ Gtk.Style style = widget.get_style();
+#endif
+ Gdk.RGBA link_color = get_link_color(style);
+#if HAVE_GTK3
+ Gdk.RGBA color_normal = style.get_color((flags & Gtk.CellRendererState.FOCUSED) > 0 ? Gtk.StateFlags.SELECTED : Gtk.StateFlags.NORMAL);
+ Gdk.RGBA color_insensitive = style.get_color(Gtk.StateFlags.INSENSITIVE);
+#else
+ Gdk.RGBA color_normal = gdk_color_to_rgba(style.fg[(flags & Gtk.CellRendererState.FOCUSED) > 0 ? Gtk.StateType.SELECTED : Gtk.StateType.NORMAL]);
+ Gdk.RGBA color_insensitive = gdk_color_to_rgba(style.fg[Gtk.StateType.INSENSITIVE]);
+
+ Cairo.Context cr = Gdk.cairo_create(draw);
+#endif
+
+ /* Compute font size */
+ Pango.FontDescription font_medium = widget.get_pango_context ().get_font_description ();
+ Pango.FontDescription old_desc = font_medium;
+ font_medium.set_size(Pango.units_from_double (Pango.units_to_double (font_medium.get_size()) - 2));
+
+ Pango.FontDescription font_small = widget.get_pango_context().get_font_description ();
+ font_small.set_size(Pango.units_from_double (Pango.units_to_double (old_desc.get_size ()) - 3));
+
+ /* Important */
+ if (flagged) {
+ color_normal.red += 0.5;
+ color_normal.green -= 0.2;
+ color_normal.blue -= 0.2;
+ color_insensitive = color_normal;
+ color_insensitive.alpha -= 0.4;
+ }
+
+ /* Unread */
+ if (message_unread) {
+ color_normal.blue += 0.5;
+ color_normal.green -= 0.2;
+ color_normal.red -= 0.2;
+ color_insensitive = color_normal;
+ color_insensitive.alpha -= 0.4;
+ }
+
+ /* Show date */
+ Gdk.cairo_set_source_rgba (cr,
+ (flags & Gtk.CellRendererState.FOCUSED) > 0 ? color_normal : link_color);
+ layout = widget.create_pango_layout (date);
+ layout.set_font_description (font_small);
+ double date_width = get_layout_width (layout);
+ cr.move_to (area.x + area.width - get_layout_width (layout) - 5, area.y);
+ Pango.cairo_show_layout (cr, layout);
+
+ /* Show unread count */
+ double unread_width = 0.0;
+ if (unread > 0) { /* Don't show [0] */
+ layout = widget.create_pango_layout (unread.to_string ());
+ double margin = 5;
+ double rect_width = get_layout_width (layout) + margin * 2;
+ double rect_height = get_layout_height (layout) + margin * 2;
+ unread_width = rect_width + 5;
+ /* Background */
+ rounded (cr, area.x + area.width - rect_width - 5,
+ area.y + area.height / 2 - rect_height / 2 + margin,
+ rect_width, rect_height);
+ Gdk.cairo_set_source_rgba (cr, link_color);
+ cr.fill ();
+ /* Real text */
+ cr.move_to (area.x + area.width - get_layout_width (layout) - margin - 5,
+ area.y + area.height / 2 - get_layout_height (layout) / 2);
+ Gdk.cairo_set_source_rgba (cr, {1, 1, 1, 1});
+ Pango.cairo_show_layout (cr, layout);
+ }
+
+ /* Sender */
+ layout = widget.create_pango_layout (sender);
+ layout.set_ellipsize (Pango.EllipsizeMode.END);
+ layout.set_width (Pango.units_from_double (area.width - date_width - 5));
+ cr.move_to (area.x, area.y);
+ Gdk.cairo_set_source_rgba (cr, color_normal);
+ Pango.cairo_show_layout (cr, layout);
+ double y = sender_height;
+
+ /* Subject */
+ layout = widget.create_pango_layout (subject);
+ layout.set_font_description (font_medium);
+ layout.set_ellipsize (Pango.EllipsizeMode.END);
+ layout.set_width (Pango.units_from_double (area.width - unread_width));
+ cr.move_to (area.x, area.y + y);
+ Gdk.cairo_set_source_rgba (cr, color_normal);
+ Pango.cairo_show_layout (cr, layout);
+
+ y += subject_height;
+
+ /* The beginning of the message */
+ layout = widget.create_pango_layout (text);
+ layout.set_ellipsize (Pango.EllipsizeMode.END);
+ layout.set_width (Pango.units_from_double (area.width - unread_width));
+ cr.move_to (area.x, area.y + y);
+ Gdk.cairo_set_source_rgba (cr, color_insensitive);
+ layout.set_font_description (font_medium);
+ Pango.cairo_show_layout (cr, layout);
+
+ layout.set_font_description (old_desc); /* Restore the old font, it could
+ * cause some strange behavior */
+ }
+
+ double get_height (Gtk.Widget widget) {
+ /* Why "|" ? Because it is the highest char I found… */
+ Pango.Layout layout = widget.create_pango_layout ("|");
+ double y = get_layout_height (layout) + 5;
+ sender_height = y;
+
+ layout = widget.create_pango_layout ("|");
+ Pango.FontDescription font_medium = widget.get_pango_context ().get_font_description ();
+ Pango.FontDescription old_desc = font_medium;
+ font_medium.set_size (Pango.units_from_double (
+ Pango.units_to_double (font_medium.get_size ()) - 2));
+ layout.set_font_description (font_medium);
+
+ y += get_layout_height (layout) + 5;
+ subject_height = get_layout_height (layout) + 5;
+
+ layout = widget.create_pango_layout ("|");
+ layout.set_font_description (font_medium);
+ y += get_layout_height (layout) + 5;
+ layout.set_font_description (old_desc);
+
+ return y;
+ }
+}
+
diff --git a/postler/postler-messages.vala b/postler/postler-messages.vala
index 079c0c0..7cf16f2 100644
--- a/postler/postler-messages.vala
+++ b/postler/postler-messages.vala
@@ -128,41 +128,24 @@ public class Postler.Messages : Gtk.TreeView {
Gtk.TreeModel model, Gtk.TreeIter iter) {
Message message;
- var renderer = cell as Gtk.CellRendererText;
+ var renderer = cell as Postler.CellRendererConvo;
model.get (iter, Columns.MESSAGE, out message);
- if (message.uri == "error:") {
- renderer.markup = message.subject;
- renderer.xpad = renderer.ypad = 8;
- renderer.xalign = renderer.yalign = 0.5f;
- return;
- }
-
- renderer.xpad = renderer.ypad = 0;
- renderer.xalign = renderer.yalign = 0.0f;
-
if (message.uri == null) {
new Client ().get_message.begin (message, MessageFlags.NONE,
new Gtk.TreeRowReference (model, model.get_path (iter)));
- renderer.markup = "...";
+ renderer.subject = "...";
return;
}
- string subject = escape_text (message.subject ?? _("No subject"));
- string date = Postler.Content.format_date (message.date);
- long size = date.length;
- for (int j = 0; j < 20 - size; j++)
- date = date + " ";
-
- string from = escape_text (Postler.Contact.name_from_string (message.sender));
- int weight = message.unread ? Pango.Weight.BOLD : Pango.Weight.NORMAL;
-
- renderer.ellipsize = Pango.EllipsizeMode.MIDDLE;
- renderer.markup = ("<span weight=\"%d\">%s</span>\n" +
- "<small><tt>%s </tt></small> %s <b>%s</b>").printf (
- weight, from, date, subject,
- message.replies > 1 ? message.replies.to_string () : "");
+ renderer.subject = escape_text (message.subject ?? _("No subject"));
+ renderer.date = Postler.Content.format_date (message.date);
+ renderer.sender = escape_text (Postler.Contact.name_from_string (message.sender));
+ renderer.unread = (int)message.replies;
+ renderer.message_unread = message.unread;
+ renderer.flagged = message.flagged;
+ renderer.text = message.excerpt + "…";
}
void renderer_flag_toggled (Gtk.CellRendererToggle renderer,
@@ -238,12 +221,10 @@ public class Postler.Messages : Gtk.TreeView {
Gtk.cell_renderer_get_padding (renderer_flag, out xpad, null);
column.set_fixed_width (cell_width + xpad * 4);
- column = new Gtk.TreeViewColumn ();
+ var renderer_text = new Postler.CellRendererConvo ();
+ column = new Gtk.TreeViewColumn.with_attributes ("Messages", renderer_text, null);;
column.set_sizing (Gtk.TreeViewColumnSizing.FIXED);
column.set_title (_("Subject"));
- var renderer_text = new Gtk.CellRendererText ();
- renderer_text.set_fixed_height_from_font (2);
- column.pack_start (renderer_text, true);
column.set_cell_data_func (renderer_text, render_subject);
insert_column (column, -1);
More information about the Xfce4-commits
mailing list