/*
* RectangleLocator - Generalized mechanism to calculate rectangles
*
* Author: Phillip Piper
* Date: 18/01/2010 5:48 PM
*
* Change log:
* 2010-01-18 JPP - Initial version
*
* To do:
*
* Copyright (C) 2009 Phillip Piper
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com.
*/
using System.Drawing;
namespace BrightIdeasSoftware
{
///
/// A IRectangleLocator calculates a rectangle
///
public interface IRectangleLocator
{
ISprite Sprite { get; set; }
Rectangle GetRectangle();
}
///
/// A safe do-nothing implementation of IRectangleLocator plus some useful utilities
///
public class AbstractRectangleLocator : IRectangleLocator
{
#region Properties
public Point Expansion ;
public ISprite Sprite {
get { return this.sprite; }
set {
this.sprite = value;
this.InitializeSublocators();
}
}
private ISprite sprite;
#endregion
#region Public interface
public virtual Rectangle GetRectangle() {
return Rectangle.Empty;
}
#endregion
#region Utilities
protected Rectangle Expand(Rectangle r) {
if (this.Expansion == Point.Empty)
return r;
Rectangle r2 = r;
r2.Inflate(this.Expansion.X, this.Expansion.Y);
return r2;
}
///
/// The sprite associate with this locator has changed.
/// Make sure any dependent locators are updated
///
protected virtual void InitializeSublocators() {
}
protected void InitializeLocator(IPointLocator locator) {
if (locator != null && locator.Sprite == null)
locator.Sprite = this.Sprite;
}
protected void InitializeLocator(IRectangleLocator locator) {
if (locator != null && locator.Sprite == null)
locator.Sprite = this.Sprite;
}
#endregion
}
///
/// A SpritePointLocator calculates a point relative to
/// the reference bound of sprite.
///
public class SpriteBoundsLocator : AbstractRectangleLocator
{
public SpriteBoundsLocator() {
}
public SpriteBoundsLocator(ISprite sprite) {
this.Sprite = sprite;
}
public SpriteBoundsLocator(int expandX, int expandY) {
this.Expansion = new Point(expandX, expandY);
}
public override Rectangle GetRectangle() {
return this.Expand(this.Sprite.Bounds);
}
}
///
/// A AnimationBoundsLocator calculates a point
/// on the bounds of whole animation.
///
public class AnimationBoundsLocator : AbstractRectangleLocator
{
public AnimationBoundsLocator() {
}
public AnimationBoundsLocator(int expandX, int expandY) {
this.Expansion = new Point(expandX, expandY);
}
public override Rectangle GetRectangle() {
return this.Expand(this.Sprite.OuterBounds);
}
}
///
/// A RectangleFromCornersLocator calculates its rectangle through two point locators,
/// one for the top left, the other for the bottom right. The rectangle
/// can also be expanded by a fixed amount.
///
public class RectangleFromCornersLocator : AbstractRectangleLocator
{
#region Life and death
public RectangleFromCornersLocator(IPointLocator topLeftLocator, IPointLocator bottomRightLocator) :
this(topLeftLocator, bottomRightLocator, Point.Empty) {
}
public RectangleFromCornersLocator(IPointLocator topLeftLocator, IPointLocator bottomRightLocator, Point expand) {
this.TopLeftLocator = topLeftLocator;
this.BottomRightLocator = bottomRightLocator;
this.Expansion = expand;
}
#endregion
#region Configuration properties
protected IPointLocator TopLeftLocator ;
protected IPointLocator BottomRightLocator ;
#endregion
#region Public methods
public override Rectangle GetRectangle() {
Point topLeft = this.TopLeftLocator.GetPoint();
Point bottomRight = this.BottomRightLocator.GetPoint();
return this.Expand(Rectangle.FromLTRB(topLeft.X, topLeft.Y, bottomRight.X, bottomRight.Y));
}
#endregion
protected override void InitializeSublocators() {
this.InitializeLocator(this.TopLeftLocator);
this.InitializeLocator(this.BottomRightLocator);
}
}
///
/// A FixedRectangleLocator simply returns the rectangle with which it was initialized
///
public class FixedRectangleLocator : AbstractRectangleLocator
{
public FixedRectangleLocator(Rectangle r) {
this.Rectangle = r;
}
public FixedRectangleLocator(int x, int y, int width, int height) {
this.Rectangle = new Rectangle(x, y, width, height);
}
protected Rectangle Rectangle ;
public override Rectangle GetRectangle() {
return this.Expand(this.Rectangle);
}
}
}