diff --git a/CHANGELOG.md b/CHANGELOG.md index 33ed32d..b7df406 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Improvements ### MLEM.Ui Additions - Added some extension methods for querying Anchor types +- Added Element.AutoSizeAddedAbsolute to allow for more granular control of auto-sizing Improvements - Allow elements to auto-adjust their size even when their children are aligned oddly diff --git a/FNA b/FNA index 102990f..31ff5cd 160000 --- a/FNA +++ b/FNA @@ -1 +1 @@ -Subproject commit 102990f514f1e5bfac07d33f7c33e2e712946da4 +Subproject commit 31ff5cd8b6d62b0c10b627c67cc66db1d4def4e7 diff --git a/FontStashSharp b/FontStashSharp index f077413..7373710 160000 --- a/FontStashSharp +++ b/FontStashSharp @@ -1 +1 @@ -Subproject commit f0774130cad6cec0b790a58bc7c811a186443fb3 +Subproject commit 7373710db2260a5a0214c8102015b1e11425fa25 diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index b242c56..d51e2fb 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -71,9 +71,10 @@ namespace MLEM.Ui.Elements { /// The size of this element, where X represents the width and Y represents the height. /// If the x or y value of the size is between 0 and 1, the size will be seen as a percentage of its parent's size rather than as an absolute value. /// If the x (or y) value of the size is negative, the width (or height) is seen as a percentage of the element's resulting height (or width). + /// Additionally, if auto-sizing is used, can be set to add or subtract an absolute value from the automatically calculated size. /// /// - /// The following example combines both types of percentage-based sizing. + /// The following example, ignoring , combines both types of percentage-based sizing. /// If this element is inside of a whose width is 20, this element's width will be set to 0.5 * 20 = 10, and its height will be set to 2.5 * 10 = 25. /// /// element.Size = new Vector2(0.5F, -2.5F); @@ -93,6 +94,26 @@ namespace MLEM.Ui.Elements { /// public Vector2 ScaledSize => this.size * this.Scale; /// + /// If auto-sizing is used by setting less than or equal to 1, this property allows adding or subtracting an additional, absolute value from the automatically calculated size. + /// If this element is not using auto-sizing, this property is ignored. + /// + /// + /// Ignoring , if this element's is set to 0.5, 0.75 and its has a size of 200, 100, then an added absolute size of -50, 25 will result in a final size of 0.5 * 200 - 50, 0.75 * 100 + 25, or 50, 100. + /// + public Vector2 AutoSizeAddedAbsolute { + get => this.autoSizeAddedAbsolute; + set { + if (this.autoSizeAddedAbsolute == value) + return; + this.autoSizeAddedAbsolute = value; + this.SetAreaDirty(); + } + } + /// + /// The , but with applied. + /// + public Vector2 ScaledAutoSizeAddedAbsolute => this.autoSizeAddedAbsolute * this.Scale; + /// /// This element's offset from its default position, which is dictated by its . /// Note that, depending on the side that the element is anchored to, this offset moves it in a different direction. /// @@ -430,6 +451,7 @@ namespace MLEM.Ui.Elements { private UiSystem system; private Anchor anchor; private Vector2 size; + private Vector2 autoSizeAddedAbsolute; private Vector2 offset; private RectangleF area; private bool isHidden; @@ -751,12 +773,12 @@ namespace MLEM.Ui.Elements { /// The actual size of this element, taking into account protected virtual Vector2 CalcActualSize(RectangleF parentArea) { var ret = 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); + this.size.X > 1 ? this.ScaledSize.X : parentArea.Width * this.size.X + this.ScaledAutoSizeAddedAbsolute.X, + this.size.Y > 1 ? this.ScaledSize.Y : parentArea.Height * this.size.Y + this.ScaledAutoSizeAddedAbsolute.Y); if (this.size.X < 0) - ret.X = -this.size.X * ret.Y; + ret.X = -this.size.X * ret.Y + this.ScaledAutoSizeAddedAbsolute.X; if (this.size.Y < 0) - ret.Y = -this.size.Y * ret.X; + ret.Y = -this.size.Y * ret.X + this.ScaledAutoSizeAddedAbsolute.Y; return ret; } diff --git a/Tests/UiTests.cs b/Tests/UiTests.cs index f289c51..1c1458e 100644 --- a/Tests/UiTests.cs +++ b/Tests/UiTests.cs @@ -77,6 +77,27 @@ namespace Tests { Assert.AreEqual(testBtn.GetChildren().Single().DisplayArea.Width, (panelContentWidth - 3 - 3) * 0.5F); } + [Test] + public void TestAbsoluteAutoSize() { + var parent = new Panel(Anchor.AutoLeft, new Vector2(200, 100), Vector2.Zero) { + ChildPadding = Padding.Empty + }; + var el1 = parent.AddChild(new Button(Anchor.AutoLeft, new Vector2(0.5F, 0.75F)) { + AutoSizeAddedAbsolute = new Vector2(-50, 25) + }); + var el2 = parent.AddChild(new Button(Anchor.AutoLeft, new Vector2(0.25F, -0.5F)) { + AutoSizeAddedAbsolute = new Vector2(-25, 50) + }); + this.AddAndUpdate(parent); + + Assert.AreEqual(0.5F * 200 - 50, el1.DisplayArea.Width); + Assert.AreEqual(0.75F * 100 + 25, el1.DisplayArea.Height); + + const float el2Width = 0.25F * 200 - 25; + Assert.AreEqual(el2Width, el2.DisplayArea.Width); + Assert.AreEqual(0.5F * el2Width + 50, el2.DisplayArea.Height); + } + [Test] public void TestStyle() { var style = new StyleProp();