Add img tag to rich text box
This commit is contained in:
@@ -41,6 +41,19 @@ namespace FlaxEngine.GUI
|
||||
/// Text styles stack (new tags push modified style and pop on tag end).
|
||||
/// </summary>
|
||||
public Stack<TextBlockStyle> StyleStack;
|
||||
|
||||
/// <summary>
|
||||
/// Adds the text block to the control
|
||||
/// </summary>
|
||||
/// <param name="textBlock">The text block to add.</param>
|
||||
public void AddTextBlock(ref TextBlock textBlock)
|
||||
{
|
||||
// Post-processing
|
||||
Control.PostProcessBlock?.Invoke(ref this, ref textBlock);
|
||||
|
||||
// Add to the text blocks
|
||||
Control._textBlocks.Add(textBlock);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -76,6 +89,7 @@ namespace FlaxEngine.GUI
|
||||
{ "b", ProcessBold },
|
||||
{ "i", ProcessItalic },
|
||||
{ "size", ProcessSize },
|
||||
{ "img", ProcessImage },
|
||||
};
|
||||
|
||||
private HtmlParser _parser = new HtmlParser();
|
||||
@@ -184,11 +198,7 @@ namespace FlaxEngine.GUI
|
||||
textBlock.Bounds = new Rectangle(context.Caret, line.Size);
|
||||
textBlock.Bounds.X += line.Location.X;
|
||||
|
||||
// Post-processing
|
||||
PostProcessBlock?.Invoke(ref context, ref textBlock);
|
||||
|
||||
// Add to the text blocks
|
||||
_textBlocks.Add(textBlock);
|
||||
context.AddTextBlock(ref textBlock);
|
||||
}
|
||||
|
||||
// Update the caret location
|
||||
|
||||
@@ -47,13 +47,9 @@ namespace FlaxEngine.GUI
|
||||
if (tag.Attributes.TryGetValue(string.Empty, out var alphaText))
|
||||
{
|
||||
if (alphaText.Length == 3 && alphaText[0] == '#')
|
||||
{
|
||||
style.Color.A = ((StringUtils.HexDigit(alphaText[1]) << 4) + StringUtils.HexDigit(alphaText[2])) / 255.0f;
|
||||
}
|
||||
else if (alphaText.Length > 1 && alphaText[alphaText.Length - 1] == '%')
|
||||
{
|
||||
style.Color.A = float.Parse(alphaText.Substring(0, alphaText.Length - 1)) / 100.0f;
|
||||
}
|
||||
}
|
||||
context.StyleStack.Push(style);
|
||||
}
|
||||
@@ -93,16 +89,9 @@ namespace FlaxEngine.GUI
|
||||
style.Font = new FontReference(style.Font);
|
||||
if (tag.Attributes.TryGetValue(string.Empty, out var fontName))
|
||||
{
|
||||
var ids = Content.GetAllAssetsByType(typeof(FontAsset));
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (Content.GetAssetInfo(id, out var info) && string.Equals(fontName, System.IO.Path.GetFileNameWithoutExtension(info.Path), System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var font = Content.LoadAsync<FontAsset>(id);
|
||||
if (font != null)
|
||||
style.Font.Font = font;
|
||||
}
|
||||
}
|
||||
var font = (FontAsset)FindAsset(fontName, typeof(FontAsset));
|
||||
if (font)
|
||||
style.Font.Font = font;
|
||||
}
|
||||
if (tag.Attributes.TryGetValue("size", out var sizeText) && int.TryParse(sizeText, out var size))
|
||||
style.Font.Size = size;
|
||||
@@ -148,15 +137,80 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
var style = context.StyleStack.Peek();
|
||||
style.Font = new FontReference(style.Font);
|
||||
if (tag.Attributes.TryGetValue(string.Empty, out var sizeText))
|
||||
{
|
||||
if (int.TryParse(sizeText, out var sizeInt))
|
||||
style.Font.Size = sizeInt;
|
||||
if (sizeText.Length > 1 && sizeText[sizeText.Length - 1] == '%')
|
||||
style.Font.Size = (int)(style.Font.Size * float.Parse(sizeText.Substring(0, sizeText.Length - 1)) / 100.0f);
|
||||
}
|
||||
TryParseNumberTag(ref tag, string.Empty, style.Font.Size, out var size);
|
||||
style.Font.Size = (int)size;
|
||||
context.StyleStack.Push(style);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessImage(ref ParsingContext context, ref HtmlTag tag)
|
||||
{
|
||||
// Get image brush
|
||||
IBrush image = null;
|
||||
if (tag.Attributes.TryGetValue(string.Empty, out var srcText) || tag.Attributes.TryGetValue("src", out srcText))
|
||||
{
|
||||
if (!context.Control.Images.TryGetValue(srcText, out image))
|
||||
{
|
||||
var tex = (Texture)FindAsset(srcText, typeof(Texture));
|
||||
if (tex)
|
||||
image = new TextureBrush(tex);
|
||||
}
|
||||
}
|
||||
if (image == null)
|
||||
return;
|
||||
|
||||
// Create image block
|
||||
var imageBlock = new TextBlock
|
||||
{
|
||||
Range = new TextRange
|
||||
{
|
||||
StartIndex = tag.StartPosition,
|
||||
EndIndex = tag.StartPosition,
|
||||
},
|
||||
Style = context.StyleStack.Peek(),
|
||||
Bounds = new Rectangle(context.Caret, new Float2(64.0f)),
|
||||
};
|
||||
imageBlock.Style.BackgroundBrush = image;
|
||||
|
||||
// Setup size
|
||||
var font = imageBlock.Style.Font.GetFont();
|
||||
if (font)
|
||||
imageBlock.Bounds.Size = new Float2(font.Height);
|
||||
imageBlock.Bounds.Size.X *= image.Size.X / image.Size.Y; // Keep aspect ration
|
||||
TryParseNumberTag(ref tag, "width", imageBlock.Bounds.Width, out var width);
|
||||
imageBlock.Bounds.Width = width;
|
||||
TryParseNumberTag(ref tag, "height", imageBlock.Bounds.Height, out var height);
|
||||
imageBlock.Bounds.Height = height;
|
||||
TryParseNumberTag(ref tag, "scale", 1.0f, out var scale);
|
||||
imageBlock.Bounds.Size *= scale;
|
||||
|
||||
context.AddTextBlock(ref imageBlock);
|
||||
context.Caret.X += imageBlock.Bounds.Size.X;
|
||||
}
|
||||
|
||||
private static Asset FindAsset(string name, System.Type type)
|
||||
{
|
||||
var ids = Content.GetAllAssetsByType(type);
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (Content.GetAssetInfo(id, out var info) && string.Equals(name, System.IO.Path.GetFileNameWithoutExtension(info.Path), System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return Content.LoadAsync(id, type);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void TryParseNumberTag(ref HtmlTag tag, string name, float input, out float output)
|
||||
{
|
||||
output = input;
|
||||
if (tag.Attributes.TryGetValue(name, out var text))
|
||||
{
|
||||
if (float.TryParse(text, out var width))
|
||||
output = width;
|
||||
if (text.Length > 1 && text[text.Length - 1] == '%')
|
||||
output = input * float.Parse(text.Substring(0, text.Length - 1)) / 100.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,12 @@ namespace FlaxEngine.GUI
|
||||
[EditorOrder(30)]
|
||||
public Dictionary<string, TextBlockStyle> Styles = new Dictionary<string, TextBlockStyle>();
|
||||
|
||||
/// <summary>
|
||||
/// The collection of custom images/sprites that can be inlined in text (named).
|
||||
/// </summary>
|
||||
[EditorOrder(40)]
|
||||
public Dictionary<string, IBrush> Images = new Dictionary<string, IBrush>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RichTextBox"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -267,11 +267,17 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
}
|
||||
|
||||
// Draw selection background
|
||||
// Draw background
|
||||
for (int i = firstTextBlock; i < endTextBlock; i++)
|
||||
{
|
||||
ref TextBlock textBlock = ref textBlocks[i];
|
||||
|
||||
// Background
|
||||
if (textBlock.Style.BackgroundBrush != null)
|
||||
{
|
||||
textBlock.Style.BackgroundBrush.Draw(textBlock.Bounds, textBlock.Style.Color);
|
||||
}
|
||||
|
||||
// Pick font
|
||||
var font = textBlock.Style.Font.GetFont();
|
||||
if (!font)
|
||||
|
||||
@@ -37,6 +37,12 @@ namespace FlaxEngine.GUI
|
||||
[EditorOrder(40), Tooltip("The text shadow offset from the text location. Set to zero to disable shadow drawing.")]
|
||||
public Float2 ShadowOffset;
|
||||
|
||||
/// <summary>
|
||||
/// The background brush for the text range.
|
||||
/// </summary>
|
||||
[EditorOrder(45), Tooltip("The background brush for the text range.")]
|
||||
public IBrush BackgroundBrush;
|
||||
|
||||
/// <summary>
|
||||
/// The background brush for the selected text range.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user