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();