Window.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 » Window.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

using System;
using System.Collections;

namespace CrayzEdsGui.Base{
  /// <summary>
  ///     Definition of a Window class.
  /// </summary>
  public abstract class Window : IDisposable {
    // -----------------------------
    #region Fields

    #region General Data
    
    /// <summary>
    ///    GuiSystem unique name of this window.
    /// </summary>
    protected string name;
    /// <summary>
    ///     List of child windows attached to this window.
    /// </summary>
    protected WindowList children = new WindowList();
    /// <summary>
    ///    Holds the active metrics mode for this window.
    /// </summary>
    protected MetricsMode metricsMode;
    /// <summary>
    ///     Window that has captured inputs.
    /// </summary>
    protected static Window captureWindow;
    /// <summary>
    ///     Previous window to have mouse capture.
    /// </summary>
    protected Window oldCapture;
    /// <summary>
    ///     This window's parent window.
    /// </summary>
    protected Window parent;
    /// <summary>
    ///    Holds reference to the Window object's current Font.
    /// </summary>
    protected Font font;
    /// <summary>
    ///     Text / label/ caption for this window.
    /// </summary>
    protected string text;
    /// <summary>
    ///     Optional user defined ID for this window.
    /// </summary>
    protected int id;
    /// <summary>
    ///    Alpha transparency setting for the Window.
    /// </summary>
    protected float alpha;
    /// <summary>
    ///    This Window objects area (pixels relative to parent.
    /// </summary>
    protected Rect absArea;
    /// <summary>
    ///    This Window objects area (decimal fractions relative to parent).
    /// </summary>
    protected Rect relArea;
    /// <summary>
    ///    Holds reference to the Window objects current mouse cursor image.
    /// </summary>
    protected Image mouseCursor;

    #endregion General Data

    #region Min/Max Sizes

    /// <summary>
    ///    Current minimum size for the window (this is always stored in pixels).
    /// </summary>
    protected Size minSize;
    /// <summary>
    ///    Current maximum size for the window (this is always stored in pixels).
    /// </summary>
    protected Size maxSize;

    #endregion Min/Max Sizes

    #region Settings

    /// <summary>
    ///     True when window is enabled.
    /// </summary>
    protected bool isEnabled;
    /// <summary>
    ///     True if window is visible (not hidden).
    /// </summary>
    protected bool isVisible;
    /// <summary>
    ///     True if the window is active (has input focus).
    /// </summary>
    protected bool isActive;
    /// <summary>
    ///     True if this window is to be kept within it's parents area.
    /// </summary>
    protected bool isClippedByParent;
    /// <summary>
    ///    True when Window will be auto-destroyed by parent.
    /// </summary>
    protected bool isDestroyedByParent;
    /// <summary>
    ///     True if this is a top-most window (i.e. Always on top).
    /// </summary>
    protected bool isAlwaysOnTop;
    /// <summary>
    ///    True if the Window inherits alpha from the parent Window.
    /// </summary>
    protected bool inheritsAlpha;
    /// <summary>
    ///     True if window should restore any 'old' capture when it releases capture.
    /// </summary>
    protected bool restoreOldCapture;

    #endregion Settings

    #endregion Fields
    // -----------------------------

    // -----------------------------
    #region Constructor

    /// <summary>
    ///     Default constructor.
    /// </summary>
    public Window(string name) {
      this.name = name;

      // setup
      metricsMode = MetricsMode.Relative;
      alpha = 1.0f;
    
      mouseCursor = GuiSystem.Instance.DefaultMouseCursor;

      // settings
      isEnabled = true;
      isVisible = true;
      isClippedByParent = true;
      isDestroyedByParent = true;
      inheritsAlpha = true;

      // position and size
      absArea = new Rect(0, 0, 0, 0);
      relArea = new Rect(0, 0, 0, 0);

      // TODO: Change these to named constants
      minSize = new Size(0, 0);
      maxSize = new Size(1024, 768);  //640x480

      // init to empty text
      text = string.Empty;
    }

    #endregion Constructor
    // -----------------------------

    // -----------------------------
    #region Properties

    /// <summary>
    ///    Get/Set whether or not this Window will automatically be destroyed when its parent Window is destroyed.
    /// </summary>
    /// <value>
    ///    true to have the Window auto-destroyed when its parent is destroyed (default), or false to have the Window
    ///    remain after its parent is destroyed.
    /// </value>
    [WidgetProperty("DesroyedByParent")]
    public bool DestroyedByParent {
      get {
        return isDestroyedByParent;
      }
      set {
        isDestroyedByParent = value;
      }
    }

    /// <summary>
    ///    Gets the effective alpha value that will be used when rendering this window, taking into account inheritance of parent
    ///    window(s) alpha.
    /// </summary>
    /// <value>The effective alpha that will be applied to this Window when rendering.  Will be between 0.0f and 1.0f.</value>
    public float EffectiveAlpha {
      get {
        if((parent == null) || (!this.inheritsAlpha)) {
          return alpha;
        }

        return alpha * parent.EffectiveAlpha;
      }
    }

    /// <summary>
    ///    Returns the reference to the active Font for this window.
    /// </summary>
    /// <value>
    ///    Reference to the Font being used by this Window.  
    ///    If the window has no assigned font, the default font is returned.
    ///  </value>
    [WidgetProperty("Font")]
    public Font Font {
      get {
        // just use the default system font if this window doesn't have
        // its own specified
        if(font == null) {
          return GuiSystem.Instance.DefaultFont;
        }

        return font;
      }
      set
      {
        font = value;
        OnFontChanged( new GuiEventArgs() );
      }
    }

    /// <summary>
    ///    Get/Set whether this Window will inherit alpha from its parent windows.
    /// </summary>
    /// <value>true if the Window should use inherited alpha, or false if the Window should have an independant alpha value.</value>
    [WidgetProperty("InheritsAlpha")]
    public bool InheritsAlpha {
      get {
        return inheritsAlpha;
      }
      set {
        inheritsAlpha = value;
        OnInheritsAlphaChanged(new GuiEventArgs());
      }
    }

    /// <summary>
    ///     Gets/Sets whether this window is 'always on top' or not.
    /// </summary>
    /// <value>
    ///    true if this Window is always show on top of other normal windows.  
    ///    false if the Window has normal z-order behavior.
    ///  </value>
    [WidgetProperty("AlwaysOnTop")]
    public bool AlwaysOnTop {
      get {
        return isAlwaysOnTop;
      }
      set {
        // only react to an actual change
        if (isAlwaysOnTop != value) {
          isAlwaysOnTop = value;

          // move us infront of sibling windows with the same 'always-on-top' setting as we have.
          if (parent != null) {
            Window origParent = parent;

            // remove the window from parents list
            origParent.RemoveChildImpl(this);

            // re-add window to parent, which will place it behind all top-most windows,
            // which in either case is the right place for this window
            origParent.AddChildImpl(this);

            OnZChangedImpl();
          }

          OnAlwaysOnTopChanged(new GuiEventArgs());
        }
      }
    }

    /// <summary>
    ///     Returns true if this window is in a disabled state.
    /// </summary>
    public bool IsEnabled {
      get {
        bool parentEnabled = 
          (parent == null) ? true : parent.IsEnabled;

        return (isEnabled && parentEnabled);
      }
      set {
        if(isEnabled != value) {
          isEnabled = value;

          if(isEnabled) {
            OnEnabled(new GuiEventArgs());
          }
          else {
            OnDisabled(new GuiEventArgs());
          }
        }
      }
    }

    [WidgetProperty("Disabled")]
    public bool IsDisabled
    {
      get
      {
        return !IsEnabled;
      }
      set
      {
        IsEnabled = !value;
      }
    }

    /// <summary>
    ///     Returns true if this window is visible (not hidden).
    /// </summary>
    [WidgetProperty("Visible")]
    public bool Visible {
      get {
        bool parentVisible = 
          (parent == null) ? true : parent.Visible;

        return (isVisible && parentVisible);
      }
      set {
        if(isVisible != value) {
          isVisible = value;

          if(isVisible) {
            OnShown(new GuiEventArgs());
          }
          else {
            OnHidden(new GuiEventArgs());
          }
        }
      }
    }

    /// <summary>
    ///     Returns true if this window is active. 
    /// </summary>
    /// <remarks>
    ///     The active window is always the front most window.
    /// </remarks>
    public bool IsActive {
      get {
        bool parentActive = 
          (parent == null) ? true : parent.IsActive;

        return (isActive && parentActive);
      }
    }

    /// <summary>
    ///     Returns true if this window is to be clipped by it's parent.
    /// </summary>
    [WidgetProperty("ClippedByParent")]
    public bool IsClippedByParent {
      get {
        return isClippedByParent;
      }
      set {
        if(isClippedByParent != value) {
          isClippedByParent = value;
          OnClippingChanged(new GuiEventArgs());
        }
      }
    }

