1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-25 22:18:34 +01:00

Some more ui style improvements

This commit is contained in:
Ell 2021-10-30 15:33:38 +02:00
parent 3648352540
commit ca89d03ca4
11 changed files with 64 additions and 42 deletions

View file

@ -27,6 +27,8 @@ Improvements
- Exposed the epsilon value used by Element calculations - Exposed the epsilon value used by Element calculations
- Made Image ScaleToImage take ui scale into account - Made Image ScaleToImage take ui scale into account
- Added style properties for a lot of hardcoded default element styles - Added style properties for a lot of hardcoded default element styles
- Allow style properties to set style values with a higher priority, which allows elements to style their default children
- Allow changing the entire ui style for a single element
Fixes Fixes
- Fixed VerticalSpace height parameter being an integer - Fixed VerticalSpace height parameter being an integer

View file

@ -69,7 +69,7 @@ namespace Demos {
this.UiRoot.AddChild(this.root); this.UiRoot.AddChild(this.root);
this.root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "This is a small demo for MLEM.Ui, a user interface library that is part of the MLEM Library for Extending MonoGame.")); this.root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "This is a small demo for MLEM.Ui, a user interface library that is part of the MLEM Library for Extending MonoGame."));
var image = this.root.AddChild(new Image(Anchor.AutoCenter, new Vector2(50, 50), new TextureRegion(this.testTexture, 0, 0, 8, 8)) {IsHidden = true, Padding = new Vector2(3)}); var image = this.root.AddChild(new Image(Anchor.AutoCenter, new Vector2(50, 50), new TextureRegion(this.testTexture, 0, 0, 8, 8)) {IsHidden = true, Padding = new Padding(3)});
// Setting the x or y coordinate of the size to 1 or a lower number causes the width or height to be a percentage of the parent's width or height // Setting the x or y coordinate of the size to 1 or a lower number causes the width or height to be a percentage of the parent's width or height
// (for example, setting the size's x to 0.75 would make the element's width be 0.75*parentWidth) // (for example, setting the size's x to 0.75 would make the element's width be 0.75*parentWidth)
this.root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 10), "Toggle Grass Image", "This button shows a grass tile above it to show the automatic anchoring of objects.") { this.root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 10), "Toggle Grass Image", "This button shows a grass tile above it to show the automatic anchoring of objects.") {

View file

@ -1,5 +1,6 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using MLEM.Misc;
using MLEM.Textures; using MLEM.Textures;
using MLEM.Ui.Style; using MLEM.Ui.Style;
@ -81,7 +82,8 @@ namespace MLEM.Ui.Elements {
/// <param name="tooltipText">The text that should be displayed in a <see cref="Tooltip"/> when hovering over this button</param> /// <param name="tooltipText">The text that should be displayed in a <see cref="Tooltip"/> when hovering over this button</param>
public Button(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : base(anchor, size) { public Button(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : base(anchor, size) {
if (text != null) { if (text != null) {
this.Text = new Paragraph(Anchor.Center, 1, text, true) {Padding = new Vector2(1)}; this.Text = new Paragraph(Anchor.Center, 1, text, true);
this.Text.Padding.SetFromStyle(new Padding(1), 1);
this.AddChild(this.Text); this.AddChild(this.Text);
} }
if (tooltipText != null) if (tooltipText != null)

View file

@ -32,8 +32,17 @@ namespace MLEM.Ui.Elements {
internal set { internal set {
this.system = value; this.system = value;
this.Controls = value?.Controls; this.Controls = value?.Controls;
if (this.system != null) this.Style = value?.Style;
this.InitStyle(this.system.Style); }
}
public UiStyle Style {
get => this.style;
set {
if (this.style != value) {
this.style = value;
if (value != null)
this.InitStyle(value);
}
} }
} }
/// <summary> /// <summary>
@ -109,31 +118,13 @@ namespace MLEM.Ui.Elements {
/// </summary> /// </summary>
public Vector2 ScaledOffset => this.offset * this.Scale; public Vector2 ScaledOffset => this.offset * this.Scale;
/// <summary> /// <summary>
/// The padding that this element has.
/// The padding is subtracted from the element's <see cref="Size"/>, and it is an area that the element does not extend into. This means that this element's resulting <see cref="DisplayArea"/> does not include this padding.
/// </summary>
public Padding Padding;
/// <summary>
/// The <see cref="Padding"/>, but with <see cref="Scale"/> applied. /// The <see cref="Padding"/>, but with <see cref="Scale"/> applied.
/// </summary> /// </summary>
public Padding ScaledPadding => this.Padding * this.Scale; public Padding ScaledPadding => this.Padding.Value * this.Scale;
/// <summary>
/// The child padding that this element has.
/// The child padding moves any <see cref="Children"/> added to this element inwards by the given amount in each direction.
/// </summary>
public Padding ChildPadding {
get => this.childPadding;
set {
if (this.childPadding == value)
return;
this.childPadding = value;
this.SetAreaDirty();
}
}
/// <summary> /// <summary>
/// The <see cref="ChildPadding"/>, but with <see cref="Scale"/> applied. /// The <see cref="ChildPadding"/>, but with <see cref="Scale"/> applied.
/// </summary> /// </summary>
public Padding ScaledChildPadding => this.childPadding * this.Scale; public Padding ScaledChildPadding => this.ChildPadding.Value * this.Scale;
/// <summary> /// <summary>
/// This element's current <see cref="Area"/>, but with <see cref="ScaledChildPadding"/> applied. /// This element's current <see cref="Area"/>, but with <see cref="ScaledChildPadding"/> applied.
/// </summary> /// </summary>
@ -260,6 +251,7 @@ namespace MLEM.Ui.Elements {
/// Stores whether this element is its <see cref="Root"/>'s <see cref="RootElement.SelectedElement"/>. /// Stores whether this element is its <see cref="Root"/>'s <see cref="RootElement.SelectedElement"/>.
/// </summary> /// </summary>
public bool IsSelected { get; protected set; } public bool IsSelected { get; protected set; }
/// <summary> /// <summary>
/// A style property that contains the selection indicator that is displayed on this element if it is the <see cref="RootElement.SelectedElement"/> /// A style property that contains the selection indicator that is displayed on this element if it is the <see cref="RootElement.SelectedElement"/>
/// </summary> /// </summary>
@ -272,6 +264,17 @@ namespace MLEM.Ui.Elements {
/// A style property that contains the sound effect that is played when this element's <see cref="OnSecondaryPressed"/> is called /// A style property that contains the sound effect that is played when this element's <see cref="OnSecondaryPressed"/> is called
/// </summary> /// </summary>
public StyleProp<SoundEffectInfo> SecondActionSound; public StyleProp<SoundEffectInfo> SecondActionSound;
/// <summary>
/// The padding that this element has.
/// The padding is subtracted from the element's <see cref="Size"/>, and it is an area that the element does not extend into. This means that this element's resulting <see cref="DisplayArea"/> does not include this padding.
/// </summary>
public StyleProp<Padding> Padding;
/// <summary>
/// The child padding that this element has.
/// The child padding moves any <see cref="Children"/> added to this element inwards by the given amount in each direction.
/// When setting this style after this element has already been added to a ui, <see cref="SetAreaDirty"/> should be called.
/// </summary>
public StyleProp<Padding> ChildPadding;
/// <summary> /// <summary>
/// Event that is called after this element is drawn, but before its children are drawn /// Event that is called after this element is drawn, but before its children are drawn
@ -389,11 +392,11 @@ namespace MLEM.Ui.Elements {
private Anchor anchor; private Anchor anchor;
private Vector2 size; private Vector2 size;
private Vector2 offset; private Vector2 offset;
private Padding childPadding;
private RectangleF area; private RectangleF area;
private bool areaDirty; private bool areaDirty;
private bool isHidden; private bool isHidden;
private int priority; private int priority;
private UiStyle style;
/// <summary> /// <summary>
/// Creates a new element with the given anchor and size and sets up some default event reactions. /// Creates a new element with the given anchor and size and sets up some default event reactions.

View file

@ -2,6 +2,7 @@ using System;
using System.Linq; using System.Linq;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using MLEM.Input; using MLEM.Input;
using MLEM.Misc;
using MLEM.Textures; using MLEM.Textures;
namespace MLEM.Ui.Elements { namespace MLEM.Ui.Elements {
@ -22,7 +23,8 @@ namespace MLEM.Ui.Elements {
/// <returns>An image button</returns> /// <returns>An image button</returns>
public static Button ImageButton(Anchor anchor, Vector2 size, TextureRegion texture, string text = null, string tooltipText = null, float imagePadding = 2) { public static Button ImageButton(Anchor anchor, Vector2 size, TextureRegion texture, string text = null, string tooltipText = null, float imagePadding = 2) {
var button = new Button(anchor, size, text, tooltipText); var button = new Button(anchor, size, text, tooltipText);
var image = new Image(Anchor.CenterLeft, Vector2.One, texture) {Padding = new Vector2(imagePadding)}; var image = new Image(Anchor.CenterLeft, Vector2.One, texture);
image.Padding.SetFromStyle(new Padding(imagePadding), 1);
button.OnAreaUpdated += e => image.Size = new Vector2(e.Area.Height, e.Area.Height) / e.Scale; button.OnAreaUpdated += e => image.Size = new Vector2(e.Area.Height, e.Area.Height) / e.Scale;
button.AddChild(image, 0); button.AddChild(image, 0);
return button; return button;

View file

@ -71,8 +71,12 @@ namespace MLEM.Ui.Elements {
AutoHideWhenEmpty = autoHideScrollbar, AutoHideWhenEmpty = autoHideScrollbar,
IsHidden = autoHideScrollbar IsHidden = autoHideScrollbar
}; };
if (autoHideScrollbar) if (autoHideScrollbar) {
this.ScrollBar.OnAutoHide += e => this.ChildPadding += new Padding(0, this.ScrollerSize.Value.X, 0, 0) * (e.IsHidden ? -1 : 1); this.ScrollBar.OnAutoHide += e => {
this.ChildPadding += new Padding(0, this.ScrollerSize.Value.X, 0, 0) * (e.IsHidden ? -1 : 1);
this.SetAreaDirty();
};
}
// handle automatic element selection, the scroller needs to scroll to the right location // handle automatic element selection, the scroller needs to scroll to the right location
this.OnSelectedElementChanged += (element, otherElement) => { this.OnSelectedElementChanged += (element, otherElement) => {
@ -216,8 +220,7 @@ namespace MLEM.Ui.Elements {
this.Texture.SetFromStyle(style.PanelTexture); this.Texture.SetFromStyle(style.PanelTexture);
this.StepPerScroll.SetFromStyle(style.PanelStepPerScroll); this.StepPerScroll.SetFromStyle(style.PanelStepPerScroll);
this.ScrollerSize.SetFromStyle(style.PanelScrollerSize); this.ScrollerSize.SetFromStyle(style.PanelScrollerSize);
if (this.ChildPadding == default) this.ChildPadding.SetFromStyle(style.PanelChildPadding);
this.ChildPadding = style.PanelChildPadding;
this.SetScrollBarStyle(); this.SetScrollBarStyle();
} }
@ -235,7 +238,7 @@ namespace MLEM.Ui.Elements {
var lowestChild = this.GetLowestChild(c => c != this.ScrollBar && !c.IsHidden); var lowestChild = this.GetLowestChild(c => c != this.ScrollBar && !c.IsHidden);
// the max value of the scrollbar is the amount of non-scaled pixels taken up by overflowing components // the max value of the scrollbar is the amount of non-scaled pixels taken up by overflowing components
var childrenHeight = lowestChild.Area.Bottom - firstChild.Area.Top; var childrenHeight = lowestChild.Area.Bottom - firstChild.Area.Top;
this.ScrollBar.MaxValue = (childrenHeight - this.Area.Height) / this.Scale + this.ChildPadding.Height; this.ScrollBar.MaxValue = (childrenHeight - this.Area.Height) / this.Scale + this.ChildPadding.Value.Height;
// update the render target // update the render target
var targetArea = (Rectangle) this.GetRenderTargetArea(); var targetArea = (Rectangle) this.GetRenderTargetArea();

View file

@ -79,10 +79,9 @@ namespace MLEM.Ui.Elements {
this.Texture.SetFromStyle(style.TooltipBackground); this.Texture.SetFromStyle(style.TooltipBackground);
this.MouseOffset.SetFromStyle(style.TooltipOffset); this.MouseOffset.SetFromStyle(style.TooltipOffset);
this.Delay.SetFromStyle(style.TooltipDelay); this.Delay.SetFromStyle(style.TooltipDelay);
this.ChildPadding = style.TooltipChildPadding; this.ChildPadding.SetFromStyle(style.TooltipChildPadding);
if (this.Paragraph != null) { if (this.Paragraph != null) {
// we can't set from style here since it's a different element this.Paragraph.TextColor.SetFromStyle(style.TooltipTextColor, 1);
this.Paragraph.TextColor.Set(style.TooltipTextColor);
this.Paragraph.Size = new Vector2(style.TooltipTextWidth, 0); this.Paragraph.Size = new Vector2(style.TooltipTextWidth, 0);
} }
} }

View file

@ -14,14 +14,14 @@ namespace MLEM.Ui.Style {
/// The currently applied style /// The currently applied style
/// </summary> /// </summary>
public T Value { get; private set; } public T Value { get; private set; }
private bool isCustom; private byte lastSetPriority;
/// <summary> /// <summary>
/// Creates a new style property with the given custom style. /// Creates a new style property with the given custom style.
/// </summary> /// </summary>
/// <param name="value">The custom style to apply</param> /// <param name="value">The custom style to apply</param>
public StyleProp(T value) { public StyleProp(T value) {
this.isCustom = true; this.lastSetPriority = byte.MaxValue;
this.Value = value; this.Value = value;
} }
@ -30,9 +30,12 @@ namespace MLEM.Ui.Style {
/// This allows this property to be overridden by custom style settings using <see cref="Set"/>. /// This allows this property to be overridden by custom style settings using <see cref="Set"/>.
/// </summary> /// </summary>
/// <param name="value">The style to apply</param> /// <param name="value">The style to apply</param>
public void SetFromStyle(T value) { /// <param name="priority">The priority that this style value has. Higher priority style values will override lower priority style values.</param>
if (!this.isCustom) public void SetFromStyle(T value, byte priority = 0) {
if (priority >= this.lastSetPriority) {
this.Value = value; this.Value = value;
this.lastSetPriority = priority;
}
} }
/// <summary> /// <summary>
@ -41,7 +44,7 @@ namespace MLEM.Ui.Style {
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
public void Set(T value) { public void Set(T value) {
this.isCustom = true; this.lastSetPriority = byte.MaxValue;
this.Value = value; this.Value = value;
} }
@ -64,7 +67,7 @@ namespace MLEM.Ui.Style {
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() { public override string ToString() {
return $"{this.Value} (Custom: {this.isCustom})"; return this.Value?.ToString();
} }
/// <summary> /// <summary>

View file

@ -52,6 +52,14 @@ namespace MLEM.Misc {
this.Bottom = bottom; this.Bottom = bottom;
} }
/// <summary>
/// Creates a new padding with the specified value, which will be applied to each edge.
/// </summary>
/// <param name="value">The padding to apply to each edge</param>
public Padding(float value) :
this(value, value) {
}
/// <summary> /// <summary>
/// Creates a new padding with the specified x and y values, applying them to both edges. /// Creates a new padding with the specified x and y values, applying them to both edges.
/// </summary> /// </summary>

View file

@ -224,7 +224,7 @@ namespace Sandbox {
var button = loadPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1)) { var button = loadPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1)) {
SetHeightBasedOnChildren = true, SetHeightBasedOnChildren = true,
Padding = new Padding(0, 0, 0, 1), Padding = new Padding(0, 0, 0, 1),
ChildPadding = new Vector2(3) ChildPadding = new Padding(3)
}); });
button.AddChild(new Group(Anchor.AutoLeft, new Vector2(0.5F, 30), false) { button.AddChild(new Group(Anchor.AutoLeft, new Vector2(0.5F, 30), false) {
CanBeMoused = false CanBeMoused = false

View file

@ -49,7 +49,7 @@ namespace Tests {
var button = panel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1)) { var button = panel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1)) {
SetHeightBasedOnChildren = true, SetHeightBasedOnChildren = true,
Padding = new Padding(0, 0, 0, 1), Padding = new Padding(0, 0, 0, 1),
ChildPadding = new Vector2(3) ChildPadding = new Padding(3)
}); });
button.AddChild(new Group(Anchor.AutoLeft, new Vector2(0.5F, 30), false) { button.AddChild(new Group(Anchor.AutoLeft, new Vector2(0.5F, 30), false) {
CanBeMoused = false CanBeMoused = false