1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-04 06:13:36 +02:00

Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
Ell 2021-12-11 01:02:36 +01:00
commit 18a62f5ca3
4 changed files with 78 additions and 7 deletions

View file

@ -37,6 +37,7 @@ Additions
- Allow specifying a maximum amount of characters for a TextField
- Added a multiline editing mode to TextField
- Added a formatting code to allow for inline font changes
- Added PreventSiblingSpill to Element
Improvements
- **Made Image ScaleToImage take ui scale into account**

View file

@ -241,9 +241,16 @@ namespace MLEM.Ui.Elements {
/// Set this field to true to cause this element's final display area to never exceed that of its <see cref="Parent"/>.
/// If the resulting area is too large, the size of this element is shrunk to fit the target area.
/// This can be useful if an element should fill the remaining area of a parent exactly.
/// When setting this value after this element has already been added to a ui, <see cref="SetAreaDirty"/> should be called.
/// </summary>
public bool PreventParentSpill;
/// <summary>
/// Set this field to true to cause this element's final display ever to never overlap with any of its siblings (<see cref="GetSiblings"/>).
/// If the resulting area is too large, the size of this element is shrunk to best accomodate for the areas of its siblings.
/// When setting this value after this element has already been added to a ui, <see cref="SetAreaDirty"/> should be called.
/// </summary>
public bool PreventSiblingSpill;
/// <summary>
/// The transparency (alpha value) that this element is rendered with.
/// Note that, when <see cref="Draw"/> is called, this alpha value is multiplied with the <see cref="Parent"/>'s alpha value and passed down to this element's <see cref="Children"/>.
/// </summary>
@ -333,6 +340,10 @@ namespace MLEM.Ui.Elements {
/// </summary>
public GenericCallback OnAreaUpdated;
/// <summary>
/// Event that is called when this element's area is marked as dirty using <see cref="SetAreaDirty"/>.
/// </summary>
public GenericCallback OnAreaDirty;
/// <summary>
/// Event that is called when the element that is currently being moused changes within the ui system.
/// Note that the event fired doesn't necessarily correlate to this specific element.
/// </summary>
@ -516,8 +527,17 @@ namespace MLEM.Ui.Elements {
/// </summary>
public void SetAreaDirty() {
this.areaDirty = true;
if (this.Parent != null && (this.Anchor >= Anchor.AutoLeft || this.Parent.SetWidthBasedOnChildren || this.Parent.SetHeightBasedOnChildren))
this.Parent.SetAreaDirty();
if (this.Parent != null) {
// set parent dirty if the parent's layout depends on our area
if (this.Anchor >= Anchor.AutoLeft || this.Parent.SetWidthBasedOnChildren || this.Parent.SetHeightBasedOnChildren)
this.Parent.SetAreaDirty();
// set siblings dirty that depend on our area
foreach (var sibling in this.GetSiblings()) {
if (sibling.PreventSiblingSpill)
sibling.SetAreaDirty();
}
}
this.System?.InvokeOnElementAreaDirty(this);
}
/// <summary>
@ -644,6 +664,30 @@ namespace MLEM.Ui.Elements {
newSize.Y = parentArea.Bottom - pos.Y;
}
if (this.PreventSiblingSpill) {
foreach (var sibling in this.GetSiblings(e => !e.IsHidden)) {
var leftIntersect = sibling.Area.Right - pos.X;
var rightIntersect = pos.X + newSize.X - sibling.Area.Left;
var bottomIntersect = sibling.Area.Bottom - pos.Y;
var topIntersect = pos.Y + newSize.Y - sibling.Area.Top;
if (leftIntersect > 0 && rightIntersect > 0 && bottomIntersect > 0 && topIntersect > 0) {
if (rightIntersect + leftIntersect < topIntersect + bottomIntersect) {
if (rightIntersect > leftIntersect) {
pos.X = Math.Max(pos.X, sibling.Area.Right);
} else {
newSize.X = Math.Min(pos.X + newSize.X, sibling.Area.Left) - pos.X;
}
} else {
if (topIntersect > bottomIntersect) {
pos.Y = Math.Max(pos.Y, sibling.Area.Bottom);
} else {
newSize.Y = Math.Min(pos.Y + newSize.Y, sibling.Area.Top) - pos.Y;
}
}
}
}
}
this.area = new RectangleF(pos, newSize);
this.System.InvokeOnElementAreaUpdated(this);

View file

@ -152,6 +152,10 @@ namespace MLEM.Ui {
/// </summary>
public event Element.GenericCallback OnElementAreaUpdated;
/// <summary>
/// Event that is invoked when an element's area is marked as dirty using <see cref="Element.SetAreaDirty"/>.
/// </summary>
public event Element.GenericCallback OnElementAreaDirty;
/// <summary>
/// Event that is invoked when the <see cref="Element"/> that the mouse is currently over changes
/// </summary>
public event Element.GenericCallback OnMousedElementChanged;
@ -193,6 +197,7 @@ namespace MLEM.Ui {
this.OnElementTouchEnter += e => e.OnTouchEnter?.Invoke(e);
this.OnElementTouchExit += e => e.OnTouchExit?.Invoke(e);
this.OnElementAreaUpdated += e => e.OnAreaUpdated?.Invoke(e);
this.OnElementAreaDirty += e => e.OnAreaDirty?.Invoke(e);
this.OnMousedElementChanged += e => this.ApplyToAll(t => t.OnMousedElementChanged?.Invoke(t, e));
this.OnTouchedElementChanged += e => this.ApplyToAll(t => t.OnTouchedElementChanged?.Invoke(t, e));
this.OnSelectedElementChanged += e => this.ApplyToAll(t => t.OnSelectedElementChanged?.Invoke(t, e));
@ -357,6 +362,7 @@ namespace MLEM.Ui {
internal void InvokeOnSelectedElementDrawn(Element element, GameTime time, SpriteBatch batch, float alpha) => this.OnSelectedElementDrawn?.Invoke(element, time, batch, alpha);
internal void InvokeOnElementUpdated(Element element, GameTime time) => this.OnElementUpdated?.Invoke(element, time);
internal void InvokeOnElementAreaUpdated(Element element) => this.OnElementAreaUpdated?.Invoke(element);
internal void InvokeOnElementAreaDirty(Element element) => this.OnElementAreaDirty?.Invoke(element);
internal void InvokeOnElementPressed(Element element) => this.OnElementPressed?.Invoke(element);
internal void InvokeOnElementSecondaryPressed(Element element) => this.OnElementSecondaryPressed?.Invoke(element);
internal void InvokeOnElementSelected(Element element) => this.OnElementSelected?.Invoke(element);

View file

@ -8,7 +8,6 @@ using Microsoft.Xna.Framework.Input;
using MLEM.Cameras;
using MLEM.Data;
using MLEM.Data.Content;
using MLEM.Extended.Extensions;
using MLEM.Extended.Font;
using MLEM.Extended.Tiled;
using MLEM.Extensions;
@ -22,9 +21,7 @@ using MLEM.Textures;
using MLEM.Ui;
using MLEM.Ui.Elements;
using MLEM.Ui.Style;
using MonoGame.Extended;
using MonoGame.Extended.Tiled;
using Group = MLEM.Ui.Elements.Group;
namespace Sandbox {
public class GameImpl : MlemGame {
@ -216,7 +213,7 @@ namespace Sandbox {
invalidPanel.AddChild(new VerticalSpace(1));
this.UiSystem.Add("Invalid", invalidPanel);*/
var loadGroup = new Group(Anchor.TopLeft, Vector2.One, false);
/*var loadGroup = new Group(Anchor.TopLeft, Vector2.One, false);
var loadPanel = loadGroup.AddChild(new Panel(Anchor.Center, new Vector2(150, 150), Vector2.Zero, false, true, false) {
ChildPadding = new Padding(5, 10, 5, 5)
});
@ -240,7 +237,30 @@ namespace Sandbox {
}
};
par.OnDrawn = (e, time, batch, a) => batch.DrawRectangle(e.DisplayArea.ToExtended(), Color.Red);
this.UiSystem.Add("Load", loadGroup);
this.UiSystem.Add("Load", loadGroup);*/
var spillPanel = new Panel(Anchor.Center, new Vector2(100), Vector2.Zero);
spillPanel.AddChild(new Button(Anchor.TopLeft, new Vector2(30), "TL") {
OnUpdated = (e, time) => e.IsHidden = Input.IsKeyDown(Keys.D1)
});
spillPanel.AddChild(new Button(Anchor.TopRight, new Vector2(30), "TR") {
OnUpdated = (e, time) => e.IsHidden = Input.IsKeyDown(Keys.D2)
});
spillPanel.AddChild(new Button(Anchor.BottomLeft, new Vector2(30), "BL") {
OnUpdated = (e, time) => e.IsHidden = Input.IsKeyDown(Keys.D3)
});
spillPanel.AddChild(new Button(Anchor.BottomRight, new Vector2(30), "BR") {
OnUpdated = (e, time) => e.IsHidden = Input.IsKeyDown(Keys.D4)
});
spillPanel.AddChild(new Button(Anchor.Center, Vector2.Zero, "Spill Test") {
PositionOffset = new Vector2(-10, -5),
Size = new Vector2(60, 55),
OnPressed = e => {
e.PreventSiblingSpill = !e.PreventSiblingSpill;
e.SetAreaDirty();
}
});
this.UiSystem.Add("SpillTest", spillPanel);
}
protected override void DoUpdate(GameTime gameTime) {