    /// <summary>
    ///     Gets/Sets the width of the window (in unspecified units).
    /// </summary>
    [WidgetProperty("Width")]
    public float Width {
      get {
        if(this.MetricsMode == MetricsMode.Relative) {
          return relArea.Width;
        }

        return absArea.Width;
      }
      set {
        this.Size = new Size(value, Height);
      }
    }

    /// <summary>
    ///     Gets/Sets the height of the window (in unspecified units).
    /// </summary>
    /// <remarks>
    ///    Interpretation of the value is dependant upon the current metrics system set for the Window.
    /// </remarks>
    [WidgetProperty("Height")]
    public float Height {
      get {
        if(this.MetricsMode == MetricsMode.Relative) {
          return relArea.Height;
        }

        return absArea.Height;
      }
      set {
        this.Size = new Size(Width, value);
      }
    }

    /// <summary>
    ///     Get/Set the x position of the window.
    /// </summary>
    /// <remarks>Interpretation of return value depends upon the metric type in use by this window.</remarks>
    /// <value>
    ///    float value that specifies the x position of the Window relative to it's parent, depending on the metrics system in use for this
    ///    Window, this value will specify either pixels or a decimal fraction of the width of the parent Window.
    /// </value>
    [WidgetProperty("XPosition")]
    public float X {
      get {
        if(this.MetricsMode == MetricsMode.Relative) {
          return relArea.left;
        }

        return absArea.left;
      }
      set {
        this.Position = new Point(value, Y);
      }
    }

    /// <summary>
    ///     Get/Set the y position of the window.
    /// </summary>
    /// <remarks>Interpretation of return value depends upon the metric type in use by this window.</remarks>
    /// <value>
    ///    float value that specifies the y position of the Window relative to it's parent, depending on the metrics system in use for this
    ///    Window, this value will specify either pixels or a decimal fraction of the width of the parent Window.
    /// </value>
    [WidgetProperty("YPosition")]
    public float Y {
      get {
        if(this.MetricsMode == MetricsMode.Relative) {
          return relArea.top;
        }

        return absArea.top;
      }
      set {
        this.Position = new Point(X, value);
      }
    }

    /// <summary>
    ///     Gets/Sets the ID assigned to this window.
    /// </summary>
    [WidgetProperty("ID")]
    public int ID {
      get {
        return id;
      }
      set {
        id = value;
      }
    }

    /// <summary>
    ///    Get/Set the maximum size for this window.
    /// </summary>
    /// <value>
    ///    Size describing the maximum size for the window.  For absolute metrics, the Size values are in screen pixels,
    ///    for relative metrics the Size values are relative to the display size.
    /// </value>
    [WidgetProperty("MaxSize")]
    public Size MaximumSize {
      get {
        if(this.MetricsMode == MetricsMode.Absolute) {
          return maxSize;
        }
        else {
          return AbsoluteToRelativeImpl(null, maxSize);
        }
      }
      set {
        if (this.MetricsMode == MetricsMode.Absolute) {
          maxSize = value;
        }
        else {
          maxSize = RelativeToAbsoluteImpl(null, value);
        }

        absArea.ConstrainSizeMax(maxSize);
      }
    }

    /// <summary>
    ///    Set the minimum size for this window.
    /// </summary>
    /// <value>
    ///    Size describing the minimum size for the window.  For absolute metrics, the Size values are in screen pixels,
    ///    for relative metrics the Size values are relative to the display size
    /// </value>
    [WidgetProperty("MinSize")]
    public Size MinimumSize {
      get {
        if(this.MetricsMode == MetricsMode.Absolute) {
          return minSize;
        }
        else {
          return AbsoluteToRelativeImpl(null, minSize);
        }
      }
      set {
        if (this.MetricsMode == MetricsMode.Absolute) {
          minSize = value;
        }
        else {
          minSize = RelativeToAbsoluteImpl(null, value);
        }

        absArea.ConstrainSizeMin(minSize);
      }
    }

    /// <summary>
    ///    Gets/Sets the current metrics mode employed by the window.
    /// </summary>
    /// <value>One of the values of the <see cref="MetricsMode"/> enumerated type, that describes the metrics mode to be used by the Window.</value>
    [MetricsModeProperty( "MetricsMode" )]
    public MetricsMode MetricsMode
    {
      get {
        if(metricsMode == MetricsMode.Inherited) {
          if(parent != null) {
            return parent.MetricsMode;
          }

          return MetricsMode.Relative;
        }

        return metricsMode;
      }
      set {
        metricsMode = value;
      }
    }

    /// <summary>
    ///    Get a reference to the mouse cursor image to use when the mouse is within this window.
    /// </summary>
    [WidgetProperty( "MouseCursorImage" )]
    public Image Cursor {
      get {
        if(mouseCursor != null && mouseCursor != GuiSystem.Instance.DefaultMouseCursor) {
          return mouseCursor;
        }
        else {
          return GuiSystem.Instance.DefaultMouseCursor;
        }
      }
    }

    /// <summary>
    ///    The name of this window.
    /// </summary>
    /// <value>The unique name of this window.</value>
    public string Name {
      get {
        return name;
      }
    }

    /// <summary>
    ///     Gets/Sets a reference to this window's parent window.
    /// </summary>
    public Window Parent {
      get {
        return parent;
      }
      set {
        parent = value;
      }
    }

    /// <summary>
    ///     Gets the number of child windows attached to this window.
    /// </summary>
    public int ChildCount {
      get {
        return children.Count;
      }
    }

    /// <summary>
    ///     Gets a reference to the top-most active child window starting at 'this'.
    /// </summary>
    /// <remarks>
    ///     Returns 'this' if it is 'this' window which is active.
    ///     Returns null if neither this window nor any children are active.
    /// </remarks>
    public Window ActiveChild {
      get {
        // if this window is not active just return null, since it's children can't be
        // active if 'this' is not.
        if (!this.IsActive) {
          return null;
        }

        // Travel through the child list(s) until we find the active window
        for (int i = 0; i < children.Count; i++) {
          Window child = children[i];

          if (child.IsActive) {
            return child.ActiveChild;
          }
        }

        // no child is active (or has no children), so return 'this' as active window
        return this;
      }
    }

    /// <summary>
    ///    Get/Set the current alpha value for this window.
    /// </summary>
    /// <remarks>
    ///    The alpha value set for any given window may or may not be the final alpha value that is used when rendering.  All window
    ///    objects, by default, inherit alpha from thier parent window(s) - this will blend child windows, relatively, down the line of
    ///    inheritance.  This behavior can be overridden via <see cref="InheritsAlpha"/>.  To return the true alpha value that will be
    ///    applied when rendering, use <see cref="EffectiveAlpha"/>.
    /// </remarks>
    [WidgetProperty("Alpha")]
    public float Alpha {
      get {
        return alpha;
      }
      set {
        alpha = value;
        OnAlphaChanged(new GuiEventArgs());
      }
    }

    /// <summary>
    ///    Gets a Rect describing the clipped inner area for this window.
    /// </summary>
    /// <value>Rect describing, in appropriately clipped screen pixel co-ordinates, the window object's inner rect area.</value>
    public Rect InnerRect {
      get {
        // clip to parent?
        if(IsClippedByParent && parent != null) {
          return UnclippedInnerRect.GetIntersection(parent.InnerRect);
        }

        // clip to screen
        return UnclippedInnerRect.GetIntersection(GuiSystem.Instance.Renderer.Rect);
      }
    }

    /// <summary>
    ///     Returns true if input is captured by 'this'.
    /// </summary>
    public bool IsCapturedByThis {
      get {
        return captureWindow == this;
      }
    }

    /// <summary>
    ///     Returns true if input is capptured by some ancestor of 'this'.
    /// </summary>
    public bool IsCapturedByAncestor {
      get {
        return IsAncestor(captureWindow);
      }
    }

    /// <summary>
    ///     Returns true if input is captured by a child of 'this'.
    /// </summary>
    public bool IsCapturedByChild {
      get {
        return IsChild(captureWindow);
      }
    }

    /// <summary>
    ///    Gets a Rect describing the Window area in screen space.
    /// </summary>
    /// <remarks>
    ///    This has been made virtual to ease some customisations that require more specialised clipping requirements.
    /// </remarks>
    /// <value>
    ///    Rect object that describes the area covered by the Window.  The values in the returned Rect are in screen pixels.  The
    ///    returned Rect is clipped as appropriate and depending upon the 'ClippedByParent' setting.
    /// </value>
    public virtual Rect PixelRect {
      get {
        // clip to parent?
        if(IsClippedByParent && parent != null) {
          return UnclippedPixelRect.GetIntersection(parent.InnerRect);
        }

        // clip to screen
        return UnclippedPixelRect.GetIntersection(GuiSystem.Instance.Renderer.Rect);
      }
    }

