Logo Search packages:      
Sourcecode: galaxium version File versions  Download package

CellRendererContact.cs

/*
 * Galaxium Messenger
 * Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
 *
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;
using System.Text;

using Gdk;
using Gtk;

using Anculus.Core;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;
using Galaxium.Protocol;
using Galaxium.Protocol.Gui;

namespace Galaxium.Gui.GtkGui
{
      public class CellRendererContact: Gtk.CellRendererText
      {
            int _emoticonmargin = 1;
            string _text;
            string _markup = string.Empty;
            List<ITextChunk> _chunks = new List<ITextChunk> ();
            IProtocol _protocol;
            bool _showEmoticons = true;
            
            public bool ShowEmoticons
            {
                  get { return _showEmoticons; }
                  set { _showEmoticons = value; }
            }

            public new string Markup
            {
                  get { return _markup; }
                  set
                  {
                        if (_markup == value)
                              return;
                        
                        //Log.Debug ("Old markup: {0}", _markup.Replace ("\n", ""));

                        _markup = value;

                        char accel_char;
                        Pango.AttrList attrs;
                        Pango.Global.ParseMarkup (_markup, char.MaxValue, out attrs, out _text, out accel_char);
                        
                        //Log.Debug ("New markup: {0}", _markup.Replace ("\n", ""));
                        
                        SplitMarkup ();
                  }
            }
            
            public int EmoticonMargin
            {
                  get { return _emoticonmargin; }
                  set { _emoticonmargin = value; }
            }
            
            public CellRendererContact (IProtocol protocol)
            {
                  _protocol = protocol;
            }
            
            void SplitMarkup ()
            {
                  lock (_chunks)
                  {
                        _chunks.Clear ();
                        
                        if (!string.IsNullOrEmpty (_text))
                              _chunks.AddRange (PangoUtility.SplitMarkup (_markup, _protocol, null));
                  }
            }
            
            protected override void Render (Drawable window,
                                            Gtk.Widget widget,
                                            Gdk.Rectangle background_area,
                                            Gdk.Rectangle cell_area,
                                            Gdk.Rectangle expose_area,
                                            Gtk.CellRendererState flags)
      {
                  int xoffset, yoffset, width, height;
                  GetSize (widget, ref cell_area, out xoffset, out yoffset, out width, out height);

                  int y = (int) Ypad;
                  int x = (int) Xpad;
                  
                  int pw, ph, lineheight = 0;
                  
                  Gtk.StateType state;
                  if (!this.Sensitive)
                        state = Gtk.StateType.Insensitive;
                  else if ((flags & Gtk.CellRendererState.Selected) == Gtk.CellRendererState.Selected)
                        state = (widget.HasFocus ? Gtk.StateType.Selected : Gtk.StateType.Active);
                  else if (((flags & Gtk.CellRendererState.Prelit) == Gtk.CellRendererState.Prelit) && (widget.State == Gtk.StateType.Prelight))
                        state = Gtk.StateType.Prelight;
                  else
                        state = (widget.State == Gtk.StateType.Insensitive ? Gtk.StateType.Insensitive : Gtk.StateType.Normal);

                  lock (_chunks)
                  {
                        int fontMaxHeight = 0;
                        int fontHeight = 16;
                        
                        foreach (ITextChunk chunk in _chunks)
                        {
                              if ((!_showEmoticons) || (chunk.Type != TextChunkType.Emoticon))
                              {
                                    char accel_char;
                                    Pango.AttrList attrs;
                                    string txt;
                                    Pango.Global.ParseMarkup (chunk.Text, char.MaxValue, out attrs, out txt, out accel_char);
                                    
                                    if (txt == "\n")
                                    {
                                          y += lineheight;
                                          x = (int)Xpad;
                                          lineheight = 0;
                                          fontMaxHeight = 0;
                                          attrs.Dispose ();
                                          continue;
                                    }
                                    
                                    if (string.IsNullOrEmpty (txt))
                                    {
                                          Log.Warn ("No text in markup {0}", chunk.Text);
                                          
                                          foreach (ITextChunk c in _chunks)
                                                Log.Debug ("{0}: {1}", c.Type, c.Text);
                                          
                                          attrs.Dispose ();
                                          continue;
                                    }
                                    
                                    Pango.Layout lay = widget.CreatePangoLayout (txt);
                                    lay.FontDescription = this.FontDesc;
                                    lay.Wrap = this.WrapMode;
                                    lay.Ellipsize = this.Ellipsize;
                                    lay.Attributes = attrs;
                                    
                                    lay.GetPixelSize(out pw, out ph);
                                    
                                    Pango.Rectangle inkRect, logicalRect;
                                    lay.GetPixelExtents (out inkRect, out logicalRect);
                                    fontHeight = logicalRect.Height;
                                    
                                    if (fontHeight > fontMaxHeight)
                                          fontMaxHeight = fontHeight;
                                    
                                    if (ph > lineheight)
                                          lineheight = ph;
                                    
                                    //check if we need ellipsizing
                                    if (Ellipsize != Pango.EllipsizeMode.None && (cell_area.X + x + pw) > (cell_area.Width + cell_area.X))
                                          lay.Width = Convert.ToInt32 ((cell_area.Width - xoffset - x - 2 * Xpad) * Pango.Scale.PangoScale);
                                    
                                    //paint the layout
                                    Gtk.Style.PaintLayout (widget.Style,
                                                           window,
                                                           state,
                                                           true,
                                                           cell_area,
                                                           widget,
                                                           "cellrenderertext",
                                                           cell_area.X + x,
                                                           cell_area.Y + y + ((fontMaxHeight - fontHeight) / 2),
                                                           lay);
                                    
                                    lay.Dispose ();
                                    attrs.Dispose ();
                                    
                                    x += pw;
                              }
                              else
                              {
                                    x += _emoticonmargin;
                                    
                                    IEmoticon emot = ((EmoticonTextChunk)chunk).Emoticon;
                                    Gdk.Pixbuf pixbuf = new Pixbuf (emot.Data);
                                    
                                    int newH = fontHeight;
                                    int newW = (int)(((double)pixbuf.Width / (double)pixbuf.Height) * newH);
                                    Gdk.Pixbuf scaled = pixbuf.ScaleSimple (newW, newH, InterpType.Bilinear);
                                    
                                    if (scaled != null)
                                    {
                                          if (cell_area.X + x < (cell_area.Width + cell_area.X))
                                                window.DrawPixbuf (null, scaled, 0, 0, cell_area.X + x,
                                                                   cell_area.Y + y, scaled.Width, scaled.Height,
                                                                   RgbDither.None, 0, 0);
                                          
                                          x += scaled.Width + _emoticonmargin;
                                          
                                          scaled.Dispose ();
                                    }
                                    else
                                          Log.Error ("Unable to scale emoticon pixmap");
                                    
                                    pixbuf.Dispose ();
                              }
                        }
                  }
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index