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

PixbufUtility.cs

/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2005-2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2007 Ben Motmans <ben.motmans@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.Timers;
using System.Collections.Generic;

using Gdk;
using G=Gtk;
using Gtk;

using Anculus.Core;
using Anculus.Gui;
using Galaxium.Core;

namespace Galaxium.Gui.GtkGui
{
      public delegate void FadeCompleteDelegate ();
      
      internal class FadeTimer : System.Timers.Timer
      {
            G.Image _fromImage;
            Pixbuf _originalPixbuf;
            Pixbuf _toPixbuf;
            int _step = 0;
            FadeCompleteDelegate _callback;
            
            public FadeTimer (G.Image fromImage, Pixbuf toPixbuf, FadeCompleteDelegate callback) : base (15)
            {
                  _fromImage = fromImage;
                  _originalPixbuf = fromImage.StorageType == G.ImageType.Pixbuf ? fromImage.Pixbuf.Copy () : fromImage.PixbufAnimation.StaticImage.Copy ();
                  _toPixbuf = PixbufUtility.GetScaledPixbuf(toPixbuf, _originalPixbuf.Width, _originalPixbuf.Height);
                  _callback = callback;
                  
                  Elapsed += FadeTimerElapsed;
            }
            
            private void FadeTimerElapsed (object sender, ElapsedEventArgs args)
            {
                  _step += 5;
                  
                  if (_step < 255)
                  {
                        ThreadUtility.SyncDispatch (new VoidDelegate (delegate
                        {
                              _fromImage.FromPixbuf = PixbufUtility.GetAlphaPixbuf (_originalPixbuf, _toPixbuf, _step);
                        }));
                  }
                  else
                  {
                        Stop ();
                        
                        if (_callback != null)
                              _callback ();
                  }
            }
      }
      
      public static class PixbufUtility
      {
            public static void FadeInImage (G.Image fromImage, Pixbuf toPixbuf, FadeCompleteDelegate callback)
            {
                  if ((fromImage.StorageType != G.ImageType.Pixbuf) && (fromImage.StorageType != G.ImageType.Animation))
                  {
                        // Nothing to fade from, just set the new pixbuf
                        
                        fromImage.FromPixbuf = toPixbuf;
                        
                        if (callback != null)
                              callback ();
                        
                        return;
                  }
                  
                  FadeTimer timer = new FadeTimer (fromImage, toPixbuf, callback);
                  timer.Start ();
            }
            
            public static void FadeInImage (G.Image fromImage, Pixbuf toPixbuf)
            {
                  FadeInImage (fromImage, toPixbuf, null);
            }
            
            public static Pixbuf GetAlphaPixbuf (Pixbuf original, Pixbuf to, int step)
            {
                  Gdk.Pixbuf compbuf = new Gdk.Pixbuf(original.Colorspace, true, original.BitsPerSample, original.Width, original.Height);
                  compbuf.Fill(0);
                  
                  if (step > 255)
                        step = 255;
                  
                  original.Composite(compbuf, 0, 0, original.Width, original.Height, 0.0, 0.0, (to.Height / original.Height), (to.Width / original.Width), Gdk.InterpType.Bilinear, 255);
                  to.Composite(compbuf, 0, 0, original.Width, original.Height, 0.0, 0.0, 1.0, 1.0, Gdk.InterpType.Bilinear, step);
                  
                  return (compbuf);
            }
            
