mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-25 17:59:24 +01:00
Added AutoInlineCenter
and AutoInlineBottom
anchors
This commit is contained in:
parent
bef670c09b
commit
94a54c336e
4 changed files with 74 additions and 37 deletions
|
@ -33,6 +33,9 @@ Removals
|
|||
- Marked GetDownTime, GetUpTime and GetTimeSincePress in Keybind and Combination as obsolete
|
||||
|
||||
### MLEM.Ui
|
||||
Additions
|
||||
- Added `AutoInlineCenter` and `AutoInlineBottom` anchors
|
||||
|
||||
Fixes
|
||||
- Fixed images not updating their hidden state properly when the displayed texture changes
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ using MLEM.Ui.Elements;
|
|||
|
||||
namespace MLEM.Ui {
|
||||
/// <summary>
|
||||
/// Represents a location for an <see cref="Element"/> to attach to within its parent (or within the screen's viewport if it is the <see cref="RootElement"/>).
|
||||
/// Represents a location for an <see cref="Element"/> to attach to within its parent (or within the screen's viewport if it is the <see cref="RootElement"/>).
|
||||
/// </summary>
|
||||
public enum Anchor {
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace MLEM.Ui {
|
|||
AutoRight,
|
||||
/// <summary>
|
||||
/// This is an auto-anchoring value.
|
||||
/// This anchor will cause an element to be placed in the same line as its older sibling, or at the start of the next line if there is no space to the right of its older sibling.
|
||||
/// This anchor will cause an element to be placed at the top right of its older sibling, or at the start of the next line if there is no space to the right of its older sibling.
|
||||
/// </summary>
|
||||
AutoInline,
|
||||
/// <summary>
|
||||
|
@ -68,7 +68,29 @@ namespace MLEM.Ui {
|
|||
/// This anchor is an overflow-ignoring version of <see cref="AutoInline"/>, meaning that the element will never be forced into the next line.
|
||||
/// Note that, when using this property, it is very easy to cause an element to overflow out of its parent container.
|
||||
/// </summary>
|
||||
AutoInlineIgnoreOverflow
|
||||
AutoInlineIgnoreOverflow,
|
||||
/// <summary>
|
||||
/// This is an auto-anchoring value.
|
||||
/// This anchor will cause an element to be placed at the center right of its older sibling, or at the start of the next line if there is no space to the right of its older sibling.
|
||||
/// </summary>
|
||||
AutoInlineCenter,
|
||||
/// <summary>
|
||||
/// This is an auto-anchoring value.
|
||||
/// This anchor is an overflow-ignoring version of <see cref="AutoInlineCenter"/>, meaning that the element will never be forced into the next line.
|
||||
/// Note that, when using this property, it is very easy to cause an element to overflow out of its parent container.
|
||||
/// </summary>
|
||||
AutoInlineCenterIgnoreOverflow,
|
||||
/// <summary>
|
||||
/// This is an auto-anchoring value.
|
||||
/// This anchor will cause an element to be placed at the bottom right of its older sibling, or at the start of the next line if there is no space to the right of its older sibling.
|
||||
/// </summary>
|
||||
AutoInlineBottom,
|
||||
/// <summary>
|
||||
/// This is an auto-anchoring value.
|
||||
/// This anchor is an overflow-ignoring version of <see cref="AutoInlineBottom"/>, meaning that the element will never be forced into the next line.
|
||||
/// Note that, when using this property, it is very easy to cause an element to overflow out of its parent container.
|
||||
/// </summary>
|
||||
AutoInlineBottomIgnoreOverflow
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -672,8 +672,6 @@ namespace MLEM.Ui.Elements {
|
|||
switch (this.anchor) {
|
||||
case Anchor.TopLeft:
|
||||
case Anchor.AutoLeft:
|
||||
case Anchor.AutoInline:
|
||||
case Anchor.AutoInlineIgnoreOverflow:
|
||||
pos.X = parentArea.X + this.ScaledOffset.X;
|
||||
pos.Y = parentArea.Y + this.ScaledOffset.Y;
|
||||
break;
|
||||
|
@ -714,36 +712,32 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
if (this.Anchor.IsAuto()) {
|
||||
Element previousChild;
|
||||
if (this.Anchor == Anchor.AutoInline || this.Anchor == Anchor.AutoInlineIgnoreOverflow) {
|
||||
previousChild = this.GetOlderSibling(e => !e.IsHidden && e.CanAutoAnchorsAttach);
|
||||
} else {
|
||||
previousChild = this.GetLowestOlderSibling(e => !e.IsHidden && e.CanAutoAnchorsAttach);
|
||||
}
|
||||
if (previousChild != null) {
|
||||
var prevArea = previousChild.GetAreaForAutoAnchors();
|
||||
switch (this.Anchor) {
|
||||
case Anchor.AutoLeft:
|
||||
case Anchor.AutoCenter:
|
||||
case Anchor.AutoRight:
|
||||
pos.Y = prevArea.Bottom + this.ScaledOffset.Y;
|
||||
break;
|
||||
case Anchor.AutoInline:
|
||||
var newX = prevArea.Right + this.ScaledOffset.X;
|
||||
// with awkward ui scale values, floating point rounding can cause an element that would usually
|
||||
// be positioned correctly to be pushed into the next line due to a very small deviation
|
||||
if (newX + newSize.X <= parentArea.Right + Element.Epsilon) {
|
||||
pos.X = newX;
|
||||
pos.Y = prevArea.Y + this.ScaledOffset.Y;
|
||||
} else {
|
||||
pos.Y = prevArea.Bottom + this.ScaledOffset.Y;
|
||||
if (this.Anchor.IsInline()) {
|
||||
var anchorEl = this.GetOlderSibling(e => !e.IsHidden && e.CanAutoAnchorsAttach);
|
||||
if (anchorEl != null) {
|
||||
var anchorElArea = anchorEl.GetAreaForAutoAnchors();
|
||||
var newX = anchorElArea.Right + this.ScaledOffset.X;
|
||||
// with awkward ui scale values, floating point rounding can cause an element that would usually
|
||||
// be positioned correctly to be pushed into the next line due to a very small deviation
|
||||
if (this.Anchor.IsIgnoreOverflow() || newX + newSize.X <= parentArea.Right + Element.Epsilon) {
|
||||
pos.X = newX;
|
||||
pos.Y = anchorElArea.Y + this.ScaledOffset.Y;
|
||||
if (this.Anchor == Anchor.AutoInlineCenter || this.Anchor == Anchor.AutoInlineCenterIgnoreOverflow) {
|
||||
pos.Y += (anchorElArea.Height - newSize.Y) / 2;
|
||||
} else if (this.Anchor == Anchor.AutoInlineBottom || this.Anchor == Anchor.AutoInlineBottomIgnoreOverflow) {
|
||||
pos.Y += anchorElArea.Height - newSize.Y;
|
||||
}
|
||||
break;
|
||||
case Anchor.AutoInlineIgnoreOverflow:
|
||||
pos.X = prevArea.Right + this.ScaledOffset.X;
|
||||
pos.Y = prevArea.Y + this.ScaledOffset.Y;
|
||||
break;
|
||||
} else {
|
||||
// all inline anchors act the same when overflowing into the next line
|
||||
pos.X = parentArea.X + this.ScaledOffset.X;
|
||||
pos.Y = anchorElArea.Bottom + this.ScaledOffset.Y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// non-inline auto anchors keep their x coordinates from the switch above
|
||||
var anchorEl = this.GetLowestOlderSibling(e => !e.IsHidden && e.CanAutoAnchorsAttach);
|
||||
if (anchorEl != null)
|
||||
pos.Y = anchorEl.GetAreaForAutoAnchors().Bottom + this.ScaledOffset.Y;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -234,21 +234,39 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given <see cref="Anchor"/> is automatic. The anchors <see cref="Anchor.AutoLeft"/>, <see cref="Anchor.AutoCenter"/>, <see cref="Anchor.AutoRight"/>, <see cref="Anchor.AutoInline"/> and <see cref="Anchor.AutoInlineIgnoreOverflow"/> will return true.
|
||||
/// Returns whether the given <see cref="Anchor"/> is automatic. The anchors <see cref="Anchor.AutoLeft"/>, <see cref="Anchor.AutoCenter"/>, <see cref="Anchor.AutoRight"/>, and any anchor that <see cref="IsInline"/> will return true.
|
||||
/// </summary>
|
||||
/// <param name="anchor">The anchor to query.</param>
|
||||
/// <returns>Whether the given anchor is automatic.</returns>
|
||||
public static bool IsAuto(this Anchor anchor) {
|
||||
return anchor == Anchor.AutoLeft || anchor == Anchor.AutoCenter || anchor == Anchor.AutoRight || anchor == Anchor.AutoInline || anchor == Anchor.AutoInlineIgnoreOverflow;
|
||||
return anchor == Anchor.AutoLeft || anchor == Anchor.AutoCenter || anchor == Anchor.AutoRight || anchor.IsInline();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given <see cref="Anchor"/> is left-aligned for the purpose of <see cref="Element.GetRightmostChild"/>. The anchors <see cref="Anchor.TopLeft"/>, <see cref="Anchor.CenterLeft"/>, <see cref="Anchor.BottomLeft"/>, <see cref="Anchor.AutoLeft"/>, <see cref="Anchor.AutoInline"/> and <see cref="Anchor.AutoInlineIgnoreOverflow"/> will return true.
|
||||
/// Returns whether the given <see cref="Anchor"/> is inline. The anchors <see cref="Anchor.AutoInline"/>, <see cref="Anchor.AutoInlineCenter"/>, <see cref="Anchor.AutoInlineBottom"/>, and any anchor that <see cref="IsIgnoreOverflow"/> will return true.
|
||||
/// </summary>
|
||||
/// <param name="anchor">The anchor to query.</param>
|
||||
/// <returns>Whether the given anchor is inline.</returns>
|
||||
public static bool IsInline(this Anchor anchor) {
|
||||
return anchor == Anchor.AutoInline || anchor == Anchor.AutoInlineCenter || anchor == Anchor.AutoInlineBottom || anchor.IsIgnoreOverflow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given <see cref="Anchor"/> ignores overflow. The anchors <see cref="Anchor.AutoInlineIgnoreOverflow"/>, <see cref="Anchor.AutoInlineCenterIgnoreOverflow"/>, and <see cref="Anchor.AutoInlineBottomIgnoreOverflow"/> will return true.
|
||||
/// </summary>
|
||||
/// <param name="anchor">The anchor to query.</param>
|
||||
/// <returns>Whether the given anchor ignores overflow.</returns>
|
||||
public static bool IsIgnoreOverflow(this Anchor anchor) {
|
||||
return anchor == Anchor.AutoInlineIgnoreOverflow || anchor == Anchor.AutoInlineCenterIgnoreOverflow || anchor == Anchor.AutoInlineBottomIgnoreOverflow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given <see cref="Anchor"/> is left-aligned for the purpose of <see cref="Element.GetRightmostChild"/>. The anchors <see cref="Anchor.TopLeft"/>, <see cref="Anchor.CenterLeft"/>, <see cref="Anchor.BottomLeft"/>, <see cref="Anchor.AutoLeft"/>, and any anchor that <see cref="IsInline"/> will return true.
|
||||
/// </summary>
|
||||
/// <param name="anchor">The anchor to query.</param>
|
||||
/// <returns>Whether the given anchor is left-aligned.</returns>
|
||||
public static bool IsLeftAligned(this Anchor anchor) {
|
||||
return anchor == Anchor.TopLeft || anchor == Anchor.CenterLeft || anchor == Anchor.BottomLeft || anchor == Anchor.AutoLeft || anchor == Anchor.AutoInline || anchor == Anchor.AutoInlineIgnoreOverflow;
|
||||
return anchor == Anchor.TopLeft || anchor == Anchor.CenterLeft || anchor == Anchor.BottomLeft || anchor == Anchor.AutoLeft || anchor.IsInline();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Reference in a new issue