2 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Graphics;
5 using System.Collections.Generic;
6 using System.Collections.Immutable;
7 using System.Diagnostics.CodeAnalysis;
25 private float textScale = 1;
30 protected Color
textColor, disabledTextColor, selectedTextColor;
33 private string censoredText;
42 private bool overflowClipActive;
47 get {
return overflowClipActive; }
50 private float textDepth;
54 private Vector4 padding;
57 get {
return padding; }
73 if (base.Font == value) {
return; }
85 #warning TODO: Remove this eventually. Nobody should want to pass null.
94 if (
Text == newText) {
return; }
97 if (autoScaleHorizontal || autoScaleVertical) { textScale = 1.0f; }
107 get {
return wrappedText; }
112 get {
return textDepth; }
113 set { textDepth = MathHelper.Clamp(value, 0.0f, 1.0f); }
128 get {
return textScale; }
131 if (value != textScale)
139 private bool autoScaleHorizontal, autoScaleVertical;
146 get {
return autoScaleHorizontal; }
149 if (autoScaleHorizontal == value) {
return; }
150 autoScaleHorizontal = value;
151 if (autoScaleHorizontal)
163 get {
return autoScaleVertical; }
166 if (autoScaleVertical == value) {
return; }
167 autoScaleVertical = value;
168 if (autoScaleVertical)
178 get {
return forceUpperCase; }
181 if (forceUpperCase == value) {
return; }
183 forceUpperCase = value;
207 get => disabledTextColor;
208 set => disabledTextColor = value;
211 private Color? hoverTextColor;
214 get {
return hoverTextColor ??
textColor; }
215 set { hoverTextColor = value; }
220 get {
return selectedTextColor; }
221 set { selectedTextColor = value; }
243 get {
return censoredText; }
248 public Color Color {
get;
set; } = GUIStyle.Red;
249 private int thickness;
255 this.thickness = thickness;
256 this.expand = expand;
259 public void Draw(SpriteBatch spriteBatch,
float textSizeHalf,
float xPos,
float yPos)
261 ShapeExtensions.DrawLine(spriteBatch,
new Vector2(xPos - textSizeHalf - expand, yPos),
new Vector2(xPos + textSizeHalf + expand, yPos), Color, thickness);
281 public List<ClickableArea>
ClickableAreas {
get;
private set; } =
new List<ClickableArea>();
290 Alignment
textAlignment = Alignment.Left,
bool wrap =
false,
string style =
"", Color?
color =
null)
297 if (textColor.HasValue)
304 var selectedFont = font ?? GUIStyle.Font;
305 this.
Font = selectedFont;
308 this.
Text = text ??
"";
309 if (rectT.
Rect.Height == 0 && !
text.IsNullOrEmpty())
324 if (wrappedText ==
null) {
return; }
335 if (componentStyle ==
null) {
return; }
336 base.ApplyStyle(componentStyle);
337 padding = componentStyle.
Padding;
344 if (
Font ==
null || !componentStyle.
Font.IsEmpty)
346 Font = GUIStyle.Fonts[componentStyle.
Font.AppendIfMissing(
"Font")];
352 cachedCaretPositions = ImmutableArray<Vector2>.Empty;
358 if (
text ==
null) {
return; }
360 censoredText =
text.IsNullOrEmpty() ?
"" :
new string(
'\u2022',
text.
Length);
364 overflowClipActive =
false;
369 if (
Wrap && rect.Width > 0)
372 TextSize = MeasureText(wrappedText);
376 overflowClipActive =
TextSize.X > rect.Width - padding.X - padding.Z;
379 Vector2 minSize =
new Vector2(
380 Math.Max(rect.Width - padding.X - padding.Z, 5.0f),
381 Math.Max(rect.Height - padding.Y - padding.W, 5.0f));
382 if (!autoScaleHorizontal) { minSize.X =
float.MaxValue; }
383 if (!
Wrap && !autoScaleVertical) { minSize.Y =
float.MaxValue; }
385 if ((autoScaleHorizontal || autoScaleVertical) && textScale > 0.1f &&
392 textPos =
new Vector2(padding.X + (rect.Width - padding.Z - padding.X) / 2.0f, padding.Y + (rect.Height - padding.Y - padding.W) / 2.0f);
402 textPos.X = rect.Width - padding.Z;
411 textPos.Y = rect.Height - padding.W;
424 return MeasureText(
text.Value);
427 private Vector2 MeasureText(
string text)
429 if (
Font ==
null)
return Vector2.Zero;
431 if (
string.IsNullOrEmpty(
text))
442 if (hoverTextColor.HasValue)
444 hoverTextColor =
new Color(hoverTextColor.Value, a);
454 hoverTextColor =
color;
455 selectedTextColor =
color;
456 disabledTextColor =
color;
459 private ImmutableArray<Vector2> cachedCaretPositions = ImmutableArray<Vector2>.Empty;
461 private string cachedCaretPositionsText;
465 if (cachedCaretPositions.Any() &&
466 textDrawn == cachedCaretPositionsText)
468 return cachedCaretPositions;
472 :
float.PositiveInfinity;
473 string wrapped =
Font.
WrapText(textDrawn, w, out Vector2[] positions);
479 cachedCaretPositions = positions
480 .Select(p => p -
new Vector2(alignmentXDiff, 0))
483 cachedCaretPositionsText = textDrawn;
484 return cachedCaretPositions;
495 if (positions.Length == 0) {
return 0; }
497 float closestXDist =
float.PositiveInfinity;
498 float closestYDist =
float.PositiveInfinity;
499 int closestIndex = -1;
500 for (
int i = 0; i < positions.Length; i++)
502 float xDist = Math.Abs(pos.X - positions[i].X);
503 float yDist = Math.Abs(pos.Y - (positions[i].Y +
Font.
LineHeight * 0.5f));
504 if (yDist < closestYDist || (MathUtils.NearlyEqual(yDist, closestYDist) && xDist < closestXDist))
507 closestXDist = xDist;
508 closestYDist = yDist;
512 return closestIndex >= 0 ? closestIndex :
Text.
Length;
515 protected override void Update(
float deltaTime)
517 base.Update(deltaTime);
519 if (
ClickableAreas.Any() && ((GUI.MouseOn?.IsParentOf(
this) ??
true) || GUI.MouseOn ==
this))
530 clickableArea.
OnClick?.Invoke(
this, clickableArea);
542 protected override void Draw(SpriteBatch spriteBatch)
550 base.Draw(spriteBatch);
556 Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
557 if (overflowClipActive)
559 Rectangle scissorRect =
new Rectangle(rect.X + (
int)padding.X, rect.Y, rect.Width - (
int)padding.X - (
int)padding.Z, rect.Height);
560 if (!scissorRect.Intersects(prevScissorRect)) {
return; }
562 spriteBatch.GraphicsDevice.ScissorRectangle =
Rectangle.Intersect(prevScissorRect, scissorRect);
566 if (!
string.IsNullOrEmpty(textToShow))
579 currentTextColor = disabledTextColor;
583 currentTextColor = selectedTextColor;
588 Color colorToShow = currentTextColor * (currentTextColor.A / 255.0f);
589 if (TextManager.DebugDraw)
593 colorToShow = Color.Magenta;
599 Vector2 shadowOffset =
new Vector2(Math.Max(GUI.IntScale(2), 1));
600 Font.
DrawString(spriteBatch, textToShow, pos + shadowOffset, Color.Black, 0.0f,
origin,
TextScale,
SpriteEffects.None, textDepth,
alignment:
textAlignment, forceUpperCase:
ForceUpperCase);
603 Font.
DrawString(spriteBatch, textToShow, pos, colorToShow, 0.0f,
origin,
TextScale,
SpriteEffects.None, textDepth,
alignment:
textAlignment, forceUpperCase:
ForceUpperCase);
609 RichTextData?.ForEach(rt => rt.Alpha = currentTextColor.A / 255.0f);
619 if (overflowClipActive)
622 spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
626 if (
OutlineColor.A * currColor.A > 0.0f) GUI.DrawRectangle(spriteBatch, rect,
OutlineColor * (currColor.A / 255.0f),
false);
648 public static void AutoScaleAndNormalize(IEnumerable<GUITextBlock> textBlocks,
bool scaleHorizontal =
true,
bool scaleVertical =
false,
float? defaultScale =
null)
650 if (!textBlocks.Any()) {
return; }
651 float minScale = Math.Max(textBlocks.First().TextScale, 1.0f);
654 if (defaultScale.HasValue) { textBlock.
TextScale = defaultScale.Value; }
657 minScale = Math.Min(textBlock.
TextScale, minScale);
virtual ComponentState State
virtual Color GetColor(ComponentState state)
virtual Color OutlineColor
SpriteEffects SpriteEffects
readonly Color SelectedTextColor
readonly Color HoverTextColor
readonly Color DisabledTextColor
Vector2 MeasureString(LocalizedString str, bool removeExtraSpacing=false)
string WrapText(string text, float width)
void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float layerDepth, in ImmutableArray< RichTextData >? richTextData, int rtdOffset=0, Alignment alignment=Alignment.TopLeft, ForceUpperCase forceUpperCase=Barotrauma.ForceUpperCase.Inherit)
void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects spriteEffects, float layerDepth)
StrikethroughSettings(Color? color=null, int thickness=1, int expand=0)
void Draw(SpriteBatch spriteBatch, float textSizeHalf, float xPos, float yPos)
StrikethroughSettings Strikethrough
void ClearCaretPositions()
override void ApplyStyle(GUIComponentStyle componentStyle)
ImmutableArray< Vector2 > GetAllCaretPositions()
override void Update(float deltaTime)
void OverrideTextColor(Color color)
Overrides the color for all the states.
GUITextBlock(RectTransform rectT, RichString text, Color? textColor=null, GUIFont font=null, Alignment textAlignment=Alignment.Left, bool wrap=false, string style="", Color? color=null)
This is the new constructor. If the rectT height is set 0, the height is calculated from the text.
void CalculateHeightFromText(int padding=0, bool removeExtraSpacing=false)
static void AutoScaleAndNormalize(bool scaleHorizontal=true, bool scaleVertical=false, params GUITextBlock[] textBlocks)
Set the text scale of the GUITextBlocks so that they all use the same scale and can fit the text with...
bool AutoScaleHorizontal
When enabled, the text is automatically scaled down to fit the textblock horizontally.
static void AutoScaleAndNormalize(params GUITextBlock[] textBlocks)
Set the text scale of the GUITextBlocks so that they all use the same scale and can fit the text with...
int GetCaretIndexFromScreenPos(in Vector2 pos)
override void Draw(SpriteBatch spriteBatch)
bool OverrideRichTextDataAlpha
static void AutoScaleAndNormalize(IEnumerable< GUITextBlock > textBlocks, bool scaleHorizontal=true, bool scaleVertical=false, float? defaultScale=null)
Set the text scale of the GUITextBlocks so that they all use the same scale and can fit the text with...
override void SetAlpha(float a)
int GetCaretIndexFromLocalPos(in Vector2 pos)
LocalizedString WrappedText
bool AutoScaleVertical
When enabled, the text is automatically scaled down to fit the textblock vertically.
List< ClickableArea > ClickableAreas
void SetRichText(LocalizedString richText)
TextGetterHandler TextGetter
delegate LocalizedString TextGetterHandler()
static RasterizerState ScissorTestEnable
LanguageIdentifier Language
LocalizedString NestedStr
ImmutableArray< RichTextData >? RichTextData
static RichString Rich(LocalizedString str, Func< string, string >? postProcess=null)
readonly LocalizedString SanitizedString
delegate void OnClickDelegate(GUITextBlock textBlock, ClickableArea area)
OnClickDelegate OnSecondaryClick
static readonly LanguageIdentifier None