diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bf0183..4826f55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Improvements Fixes - Fixed panels updating their relevant children too much when the scroll bar is hidden +- Fixed a stack overflow exception when a panel's scroll bar auto-hiding causes elements to gain height ### MLEM.Data Fixes diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index dfb4398..d5006ea 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -56,6 +56,7 @@ namespace MLEM.Ui.Elements { private readonly List relevantChildren = new List(); private readonly HashSet scrolledChildren = new HashSet(); + private readonly float[] scrollBarMaxHistory = new float[3]; private readonly bool scrollOverflow; private RenderTarget2D renderTarget; @@ -110,7 +111,10 @@ namespace MLEM.Ui.Elements { throw new NotSupportedException($"A panel that handles overflow can't contain non-automatic anchors ({child})"); } } + base.ForceUpdateArea(); + Array.Clear(this.scrollBarMaxHistory, 0, this.scrollBarMaxHistory.Length); + this.SetScrollBarStyle(); } @@ -273,8 +277,15 @@ namespace MLEM.Ui.Elements { // the max value of the scroll bar is the amount of non-scaled pixels taken up by overflowing components var scrollBarMax = Math.Max(0, (childrenHeight - this.ChildPaddedArea.Height) / this.Scale); if (!this.ScrollBar.MaxValue.Equals(scrollBarMax, Element.Epsilon)) { - this.ScrollBar.MaxValue = scrollBarMax; - this.relevantChildrenDirty = true; + // avoid a show/hide oscillation that occurs while updating our area with children that can lose height when the scroll bar is shown (like long paragraphs) + if (!this.scrollBarMaxHistory[0].Equals(this.scrollBarMaxHistory[2], Element.Epsilon) || !this.scrollBarMaxHistory[1].Equals(scrollBarMax, Element.Epsilon)) { + this.scrollBarMaxHistory[0] = this.scrollBarMaxHistory[1]; + this.scrollBarMaxHistory[1] = this.scrollBarMaxHistory[2]; + this.scrollBarMaxHistory[2] = scrollBarMax; + + this.ScrollBar.MaxValue = scrollBarMax; + this.relevantChildrenDirty = true; + } } // update child padding based on whether the scroll bar is visible