OverlayElement.cs :  » Game » RealmForge » Axiom » Overlays » 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 » Axiom » Overlays » OverlayElement.cs
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using Axiom.Collections;
using Axiom.Core;
using Axiom.MathLib;
using Axiom.Scripting;
using Axiom.Graphics;

namespace Axiom.Overlays{
  /// <summary>
  ///   Abstract definition of a 2D element to be displayed in an Overlay.
  /// </summary>
  /// <remarks>
  ///   This class abstracts all the details of a 2D element which will appear in
  ///   an overlay. In fact, not all OverlayElement instances can be directly added to an
  ///   Overlay, only those which are OverlayElementContainer instances (a subclass of this class).
  ///   OverlayElementContainer objects can contain any OverlayElement however. This is just to 
  ///   enforce some level of grouping on widgets.
  ///   <p/>
  ///   OverlayElements should be managed using GuiManager. This class is responsible for
  ///   instantiating / deleting elements, and also for accepting new types of element
  ///   from plugins etc.
  ///   <p/>
  ///   Note that positions / dimensions of 2D screen elements are expressed as parametric
  ///   values (0.0 - 1.0) because this makes them resolution-independent. However, most
  ///   screen resolutions have an aspect ratio of 1.3333:1 (width : height) so note that
  ///   in physical pixels 0.5 is wider than it is tall, so a 0.5x0.5 panel will not be
  ///   square on the screen (but it will take up exactly half the screen in both dimensions).
  /// </remarks>
    public abstract class OverlayElement : IRenderable {
        #region Member variables
    
        protected string name;
        protected bool isVisible;
        protected bool isCloneable;
        protected float left, top, width, height;
        protected string materialName;
        protected Material material;
        protected string text;
        protected ColorEx color;
        protected MetricsMode metricsMode;
        protected HorizontalAlignment horzAlign;
        protected VerticalAlignment vertAlign;

        // Pixel-mode positions, used in GMM_PIXELS mode.
        protected int pixelTop;
        protected int pixelLeft;
        protected int pixelWidth;
        protected int pixelHeight;

        // parent container
        protected OverlayElementContainer parent;
        // overlay this element is attached to
        protected Overlay overlay;

        protected float derivedLeft, derivedTop;
        protected bool isDerivedOutOfDate;
        // Flag indicating if the vertex positons need recalculating
        protected bool geomPositionsOutOfDate;

        // Zorder for when sending to render queue
        // Derived from parent
        protected int zOrder;

        protected bool isEnabled;
        /// <summary>Parser method lookup for script parameters.</summary>
        protected Hashtable attribParsers = new Hashtable();
        protected LightList emptyLightList = new LightList();
    protected Hashtable customParams = new Hashtable();

        #endregion
    
        #region Constructors

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        protected internal OverlayElement(string name) {
            this.name = name;
            width = 1.0f;
            height = 1.0f;
            isVisible = true;
            isDerivedOutOfDate = true;
            isCloneable = true;
            metricsMode = MetricsMode.Relative;
            horzAlign = HorizontalAlignment.Left;
            vertAlign = VerticalAlignment.Top;
            geomPositionsOutOfDate = true;
            isEnabled = true;

            RegisterParsers();
        }
    
        #endregion
    
        #region Methods
    
        /// <summary>
        ///    Copys data from the template element to this element to clone it.
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        public virtual void CopyFromTemplate(OverlayElement template) {
            PropertyInfo[] props = template.GetType().GetProperties();

            for(int i = 0; i < props.Length; i++) {
                PropertyInfo prop = props[i];

                // if the prop is not settable, then skip
                if(!prop.CanWrite || !prop.CanRead) {
                    Console.WriteLine(prop.Name);
                    continue;
                }

                object srcVal = prop.GetValue(template, null);
                prop.SetValue(this, srcVal, null);
            }
        }

        /// <summary>
        ///    Hides an element if it is currently visible.
        /// </summary>
        public void Hide() {
            isVisible = false;
        }

        /// <summary>
        ///    Initialize the OverlayElement.
        /// </summary>
        public abstract void Initialize();

        /// <summary>
        ///    Internal method for notifying the gui element of it's parent and ultimate overlay.
        /// </summary>
        /// <param name="parent">Parent of this element.</param>
        /// <param name="overlay">Overlay this element belongs to.</param>
        public virtual void NotifyParent(OverlayElementContainer parent, Overlay overlay) {
            this.parent = parent;
            this.overlay = overlay;
            isDerivedOutOfDate = true;
        }

