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:
parent
f5ff96d348
commit
179afbc428
4 changed files with 130 additions and 15 deletions
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue