FModel/FModel/Creator/Bases/FN/BaseUserControl.cs
2023-05-23 00:38:31 +02:00

192 lines
6.8 KiB
C#

using System.Collections.Generic;
using System.Globalization;
using CUE4Parse.UE4.Assets.Exports;
using CUE4Parse.UE4.Assets.Objects;
using CUE4Parse.UE4.Objects.Core.i18N;
using CUE4Parse.UE4.Objects.Core.Math;
using CUE4Parse.UE4.Objects.UObject;
using FModel.Framework;
using SkiaSharp;
using SkiaSharp.HarfBuzz;
namespace FModel.Creator.Bases.FN;
public class BaseUserControl : UCreator
{
private List<Options> _optionValues = new();
private readonly SKPaint _displayNamePaint = new()
{
IsAntialias = true, FilterQuality = SKFilterQuality.High,
Typeface = Utils.Typefaces.DisplayName, TextSize = 45,
Color = SKColors.White, TextAlign = SKTextAlign.Left
};
private readonly SKPaint _descriptionPaint = new()
{
IsAntialias = true, FilterQuality = SKFilterQuality.High,
Typeface = Utils.Typefaces.DisplayName, TextSize = 25,
Color = SKColor.Parse("88DBFF"), TextAlign = SKTextAlign.Left
};
public BaseUserControl(UObject uObject, EIconStyle style) : base(uObject, style)
{
Width = 512;
Height = 128;
Margin = 32;
}
public override void ParseForInfo()
{
if (Object.TryGetValue(out FText optionDisplayName, "OptionDisplayName", "OptionText"))
DisplayName = optionDisplayName.Text.ToUpperInvariant();
if (Object.TryGetValue(out FText optionDescription, "OptionDescription", "OptionToolTip"))
{
Description = optionDescription.Text;
if (string.IsNullOrWhiteSpace(Description)) return;
Height += (int) _descriptionPaint.TextSize * Utils.SplitLines(Description, _descriptionPaint, Width - Margin).Count;
Height += (int) _descriptionPaint.TextSize;
}
if (Object.TryGetValue(out FStructFallback[] optionValues, "OptionValues", "Options"))
{
_optionValues = new List<Options>();
foreach (var option in optionValues)
{
if (option.TryGetValue(out FText displayName, "DisplayName", "DisplayText"))
{
var opt = new Options { Option = displayName.Text.ToUpperInvariant() };
if (option.TryGetValue(out FLinearColor color, "Value"))
opt.Color = SKColor.Parse(color.Hex).WithAlpha(150);
_optionValues.Add(opt);
}
else if (option.TryGetValue(out FName primaryAssetName, "PrimaryAssetName"))
{
_optionValues.Add(new Options { Option = primaryAssetName.Text });
}
}
}
if (Object.TryGetValue(out FText optionOnText, "OptionOnText"))
_optionValues.Add(new Options { Option = optionOnText.Text });
if (Object.TryGetValue(out FText optionOffText, "OptionOffText"))
_optionValues.Add(new Options { Option = optionOffText.Text });
if (Object.TryGetValue(out int iMin, "Min", "DefaultValue") &&
Object.TryGetValue(out int iMax, "Max"))
{
var increment = iMin;
if (Object.TryGetValue(out int incrementValue, "IncrementValue"))
increment = incrementValue;
var format = "{0}";
if (Object.TryGetValue(out FText unitName, "UnitName"))
format = unitName.Text;
for (var i = iMin; i <= iMax; i += increment)
{
_optionValues.Add(new Options { Option = string.Format(format, i) });
}
}
if (Object.TryGetValue(out float fMin, "Min", "DefaultValue") &&
Object.TryGetValue(out float fMax, "Max"))
{
var increment = fMin;
if (Object.TryGetValue(out float incrementValue, "IncrementValue"))
increment = incrementValue;
var format = "{0}";
if (Object.TryGetValue(out FText unitName, "UnitName"))
format = unitName.Text;
for (var i = fMin; i <= fMax; i += increment)
{
_optionValues.Add(new Options { Option = string.Format(format, i) });
}
}
Height += Margin;
Height += 35 * _optionValues.Count;
}
public override SKBitmap[] Draw()
{
var ret = new SKBitmap(Width, Height, SKColorType.Rgba8888, SKAlphaType.Opaque);
using var c = new SKCanvas(ret);
DrawBackground(c);
DrawInformation(c);
return new[] { ret };
}
private new void DrawBackground(SKCanvas c)
{
c.DrawRect(new SKRect(0, 0, Width, Height),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateLinearGradient(
new SKPoint(Width / 2, Height),
new SKPoint(Width, Height / 4),
new[] { SKColor.Parse("01369C"), SKColor.Parse("1273C8") },
SKShaderTileMode.Clamp)
});
}
private void DrawInformation(SKCanvas c)
{
// display name
while (_displayNamePaint.MeasureText(DisplayName) > Width - Margin * 2)
{
_displayNamePaint.TextSize -= 2;
}
var shaper = new CustomSKShaper(_displayNamePaint.Typeface);
c.DrawShapedText(shaper, DisplayName, Margin, Margin + _displayNamePaint.TextSize, _displayNamePaint);
#if DEBUG
c.DrawRect(new SKRect(Margin, Margin, Width - Margin, Margin + _displayNamePaint.TextSize), new SKPaint { Color = SKColors.Blue, IsStroke = true });
#endif
// description
float y = Margin;
if (!string.IsNullOrEmpty(DisplayName)) y += _displayNamePaint.TextSize;
if (!string.IsNullOrEmpty(Description)) y += _descriptionPaint.TextSize + Margin / 2F;
Utils.DrawMultilineText(c, Description, Width, Margin, SKTextAlign.Left,
new SKRect(Margin, y, Width - Margin, 256), _descriptionPaint, out var top);
// options
foreach (var option in _optionValues)
{
option.Draw(c, Margin, Width, ref top);
}
}
}
public class Options
{
private const int _SPACE = 5;
private const int _HEIGHT = 30;
private readonly SKPaint _optionPaint = new()
{
IsAntialias = true, FilterQuality = SKFilterQuality.High,
Typeface = Utils.Typefaces.DisplayName, TextSize = 20,
Color = SKColor.Parse("EEFFFF"), TextAlign = SKTextAlign.Left
};
public string Option;
public SKColor Color = SKColor.Parse("55C5FC").WithAlpha(150);
public void Draw(SKCanvas c, int margin, int width, ref float top)
{
c.DrawRect(new SKRect(margin, top, width - margin, top + _HEIGHT), new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High, Color = Color });
c.DrawText(Option, margin + _SPACE * 2, top + 20 * 1.1f, _optionPaint);
top += _HEIGHT + _SPACE;
}
}