mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-26 02:09:24 +01:00
Added Panel.ScrollToElement
This commit is contained in:
parent
d6a51776e5
commit
92f9164256
2 changed files with 64 additions and 46 deletions
|
@ -32,6 +32,7 @@ Additions
|
|||
- Added Element.AutoSizeAddedAbsolute to allow for more granular control of auto-sizing
|
||||
- Added Element.OnAddedToUi and Element.OnRemovedFromUi
|
||||
- Added ScrollBar.MouseDragScrolling
|
||||
- Added Panel.ScrollToElement
|
||||
|
||||
Improvements
|
||||
- Allow elements to auto-adjust their size even when their children are aligned oddly
|
||||
|
|
|
@ -84,9 +84,7 @@ namespace MLEM.Ui.Elements {
|
|||
return;
|
||||
if (e == null || !e.GetParentTree().Contains(this))
|
||||
return;
|
||||
var firstChild = this.Children.FirstOrDefault(c => c != this.ScrollBar);
|
||||
if (firstChild != null)
|
||||
this.ScrollBar.CurrentValue = (e.Area.Center.Y - this.Area.Height / 2 - firstChild.Area.Top) / e.Scale + this.ChildPadding.Value.Height / 2;
|
||||
this.ScrollToElement(e);
|
||||
};
|
||||
this.AddChild(this.ScrollBar);
|
||||
}
|
||||
|
@ -116,15 +114,6 @@ namespace MLEM.Ui.Elements {
|
|||
this.ScrollSetup();
|
||||
}
|
||||
|
||||
private void ScrollChildren() {
|
||||
if (!this.scrollOverflow)
|
||||
return;
|
||||
// we ignore false grandchildren so that the children of the scroll bar stay in place
|
||||
foreach (var child in this.GetChildren(c => c != this.ScrollBar, true, true))
|
||||
child.ScrollOffset.Y = -this.ScrollBar.CurrentValue;
|
||||
this.relevantChildrenDirty = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ForceUpdateSortedChildren() {
|
||||
base.ForceUpdateSortedChildren();
|
||||
|
@ -144,26 +133,6 @@ namespace MLEM.Ui.Elements {
|
|||
base.RemoveChildren(e => e != this.ScrollBar && (condition == null || condition(e)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IList<Element> GetRelevantChildren() {
|
||||
var relevant = base.GetRelevantChildren();
|
||||
if (this.scrollOverflow) {
|
||||
if (this.relevantChildrenDirty)
|
||||
this.ForceUpdateRelevantChildren();
|
||||
relevant = this.relevantChildren;
|
||||
}
|
||||
return relevant;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) {
|
||||
// draw children onto the render target if we have one
|
||||
|
@ -208,11 +177,32 @@ namespace MLEM.Ui.Elements {
|
|||
return base.GetElementUnderPos(position);
|
||||
}
|
||||
|
||||
private RectangleF GetRenderTargetArea() {
|
||||
var area = this.ChildPaddedArea;
|
||||
area.X = this.DisplayArea.X;
|
||||
area.Width = this.DisplayArea.Width;
|
||||
return area;
|
||||
/// <inheritdoc />
|
||||
public override void Dispose() {
|
||||
if (this.renderTarget != null) {
|
||||
this.renderTarget.Dispose();
|
||||
this.renderTarget = null;
|
||||
}
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls this panel's <see cref="ScrollBar"/> to the given <see cref="Element"/> in such a way that its center is positioned in the center of this panel.
|
||||
/// </summary>
|
||||
/// <param name="element">The element to scroll to.</param>
|
||||
public void ScrollToElement(Element element) {
|
||||
this.ScrollToElement(element.Area.Center.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls this panel's <see cref="ScrollBar"/> to the given <paramref name="elementY"/> coordinate in such a way that the coordinate is positioned in the center of this panel.
|
||||
/// </summary>
|
||||
/// <param name="elementY">The y coordinate to scroll to, which should have this element's <see cref="Element.Scale"/> applied.</param>
|
||||
public void ScrollToElement(float elementY) {
|
||||
var firstChild = this.Children.FirstOrDefault(c => c != this.ScrollBar);
|
||||
if (firstChild == null)
|
||||
return;
|
||||
this.ScrollBar.CurrentValue = (elementY - this.Area.Height / 2 - firstChild.Area.Top) / this.Scale + this.ChildPadding.Value.Height / 2;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -226,6 +216,26 @@ namespace MLEM.Ui.Elements {
|
|||
this.SetScrollBarStyle();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IList<Element> GetRelevantChildren() {
|
||||
var relevant = base.GetRelevantChildren();
|
||||
if (this.scrollOverflow) {
|
||||
if (this.relevantChildrenDirty)
|
||||
this.ForceUpdateRelevantChildren();
|
||||
relevant = this.relevantChildren;
|
||||
}
|
||||
return relevant;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the panel for auto-scrolling, creating the render target and setting up the scroll bar's maximum value.
|
||||
/// </summary>
|
||||
|
@ -274,15 +284,6 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Dispose() {
|
||||
if (this.renderTarget != null) {
|
||||
this.renderTarget.Dispose();
|
||||
this.renderTarget = null;
|
||||
}
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
private void SetScrollBarStyle() {
|
||||
if (this.ScrollBar == null)
|
||||
return;
|
||||
|
@ -309,5 +310,21 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
}
|
||||
|
||||
private RectangleF GetRenderTargetArea() {
|
||||
var area = this.ChildPaddedArea;
|
||||
area.X = this.DisplayArea.X;
|
||||
area.Width = this.DisplayArea.Width;
|
||||
return area;
|
||||
}
|
||||
|
||||
private void ScrollChildren() {
|
||||
if (!this.scrollOverflow)
|
||||
return;
|
||||
// we ignore false grandchildren so that the children of the scroll bar stay in place
|
||||
foreach (var child in this.GetChildren(c => c != this.ScrollBar, true, true))
|
||||
child.ScrollOffset.Y = -this.ScrollBar.CurrentValue;
|
||||
this.relevantChildrenDirty = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue