mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 20:58:34 +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.AutoSizeAddedAbsolute to allow for more granular control of auto-sizing
|
||||||
- Added Element.OnAddedToUi and Element.OnRemovedFromUi
|
- Added Element.OnAddedToUi and Element.OnRemovedFromUi
|
||||||
- Added ScrollBar.MouseDragScrolling
|
- Added ScrollBar.MouseDragScrolling
|
||||||
|
- Added Panel.ScrollToElement
|
||||||
|
|
||||||
Improvements
|
Improvements
|
||||||
- Allow elements to auto-adjust their size even when their children are aligned oddly
|
- Allow elements to auto-adjust their size even when their children are aligned oddly
|
||||||
|
|
|
@ -84,9 +84,7 @@ namespace MLEM.Ui.Elements {
|
||||||
return;
|
return;
|
||||||
if (e == null || !e.GetParentTree().Contains(this))
|
if (e == null || !e.GetParentTree().Contains(this))
|
||||||
return;
|
return;
|
||||||
var firstChild = this.Children.FirstOrDefault(c => c != this.ScrollBar);
|
this.ScrollToElement(e);
|
||||||
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.AddChild(this.ScrollBar);
|
this.AddChild(this.ScrollBar);
|
||||||
}
|
}
|
||||||
|
@ -116,15 +114,6 @@ namespace MLEM.Ui.Elements {
|
||||||
this.ScrollSetup();
|
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 />
|
/// <inheritdoc />
|
||||||
public override void ForceUpdateSortedChildren() {
|
public override void ForceUpdateSortedChildren() {
|
||||||
base.ForceUpdateSortedChildren();
|
base.ForceUpdateSortedChildren();
|
||||||
|
@ -144,26 +133,6 @@ namespace MLEM.Ui.Elements {
|
||||||
base.RemoveChildren(e => e != this.ScrollBar && (condition == null || condition(e)));
|
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 />
|
/// <inheritdoc />
|
||||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) {
|
public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) {
|
||||||
// draw children onto the render target if we have one
|
// draw children onto the render target if we have one
|
||||||
|
@ -208,11 +177,32 @@ namespace MLEM.Ui.Elements {
|
||||||
return base.GetElementUnderPos(position);
|
return base.GetElementUnderPos(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RectangleF GetRenderTargetArea() {
|
/// <inheritdoc />
|
||||||
var area = this.ChildPaddedArea;
|
public override void Dispose() {
|
||||||
area.X = this.DisplayArea.X;
|
if (this.renderTarget != null) {
|
||||||
area.Width = this.DisplayArea.Width;
|
this.renderTarget.Dispose();
|
||||||
return area;
|
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 />
|
/// <inheritdoc />
|
||||||
|
@ -226,6 +216,26 @@ namespace MLEM.Ui.Elements {
|
||||||
this.SetScrollBarStyle();
|
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>
|
/// <summary>
|
||||||
/// Prepares the panel for auto-scrolling, creating the render target and setting up the scroll bar's maximum value.
|
/// Prepares the panel for auto-scrolling, creating the render target and setting up the scroll bar's maximum value.
|
||||||
/// </summary>
|
/// </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() {
|
private void SetScrollBarStyle() {
|
||||||
if (this.ScrollBar == null)
|
if (this.ScrollBar == null)
|
||||||
return;
|
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