mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-23 05:08:34 +01:00
some element code cleanup
This commit is contained in:
parent
85e63ac998
commit
5115bd8ca6
4 changed files with 80 additions and 77 deletions
|
@ -10,6 +10,7 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||||
|
// since the group never accesses its own area when drawing, we have to update it manually
|
||||||
this.UpdateAreaIfDirty();
|
this.UpdateAreaIfDirty();
|
||||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,11 @@ namespace MLEM.Ui.Elements {
|
||||||
private TextureRegion texture;
|
private TextureRegion texture;
|
||||||
public TextureCallback GetTextureCallback;
|
public TextureCallback GetTextureCallback;
|
||||||
public TextureRegion Texture {
|
public TextureRegion Texture {
|
||||||
get => this.texture;
|
get {
|
||||||
|
if (this.GetTextureCallback != null)
|
||||||
|
this.Texture = this.GetTextureCallback(this);
|
||||||
|
return this.texture;
|
||||||
|
}
|
||||||
set {
|
set {
|
||||||
if (this.texture != value) {
|
if (this.texture != value) {
|
||||||
this.texture = value;
|
this.texture = value;
|
||||||
|
@ -53,33 +57,21 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Vector2 CalcActualSize(RectangleF parentArea) {
|
protected override Vector2 CalcActualSize(RectangleF parentArea) {
|
||||||
return this.texture != null && this.scaleToImage ? this.texture.Size.ToVector2() : base.CalcActualSize(parentArea);
|
return this.Texture != null && this.scaleToImage ? this.Texture.Size.ToVector2() : base.CalcActualSize(parentArea);
|
||||||
}
|
|
||||||
|
|
||||||
public override void ForceUpdateArea() {
|
|
||||||
if (this.GetTextureCallback != null)
|
|
||||||
this.Texture = this.GetTextureCallback(this);
|
|
||||||
base.ForceUpdateArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(GameTime time) {
|
|
||||||
base.Update(time);
|
|
||||||
if (this.GetTextureCallback != null)
|
|
||||||
this.Texture = this.GetTextureCallback(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||||
if (this.texture == null)
|
if (this.Texture == null)
|
||||||
return;
|
return;
|
||||||
var center = new Vector2(this.texture.Width / 2F, this.texture.Height / 2F);
|
var center = new Vector2(this.Texture.Width / 2F, this.Texture.Height / 2F);
|
||||||
var color = this.Color.OrDefault(Microsoft.Xna.Framework.Color.White) * alpha;
|
var color = this.Color.OrDefault(Microsoft.Xna.Framework.Color.White) * alpha;
|
||||||
if (this.MaintainImageAspect) {
|
if (this.MaintainImageAspect) {
|
||||||
var scale = Math.Min(this.DisplayArea.Width / this.texture.Width, this.DisplayArea.Height / this.texture.Height);
|
var scale = Math.Min(this.DisplayArea.Width / this.Texture.Width, this.DisplayArea.Height / this.Texture.Height);
|
||||||
var imageOffset = new Vector2(this.DisplayArea.Width / 2F - this.texture.Width * scale / 2, this.DisplayArea.Height / 2F - this.texture.Height * scale / 2);
|
var imageOffset = new Vector2(this.DisplayArea.Width / 2F - this.Texture.Width * scale / 2, this.DisplayArea.Height / 2F - this.Texture.Height * scale / 2);
|
||||||
batch.Draw(this.texture, this.DisplayArea.Location + center * scale + imageOffset, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
|
batch.Draw(this.Texture, this.DisplayArea.Location + center * scale + imageOffset, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
|
||||||
} else {
|
} else {
|
||||||
var scale = new Vector2(1F / this.texture.Width, 1F / this.texture.Height) * this.DisplayArea.Size;
|
var scale = new Vector2(1F / this.Texture.Width, 1F / this.Texture.Height) * this.DisplayArea.Size;
|
||||||
batch.Draw(this.texture, this.DisplayArea.Location + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
|
batch.Draw(this.Texture, this.DisplayArea.Location + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
|
||||||
}
|
}
|
||||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,27 +67,9 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ForceUpdateArea();
|
base.ForceUpdateArea();
|
||||||
|
|
||||||
this.ScrollChildren();
|
this.ScrollChildren();
|
||||||
|
this.ScrollSetup();
|
||||||
if (this.scrollOverflow) {
|
|
||||||
// if there is only one child, then we have just the scroll bar
|
|
||||||
if (this.Children.Count == 1)
|
|
||||||
return;
|
|
||||||
// the "real" first child is the scroll bar, which we want to ignore
|
|
||||||
var firstChild = this.Children[1];
|
|
||||||
var lowestChild = this.GetLowestChild(e => !e.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;
|
|
||||||
|
|
||||||
// update the render target
|
|
||||||
var targetArea = (Rectangle) this.GetRenderTargetArea();
|
|
||||||
if (this.renderTarget == null || targetArea.Width != this.renderTarget.Width || targetArea.Height != this.renderTarget.Height) {
|
|
||||||
if (this.renderTarget != null)
|
|
||||||
this.renderTarget.Dispose();
|
|
||||||
this.renderTarget = targetArea.IsEmpty ? null : new RenderTarget2D(this.System.GraphicsDevice, targetArea.Width, targetArea.Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScrollChildren() {
|
private void ScrollChildren() {
|
||||||
|
@ -183,5 +165,27 @@ namespace MLEM.Ui.Elements {
|
||||||
this.Texture.SetFromStyle(style.PanelTexture);
|
this.Texture.SetFromStyle(style.PanelTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void ScrollSetup() {
|
||||||
|
if (!this.scrollOverflow)
|
||||||
|
return;
|
||||||
|
// if there is only one child, then we have just the scroll bar
|
||||||
|
if (this.Children.Count == 1)
|
||||||
|
return;
|
||||||
|
// the "real" first child is the scroll bar, which we want to ignore
|
||||||
|
var firstChild = this.Children[1];
|
||||||
|
var lowestChild = this.GetLowestChild(e => !e.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;
|
||||||
|
|
||||||
|
// update the render target
|
||||||
|
var targetArea = (Rectangle) this.GetRenderTargetArea();
|
||||||
|
if (this.renderTarget == null || targetArea.Width != this.renderTarget.Width || targetArea.Height != this.renderTarget.Height) {
|
||||||
|
if (this.renderTarget != null)
|
||||||
|
this.renderTarget.Dispose();
|
||||||
|
this.renderTarget = targetArea.IsEmpty ? null : new RenderTarget2D(this.System.GraphicsDevice, targetArea.Width, targetArea.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,13 +33,16 @@ namespace MLEM.Ui.Elements {
|
||||||
public StyleProp<Color> TextColor;
|
public StyleProp<Color> TextColor;
|
||||||
public StyleProp<float> TextScale;
|
public StyleProp<float> TextScale;
|
||||||
public string Text {
|
public string Text {
|
||||||
get => this.text;
|
get {
|
||||||
|
this.QueryTextCallback();
|
||||||
|
return this.text;
|
||||||
|
}
|
||||||
set {
|
set {
|
||||||
if (this.text != value) {
|
if (this.text != value) {
|
||||||
this.text = value;
|
this.text = value;
|
||||||
this.IsHidden = string.IsNullOrWhiteSpace(this.text);
|
this.IsHidden = string.IsNullOrWhiteSpace(this.text);
|
||||||
this.SetAreaDirty();
|
this.SetAreaDirty();
|
||||||
// cause text to be re-tokenized
|
// force text to be re-tokenized
|
||||||
this.TokenizedText = null;
|
this.TokenizedText = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,51 +73,22 @@ namespace MLEM.Ui.Elements {
|
||||||
|
|
||||||
protected override Vector2 CalcActualSize(RectangleF parentArea) {
|
protected override Vector2 CalcActualSize(RectangleF parentArea) {
|
||||||
var size = base.CalcActualSize(parentArea);
|
var size = base.CalcActualSize(parentArea);
|
||||||
var sc = this.TextScale * this.Scale;
|
this.ParseText(size);
|
||||||
|
|
||||||
// old formatting stuff
|
// old formatting stuff
|
||||||
this.splitText = this.RegularFont.Value.SplitString(this.text.RemoveFormatting(this.RegularFont.Value), size.X - this.ScaledPadding.Width, sc);
|
|
||||||
this.Formatting = this.text.GetFormattingCodes(this.RegularFont.Value);
|
|
||||||
if (this.Formatting.Count > 0) {
|
if (this.Formatting.Count > 0) {
|
||||||
var textDims = this.RegularFont.Value.MeasureString(this.splitText) * sc;
|
var textDims = this.RegularFont.Value.MeasureString(this.splitText) * this.TextScale * this.Scale;
|
||||||
return new Vector2(this.AutoAdjustWidth ? textDims.X + this.ScaledPadding.Width : size.X, textDims.Y + this.ScaledPadding.Height);
|
return new Vector2(this.AutoAdjustWidth ? textDims.X + this.ScaledPadding.Width : size.X, textDims.Y + this.ScaledPadding.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.TokenizedText.Split(this.RegularFont, size.X - this.ScaledPadding.Width, sc);
|
var dims = this.TokenizedText.Measure(this.RegularFont) * this.TextScale * this.Scale;
|
||||||
var linkTokens = this.TokenizedText.Tokens.Where(t => t.AppliedCodes.Any(c => c is LinkCode)).ToArray();
|
|
||||||
// this basically checks if there are any tokens that have an area that doesn't have a link element associated with it
|
|
||||||
if (linkTokens.Any(t => !t.GetArea(Vector2.Zero, this.TextScale).All(a => this.GetChildren<Link>(c => c.PositionOffset == a.Location && c.Size == a.Size).Any()))) {
|
|
||||||
this.RemoveChildren(c => c is Link);
|
|
||||||
foreach (var link in linkTokens) {
|
|
||||||
var areas = link.GetArea(Vector2.Zero, this.TextScale).ToArray();
|
|
||||||
for (var i = 0; i < areas.Length; i++) {
|
|
||||||
var area = areas[i];
|
|
||||||
this.AddChild(new Link(Anchor.TopLeft, link, area.Size) {
|
|
||||||
PositionOffset = area.Location,
|
|
||||||
// only allow selecting the first part of a link
|
|
||||||
CanBeSelected = i == 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var dims = this.TokenizedText.Measure(this.RegularFont) * sc;
|
|
||||||
return new Vector2(this.AutoAdjustWidth ? dims.X + this.ScaledPadding.Width : size.X, dims.Y + this.ScaledPadding.Height);
|
return new Vector2(this.AutoAdjustWidth ? dims.X + this.ScaledPadding.Width : size.X, dims.Y + this.ScaledPadding.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ForceUpdateArea() {
|
|
||||||
if (this.GetTextCallback != null)
|
|
||||||
this.Text = this.GetTextCallback(this);
|
|
||||||
|
|
||||||
if (this.TokenizedText == null)
|
|
||||||
this.TokenizedText = this.System.TextFormatter.Tokenize(this.RegularFont, this.text);
|
|
||||||
base.ForceUpdateArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(GameTime time) {
|
public override void Update(GameTime time) {
|
||||||
|
this.QueryTextCallback();
|
||||||
base.Update(time);
|
base.Update(time);
|
||||||
if (this.GetTextCallback != null)
|
|
||||||
this.Text = this.GetTextCallback(this);
|
|
||||||
this.TimeIntoAnimation += time.ElapsedGameTime;
|
this.TimeIntoAnimation += time.ElapsedGameTime;
|
||||||
|
|
||||||
if (this.TokenizedText != null)
|
if (this.TokenizedText != null)
|
||||||
|
@ -145,6 +119,38 @@ namespace MLEM.Ui.Elements {
|
||||||
this.FormatSettings.SetFromStyle(style.FormatSettings);
|
this.FormatSettings.SetFromStyle(style.FormatSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void ParseText(Vector2 size) {
|
||||||
|
// old formatting stuff
|
||||||
|
this.splitText = this.RegularFont.Value.SplitString(this.Text.RemoveFormatting(this.RegularFont.Value), size.X - this.ScaledPadding.Width, this.TextScale * this.Scale);
|
||||||
|
this.Formatting = this.Text.GetFormattingCodes(this.RegularFont.Value);
|
||||||
|
|
||||||
|
if (this.TokenizedText == null)
|
||||||
|
this.TokenizedText = this.System.TextFormatter.Tokenize(this.RegularFont, this.Text);
|
||||||
|
|
||||||
|
this.TokenizedText.Split(this.RegularFont, size.X - this.ScaledPadding.Width, this.TextScale * this.Scale);
|
||||||
|
var linkTokens = this.TokenizedText.Tokens.Where(t => t.AppliedCodes.Any(c => c is LinkCode)).ToArray();
|
||||||
|
// this basically checks if there are any tokens that have an area that doesn't have a link element associated with it
|
||||||
|
if (linkTokens.Any(t => !t.GetArea(Vector2.Zero, this.TextScale).All(a => this.GetChildren<Link>(c => c.PositionOffset == a.Location && c.Size == a.Size).Any()))) {
|
||||||
|
this.RemoveChildren(c => c is Link);
|
||||||
|
foreach (var link in linkTokens) {
|
||||||
|
var areas = link.GetArea(Vector2.Zero, this.TextScale).ToArray();
|
||||||
|
for (var i = 0; i < areas.Length; i++) {
|
||||||
|
var area = areas[i];
|
||||||
|
this.AddChild(new Link(Anchor.TopLeft, link, area.Size) {
|
||||||
|
PositionOffset = area.Location,
|
||||||
|
// only allow selecting the first part of a link
|
||||||
|
CanBeSelected = i == 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void QueryTextCallback() {
|
||||||
|
if (this.GetTextCallback != null)
|
||||||
|
this.Text = this.GetTextCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
public delegate string TextCallback(Paragraph paragraph);
|
public delegate string TextCallback(Paragraph paragraph);
|
||||||
|
|
||||||
[Obsolete("Use the new text formatting system in MLEM.Formatting instead")]
|
[Obsolete("Use the new text formatting system in MLEM.Formatting instead")]
|
||||||
|
|
Loading…
Reference in a new issue