mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-25 22:18: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 MonoGame.Extended.TextureAtlases;
|
||||
|
||||
|
@ -5,7 +6,7 @@ namespace MLEM.Extended.Extensions {
|
|||
public static class TextureExtensions {
|
||||
|
||||
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) {
|
||||
|
|
|
@ -25,9 +25,8 @@ namespace MLEM.Ui.Elements {
|
|||
private Anchor anchor;
|
||||
private Vector2 size;
|
||||
private Vector2 offset;
|
||||
public Vector2 Padding;
|
||||
public Vector2 ScaledPadding => this.Padding * this.Scale;
|
||||
private Vector2 childPadding;
|
||||
public Padding Padding;
|
||||
public Padding ScaledPadding => this.Padding * this.Scale;
|
||||
public Anchor Anchor {
|
||||
get => this.anchor;
|
||||
set {
|
||||
|
@ -56,8 +55,9 @@ namespace MLEM.Ui.Elements {
|
|||
this.SetAreaDirty();
|
||||
}
|
||||
}
|
||||
public Vector2 ScaledOffset => (this.offset * this.Scale);
|
||||
public Vector2 ChildPadding {
|
||||
public Vector2 ScaledOffset => this.offset * this.Scale;
|
||||
private Padding childPadding;
|
||||
public Padding ChildPadding {
|
||||
get => this.childPadding;
|
||||
set {
|
||||
if (this.childPadding == value)
|
||||
|
@ -67,7 +67,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
}
|
||||
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 TimeCallback OnUpdated;
|
||||
|
@ -319,7 +319,7 @@ namespace MLEM.Ui.Elements {
|
|||
if (this.SetHeightBasedOnChildren) {
|
||||
var lowest = this.GetLowestChild(e => !e.IsHidden);
|
||||
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) {
|
||||
this.size.Y = newHeight;
|
||||
this.ForceUpdateArea();
|
||||
|
@ -328,7 +328,7 @@ namespace MLEM.Ui.Elements {
|
|||
} else if (this.SetWidthBasedOnChildren) {
|
||||
var rightmost = this.GetRightmostChild(e => !e.IsHidden);
|
||||
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) {
|
||||
this.size.X = newWidth;
|
||||
this.ForceUpdateArea();
|
||||
|
|
|
@ -32,13 +32,13 @@ namespace MLEM.Ui.Elements {
|
|||
StepPerScroll = 10,
|
||||
OnValueChanged = (element, value) => this.ScrollChildren(),
|
||||
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
|
||||
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
|
||||
this.OnSelectedElementChanged += (element, otherElement) => {
|
||||
|
@ -48,6 +48,7 @@ namespace MLEM.Ui.Elements {
|
|||
return;
|
||||
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);
|
||||
// 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;
|
||||
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
|
||||
var targetArea = (Rectangle) this.GetRenderTargetArea();
|
||||
|
|
|
@ -60,11 +60,11 @@ namespace MLEM.Ui.Elements {
|
|||
var size = base.CalcActualSize(parentArea);
|
||||
|
||||
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();
|
||||
|
||||
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) {
|
||||
|
|
|
@ -37,8 +37,8 @@ namespace MLEM.Ui.Elements {
|
|||
|
||||
var percentage = this.CurrentValue / this.MaxValue;
|
||||
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 padHor = tex != null ? tex.Padding.Width * this.Scale : 0;
|
||||
var padVer = tex != null ? tex.Padding.Height * this.Scale : 0;
|
||||
var width = percentage * (this.DisplayArea.Width - padHor) + padHor;
|
||||
var height = percentage * (this.DisplayArea.Height - padVer) + padVer;
|
||||
RectangleF progressArea;
|
||||
|
|
|
@ -23,8 +23,10 @@ namespace MLEM.Ui.Elements {
|
|||
this.maxValue = Math.Max(0, value);
|
||||
// force current value to be clamped
|
||||
this.CurrentValue = this.currValue;
|
||||
if (this.AutoHideWhenEmpty)
|
||||
if (this.AutoHideWhenEmpty && this.IsHidden != this.maxValue <= 0) {
|
||||
this.IsHidden = this.maxValue <= 0;
|
||||
this.OnAutoHide?.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
private float currValue;
|
||||
|
@ -41,6 +43,7 @@ namespace MLEM.Ui.Elements {
|
|||
public readonly bool Horizontal;
|
||||
public float StepPerScroll = 1;
|
||||
public ValueChanged OnValueChanged;
|
||||
public GenericCallback OnAutoHide;
|
||||
private bool isMouseHeld;
|
||||
private bool isDragging;
|
||||
private bool isTouchHeld;
|
||||
|
|
|
@ -67,5 +67,13 @@ namespace MLEM.Extensions {
|
|||
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 readonly TextureRegion Region;
|
||||
public readonly int PaddingLeft;
|
||||
public readonly int PaddingRight;
|
||||
public readonly int PaddingTop;
|
||||
public readonly int PaddingBottom;
|
||||
|
||||
public readonly Padding Padding;
|
||||
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.PaddingLeft = paddingLeft;
|
||||
this.PaddingRight = paddingRight;
|
||||
this.PaddingTop = paddingTop;
|
||||
this.PaddingBottom = paddingBottom;
|
||||
this.Padding = padding;
|
||||
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) :
|
||||
this(new TextureRegion(texture), paddingLeft, paddingRight, paddingTop, paddingBottom) {
|
||||
}
|
||||
|
@ -40,10 +37,10 @@ namespace MLEM.Textures {
|
|||
}
|
||||
|
||||
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);
|
||||
var pb = (int) (this.PaddingBottom * patchScale);
|
||||
var pl = (int) (this.Padding.Left * patchScale);
|
||||
var pr = (int) (this.Padding.Right * patchScale);
|
||||
var pt = (int) (this.Padding.Top * patchScale);
|
||||
var pb = (int) (this.Padding.Bottom * patchScale);
|
||||
|
||||
var centerW = area.Width - pl - pr;
|
||||
var centerH = area.Height - pt - pb;
|
||||
|
|
Loading…
Reference in a new issue