ImageSet.cs :  » Game » RealmForge » CrayzEdsGui » Base » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » RealmForge 
RealmForge » CrayzEdsGui » Base » ImageSet.cs
#region LGPL License

/*************************************************************************
    Crazy Eddie's GUI System (http://crayzedsgui.sourceforge.net)
    Copyright (C)2004 Paul D Turner (crayzed@users.sourceforge.net)
  
  C# Port developed by Chris McGuirk (leedgitar@latenitegames.com)
  Compatible with the Axiom 3D Engine (http://axiomengine.sf.net)

    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.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*************************************************************************/

#endregion LGPL License

#region Using directives

using System;
using System.Data;
using System.Text;
using System.Xml;

#endregion

namespace CrayzEdsGui.Base{

  /// <summary>
  ///    Offers functions to define, access, and draw, a set of image components 
  ///    on a single graphical surface or <see cref="Texture"/>.
  /// </summary>
  /// <remarks>
  ///    Imageset objects are a means by which a single graphical image (file, Texture, etc), can be split into a number
  ///    of 'components' which can later be accessed via name.  The components of an Imageset can queried for
  ///    various details, and sent to the <see cref="Renderer"/> object for drawing.
  /// </remarks>
  public class Imageset : IDisposable {
    #region Constants

    /// <summary>
    ///    Name of the XSD file to use for validation.
    /// </summary>
    const string SchemaFileName = "Imageset.xsd";

    // TODO: Move into a central location
    /// <summary>
    ///    Default native horizontal resolution (for fonts and imagesets).
    /// </summary>
    const float    DefaultNativeHorzRes  = 640.0f;
    /// <summary>
    ///    Default native vertical resolution (for fonts and imagesets)
    /// </summary>
    const float    DefaultNativeVertRes  = 480.0f;

    #endregion Constants

    #region Fields

    /// <summary>
    ///    Name of this image set.
    /// </summary>
    protected string name;
    /// <summary>
    ///    List of images defined in this set.
    /// </summary>
    protected ImageList imageList = new ImageList();
    /// <summary>
    ///    Texture object that handles imagery for this Imageset.
    /// </summary>
    protected Texture texture;

    /// <summary>
    ///    True when auto-scaling is enabled.
    /// </summary>
    protected bool autoScale;
    /// <summary>
    ///    Current horizontal scaling factor.
    /// </summary>
    protected float horzScaling;
    /// <summary>
    ///    Current vertical scaling factor.
    /// </summary>
    protected float vertScaling;
    /// <summary>
    ///    Native horizontal/vertical resolution for this Imageset.
    /// </summary>
    protected Size nativeResolution;

    #endregion Fields

    #region Constructors

    internal Imageset(string name, Texture texture) {
      this.name = name;
      this.texture = texture;

      if(texture == null) {
        throw new ArgumentNullException("Texture object supplied for Imageset creation must not be null.");
      }

      // set scaling defaults
      autoScale = false;
      NativeResolution = new Size(DefaultNativeHorzRes, DefaultNativeVertRes);
    }

    /// <summary>
    ///    Internal constructor.  Constructs a new Imageset object using data contained in the specified file.
    /// </summary>
    /// <remarks>
    ///    This is internal, and only needs to be accessible via the various CreateXXX methods of the <see cref="ImagesetManager"/>.
    /// </remarks>
    /// <param name="fileName">The name of the Imageset data file that is to be processed.</param>
    /// <exception cref="System.IO.FileNotFoundException">If the specified file simply does not exist.</exception>
    internal Imageset(string fileName) {
      // set scaling defaults
      autoScale = false;
      NativeResolution = new Size(DefaultNativeHorzRes, DefaultNativeVertRes);

      // load the texture from file
      Load(fileName);
    }

    #endregion Constructors

    #region Public Properties

    /// <summary>
    ///    Get/Set flag indicating whether to use auto-scaling for this Imageset.
    /// </summary>
    /// <value>true to enable auto-scaling, false to disable auto-scaling.</value>
    public bool AutoScale {
      get {
        return autoScale;
      }
      set {
        if(value != autoScale) {
          autoScale = value;
          UpdateImageScalingFactors();
        }
      }
    }

    /// <summary>
    ///    Gets the number of images defined for this Imageset.
    /// </summary>
    /// <value>Integer value equal to the number of Image objects defined for the Imageset.</value>
    public int ImageCount {
      get {
        return imageList.Count;
      }
    }

    /// <summary>
    ///    Name of the Imageset.
    /// </summary>
    /// <value>String holding the name of this Imageset.</value>
    public string Name {
      get {
        return name;
      }
    }

    /// <summary>
    ///    Get/Set the native resolution for this Imageset.
    /// </summary>
    /// <value>Size describing the new native screen resolution for this Imageset.</value>
    public Size NativeResolution { 
      get {
        return nativeResolution;
      }
      set {
        nativeResolution = value;

        // re-calculate scaling factors and notify images as required 
        NotifyScreenResolution(GuiSystem.Instance.Renderer.Size);
      }
    }

