mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 04:53:29 +01:00
Some more ui style improvements
This commit is contained in:
parent
3648352540
commit
ca89d03ca4
11 changed files with 64 additions and 42 deletions
|
@ -27,6 +27,8 @@ Improvements
|
|||
- Exposed the epsilon value used by Element calculations
|
||||
- Made Image ScaleToImage take ui scale into account
|
||||
- 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
|
||||
- Fixed VerticalSpace height parameter being an integer
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace Demos {
|
|||
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."));
|
||||
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
|
||||
// (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.") {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MLEM.Misc;
|
||||
using MLEM.Textures;
|
||||
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>
|
||||
public Button(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : base(anchor, size) {
|
||||
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);
|
||||
}
|
||||
if (tooltipText != null)
|
||||
|
|
|
@ -32,8 +32,17 @@ namespace MLEM.Ui.Elements {
|
|||
internal set {
|
||||
this.system = value;
|
||||
this.Controls = value?.Controls;
|
||||
if (this.system != null)
|
||||
this.InitStyle(this.system.Style);
|
||||
this.Style = value?.Style;
|
||||
}
|
||||
}
|
||||
public UiStyle Style {
|
||||
get => this.style;
|
||||
set {
|
||||
if (this.style != value) {
|
||||
this.style = value;
|
||||
if (value != null)
|
||||
this.InitStyle(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -109,31 +118,13 @@ namespace MLEM.Ui.Elements {
|
|||
/// </summary>
|
||||
public Vector2 ScaledOffset => this.offset * this.Scale;
|
||||
/// <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.
|
||||
/// </summary>
|
||||
public Padding ScaledPadding => this.Padding * 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();
|
||||
}
|
||||
}
|
||||
public Padding ScaledPadding => this.Padding.Value * this.Scale;
|
||||
/// <summary>
|
||||
/// The <see cref="ChildPadding"/>, but with <see cref="Scale"/> applied.
|
||||
/// </summary>
|
||||
public Padding ScaledChildPadding => this.childPadding * this.Scale;
|
||||
public Padding ScaledChildPadding => this.ChildPadding.Value * this.Scale;
|
||||
/// <summary>
|
||||
/// This element's current <see cref="Area"/>, but with <see cref="ScaledChildPadding"/> applied.
|
||||
/// </summary>
|
||||
|
@ -260,6 +251,7 @@ namespace MLEM.Ui.Elements {
|
|||
/// Stores whether this element is its <see cref="Root"/>'s <see cref="RootElement.SelectedElement"/>.
|
||||
/// </summary>
|
||||
public bool IsSelected { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A style property that contains the selection indicator that is displayed on this element if it is the <see cref="RootElement.SelectedElement"/>
|
||||
/// </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
|
||||
/// </summary>
|
||||
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>
|
||||
/// 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 Vector2 size;
|
||||
private Vector2 offset;
|
||||
private Padding childPadding;
|
||||
private RectangleF area;
|
||||
private bool areaDirty;
|
||||
private bool isHidden;
|
||||
private int priority;
|
||||
private UiStyle style;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new element with the given anchor and size and sets up some default event reactions.
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MLEM.Input;
|
||||
using MLEM.Misc;
|
||||
using MLEM.Textures;
|
||||
|
||||
namespace MLEM.Ui.Elements {
|
||||
|
@ -22,7 +23,8 @@ namespace MLEM.Ui.Elements {
|
|||
/// <returns>An image button</returns>
|
||||
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 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.AddChild(image, 0);
|
||||
return button;
|
||||
|
|
|
@ -71,8 +71,12 @@ namespace MLEM.Ui.Elements {
|
|||
AutoHideWhenEmpty = autoHideScrollbar,
|
||||
IsHidden = autoHideScrollbar
|
||||
};
|
||||
if (autoHideScrollbar)
|
||||
this.ScrollBar.OnAutoHide += e => this.ChildPadding += new Padding(0, this.ScrollerSize.Value.X, 0, 0) * (e.IsHidden ? -1 : 1);
|
||||
if (autoHideScrollbar) {
|
||||
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
|
||||
this.OnSelectedElementChanged += (element, otherElement) => {
|
||||
|
@ -216,8 +220,7 @@ namespace MLEM.Ui.Elements {
|
|||
this.Texture.SetFromStyle(style.PanelTexture);
|
||||
this.StepPerScroll.SetFromStyle(style.PanelStepPerScroll);
|
||||
this.ScrollerSize.SetFromStyle(style.PanelScrollerSize);
|
||||
if (this.ChildPadding == default)
|
||||
this.ChildPadding = style.PanelChildPadding;
|
||||
this.ChildPadding.SetFromStyle(style.PanelChildPadding);
|
||||
this.SetScrollBarStyle();
|
||||
}
|
||||
|
||||
|
@ -235,7 +238,7 @@ namespace MLEM.Ui.Elements {
|
|||
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
|
||||
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
|
||||
var targetArea = (Rectangle) this.GetRenderTargetArea();
|
||||
|
|
|
@ -79,10 +79,9 @@ namespace MLEM.Ui.Elements {
|
|||
this.Texture.SetFromStyle(style.TooltipBackground);
|
||||
this.MouseOffset.SetFromStyle(style.TooltipOffset);
|
||||
this.Delay.SetFromStyle(style.TooltipDelay);
|
||||
this.ChildPadding = style.TooltipChildPadding;
|
||||
this.ChildPadding.SetFromStyle(style.TooltipChildPadding);
|
||||
if (this.Paragraph != null) {
|
||||
// we can't set from style here since it's a different element
|
||||
this.Paragraph.TextColor.Set(style.TooltipTextColor);
|
||||
this.Paragraph.TextColor.SetFromStyle(style.TooltipTextColor, 1);
|
||||
this.Paragraph.Size = new Vector2(style.TooltipTextWidth, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,14 @@ namespace MLEM.Ui.Style {
|
|||
/// The currently applied style
|
||||
/// </summary>
|
||||
public T Value { get; private set; }
|
||||
private bool isCustom;
|
||||
private byte lastSetPriority;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new style property with the given custom style.
|
||||
/// </summary>
|
||||
/// <param name="value">The custom style to apply</param>
|
||||
public StyleProp(T value) {
|
||||
this.isCustom = true;
|
||||
this.lastSetPriority = byte.MaxValue;
|
||||
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"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The style to apply</param>
|
||||
public void SetFromStyle(T value) {
|
||||
if (!this.isCustom)
|
||||
/// <param name="priority">The priority that this style value has. Higher priority style values will override lower priority style values.</param>
|
||||
public void SetFromStyle(T value, byte priority = 0) {
|
||||
if (priority >= this.lastSetPriority) {
|
||||
this.Value = value;
|
||||
this.lastSetPriority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -41,7 +44,7 @@ namespace MLEM.Ui.Style {
|
|||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void Set(T value) {
|
||||
this.isCustom = true;
|
||||
this.lastSetPriority = byte.MaxValue;
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
|
@ -64,7 +67,7 @@ namespace MLEM.Ui.Style {
|
|||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() {
|
||||
return $"{this.Value} (Custom: {this.isCustom})";
|
||||
return this.Value?.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -52,6 +52,14 @@ namespace MLEM.Misc {
|
|||
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>
|
||||
/// Creates a new padding with the specified x and y values, applying them to both edges.
|
||||
/// </summary>
|
||||
|
|
|
@ -224,7 +224,7 @@ namespace Sandbox {
|
|||
var button = loadPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1)) {
|
||||
SetHeightBasedOnChildren = true,
|
||||
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) {
|
||||
CanBeMoused = false
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace Tests {
|
|||
var button = panel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1)) {
|
||||
SetHeightBasedOnChildren = true,
|
||||
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) {
|
||||
CanBeMoused = false
|
||||
|
|
Loading…
Reference in a new issue