using OpenTK.Graphics;
using RecrownedAthenaeum.Graphics.Render;
using System.Collections.Generic;
namespace RecrownedAthenaeum.Graphics.UI.ScreenSystem
{
///
/// Represents one of the poosible states a screen can be in.
///
public enum ScreenState {
///
/// Screen is transitioning in.
///
EnterTransition,
///
/// Screen is transitioning out.
///
ExitTransition,
///
/// Screen is currently displayed normally without transition.
///
Normal
}
///
/// A screen represents a virtual system of management that controls an system of items to be displayed.
///
public class Screen
{
///
/// Transitions to apply.
///
public readonly List Transitions;
///
/// Whether or not to continue rendering this screen onto a buffer for the benefit of the next screen to use as a transition.
///
public bool UseRenderTargetForExitTransition { get; private set; }
///
/// The background color to be used to clear the screen.
///
public Color4 BackgroundColor;
///
/// The next screen to be displayed after exit transition finishes. May be null, leading to transition to previous screen or loading screen.
///
public Screen NextScreen { get; set; }
///
/// The current window dimensions.
///
public int width, height;
///
/// Current state of the screen.
///
public ScreenState State { get; private set; }
///
/// Creates a new screen.
///
/// True to start in entering transition state.
public Screen(bool useEnterTransition = false)
{
State = useEnterTransition ? ScreenState.EnterTransition : ScreenState.Normal;
Transitions = new List();
}
///
/// Called when screen size is set.
///
/// The width of the screen.
/// The height of the screen.
public virtual void ApplySize(int width, int height)
{
this.width = width;
this.height = height;
}
///
/// Called to update the screen.
///
/// Game time information.
public virtual void Update(GameTime gameTime)
{
}
///
/// Called to draw this screen.
///
/// SpriteBatch to use.
public virtual void Draw(ConsistentSpriteBatch spriteBatch)
{
foreach (ITransition transition in Transitions)
{
transition.DrawTransition(spriteBatch);
}
}
///
/// Updates the transition based on the current state of the screen.
///
/// Time passed since last frame in seconds.
/// If the this transition should wait.
/// Only returns true if exit transition is complete. Returns false otherwise.
public bool UpdateTransition(double delta, bool waiting)
{
switch (State)
{
case ScreenState.EnterTransition:
EnteringTransition(delta, waiting);
break;
case ScreenState.ExitTransition:
return ExitingTransition(delta, waiting);
}
return false;
}
private void EnteringTransition(double delta, bool waiting)
{
bool complete = true;
for (int transitionID = 0; transitionID < Transitions.Count; transitionID++)
{
ITransition transition = Transitions[transitionID];
if (!transition.UpdateEnteringTransition(delta, waiting))
{
complete = false;
}
}
if (complete && State != ScreenState.ExitTransition)
{
State = ScreenState.Normal;
}
}
private bool ExitingTransition(double delta, bool waiting)
{
bool complete = true;
foreach (ITransition transition in Transitions)
{
if (!transition.UpdateExitingTransition(delta, waiting))
{
complete = false;
}
}
return complete;
}
///
/// Called when the screen is shown.
///
public virtual void Show()
{
foreach (ITransition transition in Transitions)
{
transition.InitiateTransition(new Rectangle(0, 0, width, height));
}
}
///
/// Called when this screen is no longer the displayed screen.
///
public virtual void Hide()
{
}
///
/// Called whenever the status of assets changes from being loaded to unloaded or unloaded to loaded.
///
/// True for loaded, false for unloaded.
public virtual void AssetLoadStateChange(bool state)
{
}
///
/// Call this to begin exit transition.
///
/// Whether or not to use a render target for the next screen to use.
public void StartExitTransition(bool UseRenderTargetForExitTransition = false)
{
this.UseRenderTargetForExitTransition = UseRenderTargetForExitTransition;
State = ScreenState.ExitTransition;
}
///
/// Called everytime the previous screen frame buffer updates. Used for transition purposes.
///
/// The previous screen's render buffer.
public virtual void UpdatePreviousScreenFrame(RenderTarget2D previousScreenFrame)
{
foreach (ITransition transition in Transitions)
{
transition.UpdatePreviousScreenFrame(previousScreenFrame);
}
}
}
}