    /// <summary>
    ///    Get/Set the position of the window.
    /// </summary>
    /// <remarks>Interpretation of return value depends upon the metric type in use by this window.</remarks>
    /// <value>
    ///    Point that describes the position of the Window relative to it's parent, depending on the metrics system in use for this
    ///    Window, the values in the Point will specify either pixels or decimal fractions of the total width and height of the parent.
    /// </value>
    [WidgetProperty("Position")]
    public Point Position {
      get {
        if(this.MetricsMode == MetricsMode.Relative) {
          return relArea.Position;
        }

        return absArea.Position;
      }
      set {
        if(this.MetricsMode == MetricsMode.Relative) {
          relArea.Position = value;
          absArea.Position = RelativeToAbsoluteImpl(parent, value);
        }
        else {
          absArea.Position = value;
          relArea.Position = AbsoluteToRelativeImpl(parent, value);
        }

        OnMoved(new GuiEventArgs());
      }
    }

    /// <summary>
    ///    Gets a Rect object that describes the Window area.
    /// </summary>
    /// <value>
    ///    Rect that describes the area covered by the Window.  The values in the returned Rect are in whatever form is set
    ///    as the current metric type.  The returned Rect is unclipped and relative to the Window objects parent.
    /// </value>
    [WidgetProperty("Rect")]
    public Rect Rect {
      get {
        if(this.metricsMode == MetricsMode.Relative) {
          return relArea;
        }
        
        return absArea;
      }
      set
      {
        Position = value.Position;
        Size = value.Size;
      }
    }

    /// <summary>
    ///    Get/Set the size of the window.
    /// </summary>
    /// <remarks>Interpretation of return value depends upon the metric type in use by this window.</remarks>
    /// <value>
    ///    Size that describes the dimensions of the Window.  Depending upon the metrics system in use for this window, the
    ///    values will either be in pixels, or as decimal fractions of the width and height of the parent Window.
    /// </value>
    [WidgetPropertyAttribute("Size")]
    public Size Size {
      get {
        if(this.MetricsMode == MetricsMode.Relative) {
          return relArea.Size;
        }

        return absArea.Size;
      }
      set {
        if(this.MetricsMode == MetricsMode.Relative) {
          relArea.Size = value;

          // update Rect for the other metrics system
          absArea.Size = RelativeToAbsoluteImpl(parent, value);
          absArea.ConstrainSize(maxSize, minSize);
        }
        else {
          absArea.Size = value;
          absArea.ConstrainSize(maxSize, minSize);

          // update Rect for the other metrics system
          relArea.Size = AbsoluteToRelativeImpl(parent, value);
        }

        OnSized(new GuiEventArgs());
      }
    }

    /// <summary>
    ///     Gets/Sets the window's text string.
    /// </summary>
    [StringPropertyAttribute("Text")]
    public string Text {
      get {
        return text;
      }
      set {
        text = value;

        // event notification
        OnTextChanged(new WindowEventArgs(this));
      }
    }

    /// <summary>
    ///    Return a Rect that describes, unclipped, the inner rectangle for this window.  The inner rectangle is
    ///    typically an area that excludes some frame or other rendering that should not be touched by subsequent rendering.
    /// </summary>
    /// <value>
    ///    Rect that describes, in unclipped screen pixel co-ordinates, the window object's inner rect area.
    /// </value>
    public virtual Rect UnclippedInnerRect {
      get {
        return UnclippedPixelRect;
      }
    }

    /// <summary>
    ///    Gets a Rect describing the Window area unclipped, in screen space.
    /// </summary>
    /// <value>
    ///    Rect that describes the area covered by the Window.  The values in the returned 
    ///    Rect are in screen pixels.  The returned rect is fully unclipped.
    /// </value>
    public Rect UnclippedPixelRect {
      get {
        if(this.MetricsMode == MetricsMode.Relative) {
          return WindowToScreen(new Rect(0, 0, 1, 1));
        }
        else {
          return WindowToScreen(new Rect(0, 0, absArea.Width, absArea.Height));
        }
      }
    }

    #endregion Properties
    // -----------------------------

    // -----------------------------
    #region Static Properties

    /// <summary>
    ///     Returns a references to the window that currently has input capture, or null if none.
    /// </summary>
    public static Window CaptureWindow {
      get {
        return captureWindow;
      }
    }

    #endregion Static Properties
    // -----------------------------   

    #region Abstract Members

    #region Methods

    /// <summary>
    ///     Perform the actual rendering for this Window.
    /// </summary>
    /// <param name="z">float value specifying the base Z co-ordinate that should be used when rendering.</param>
    protected abstract void DrawSelf(float z);

    #endregion Methods

    #endregion Abstract Members

    // -----------------------------      
    #region Methods

    /// <summary>
    ///    Activate the Window giving it input focus and bringing it to the top of all non always-on-top Windows.
    /// </summary>
    /// <remarks>
    ///    A Window cannot be programmatically 'disabled', as such.  To disable a Window, you must activate another one.
    /// </remarks>
    public void Activate() {
      MoveToFront();
    }

    /// <summary>
    ///    Add the named Window as a child of this Window.  If the Window \a name is already attached to a Window, it is detached before
    ///    being added to this Window.
    /// </summary>
    /// <param name="name">The name of the Window to be added.</param>
    public void AddChild(string name) {
      AddChild(WindowManager.Instance.GetWindow(name));
    }

    /// <summary>
    ///     Add the specified Window as a child of this Window.  If the Window \a window is already attached to a Window, it is detached before
    ///     being added to this Window.
    /// </summary>
    /// <param name="window">Reference to a window to add as a child.</param>
    public void AddChild(Window window) {
      AddChildImpl(window);
      OnChildAdded(new WindowEventArgs(window));
      window.OnZChangedImpl();
    }

    /// <summary>
    ///    Removes the child window with the specified name.
    /// </summary>
    /// <param name="name">Name of the child window to remove.</param>
    public void RemoveChild(string name) {
      Window child = GetChild(name);

      if(child != null) {
        RemoveChild(child);
      }
    }

    /// <summary>
    ///    Removes the child window with the specified ID.
    /// </summary>
    /// <param name="id">ID of the child to remove.</param>
    public void RemoveChild(int id) {
      Window child = GetChild(id);

      if(child != null) {
        RemoveChild(child);
      }
    }

    /// <summary>
    ///     Removes 'window' from this window's child list.
    /// </summary>
    /// <param name="window">Reference to a window to add as a child.</param>
    public void RemoveChild(Window window) {
      RemoveChildImpl(window);
      OnChildRemoved(new WindowEventArgs(window));
      window.OnZChangedImpl();
    }

    /// <summary>
    ///    Return a reference to the child window with the specified name.
    /// </summary>
    /// <remarks>
    ///    This function will throw an exception if no child object with the given name is attached.  This decision
    ///    was made (over returning 'null' if no window was found) so that client code can assume that if the call
    ///    returns it has a valid window pointer.  We provide the <see cref="IsChild"/> functions for checking if a given window
    ///    is attached.
    /// </remarks>
    /// <param name="name">The name of the child window to return.</param>
    /// <returns>Window object attached to this window that has the specified <paramref name="name"/>.</returns>
    /// <exception cref="UnknownObjectException">Thrown if no window named <paramref name="name"/> is attached to this Window.</exception>
    public Window GetChild(string name) {
      for (int i = 0; i < children.Count; i++) {
        if (children[i].Name == name) {
          return children[i];
        }
      }

      throw new UnknownObjectException("There is no child named '{0}' attached to window '{1}'", name, this.Name);
    }

    /// <summary>
    ///    Return a reference to the first attached child window with the specified ID.
    /// </summary>
    /// <remarks>
    ///    This function will throw an exception if no child object with the given ID is attached.  This decision
    ///    was made (over returning 'null' if no window was found) so that client code can assume that if the call
    ///    returns it has a valid window pointer.  We provide the <see cref="IsChild"/> functions for checking if a given window
    ///    is attached.
    /// </remarks>
    /// <param name="id">The ID of the child window to return.</param>
    /// <returns>The (first) Window object attached to this window that has the specified <paramref name="id"/>.</returns>
    /// <exception cref="UnknownObjectException">Thrown if no window named <paramref name="name"/> is attached to this Window.</exception>
    public Window GetChild(int id) {
      for (int i = 0; i < children.Count; i++) {
        if (children[i].ID == id) {
          return children[i];
        }
      }

      throw new UnknownObjectException("There is no child with ID '{0}' attached to window '{1}'", id, this.Name); 
    }

    /// <summary>
    ///     Gets a reference to the child window at the specified index.
    /// </summary>
    /// <param name="index">Index of the child to retreive.</param>
    /// <returns>The child at the specified index, or null if the index is out of bounds.</returns>
    public Window GetChildAtIndex(int index) {
      if (index < 0 || index >= children.Count) {
        return null;
      }

      return (Window) children[index];
    }

