using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; namespace RecrownedAthenaeum.SpecialTypes { /// /// An object that represents a ninepatch. /// public class NinePatch : ISpecialDrawable { /// /// color of 9patch. /// public Color color; /// /// Dimensions in ninepatch. May also represent position in texture atlas. /// public Rectangle textureRegion; readonly Texture2D texture; readonly int left, right, bottom, top; /// /// A nine patch object. /// /// Texture used for the nine patch. Dimensions must be greater than their sum border counter parts. If used as part of texture atlas, the texture should be the texture of the entire atlas. /// Left side. /// Right side. /// Bottom side. /// Top side. /// The dimensions and potentially the coordinates of the rectangle on an atlas. If left to default of null, will only be set to texture bounds. public NinePatch(Texture2D texture, int left, int right, int bottom, int top, Rectangle? textureBounds = null) { this.texture = texture; if (textureBounds.HasValue) textureRegion = textureBounds.Value; else textureRegion = texture.Bounds; if (left + right >= textureRegion.Width) throw new ArgumentOutOfRangeException("a and b cannot be greater than or equal to the width of region."); if (bottom + top >= textureRegion.Height) throw new ArgumentOutOfRangeException("c and d cannot be greater or equal to the height of the texture."); this.left = left; this.right = right; this.bottom = bottom; this.top = top; color = Color.White; } /// /// Draws the ninepatch. /// /// Batch to use. /// Where to the patch. public void Draw(SpriteBatch spriteBatch, Rectangle destination) { Rectangle sourceRectangle; Rectangle drawnRectangle; //1x1 drawnRectangle.X = destination.X; drawnRectangle.Y = destination.Y; drawnRectangle.Width = left; drawnRectangle.Height = bottom; sourceRectangle.X = 0; sourceRectangle.Y = 0; sourceRectangle.Width = left; sourceRectangle.Height = bottom; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //2x1 drawnRectangle.X = destination.X + left; drawnRectangle.Y = destination.Y; drawnRectangle.Width = destination.Width - left - right; drawnRectangle.Height = bottom; sourceRectangle.X = left; sourceRectangle.Y = 0; sourceRectangle.Width = textureRegion.Width - left - right; sourceRectangle.Height = bottom; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //3x1 drawnRectangle.X = destination.X + destination.Width - right; drawnRectangle.Y = destination.Y; drawnRectangle.Width = right; drawnRectangle.Height = bottom; sourceRectangle.X = textureRegion.Width - right; sourceRectangle.Y = 0; sourceRectangle.Width = right; sourceRectangle.Height = bottom; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //1x2 drawnRectangle.X = destination.X; drawnRectangle.Y = destination.Y + bottom; drawnRectangle.Width = left; drawnRectangle.Height = destination.Height - top - bottom; sourceRectangle.X = 0; sourceRectangle.Y = bottom; sourceRectangle.Width = left; sourceRectangle.Height = textureRegion.Height - bottom - top; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //2x2 drawnRectangle.X = destination.X + left; drawnRectangle.Y = destination.Y + bottom; drawnRectangle.Width = destination.Width - left - right; drawnRectangle.Height = destination.Height - bottom - top; sourceRectangle.X = left; sourceRectangle.Y = bottom; sourceRectangle.Width = textureRegion.Width - left - right; sourceRectangle.Height = textureRegion.Height - bottom - top; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //3x2 drawnRectangle.X = destination.X + destination.Width - right; drawnRectangle.Y = destination.Y + bottom; drawnRectangle.Width = right; drawnRectangle.Height = destination.Height - bottom - top; sourceRectangle.X = textureRegion.Width - right; sourceRectangle.Y = bottom; sourceRectangle.Width = right; sourceRectangle.Height = textureRegion.Height - bottom - top; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //1x3 drawnRectangle.X = destination.X; drawnRectangle.Y = destination.Height - top; drawnRectangle.Width = left; drawnRectangle.Height = top; sourceRectangle.X = left; sourceRectangle.Y = textureRegion.Height - top; sourceRectangle.Width = left; sourceRectangle.Height = top; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //2x3 drawnRectangle.X = destination.X + left; drawnRectangle.Y = destination.Height - top; drawnRectangle.Width = destination.Width - left - right; drawnRectangle.Height = top; sourceRectangle.X = left; sourceRectangle.Y = textureRegion.Height - top; sourceRectangle.Width = textureRegion.Width - left - right; sourceRectangle.Height = top; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); //3x3 drawnRectangle.X = destination.X + destination.Width - right; drawnRectangle.Y = destination.Height - top; drawnRectangle.Width = right; drawnRectangle.Height = top; sourceRectangle.X = textureRegion.Width - right; sourceRectangle.Y = textureRegion.Height - top; sourceRectangle.Width = right; sourceRectangle.Height = top; sourceRectangle.X += textureRegion.X; sourceRectangle.Y += textureRegion.Y; spriteBatch.Draw(texture, drawnRectangle, sourceRectangle, color); } /// /// Draw with more options. /// /// Spritebatch to use. /// The destination to draw the patch. /// The tint for each patch. /// Not considered for 9patches. /// Not considered for 9patches. public void Draw(SpriteBatch spriteBatch, Rectangle destination, Color color, float rotation = 0, Vector2 origin = default(Vector2)) { this.color = color; Draw(spriteBatch, destination); } } }