        /// <summary>
        ///    Internal method to notify the element when Zorder of parent overlay
        ///    has changed.
        /// </summary>
        /// <remarks>
        ///    Overlays have explicit Z orders. OverlayElements do not, they inherit the 
        ///    ZOrder of the overlay, and the Zorder is incremented for every container
        ///    nested within this to ensure that containers are displayed behind contained
        ///    items. This method is used internally to notify the element of a change in
        ///    final zorder which is used to render the element.
        /// </remarks>
        /// <param name="zOrder"></param>
        public virtual void NotifyZOrder(int zOrder) {
            this.zOrder = zOrder;
        }

        /// <summary>
        ///    Tells this element to recaculate it's position.
        /// </summary>
        public virtual void PositionsOutOfDate() {
            geomPositionsOutOfDate = true;
        }

        /// <summary>
        ///    Registers all attribute names with their respective parser.
        /// </summary>
        /// <remarks>
        ///    Methods meant to serve as attribute parsers should use a method attribute to 
        /// </remarks>
        protected virtual void RegisterParsers() {
            MethodInfo[] methods = this.GetType().GetMethods(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Static);
      
            // loop through all methods and look for ones marked with attributes
            for(int i = 0; i < methods.Length; i++) {
                // get the current method in the loop
                MethodInfo method = methods[i];
        
                // see if the method should be used to parse one or more material attributes
                AttributeParserAttribute[] parserAtts = 
                    (AttributeParserAttribute[])method.GetCustomAttributes(typeof(AttributeParserAttribute), true);

                // loop through each one we found and register its parser
                for(int j = 0; j < parserAtts.Length; j++) {
                    AttributeParserAttribute parserAtt = parserAtts[j];

                    attribParsers.Add(parserAtt.Name, Delegate.CreateDelegate(typeof(AttributeParserMethod), method));
                } // for
            } // for
        }

        /// <summary>
        ///    
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void SetDimensions(float width, float height) {
            if(metricsMode == MetricsMode.Pixels) {
                pixelWidth = (int)width;
                pixelHeight = (int)height;
            }
            else {
                this.width = width;
                this.height = height;
            }

            isDerivedOutOfDate = true;
            PositionsOutOfDate();
        }

        /// <summary>
        ///    Sets param values from script values.  Subclasses can define their own params in addition to what
        ///    this base class already defines.
        /// </summary>
        /// <param name="param"></param>
        /// <param name="val"></param>
        public bool SetParam(string param, string val) {
            if(!attribParsers.ContainsKey(param)) {
                return false;
            }

            AttributeParserMethod parser = (AttributeParserMethod)attribParsers[param];
            
            // call the parser method, passing in an array of the split val param, and this element for the optional object
            // MONO: As of 1.0.5, complains if the second param is not explicitly passed as an object array
            parser(val.Split(' '), new object[] {this} );

            return true;
        }

        /// <summary>
        ///    Sets the position of this element.
        /// </summary>
        /// <param name="left"></param>
        /// <param name="top"></param>
        public void SetPosition(float left, float top) {
            if(metricsMode == MetricsMode.Pixels) {
                pixelLeft = (int)left;
                pixelTop = (int)top;
            }
            else {
                this.left = left;
                this.top = top;
            }

            isDerivedOutOfDate = true;
            PositionsOutOfDate();
        }

        /// <summary>
        ///    Shows this element if it was previously hidden.
        /// </summary>
        public void Show() {
            isVisible = true;
        }

        /// <summary>
        ///    Internal method to update the element based on transforms applied.
        /// </summary>
        public virtual void Update() {
            if(metricsMode == MetricsMode.Pixels && (OverlayManager.Instance.HasViewportChanged || geomPositionsOutOfDate)) {
                float vpWidth = OverlayManager.Instance.ViewportWidth;
                float vpHeight = OverlayManager.Instance.ViewportHeight;

                left = (float)pixelLeft / vpWidth;
                width = (float)pixelWidth / vpWidth;
                top = (float)pixelTop / vpHeight;
                height = (float)pixelHeight / vpHeight;
                geomPositionsOutOfDate = true;
            }

            // container subclasses will update children too
            UpdateFromParent();

            // update our own position geometry
            if(geomPositionsOutOfDate) {
                UpdatePositionGeometry();
                geomPositionsOutOfDate = false;
            }
        }