            public static Pixbuf GetShadedPixbuf (Pixbuf original, ContactTreeDetailLevel detailLevel)
            {
                  // Get the frame pixbuf.
                  Gdk.Pixbuf fadebuf = GetScaledPixbuf(IconUtility.GetIcon("display-fade"), original.Width, original.Height); ;
                  
                  if (fadebuf == null)
                        return(null);
                  
                  // Create the composite pixbuf with the primary image properties.
                  Gdk.Pixbuf compbuf = new Gdk.Pixbuf(original.Colorspace, original.HasAlpha, original.BitsPerSample, original.Width, original.Height);
                  
                  // Clear the composite data, otherwise we will see garbage.
                  compbuf.Fill(0);
                  
                  // Overlay the images on top of eachother if they are present.
                  original.Composite(compbuf, 0, 0, original.Width, original.Height, 0.0, 0.0, 1.0, 1.0, Gdk.InterpType.Bilinear, 255);
                  fadebuf.Composite(compbuf, 0, 0, original.Width, original.Height, 0.0, 0.0, (fadebuf.Height / original.Height), (fadebuf.Height / original.Width), Gdk.InterpType.Bilinear, 255);
                  
                  Pixbuf pixbuf = GetFramedPixbuf(compbuf, detailLevel);
                  
                  return(pixbuf);
            }
            
            public static Gdk.Pixbuf GetScaledCroppedPixbuf (Pixbuf pixbuf, int w, int h)
            {
                  if (pixbuf.Height > pixbuf.Width)
                  {
                        // The image is taller than width.
                        double ratio = (double)w / (double)pixbuf.Width;
                        int newh = (int)((double)pixbuf.Height * ratio);
                        
                        pixbuf = GetScaledPixbuf (pixbuf, w, newh);
                        return (GetCroppedPixbuf (pixbuf, w, h));
                  }
                  else if (pixbuf.Width > pixbuf.Height)
                  {
                        // The image is wider than tall.
                        double ratio = (double)h / (double)pixbuf.Height;
                        int neww = (int)((double)pixbuf.Width * ratio);
                        
                        pixbuf = GetScaledPixbuf (pixbuf, neww, h);
                        return (GetCroppedPixbuf (pixbuf, w, h));
                  }
                  else
                  {
                        // The image is square. We only need to scale.
                        return (GetScaledPixbuf (pixbuf, w, h));
                  }
            }
            
            public static Gdk.Pixbuf GetCroppedPixbuf (Pixbuf original, int w, int h)
            {
                  int src_x = (original.Width/2) - (w/2);
                  int src_y = (original.Height/2) - (w/2);
                  Gdk.Pixbuf dest_pixbuf = new Pixbuf (original.Colorspace, original.HasAlpha, original.BitsPerSample, w, h);
                  
                  original.CopyArea (src_x, src_y, w, h, dest_pixbuf, 0, 0);
                  
                  return (dest_pixbuf);
            }
            
            public static Gdk.Pixbuf GetScaledPixbuf(Pixbuf pixbuf, int x, int y)
            {
                  if (pixbuf.Height != y || pixbuf.Width != x)
                        return(pixbuf.ScaleSimple(x, y+1, Gdk.InterpType.Bilinear));
                  else
                        return(pixbuf);
            }
            
            public static Pixbuf GetFramedPixbuf (Pixbuf original, ContactTreeDetailLevel detailLevel)
            {
                  ThrowUtility.ThrowIfNull ("original", original);

                  switch (detailLevel)
                  {
                        case ContactTreeDetailLevel.Compact:
                              return (GetFramedPixbuf (original, PixbufRendererFrameSize.Small));
                        case ContactTreeDetailLevel.Normal:
                              return (GetFramedPixbuf (original, PixbufRendererFrameSize.Medium));
                        case ContactTreeDetailLevel.Detailed:
                              return (GetFramedPixbuf (original, PixbufRendererFrameSize.Large));
                        case ContactTreeDetailLevel.Info:
                              return (GetFramedPixbuf (original, PixbufRendererFrameSize.Huge));
                      case ContactTreeDetailLevel.List:
                            return (GetFramedPixbuf (original, PixbufRendererFrameSize.Info));
                        default:
                              return null;
                  }
            }