    /// <summary>
    ///    Gets the Texture object for this Imageset.
    /// </summary>
    /// <value>Texture object that holds the imagery for this Imageset</value>
    public Texture Texture {
      get {
        return texture;
      }
    }

    #endregion Public Properties

    #region Protected Methods

    /// <summary>
    ///    Initialize the image set with information taken from the specified file.
    /// </summary>
    /// <param name="fileName">The name of the Imageset data file that is to be processed.</param>
    protected void Load(string fileName) {
      // unload old data and textures
      Unload();

      if (fileName == null || fileName.Length == 0) {
        throw new ArgumentException("Invalid Imageset name requested.", "fileName");
      }

      try {
        // initialize a validating reader with the schema
        XmlValidatingReader reader = new XmlValidatingReader(new XmlTextReader(fileName));
        reader.Schemas.Add("", SchemaFileName);

        // grab the Imageset and Image data
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);

        // grab the Imageset data
        XmlNode imagesetNode = doc.SelectSingleNode("//Imageset");

        name = imagesetNode.Attributes["Name"].Value;
        int horzRes = XmlConvert.ToInt32(imagesetNode.Attributes["NativeHorzRes"].Value);
        int vertRes = XmlConvert.ToInt32(imagesetNode.Attributes["NativeVertRes"].Value);

        this.NativeResolution = new Size(horzRes, vertRes);

        this.AutoScale = XmlConvert.ToBoolean(imagesetNode.Attributes["AutoScaled"].Value);

        string imageFileName = imagesetNode.Attributes["Imagefile"].Value;

        // create the texture for the imageset texture
        texture = GuiSystem.Instance.Renderer.CreateTexture(imageFileName);

        // load the data for each image defined
        foreach (XmlNode imageNode in imagesetNode.SelectNodes("Image")) {
          string imageName = imageNode.Attributes["Name"].Value;

          Rect rect = new Rect();
          rect.left  = XmlConvert.ToSingle(imageNode.Attributes["XPos"].Value);
          rect.top  = XmlConvert.ToSingle(imageNode.Attributes["YPos"].Value);
          rect.Width  = XmlConvert.ToSingle(imageNode.Attributes["Width"].Value);
          rect.Height = XmlConvert.ToSingle(imageNode.Attributes["Height"].Value);

          Point offset = new Point();
          offset.x = XmlConvert.ToSingle(imageNode.Attributes["XOffset"].Value);
          offset.y = XmlConvert.ToSingle(imageNode.Attributes["YOffset"].Value);

          // define a new image with the xml data
          DefineImage(imageName, rect, offset);
        }
      }
      catch (System.Xml.XmlException ex) {
        // unload anything that was created since this failed
        Unload();

        // just rethrow this one
        throw ex;
      }
    }

    /// <summary>
    ///    Set the Texture object to be used by this Imageset.
    /// </summary>
    /// <remarks>Changing textures on an Imageset that is in use is not a good idea!.</remarks>
    /// <param name="texture">
    ///    Texture object to be used by the Imageset.  The old texture is NOT disposed of, that is the clients responsibility.
    /// </param>
    protected void SetTexture(Texture texture) {
      if (texture == null) {
        throw new ArgumentNullException("An Imageset cannot be set to use a null texture");
      }

      this.texture = texture;
    }

    /// <summary>
    ///    Unloads all loaded data and leaves the Imageset in a clean (but un-usable) state.  
    /// </summary>
    /// <remarks>
    ///    This should be called for cleanup purposes only.
    /// </remarks>
    protected void Unload() {
      UndefineAllImages();

      // cleanup texture
      GuiSystem.Instance.Renderer.DestroyTexture(texture);
      texture = null;
    }

    /// <summary>
    ///    Sets the scaling factor for all Images that are a part of this Imageset.
    /// </summary>
    protected void UpdateImageScalingFactors() {
      float hScale = 1.0f, vScale = 1.0f;

      if (autoScale) {
        hScale = horzScaling;
        vScale = vertScaling;
      }

      for (int i = 0; i < imageList.Count; i++) {
        Image image = imageList[i];
        image.SetHorizontalScaling(hScale);
        image.SetVerticalScaling(vScale);
      }
    }

    #endregion Protected Methods

    #region Public Methods

    /// <summary>
    ///    Define a new Image for this Imageset.
    /// </summary>
    /// <param name="name">The name that will be assigned to the new Image, which must be unique within the Imageset.</param>
    /// <param name="position">Point describing the pixel location of the Image on the image file / texture associated with this Imageset.</param>
    /// <param name="size">Size describing the dimensions of the Image, in pixels.</param>
    /// <param name="renderOffset">Point describing the offsets, in pixels, that are to be applied to the Image when it is drawn.</param>
    /// <exception cref="AlreadyExistsException">If an image named <paramref name="name"/> already exists.</exception>
    public void DefineImage(string name, Point position, Size size, Point renderOffset) {
      Rect imageRect = new Rect(
        position.x, position.y,
        position.x + size.width,
        position.y + size.height);

      DefineImage(name, imageRect, renderOffset);
    }