        /// <summary>
        ///    Updates this elements transform based on it's parent.
        /// </summary>
        public virtual void UpdateFromParent() {
            float parentLeft, parentTop, parentBottom, parentRight;

            parentLeft = parentTop = parentBottom = parentRight = 0;

            if(parent != null) {
                parentLeft = parent.DerivedLeft;
                parentTop = parent.DerivedTop;

                // derive right position
                if(horzAlign == HorizontalAlignment.Center || horzAlign == HorizontalAlignment.Right) {
                    parentRight = parentLeft + parent.Width;
                }
                // derive bottom position
                if(vertAlign == VerticalAlignment.Center || vertAlign == VerticalAlignment.Bottom) {
                    parentBottom = parentTop + parent.Height;
                }
            }
            else {
                // with no real parent, the "parent" is actually the full viewport size
                parentLeft = parentTop = 0.0f;
                parentRight = parentBottom = 1.0f;
            }

            // sort out position based on alignment
            // all we do is derived the origin, we don't automatically sort out the position
            // This is more flexible than forcing absolute right & middle 

            switch(horzAlign) {
                case HorizontalAlignment.Center:
                    derivedLeft = ((parentLeft + parentRight) * 0.5f) + left;
                    break;

                case HorizontalAlignment.Left:
                    derivedLeft = parentLeft + left;
                    break;

                case HorizontalAlignment.Right:
                    derivedLeft = parentRight + left;
                    break;
            }

            switch(vertAlign) {
                case VerticalAlignment.Center:
                    derivedTop = ((parentTop + parentBottom) * 0.5f) + top;
                    break;

                case VerticalAlignment.Top:
                    derivedTop = parentTop + top;
                    break;

                case VerticalAlignment.Bottom:
                    derivedTop = parentBottom + top;
                    break;
            }

            isDerivedOutOfDate = false;
        }

        /// <summary>
        ///    Internal method which is triggered when the positions of the element get updated,
        ///    meaning the element should be rebuilding it's mesh positions. Abstract since
        ///    subclasses must implement this.
        /// </summary>
        protected abstract void UpdatePositionGeometry();

        /// <summary>
        ///    Internal method to put the contents onto the render queue.
        /// </summary>
        /// <param name="queue">Current render queue.</param>
        public virtual void UpdateRenderQueue(RenderQueue queue) {
            if(isVisible) {
                queue.AddRenderable(this, (ushort)zOrder, RenderQueueGroupID.Overlay);
            }
        }

        #endregion
    
        #region Properties

        /// <summary>
        ///    Sets the color on elements that support it.
        /// </summary>
        /// <remarks>
        ///    Note that not all elements support this, but it is still a relevant base class property.
        /// </remarks>
        public virtual ColorEx Color {
            get {
                return color;
            }
            set {
                color = value;
            }
        }

        /// <summary>
        ///    Gets the 'left' position as derived from own left and that of parents.
        /// </summary>
        public virtual float DerivedLeft {
            get {
                if(isDerivedOutOfDate) {
                    UpdateFromParent();
                }
                return derivedLeft;
            }
        }

        /// <summary>
        ///    Gets the 'top' position as derived from own top and that of parents.
        /// </summary>
        public virtual float DerivedTop {
            get {
                if(isDerivedOutOfDate) {
                    UpdateFromParent();
                }
                return derivedTop;
            }
        }

        /// <summary>
        ///    Gets/Sets whether or not this element is enabled.
        /// </summary>
        public bool Enabled {
            get {
                return isEnabled;
            }
            set {
                isEnabled = value;
            }
        }

