Add horizontal alignment tags for rich text box

This commit is contained in:
Wojciech Figat
2022-08-05 15:29:37 +02:00
parent 9caf80bdc9
commit f781fd8ab6
4 changed files with 107 additions and 12 deletions

View File

@@ -26,12 +26,12 @@ namespace FlaxEngine.GUI
/// Current caret location for the new text blocks origin. /// Current caret location for the new text blocks origin.
/// </summary> /// </summary>
public Float2 Caret; public Float2 Caret;
/// <summary> /// <summary>
/// Index of the current line start character. /// Index of the current line start character.
/// </summary> /// </summary>
public int LineStartCharacterIndex; public int LineStartCharacterIndex;
/// <summary> /// <summary>
/// Index of the current line start text block. /// Index of the current line start text block.
/// </summary> /// </summary>
@@ -50,12 +50,12 @@ namespace FlaxEngine.GUI
{ {
// Post-processing // Post-processing
Control.PostProcessBlock?.Invoke(ref this, ref textBlock); Control.PostProcessBlock?.Invoke(ref this, ref textBlock);
// Add to the text blocks // Add to the text blocks
Control._textBlocks.Add(textBlock); Control._textBlocks.Add(textBlock);
} }
} }
/// <summary> /// <summary>
/// The delegate for text blocks post-processing. /// The delegate for text blocks post-processing.
/// </summary> /// </summary>
@@ -68,7 +68,7 @@ namespace FlaxEngine.GUI
/// </summary> /// </summary>
[HideInEditor] [HideInEditor]
public PostProcessBlockDelegate PostProcessBlock; public PostProcessBlockDelegate PostProcessBlock;
/// <summary> /// <summary>
/// The delegate for HTML tag processing. /// The delegate for HTML tag processing.
/// </summary> /// </summary>
@@ -91,6 +91,8 @@ namespace FlaxEngine.GUI
{ "size", ProcessSize }, { "size", ProcessSize },
{ "img", ProcessImage }, { "img", ProcessImage },
{ "valign", ProcessVAlign }, { "valign", ProcessVAlign },
{ "align", ProcessAlign },
{ "center", ProcessCenter },
}; };
private HtmlParser _parser = new HtmlParser(); private HtmlParser _parser = new HtmlParser();
@@ -104,7 +106,7 @@ namespace FlaxEngine.GUI
ParseTextBlocks(_text, _textBlocks); ParseTextBlocks(_text, _textBlocks);
return; return;
} }
// Setup parsing // Setup parsing
_parser.Reset(_text); _parser.Reset(_text);
_styleStack.Clear(); _styleStack.Clear();
@@ -206,7 +208,7 @@ namespace FlaxEngine.GUI
context.AddTextBlock(ref textBlock); context.AddTextBlock(ref textBlock);
} }
// Update the caret location // Update the caret location
ref var lastLine = ref lines[lines.Length - 1]; ref var lastLine = ref lines[lines.Length - 1];
if (lines.Length == 1) if (lines.Length == 1)
@@ -226,7 +228,7 @@ namespace FlaxEngine.GUI
var lineOrigin = textBlocks[context.LineStartTextBlockIndex].Bounds.Location; var lineOrigin = textBlocks[context.LineStartTextBlockIndex].Bounds.Location;
var lineSize = Float2.Zero; var lineSize = Float2.Zero;
var lineAscender = 0.0f; var lineAscender = 0.0f;
for(int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++) for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{ {
ref TextBlock textBlock = ref textBlocks[i]; ref TextBlock textBlock = ref textBlocks[i];
var textBlockSize = textBlock.Bounds.BottomRight - lineOrigin; var textBlockSize = textBlock.Bounds.BottomRight - lineOrigin;
@@ -242,10 +244,12 @@ namespace FlaxEngine.GUI
} }
// Organize text blocks within line // Organize text blocks within line
for(int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++) var horizontalAlignments = TextBlockStyle.Alignments.Baseline;
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{ {
ref TextBlock textBlock = ref textBlocks[i]; ref TextBlock textBlock = ref textBlocks[i];
var vOffset = lineSize.Y - textBlock.Bounds.Height; var vOffset = lineSize.Y - textBlock.Bounds.Height;
horizontalAlignments |= textBlock.Style.Alignment & TextBlockStyle.Alignments.HorizontalMask;
switch (textBlock.Style.Alignment & TextBlockStyle.Alignments.VerticalMask) switch (textBlock.Style.Alignment & TextBlockStyle.Alignments.VerticalMask)
{ {
case TextBlockStyle.Alignments.Baseline: case TextBlockStyle.Alignments.Baseline:
@@ -279,6 +283,24 @@ namespace FlaxEngine.GUI
} }
} }
} }
var hOffset = Width - lineSize.X;
if ((horizontalAlignments & TextBlockStyle.Alignments.Center) == TextBlockStyle.Alignments.Center)
{
hOffset *= 0.5f;
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{
ref TextBlock textBlock = ref textBlocks[i];
textBlock.Bounds.Location.X += hOffset;
}
}
else if ((horizontalAlignments & TextBlockStyle.Alignments.Right) == TextBlockStyle.Alignments.Right)
{
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{
ref TextBlock textBlock = ref textBlocks[i];
textBlock.Bounds.Location.X += hOffset;
}
}
// Move to the next line // Move to the next line
context.LineStartCharacterIndex = lineEnd + 1; context.LineStartCharacterIndex = lineEnd + 1;

