1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-08 07:43:37 +02:00

made ui styling a lot more user friendly

This commit is contained in:
Ellpeck 2019-10-14 21:28:12 +02:00
parent 7392aa40fe
commit ee35509f23
17 changed files with 137 additions and 120 deletions

View file

@ -44,11 +44,11 @@ namespace AndroidDemos
public partial class Drawable public partial class Drawable
{ {
// aapt resource value: 0x7f020000 // aapt resource value: 0x7F010000
public const int Icon = 2130837504; public const int Icon = 2130771968;
// aapt resource value: 0x7f020001 // aapt resource value: 0x7F010001
public const int Splash = 2130837505; public const int Splash = 2130771969;
static Drawable() static Drawable()
{ {
@ -63,11 +63,11 @@ namespace AndroidDemos
public partial class String public partial class String
{ {
// aapt resource value: 0x7f030001 // aapt resource value: 0x7F020000
public const int ApplicationName = 2130903041; public const int ApplicationName = 2130837504;
// aapt resource value: 0x7f030000 // aapt resource value: 0x7F020001
public const int Hello = 2130903040; public const int Hello = 2130837505;
static String() static String()
{ {
@ -82,8 +82,8 @@ namespace AndroidDemos
public partial class Style public partial class Style
{ {
// aapt resource value: 0x7f040000 // aapt resource value: 0x7F030000
public const int Theme_Splash = 2130968576; public const int Theme_Splash = 2130903040;
static Style() static Style()
{ {

View file

@ -81,16 +81,11 @@ namespace Demos {
root.AddChild(new VerticalSpace(3)); root.AddChild(new VerticalSpace(3));
root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "Note that the default style does not contain any textures or font files and, as such, is quite bland. However, the default style is quite easy to override.")); root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "Note that the default style does not contain any textures or font files and, as such, is quite bland. However, the default style is quite easy to override."));
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 10), "Change Style") { var customButton = 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)
// set HasCustomStyle to true before changing style information so that, when changing the style globally
// (like above), these custom values don't get undone
HasCustomStyle = true,
Texture = this.testPatch,
HoveredColor = Color.LightGray,
SelectionIndicator = style.SelectionIndicator
}); });
customButton.Texture.Set(this.testPatch);
root.AddChild(new VerticalSpace(3)); root.AddChild(new VerticalSpace(3));

View file

@ -7,9 +7,9 @@ using MLEM.Ui.Style;
namespace MLEM.Ui.Elements { namespace MLEM.Ui.Elements {
public class Button : Element { public class Button : Element {
public NinePatch Texture; public StyleProp<NinePatch> Texture;
public NinePatch HoveredTexture; public StyleProp<NinePatch> HoveredTexture;
public Color HoveredColor; public StyleProp<Color> HoveredColor;
public Paragraph Text; public Paragraph Text;
public Tooltip Tooltip; public Tooltip Tooltip;
@ -26,9 +26,9 @@ namespace MLEM.Ui.Elements {
var tex = this.Texture; var tex = this.Texture;
var color = Color.White * alpha; var color = Color.White * alpha;
if (this.IsMouseOver) { if (this.IsMouseOver) {
if (this.HoveredTexture != null) if (this.HoveredTexture.Value != null)
tex = this.HoveredTexture; tex = this.HoveredTexture;
color = this.HoveredColor * alpha; color = (Color) this.HoveredColor * alpha;
} }
batch.Draw(tex, this.DisplayArea, color, this.Scale); batch.Draw(tex, this.DisplayArea, color, this.Scale);
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, matrix);
@ -36,9 +36,9 @@ namespace MLEM.Ui.Elements {
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.Texture = style.ButtonTexture; this.Texture.SetFromStyle(style.ButtonTexture);
this.HoveredTexture = style.ButtonHoveredTexture; this.HoveredTexture.SetFromStyle(style.ButtonHoveredTexture);
this.HoveredColor = style.ButtonHoveredColor; this.HoveredColor.SetFromStyle(style.ButtonHoveredColor);
} }
} }

View file

@ -8,10 +8,10 @@ using MLEM.Ui.Style;
namespace MLEM.Ui.Elements { namespace MLEM.Ui.Elements {
public class Checkbox : Element { public class Checkbox : Element {
public NinePatch Texture; public StyleProp<NinePatch> Texture;
public NinePatch HoveredTexture; public StyleProp<NinePatch> HoveredTexture;
public Color HoveredColor; public StyleProp<Color> HoveredColor;
public TextureRegion Checkmark; public StyleProp<TextureRegion> Checkmark;
public Paragraph Label; public Paragraph Label;
public float TextOffsetX = 2; public float TextOffsetX = 2;
@ -50,9 +50,9 @@ namespace MLEM.Ui.Elements {
var tex = this.Texture; var tex = this.Texture;
var color = Color.White * alpha; var color = Color.White * alpha;
if (this.IsMouseOver) { if (this.IsMouseOver) {
if (this.HoveredTexture != null) if (this.HoveredTexture.Value != null)
tex = this.HoveredTexture; tex = this.HoveredTexture;
color = this.HoveredColor * alpha; color = (Color) this.HoveredColor * alpha;
} }
var boxDisplayArea = new Rectangle(this.DisplayArea.Location, new Point(this.DisplayArea.Height)); var boxDisplayArea = new Rectangle(this.DisplayArea.Location, new Point(this.DisplayArea.Height));
@ -64,10 +64,10 @@ namespace MLEM.Ui.Elements {
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.Texture = style.CheckboxTexture; this.Texture.SetFromStyle(style.CheckboxTexture);
this.HoveredTexture = style.CheckboxHoveredTexture; this.HoveredTexture.SetFromStyle(style.CheckboxHoveredTexture);
this.HoveredColor = style.CheckboxHoveredColor; this.HoveredColor.SetFromStyle(style.CheckboxHoveredColor);
this.Checkmark = style.CheckboxCheckmark; this.Checkmark.SetFromStyle(style.CheckboxCheckmark);
} }
public delegate void CheckStateChange(Checkbox box, bool checced); public delegate void CheckStateChange(Checkbox box, bool checced);

View file

@ -34,8 +34,8 @@ namespace MLEM.Ui.Elements {
}; };
if (pressed != null) if (pressed != null)
paragraph.OnPressed += pressed; paragraph.OnPressed += pressed;
paragraph.OnMouseEnter += e => paragraph.TextColor = Color.LightGray; paragraph.OnMouseEnter += e => paragraph.TextColor.Set(Color.LightGray);
paragraph.OnMouseExit += e => paragraph.TextColor = Color.White; paragraph.OnMouseExit += e => paragraph.TextColor.Set(Color.White);
this.AddElement(paragraph); this.AddElement(paragraph);
} }

View file

@ -89,7 +89,7 @@ namespace MLEM.Ui.Elements {
get => this.system; get => this.system;
internal set { internal set {
this.system = value; this.system = value;
if (this.system != null && !this.HasCustomStyle) if (this.system != null)
this.InitStyle(this.system.Style); this.InitStyle(this.system.Style);
} }
} }
@ -113,7 +113,6 @@ namespace MLEM.Ui.Elements {
public bool CanBeSelected = true; public bool CanBeSelected = true;
public bool CanBeMoused = true; public bool CanBeMoused = true;
public float DrawAlpha = 1; public float DrawAlpha = 1;
public bool HasCustomStyle;
public bool SetHeightBasedOnChildren; public bool SetHeightBasedOnChildren;
public bool CanAutoAnchorsAttach = true; public bool CanAutoAnchorsAttach = true;
@ -139,7 +138,7 @@ namespace MLEM.Ui.Elements {
} }
private bool areaDirty; private bool areaDirty;
private bool sortedChildrenDirty; private bool sortedChildrenDirty;
public NinePatch SelectionIndicator; public StyleProp<NinePatch> SelectionIndicator;
public Element(Anchor anchor, Vector2 size) { public Element(Anchor anchor, Vector2 size) {
this.anchor = anchor; this.anchor = anchor;
@ -463,7 +462,7 @@ namespace MLEM.Ui.Elements {
} }
protected virtual void InitStyle(UiStyle style) { protected virtual void InitStyle(UiStyle style) {
this.SelectionIndicator = style.SelectionIndicator; this.SelectionIndicator.SetFromStyle(style.SelectionIndicator);
} }
public delegate void TextInputCallback(Element element, Keys key, char character); public delegate void TextInputCallback(Element element, Keys key, char character);

View file

@ -1,13 +1,13 @@
using System; using System;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Textures; using MLEM.Textures;
using MLEM.Ui.Style;
namespace MLEM.Ui.Elements { namespace MLEM.Ui.Elements {
public class Image : Element { public class Image : Element {
public Color Color = Color.White; public StyleProp<Color> Color;
private TextureRegion texture; private TextureRegion texture;
public TextureCallback GetTextureCallback; public TextureCallback GetTextureCallback;
public TextureRegion Texture { public TextureRegion Texture {
@ -65,13 +65,14 @@ namespace MLEM.Ui.Elements {
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.Value != default ? this.Color : Microsoft.Xna.Framework.Color.White) * alpha;
if (this.MaintainImageAspect) { if (this.MaintainImageAspect) {
var scale = Math.Min(this.DisplayArea.Width / (float) this.texture.Width, this.DisplayArea.Height / (float) this.texture.Height); var scale = Math.Min(this.DisplayArea.Width / (float) this.texture.Width, this.DisplayArea.Height / (float) 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.ToVector2() + center * scale + imageOffset, this.Color * alpha, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0); batch.Draw(this.texture, this.DisplayArea.Location.ToVector2() + 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.ToVector2(); var scale = new Vector2(1F / this.texture.Width, 1F / this.texture.Height) * this.DisplayArea.Size.ToVector2();
batch.Draw(this.texture, this.DisplayArea.Location.ToVector2() + center * scale, this.Color * alpha, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0); batch.Draw(this.texture, this.DisplayArea.Location.ToVector2() + 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);
} }

View file

@ -11,7 +11,7 @@ using MLEM.Ui.Style;
namespace MLEM.Ui.Elements { namespace MLEM.Ui.Elements {
public class Panel : Element { public class Panel : Element {
public NinePatch Texture; public StyleProp<NinePatch> Texture;
public readonly ScrollBar ScrollBar; public readonly ScrollBar ScrollBar;
private readonly bool scrollOverflow; private readonly bool scrollOverflow;
private RenderTarget2D renderTarget; private RenderTarget2D renderTarget;
@ -169,7 +169,7 @@ namespace MLEM.Ui.Elements {
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.Texture = style.PanelTexture; this.Texture.SetFromStyle(style.PanelTexture);
} }
} }

View file

@ -16,14 +16,14 @@ namespace MLEM.Ui.Elements {
private string text; private string text;
private string splitText; private string splitText;
private Dictionary<int, FormattingCode> codeLocations; private Dictionary<int, FormattingCode> codeLocations;
public IGenericFont RegularFont; public StyleProp<IGenericFont> RegularFont;
public IGenericFont BoldFont; public StyleProp<IGenericFont> BoldFont;
public IGenericFont ItalicFont; public StyleProp<IGenericFont> ItalicFont;
public NinePatch Background; public StyleProp<NinePatch> Background;
public Color BackgroundColor; public StyleProp<Color> BackgroundColor;
public Color TextColor = Color.White; public StyleProp<Color> TextColor;
public float TextScale; public StyleProp<float> TextScale;
public string Text { public string Text {
get => this.text; get => this.text;
set { set {
@ -59,10 +59,10 @@ namespace MLEM.Ui.Elements {
var size = base.CalcActualSize(parentArea); var size = base.CalcActualSize(parentArea);
var sc = this.TextScale * this.Scale; var sc = this.TextScale * this.Scale;
this.splitText = this.RegularFont.SplitString(this.text.RemoveFormatting(), size.X - this.ScaledPadding.X * 2, sc); this.splitText = this.RegularFont.Value.SplitString(this.text.RemoveFormatting(), size.X - this.ScaledPadding.X * 2, sc);
this.codeLocations = this.text.GetFormattingCodes(); this.codeLocations = this.text.GetFormattingCodes();
var textDims = this.RegularFont.MeasureString(this.splitText) * sc; var textDims = this.RegularFont.Value.MeasureString(this.splitText) * sc;
return new Point(this.AutoAdjustWidth ? textDims.X.Ceil() + this.ScaledPadding.X * 2 : size.X, textDims.Y.Ceil() + this.ScaledPadding.Y * 2); return new Point(this.AutoAdjustWidth ? textDims.X.Ceil() + this.ScaledPadding.X * 2 : size.X, textDims.Y.Ceil() + this.ScaledPadding.Y * 2);
} }
@ -74,28 +74,29 @@ 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) {
if (this.Background != null) if (this.Background.Value != null)
batch.Draw(this.Background, this.Area, this.BackgroundColor * alpha); batch.Draw(this.Background, this.Area, (Color) this.BackgroundColor * alpha);
var pos = this.DisplayArea.Location.ToVector2(); var pos = this.DisplayArea.Location.ToVector2();
var sc = this.TextScale * this.Scale; var sc = this.TextScale * this.Scale;
var color = (this.TextColor.Value != default ? this.TextColor : Color.White) * alpha;
// if we don't have any formatting codes, then we don't need to do complex drawing // if we don't have any formatting codes, then we don't need to do complex drawing
if (this.codeLocations.Count <= 0) { if (this.codeLocations.Count <= 0) {
this.RegularFont.DrawString(batch, this.splitText, pos, this.TextColor * alpha, 0, Vector2.Zero, sc, SpriteEffects.None, 0); this.RegularFont.Value.DrawString(batch, this.splitText, pos, color, 0, Vector2.Zero, sc, SpriteEffects.None, 0);
} else { } else {
// if we have formatting codes, we should do it // if we have formatting codes, we should do it
this.RegularFont.DrawFormattedString(batch, pos, this.splitText, this.codeLocations, this.TextColor * alpha, sc, this.BoldFont, this.ItalicFont, 0, this.TimeIntoAnimation); this.RegularFont.Value.DrawFormattedString(batch, pos, this.splitText, this.codeLocations, color, sc, this.BoldFont.Value, this.ItalicFont.Value, 0, this.TimeIntoAnimation);
} }
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, matrix);
} }
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.TextScale = style.TextScale; this.TextScale.SetFromStyle(style.TextScale);
this.RegularFont = style.Font; this.RegularFont.SetFromStyle(style.Font);
this.BoldFont = style.BoldFont ?? style.Font; this.BoldFont.SetFromStyle(style.BoldFont ?? style.Font);
this.ItalicFont = style.ItalicFont ?? style.Font; this.ItalicFont.SetFromStyle(style.ItalicFont ?? style.Font);
} }
public delegate string TextCallback(Paragraph paragraph); public delegate string TextCallback(Paragraph paragraph);

View file

@ -9,11 +9,11 @@ using MLEM.Ui.Style;
namespace MLEM.Ui.Elements { namespace MLEM.Ui.Elements {
public class ProgressBar : Element { public class ProgressBar : Element {
public NinePatch Texture; public StyleProp<NinePatch> Texture;
public Color Color; public StyleProp<Color> Color;
public Point ProgressPadding; public StyleProp<Point> ProgressPadding;
public NinePatch ProgressTexture; public StyleProp<NinePatch> ProgressTexture;
public Color ProgressColor; public StyleProp<Color> ProgressColor;
public Direction2 Direction; public Direction2 Direction;
public float MaxValue; public float MaxValue;
@ -33,11 +33,12 @@ 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) {
batch.Draw(this.Texture, this.DisplayArea, this.Color * alpha, this.Scale); batch.Draw(this.Texture, this.DisplayArea, (Color) this.Color * alpha, this.Scale);
var percentage = this.CurrentValue / this.MaxValue; var percentage = this.CurrentValue / this.MaxValue;
var padHor = this.ProgressTexture != null ? (this.ProgressTexture.PaddingLeft + this.ProgressTexture.PaddingRight) * this.Scale : 0; var tex = this.ProgressTexture.Value;
var padVer = this.ProgressTexture != null ? (this.ProgressTexture.PaddingTop + this.ProgressTexture.PaddingBottom) * this.Scale : 0; var padHor = tex != null ? (tex.PaddingLeft + tex.PaddingRight) * this.Scale : 0;
var padVer = tex != null ? (tex.PaddingTop + tex.PaddingBottom) * this.Scale : 0;
var width = (percentage * (this.DisplayArea.Width - padHor) + padHor).Floor(); var width = (percentage * (this.DisplayArea.Width - padHor) + padHor).Floor();
var height = (percentage * (this.DisplayArea.Height - padVer) + padVer).Floor(); var height = (percentage * (this.DisplayArea.Height - padVer) + padVer).Floor();
Rectangle progressArea; Rectangle progressArea;
@ -59,22 +60,22 @@ namespace MLEM.Ui.Elements {
progressArea = new Rectangle(this.DisplayArea.Location, new Point(width, this.DisplayArea.Height)); progressArea = new Rectangle(this.DisplayArea.Location, new Point(width, this.DisplayArea.Height));
break; break;
} }
var offsetArea = progressArea.Shrink(this.ProgressPadding.Multiply(this.Scale)); var offsetArea = progressArea.Shrink(this.ProgressPadding.Value.Multiply(this.Scale));
if (this.ProgressTexture != null) { if (this.ProgressTexture.Value != null) {
batch.Draw(this.ProgressTexture, offsetArea, this.ProgressColor * alpha, this.Scale); batch.Draw(this.ProgressTexture, offsetArea, (Color) this.ProgressColor * alpha, this.Scale);
} else { } else {
batch.Draw(batch.GetBlankTexture(), offsetArea, this.ProgressColor * alpha); batch.Draw(batch.GetBlankTexture(), offsetArea, (Color) this.ProgressColor * alpha);
} }
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, matrix);
} }
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.Texture = style.ProgressBarTexture; this.Texture.SetFromStyle(style.ProgressBarTexture);
this.Color = style.ProgressBarColor; this.Color.SetFromStyle(style.ProgressBarColor);
this.ProgressPadding = style.ProgressBarProgressPadding; this.ProgressPadding.SetFromStyle(style.ProgressBarProgressPadding);
this.ProgressTexture = style.ProgressBarProgressTexture; this.ProgressTexture.SetFromStyle(style.ProgressBarProgressTexture);
this.ProgressColor = style.ProgressBarProgressColor; this.ProgressColor.SetFromStyle(style.ProgressBarProgressColor);
} }
} }

View file

@ -23,10 +23,10 @@ namespace MLEM.Ui.Elements {
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.Texture = style.RadioTexture; this.Texture.SetFromStyle(style.RadioTexture);
this.HoveredTexture = style.RadioHoveredTexture; this.HoveredTexture.SetFromStyle(style.RadioHoveredTexture);
this.HoveredColor = style.RadioHoveredColor; this.HoveredColor.SetFromStyle(style.RadioHoveredColor);
this.Checkmark = style.RadioCheckmark; this.Checkmark.SetFromStyle(style.RadioCheckmark);
} }
} }

View file

@ -11,8 +11,8 @@ using MLEM.Ui.Style;
namespace MLEM.Ui.Elements { namespace MLEM.Ui.Elements {
public class ScrollBar : Element { public class ScrollBar : Element {
public NinePatch Background; public StyleProp<NinePatch> Background;
public NinePatch ScrollerTexture; public StyleProp<NinePatch> ScrollerTexture;
public Point ScrollerOffset; public Point ScrollerOffset;
public Point ScrollerSize; public Point ScrollerSize;
private float maxValue; private float maxValue;
@ -132,8 +132,8 @@ namespace MLEM.Ui.Elements {
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.Background = style.ScrollBarBackground; this.Background.SetFromStyle(style.ScrollBarBackground);
this.ScrollerTexture = style.ScrollBarScrollerTexture; this.ScrollerTexture.SetFromStyle(style.ScrollBarScrollerTexture);
} }
public delegate void ValueChanged(Element element, float value); public delegate void ValueChanged(Element element, float value);

View file

@ -18,16 +18,16 @@ namespace MLEM.Ui.Elements {
public static readonly Rule OnlyNumbers = (field, add) => add.All(char.IsNumber); public static readonly Rule OnlyNumbers = (field, add) => add.All(char.IsNumber);
public static readonly Rule LettersNumbers = (field, add) => add.All(c => char.IsLetter(c) || char.IsNumber(c)); public static readonly Rule LettersNumbers = (field, add) => add.All(c => char.IsLetter(c) || char.IsNumber(c));
public NinePatch Texture; public StyleProp<NinePatch> Texture;
public NinePatch HoveredTexture; public StyleProp<NinePatch> HoveredTexture;
public Color HoveredColor; public StyleProp<Color> HoveredColor;
public float TextScale; public StyleProp<float> TextScale;
public StyleProp<IGenericFont> Font;
private readonly StringBuilder text = new StringBuilder(); private readonly StringBuilder text = new StringBuilder();
public string Text => this.text.ToString(); public string Text => this.text.ToString();
public string PlaceholderText; public string PlaceholderText;
public TextChanged OnTextChange; public TextChanged OnTextChange;
public float TextOffsetX = 4; public float TextOffsetX = 4;
private IGenericFont font;
private double caretBlinkTimer; private double caretBlinkTimer;
private string displayedText; private string displayedText;
private int textOffset; private int textOffset;
@ -50,7 +50,8 @@ namespace MLEM.Ui.Elements {
public TextField(Anchor anchor, Vector2 size, Rule rule = null, IGenericFont font = null) : base(anchor, size) { public TextField(Anchor anchor, Vector2 size, Rule rule = null, IGenericFont font = null) : base(anchor, size) {
this.InputRule = rule ?? DefaultRule; this.InputRule = rule ?? DefaultRule;
this.font = font; if (font != null)
this.Font.Set(font);
if (WindowExtensions.SupportsTextInput()) { if (WindowExtensions.SupportsTextInput()) {
this.OnTextInput += (element, key, character) => { this.OnTextInput += (element, key, character) => {
@ -83,9 +84,9 @@ namespace MLEM.Ui.Elements {
private void HandleTextChange(bool textChanged = true) { private void HandleTextChange(bool textChanged = true) {
// not initialized yet // not initialized yet
if (this.font == null) if (this.Font.Value == null)
return; return;
var length = this.font.MeasureString(this.text).X * this.TextScale; var length = this.Font.Value.MeasureString(this.text).X * this.TextScale;
var maxWidth = this.DisplayArea.Width / this.Scale - this.TextOffsetX * 2; var maxWidth = this.DisplayArea.Width / this.Scale - this.TextOffsetX * 2;
if (length > maxWidth) { if (length > maxWidth) {
// if we're moving the caret to the left // if we're moving the caret to the left
@ -94,13 +95,13 @@ namespace MLEM.Ui.Elements {
} else { } else {
// if we're moving the caret to the right // if we're moving the caret to the right
var importantArea = this.text.ToString(this.textOffset, Math.Min(this.CaretPos, this.text.Length) - this.textOffset); var importantArea = this.text.ToString(this.textOffset, Math.Min(this.CaretPos, this.text.Length) - this.textOffset);
var bound = this.CaretPos - this.font.TruncateString(importantArea, maxWidth, this.TextScale, true).Length; var bound = this.CaretPos - this.Font.Value.TruncateString(importantArea, maxWidth, this.TextScale, true).Length;
if (this.textOffset < bound) { if (this.textOffset < bound) {
this.textOffset = bound; this.textOffset = bound;
} }
} }
var visible = this.text.ToString(this.textOffset, this.text.Length - this.textOffset); var visible = this.text.ToString(this.textOffset, this.text.Length - this.textOffset);
this.displayedText = this.font.TruncateString(visible, maxWidth, this.TextScale); this.displayedText = this.Font.Value.TruncateString(visible, maxWidth, this.TextScale);
} else { } else {
this.displayedText = this.Text; this.displayedText = this.Text;
this.textOffset = 0; this.textOffset = 0;
@ -136,9 +137,9 @@ namespace MLEM.Ui.Elements {
var tex = this.Texture; var tex = this.Texture;
var color = Color.White * alpha; var color = Color.White * alpha;
if (this.IsMouseOver) { if (this.IsMouseOver) {
if (this.HoveredTexture != null) if (this.HoveredTexture.Value != null)
tex = this.HoveredTexture; tex = this.HoveredTexture;
color = this.HoveredColor * alpha; color = (Color) this.HoveredColor * alpha;
} }
batch.Draw(tex, this.DisplayArea, color, this.Scale); batch.Draw(tex, this.DisplayArea, color, this.Scale);
@ -146,9 +147,9 @@ namespace MLEM.Ui.Elements {
if (this.text.Length > 0 || this.IsSelected) { if (this.text.Length > 0 || this.IsSelected) {
var caret = this.IsSelected ? this.caretBlinkTimer >= 0.5F ? "|" : " " : ""; var caret = this.IsSelected ? this.caretBlinkTimer >= 0.5F ? "|" : " " : "";
var display = this.displayedText.Insert(this.CaretPos - this.textOffset, caret); var display = this.displayedText.Insert(this.CaretPos - this.textOffset, caret);
this.font.DrawCenteredString(batch, display, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true); this.Font.Value.DrawCenteredString(batch, display, textPos, this.TextScale * this.Scale, Color.White * alpha, false, true);
} else if (this.PlaceholderText != null) { } else if (this.PlaceholderText != null) {
this.font.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true); this.Font.Value.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true);
} }
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, matrix);
} }
@ -187,11 +188,11 @@ namespace MLEM.Ui.Elements {
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.TextScale = style.TextScale; this.TextScale.SetFromStyle(style.TextScale);
this.font = style.Font; this.Font.SetFromStyle(style.Font);
this.Texture = style.TextFieldTexture; this.Texture.SetFromStyle(style.TextFieldTexture);
this.HoveredTexture = style.TextFieldHoveredTexture; this.HoveredTexture.SetFromStyle(style.TextFieldHoveredTexture);
this.HoveredColor = style.TextFieldHoveredColor; this.HoveredColor.SetFromStyle(style.TextFieldHoveredColor);
} }
public delegate void TextChanged(TextField field, string text); public delegate void TextChanged(TextField field, string text);

View file

@ -48,8 +48,8 @@ namespace MLEM.Ui.Elements {
protected override void InitStyle(UiStyle style) { protected override void InitStyle(UiStyle style) {
base.InitStyle(style); base.InitStyle(style);
this.Background = style.TooltipBackground; this.Background.SetFromStyle(style.TooltipBackground);
this.BackgroundColor = style.TooltipBackgroundColor; this.BackgroundColor.SetFromStyle(style.TooltipBackgroundColor);
} }
} }

View file

@ -0,0 +1,23 @@
namespace MLEM.Ui.Style {
public struct StyleProp<T> {
public T Value { get; private set; }
private bool isCustom;
public void SetFromStyle(T value) {
if (!this.isCustom) {
this.Value = value;
}
}
public void Set(T value) {
this.isCustom = true;
this.Value = value;
}
public static implicit operator T(StyleProp<T> prop) {
return prop.Value;
}
}
}

View file

@ -87,7 +87,7 @@ namespace MLEM.Ui {
this.OnMousedElementChanged = e => this.ApplyToAll(t => t.OnMousedElementChanged?.Invoke(t, e)); this.OnMousedElementChanged = e => this.ApplyToAll(t => t.OnMousedElementChanged?.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));
this.OnSelectedElementDrawn = (element, time, batch, alpha) => { this.OnSelectedElementDrawn = (element, time, batch, alpha) => {
if (this.Controls.IsAutoNavMode && element.SelectionIndicator != null) { if (this.Controls.IsAutoNavMode && element.SelectionIndicator.Value != null) {
batch.Draw(element.SelectionIndicator, element.DisplayArea, Color.White * alpha, element.Scale / 2); batch.Draw(element.SelectionIndicator, element.DisplayArea, Color.White * alpha, element.Scale / 2);
} }
}; };

View file

@ -53,19 +53,15 @@ namespace Sandbox {
var group = root.AddChild(new CustomDrawGroup(Anchor.AutoLeft, new Vector2(1, 10))); var group = root.AddChild(new CustomDrawGroup(Anchor.AutoLeft, new Vector2(1, 10)));
group.AddChild(new Button(Anchor.AutoLeft, Vector2.One, "Test text")); group.AddChild(new Button(Anchor.AutoLeft, Vector2.One, "Test text"));
this.progress = new ProgressBar(Anchor.Center, new Vector2(0.8F, 0.5F), Direction2.Down, 1) { this.progress = new ProgressBar(Anchor.Center, new Vector2(0.8F, 0.5F), Direction2.Down, 1);
HasCustomStyle = true, this.progress.Texture.Set(new NinePatch(new TextureRegion(tex, 0, 8, 24, 24), 8));
Texture = new NinePatch(new TextureRegion(tex, 0, 8, 24, 24), 8), this.progress.ProgressTexture.Set(new NinePatch(new TextureRegion(tex, 24, 8, 16, 16), 4));
Color = Color.White,
ProgressTexture = new NinePatch(new TextureRegion(tex, 24, 8, 16, 16), 4),
ProgressColor = Color.White
};
this.UiSystem.Add("Progress", this.progress); this.UiSystem.Add("Progress", this.progress);
} }
protected override void Update(GameTime gameTime) { protected override void Update(GameTime gameTime) {
base.Update(gameTime); base.Update(gameTime);
this.progress.CurrentValue = (float) (Math.Sin(gameTime.TotalGameTime.TotalSeconds/2) + 1) / 2; this.progress.CurrentValue = (float) (Math.Sin(gameTime.TotalGameTime.TotalSeconds / 2) + 1) / 2;
} }
protected override void DoDraw(GameTime gameTime) { protected override void DoDraw(GameTime gameTime) {