mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-24 01:09:23 +01:00
added a rectanglef class which allows mlem to use decimal coordinates
This commit is contained in:
parent
cb7abbbbef
commit
32c8147a4c
19 changed files with 310 additions and 79 deletions
15
MLEM.Extended/Extensions/NumberExtensions.cs
Normal file
15
MLEM.Extended/Extensions/NumberExtensions.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
142
MLEM/Misc/RectangleF.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue