#region File Description //----------------------------------------------------------------------------- // Layout.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace PerformanceMeasuring.GameDebugTools { /// /// Alignment for layout. /// [Flags] public enum Alignment { None = 0, // Horizontal layouts Left = 1, Right = 2, HorizontalCenter = 4, // Vertical layouts Top = 8, Bottom = 16, VerticalCenter = 32, // Combinations TopLeft = Top | Left, TopRight = Top | Right, TopCenter = Top | HorizontalCenter, BottomLeft = Bottom | Left, BottomRight = Bottom | Right, BottomCenter = Bottom | HorizontalCenter, CenterLeft = VerticalCenter | Left, CenterRight = VerticalCenter | Right, Center = VerticalCenter | HorizontalCenter } /// /// Layout class that supports title safe area. /// /// /// You have to support various resolutions when you develop multi-platform /// games. Also, you have to support title safe area for Xbox 360 games. /// /// This structure places given rectangle with specified alignment and margin /// based on layout area (client area) with safe area. /// /// Margin is percentage of client area size. /// /// Example: /// /// Place( region, 0.1f, 0.2f, Aligment.TopLeft ); /// /// Place region at 10% from left side of the client area, /// 20% from top of the client area. /// /// /// Place( region, 0.3f, 0.4f, Aligment.BottomRight ); /// /// Place region at 30% from right side of client, /// 40% from the bottom of the client area. /// /// /// You can individually specify client area and safe area. /// So, it is useful when you have split screen game which layout happens based /// on client and it takes care of the safe at same time. /// /// public struct Layout { #region Fields /// /// Gets/Sets client area. /// public Rectangle ClientArea; /// /// Gets/Sets safe area. /// public Rectangle SafeArea; #endregion #region Initialization /// /// Construct layout object by specify both client area and safe area. /// /// Client area /// safe area public Layout(Rectangle clientArea, Rectangle safeArea) { ClientArea = clientArea; SafeArea = safeArea; } /// /// Construct layout object by specify client area. /// Safe area becomes same size as client area. /// /// Client area public Layout(Rectangle clientArea) : this(clientArea, clientArea) { } /// /// Construct layout object by specify viewport. /// Safe area becomes same as Viewpoert.TItleSafeArea. /// public Layout(Viewport viewport) { ClientArea = new Rectangle((int)viewport.X, (int)viewport.Y, (int)viewport.Width, (int)viewport.Height); SafeArea = viewport.TitleSafeArea; } #endregion /// /// Layouting specified region /// /// placing region /// Placed position public Vector2 Place(Vector2 size, float horizontalMargin, float verticalMargine, Alignment alignment) { Rectangle rc = new Rectangle(0, 0, (int)size.X, (int)size.Y); rc = Place(rc, horizontalMargin, verticalMargine, alignment); return new Vector2(rc.X, rc.Y); } /// /// Layouting specified region /// /// placing rectangle /// placed rectangle public Rectangle Place(Rectangle region, float horizontalMargin, float verticalMargine, Alignment alignment) { // Horizontal layout. if ((alignment & Alignment.Left) != 0) { region.X = ClientArea.X + (int)(ClientArea.Width * horizontalMargin); } else if ((alignment & Alignment.Right) != 0) { region.X = ClientArea.X + (int)(ClientArea.Width * (1.0f - horizontalMargin)) - region.Width; } else if ((alignment & Alignment.HorizontalCenter) != 0) { region.X = ClientArea.X + (ClientArea.Width - region.Width) / 2 + (int)(horizontalMargin * ClientArea.Width); } else { // Don't do layout. } // Vertical layout. if ((alignment & Alignment.Top) != 0) { region.Y = ClientArea.Y + (int)(ClientArea.Height * verticalMargine); } else if ((alignment & Alignment.Bottom) != 0) { region.Y = ClientArea.Y + (int)(ClientArea.Height * (1.0f - verticalMargine)) - region.Height; } else if ((alignment & Alignment.VerticalCenter) != 0) { region.Y = ClientArea.Y + (ClientArea.Height - region.Height) / 2 + (int)(verticalMargine * ClientArea.Height); } else { // Don't do layout. } // Make sure layout region is in the safe area. if (region.Left < SafeArea.Left) region.X = SafeArea.Left; if (region.Right > SafeArea.Right) region.X = SafeArea.Right - region.Width; if (region.Top < SafeArea.Top) region.Y = SafeArea.Top; if (region.Bottom > SafeArea.Bottom) region.Y = SafeArea.Bottom - region.Height; return region; } } }