2020-03-02 10:31:03 +01:00
|
|
|
using System;
|
2019-09-08 16:30:55 +02:00
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
|
|
|
|
namespace MLEM.Ui.Elements {
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// A <see cref="Group"/> that can have custom drawing parameters.
|
|
|
|
/// Custom drawing parameters include a <see cref="Transform"/> matrix, as well as a custom <see cref="SpriteBatch.Begin"/> call.
|
|
|
|
/// All <see cref="Element.Children"/> of the custom draw group will be drawn with the custom parameters.
|
|
|
|
/// </summary>
|
2019-09-08 16:30:55 +02:00
|
|
|
public class CustomDrawGroup : Group {
|
|
|
|
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// This custom draw group's transform matrix
|
|
|
|
/// </summary>
|
2019-12-29 19:28:56 +01:00
|
|
|
public Matrix? Transform;
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// A callback for retrieving this group's <see cref="Transform"/> automatically
|
|
|
|
/// </summary>
|
2019-12-29 19:28:56 +01:00
|
|
|
public TransformCallback TransformGetter;
|
2020-03-02 10:31:03 +01:00
|
|
|
private BeginDelegate beginImpl;
|
|
|
|
private bool isDefaultBegin;
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// The call that this custom draw group should make to <see cref="SpriteBatch"/> to begin drawing.
|
|
|
|
/// </summary>
|
2020-03-02 10:31:03 +01:00
|
|
|
public BeginDelegate BeginImpl {
|
|
|
|
get => this.beginImpl;
|
|
|
|
set {
|
|
|
|
this.beginImpl = value ?? ((element, time, batch, alpha, blendState, samplerState, matrix) => batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, matrix));
|
|
|
|
this.isDefaultBegin = value == null;
|
|
|
|
}
|
|
|
|
}
|
2019-09-08 16:30:55 +02:00
|
|
|
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Creates a new custom draw group with the given settings
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="anchor">The group's anchor</param>
|
|
|
|
/// <param name="size">The group's size</param>
|
|
|
|
/// <param name="transformGetter">The group's <see cref="TransformGetter"/></param>
|
|
|
|
/// <param name="beginImpl">The group's <see cref="BeginImpl"/></param>
|
|
|
|
/// <param name="setHeightBasedOnChildren">Whether this group should automatically calculate its height based on its children</param>
|
2019-12-29 19:28:56 +01:00
|
|
|
public CustomDrawGroup(Anchor anchor, Vector2 size, TransformCallback transformGetter = null, BeginDelegate beginImpl = null, bool setHeightBasedOnChildren = true) :
|
2019-09-08 16:30:55 +02:00
|
|
|
base(anchor, size, setHeightBasedOnChildren) {
|
2019-12-29 19:28:56 +01:00
|
|
|
this.TransformGetter = transformGetter ?? ((element, time, matrix) => Matrix.Identity);
|
2020-03-02 10:31:03 +01:00
|
|
|
this.BeginImpl = beginImpl;
|
2019-09-08 16:30:55 +02:00
|
|
|
}
|
|
|
|
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <inheritdoc />
|
2019-09-20 13:22:05 +02:00
|
|
|
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
2020-03-02 10:31:03 +01:00
|
|
|
var transform = this.Transform ?? this.TransformGetter(this, time, matrix);
|
|
|
|
var customDraw = !this.isDefaultBegin || transform != Matrix.Identity;
|
|
|
|
var mat = matrix * transform;
|
|
|
|
if (customDraw) {
|
|
|
|
// end the usual draw so that we can begin our own
|
|
|
|
batch.End();
|
|
|
|
this.BeginImpl(this, time, batch, alpha, blendState, samplerState, mat);
|
|
|
|
}
|
2019-09-08 16:30:55 +02:00
|
|
|
// draw child components in custom begin call
|
2019-09-20 13:22:05 +02:00
|
|
|
base.Draw(time, batch, alpha, blendState, samplerState, mat);
|
2020-03-02 10:31:03 +01:00
|
|
|
if (customDraw) {
|
|
|
|
// end our draw
|
|
|
|
batch.End();
|
|
|
|
// begin the usual draw again for other elements
|
|
|
|
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, matrix);
|
|
|
|
}
|
2019-09-08 16:30:55 +02:00
|
|
|
}
|
|
|
|
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Scales this custom draw group's <see cref="Transform"/> matrix based on the given scale and origin.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="scale">The scale to use</param>
|
|
|
|
/// <param name="origin">The origin to use for scaling, or null to use this element's center point</param>
|
2020-03-18 16:47:14 +01:00
|
|
|
public void ScaleOrigin(float scale, Vector2? origin = null) {
|
2020-06-02 16:15:41 +02:00
|
|
|
this.Transform = Matrix.CreateScale(scale, scale, 1) * Matrix.CreateTranslation(new Vector3((1 - scale) * (origin ?? this.DisplayArea.Center), 0));
|
2020-03-18 16:47:14 +01:00
|
|
|
}
|
|
|
|
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// A delegate method used for <see cref="CustomDrawGroup.BeginImpl"/>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="element">The custom draw group</param>
|
|
|
|
/// <param name="time">The game's time</param>
|
|
|
|
/// <param name="batch">The sprite batch used for drawing</param>
|
|
|
|
/// <param name="alpha">This element's draw alpha</param>
|
|
|
|
/// <param name="blendState">The blend state used for drawing</param>
|
|
|
|
/// <param name="samplerState">The sampler state used for drawing</param>
|
|
|
|
/// <param name="matrix">The transform matrix used for drawing</param>
|
2019-12-29 19:28:56 +01:00
|
|
|
public delegate void BeginDelegate(CustomDrawGroup element, GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix);
|
|
|
|
|
2020-05-22 17:02:24 +02:00
|
|
|
/// <summary>
|
|
|
|
/// A delegate method used for <see cref="CustomDrawGroup.TransformGetter"/>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="element">The element whose transform to get</param>
|
|
|
|
/// <param name="time">The game's time</param>
|
|
|
|
/// <param name="matrix">The regular transform matrix</param>
|
2019-12-29 19:28:56 +01:00
|
|
|
public delegate Matrix TransformCallback(CustomDrawGroup element, GameTime time, Matrix matrix);
|
|
|
|
|
2019-09-08 16:30:55 +02:00
|
|
|
}
|
|
|
|
}
|