From c28f6d858c624220d17b4c741409c51788626feb Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sun, 9 Jan 2022 01:12:16 +0100 Subject: [PATCH] Ensure that a panel gets notified of all relevant changes by calling OnChildAreaDirty for all grandchildren --- CHANGELOG.md | 1 + MLEM.Ui/Elements/Element.cs | 16 ++++++++++------ MLEM.Ui/Elements/Panel.cs | 9 +++++++++ MLEM.Ui/Elements/Paragraph.cs | 4 ++-- MLEM.Ui/Elements/SquishingGroup.cs | 7 ++++--- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 013af60..3a9031d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Fixes Improvements - Allow for checkboxes and radio buttons to be disabled - Only set a paragraph's area dirty when a text change would cause it to change size +- Ensure that a panel gets notified of all relevant changes by calling OnChildAreaDirty for all grandchildren Fixes - Fixed paragraph links having incorrect hover locations when using special text alignments diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index f386e39..ab0bd07 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -530,7 +530,7 @@ namespace MLEM.Ui.Elements { /// public void SetAreaDirty() { this.AreaDirty = true; - this.Parent?.OnChildAreaDirty(this); + this.Parent?.OnChildAreaDirty(this, false); } /// @@ -1061,13 +1061,17 @@ namespace MLEM.Ui.Elements { } /// - /// A method that gets called by this element's when their methods get called. + /// A method that gets called by this element's or any of its grandchildren when their methods get called. /// Note that the element's area might already be dirty, which will not stop this method from being called. /// - /// The child whose area is being set dirty - protected virtual void OnChildAreaDirty(Element child) { - if (child.Anchor >= Anchor.AutoLeft || this.SetWidthBasedOnChildren || this.SetHeightBasedOnChildren) - this.SetAreaDirty(); + /// The child whose area is being set dirty. + /// Whether the is a grandchild of this element, rather than a direct child. + protected virtual void OnChildAreaDirty(Element child, bool grandchild) { + if (!grandchild) { + if (child.Anchor >= Anchor.AutoLeft || this.SetWidthBasedOnChildren || this.SetHeightBasedOnChildren) + this.SetAreaDirty(); + } + this.Parent?.OnChildAreaDirty(child, true); } /// diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index b84e9cf..39bf5a3 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -157,6 +157,15 @@ namespace MLEM.Ui.Elements { return relevant; } + /// + protected override void OnChildAreaDirty(Element child, bool grandchild) { + base.OnChildAreaDirty(child, grandchild); + // we only need to scroll when a grandchild changes, since all of our children are forced + // to be auto-anchored and so will automatically propagate their changes up to us + if (grandchild) + this.ScrollChildren(); + } + /// public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { if (this.Texture.HasValue()) diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index 5c208bf..0784e2b 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -191,8 +191,8 @@ namespace MLEM.Ui.Elements { /// protected void SetTextDirty() { this.TokenizedText = null; - // only set our area dirty if our size changed as a result of this action or if we have link children we need to update - if (!this.AreaDirty && (!this.CalcActualSize(this.ParentArea).Equals(this.DisplayArea.Size, Epsilon) || this.Children.Count > 0)) + // only set our area dirty if our size changed as a result of this action + if (!this.AreaDirty && !this.CalcActualSize(this.ParentArea).Equals(this.DisplayArea.Size, Epsilon)) this.SetAreaDirty(); } diff --git a/MLEM.Ui/Elements/SquishingGroup.cs b/MLEM.Ui/Elements/SquishingGroup.cs index 46870a3..956b09d 100644 --- a/MLEM.Ui/Elements/SquishingGroup.cs +++ b/MLEM.Ui/Elements/SquishingGroup.cs @@ -30,9 +30,10 @@ namespace MLEM.Ui.Elements { } /// - protected override void OnChildAreaDirty(Element child) { - base.OnChildAreaDirty(child); - this.SetAreaDirty(); + protected override void OnChildAreaDirty(Element child, bool grandchild) { + base.OnChildAreaDirty(child, grandchild); + if (!grandchild) + this.SetAreaDirty(); } private static bool SquishChild(Element element, out RectangleF squishedArea) {