1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-18 11:24:31 +02:00

added a rectanglef class which allows mlem to use decimal coordinates

This commit is contained in:
Ellpeck 2019-11-02 14:53:59 +01:00
parent cb7abbbbef
commit 32c8147a4c
19 changed files with 310 additions and 79 deletions

View file

@ -0,0 +1,15 @@
using MonoGame.Extended;
namespace MLEM.Extended.Extensions {
public static class NumberExtensions {
public static RectangleF ToExtended(this Misc.RectangleF rect) {
return new RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
}
public static Misc.RectangleF ToMlem(this RectangleF rect) {
return new Misc.RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
}
}
}

View file

@ -1,5 +1,8 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Textures;
using MonoGame.Extended;
using MonoGame.Extended.BitmapFonts;
namespace MLEM.Extended.Extensions {
@ -15,6 +18,18 @@ namespace MLEM.Extended.Extensions {
color, 0, size / 2, scale + addedScale, SpriteEffects.None, 0);
}
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) {
batch.Draw(texture, destinationRectangle.ToMlem(), sourceRectangle, color, rotation, origin, effects, layerDepth);
}
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color) {
batch.Draw(texture, destinationRectangle, sourceRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
}
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Color color) {
batch.Draw(texture, destinationRectangle, null, color);
}
}
}

View file