    /// <summary>
    ///     Returns the child Window that is 'hit' by the given position
    /// </summary>
    /// <param name="position">Point that describes the position to check in screen pixels.</param>
    /// <returns>Child located at the specified position, or null if none exists.</returns>
    public Window GetChildAtPosition(Point position) {
      // scan child list backwards (Windows towards the end of the list are considered 'in front of' those towards the begining)
      for (int i = children.Count - 1; i >= 0; i--) {
        Window child = children[i];

        // only check if the child is visible
        if (child.Visible) {
          // recursively scan children of this child windows...
          Window window = child.GetChildAtPosition(position);

          // return window if we found a 'hit' down the chain somewhere
          if (window != null) {
            return window;
          }
          // none of our children hit
          else {
            if (child is GuiSheet) 
              continue; // can't click a GuiSheet. -- njk-patch
            // see if this child is hit and return it if it is
            if (child.IsHit(position)) {
              return child;
            }
          }
        }
      }

      // nothing hit
      return null;
    }

    /// <summary>
    ///    returns whether a Window with the specified name is currently 
    ///    attached to this Window as a child.
    /// </summary>
    /// <param name="name">The name of the Window to look for.</param>
    /// <returns>True if a Window named <paramref name="name" /> is currently attached to this Window as a child, else false.</returns>
    public bool IsChild(string name) {
      for(int i = 0; i < this.ChildCount; i++) {
        if(children[i].Name == name) {
          return true;
        }
      }

      return false;
    }

    /// <summary>
    ///    Returns whether at least one window with the given ID code is attached as a child.
    /// </summary>
    /// <remarks>
    ///    ID codes are client assigned and may or may not be unique, and as such, the return from this function
    ///    will only have meaning to the client code.
    /// </remarks>
    /// <param name="id">ID code to look for.</param>
    /// <returns>
    ///    True if a child window was found with the ID code <paramref name="id" />, 
    ///    or false if no child window was found with that id.
    /// </returns>
    public bool IsChild(int id) {
      for(int i = 0; i < this.ChildCount; i++) {
        if(children[i].ID == id) {
          return true;
        }
      }

      return false;
    }

    /// <summary>
    ///     Returns true if <paramref name="window"/> is a child window of 'this'.
    /// </summary>
    /// <param name="window">Window to look for.</param>
    /// <returns>True if <paramref name="window"/> is a child of 'this'.</returns>
    public bool IsChild(Window window) {
      for(int i = 0; i < this.ChildCount; i++) {
        if(children[i] == window) {
          return true;
        }
      }

      return false;
    }

    /// <summary>
    ///     Returns true if the Window named <paramref name="name"/> is some ancestor of 'this'.
    /// </summary>
    /// <param name="name">Name of the Window to look for.</param>
    /// <returns>True if a Window named <paramref name="name"/> is an ancestor of 'this'.</returns>
    public bool IsAncestor(string name) {
      // if parent is false, we have no ancestors
      if (parent == null) {
        return false;
      }

      // return true if our immediate parent is a match
      if (parent.name == name) {
        return true;
      }
      else {
        // scan back up the line until we get a result
        return parent.IsAncestor(name);
      }
    }

    /// <summary>
    ///     Returns true if the Window with ID <paramref name="id"/> is some ancestor of 'this'.
    /// </summary>
    /// <param name="name">Name of the Window to look for.</param>
    /// <returns>True if a Window with ID <paramref name="id"/> is an ancestor of 'this'.</returns>
    public bool IsAncestor(int id) {
      // if parent is false, we have no ancestors
      if (parent == null) {
        return false;
      }

      // return true if our immediate parent is a match
      if (parent.ID == id) {
        return true;
      }
      else {
        // scan back up the line until we get a result
        return parent.IsAncestor(id);
      }
    }

    /// <summary>
    ///     Returns true is <paramref name="window"/> is some ancestor of 'this'.
    /// </summary>
    /// <param name="window">Window to look for.</param>
    /// <returns>True if <paramref name="window"/> is an ancestor of 'this'.</returns>
    public bool IsAncestor(Window window) {
      // if parent is false, we have no ancestors
      if (parent == null) {
        return false;
      }

      // return true if our immediate parent is a match
      if (parent == window) {
        return true;
      }
      else {
        // scan back up the line until we get a result
        return parent.IsAncestor(window);
      }
    }

    /// <summary>
    ///     check if the given position would hit this window.
    /// </summary>
    /// <param name="position">Point describing the position to check in screen pixels.</param>
    /// <returns>True if the given point is within this window's area.</returns>
    public virtual bool IsHit(Point position) {
      // if window is disabled, default is not to react
      if (!IsEnabled) {
        return false;
      }

      Rect clippedArea = PixelRect;

      if (clippedArea.Width == 0) {
        return false;
      }

      // return whether point is within this area
      return clippedArea.IsPointInRect(position);
    }

    /// <summary>
    ///    Move the Window to the bottom of the Z order.
    /// </summary>
    /// <remarks>
    ///    - If the window is non always-on-top the Window is sent to the very bottom of its sibling windows and the process repeated for all ancestors.
    ///    - If the window is always-on-top, the Window is sent to the bottom of all sibling always-on-top windows and the process repeated for all ancestors.
    /// </remarks>
    public void MoveToBack() {
      // if the window is active, deactivate it
      if(IsActive) {
        OnDeactivated(new WindowEventArgs(this));
      }

      // if the window has no parent then we can have no siblings and have nothing more to do.
      if (parent == null) {
        return;
      }

      // move us behind all sibling windows with the same 'always-on-top' setting as we have.
      Window orgParent = parent;
      parent.RemoveChildImpl(this);

      int pos = 0;

      if (AlwaysOnTop) {
        while ((pos != ChildCount - 1) && (!children[pos].AlwaysOnTop)) {
          pos++;
        }
      }

      children.Insert(pos, this);
      Parent = orgParent;

      OnZChangedImpl();

      parent.MoveToBack();
    }

    /// <summary>
    ///    Move the Window to the top of the z order.
    /// </summary>
    /// <remarks>
    ///    - If the Window is a non always-on-top window it is moved the the top of all other non always-on-top sibling windows, and the process
    ///    repeated for all ancestors.
    ///    - If the Window is an always-on-top window it is moved to the of of all sibling Windows, and the process repeated for all ancestors.
    /// </remarks>
    public void MoveToFront() {
      // // if the window has no parent then we can have no siblings and have nothing more to do.
      if(parent == null) {
        // perform initial activation if required
        if(!IsActive) {
          OnActivated(new WindowEventArgs(null));
        }

        return;
      }

      // bring parent window to front of its siblings
      parent.MoveToFront();

      // get our sibling window which is currently active (if any)
      Window activeWindow = null;

      int idx = parent.ChildCount;

      while(--idx >= 0) {
        if(parent.children[idx].IsActive) {
          activeWindow = parent.children[idx];
          break;
        }
      }

      // move us infront of sibling windows with the same 'always-on-top' setting as we have.
      Window orgParent = parent;
      orgParent.RemoveChildImpl(this);
      orgParent.AddChildImpl(this);

      // notify ourselves that we have become active
      if(activeWindow != this) {
        OnActivated(new WindowEventArgs(activeWindow));
      }

      // notify previously active window that it is no longer active
      if((activeWindow != null) && (activeWindow != this)) {
        activeWindow.OnDeactivated(new WindowEventArgs(this));
      }

      OnZChangedImpl();
    }

    #endregion Methods
    // -----------------------------    

    #region Protected/Private Methods

    /// <summary>
    ///    Cleanup child windows.
    /// </summary>
    private void CleanupChildren() {
      while(ChildCount != 0) {
        Window window = children[0];

        // always remove child
        RemoveChild(window);

        // destroy child if required
        if(window.DestroyedByParent) {
          WindowManager.Instance.DestroyWindow(window);
        }
      }
    }

    /// <summary>
    ///    Add given window to child list at an appropriate position.
    /// </summary>
    /// <param name="window">Window to add.</param>
    private void AddChildImpl(Window window) {
      // if window is already attached, detach it first (will fire normal events)
      if(window.Parent != null) {
        window.Parent.RemoveChild(window);
      }

      int position = (ChildCount == 0) ? 0 : ChildCount;

      if(!window.AlwaysOnTop) {
        // find last non-topmost window
        while((position != 0) && children[position - 1].AlwaysOnTop) {
          position--;
        }
      }

      // add window at the end
      if(position == ChildCount) {
        children.Add(window);
      }
      else {
        // insert before position
        children.Insert(position, window);
      }

      window.Parent = this;

      // force an update for the area Rects for 'window' so they are correct for its new parent
      window.OnParentSized(new WindowEventArgs(this));
    }

