mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 20:58:34 +01:00
made padding a lot more versatile in mlem.ui
This commit is contained in:
parent
b8e73717f4
commit
dbe7980add
9 changed files with 103 additions and 32 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
using MLEM.Extensions;
|
||||||
using MLEM.Textures;
|
using MLEM.Textures;
|
||||||
using MonoGame.Extended.TextureAtlases;
|
using MonoGame.Extended.TextureAtlases;
|
||||||
|
|
||||||
|
@ -5,7 +6,7 @@ namespace MLEM.Extended.Extensions {
|
||||||
public static class TextureExtensions {
|
public static class TextureExtensions {
|
||||||
|
|
||||||
public static NinePatchRegion2D ToExtended(this NinePatch patch) {
|
public static NinePatchRegion2D ToExtended(this NinePatch patch) {
|
||||||
return new NinePatchRegion2D(patch.Region.ToExtended(), patch.PaddingLeft, patch.PaddingTop, patch.PaddingRight, patch.PaddingBottom);
|
return new NinePatchRegion2D(patch.Region.ToExtended(), patch.Padding.Left.Floor(), patch.Padding.Top.Floor(), patch.Padding.Right.Floor(), patch.Padding.Bottom.Floor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextureRegion2D ToExtended(this TextureRegion region) {
|
public static TextureRegion2D ToExtended(this TextureRegion region) {
|
||||||
|
|
|
@ -25,9 +25,8 @@ namespace MLEM.Ui.Elements {
|
||||||
private Anchor anchor;
|
private Anchor anchor;
|
||||||
private Vector2 size;
|
private Vector2 size;
|
||||||
private Vector2 offset;
|
private Vector2 offset;
|
||||||
public Vector2 Padding;
|
public Padding Padding;
|
||||||
public Vector2 ScaledPadding => this.Padding * this.Scale;
|
public Padding ScaledPadding => this.Padding * this.Scale;
|
||||||
private Vector2 childPadding;
|
|
||||||
public Anchor Anchor {
|
public Anchor Anchor {
|
||||||
get => this.anchor;
|
get => this.anchor;
|
||||||
set {
|
set {
|
||||||
|
@ -56,8 +55,9 @@ namespace MLEM.Ui.Elements {
|
||||||
this.SetAreaDirty();
|
this.SetAreaDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Vector2 ScaledOffset => (this.offset * this.Scale);
|
public Vector2 ScaledOffset => this.offset * this.Scale;
|
||||||
public Vector2 ChildPadding {
|
private Padding childPadding;
|
||||||
|
public Padding ChildPadding {
|
||||||
get => this.childPadding;
|
get => this.childPadding;
|
||||||
set {
|
set {
|
||||||
if (this.childPadding == value)
|
if (this.childPadding == value)
|
||||||
|
@ -67,7 +67,7 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public RectangleF ChildPaddedArea => this.UnscrolledArea.Shrink(this.ScaledChildPadding);
|
public RectangleF ChildPaddedArea => this.UnscrolledArea.Shrink(this.ScaledChildPadding);
|
||||||
public Vector2 ScaledChildPadding => this.childPadding * this.Scale;
|
public Padding ScaledChildPadding => this.childPadding * this.Scale;
|
||||||
|
|
||||||
public DrawCallback OnDrawn;
|
public DrawCallback OnDrawn;
|
||||||
public TimeCallback OnUpdated;
|
public TimeCallback OnUpdated;
|
||||||
|
@ -319,7 +319,7 @@ namespace MLEM.Ui.Elements {
|
||||||
if (this.SetHeightBasedOnChildren) {
|
if (this.SetHeightBasedOnChildren) {
|
||||||
var lowest = this.GetLowestChild(e => !e.IsHidden);
|
var lowest = this.GetLowestChild(e => !e.IsHidden);
|
||||||
if (lowest != null) {
|
if (lowest != null) {
|
||||||
var newHeight = (lowest.UnscrolledArea.Bottom - pos.Y + this.ScaledChildPadding.Y) / this.Scale;
|
var newHeight = (lowest.UnscrolledArea.Bottom - pos.Y + this.ScaledChildPadding.Bottom) / this.Scale;
|
||||||
if ((int) newHeight != (int) this.size.Y) {
|
if ((int) newHeight != (int) this.size.Y) {
|
||||||
this.size.Y = newHeight;
|
this.size.Y = newHeight;
|
||||||
this.ForceUpdateArea();
|
this.ForceUpdateArea();
|
||||||
|
@ -328,7 +328,7 @@ namespace MLEM.Ui.Elements {
|
||||||
} else if (this.SetWidthBasedOnChildren) {
|
} else if (this.SetWidthBasedOnChildren) {
|
||||||
var rightmost = this.GetRightmostChild(e => !e.IsHidden);
|
var rightmost = this.GetRightmostChild(e => !e.IsHidden);
|
||||||
if (rightmost != null) {
|
if (rightmost != null) {
|
||||||
var newWidth = (rightmost.UnscrolledArea.Right - pos.X + this.ScaledChildPadding.X) / this.Scale;
|
var newWidth = (rightmost.UnscrolledArea.Right - pos.X + this.ScaledChildPadding.Right) / this.Scale;
|
||||||
if ((int) newWidth != (int) this.size.X) {
|
if ((int) newWidth != (int) this.size.X) {
|
||||||
this.size.X = newWidth;
|
this.size.X = newWidth;
|
||||||
this.ForceUpdateArea();
|
this.ForceUpdateArea();
|
||||||
|
|
|
@ -32,13 +32,13 @@ namespace MLEM.Ui.Elements {
|
||||||
StepPerScroll = 10,
|
StepPerScroll = 10,
|
||||||
OnValueChanged = (element, value) => this.ScrollChildren(),
|
OnValueChanged = (element, value) => this.ScrollChildren(),
|
||||||
CanAutoAnchorsAttach = false,
|
CanAutoAnchorsAttach = false,
|
||||||
AutoHideWhenEmpty = true
|
AutoHideWhenEmpty = true,
|
||||||
|
IsHidden = true
|
||||||
};
|
};
|
||||||
this.AddChild(this.ScrollBar);
|
|
||||||
|
|
||||||
// modify the padding so that the scroll bar isn't over top of something else
|
// modify the padding so that the scroll bar isn't over top of something else
|
||||||
this.ScrollBar.PositionOffset -= new Vector2(scrollSize.X + 1, 0);
|
this.ScrollBar.PositionOffset -= new Vector2(scrollSize.X + 1, 0);
|
||||||
this.ChildPadding += new Vector2(scrollSize.X, 0);
|
this.ScrollBar.OnAutoHide += e => this.ChildPadding += new Padding(0, scrollSize.X, 0, 0) * (e.IsHidden ? -1 : 1);
|
||||||
|
|
||||||
// handle automatic element selection, the scroller needs to scroll to the right location
|
// handle automatic element selection, the scroller needs to scroll to the right location
|
||||||
this.OnSelectedElementChanged += (element, otherElement) => {
|
this.OnSelectedElementChanged += (element, otherElement) => {
|
||||||
|
@ -48,6 +48,7 @@ namespace MLEM.Ui.Elements {
|
||||||
return;
|
return;
|
||||||
this.ScrollBar.CurrentValue = (otherElement.Area.Bottom - this.Children[1].Area.Top - this.Area.Height / 2) / this.Scale;
|
this.ScrollBar.CurrentValue = (otherElement.Area.Bottom - this.Children[1].Area.Top - this.Area.Height / 2) / this.Scale;
|
||||||
};
|
};
|
||||||
|
this.AddChild(this.ScrollBar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ namespace MLEM.Ui.Elements {
|
||||||
var lowestChild = this.GetLowestChild(e => !e.IsHidden);
|
var lowestChild = this.GetLowestChild(e => !e.IsHidden);
|
||||||
// the max value of the scrollbar is the amount of non-scaled pixels taken up by overflowing components
|
// the max value of the scrollbar is the amount of non-scaled pixels taken up by overflowing components
|
||||||
var childrenHeight = lowestChild.Area.Bottom - firstChild.Area.Top;
|
var childrenHeight = lowestChild.Area.Bottom - firstChild.Area.Top;
|
||||||
this.ScrollBar.MaxValue = (childrenHeight - this.Area.Height) / this.Scale + this.ChildPadding.Y * 2;
|
this.ScrollBar.MaxValue = (childrenHeight - this.Area.Height) / this.Scale + this.ChildPadding.Height;
|
||||||
|
|
||||||
// update the render target
|
// update the render target
|
||||||
var targetArea = (Rectangle) this.GetRenderTargetArea();
|
var targetArea = (Rectangle) this.GetRenderTargetArea();
|
||||||
|
|
|
@ -60,11 +60,11 @@ namespace MLEM.Ui.Elements {
|
||||||
var size = base.CalcActualSize(parentArea);
|
var size = base.CalcActualSize(parentArea);
|
||||||
|
|
||||||
var sc = this.TextScale * this.Scale;
|
var sc = this.TextScale * this.Scale;
|
||||||
this.splitText = this.RegularFont.Value.SplitString(this.text.RemoveFormatting(), size.X - this.ScaledPadding.X * 2, sc);
|
this.splitText = this.RegularFont.Value.SplitString(this.text.RemoveFormatting(), size.X - this.ScaledPadding.Width, sc);
|
||||||
this.codeLocations = this.text.GetFormattingCodes();
|
this.codeLocations = this.text.GetFormattingCodes();
|
||||||
|
|
||||||
var textDims = this.RegularFont.Value.MeasureString(this.splitText) * sc;
|
var textDims = this.RegularFont.Value.MeasureString(this.splitText) * sc;
|
||||||
return new Vector2(this.AutoAdjustWidth ? textDims.X + this.ScaledPadding.X * 2 : size.X, textDims.Y + this.ScaledPadding.Y * 2);
|
return new Vector2(this.AutoAdjustWidth ? textDims.X + this.ScaledPadding.Width : size.X, textDims.Y + this.ScaledPadding.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(GameTime time) {
|
public override void Update(GameTime time) {
|
||||||
|
|
|
@ -37,8 +37,8 @@ namespace MLEM.Ui.Elements {
|
||||||
|
|
||||||
var percentage = this.CurrentValue / this.MaxValue;
|
var percentage = this.CurrentValue / this.MaxValue;
|
||||||
var tex = this.ProgressTexture.Value;
|
var tex = this.ProgressTexture.Value;
|
||||||
var padHor = tex != null ? (tex.PaddingLeft + tex.PaddingRight) * this.Scale : 0;
|
var padHor = tex != null ? tex.Padding.Width * this.Scale : 0;
|
||||||
var padVer = tex != null ? (tex.PaddingTop + tex.PaddingBottom) * this.Scale : 0;
|
var padVer = tex != null ? tex.Padding.Height * this.Scale : 0;
|
||||||
var width = percentage * (this.DisplayArea.Width - padHor) + padHor;
|
var width = percentage * (this.DisplayArea.Width - padHor) + padHor;
|
||||||
var height = percentage * (this.DisplayArea.Height - padVer) + padVer;
|
var height = percentage * (this.DisplayArea.Height - padVer) + padVer;
|
||||||
RectangleF progressArea;
|
RectangleF progressArea;
|
||||||
|
|
|
@ -23,8 +23,10 @@ namespace MLEM.Ui.Elements {
|
||||||
this.maxValue = Math.Max(0, value);
|
this.maxValue = Math.Max(0, value);
|
||||||
// force current value to be clamped
|
// force current value to be clamped
|
||||||
this.CurrentValue = this.currValue;
|
this.CurrentValue = this.currValue;
|
||||||
if (this.AutoHideWhenEmpty)
|
if (this.AutoHideWhenEmpty && this.IsHidden != this.maxValue <= 0) {
|
||||||
this.IsHidden = this.maxValue <= 0;
|
this.IsHidden = this.maxValue <= 0;
|
||||||
|
this.OnAutoHide?.Invoke(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private float currValue;
|
private float currValue;
|
||||||
|
@ -41,6 +43,7 @@ namespace MLEM.Ui.Elements {
|
||||||
public readonly bool Horizontal;
|
public readonly bool Horizontal;
|
||||||
public float StepPerScroll = 1;
|
public float StepPerScroll = 1;
|
||||||
public ValueChanged OnValueChanged;
|
public ValueChanged OnValueChanged;
|
||||||
|
public GenericCallback OnAutoHide;
|
||||||
private bool isMouseHeld;
|
private bool isMouseHeld;
|
||||||
private bool isDragging;
|
private bool isDragging;
|
||||||
private bool isTouchHeld;
|
private bool isTouchHeld;
|
||||||
|
|
|
@ -67,5 +67,13 @@ namespace MLEM.Extensions {
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RectangleF Shrink(this RectangleF rect, Padding padding) {
|
||||||
|
rect.X += padding.Left;
|
||||||
|
rect.Y += padding.Left;
|
||||||
|
rect.Width -= padding.Width;
|
||||||
|
rect.Height -= padding.Height;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
61
MLEM/Misc/Padding.cs
Normal file
61
MLEM/Misc/Padding.cs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace MLEM.Misc {
|
||||||
|
public struct Padding {
|
||||||
|
|
||||||
|
public float Left;
|
||||||
|
public float Right;
|
||||||
|
public float Top;
|
||||||
|
public float Bottom;
|
||||||
|
public float Width => this.Left + this.Right;
|
||||||
|
public float Height => this.Top + this.Bottom;
|
||||||
|
|
||||||
|
public Padding(float left, float right, float top, float bottom) {
|
||||||
|
this.Left = left;
|
||||||
|
this.Right = right;
|
||||||
|
this.Top = top;
|
||||||
|
this.Bottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Padding(Vector2 vec) {
|
||||||
|
return new Padding(vec.X, vec.X, vec.Y, vec.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Padding operator *(Padding p, float scale) {
|
||||||
|
return new Padding(p.Left * scale, p.Right * scale, p.Top * scale, p.Bottom * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Padding operator +(Padding left, Padding right) {
|
||||||
|
return new Padding(left.Left + right.Left, left.Right + right.Right, left.Top + right.Top, left.Bottom + right.Bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Padding operator -(Padding left, Padding right) {
|
||||||
|
return new Padding(left.Left - right.Left, left.Right - right.Right, left.Top - right.Top, left.Bottom - right.Bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(Padding left, Padding right) {
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Padding left, Padding right) {
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(Padding other) {
|
||||||
|
return this.Left.Equals(other.Left) && this.Right.Equals(other.Right) && this.Top.Equals(other.Top) && this.Bottom.Equals(other.Bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj) {
|
||||||
|
return obj is Padding other && this.Equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
var hashCode = this.Left.GetHashCode();
|
||||||
|
hashCode = (hashCode * 397) ^ this.Right.GetHashCode();
|
||||||
|
hashCode = (hashCode * 397) ^ this.Top.GetHashCode();
|
||||||
|
hashCode = (hashCode * 397) ^ this.Bottom.GetHashCode();
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,22 +9,19 @@ namespace MLEM.Textures {
|
||||||
public class NinePatch {
|
public class NinePatch {
|
||||||
|
|
||||||
public readonly TextureRegion Region;
|
public readonly TextureRegion Region;
|
||||||
public readonly int PaddingLeft;
|
public readonly Padding Padding;
|
||||||
public readonly int PaddingRight;
|
|
||||||
public readonly int PaddingTop;
|
|
||||||
public readonly int PaddingBottom;
|
|
||||||
|
|
||||||
public readonly Rectangle[] SourceRectangles;
|
public readonly Rectangle[] SourceRectangles;
|
||||||
|
|
||||||
public NinePatch(TextureRegion texture, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) {
|
public NinePatch(TextureRegion texture, Padding padding) {
|
||||||
this.Region = texture;
|
this.Region = texture;
|
||||||
this.PaddingLeft = paddingLeft;
|
this.Padding = padding;
|
||||||
this.PaddingRight = paddingRight;
|
|
||||||
this.PaddingTop = paddingTop;
|
|
||||||
this.PaddingBottom = paddingBottom;
|
|
||||||
this.SourceRectangles = this.CreateRectangles(this.Region.Area).ToArray();
|
this.SourceRectangles = this.CreateRectangles(this.Region.Area).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NinePatch(TextureRegion texture, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) :
|
||||||
|
this(texture, new Padding(paddingLeft, paddingRight, paddingTop, paddingBottom)) {
|
||||||
|
}
|
||||||
|
|
||||||
public NinePatch(Texture2D texture, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) :
|
public NinePatch(Texture2D texture, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) :
|
||||||
this(new TextureRegion(texture), paddingLeft, paddingRight, paddingTop, paddingBottom) {
|
this(new TextureRegion(texture), paddingLeft, paddingRight, paddingTop, paddingBottom) {
|
||||||
}
|
}
|
||||||
|
@ -40,10 +37,10 @@ namespace MLEM.Textures {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<RectangleF> CreateRectangles(RectangleF area, float patchScale = 1) {
|
public IEnumerable<RectangleF> CreateRectangles(RectangleF area, float patchScale = 1) {
|
||||||
var pl = (int) (this.PaddingLeft * patchScale);
|
var pl = (int) (this.Padding.Left * patchScale);
|
||||||
var pr = (int) (this.PaddingRight * patchScale);
|
var pr = (int) (this.Padding.Right * patchScale);
|
||||||
var pt = (int) (this.PaddingTop * patchScale);
|
var pt = (int) (this.Padding.Top * patchScale);
|
||||||
var pb = (int) (this.PaddingBottom * patchScale);
|
var pb = (int) (this.Padding.Bottom * patchScale);
|
||||||
|
|
||||||
var centerW = area.Width - pl - pr;
|
var centerW = area.Width - pl - pr;
|
||||||
var centerH = area.Height - pt - pb;
|
var centerH = area.Height - pt - pb;
|
||||||
|
|
Loading…
Reference in a new issue