        /// <summary>
        ///    Gets/Sets the height of this element.
        /// </summary>
        public float Height {
            get {
                if(metricsMode == MetricsMode.Pixels) {
                    return pixelHeight;
                }
                else {
                    return height;
                }
            }
            set {
                if(metricsMode == MetricsMode.Pixels) {
                    pixelHeight = (int)value;
                }
                else {
                    height = value;
                }

                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Gets/Sets the horizontal origin for this element.
        /// </summary>
        /// <remarks>
        ///    By default, the horizontal origin for a OverlayElement is the left edge of the parent container
        ///    (or the screen if this is a root element). You can alter this by using this property, which is
        ///    especially useful when you want to use pixel-based metrics (see MetricsMode) since in this
        ///    mode you can't use relative positioning.
        ///    <p/>
        ///    For example, if you were using Pixels metrics mode, and you wanted to place a 30x30 pixel
        ///    crosshair in the center of the screen, you would use Center with a 'left' property of -15.
        ///    <p/>
        ///    Note that neither Center nor Right alter the position of the element based
        ///    on it's width, you have to alter the 'left' to a negative number to do that; all this
        ///    does is establish the origin. This is because this way you can align multiple things
        ///    in the center and right with different 'left' offsets for maximum flexibility.
        /// </remarks>
        public virtual HorizontalAlignment HorizontalAlignment {
            get {
                return horzAlign;
            }
            set {
                horzAlign = value;
                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Gets whether or not this element is a container type.
        /// </summary>
        public virtual bool IsContainer {
            get {
                return false;
            }
        }

        /// <summary>
        ///    Gets/Sets whether or not this element can be cloned.
        /// </summary>
        public virtual bool IsCloneable {
            get {
                return isCloneable;
            }
            set {
                isCloneable = value;
            }
        }

        /// <summary>
        ///    Returns whether or not this element is currently visible.
        /// </summary>
        public bool IsVisible {
            get {
                return isVisible;
            }
        }

        /// <summary>
        ///    Gets/Sets the left position of this element.
        /// </summary>
        public float Left {
            get {
                if(metricsMode == MetricsMode.Pixels) {
                    return pixelLeft;
                }
                else {
                    return left;
                }
            }
            set {
                if(metricsMode == MetricsMode.Pixels) {
                    pixelLeft = (int)value;
                }
                else {
                    left = value;
                }

                isDerivedOutOfDate = true;
                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Gets/Sets the name of the material in use by this element.
        /// </summary>
        public virtual string MaterialName {
            get {
                return materialName;
            }
            set {
                materialName = value;
                material = MaterialManager.Instance.GetByName(materialName);

                if(material == null) {
                    throw new Exception(string.Format("Could not find material '{0}'.", materialName));
                }
                material.Load();
            }
        }

        /// <summary>
        ///    Tells this element how to interpret the position and dimension values it is given.
        /// </summary>
        /// <remarks>
        ///    By default, OverlayElements are positioned and sized according to relative dimensions
        ///    of the screen. This is to ensure portability between different resolutions when you
        ///    want things to be positioned and sized the same way across all resolutions. However, 
        ///    sometimes you want things to be sized according to fixed pixels. In order to do this,
        ///    you can call this method with the parameter Pixels. Note that if you then want
        ///    to place your element relative to the center, right or bottom of it's parent, you will
        ///    need to use the HorizontalAlignment and VerticalAlignment properties.
        /// </remarks>
        public virtual MetricsMode MetricsMode {
            get {
                return metricsMode;
            }
            set {
                metricsMode = value;

                if(metricsMode == MetricsMode.Pixels) {
                    // Copy settings into pixel versions
                    // Relative versions will be derived at viewport change time
                    pixelLeft = (int)left;
                    pixelTop = (int)top;
                    pixelWidth = (int)width;
                    pixelHeight = (int)height;
                }

                isDerivedOutOfDate = true;
                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Gets the name of this element.
        /// </summary>
        public string Name {
            get {
                return name;
            }
        }

        /// <summary>
        ///    Gets the parent container of this element.
        /// </summary>
        public OverlayElementContainer Parent {
            get {
                return parent;
            }
        }

        /// <summary>
        ///    Sets the caption on elements that support it. 
        /// </summary>
        /// <remarks>
        ///    Not all elements support this, but it is still a relevant base class property.
        /// </remarks>
        public virtual string Text {
            get {
                return text;
            }
            set {
                text = value;
                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Gets/Sets the top position of this element.
        /// </summary>
        public float Top {
            get {
                if(metricsMode == MetricsMode.Pixels) {
                    return pixelTop;
                }
                else {
                    return top;
                }
            }
            set {
                if(metricsMode == MetricsMode.Pixels) {
                    pixelTop = (int)value;
                }
                else {
                    top = value;
                }

                isDerivedOutOfDate = true;
                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Type name of this element.
        /// </summary>
        public abstract string Type {
            get;
        }

        /// <summary>
        ///    Sets the vertical origin for this element.
        /// </summary>
        /// <remarks>
        ///    By default, the vertical origin for a OverlayElement is the top edge of the parent container
        ///    (or the screen if this is a root element). You can alter this by using this property, which is
        ///    especially useful when you want to use pixel-based metrics (see MetricsMode) since in this
        ///    mode you can't use relative positioning.
        ///    <p/>
        ///    For example, if you were using Pixels metrics mode, and you wanted to place a 30x30 pixel
        ///    crosshair in the center of the screen, you would use Center with a 'top' property of -15.
        ///    <p/>
        ///    Note that neither Center or Bottom alter the position of the element based
        ///    on it's height, you have to alter the 'top' to a negative number to do that; all this
        ///    does is establish the origin. This is because this way you can align multiple things
        ///    in the center and bottom with different 'top' offsets for maximum flexibility.
        /// </remarks>
        public virtual VerticalAlignment VerticalAlignment {
            get {
                return vertAlign;
            }
            set {
                vertAlign = value;
                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Gets/Sets the width of this element.
        /// </summary>
        public float Width {
            get {
                if(metricsMode == MetricsMode.Pixels) {
                    return pixelWidth;
                }
                else {
                    return width;
                }
            }
            set {
                if(metricsMode == MetricsMode.Pixels) {
                    pixelWidth = (int)value;
                }
                else {
                    width = value;
                }

                PositionsOutOfDate();
            }
        }

        /// <summary>
        ///    Gets the z ordering of this element.
        /// </summary>
        public int ZOrder {
            get {
                return zOrder;
            }
        }

    #endregion

        #region IRenderable Members

    public bool CastsShadows {
      get {
        return false;
      }
    }

        public Material Material {
            get {
                return material;
            }
        }

        public bool NormalizeNormals {
            get {
                return false;
            }
        }

        public Technique Technique {
            get {
                return material.GetBestTechnique();
            }
        }

        /// <summary>
        ///    Abstract.  Force subclasses to implement this.
        /// </summary>
        /// <param name="op"></param>
        public abstract void GetRenderOperation(RenderOperation op);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="matrices"></param>
        public void GetWorldTransforms(Axiom.MathLib.Matrix4[] matrices) {
            overlay.GetWorldTransforms(matrices);
        }

        /// <summary>
        /// 
        /// </summary>
        public ushort NumWorldTransforms {
            get {
                return 1;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public bool UseIdentityProjection {
            get {
                return true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public bool UseIdentityView {
            get {
                return true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Axiom.Graphics.SceneDetailLevel RenderDetail {
            get {
                return SceneDetailLevel.Solid;
            }
        }

        /// <summary>
        ///    Implementation of IRenderable.
        /// </summary>
        /// <param name="camera"></param>
        /// <returns></returns>
        public float GetSquaredViewDepth(Camera camera) {
            return 10000 - this.ZOrder;
        }

        /// <summary>
        /// 
        /// </summary>
        public Quaternion WorldOrientation {
            get {
                return overlay.DerivedOrientation;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Vector3 WorldPosition {
            get {
                return overlay.DerivedPosition;
            }
        }

        public LightList Lights {
            get {
                return emptyLightList;
            }
        }

    public Vector4 GetCustomParameter(int index) {
      if(customParams[index] == null) {
        throw new Exception("A parameter was not found at the given index");
      }
      else {
        return (Vector4)customParams[index];
      }
    }

    public void SetCustomParameter(int index, Vector4 val) {
      customParams[index] = val;
    }

    public void UpdateCustomGpuParameter(GpuProgramParameters.AutoConstantEntry entry, GpuProgramParameters gpuParams) {
      if(customParams[entry.data] != null) {
        gpuParams.SetConstant(entry.index, (Vector4)customParams[entry.data]);
      }
    }

        #endregion

        #region Script parser methods

        [AttributeParser("metrics_mode", "OverlayElement")]
        public static void ParseMetricsMode(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.MetricsMode = (MetricsMode)ScriptEnumAttribute.Lookup(parms[0], typeof(MetricsMode));
        }

        [AttributeParser("horz_align", "OverlayElement")]
        public static void ParseHorzAlign(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.HorizontalAlignment = (HorizontalAlignment)ScriptEnumAttribute.Lookup(parms[0], typeof(HorizontalAlignment));
        }

        [AttributeParser("vert_align", "OverlayElement")]
        public static void ParseVertAlign(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.VerticalAlignment = (VerticalAlignment)ScriptEnumAttribute.Lookup(parms[0], typeof(VerticalAlignment));
        }

        [AttributeParser("top", "OverlayElement")]
        public static void ParseTop(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.Top = StringConverter.ParseFloat(parms[0]);
        }

        [AttributeParser("left", "OverlayElement")]
        public static void ParseLeft(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.Left = StringConverter.ParseFloat(parms[0]);
        }

        [AttributeParser("width", "OverlayElement")]
        public static void ParseWidth(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.Width = StringConverter.ParseFloat(parms[0]);
        }

        [AttributeParser("height", "OverlayElement")]
        public static void ParseHeight(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.Height = StringConverter.ParseFloat(parms[0]);
        }

        [AttributeParser("caption", "OverlayElement")]
        public static void ParseCaption(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            // reconstruct the single string since the caption could have spaces
            for(int i = 0; i < parms.Length; i++) {
                sb.Append(parms[i]);
                sb.Append(" ");
            }

            element.Text = sb.ToString();
        }

        [AttributeParser("material", "OverlayElement")]
        public static void ParseMaterial(string[] parms, params object[] objects) {
            OverlayElement element = (OverlayElement)objects[0];

            element.MaterialName = parms[0];
        }

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