    /// <summary>
    ///    Remove given window from child list.
    /// </summary>
    /// <param name="window">Window to remove.</param>
    private void RemoveChildImpl(Window window) {
      if(children.Count != 0) {
        if(children[window.Name] != null) {
          children.Remove(window.Name);
          window.Parent = null;
        }
      }
    }

    /// <summary>
    ///    Notify 'this' and all siblings of a ZOrder change event.
    /// </summary>
    private void OnZChangedImpl() {
      if(parent == null) {
        OnZChanged(new GuiEventArgs());
      }
      else {
        GuiEventArgs nullArgs = new GuiEventArgs();

        for(int i = 0; i < parent.ChildCount; i++) {
          parent.children[i].OnZChanged(nullArgs);
        }
      }
    }

    /// <summary>
    ///    Gets the size of the specified window.
    /// </summary>
    /// <param name="window">Window to get the size for.</param>
    protected Size GetWindowSizeImpl(Window window) {
      if (window == null) {
        return GuiSystem.Instance.Renderer.Size;
      }
      else {
        return window.absArea.Size;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="rect"></param>
    /// <returns></returns>
    protected Rect AbsoluteToRelativeImpl(Window window, Rect rect) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      Rect tmp = new Rect();

      if (size.width != 0) {
        tmp.left = rect.left / size.width;
        tmp.right = rect.right / size.width;
      }
      else {
        tmp.left = tmp.right = 0;
      }

      if (size.height != 0) {
        tmp.top  = rect.top / size.height;
        tmp.bottom = rect.bottom / size.height;
      }
      else {
        tmp.top = tmp.bottom = 0;
      }

      return tmp;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="size"></param>
    /// <returns></returns>
    protected Size AbsoluteToRelativeImpl(Window window, Size size) {
      // get size object for whatever we are using as a base for the conversion
      Size windowSize = GetWindowSizeImpl(window);

      Size tmp = new Size();

      if (windowSize.width != 0) {
        tmp.width = size.width / windowSize.width;
      }
      else {
        tmp.width = 0;
      }

      if (windowSize.height != 0) {
        tmp.height = size.height / windowSize.height;
      }
      else {
        tmp.height = 0;
      }

      return tmp;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="size"></param>
    /// <returns></returns>
    protected Point AbsoluteToRelativeImpl(Window window, Point point) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      Point tmp = new Point();

      if (size.width != 0) {
        tmp.x = point.x / size.width;
      }
      else {
        tmp.x = 0;
      }

      if (size.height != 0) {
        tmp.y = point.y / size.height;
      }
      else {
        tmp.y = 0;
      }

      return tmp;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="x"></param>
    /// <returns></returns>
    protected float AbsoluteToRelativeXImpl(Window window, float x) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      if (size.width != 0) {
        return x / size.width;
      }
      else {
        return 0;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    protected float AbsoluteToRelativeYImpl(Window window, float y) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      if (size.height != 0) {
        return y / size.height;
      }
      else {
        return 0;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="rect"></param>
    /// <returns></returns>
    protected Rect RelativeToAbsoluteImpl(Window window, Rect rect) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      return new Rect(
        rect.left * size.width, 
        rect.top * size.height, 
        rect.right * size.width, 
        rect.bottom * size.height);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="size"></param>
    /// <returns></returns>
    protected Size RelativeToAbsoluteImpl(Window window, Size size) {
      // get size object for whatever we are using as a base for the conversion
      Size windowSize = GetWindowSizeImpl(window);

      return new Size(
        size.width * windowSize.width, 
        size.height * windowSize.height);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="point"></param>
    /// <returns></returns>
    protected Point RelativeToAbsoluteImpl(Window window, Point point) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      return new Point(
        point.x * size.width, 
        point.y * size.height);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="x"></param>
    /// <returns></returns>
    protected float RelativeToAbsoluteXImpl(Window window, float x) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      return x * size.width;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="window"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    protected float RelativeToAbsoluteYImpl(Window window, float y) {
      // get size object for whatever we are using as a base for the conversion
      Size size = GetWindowSizeImpl(window);

      return y * size.height;
    }

    #endregion Private Methods

    // -----------------------------
    #region Co-ordinate/Size Conversion Methods

    /// <summary>
    ///    Convert the given X co-ordinate from absolute to relative metrics.
    /// </summary>
    /// <param name="val">X co-ordinate specified in pixels relative to this Window (so 0 is this windows left edge).</param>
    /// <returns>A relative metric value that is equivalent to <paramref name="val"/>, given the Window objects current width.</returns>
    public float AbsoluteToRelativeX(float val) {
      return AbsoluteToRelativeXImpl(this, val);
    }

    /// <summary>
    ///    Convert the given Y co-ordinate from absolute to relative metrics.
    /// </summary>
    /// <param name="val">Y co-ordinate specified in pixels relative to this Window (so 0 is this windows top edge).</param>
    /// <returns>A relative metric value that is equivalent to <paramref name="val"/>, given the Window objects current height.</returns>
    public float AbsoluteToRelativeY(float val) {
      return AbsoluteToRelativeYImpl(this, val);
    }

    /// <summary>
    ///    Convert the given position from absolute to relative metrics.
    /// </summary>
    /// <param name="point">Point that describes a position specified in pixels relative to this Window (so 0,0 is this windows top-left corner).</param>
    /// <returns>A Point describing a relative metric position that is equivalent to <paramref name="point"/>, given the Window objects current size.</returns>
    public Point AbsoluteToRelative(Point point) {
      return AbsoluteToRelativeImpl(this, point);
    }

    /// <summary>
    ///    Convert the given size from absolute to relative metrics.
    /// </summary>
    /// <param name="size">Size that describes a size specified in pixels.</param>
    /// <returns>A Size object describing a relative metric size that is equivalent to <paramref name="size"/>, given the Window objects current size.</returns>
    public Size AbsoluteToRelative(Size size) {
      return AbsoluteToRelativeImpl(this, size);
    }

    /// <summary>
    ///    Convert the given area from absolute to relative metrics.
    /// </summary>
    /// <param name="rect">Rect describing the area specified in pixels relative to this Window.</param>
    /// <returns>A Rect describing a relative metric area that is equivalent to <paramref name="rect"/>, given the Window objects current size.</returns>
    public Rect AbsoluteToRelative(Rect rect) {
      return AbsoluteToRelativeImpl(this, rect);
    }

    /// <summary>
    ///    Convert the given X co-ordinate from relative to absolute metrics.
    /// </summary>
    /// <param name="val">X co-ordinate specified in pixels relative to this Window (so 0 is this windows left edge).</param>
    /// <returns>An absolute  metric value that is equivalent to <paramref name="val"/>, given the Window objects current width.</returns>
    public float RelativeToAbsoluteX(float val) {
      return RelativeToAbsoluteXImpl(this, val);
    }

    /// <summary>
    ///    Convert the given Y co-ordinate from relative to absolute metrics.
    /// </summary>
    /// <param name="val">Y co-ordinate specified in pixels relative to this Window (so 0 is this windows top edge).</param>
    /// <returns>An absolute metric value that is equivalent to <paramref name="val"/>, given the Window objects current height.</returns>
    public float RelativeToAbsoluteY(float val) {
      return RelativeToAbsoluteYImpl(this, val);
    }

    /// <summary>
    ///    Convert the given position from relative to absolute metrics.
    /// </summary>
    /// <param name="point">Point that describes a position specified in pixels relative to this Window (so 0,0 is this windows top-left corner).</param>
    /// <returns>A Point describing a absolute metric position that is equivalent to <paramref name="point"/>, given the Window objects current size.</returns>
    public Point RelativeToAbsolute(Point point) {
      return RelativeToAbsoluteImpl(this, point);
    }

    /// <summary>
    ///    Convert the given size from relative to absolute metrics.
    /// </summary>
    /// <param name="size">Size that describes a size specified in pixels.</param>
    /// <returns>A Size object describing an absolute metric size that is equivalent to <paramref name="size"/>, given the Window objects current size.</returns>
    public Size RelativeToAbsolute(Size size) {
      return RelativeToAbsoluteImpl(this, size);
    }

    /// <summary>
    ///    Convert the given area from relative to absolute metrics.
    /// </summary>
    /// <param name="rect">Rect describing the area specified in pixels relative to this Window.</param>
    /// <returns>A Rect describing an absolute metric area that is equivalent to <paramref name="rect"/>, given the Window objects current size.</returns>
    public Rect RelativeToAbsolute(Rect rect) {
      return RelativeToAbsoluteImpl(this, rect);
    }

    /// <summary>
    ///    Convert a window co-ordinate value, specified in whichever metrics mode is active, to a screen relative pixel co-ordinate.
    /// </summary>
    /// <param name="x">x co-ordinate value to be converted.</param>
    /// <returns>float value describing a screen co-ordinate that is equivalent to window co-ordinate <paramref name="x"/>.</returns>
    public float WindowToScreenX(float x) {
      Window window = this;
      float baseX = 0;

      while(window != null) {
        baseX += window.absArea.left;
        window = window.parent;
      }

      if(this.MetricsMode == MetricsMode.Relative) {
        return baseX + RelativeToAbsoluteX(x);
      }
      else {
        return baseX + x;
      }
    }

    /// <summary>
    ///    Convert a window co-ordinate value, specified in whichever metrics mode is active, to a screen relative pixel co-ordinate.
    /// </summary>
    /// <param name="y">y co-ordinate value to be converted.</param>
    /// <returns>float value describing a screen co-ordinate that is equivalent to window co-ordinate <paramref name="y"/>.</returns>
    public float WindowToScreenY(float y) {
      Window window = this;
      float baseY = 0;

      while(window != null) {
        baseY += window.absArea.top;
        window = window.parent;
      }

      if(this.MetricsMode == MetricsMode.Relative) {
        return baseY + RelativeToAbsoluteY(y);
      }
      else {
        return baseY + y;
      }
    }

    /// <summary>
    ///    Convert a window co-ordinate position, specified in whichever metrics mode is active, to a screen relative pixel co-ordinate position.
    /// </summary>
    /// <param name="point">Point describing the position to be converted.</param>
    /// <returns>Point object describing a screen co-ordinate position that is equivalent to window co-ordinate position <paramref name="point"/>.</returns>
    public Point WindowToScreen(Point point) {
      Window window = this;
      Point basePoint = new Point();

      while(window != null) {
        basePoint.x += window.absArea.left;
        basePoint.y += window.absArea.top;
        window = window.parent;
      }

      if(this.MetricsMode == MetricsMode.Relative) {
        return basePoint + RelativeToAbsolute(point);
      }
      else {
        return basePoint + point;
      }
    }

    /// <summary>
    ///    Convert a window size value, specified in whichever metrics mode is active, to a size in pixels.
    /// </summary>
    /// <param name="size">Size describing the size to be converted.</param>
    /// <returns>Size describing describing a size in pixels that is equivalent to the window based <paramref name="rect"/>.</returns>
    public Size WindowToScreen(Size size) {
      if (this.MetricsMode == MetricsMode.Relative) {
        return new Size(
          size.width * absArea.Width, 
          size.height * absArea.Height);
      }
      else {
        return size;
      }
    }

    /// <summary>
    ///    Convert a window area, specified in whichever metrics mode is active, to a screen area.
    /// </summary>
    /// <param name="rect">Rect describing the area to be converted.</param>
    /// <returns>Rect describing a screen area that is equivalent to window area <paramref name="rect"/>.</returns>
    public Rect WindowToScreen(Rect rect) {
      Window window = this;
      Point basePoint = new Point();

      while(window != null) {
        basePoint.x += window.absArea.left;
        basePoint.y += window.absArea.top;
        window = window.parent;
      }

      Rect temp;

      if(this.MetricsMode == MetricsMode.Relative) {
        temp = RelativeToAbsolute(rect);
      }
      else {
        temp = rect;
      }

      temp.Offset(basePoint);

      return temp;
    }

    /// <summary>
    ///    Convert a screen relative pixel co-ordinate value to a window co-ordinate value, specified in whichever metrics mode is active.
    /// </summary>
    /// <param name="x">x co-ordinate value to be converted.</param>
    /// <returns>float value describing a window co-ordinate value that is equivalent to screen co-ordinate <paramref name="x"/>.</returns>
    public float ScreenToWindowX(float x) {
      x -= WindowToScreenX(0);

      if(this.MetricsMode == MetricsMode.Relative) {
        x /= absArea.Width;
      }

      return x;
    }

    /// <summary>
    ///    Convert a screen relative pixel co-ordinate value to a window co-ordinate value, specified in whichever metrics mode is active.
    /// </summary>
    /// <param name="y">y co-ordinate value to be converted.</param>
    /// <returns>float value describing a window co-ordinate value that is equivalent to screen co-ordinate <paramref name="y"/>.</returns>
    public float ScreenToWindowY(float y) {
      y -= WindowToScreenY(0);

      if(this.MetricsMode == MetricsMode.Relative) {
        y /= absArea.Height;
      }

      return y;
    }

    /// <summary>
    ///    Convert a screen relative pixel position to a window co-ordinate position, specified in whichever metrics mode is active.
    /// </summary>
    /// <param name="point">Point describing the position to be converted.</param>
    /// <returns>Point describing a window co-ordinate position that is equivalent to screen co-ordinate <paramref name="point"/>.</returns>
    public Point ScreenToWindow(Point point) {
      Point temp = point;

      temp.x -= WindowToScreenX(0);
      temp.y -= WindowToScreenY(0);

      if (this.MetricsMode == MetricsMode.Relative) {
        temp.x /= absArea.Width;
        temp.y /= absArea.Height;
      }

      return temp;
    }

    /// <summary>
    ///    Convert a pixel screen size to a window based size, specified in whichever metrics mode is active.
    /// </summary>
    /// <param name="size">Size describing the area to be converted.</param>
    /// <returns>Size object describing a window based size that is equivalent to screen based size <paramref name="size"/>.</returns>
    public Size ScreenToWindow(Size size) {
      Size temp = size;

      if (this.MetricsMode == MetricsMode.Relative) {
        temp.width /= absArea.Width;
        temp.height /= absArea.Height;
      }

      return temp;
    }

    /// <summary>
    ///    Convert a screen area to a window area, specified in whichever metrics mode is active.
    /// </summary>
    /// <param name="rect">Rect describing the area to be converted.</param>
    /// <returns>Rect object describing a window area that is equivalent to screen area <paramref name="rect"/>.</returns>
    public Rect ScreenToWindow(Rect rect) {
      Rect temp = rect;

      temp.left    -= WindowToScreenX(0);
      temp.top    -= WindowToScreenY(0);
      temp.right    -= WindowToScreenX(0);
      temp.bottom    -= WindowToScreenY(0);

      if (this.MetricsMode == MetricsMode.Relative) {
        temp.left  /= absArea.Width;
        temp.top  /= absArea.Height;
        temp.right  /= absArea.Width;
        temp.bottom  /= absArea.Height;
      }

      return temp;
    }

    #endregion Co-ordinate/Size Conversion Methods
    // -----------------------------

    // -----------------------------
    #region Clipboard Methods

    /// <summary>
    ///     Copy information to the clipboard.
    /// </summary>
    public virtual void CopyToClipboard() {
      if (parent != null) {
        parent.CopyToClipboard();
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public virtual void CutToClipboard() {
      if (parent != null) {
        parent.CutToClipboard();
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public virtual void PasteFromClipboard() {
      if (parent != null) {
        parent.PasteFromClipboard();
      }
    }

    #endregion Clipboard Methods
    // -----------------------------

    // -----------------------------
    #region Rendering Methods

    /// <summary>
    ///     Causes the Window object to render itself and all of it's attached children
    /// </summary>
    public void Render() {
      // don't do anything if window is not visible
      if (!Visible) {
        return;
      }

      // perform drawing for this window
      Renderer renderer = GuiSystem.Instance.Renderer;
      DrawSelf(renderer.CurrentZ);
      renderer.AdvanceZValue();

      // render any child windows
      for (int i = 0; i < ChildCount; i++) {
        children[i].Render();
      }
    }

    /// <summary>
    ///    Signal the System object to redraw (at least) this Window on the next render cycle.
    /// </summary>
    public void RequestRedraw() {
      GuiSystem.Instance.SignalRedraw();
    }

    #endregion Rendering Methods
    // -----------------------------

    // -----------------------------
    #region Manipulator Methods

    /// <summary>
    ///     Complete initialiZation of window (required so derived classes can affect initialisation).
    /// </summary>
    /// <remarks>
    ///     *MUST* be called before this window is used.
    /// </remarks>
    /// <returns></returns>
    public virtual void Initialize() {
    }

    /// <summary>
    ///     Enables this window.
    /// </summary>
    public void Enable() {
      isEnabled = true;
    }

    /// <summary>
    ///     Disable this window.
    /// </summary>
    public void Disable() {
      isEnabled = false;
    }

    /// <summary>
    ///     Show this window (make visible).
    /// </summary>
    public void Show() {
      isVisible = true;
    }

    /// <summary>
    ///     Hide this window.
    /// </summary>
    public void Hide() {
      isVisible = false;
    }

    /// <summary>
    ///     Capture input to this window.
    /// </summary>
    public void CaptureInput() {
      // we can only capture if we are the active window
      if (!IsActive) {
        return;
      }

      Window currentCapture = captureWindow;
      captureWindow = this;

      // inform any window which previously had mouse that it doesn't anymore!
      if ((currentCapture != null) && (currentCapture != this) && (!restoreOldCapture)) {
        currentCapture.OnCaptureLost(new GuiEventArgs());
      }

      if (restoreOldCapture) {
        oldCapture = currentCapture;
      }

      // event notification
      OnCaptureGained(new GuiEventArgs());
    }

    /// <summary>
    ///     Releases the capture of input from this window.
    /// </summary>
    /// <remarks>
    ///    If this Window does not have inputs captured, nothing happens.
    /// </remarks>
    public void ReleaseInput() {
      // if we are not the window that has capture, do nothing
      if (!IsCapturedByThis) {
        return;
      }

      // restore old captured window if that mode is set
      if (restoreOldCapture) {
        captureWindow = oldCapture;

        // check for case when there was no previously captured window
        if (oldCapture != null) {
          oldCapture = null;
          captureWindow.MoveToFront();
        }
      }
      else {
        captureWindow = null;
      }

      // event notification
      OnCaptureLost(new GuiEventArgs());
    }

    /// <summary>
    ///    Set the current area for the Window, this allows for setting of position and size at the same time.  
    ///    Interpretation of the input value <paramref name="area"/> is dependant upon the current metrics system set for the Window.
    /// </summary>
    /// <param name="area">Rect that describes the new area for Window, in units consistent with the current metrics mode.</param>
    public void SetAreaRect(Rect area) {
      if (this.MetricsMode == MetricsMode.Relative) {
        relArea = area;

        absArea = RelativeToAbsoluteImpl(parent, area);
        absArea.ConstrainSize(maxSize, minSize);
      }
      else {
        absArea = area;
        absArea.ConstrainSize(maxSize, minSize);

        relArea = AbsoluteToRelativeImpl(parent, area);
      }

      OnMoved(new GuiEventArgs());
      OnSized(new GuiEventArgs());
    }

    /// <summary>
    ///    Set the font used by this Window.
    /// </summary>
    /// <param name="name">
    ///    Name of a Font object to be used by this Window.  
    ///    If <paramref name="name"/> is null or "", the default font will be used.
    /// </param>
    /// <exception cref="UnknownObjectException">If the font with the specified name does not exist in the system.</exception>
    public void SetFont(string name) {
      if(name == null || name.Length == 0) {
        // copied here from the overload because of the ambiguity of SetFont(null)
        this.font = null;
        OnFontChanged(new GuiEventArgs());
      }
      else {
        SetFont(FontManager.Instance.GetFont(name));
      }
    }

    /// <summary>
    ///    Set the font used by this Window.
    /// </summary>
    /// <param name="font">
    ///    Font object to be used by this Window.  
    ///    If <paramref name="font"/> is null, the default font will be used.
    /// </param>
    public void SetFont(Font font) {
      this.font = font;
      OnFontChanged(new GuiEventArgs());
    }

    /// <summary>
    ///    Set the mouse cursor image to be used when the mouse enters this window.  
    /// </summary>
    /// <param name="imagesetName">The name of the Imageset that contains the image to be used.</param>
    /// <param name="imageName">The name of the Image on <paramref name="imageset"/> that is to be used.</param>
    public void SetMouseCursor(string imagesetName, string imageName) {
      mouseCursor = ImagesetManager.Instance.GetImageset(imagesetName).GetImage(imageName);
    }

    /// <summary>
    ///    Sets the mouse cursor to use when the mouse is within this window.
    /// </summary>
    /// <param name="image">Mouse cursor image to use.</param>
    public void SetMouseCursor(Image image) {
      mouseCursor = image;
    }

    /// <summary>
    ///     Sets the 'restore old capture' mode to on / off.
    /// </summary>
    /// <remarks>
    ///     Also sets the mode on all child controls. <p/>
    ///     Note: Intended for use by composite control sub-classes.
    /// </remarks>
    /// <param name="restore">On or off.</param>
    public void SetRestoreCapture(bool restore) {
      restoreOldCapture = restore;

      // trickle the changes down to the children
      for (int i = 0; i < ChildCount; i++) {
        children[i].SetRestoreCapture(restore);
      }
    }

    #region Properties

    /// <summary>
    ///    Return the window X position in absolute metrics.
    /// </summary>
    /// <value>float value describing this windows X position, relative to the parent window, in absolute metrics.</value>
    public float AbsoluteX {
      get {
        return absArea.left;
      }
    }

    /// <summary>
    ///    Return the window Y position in absolute metrics.
    /// </summary>
    /// <value>float value describing this windows Y position, relative to the parent window, in absolute metrics.</value>
    public float AbsoluteY {
      get {
        return absArea.top;
      }
    }

    /// <summary>
    ///    Return the window size in absolute metrics.
    /// </summary>
    /// <value>Size describing this windows size in absolute metrics.</value>
    public Size AbsoluteSize {
      get {
        return absArea.Size;
      }
    }

    /// <summary>
    ///    Return the window width in absolute metrics.
    /// </summary>
    /// <value>float value describing this windows width in absolute metrics.</value>
    public float AbsoluteWidth {
      get {
        return absArea.Width;
      }
    }

    /// <summary>
    ///    Return the window height in absolute metrics.
    /// </summary>
    /// <value>float value describing this windows height in absolute metrics.</value>
    public float AbsoluteHeight {
      get {
        return absArea.Height;
      }
    }

    #endregion Properties

    #endregion Manipulator Methods
    // -----------------------------

    // -----------------------------
    #region Events

    #region Trigger Methods

    /// <summary>
    ///      Event trigger method for the <see cref="Sized"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnSized(GuiEventArgs e) {
      for(int i = 0; i < ChildCount; i++) {
        children[i].OnParentSized(new WindowEventArgs(this));
      }

      RequestRedraw();

      if (Sized != null) {
        Sized(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Moved"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMoved(GuiEventArgs e) {
      RequestRedraw();

      if (Moved != null) {
        Moved(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="TextChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnTextChanged(WindowEventArgs e) {
      RequestRedraw();

      if (TextChanged != null) {
        TextChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="FontChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnFontChanged(GuiEventArgs e) {
      RequestRedraw();

      if (FontChanged != null) {
        FontChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="AlphaChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnAlphaChanged(GuiEventArgs e) {
      // scan child list and call this method for all children that inherit alpha
      for(int i = 0; i < ChildCount; i++) {
        if(children[i].InheritsAlpha) {
          children[i].OnAlphaChanged(e);
        }
      }

      RequestRedraw();

      if (AlphaChanged != null) {
        AlphaChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="IDChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnIDChanged(GuiEventArgs e) {
      RequestRedraw();

      if (IDChanged != null) {
        IDChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Shown"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnShown(GuiEventArgs e) {
      RequestRedraw();

      if (Shown != null) {
        Shown(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Hidden"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnHidden(GuiEventArgs e) {
      RequestRedraw();

      if (Hidden != null) {
        Hidden(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Enabled"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnEnabled(GuiEventArgs e) {
      RequestRedraw();

      if (Enabled != null) {
        Enabled(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Disabled"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnDisabled(GuiEventArgs e) {
      RequestRedraw();

      if (Disabled != null) {
        Disabled(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MetricsChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMetricsChanged(GuiEventArgs e) {
      RequestRedraw();

      if (MetricsChanged != null) {
        MetricsChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="ClippingChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnClippingChanged(GuiEventArgs e) {
      RequestRedraw();

      if (ClippingChanged != null) {
        ClippingChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="ParentDestroyChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnParentDestroyChanged(GuiEventArgs e) {
      if (ParentDestroyChanged != null) {
        ParentDestroyChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="InheritsAlphaChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnInheritsAlphaChanged(GuiEventArgs e) {
      RequestRedraw();

      if (InheritsAlphaChanged != null) {
        InheritsAlphaChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="AlwaysOnTopChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnAlwaysOnTopChanged(GuiEventArgs e) {
      RequestRedraw();

      if (AlwaysOnTopChanged != null) {
        AlwaysOnTopChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="CaptureGained"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnCaptureGained(GuiEventArgs e) {
      if (CaptureGained != null) {
        CaptureGained(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="CaptureLost"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnCaptureLost(GuiEventArgs e) {
      // handle restore of previous capture window as required.
      if (restoreOldCapture && (oldCapture != null)) {
        oldCapture.OnCaptureLost(e);
        oldCapture = null;
      }

      // handle case where mouse is now in a different window
      // (this is a bit of a hack that uses the mouse input injector to handle this for us).
      GuiSystem.Instance.InjectMouseMove(0, 0);

      if (CaptureLost != null) {
        CaptureLost(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="RenderingStarted"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnRenderingStarted(GuiEventArgs e) {
      if (RenderingStarted != null) {
        RenderingStarted(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="RenderingEnded"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnRenderingEnded(GuiEventArgs e) {
      if (RenderingEnded != null) {
        RenderingEnded(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="ZChanged"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnZChanged(GuiEventArgs e) {
      RequestRedraw();

      if (ZChanged != null) {
        ZChanged(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="DestructionStarted"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnDestructionStarted(GuiEventArgs e) {
      if (DestructionStarted != null) {
        DestructionStarted(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Activated"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnActivated(WindowEventArgs e) {
      isActive = true;

      RequestRedraw();

      if (Activated != null) {
        Activated(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Deactivated"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnDeactivated(WindowEventArgs e) {
      // first, de-activate all children
      for(int i = 0; i < ChildCount; i++) {
        if(children[i].IsActive) {
          children[i].OnDeactivated(e);
        }
      }

      isActive = false;

      RequestRedraw();

      if (Deactivated != null) {
        Deactivated(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="ParentSized"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnParentSized(WindowEventArgs e) {
      // synchronise area rects for new parent size
      if (this.MetricsMode == MetricsMode.Relative) {
        absArea = RelativeToAbsoluteImpl(parent, relArea);

        // Check new absolute size and limit to currently set max/min values.  This does not affect relative co-ordinates
        // which must 'recover' after window is again sized so normal relativity can take over.
        absArea.ConstrainSize(maxSize, minSize);
      }
      else {
        relArea = AbsoluteToRelativeImpl(parent, absArea);
      }

      OnSized(new GuiEventArgs());

      RequestRedraw();

      if (ParentSized != null) {
        ParentSized(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="ChildAdded"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnChildAdded(WindowEventArgs e) {
      RequestRedraw();

      if (ChildAdded != null) {
        ChildAdded(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="ChildRemoved"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnChildRemoved(WindowEventArgs e) {
      RequestRedraw();

      if (ChildRemoved != null) {
        ChildRemoved(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseEnters"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseEnters(MouseEventArgs e) {
      // set the mouse cursor
      MouseCursor.Instance.SetImage(this.Cursor);

      if (MouseEnters != null) {
        MouseEnters(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseLeaves"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseLeaves(MouseEventArgs e) {
      if (MouseLeaves != null) {
        MouseLeaves(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseMove"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseMove(MouseEventArgs e) {
      if (MouseMove != null) {
        MouseMove(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseWheel"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseWheel(MouseEventArgs e) {
      if (MouseWheel != null) {
        MouseWheel(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseButtonDown"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseButtonDown(MouseEventArgs e) {
      if(e.Button == MouseButton.Left) {
        MoveToFront();
      }

      if (MouseButtonDown != null) {
        MouseButtonDown(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseButtonUp"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseButtonUp(MouseEventArgs e) {
      if (MouseButtonUp != null) {
        MouseButtonUp(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseClicked"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseClicked(MouseEventArgs e) {
      if (MouseClicked != null) {
        MouseClicked(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseDoubleClicked"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseDoubleClicked(MouseEventArgs e) {
      if (MouseDoubleClicked != null) {
        MouseDoubleClicked(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="MouseTripleClicked"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnMouseTripleClicked(MouseEventArgs e) {
      if (MouseTripleClicked != null) {
        MouseTripleClicked(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="KeyDown"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnKeyDown(KeyEventArgs e) {
      if (KeyDown != null) {
        KeyDown(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="KeyUp"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnKeyUp(KeyEventArgs e) {
      if (KeyUp != null) {
        KeyUp(this, e);
      }
    }
    /// <summary>
    ///      Event trigger method for the <see cref="Character"/> event.
    /// </summary>
    /// <param name="e">Event information.</param>
    protected internal virtual void OnCharacter(KeyEventArgs e) {
      if (Character != null) {
        Character(this, e);
      }
    }

    #endregion Trigger Methods

    #region Event Declarations

    #region Standard Events

    /// <summary>
    ///    Window size has changed.
    /// </summary>
    public event GuiEventHandler Sized;
    /// <summary>
    ///     Window position has changed.
    /// </summary>
    public event GuiEventHandler Moved;
    /// <summary>
    ///    Text string for the Window has changed.
    /// </summary>
    public event WindowEventHandler TextChanged;
    /// <summary>
    ///     Font object for the Window has been changed.
    /// </summary>
    public event GuiEventHandler FontChanged;
    /// <summary>
    ///     Alpha blend value for the Window has changed.
    /// </summary>
    public event GuiEventHandler AlphaChanged;
    /// <summary>
    ///     Client assigned ID code for the Window has changed.
    /// </summary>
    public event GuiEventHandler IDChanged;
    /// <summary>
    ///     Window has been made visible.
    /// </summary>
    public event GuiEventHandler Shown;
    /// <summary>
    ///     Window has been hidden from view.
    /// </summary>
    public event GuiEventHandler Hidden;
    /// <summary>
    ///     Window has been enabled (interaction is possible).
    /// </summary>
    public event GuiEventHandler Enabled;
    /// <summary>
    ///     Window has been disabled (interaction is no longer possible).
    /// </summary>
    public event GuiEventHandler Disabled;
    /// <summary>
    ///     Active metrics mode has been modified.
    /// </summary>
    public event GuiEventHandler MetricsChanged;
    /// <summary>
    ///     Clipping by parent mode has been modified.
    /// </summary>
    public event GuiEventHandler ClippingChanged;
    /// <summary>
    ///     Destruction by parent mode has been modified.
    /// </summary>
    public event GuiEventHandler ParentDestroyChanged;
    /// <summary>
    ///     Alpha inherited from parent mode has been modified.
    /// </summary>
    public event GuiEventHandler InheritsAlphaChanged;
    /// <summary>
    ///     Always on top mode has been modified.
    /// </summary>
    public event GuiEventHandler AlwaysOnTopChanged;
    /// <summary>
    ///     Window has captured all inputs.
    /// </summary>
    public event GuiEventHandler CaptureGained;
    /// <summary>
    ///     Window has lost it's capture on inputs.
    /// </summary>
    public event GuiEventHandler CaptureLost;
    /// <summary>
    ///     Rendering of the Window has started.
    /// </summary>
    public event GuiEventHandler RenderingStarted;
    /// <summary>
    ///     Rendering for the Window has finished.
    /// </summary>
    public event GuiEventHandler RenderingEnded;
    /// <summary>
    ///     The z-order of the window has changed.
    /// </summary>
    public event GuiEventHandler ZChanged;
    /// <summary>
    ///     Destruction of the Window is about to begin.
    /// </summary>
    public event GuiEventHandler DestructionStarted;

    #endregion Standard Events

    #region Window Events

    /// <summary>
    ///    Window has been activated (has input focus).
    /// </summary>
    public event WindowEventHandler Activated;
    /// <summary>
    ///    Window has been deactivated (loses input focus).
    /// </summary>
    public event WindowEventHandler Deactivated;
    /// <summary>
    ///    Parent of this Window has been re-sized.
    /// </summary>
    public event WindowEventHandler ParentSized;
    /// <summary>
    ///    A child Window has been added.
    /// </summary>
    public event WindowEventHandler ChildAdded;
    /// <summary>
    ///    A child window has been removed.
    /// </summary>
    public event WindowEventHandler ChildRemoved;

    #endregion Window Events

    #region Mouse Events
    
    /// <summary>
    ///    Mouse cursor has entered the Window.
    /// </summary>
    public event MouseEventHandler MouseEnters;
    /// <summary>
    ///    Mouse cursor has left the Window.
    /// </summary>
    public event MouseEventHandler MouseLeaves;
    /// <summary>
    ///    Mouse cursor was moved within the area of the Window.
    /// </summary>
    public event MouseEventHandler MouseMove;
    /// <summary>
    ///    Mouse wheel was scrolled within the Window.
    /// </summary>
    public event MouseEventHandler MouseWheel;
    /// <summary>
    ///    A mouse button was pressed down within the Window.
    /// </summary>
    public event MouseEventHandler MouseButtonDown;
    /// <summary>
    ///    A mouse button was released within the Window.
    /// </summary>
    public event MouseEventHandler MouseButtonUp;
    /// <summary>
    ///    A mouse button was clicked (down then up) within the Window.
    /// </summary>
    public event MouseEventHandler MouseClicked;
    /// <summary>
    ///    A mouse button was double-clicked within the Window.
    /// </summary>
    public event MouseEventHandler MouseDoubleClicked;
    /// <summary>
    ///    A mouse button was triple-clicked within the Window.
    /// </summary>
    public event MouseEventHandler MouseTripleClicked;

    #endregion Mouse Events

    #region Key Events

    /// <summary>
    ///    A key on the keyboard was pressed.
    /// </summary>
    public event KeyEventHandler KeyDown;
    /// <summary>
    ///    A key on the keyboard was released.
    /// </summary>
    public event KeyEventHandler KeyUp;
    /// <summary>
    ///    A text character was typed on the keyboard.
    /// </summary>
    public event KeyEventHandler Character;

    #endregion Key Events

    #endregion Event Declarations

    // -----------------------------

    #endregion Events
    // -----------------------------

    // -----------------------------
    #region IDisposable Members

    public void Dispose() {
      // TODO:  Add Window.Dispose implementation
    }

    #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.