View File

@@ -14,7 +14,7 @@ namespace FlaxEngine.GUI
if (font) if (font)
context.Caret.Y += font.Height; context.Caret.Y += font.Height;
} }
private static void ProcessColor(ref ParsingContext context, ref HtmlTag tag) private static void ProcessColor(ref ParsingContext context, ref HtmlTag tag)
{ {
if (tag.IsSlash) if (tag.IsSlash)
@@ -198,7 +198,7 @@ namespace FlaxEngine.GUI
context.AddTextBlock(ref imageBlock); context.AddTextBlock(ref imageBlock);
context.Caret.X += imageBlock.Bounds.Size.X; context.Caret.X += imageBlock.Bounds.Size.X;
} }
private static void ProcessVAlign(ref ParsingContext context, ref HtmlTag tag) private static void ProcessVAlign(ref ParsingContext context, ref HtmlTag tag)
{ {
if (tag.IsSlash) if (tag.IsSlash)
@@ -211,7 +211,7 @@ namespace FlaxEngine.GUI
if (tag.Attributes.TryGetValue(string.Empty, out var valign)) if (tag.Attributes.TryGetValue(string.Empty, out var valign))
{ {
style.Alignment &= ~TextBlockStyle.Alignments.VerticalMask; style.Alignment &= ~TextBlockStyle.Alignments.VerticalMask;
switch(valign) switch (valign)
{ {
case "top": case "top":
style.Alignment = TextBlockStyle.Alignments.Top; style.Alignment = TextBlockStyle.Alignments.Top;
@@ -231,6 +231,49 @@ namespace FlaxEngine.GUI
} }
} }
private static void ProcessAlign(ref ParsingContext context, ref HtmlTag tag)
{
if (tag.IsSlash)
{
context.StyleStack.Pop();
}
else
{
var style = context.StyleStack.Peek();
if (tag.Attributes.TryGetValue(string.Empty, out var valign))
{
style.Alignment &= ~TextBlockStyle.Alignments.VerticalMask;
switch (valign)
{
case "left":
style.Alignment = TextBlockStyle.Alignments.Left;
break;
case "right":
style.Alignment = TextBlockStyle.Alignments.Right;
break;
case "center":
style.Alignment = TextBlockStyle.Alignments.Center;
break;
}
}
context.StyleStack.Push(style);
}
}
private static void ProcessCenter(ref ParsingContext context, ref HtmlTag tag)
{
if (tag.IsSlash)
{
context.StyleStack.Pop();
}
else
{
var style = context.StyleStack.Peek();
style.Alignment = TextBlockStyle.Alignments.Center;
context.StyleStack.Push(style);
}
}
private static Asset FindAsset(string name, System.Type type) private static Asset FindAsset(string name, System.Type type)
{ {
var ids = Content.GetAllAssetsByType(type); var ids = Content.GetAllAssetsByType(type);

View File

@@ -50,5 +50,14 @@ namespace FlaxEngine.GUI
BackgroundSelectedBrush = new SolidColorBrush(style.BackgroundSelected), BackgroundSelectedBrush = new SolidColorBrush(style.BackgroundSelected),
}; };
} }
/// <inheritdoc />
protected override void OnSizeChanged()
{
base.OnSizeChanged();
// Refresh textblocks since thos emight depend on control size (eg. align right)
UpdateTextBlocks();
}
} }
} }

View File

@@ -32,11 +32,32 @@ namespace FlaxEngine.GUI
/// </summary> /// </summary>
Bottom = 4, Bottom = 4,
/// <summary>
/// Block will be aligned to the left edge of the layout (horizontally).
/// </summary>
Left = 8,
/// <summary>
/// Block will be aligned to center of the layout (horizontally).
/// </summary>
Center = 16,
/// <summary>
/// Block will be aligned to the right edge of the layout (horizontally).
/// </summary>
Right = 32,
/// <summary> /// <summary>
/// Mask with vertical alignment flags. /// Mask with vertical alignment flags.
/// </summary> /// </summary>
[HideInEditor] [HideInEditor]
VerticalMask = Top | Middle | Bottom, VerticalMask = Top | Middle | Bottom,
/// <summary>
/// Mask with horizontal alignment flags.
/// </summary>
[HideInEditor]
HorizontalMask = Left | Center | Right,
} }
/// <summary> /// <summary>