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

made sure that all element changes mark their data dirty correctly

This commit is contained in:
Ell 2022-12-23 13:25:56 +01:00
parent f5ff96d348
commit 179afbc428
4 changed files with 130 additions and 15 deletions

View file

@ -46,7 +46,13 @@ namespace MLEM.Ui.Elements {
/// <summary> /// <summary>
/// The width of the space between this checkbox and its <see cref="Label"/> /// The width of the space between this checkbox and its <see cref="Label"/>
/// </summary> /// </summary>
public StyleProp<float> TextOffsetX; public StyleProp<float> TextOffsetX {
get => this.textOffsetX;
set {
this.textOffsetX = value;
this.SetAreaDirty();
}
}
/// <summary> /// <summary>
/// Whether or not this checkbox is currently checked. /// Whether or not this checkbox is currently checked.
/// </summary> /// </summary>
@ -80,6 +86,7 @@ namespace MLEM.Ui.Elements {
public override bool CanBePressed => base.CanBePressed && !this.IsDisabled; public override bool CanBePressed => base.CanBePressed && !this.IsDisabled;
private bool isChecked; private bool isChecked;
private StyleProp<float> textOffsetX;
/// <summary> /// <summary>
/// Creates a new checkbox with the given settings /// Creates a new checkbox with the given settings

View file

@ -233,34 +233,82 @@ namespace MLEM.Ui.Elements {
/// <summary> /// <summary>
/// Set this field to false to cause auto-anchored siblings to ignore this element as a possible anchor point. /// Set this field to false to cause auto-anchored siblings to ignore this element as a possible anchor point.
/// </summary> /// </summary>
public virtual bool CanAutoAnchorsAttach { get; set; } = true; public virtual bool CanAutoAnchorsAttach {
get => this.canAutoAnchorsAttach;
set {
if (this.canAutoAnchorsAttach != value) {
this.canAutoAnchorsAttach = value;
this.SetAreaDirty();
}
}
}
/// <summary> /// <summary>
/// Set this field to true to cause this element's width to be automatically calculated based on the area that its <see cref="Children"/> take up. /// Set this field to true to cause this element's width to be automatically calculated based on the area that its <see cref="Children"/> take up.
/// To use this element's <see cref="Size"/>'s X coordinate as a minimum or maximum width rather than ignoring it, set <see cref="TreatSizeAsMinimum"/> or <see cref="TreatSizeAsMaximum"/> to true. /// To use this element's <see cref="Size"/>'s X coordinate as a minimum or maximum width rather than ignoring it, set <see cref="TreatSizeAsMinimum"/> or <see cref="TreatSizeAsMaximum"/> to true.
/// </summary> /// </summary>
public virtual bool SetWidthBasedOnChildren { get; set; } public virtual bool SetWidthBasedOnChildren {
get => this.setWidthBasedOnChildren;
set {
if (this.setWidthBasedOnChildren != value) {
this.setWidthBasedOnChildren = value;
this.SetAreaDirty();
}
}
}
/// <summary> /// <summary>
/// Set this field to true to cause this element's height to be automatically calculated based on the area that its <see cref="Children"/> take up. /// Set this field to true to cause this element's height to be automatically calculated based on the area that its <see cref="Children"/> take up.
/// To use this element's <see cref="Size"/>'s Y coordinate as a minimum or maximum height rather than ignoring it, set <see cref="TreatSizeAsMinimum"/> or <see cref="TreatSizeAsMaximum"/> to true. /// To use this element's <see cref="Size"/>'s Y coordinate as a minimum or maximum height rather than ignoring it, set <see cref="TreatSizeAsMinimum"/> or <see cref="TreatSizeAsMaximum"/> to true.
/// </summary> /// </summary>
public virtual bool SetHeightBasedOnChildren { get; set; } public virtual bool SetHeightBasedOnChildren {
get => this.setHeightBasedOnChildren;
set {
if (this.setHeightBasedOnChildren != value) {
this.setHeightBasedOnChildren = value;
this.SetAreaDirty();
}
}
}
/// <summary> /// <summary>
/// If this field is set to true, and <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/> are enabled, the resulting width or height will always be greather than or equal to this element's <see cref="Size"/>. /// If this field is set to true, and <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/> are enabled, the resulting width or height will always be greather than or equal to this element's <see cref="Size"/>.
/// For example, if an element's <see cref="Size"/>'s Y coordinate is set to 20, but there is only one child with a height of 10 in it, the element's height would be shrunk to 10 if this value was false, but would remain at 20 if it was true. /// For example, if an element's <see cref="Size"/>'s Y coordinate is set to 20, but there is only one child with a height of 10 in it, the element's height would be shrunk to 10 if this value was false, but would remain at 20 if it was true.
/// Note that this value only has an effect if <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/> are enabled. /// Note that this value only has an effect if <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/> are enabled.
/// </summary> /// </summary>
public virtual bool TreatSizeAsMinimum { get; set; } public virtual bool TreatSizeAsMinimum {
get => this.treatSizeAsMinimum;
set {
if (this.treatSizeAsMinimum != value) {
this.treatSizeAsMinimum = value;
this.SetAreaDirty();
}
}
}
/// <summary> /// <summary>
/// If this field is set to true, and <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/>are enabled, the resulting width or height weill always be less than or equal to this element's <see cref="Size"/>. /// If this field is set to true, and <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/>are enabled, the resulting width or height weill always be less than or equal to this element's <see cref="Size"/>.
/// Note that this value only has an effect if <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/> are enabled. /// Note that this value only has an effect if <see cref="SetWidthBasedOnChildren"/> or <see cref="SetHeightBasedOnChildren"/> are enabled.
/// </summary> /// </summary>
public virtual bool TreatSizeAsMaximum { get; set; } public virtual bool TreatSizeAsMaximum {
get => this.treatSizeAsMaximum;
set {
if (this.treatSizeAsMaximum != value) {
this.treatSizeAsMaximum = value;
this.SetAreaDirty();
}
}
}
/// <summary> /// <summary>
/// Set this field to true to cause this element's final display area to never exceed that of its <see cref="Parent"/>. /// 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. /// 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. /// This can be useful if an element should fill the remaining area of a parent exactly.
/// </summary> /// </summary>
public virtual bool PreventParentSpill { get; set; } public virtual bool PreventParentSpill {
get => this.preventParentSpill;
set {
if (this.preventParentSpill != value) {
this.preventParentSpill = value;
this.SetAreaDirty();
}
}
}
/// <summary> /// <summary>
/// The transparency (alpha value) that this element is rendered with. /// The transparency (alpha value) that this element is rendered with.
/// Note that, when <see cref="Draw(Microsoft.Xna.Framework.GameTime,Microsoft.Xna.Framework.Graphics.SpriteBatch,float,MLEM.Graphics.SpriteBatchContext)"/> 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"/>. /// Note that, when <see cref="Draw(Microsoft.Xna.Framework.GameTime,Microsoft.Xna.Framework.Graphics.SpriteBatch,float,MLEM.Graphics.SpriteBatchContext)"/> 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"/>.
@ -470,6 +518,12 @@ namespace MLEM.Ui.Elements {
private StyleProp<UiStyle> style; private StyleProp<UiStyle> style;
private StyleProp<Padding> childPadding; private StyleProp<Padding> childPadding;
private bool canBeSelected = true; private bool canBeSelected = true;
private bool canAutoAnchorsAttach = true;
private bool setWidthBasedOnChildren;
private bool setHeightBasedOnChildren;
private bool treatSizeAsMinimum;
private bool treatSizeAsMaximum;
private bool preventParentSpill;
/// <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

@ -46,7 +46,13 @@ namespace MLEM.Ui.Elements {
/// <summary> /// <summary>
/// The amount of pixels of room there should be between the <see cref="ScrollBar"/> and the rest of the content /// The amount of pixels of room there should be between the <see cref="ScrollBar"/> and the rest of the content
/// </summary> /// </summary>
public StyleProp<float> ScrollBarOffset; public StyleProp<float> ScrollBarOffset {
get => this.scrollBarOffset;
set {
this.scrollBarOffset = value;
this.SetAreaDirty();
}
}
private readonly List<Element> relevantChildren = new List<Element>(); private readonly List<Element> relevantChildren = new List<Element>();
private readonly bool scrollOverflow; private readonly bool scrollOverflow;
@ -54,6 +60,7 @@ namespace MLEM.Ui.Elements {
private RenderTarget2D renderTarget; private RenderTarget2D renderTarget;
private bool relevantChildrenDirty; private bool relevantChildrenDirty;
private float scrollBarChildOffset; private float scrollBarChildOffset;
private StyleProp<float> scrollBarOffset;
/// <summary> /// <summary>
/// Creates a new panel with the given settings. /// Creates a new panel with the given settings.

View file

@ -47,12 +47,26 @@ namespace MLEM.Ui.Elements {
/// The scale that the text will be rendered with. /// The scale that the text will be rendered with.
/// To add a multiplier rather than changing the scale directly, use <see cref="TextScaleMultiplier"/>. /// To add a multiplier rather than changing the scale directly, use <see cref="TextScaleMultiplier"/>.
/// </summary> /// </summary>
public StyleProp<float> TextScale; public StyleProp<float> TextScale {
get => this.textScale;
set {
this.textScale = value;
this.SetTextDirty();
}
}
/// <summary> /// <summary>
/// A multiplier that will be applied to <see cref="TextScale"/>. /// A multiplier that will be applied to <see cref="TextScale"/>.
/// To change the text scale itself, use <see cref="TextScale"/>. /// To change the text scale itself, use <see cref="TextScale"/>.
/// </summary> /// </summary>
public float TextScaleMultiplier = 1; public float TextScaleMultiplier {
get => this.textScaleMultiplier;
set {
if (this.textScaleMultiplier != value) {
this.textScaleMultiplier = value;
this.SetTextDirty();
}
}
}
/// <summary> /// <summary>
/// The text to render inside of this paragraph. /// The text to render inside of this paragraph.
/// Use <see cref="GetTextCallback"/> if the text changes frequently. /// Use <see cref="GetTextCallback"/> if the text changes frequently.
@ -67,17 +81,41 @@ namespace MLEM.Ui.Elements {
/// <summary> /// <summary>
/// If this paragraph should automatically adjust its width based on the width of the text within it /// If this paragraph should automatically adjust its width based on the width of the text within it
/// </summary> /// </summary>
public bool AutoAdjustWidth; public bool AutoAdjustWidth {
get => this.autoAdjustWidth;
set {
if (this.autoAdjustWidth != value) {
this.autoAdjustWidth = value;
this.SetAreaDirty();
}
}
}
/// <summary> /// <summary>
/// Whether this paragraph should be truncated instead of split if the displayed <see cref="Text"/>'s width exceeds the provided width. /// Whether this paragraph should be truncated instead of split if the displayed <see cref="Text"/>'s width exceeds the provided width.
/// When the string is truncated, the <see cref="Ellipsis"/> is added to its end. /// When the string is truncated, the <see cref="Ellipsis"/> is added to its end.
/// </summary> /// </summary>
public bool TruncateIfLong; public bool TruncateIfLong {
get => this.truncateIfLong;
set {
if (this.truncateIfLong != value) {
this.truncateIfLong = value;
this.SetAlignSplitDirty();
}
}
}
/// <summary> /// <summary>
/// The ellipsis characters to use if <see cref="TruncateIfLong"/> is enabled and the string is truncated. /// The ellipsis characters to use if <see cref="TruncateIfLong"/> is enabled and the string is truncated.
/// If this is set to an empty string, no ellipsis will be attached to the truncated string. /// If this is set to an empty string, no ellipsis will be attached to the truncated string.
/// </summary> /// </summary>
public string Ellipsis = "..."; public string Ellipsis {
get => this.ellipsis;
set {
if (this.ellipsis != value) {
this.ellipsis = value;
this.SetAlignSplitDirty();
}
}
}
/// <summary> /// <summary>
/// An event that gets called when this paragraph's <see cref="Text"/> is queried. /// An event that gets called when this paragraph's <see cref="Text"/> is queried.
/// Use this event for setting this paragraph's text if it changes frequently. /// Use this event for setting this paragraph's text if it changes frequently.
@ -106,9 +144,14 @@ namespace MLEM.Ui.Elements {
private string explicitlySetText; private string explicitlySetText;
private StyleProp<TextAlignment> alignment; private StyleProp<TextAlignment> alignment;
private StyleProp<GenericFont> regularFont; private StyleProp<GenericFont> regularFont;
private StyleProp<float> textScale;
private TokenizedString tokenizedText; private TokenizedString tokenizedText;
private float? lastAlignSplitWidth; private float? lastAlignSplitWidth;
private float? lastAlignSplitScale; private float? lastAlignSplitScale;
private string ellipsis = "...";
private bool truncateIfLong;
private float textScaleMultiplier = 1;
private bool autoAdjustWidth;
/// <summary> /// <summary>
/// Creates a new paragraph with the given settings. /// Creates a new paragraph with the given settings.
@ -196,8 +239,7 @@ namespace MLEM.Ui.Elements {
// tokenize the text // tokenize the text
this.tokenizedText = this.System.TextFormatter.Tokenize(this.RegularFont, this.Text, this.Alignment); this.tokenizedText = this.System.TextFormatter.Tokenize(this.RegularFont, this.Text, this.Alignment);
this.lastAlignSplitWidth = null; this.SetAlignSplitDirty();
this.lastAlignSplitScale = null;
// add links to the paragraph // add links to the paragraph
this.RemoveChildren(c => c is Link); this.RemoveChildren(c => c is Link);
@ -221,6 +263,11 @@ namespace MLEM.Ui.Elements {
} }
} }
private void SetAlignSplitDirty() {
this.lastAlignSplitWidth = null;
this.lastAlignSplitScale = null;
}
/// <summary> /// <summary>
/// A delegate method used for <see cref="Paragraph.GetTextCallback"/> /// A delegate method used for <see cref="Paragraph.GetTextCallback"/>
/// </summary> /// </summary>