mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-29 23:58:34 +01:00
Compare commits
3 commits
f1740b7b32
...
b2f457088d
Author | SHA1 | Date | |
---|---|---|---|
b2f457088d | |||
30432e43d4 | |||
3127ad5b74 |
4 changed files with 40 additions and 11 deletions
|
@ -43,12 +43,14 @@ Improvements
|
|||
- Increased Element area calculation recursion limit to 64
|
||||
- Improved the SquishingGroup algorithm by prioritizing each element's final size
|
||||
- Allow specifying start and end indices when drawing a Paragraph
|
||||
- Allow elements with larger children to influence a panel's scrollable area
|
||||
|
||||
Fixes
|
||||
- Fixed images not updating their hidden state properly when the displayed texture changes
|
||||
- Fixed AutoInline elements overflowing into their parent if it's taller
|
||||
- Fixed Paragraph and Checkbox not reacting to SquishingGroup sizing properly
|
||||
- Fixed TextInput and Slider still reacting to input when they are selected, but not part of the active root
|
||||
- Fixed dropdown menu panels not updating their width when the dropdown's width changes
|
||||
|
||||
### MLEM.Data
|
||||
Improvements
|
||||
|
|
|
@ -37,10 +37,13 @@ namespace MLEM.Ui.Elements {
|
|||
/// <param name="text">The text displayed on the dropdown button</param>
|
||||
/// <param name="tooltipText">The text displayed as a tooltip when hovering over the dropdown button</param>
|
||||
public Dropdown(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : base(anchor, size, text, tooltipText) {
|
||||
this.Panel = this.AddChild(new Panel(Anchor.TopCenter, size, Vector2.Zero, true) {
|
||||
this.Panel = this.AddChild(new Panel(Anchor.TopCenter, Vector2.Zero, Vector2.Zero, true) {
|
||||
IsHidden = true
|
||||
});
|
||||
this.OnAreaUpdated += e => this.Panel.PositionOffset = new Vector2(0, e.Area.Height / this.Scale);
|
||||
this.OnAreaUpdated += e => {
|
||||
this.Panel.Size = new Vector2(e.Area.Width / e.Scale, 0);
|
||||
this.Panel.PositionOffset = new Vector2(0, e.Area.Height / e.Scale);
|
||||
};
|
||||
this.OnOpenedOrClosed += e => this.Priority = this.IsOpen ? 10000 : 0;
|
||||
this.OnPressed += e => {
|
||||
this.IsOpen = !this.IsOpen;
|
||||
|
|
|
@ -859,14 +859,16 @@ namespace MLEM.Ui.Elements {
|
|||
/// Returns this element's lowest child element (in terms of y position) that matches the given condition.
|
||||
/// </summary>
|
||||
/// <param name="condition">The condition to match</param>
|
||||
/// <param name="total">Whether to evaluate based on the child's <see cref="GetTotalCoveredArea"/>, rather than its <see cref="UnscrolledArea"/>.</param>
|
||||
/// <returns>The lowest element, or null if no such element exists</returns>
|
||||
public Element GetLowestChild(Func<Element, bool> condition = null) {
|
||||
public Element GetLowestChild(Func<Element, bool> condition = null, bool total = false) {
|
||||
Element lowest = null;
|
||||
var lowestX = float.MinValue;
|
||||
foreach (var child in this.Children) {
|
||||
if (condition != null && !condition(child))
|
||||
continue;
|
||||
var x = !child.Anchor.IsTopAligned() ? child.UnscrolledArea.Height : child.UnscrolledArea.Bottom;
|
||||
var covered = total ? child.GetTotalCoveredArea(true) : child.UnscrolledArea;
|
||||
var x = !child.Anchor.IsTopAligned() ? covered.Height : covered.Bottom;
|
||||
if (x >= lowestX) {
|
||||
lowest = child;
|
||||
lowestX = x;
|
||||
|
@ -879,14 +881,16 @@ namespace MLEM.Ui.Elements {
|
|||
/// Returns this element's rightmost child (in terms of x position) that matches the given condition.
|
||||
/// </summary>
|
||||
/// <param name="condition">The condition to match</param>
|
||||
/// <param name="total">Whether to evaluate based on the child's <see cref="GetTotalCoveredArea"/>, rather than its <see cref="UnscrolledArea"/>.</param>
|
||||
/// <returns>The rightmost element, or null if no such element exists</returns>
|
||||
public Element GetRightmostChild(Func<Element, bool> condition = null) {
|
||||
public Element GetRightmostChild(Func<Element, bool> condition = null, bool total = false) {
|
||||
Element rightmost = null;
|
||||
var rightmostX = float.MinValue;
|
||||
foreach (var child in this.Children) {
|
||||
if (condition != null && !condition(child))
|
||||
continue;
|
||||
var x = !child.Anchor.IsLeftAligned() ? child.UnscrolledArea.Width : child.UnscrolledArea.Right;
|
||||
var covered = total ? child.GetTotalCoveredArea(true) : child.UnscrolledArea;
|
||||
var x = !child.Anchor.IsLeftAligned() ? covered.Width : covered.Right;
|
||||
if (x >= rightmostX) {
|
||||
rightmost = child;
|
||||
rightmostX = x;
|
||||
|
@ -900,8 +904,9 @@ namespace MLEM.Ui.Elements {
|
|||
/// The returned element's <see cref="Parent"/> will always be equal to this element's <see cref="Parent"/>.
|
||||
/// </summary>
|
||||
/// <param name="condition">The condition to match</param>
|
||||
/// <param name="total">Whether to evaluate based on the child's <see cref="GetTotalCoveredArea"/>, rather than its <see cref="UnscrolledArea"/>.</param>
|
||||
/// <returns>The lowest older sibling of this element, or null if no such element exists</returns>
|
||||
public Element GetLowestOlderSibling(Func<Element, bool> condition = null) {
|
||||
public Element GetLowestOlderSibling(Func<Element, bool> condition = null, bool total = false) {
|
||||
if (this.Parent == null)
|
||||
return null;
|
||||
Element lowest = null;
|
||||
|
@ -910,7 +915,7 @@ namespace MLEM.Ui.Elements {
|
|||
break;
|
||||
if (condition != null && !condition(child))
|
||||
continue;
|
||||
if (lowest == null || child.UnscrolledArea.Bottom >= lowest.UnscrolledArea.Bottom)
|
||||
if (lowest == null || (total ? child.GetTotalCoveredArea(true) : child.UnscrolledArea).Bottom >= lowest.UnscrolledArea.Bottom)
|
||||
lowest = child;
|
||||
}
|
||||
return lowest;
|
||||
|
@ -992,6 +997,21 @@ namespace MLEM.Ui.Elements {
|
|||
yield return parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the total covered area of this element, which is its <see cref="Area"/> (or <see cref="UnscrolledArea"/>), unioned with all of the total covered areas of its <see cref="Children"/>.
|
||||
/// The returned area is only different from this element's <see cref="Area"/> (or <see cref="UnscrolledArea"/>) if it has any <see cref="Children"/> that are outside of this element's area, or are bigger than this element.
|
||||
/// </summary>
|
||||
/// <param name="unscrolled">Whether to use elements' <see cref="UnscrolledArea"/> (instead of their <see cref="Area"/>).</param>
|
||||
/// <returns>This element's total covered area.</returns>
|
||||
public RectangleF GetTotalCoveredArea(bool unscrolled) {
|
||||
var ret = unscrolled ? this.UnscrolledArea : this.Area;
|
||||
foreach (var child in this.Children) {
|
||||
if (!child.IsHidden)
|
||||
ret = RectangleF.Union(ret, child.GetTotalCoveredArea(unscrolled));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a subset of <see cref="Children"/> that are currently relevant in terms of drawing and input querying.
|
||||
/// A <see cref="Panel"/> only returns elements that are currently in view here.
|
||||
|
|
|
@ -230,8 +230,12 @@ namespace MLEM.Ui.Elements {
|
|||
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)
|
||||
if (grandchild) {
|
||||
this.ScrollChildren();
|
||||
// we also need to re-setup here in case the child is involved in a special GetTotalCoveredArea
|
||||
if (!this.AreaDirty)
|
||||
this.ScrollSetup();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -253,8 +257,8 @@ namespace MLEM.Ui.Elements {
|
|||
float childrenHeight;
|
||||
if (this.Children.Count > 1) {
|
||||
var firstChild = this.Children.FirstOrDefault(c => c != this.ScrollBar);
|
||||
var lowestChild = this.GetLowestChild(c => c != this.ScrollBar && !c.IsHidden);
|
||||
childrenHeight = lowestChild.Area.Bottom - firstChild.Area.Top;
|
||||
var lowestChild = this.GetLowestChild(c => c != this.ScrollBar && !c.IsHidden, true);
|
||||
childrenHeight = lowestChild.GetTotalCoveredArea(false).Bottom - firstChild.Area.Top;
|
||||
} else {
|
||||
// if we only have one child (the scroll bar), then the children take up no visual height
|
||||
childrenHeight = 0;
|
||||
|
|
Loading…
Reference in a new issue