From 6766d769f4a07c87064a96419587d9a72e36a89b Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sat, 24 Aug 2019 22:27:47 +0200 Subject: [PATCH] made scrolling a lot less intensive --- MLEM.Ui/Elements/Element.cs | 15 +++++++++------ MLEM.Ui/Elements/Panel.cs | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index c8d55f9..f0e811a 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -66,7 +66,7 @@ namespace MLEM.Ui.Elements { } public Rectangle ChildPaddedArea { get { - var padded = this.Area; + var padded = this.UnscrolledArea; padded.Location += this.ScaledChildPadding; padded.Width -= this.ScaledChildPadding.X * 2; padded.Height -= this.ScaledChildPadding.Y * 2; @@ -120,12 +120,15 @@ namespace MLEM.Ui.Elements { public bool CanAutoAnchorsAttach = true; private Rectangle area; - public Rectangle Area { + public Rectangle UnscrolledArea { get { this.UpdateAreaIfDirty(); return this.area; } } + public Rectangle Area => this.UnscrolledArea.OffsetCopy(this.ScaledScrollOffset); + public Point ScrollOffset; + public Point ScaledScrollOffset => this.ScrollOffset.Multiply(this.Scale); public Rectangle DisplayArea { get { var padded = this.Area; @@ -302,7 +305,7 @@ namespace MLEM.Ui.Elements { if (this.SetHeightBasedOnChildren && this.Children.Count > 0) { var lowest = this.GetLowestChild(false, true); - var newHeight = (lowest.area.Bottom - pos.Y + this.ScaledChildPadding.Y) / this.Scale; + var newHeight = (lowest.UnscrolledArea.Bottom - pos.Y + this.ScaledChildPadding.Y) / this.Scale; if (newHeight != this.size.Y) { this.size.Y = newHeight; if (this.Anchor > Anchor.TopRight) @@ -318,7 +321,7 @@ namespace MLEM.Ui.Elements { } protected virtual Rectangle GetAreaForAutoAnchors() { - return this.Area; + return this.UnscrolledArea; } public Element GetLowestChild(bool hiddenAlso, bool unattachableAlso) { @@ -330,7 +333,7 @@ namespace MLEM.Ui.Elements { continue; if (child.Anchor > Anchor.TopRight && child.Anchor < Anchor.AutoLeft) continue; - if (lowest == null || child.Area.Bottom > lowest.Area.Bottom) + if (lowest == null || child.UnscrolledArea.Bottom > lowest.UnscrolledArea.Bottom) lowest = child; } return lowest; @@ -345,7 +348,7 @@ namespace MLEM.Ui.Elements { break; if (!hiddenAlso && child.IsHidden || !unattachableAlso && !child.CanAutoAnchorsAttach) continue; - if (lowest == null || child.Area.Bottom >= lowest.Area.Bottom) + if (lowest == null || child.UnscrolledArea.Bottom >= lowest.UnscrolledArea.Bottom) lowest = child; } return lowest; diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index bfde385..54327e3 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -24,16 +24,7 @@ namespace MLEM.Ui.Elements { var scrollSize = scrollerSize ?? Point.Zero; this.ScrollBar = new ScrollBar(Anchor.TopRight, new Vector2(scrollSize.X, 1), scrollSize.Y, 0) { StepPerScroll = 10, - OnValueChanged = (element, value) => { - // if there is only one child, then we have just the scroll bar - if (this.Children.Count == 1) - return; - // the "real" first child is the scroll bar, which we want to ignore - var firstChild = this.Children[1]; - // as all children have to be auto-aligned, moving the first one up will move all others - firstChild.PositionOffset = new Vector2(firstChild.PositionOffset.X, -value.Floor()); - this.ForceUpdateArea(); - }, + OnValueChanged = (element, value) => this.ForceChildrenScroll(), CanAutoAnchorsAttach = false }; this.AddChild(this.ScrollBar); @@ -58,6 +49,7 @@ namespace MLEM.Ui.Elements { } base.ForceUpdateArea(); + this.ForceChildrenScroll(); if (this.scrollOverflow) { // if there is only one child, then we have just the scroll bar @@ -80,6 +72,14 @@ namespace MLEM.Ui.Elements { } } + private void ForceChildrenScroll() { + if (!this.scrollOverflow) + return; + var offset = -this.ScrollBar.CurrentValue.Floor(); + foreach (var child in this.GetChildren(c => c != this.ScrollBar, true)) + child.ScrollOffset = new Point(0, offset); + } + public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) { batch.Draw(this.Texture, this.DisplayArea.OffsetCopy(offset), Color.White * alpha, this.Scale); // if we handle overflow, draw using the render target in DrawUnbound