@ -2,6 +2,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Input;
using MLEM.Misc;
using MLEM.Textures;
using MLEM.Ui.Style;
@ -37,7 +38,7 @@ namespace MLEM.Ui.Elements {
}
}
protected override Point CalcActualSize(Rectangle parentArea) {
protected override Vector2 CalcActualSize(RectangleF parentArea) {
var size = base.CalcActualSize(parentArea);
if (this.Label != null) {
this.Label.Size = new Vector2((size.X - size.Y) / this.Scale - this.TextOffsetX, 1);
@ -55,7 +56,7 @@ namespace MLEM.Ui.Elements {
color = (Color) this.HoveredColor * alpha;
}
var boxDisplayArea = new Rectangle(this.DisplayArea.Location, new Point(this.DisplayArea.Height));
var boxDisplayArea = new RectangleF(this.DisplayArea.Location, new Vector2(this.DisplayArea.Height));
batch.Draw(tex, boxDisplayArea, color, this.Scale);
if (this.Checked)
batch.Draw(this.Checkmark, boxDisplayArea, Color.White * alpha);

View file

@ -26,7 +26,7 @@ namespace MLEM.Ui.Elements {
private Vector2 size;
private Vector2 offset;
public Vector2 Padding;
public Point ScaledPadding => (this.Padding * this.Scale).ToPoint();
public Vector2 ScaledPadding => this.Padding * this.Scale;
private Vector2 childPadding;
public Anchor Anchor {
get => this.anchor;
@ -56,7 +56,7 @@ namespace MLEM.Ui.Elements {
this.SetAreaDirty();
}
}
public Point ScaledOffset => (this.offset * this.Scale).ToPoint();
public Vector2 ScaledOffset => (this.offset * this.Scale);
public Vector2 ChildPadding {
get => this.childPadding;
set {
@ -66,8 +66,8 @@ namespace MLEM.Ui.Elements {
this.SetAreaDirty();
}
}
public Rectangle ChildPaddedArea => this.UnscrolledArea.Shrink(this.ScaledChildPadding);
public Point ScaledChildPadding => (this.childPadding * this.Scale).ToPoint();
public RectangleF ChildPaddedArea => this.UnscrolledArea.Shrink(this.ScaledChildPadding);
public Vector2 ScaledChildPadding => this.childPadding * this.Scale;
public DrawCallback OnDrawn;
public TimeCallback OnUpdated;
@ -116,17 +116,17 @@ namespace MLEM.Ui.Elements {
public bool SetHeightBasedOnChildren;
public bool CanAutoAnchorsAttach = true;
private Rectangle area;
public Rectangle UnscrolledArea {
private RectangleF area;
public RectangleF UnscrolledArea {
get {
this.UpdateAreaIfDirty();
return this.area;
}
}
public Rectangle Area => this.UnscrolledArea.OffsetCopy(this.ScaledScrollOffset);
public RectangleF Area => this.UnscrolledArea.OffsetCopy(this.ScaledScrollOffset);
public Vector2 ScrollOffset;
public Point ScaledScrollOffset => (this.ScrollOffset * this.Scale).ToPoint();
public Rectangle DisplayArea => this.Area.Shrink(this.ScaledPadding);
public Vector2 ScaledScrollOffset => this.ScrollOffset * this.Scale;
public RectangleF DisplayArea => this.Area.Shrink(this.ScaledPadding);
private int priority;
public int Priority {
get => this.priority;
@ -218,12 +218,12 @@ namespace MLEM.Ui.Elements {
if (this.IsHidden)
return;
var parentArea = this.Parent != null ? this.Parent.ChildPaddedArea : this.system.Viewport;
var parentArea = this.Parent != null ? this.Parent.ChildPaddedArea : (RectangleF) this.system.Viewport;
var parentCenterX = parentArea.X + parentArea.Width / 2;
var parentCenterY = parentArea.Y + parentArea.Height / 2;
var actualSize = this.CalcActualSize(parentArea);
var pos = new Point();
var pos = new Vector2();
switch (this.anchor) {
case Anchor.TopLeft:
@ -301,7 +301,7 @@ namespace MLEM.Ui.Elements {
}
}
this.area = new Rectangle(pos, actualSize);
this.area = new RectangleF(pos, actualSize);
this.System.OnElementAreaUpdated?.Invoke(this);
foreach (var child in this.Children)
@ -319,13 +319,13 @@ namespace MLEM.Ui.Elements {
}
}
protected virtual Point CalcActualSize(Rectangle parentArea) {
return new Point(
(this.size.X > 1 ? this.ScaledSize.X : parentArea.Width * this.size.X).Ceil(),
(this.size.Y > 1 ? this.ScaledSize.Y : parentArea.Height * this.size.Y).Ceil());
protected virtual Vector2 CalcActualSize(RectangleF parentArea) {
return new Vector2(
this.size.X > 1 ? this.ScaledSize.X : parentArea.Width * this.size.X,
this.size.Y > 1 ? this.ScaledSize.Y : parentArea.Height * this.size.Y);
}
protected virtual Rectangle GetAreaForAutoAnchors() {
protected virtual RectangleF GetAreaForAutoAnchors() {
return this.UnscrolledArea;
}
@ -443,7 +443,7 @@ namespace MLEM.Ui.Elements {
}
}
public virtual Element GetElementUnderPos(Point position) {
public virtual Element GetElementUnderPos(Vector2 position) {
if (this.IsHidden)
return null;
var children = this.GetRelevantChildren();

View file

@ -1,6 +1,7 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Misc;
using MLEM.Textures;
using MLEM.Ui.Style;
@ -51,8 +52,8 @@ namespace MLEM.Ui.Elements {
this.CanBeMoused = false;
}
protected override Point CalcActualSize(Rectangle parentArea) {
return this.texture != null && this.scaleToImage ? this.texture.Size : base.CalcActualSize(parentArea);
protected override Vector2 CalcActualSize(RectangleF parentArea) {
return this.texture != null && this.scaleToImage ? this.texture.Size.ToVector2() : base.CalcActualSize(parentArea);
}
public override void Update(GameTime time) {
@ -69,10 +70,10 @@ namespace MLEM.Ui.Elements {
if (this.MaintainImageAspect) {
var scale = Math.Min(this.DisplayArea.Width / (float) this.texture.Width, this.DisplayArea.Height / (float) this.texture.Height);
var imageOffset = new Vector2(this.DisplayArea.Width / 2F - this.texture.Width * scale / 2, this.DisplayArea.Height / 2F - this.texture.Height * scale / 2);
batch.Draw(this.texture, this.DisplayArea.Location.ToVector2() + center * scale + imageOffset, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
batch.Draw(this.texture, this.DisplayArea.Location + center * scale + imageOffset, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
} else {
var scale = new Vector2(1F / this.texture.Width, 1F / this.texture.Height) * this.DisplayArea.Size.ToVector2();
batch.Draw(this.texture, this.DisplayArea.Location.ToVector2() + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
var scale = new Vector2(1F / this.texture.Width, 1F / this.texture.Height) * this.DisplayArea.Size;
batch.Draw(this.texture, this.DisplayArea.Location + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
}
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
}

View file

@ -5,6 +5,7 @@ using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Misc;
using MLEM.Textures;
using MLEM.Ui.Style;
@ -82,8 +83,7 @@ namespace MLEM.Ui.Elements {
if (this.renderTarget == null || targetArea.Width != this.renderTarget.Width || targetArea.Height != this.renderTarget.Height) {
if (this.renderTarget != null)
this.renderTarget.Dispose();
var empty = targetArea.Width <= 0 || targetArea.Height <= 0;
this.renderTarget = empty ? null : new RenderTarget2D(this.System.GraphicsDevice, targetArea.Width, targetArea.Height);
this.renderTarget = targetArea.IsEmpty ? null : new RenderTarget2D(this.System.GraphicsDevice, targetArea.Width.Ceil(), targetArea.Height.Ceil());
}
}
}
@ -91,7 +91,7 @@ namespace MLEM.Ui.Elements {
private void ScrollChildren() {
if (!this.scrollOverflow)
return;
var offset = -this.ScrollBar.CurrentValue.Floor();
var offset = -this.ScrollBar.CurrentValue;
foreach (var child in this.GetChildren(c => c != this.ScrollBar, true))
child.ScrollOffset = new Vector2(0, offset);
this.relevantChildrenDirty = true;
@ -154,14 +154,14 @@ namespace MLEM.Ui.Elements {
}
}
public override Element GetElementUnderPos(Point position) {
public override Element GetElementUnderPos(Vector2 position) {
// if overflow is handled, don't propagate mouse checks to hidden children
if (this.scrollOverflow && !this.GetRenderTargetArea().Contains(position))
return null;
return base.GetElementUnderPos(position);
}
private Rectangle GetRenderTargetArea() {
private RectangleF GetRenderTargetArea() {
var area = this.ChildPaddedArea;
area.X = this.DisplayArea.X;
area.Width = this.DisplayArea.Width;

View file

@ -7,6 +7,7 @@ using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Font;
using MLEM.Formatting;
using MLEM.Misc;
using MLEM.Textures;
using MLEM.Ui.Style;
@ -55,7 +56,7 @@ namespace MLEM.Ui.Elements {
this.CanBeMoused = false;
}
protected override Point CalcActualSize(Rectangle parentArea) {
protected override Vector2 CalcActualSize(RectangleF parentArea) {
var size = base.CalcActualSize(parentArea);
var sc = this.TextScale * this.Scale;
@ -63,7 +64,7 @@ namespace MLEM.Ui.Elements {
this.codeLocations = this.text.GetFormattingCodes();
var textDims = this.RegularFont.Value.MeasureString(this.splitText) * sc;
return new Point(this.AutoAdjustWidth ? textDims.X.Ceil() + this.ScaledPadding.X * 2 : size.X, textDims.Y.Ceil() + this.ScaledPadding.Y * 2);
return new Vector2(this.AutoAdjustWidth ? textDims.X + this.ScaledPadding.X * 2 : size.X, textDims.Y + this.ScaledPadding.Y * 2);
}
public override void Update(GameTime time) {
@ -77,7 +78,7 @@ namespace MLEM.Ui.Elements {
if (this.Background.Value != null)
batch.Draw(this.Background, this.Area, (Color) this.BackgroundColor * alpha);
var pos = this.DisplayArea.Location.ToVector2();
var pos = this.DisplayArea.Location;
var sc = this.TextScale * this.Scale;
var color = (this.TextColor.Value != default ? this.TextColor : Color.White) * alpha;

View file

@ -11,7 +11,7 @@ namespace MLEM.Ui.Elements {
public StyleProp<NinePatch> Texture;
public StyleProp<Color> Color;
public StyleProp<Point> ProgressPadding;
public StyleProp<Vector2> ProgressPadding;
public StyleProp<NinePatch> ProgressTexture;
public StyleProp<Color> ProgressColor;
@ -39,28 +39,28 @@ namespace MLEM.Ui.Elements {
var tex = this.ProgressTexture.Value;
var padHor = tex != null ? (tex.PaddingLeft + tex.PaddingRight) * this.Scale : 0;
var padVer = tex != null ? (tex.PaddingTop + tex.PaddingBottom) * this.Scale : 0;
var width = (percentage * (this.DisplayArea.Width - padHor) + padHor).Floor();
var height = (percentage * (this.DisplayArea.Height - padVer) + padVer).Floor();
Rectangle progressArea;
var width = percentage * (this.DisplayArea.Width - padHor) + padHor;
var height = percentage * (this.DisplayArea.Height - padVer) + padVer;
RectangleF progressArea;
switch (this.Direction) {
case Direction2.Up:
progressArea = new Rectangle(this.DisplayArea.X,
progressArea = new RectangleF(this.DisplayArea.X,
this.DisplayArea.Y + (this.DisplayArea.Height - height),
this.DisplayArea.Width, height);
break;
case Direction2.Down:
progressArea = new Rectangle(this.DisplayArea.Location, new Point(this.DisplayArea.Width, height));
progressArea = new RectangleF(this.DisplayArea.Location, new Vector2(this.DisplayArea.Width, height));
break;
case Direction2.Left:
progressArea = new Rectangle(
progressArea = new RectangleF(
this.DisplayArea.X + (this.DisplayArea.Width - width),
this.DisplayArea.Y, width, this.DisplayArea.Height);
break;
default: // Right
progressArea = new Rectangle(this.DisplayArea.Location, new Point(width, this.DisplayArea.Height));
progressArea = new RectangleF(this.DisplayArea.Location, new Vector2(width, this.DisplayArea.Height));
break;
}
var offsetArea = progressArea.Shrink(this.ProgressPadding.Value.Multiply(this.Scale));
var offsetArea = progressArea.Shrink(this.ProgressPadding.Value * this.Scale);
if (this.ProgressTexture.Value != null) {
batch.Draw(this.ProgressTexture, offsetArea, (Color) this.ProgressColor * alpha, this.Scale);
} else {

View file

@ -5,6 +5,7 @@ using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
using MLEM.Extensions;
using MLEM.Input;
using MLEM.Misc;
using MLEM.Textures;
using MLEM.Ui.Style;
@ -13,8 +14,8 @@ namespace MLEM.Ui.Elements {
public StyleProp<NinePatch> Background;
public StyleProp<NinePatch> ScrollerTexture;
public Point ScrollerOffset;
public Point ScrollerSize;
public Vector2 ScrollerOffset;
public Vector2 ScrollerSize;
private float maxValue;
public float MaxValue {
get => this.maxValue;
@ -52,7 +53,7 @@ namespace MLEM.Ui.Elements {
public ScrollBar(Anchor anchor, Vector2 size, int scrollerSize, float maxValue, bool horizontal = false) : base(anchor, size) {
this.maxValue = maxValue;
this.Horizontal = horizontal;
this.ScrollerSize = new Point(horizontal ? scrollerSize : size.X.Floor(), !horizontal ? scrollerSize : size.Y.Floor());
this.ScrollerSize = new Vector2(horizontal ? scrollerSize : size.X, !horizontal ? scrollerSize : size.Y);
this.CanBeSelected = false;
}
@ -79,7 +80,7 @@ namespace MLEM.Ui.Elements {
// are we dragging on top of the panel?
if (this.Input.GetGesture(GestureType.VerticalDrag, out var drag)) {
// if the element under the drag's start position is on top of the panel, start dragging
var touched = this.Parent.GetElementUnderPos(drag.Position.ToPoint().Transform(this.Root.InvTransform));
var touched = this.Parent.GetElementUnderPos(Vector2.Transform(drag.Position, this.Root.InvTransform));
if (touched != null && touched != this)
this.isDragging = true;
@ -121,11 +122,11 @@ namespace MLEM.Ui.Elements {
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale);
var scrollerPos = new Point(this.DisplayArea.X + this.ScrollerOffset.X, this.DisplayArea.Y + this.ScrollerOffset.Y);
var scrollerOffset = new Point(
!this.Horizontal ? 0 : (this.currValue / this.maxValue * (this.DisplayArea.Width - this.ScrollerSize.X * this.Scale)).Floor(),
this.Horizontal ? 0 : (this.currValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale)).Floor());
var scrollerRect = new Rectangle(scrollerPos + scrollerOffset, new Point((this.ScrollerSize.X * this.Scale).Ceil(), (this.ScrollerSize.Y * this.Scale).Ceil()));
var scrollerPos = new Vector2(this.DisplayArea.X + this.ScrollerOffset.X, this.DisplayArea.Y + this.ScrollerOffset.Y);
var scrollerOffset = new Vector2(
!this.Horizontal ? 0 : this.currValue / this.maxValue * (this.DisplayArea.Width - this.ScrollerSize.X * this.Scale),
this.Horizontal ? 0 : this.currValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale));
var scrollerRect = new RectangleF(scrollerPos + scrollerOffset, new Vector2((this.ScrollerSize.X * this.Scale).Ceil(), (this.ScrollerSize.Y * this.Scale).Ceil()));
batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale);
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
}

View file

@ -143,13 +143,15 @@ namespace MLEM.Ui.Elements {
}
batch.Draw(tex, this.DisplayArea, color, this.Scale);
var textPos = this.DisplayArea.Location.ToVector2() + new Vector2(this.TextOffsetX * this.Scale, this.DisplayArea.Height / 2);
if (this.text.Length > 0 || this.IsSelected) {
var caret = this.IsSelected ? this.caretBlinkTimer >= 0.5F ? "|" : " " : "";
var display = this.displayedText.Insert(this.CaretPos - this.textOffset, caret);
this.Font.Value.DrawCenteredString(batch, display, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true);
} else if (this.PlaceholderText != null) {
this.Font.Value.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true);
if (this.displayedText != null) {
var textPos = this.DisplayArea.Location + new Vector2(this.TextOffsetX * this.Scale, this.DisplayArea.Height / 2);
if (this.text.Length > 0 || this.IsSelected) {
var caret = this.IsSelected ? this.caretBlinkTimer >= 0.5F ? "|" : " " : "";
var display = this.displayedText.Insert(this.CaretPos - this.textOffset, caret);
this.Font.Value.DrawCenteredString(batch, display, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true);
} else if (this.PlaceholderText != null) {
this.Font.Value.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true);
}
}
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
}

View file

@ -27,7 +27,7 @@ namespace MLEM.Ui.Style {
public Color TooltipBackgroundColor;
public NinePatch ProgressBarTexture;
public Color ProgressBarColor;
public Point ProgressBarProgressPadding;
public Vector2 ProgressBarProgressPadding;
public NinePatch ProgressBarProgressTexture;
public Color ProgressBarProgressColor;
public IGenericFont Font;

View file

@ -27,7 +27,7 @@ namespace MLEM.Ui.Style {
this.TooltipBackgroundColor = new Color(Color.Black, 0.65F);
this.ProgressBarTexture = GenerateTexture(batch, Color.RoyalBlue);
this.ProgressBarColor = Color.White;
this.ProgressBarProgressPadding = new Point(1);
this.ProgressBarProgressPadding = new Vector2(1);
this.ProgressBarProgressColor = Color.Red;
this.Font = new EmptyFont();
}

View file

@ -45,7 +45,7 @@ namespace MLEM.Ui {
this.ActiveRoot = this.System.GetRootElements().FirstOrDefault(root => root.CanSelectContent);
// MOUSE INPUT
var mousedNow = this.GetElementUnderPos(this.Input.MousePosition);
var mousedNow = this.GetElementUnderPos(this.Input.MousePosition.ToVector2());
if (mousedNow != this.MousedElement) {
if (this.MousedElement != null)
this.System.OnElementMouseExit?.Invoke(this.MousedElement);
@ -92,13 +92,13 @@ namespace MLEM.Ui {
// TOUCH INPUT
else if (this.Input.GetGesture(GestureType.Tap, out var tap)) {
this.IsAutoNavMode = false;
var tapped = this.GetElementUnderPos(tap.Position.ToPoint());
var tapped = this.GetElementUnderPos(tap.Position);
this.ActiveRoot?.SelectElement(tapped);
if (tapped != null)
this.System.OnElementPressed?.Invoke(tapped);
} else if (this.Input.GetGesture(GestureType.Hold, out var hold)) {
this.IsAutoNavMode = false;
var held = this.GetElementUnderPos(hold.Position.ToPoint());
var held = this.GetElementUnderPos(hold.Position);
this.ActiveRoot?.SelectElement(held);
if (held != null)
this.System.OnElementSecondaryPressed?.Invoke(held);
@ -124,9 +124,9 @@ namespace MLEM.Ui {
}
}
public virtual Element GetElementUnderPos(Point position, bool transform = true) {
public virtual Element GetElementUnderPos(Vector2 position, bool transform = true) {
foreach (var root in this.System.GetRootElements()) {
var pos = transform ? position.Transform(root.InvTransform) : position;
var pos = transform ? Vector2.Transform(position, root.InvTransform) : position;
var moused = root.Element.GetElementUnderPos(pos);
if (moused != null)
return moused;
@ -162,7 +162,7 @@ namespace MLEM.Ui {
}
}
protected virtual Element GetGamepadNextElement(Rectangle searchArea) {
protected virtual Element GetGamepadNextElement(RectangleF searchArea) {
if (this.ActiveRoot == null)
return null;
var children = this.ActiveRoot.Element.GetChildren(c => !c.IsHidden, true, true).Append(this.ActiveRoot.Element);
@ -174,7 +174,7 @@ namespace MLEM.Ui {
foreach (var child in children) {
if (!child.CanBeSelected || child == this.SelectedElement || !searchArea.Intersects(child.Area))
continue;
var dist = Vector2.Distance(child.Area.Center.ToVector2(), this.SelectedElement.Area.Center.ToVector2());
var dist = Vector2.Distance(child.Area.Center, this.SelectedElement.Area.Center);
if (closest == null || dist < closestDist) {
closest = child;
closestDist = dist;
@ -190,7 +190,7 @@ namespace MLEM.Ui {
private void HandleGamepadNextElement(Direction2 dir) {
this.IsAutoNavMode = true;
Rectangle searchArea = default;
RectangleF searchArea = default;
if (this.SelectedElement?.Root != null) {
searchArea = this.SelectedElement.Area;
var (_, _, width, height) = this.System.Viewport;

View file

@ -1,5 +1,6 @@
using System;
using Microsoft.Xna.Framework;
using MLEM.Misc;
namespace MLEM.Extensions {
public static class NumberExtensions {
@ -44,6 +45,12 @@ namespace MLEM.Extensions {
return rect;
}
public static RectangleF OffsetCopy(this RectangleF rect, Vector2 offset) {
rect.X += offset.X;
rect.Y += offset.Y;
return rect;
}
public static Rectangle Shrink(this Rectangle rect, Point padding) {
rect.X += padding.X;
rect.Y += padding.Y;
@ -52,5 +59,13 @@ namespace MLEM.Extensions {
return rect;
}
public static RectangleF Shrink(this RectangleF rect, Vector2 padding) {
rect.X += padding.X;
rect.Y += padding.Y;
rect.Width -= padding.X * 2;
rect.Height -= padding.Y * 2;
return rect;
}
}
}

View file

@ -1,5 +1,6 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Misc;
namespace MLEM.Extensions {
public static class SpriteBatchExtensions {
@ -30,5 +31,19 @@ namespace MLEM.Extensions {
color, 0, size / 2, scale + addedScale, SpriteEffects.None, 0);
}
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) {
var source = sourceRectangle ?? new Rectangle(0, 0, texture.Width, texture.Height);
var scale = new Vector2(1F / source.Width, 1F / source.Height) * destinationRectangle.Size;
batch.Draw(texture, destinationRectangle.Location, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
}
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color) {
batch.Draw(texture, destinationRectangle, sourceRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
}
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Color color) {
batch.Draw(texture, destinationRectangle, null, color);
}
}
}

142
MLEM/Misc/RectangleF.cs Normal file
View file

@ -0,0 +1,142 @@
using System;
using Microsoft.Xna.Framework;
using MLEM.Extensions;
namespace MLEM.Misc {
public struct RectangleF : IEquatable<RectangleF> {
public static RectangleF Empty => default;
public float X;
public float Y;
public float Width;
public float Height;
public float Left => this.X;
public float Right => this.X + this.Width;
public float Top => this.Y;
public float Bottom => this.Y + this.Height;
public bool IsEmpty => this.Width <= 0 || this.Height <= 0;
public Vector2 Location {
get => new Vector2(this.X, this.Y);
set {
this.X = value.X;
this.Y = value.Y;
}
}
public Vector2 Size {
get => new Vector2(this.Width, this.Height);
set {
this.Width = value.X;
this.Height = value.Y;
}
}
public Vector2 Center => new Vector2(this.X + this.Width / 2, this.Y + this.Height / 2);
public RectangleF(float x, float y, float width, float height) {
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
public RectangleF(Vector2 location, Vector2 size) {
this.X = location.X;
this.Y = location.Y;
this.Width = size.X;
this.Height = size.Y;
}
public static explicit operator Rectangle(RectangleF rect) {
return new Rectangle(rect.X.Floor(), rect.Y.Floor(), rect.Width.Floor(), rect.Height.Floor());
}
public static explicit operator RectangleF(Rectangle rect) {
return new RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
}
public static bool operator ==(RectangleF a, RectangleF b) {
return a.X == b.X && a.Y == b.Y && a.Width == b.Width && a.Height == b.Height;
}
public static bool operator !=(RectangleF a, RectangleF b) {
return !(a == b);
}
public bool Contains(float x, float y) {
return this.X <= x && x < this.X + this.Width && this.Y <= y && y < this.Y + this.Height;
}
public bool Contains(Vector2 value) {
return this.Contains(value.X, value.Y);
}
public bool Contains(RectangleF value) {
return this.X <= value.X && value.X + value.Width <= this.X + this.Width && this.Y <= value.Y && value.Y + value.Height <= this.Y + this.Height;
}
public override bool Equals(object obj) {
return obj is RectangleF f && this == f;
}
public bool Equals(RectangleF other) {
return this == other;
}
public override int GetHashCode() {
return (((17 * 23 + this.X.GetHashCode()) * 23 + this.Y.GetHashCode()) * 23 + this.Width.GetHashCode()) * 23 + this.Height.GetHashCode();
}
public void Inflate(float horizontalAmount, float verticalAmount) {
this.X -= horizontalAmount;
this.Y -= verticalAmount;
this.Width += horizontalAmount * 2;
this.Height += verticalAmount * 2;
}
public bool Intersects(RectangleF value) {
return value.Left < this.Right && this.Left < value.Right && value.Top < this.Bottom && this.Top < value.Bottom;
}
public static RectangleF Intersect(RectangleF value1, RectangleF value2) {
if (value1.Intersects(value2)) {
var num1 = Math.Min(value1.X + value1.Width, value2.X + value2.Width);
var x = Math.Max(value1.X, value2.X);
var y = Math.Max(value1.Y, value2.Y);
var num2 = Math.Min(value1.Y + value1.Height, value2.Y + value2.Height);
return new RectangleF(x, y, num1 - x, num2 - y);
} else {
return Empty;
}
}
public void Offset(float offsetX, float offsetY) {
this.X += offsetX;
this.Y += offsetY;
}
public void Offset(Vector2 amount) {
this.X += amount.X;
this.Y += amount.Y;
}
public override string ToString() {
return "{X:" + this.X + " Y:" + this.Y + " Width:" + this.Width + " Height:" + this.Height + "}";
}
public static RectangleF Union(RectangleF value1, RectangleF value2) {
var x = Math.Min(value1.X, value2.X);
var y = Math.Min(value1.Y, value2.Y);
return new RectangleF(x, y, Math.Max(value1.Right, value2.Right) - x, Math.Max(value1.Bottom, value2.Bottom) - y);
}
public void Deconstruct(out float x, out float y, out float width, out float height) {
x = this.X;
y = this.Y;
width = this.Width;
height = this.Height;
}
}
}

View file

@ -3,6 +3,7 @@ using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Misc;
namespace MLEM.Textures {
public class NinePatch {
@ -35,6 +36,10 @@ namespace MLEM.Textures {
}
public IEnumerable<Rectangle> CreateRectangles(Rectangle area, float patchScale = 1) {
return this.CreateRectangles((RectangleF) area, patchScale).Select(r => (Rectangle) r);
}
public IEnumerable<RectangleF> CreateRectangles(RectangleF area, float patchScale = 1) {
var pl = (int) (this.PaddingLeft * patchScale);
var pr = (int) (this.PaddingRight * patchScale);
var pt = (int) (this.PaddingTop * patchScale);
@ -47,22 +52,22 @@ namespace MLEM.Textures {
var topY = area.Y + pt;
var bottomY = area.Y + area.Height - pb;
yield return new Rectangle(area.X, area.Y, pl, pt);
yield return new Rectangle(leftX, area.Y, centerW, pt);
yield return new Rectangle(rightX, area.Y, pr, pt);
yield return new Rectangle(area.X, topY, pl, centerH);
yield return new Rectangle(leftX, topY, centerW, centerH);
yield return new Rectangle(rightX, topY, pr, centerH);
yield return new Rectangle(area.X, bottomY, pl, pb);
yield return new Rectangle(leftX, bottomY, centerW, pb);
yield return new Rectangle(rightX, bottomY, pr, pb);
yield return new RectangleF(area.X, area.Y, pl, pt);
yield return new RectangleF(leftX, area.Y, centerW, pt);
yield return new RectangleF(rightX, area.Y, pr, pt);
yield return new RectangleF(area.X, topY, pl, centerH);
yield return new RectangleF(leftX, topY, centerW, centerH);
yield return new RectangleF(rightX, topY, pr, centerH);
yield return new RectangleF(area.X, bottomY, pl, pb);
yield return new RectangleF(leftX, bottomY, centerW, pb);
yield return new RectangleF(rightX, bottomY, pr, pb);
}
}
public static class NinePatchExtensions {
public static void Draw(this SpriteBatch batch, NinePatch texture, Rectangle destinationRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth, float patchScale = 1) {
public static void Draw(this SpriteBatch batch, NinePatch texture, RectangleF destinationRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth, float patchScale = 1) {
var dest = texture.CreateRectangles(destinationRectangle, patchScale);
var count = 0;
foreach (var rect in dest) {
@ -72,6 +77,14 @@ namespace MLEM.Textures {
}
}
public static void Draw(this SpriteBatch batch, NinePatch texture, Rectangle destinationRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth, float patchScale = 1) {
batch.Draw(texture, (RectangleF) destinationRectangle, color, rotation, origin, effects, layerDepth, patchScale);
}
public static void Draw(this SpriteBatch batch, NinePatch texture, RectangleF destinationRectangle, Color color, float patchScale = 1) {
batch.Draw(texture, destinationRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0, patchScale);
}
public static void Draw(this SpriteBatch batch, NinePatch texture, Rectangle destinationRectangle, Color color, float patchScale = 1) {
batch.Draw(texture, destinationRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0, patchScale);
}

View file

@ -1,6 +1,8 @@
using System.Diagnostics.Tracing;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Misc;
namespace MLEM.Textures {
public class TextureRegion {
@ -44,6 +46,10 @@ namespace MLEM.Textures {
batch.Draw(texture.Texture, destinationRectangle, texture.Area, color, rotation, origin, effects, layerDepth);
}
public static void Draw(this SpriteBatch batch, TextureRegion texture, RectangleF destinationRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) {
batch.Draw(texture.Texture, destinationRectangle, texture.Area, color, rotation, origin, effects, layerDepth);
}
public static void Draw(this SpriteBatch batch, TextureRegion texture, Vector2 position, Color color) {
batch.Draw(texture, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
}
@ -52,5 +58,9 @@ namespace MLEM.Textures {
batch.Draw(texture, destinationRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
}
public static void Draw(this SpriteBatch batch, TextureRegion texture, RectangleF destinationRectangle, Color color) {
batch.Draw(texture, destinationRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
}
}
}

View file

@ -54,7 +54,7 @@ namespace Sandbox {
var show = screen.IsHidden;
screen.IsHidden = false;
var time = 0;
const float total = 200;
const float total = 20;
while (time <= total) {
yield return new WaitEvent(CoroutineEvents.Update);
var percent = show ? time / total : 1 - time / total;