From 179afbc428c372c72e903caad4d517fffbea68a3 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 23 Dec 2022 13:25:56 +0100 Subject: [PATCH] made sure that all element changes mark their data dirty correctly --- MLEM.Ui/Elements/Checkbox.cs | 9 ++++- MLEM.Ui/Elements/Element.cs | 66 +++++++++++++++++++++++++++++++---- MLEM.Ui/Elements/Panel.cs | 9 ++++- MLEM.Ui/Elements/Paragraph.cs | 61 ++++++++++++++++++++++++++++---- 4 files changed, 130 insertions(+), 15 deletions(-) diff --git a/MLEM.Ui/Elements/Checkbox.cs b/MLEM.Ui/Elements/Checkbox.cs index 11452b8..1925202 100644 --- a/MLEM.Ui/Elements/Checkbox.cs +++ b/MLEM.Ui/Elements/Checkbox.cs @@ -46,7 +46,13 @@ namespace MLEM.Ui.Elements { /// /// The width of the space between this checkbox and its /// - public StyleProp TextOffsetX; + public StyleProp TextOffsetX { + get => this.textOffsetX; + set { + this.textOffsetX = value; + this.SetAreaDirty(); + } + } /// /// Whether or not this checkbox is currently checked. /// @@ -80,6 +86,7 @@ namespace MLEM.Ui.Elements { public override bool CanBePressed => base.CanBePressed && !this.IsDisabled; private bool isChecked; + private StyleProp textOffsetX; /// /// Creates a new checkbox with the given settings diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index 22a6550..d646d0e 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -233,34 +233,82 @@ namespace MLEM.Ui.Elements { /// /// Set this field to false to cause auto-anchored siblings to ignore this element as a possible anchor point. /// - public virtual bool CanAutoAnchorsAttach { get; set; } = true; + public virtual bool CanAutoAnchorsAttach { + get => this.canAutoAnchorsAttach; + set { + if (this.canAutoAnchorsAttach != value) { + this.canAutoAnchorsAttach = value; + this.SetAreaDirty(); + } + } + } /// /// Set this field to true to cause this element's width to be automatically calculated based on the area that its take up. /// To use this element's 's X coordinate as a minimum or maximum width rather than ignoring it, set or to true. /// - public virtual bool SetWidthBasedOnChildren { get; set; } + public virtual bool SetWidthBasedOnChildren { + get => this.setWidthBasedOnChildren; + set { + if (this.setWidthBasedOnChildren != value) { + this.setWidthBasedOnChildren = value; + this.SetAreaDirty(); + } + } + } /// /// Set this field to true to cause this element's height to be automatically calculated based on the area that its take up. /// To use this element's 's Y coordinate as a minimum or maximum height rather than ignoring it, set or to true. /// - public virtual bool SetHeightBasedOnChildren { get; set; } + public virtual bool SetHeightBasedOnChildren { + get => this.setHeightBasedOnChildren; + set { + if (this.setHeightBasedOnChildren != value) { + this.setHeightBasedOnChildren = value; + this.SetAreaDirty(); + } + } + } /// /// If this field is set to true, and or are enabled, the resulting width or height will always be greather than or equal to this element's . /// For example, if an element's '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 or are enabled. /// - public virtual bool TreatSizeAsMinimum { get; set; } + public virtual bool TreatSizeAsMinimum { + get => this.treatSizeAsMinimum; + set { + if (this.treatSizeAsMinimum != value) { + this.treatSizeAsMinimum = value; + this.SetAreaDirty(); + } + } + } /// /// If this field is set to true, and or are enabled, the resulting width or height weill always be less than or equal to this element's . /// Note that this value only has an effect if or are enabled. /// - public virtual bool TreatSizeAsMaximum { get; set; } + public virtual bool TreatSizeAsMaximum { + get => this.treatSizeAsMaximum; + set { + if (this.treatSizeAsMaximum != value) { + this.treatSizeAsMaximum = value; + this.SetAreaDirty(); + } + } + } /// /// Set this field to true to cause this element's final display area to never exceed that of its . /// 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. /// - public virtual bool PreventParentSpill { get; set; } + public virtual bool PreventParentSpill { + get => this.preventParentSpill; + set { + if (this.preventParentSpill != value) { + this.preventParentSpill = value; + this.SetAreaDirty(); + } + } + } /// /// The transparency (alpha value) that this element is rendered with. /// Note that, when is called, this alpha value is multiplied with the 's alpha value and passed down to this element's . @@ -470,6 +518,12 @@ namespace MLEM.Ui.Elements { private StyleProp style; private StyleProp childPadding; private bool canBeSelected = true; + private bool canAutoAnchorsAttach = true; + private bool setWidthBasedOnChildren; + private bool setHeightBasedOnChildren; + private bool treatSizeAsMinimum; + private bool treatSizeAsMaximum; + private bool preventParentSpill; /// /// Creates a new element with the given anchor and size and sets up some default event reactions. diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index 8605249..48cf938 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -46,7 +46,13 @@ namespace MLEM.Ui.Elements { /// /// The amount of pixels of room there should be between the and the rest of the content /// - public StyleProp ScrollBarOffset; + public StyleProp ScrollBarOffset { + get => this.scrollBarOffset; + set { + this.scrollBarOffset = value; + this.SetAreaDirty(); + } + } private readonly List relevantChildren = new List(); private readonly bool scrollOverflow; @@ -54,6 +60,7 @@ namespace MLEM.Ui.Elements { private RenderTarget2D renderTarget; private bool relevantChildrenDirty; private float scrollBarChildOffset; + private StyleProp scrollBarOffset; /// /// Creates a new panel with the given settings. diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index 88512d4..3f4105c 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -47,12 +47,26 @@ namespace MLEM.Ui.Elements { /// The scale that the text will be rendered with. /// To add a multiplier rather than changing the scale directly, use . /// - public StyleProp TextScale; + public StyleProp TextScale { + get => this.textScale; + set { + this.textScale = value; + this.SetTextDirty(); + } + } /// /// A multiplier that will be applied to . /// To change the text scale itself, use . /// - public float TextScaleMultiplier = 1; + public float TextScaleMultiplier { + get => this.textScaleMultiplier; + set { + if (this.textScaleMultiplier != value) { + this.textScaleMultiplier = value; + this.SetTextDirty(); + } + } + } /// /// The text to render inside of this paragraph. /// Use if the text changes frequently. @@ -67,17 +81,41 @@ namespace MLEM.Ui.Elements { /// /// If this paragraph should automatically adjust its width based on the width of the text within it /// - public bool AutoAdjustWidth; + public bool AutoAdjustWidth { + get => this.autoAdjustWidth; + set { + if (this.autoAdjustWidth != value) { + this.autoAdjustWidth = value; + this.SetAreaDirty(); + } + } + } /// /// Whether this paragraph should be truncated instead of split if the displayed 's width exceeds the provided width. /// When the string is truncated, the is added to its end. /// - public bool TruncateIfLong; + public bool TruncateIfLong { + get => this.truncateIfLong; + set { + if (this.truncateIfLong != value) { + this.truncateIfLong = value; + this.SetAlignSplitDirty(); + } + } + } /// /// The ellipsis characters to use if is enabled and the string is truncated. /// If this is set to an empty string, no ellipsis will be attached to the truncated string. /// - public string Ellipsis = "..."; + public string Ellipsis { + get => this.ellipsis; + set { + if (this.ellipsis != value) { + this.ellipsis = value; + this.SetAlignSplitDirty(); + } + } + } /// /// An event that gets called when this paragraph's is queried. /// 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 StyleProp alignment; private StyleProp regularFont; + private StyleProp textScale; private TokenizedString tokenizedText; private float? lastAlignSplitWidth; private float? lastAlignSplitScale; + private string ellipsis = "..."; + private bool truncateIfLong; + private float textScaleMultiplier = 1; + private bool autoAdjustWidth; /// /// Creates a new paragraph with the given settings. @@ -196,8 +239,7 @@ namespace MLEM.Ui.Elements { // tokenize the text this.tokenizedText = this.System.TextFormatter.Tokenize(this.RegularFont, this.Text, this.Alignment); - this.lastAlignSplitWidth = null; - this.lastAlignSplitScale = null; + this.SetAlignSplitDirty(); // add links to the paragraph this.RemoveChildren(c => c is Link); @@ -221,6 +263,11 @@ namespace MLEM.Ui.Elements { } } + private void SetAlignSplitDirty() { + this.lastAlignSplitWidth = null; + this.lastAlignSplitScale = null; + } + /// /// A delegate method used for ///