    /// <summary>
    ///    Define a new Image for this Imageset.
    /// </summary>
    /// <param name="name">The name that will be assigned to the new Image, which must be unique within the Imageset.</param>
    /// <param name="imageRect"></param>
    /// <param name="renderOffset">Point describing the offsets, in pixels, that are to be applied to the Image when it is drawn.</param>
    /// <exception cref="AlreadyExistsException">If an image named <paramref name="name"/> already exists.</exception>
    public void DefineImage(string name, Rect imageRect, Point renderOffset) {
      if (IsImageDefined(name)) {
        throw new AlreadyExistsException("Imageset '{0}' already has a definition for Image '{1}'", this.name, name);
      }

      // get scaling factor
      float hScale = autoScale ? horzScaling : 1.0f;
      float vScale = autoScale ? vertScaling : 1.0f;

      // add the new image definition
      imageList.Add(name, new Image(name, this, imageRect, renderOffset, hScale, vScale));
    }

    /// <summary>
    ///    Queues an area of the associated Texture the be drawn on the screen.
    /// </summary>
    /// <remarks>Low-level routine to be used carefully!</remarks>
    /// <param name="sourceRect">Rect describing the area of the image file / texture that is to be queued for drawing.</param>
    /// <param name="destRect">Rect describing the area of the screen that will be filled with the imagery from <paramref name="sourceRect"/>.</param>
    /// <param name="z">float value specifying 'z' order.  0 is topmost with increasing values moving back into the screen.</param>
    /// <param name="clipRect">Rect describing a 'clipping rectangle' that will be applied when drawing the requested imagery.</param>
    /// <param name="colors">ColorRect holding the ARGB colors to be applied to the four corners of the rendered imagery.</param>
    public void Draw(Rect sourceRect, Rect destRect, float z, Rect clipRect, ColorRect colors) {
      // get the rect area that we will actually draw to (i.e. perform clipping)
      Rect finalRect = destRect.GetIntersection(clipRect);

      // check if rect was totally clipped
      if (finalRect.Width != 0) {
        float xScale = 1.0f / (float)texture.Width;
        float yScale = 1.0f / (float)texture.Height;

        float xTexPerPix = sourceRect.Width / destRect.Width;
        float yTexPerPix = sourceRect.Height / destRect.Height;

        // calculate final, clipped, texture co-ordinates
        Rect texRect = new Rect(
          (sourceRect.left + ((finalRect.left - destRect.left) * xTexPerPix)) * xScale,
          (sourceRect.top + ((finalRect.top - destRect.top) * yTexPerPix)) * yScale,
          (sourceRect.right + ((finalRect.right - destRect.right) * xTexPerPix)) * xScale,
          (sourceRect.bottom + ((finalRect.bottom - destRect.bottom) * yTexPerPix)) * yScale);

        // queue a quad to be rendered
        texture.Renderer.AddQuad(finalRect, z, texture, texRect, colors);
      }
    }

    /// <summary>
    ///    Gets the image with the specified name.
    /// </summary>
    /// <param name="name">The name of the Image object to be returned.</param>
    /// <returns>Image object that has the requested name.</returns>
    public Image GetImage(string name) {
      if (!IsImageDefined(name)) {
        throw new UnknownObjectException("Image '{0}' could not be found in Imageset '{1}'", name, this.name);
      }

      return imageList[name];
    }

    /// <summary>
    ///    Returns true if an Image with the specified name exists.
    /// </summary>
    /// <param name="name">The name of the image to look for.</param>
    /// <returns>True if the image exists within this Imageset, false otherwise.</returns>
    public bool IsImageDefined(string name) {
      return imageList[name] != null;
    }

    /// <summary>
    ///    Notify the Imageset of the current (usually new) display resolution.
    /// </summary>
    /// <param name="size">Size describing the display resolution.</param>
    public void NotifyScreenResolution(Size size) {
      horzScaling = size.width / nativeResolution.width;
      vertScaling = size.height / nativeResolution.height;

      if (autoScale) {
        UpdateImageScalingFactors();
      }
    }

    /// <summary>
    ///    Removes the definitions for all Image objects currently defined in the Imageset.
    /// </summary>
    public void UndefineAllImages() {
      imageList.Clear();
    }

    /// <summary>
    ///    Remove the definition for the Image with the specified name.  
    ///    If no such Image exists, nothing happens.
    /// </summary>
    /// <param name="name">The name of the Image object to be removed from the Imageset.</param>
    public void UndefineImage(string name) {
      imageList.Remove(name);
    }

    #endregion Public Methods

    #region IDisposable Members

    /// <summary>
    ///    Cleans up resources in use.
    /// </summary>
    public void Dispose() {
      Unload();
    }

    #endregion
  }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.