1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-25 05:58:35 +01:00

Compare commits

..

4 commits

7 changed files with 53 additions and 21 deletions

View file

@ -22,15 +22,23 @@ Fixes
- Fixed StaticSpriteBatch handling rotated sprites incorrectly - Fixed StaticSpriteBatch handling rotated sprites incorrectly
### MLEM.Ui ### MLEM.Ui
Additions
- Added Element.OnStyleInit event
Improvements Improvements
- Allow for checkboxes and radio buttons to be disabled - Allow for checkboxes and radio buttons to be disabled
- Only set a paragraph's area dirty when a text change would cause it to change size - Only set a paragraph's area dirty when a text change would cause it to change size
- Ensure that a panel gets notified of all relevant changes by calling OnChildAreaDirty for all grandchildren - Ensure that a panel gets notified of all relevant changes by calling OnChildAreaDirty for all grandchildren
- Avoid unnecessary panel updates by using an Epsilon comparison when scrolling children - Avoid unnecessary panel updates by using an Epsilon comparison when scrolling children
- Allow setting a default text alignment for paragraphs in UiStyle
- Made custom values of Element.Style persist when a new ui style is set
Fixes Fixes
- Fixed paragraph links having incorrect hover locations when using special text alignments - Fixed paragraph links having incorrect hover locations when using special text alignments
Removals
- Marked StyleProp equality members as obsolete
### MLEM.Extended ### MLEM.Extended
Improvements Improvements
- Preserve texture region names when converting between MLEM and MG.Extended - Preserve texture region names when converting between MLEM and MG.Extended

View file

@ -81,7 +81,7 @@ namespace Demos {
this.root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 10), "Change Style") { this.root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 10), "Change Style") {
OnPressed = element => this.UiSystem.Style = this.UiSystem.Style == untexturedStyle ? style : untexturedStyle, OnPressed = element => this.UiSystem.Style = this.UiSystem.Style == untexturedStyle ? style : untexturedStyle,
PositionOffset = new Vector2(0, 1), PositionOffset = new Vector2(0, 1),
Texture = this.testPatch Style = untexturedStyle
}); });
this.root.AddChild(new VerticalSpace(3)); this.root.AddChild(new VerticalSpace(3));

View file