            public static Pixbuf GetFramedPixbuf (Pixbuf original, PixbufRendererFrameSize frameSize)
            {
                  ThrowUtility.ThrowIfNull ("original", original);

                  Pixbuf frame = null;
                  int width = 0;
                  int height = 0;

                  switch (frameSize)
                  {
                        case PixbufRendererFrameSize.Small:
                              width = height = 16;
                              frame = IconUtility.GetIcon ("frame-small", IconSizes.Other);
                              break;
                        case PixbufRendererFrameSize.Medium:
                              width = height = 32;
                              frame = IconUtility.GetIcon ("frame-medium", IconSizes.Other);
                              break;
                        case PixbufRendererFrameSize.Large:
                              width = height = 48;
                              frame = IconUtility.GetIcon ("frame-large", IconSizes.Other);
                              break;
                        case PixbufRendererFrameSize.Huge:
                              width = height = 96;
                              frame = IconUtility.GetIcon ("frame-huge", IconSizes.Other);
                              break;
                        case PixbufRendererFrameSize.Info:
                              width = height = 58;
                              frame = IconUtility.GetIcon ("frame-info", IconSizes.Other);
                              break;
                        default:
                              return null;
                  }
                  
                  // Create the composite pixbuf with the primary image properties.
                  Pixbuf composite = new Pixbuf (original.Colorspace, original.HasAlpha, original.BitsPerSample, width, height);
                  
                  // Clear the composite data, otherwise we will see garbage.
                  composite.Fill (0);
                  
                  // Overlay the images on top of eachother if they are present.
                  frame.Composite (composite, 0, 0, frame.Width, frame.Height, 0.0, 0.0, (width / frame.Width), (height / frame.Height), InterpType.Bilinear, 255);
                  original.Composite (composite, 2, 2, width-4, height-4, 0.0, 0.0, (double)width / (double)original.Width, (double)height / (double)original.Height, InterpType.Bilinear, 255);
                  return composite;
            }

            public static Pixbuf GetOverlayedRightPixbuf (Pixbuf original, params Pixbuf[] overlays)
            {
                  ThrowUtility.ThrowIfNull ("original", original);
                  ThrowUtility.ThrowIfNull ("overlays", overlays);
                  
                  // Create the composite pixbuf with the primary image properties.
                  Pixbuf composite = new Pixbuf (original.Colorspace, original.HasAlpha, original.BitsPerSample, original.Width, original.Height);
                  
                  // Clear the composite data, otherwise we will see garbage.
                  composite.Fill (0);
                  
                  // Overlay the images on top of eachother if they are present.
                  original.Composite (composite, 0, 0, original.Width, original.Height, 0.0, 0.0, 1.0, 1.0, InterpType.Nearest, 255);
                  
                  foreach (Pixbuf pb in overlays)
                        pb.Composite (composite, original.Width - (pb.Width + 2), original.Height - (pb.Height + 2), pb.Width, pb.Height, original.Width - (pb.Width + 2), original.Height - (pb.Height + 2), 1.0, 1.0, InterpType.Nearest, 255);
                  
                  return composite;
            }
            
            public static Pixbuf GetOverlayedLeftPixbuf (Pixbuf original, params Pixbuf[] overlays)
            {
                  ThrowUtility.ThrowIfNull ("original", original);
                  ThrowUtility.ThrowIfNull ("overlays", overlays);
                  
                  // Create the composite pixbuf with the primary image properties.
                  Pixbuf composite = new Pixbuf (original.Colorspace, original.HasAlpha, original.BitsPerSample, original.Width, original.Height);
                  
                  // Clear the composite data, otherwise we will see garbage.
                  composite.Fill (0);
                  
                  // Overlay the images on top of eachother if they are present.
                  original.Composite (composite, 0, 0, original.Width, original.Height, 0.0, 0.0, 1.0, 1.0, InterpType.Nearest, 255);
                  
                  foreach (Pixbuf pb in overlays)
                        pb.Composite (composite, 2, original.Height - (pb.Height + 2), pb.Width, pb.Height, 2, original.Height - (pb.Height + 2), 1.0, 1.0, InterpType.Nearest, 255);
                  
                  return composite;
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index