@ -32,22 +32,7 @@ namespace MLEM.Ui.Elements {
internal set { internal set {
this.system = value; this.system = value;
this.Controls = value?.Controls; this.Controls = value?.Controls;
this.Style = value?.Style; this.Style = this.Style.OrStyle(value?.Style);
}
}
/// <summary>
/// This Element's current <see cref="UiStyle"/>.
/// When this value is changed, <see cref="InitStyle"/> is called.
/// Note that this value is automatically set to the <see cref="UiSystem"/>'s ui style when it is changed.
/// </summary>
public UiStyle Style {
get => this.style;
set {
if (this.style != value) {
this.style = value;
if (value != null)
this.InitStyle(value);
}
} }
} }
/// <summary> /// <summary>
@ -261,6 +246,18 @@ namespace MLEM.Ui.Elements {
/// </summary> /// </summary>
public bool AreaDirty { get; private set; } public bool AreaDirty { get; private set; }
/// <summary>
/// This Element's current <see cref="UiStyle"/>.
/// When this property is set, <see cref="InitStyle"/> is called.
/// </summary>
public StyleProp<UiStyle> Style {
get => this.style;
set {
this.style = value;
if (this.style.HasValue())
this.InitStyle(this.style);
}
}
/// <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>
@ -342,6 +339,10 @@ namespace MLEM.Ui.Elements {
/// </summary> /// </summary>
public GenericCallback OnAreaUpdated; public GenericCallback OnAreaUpdated;
/// <summary> /// <summary>
/// Event that is called when this element's <see cref="InitStyle"/> method is called while setting the <see cref="Style"/>.
/// </summary>
public GenericCallback OnStyleInit;
/// <summary>
/// Event that is called when the element that is currently being moused changes within the ui system. /// 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. /// Note that the event fired doesn't necessarily correlate to this specific element.
/// </summary> /// </summary>
@ -414,7 +415,7 @@ namespace MLEM.Ui.Elements {
private RectangleF area; private RectangleF area;
private bool isHidden; private bool isHidden;
private int priority; private int priority;
private UiStyle style; private StyleProp<UiStyle> style;
private StyleProp<Padding> childPadding; private StyleProp<Padding> childPadding;
/// <summary> /// <summary>
@ -1058,6 +1059,8 @@ namespace MLEM.Ui.Elements {
this.SelectionIndicator = this.SelectionIndicator.OrStyle(style.SelectionIndicator); this.SelectionIndicator = this.SelectionIndicator.OrStyle(style.SelectionIndicator);
this.ActionSound = this.ActionSound.OrStyle(style.ActionSound); this.ActionSound = this.ActionSound.OrStyle(style.ActionSound);
this.SecondActionSound = this.SecondActionSound.OrStyle(style.ActionSound); this.SecondActionSound = this.SecondActionSound.OrStyle(style.ActionSound);
this.System?.InvokeOnElementStyleInit(this);
} }
/// <summary> /// <summary>

View file

@ -90,7 +90,7 @@ namespace MLEM.Ui.Elements {
/// <summary> /// <summary>
/// The <see cref="TextAlignment"/> that this paragraph's text should be rendered with /// The <see cref="TextAlignment"/> that this paragraph's text should be rendered with
/// </summary> /// </summary>
public TextAlignment Alignment { public StyleProp<TextAlignment> Alignment {
get => this.alignment; get => this.alignment;
set { set {
this.alignment = value; this.alignment = value;
@ -99,7 +99,7 @@ namespace MLEM.Ui.Elements {
} }
private string text; private string text;
private TextAlignment alignment; private StyleProp<TextAlignment> alignment;
private StyleProp<GenericFont> regularFont; private StyleProp<GenericFont> regularFont;
/// <summary> /// <summary>
@ -158,6 +158,7 @@ namespace MLEM.Ui.Elements {
this.RegularFont = this.RegularFont.OrStyle(style.Font ?? throw new NotSupportedException("Paragraphs cannot use ui styles that don't have a font. Please supply a custom font by setting UiStyle.Font.")); this.RegularFont = this.RegularFont.OrStyle(style.Font ?? throw new NotSupportedException("Paragraphs cannot use ui styles that don't have a font. Please supply a custom font by setting UiStyle.Font."));
this.TextScale = this.TextScale.OrStyle(style.TextScale); this.TextScale = this.TextScale.OrStyle(style.TextScale);
this.TextColor = this.TextColor.OrStyle(style.TextColor); this.TextColor = this.TextColor.OrStyle(style.TextColor);
this.Alignment = this.Alignment.OrStyle(style.TextAlignment);
} }
/// <summary> /// <summary>
@ -202,7 +203,7 @@ namespace MLEM.Ui.Elements {
} }
private float GetAlignmentOffset() { private float GetAlignmentOffset() {
switch (this.Alignment) { switch (this.Alignment.Value) {
case TextAlignment.Center: case TextAlignment.Center:
return this.DisplayArea.Width / 2; return this.DisplayArea.Width / 2;
case TextAlignment.Right: case TextAlignment.Right:

View file

@ -75,6 +75,7 @@ namespace MLEM.Ui.Style {
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary> /// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param> /// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other">other</paramref> parameter; otherwise, false.</returns> /// <returns>true if the current object is equal to the <paramref name="other">other</paramref> parameter; otherwise, false.</returns>
[Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")]
public bool Equals(StyleProp<T> other) { public bool Equals(StyleProp<T> other) {
return EqualityComparer<T>.Default.Equals(this.Value, other.Value); return EqualityComparer<T>.Default.Equals(this.Value, other.Value);
} }
@ -82,12 +83,14 @@ namespace MLEM.Ui.Style {
/// <summary>Indicates whether this instance and a specified object are equal.</summary> /// <summary>Indicates whether this instance and a specified object are equal.</summary>
/// <param name="obj">The object to compare with the current instance.</param> /// <param name="obj">The object to compare with the current instance.</param>
/// <returns>true if <paramref name="obj">obj</paramref> and this instance are the same type and represent the same value; otherwise, false.</returns> /// <returns>true if <paramref name="obj">obj</paramref> and this instance are the same type and represent the same value; otherwise, false.</returns>
[Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")]
public override bool Equals(object obj) { public override bool Equals(object obj) {
return obj is StyleProp<T> other && this.Equals(other); return obj is StyleProp<T> other && this.Equals(other);
} }
/// <summary>Returns the hash code for this instance.</summary> /// <summary>Returns the hash code for this instance.</summary>
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns> /// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
[Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")]
public override int GetHashCode() { public override int GetHashCode() {
return EqualityComparer<T>.Default.GetHashCode(this.Value); return EqualityComparer<T>.Default.GetHashCode(this.Value);
} }
@ -122,6 +125,7 @@ namespace MLEM.Ui.Style {
/// <param name="left">The left style property.</param> /// <param name="left">The left style property.</param>
/// <param name="right">The right style property.</param> /// <param name="right">The right style property.</param>
/// <returns>Whether the two style properties are equal.</returns> /// <returns>Whether the two style properties are equal.</returns>
[Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")]
public static bool operator ==(StyleProp<T> left, StyleProp<T> right) { public static bool operator ==(StyleProp<T> left, StyleProp<T> right) {
return left.Equals(right); return left.Equals(right);
} }
@ -132,6 +136,7 @@ namespace MLEM.Ui.Style {
/// <param name="left">The left style property.</param> /// <param name="left">The left style property.</param>
/// <param name="right">The right style property.</param> /// <param name="right">The right style property.</param>
/// <returns>Whether the two style properties are not equal.</returns> /// <returns>Whether the two style properties are not equal.</returns>
[Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")]
public static bool operator !=(StyleProp<T> left, StyleProp<T> right) { public static bool operator !=(StyleProp<T> left, StyleProp<T> right) {
return !left.Equals(right); return !left.Equals(right);
} }

View file

@ -199,6 +199,10 @@ namespace MLEM.Ui.Style {
/// </summary> /// </summary>
public Color TextColor = Color.White; public Color TextColor = Color.White;
/// <summary> /// <summary>
/// The <see cref="TextAlignment"/> that a <see cref="Paragraph"/> should use by default.
/// </summary>
public TextAlignment TextAlignment;
/// <summary>
/// The <see cref="SoundEffectInfo"/> that should be played when an element's <see cref="Element.OnPressed"/> and <see cref="Element.OnSecondaryPressed"/> events are called. /// The <see cref="SoundEffectInfo"/> that should be played when an element's <see cref="Element.OnPressed"/> and <see cref="Element.OnSecondaryPressed"/> events are called.
/// Note that this sound is only played if the callbacks have any subscribers. /// Note that this sound is only played if the callbacks have any subscribers.
/// </summary> /// </summary>

View file

@ -153,6 +153,10 @@ namespace MLEM.Ui {
/// </summary> /// </summary>
public event Element.GenericCallback OnElementAreaUpdated; public event Element.GenericCallback OnElementAreaUpdated;
/// <summary> /// <summary>
/// Event that is called when an <see cref="Element"/>'s <see cref="Element.InitStyle"/> method is called while setting its <see cref="Element.Style"/>.
/// </summary>
public event Element.GenericCallback OnElementStyleInit;
/// <summary>
/// Event that is invoked when the <see cref="Element"/> that the mouse is currently over changes /// Event that is invoked when the <see cref="Element"/> that the mouse is currently over changes
/// </summary> /// </summary>
public event Element.GenericCallback OnMousedElementChanged; public event Element.GenericCallback OnMousedElementChanged;
@ -190,6 +194,7 @@ namespace MLEM.Ui {
public UiSystem(Game game, UiStyle style, InputHandler inputHandler = null, bool automaticViewport = true) : base(game) { public UiSystem(Game game, UiStyle style, InputHandler inputHandler = null, bool automaticViewport = true) : base(game) {
this.Controls = new UiControls(this, inputHandler); this.Controls = new UiControls(this, inputHandler);
this.style = style; this.style = style;
this.OnElementDrawn += (e, time, batch, alpha) => e.OnDrawn?.Invoke(e, time, batch, alpha); this.OnElementDrawn += (e, time, batch, alpha) => e.OnDrawn?.Invoke(e, time, batch, alpha);
this.OnElementUpdated += (e, time) => e.OnUpdated?.Invoke(e, time); this.OnElementUpdated += (e, time) => e.OnUpdated?.Invoke(e, time);
this.OnElementPressed += e => e.OnPressed?.Invoke(e); this.OnElementPressed += e => e.OnPressed?.Invoke(e);
@ -201,6 +206,7 @@ namespace MLEM.Ui {
this.OnElementTouchEnter += e => e.OnTouchEnter?.Invoke(e); this.OnElementTouchEnter += e => e.OnTouchEnter?.Invoke(e);
this.OnElementTouchExit += e => e.OnTouchExit?.Invoke(e); this.OnElementTouchExit += e => e.OnTouchExit?.Invoke(e);
this.OnElementAreaUpdated += e => e.OnAreaUpdated?.Invoke(e); this.OnElementAreaUpdated += e => e.OnAreaUpdated?.Invoke(e);
this.OnElementStyleInit += e => e.OnStyleInit?.Invoke(e);
this.OnMousedElementChanged += e => this.ApplyToAll(t => t.OnMousedElementChanged?.Invoke(t, e)); this.OnMousedElementChanged += e => this.ApplyToAll(t => t.OnMousedElementChanged?.Invoke(t, e));
this.OnTouchedElementChanged += e => this.ApplyToAll(t => t.OnTouchedElementChanged?.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)); this.OnSelectedElementChanged += e => this.ApplyToAll(t => t.OnSelectedElementChanged?.Invoke(t, e));
@ -216,6 +222,7 @@ namespace MLEM.Ui {
if (e.OnSecondaryPressed != null) if (e.OnSecondaryPressed != null)
e.SecondActionSound.Value?.Play(); e.SecondActionSound.Value?.Play();
}; };
MlemPlatform.Current?.AddTextInputListener(game.Window, (sender, key, character) => this.ApplyToAll(e => e.OnTextInput?.Invoke(e, key, character))); MlemPlatform.Current?.AddTextInputListener(game.Window, (sender, key, character) => this.ApplyToAll(e => e.OnTextInput?.Invoke(e, key, character)));
if (automaticViewport) { if (automaticViewport) {
@ -396,6 +403,10 @@ namespace MLEM.Ui {
this.OnElementAreaUpdated?.Invoke(element); this.OnElementAreaUpdated?.Invoke(element);
} }
internal void InvokeOnElementStyleInit(Element element) {
this.OnElementStyleInit?.Invoke(element);
}
internal void InvokeOnElementPressed(Element element) { internal void InvokeOnElementPressed(Element element) {
this.OnElementPressed?.Invoke(element); this.OnElementPressed?.Invoke(element);
} }