mirror of
https://github.com/4sval/FModel.git
synced 2026-03-21 17:24:26 -05:00
commit
1b93086307
|
|
@ -45,7 +45,7 @@ namespace FModel.Creator.Bases
|
|||
if (Description.Equals(DisplayName)) Description = string.Empty;
|
||||
if (!string.IsNullOrEmpty(Description))
|
||||
{
|
||||
Height += (int)descriptionPaint.TextSize * Helper.SplitLines(Description, descriptionPaint, Width - Margin).Length;
|
||||
Height += (int)descriptionPaint.TextSize * Helper.SplitLines(Description, descriptionPaint, Width - Margin).Count;
|
||||
Height += (int)descriptionPaint.TextSize;
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ namespace FModel.Creator.Bases
|
|||
s.Description = Text.GetTextPropertyBase(aDescription) ?? "";
|
||||
if (!string.IsNullOrEmpty(Description))
|
||||
{
|
||||
s.Height += (int)descriptionPaint.TextSize * Helper.SplitLines(s.Description, descriptionPaint, Width - Margin).Length;
|
||||
s.Height += (int)descriptionPaint.TextSize * Helper.SplitLines(s.Description, descriptionPaint, Width - Margin).Count;
|
||||
s.Height += (int)descriptionPaint.TextSize * 3;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace FModel.Creator.Bases
|
|||
OptionDescription = Text.GetTextPropertyBase(optionDescription);
|
||||
if (!string.IsNullOrEmpty(OptionDescription))
|
||||
{
|
||||
Height += (int)descriptionPaint.TextSize * Helper.SplitLines(OptionDescription, descriptionPaint, Width - Margin).Length;
|
||||
Height += (int)descriptionPaint.TextSize * Helper.SplitLines(OptionDescription, descriptionPaint, Width - Margin).Count;
|
||||
Height += (int)descriptionPaint.TextSize;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using FModel.Properties;
|
||||
|
||||
using SkiaSharp.HarfBuzz;
|
||||
|
||||
namespace FModel.Creator.Texts
|
||||
{
|
||||
static class Helper
|
||||
|
|
@ -19,33 +23,56 @@ namespace FModel.Creator.Texts
|
|||
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, int size, int margin, ETextSide side, SKRect area, SKPaint paint)
|
||||
{
|
||||
float lineHeight = paint.TextSize * 1.2f;
|
||||
Line[] lines = SplitLines(text, paint, area.Width - margin);
|
||||
List<Line> lines = SplitLines(text, paint, area.Width - margin);
|
||||
|
||||
if (lines == null)
|
||||
return;
|
||||
if (lines.Length <= maxLineCount)
|
||||
maxLineCount = lines.Length;
|
||||
if (lines.Count <= maxLineCount)
|
||||
maxLineCount = lines.Count;
|
||||
|
||||
float height = maxLineCount * lineHeight;
|
||||
float y = area.MidY - height / 2;
|
||||
SKShaper shaper = (ELanguage)Settings.Default.AssetsLanguage == ELanguage.Arabic ? new SKShaper(paint.Typeface) : null;
|
||||
|
||||
for (int i = 0; i < maxLineCount; i++)
|
||||
{
|
||||
Line line = lines[i];
|
||||
|
||||
y += lineHeight;
|
||||
float x = side switch
|
||||
{
|
||||
ETextSide.Center => area.MidX - lines[i].Width / 2,
|
||||
ETextSide.Right => size - margin - lines[i].Width,
|
||||
ETextSide.Center => area.MidX - line.Width / 2,
|
||||
ETextSide.Right => size - margin - line.Width,
|
||||
ETextSide.Left => margin,
|
||||
_ => area.MidX - lines[i].Width / 2
|
||||
_ => area.MidX - line.Width / 2
|
||||
};
|
||||
canvas.DrawText(lines[i].Value.TrimEnd(), x, y, paint);
|
||||
|
||||
string lineText = line.Value.TrimEnd();
|
||||
|
||||
if (shaper == null)
|
||||
{
|
||||
canvas.DrawText(lineText, x, y, paint);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (side == ETextSide.Center)
|
||||
{
|
||||
SKShaper.Result shapedText = shaper.Shape(lineText, paint);
|
||||
float shapedTextWidth = shapedText.Points[^1].X + paint.TextSize / 2f;
|
||||
canvas.DrawShapedText(shaper, lineText, (area.Width - shapedTextWidth) / 2f, y, paint);
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas.DrawShapedText(shaper, lineText, x, y, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawMultilineText(SKCanvas canvas, string text, int size, int margin, ETextSide side, SKRect area, SKPaint paint, out int yPos)
|
||||
{
|
||||
float lineHeight = paint.TextSize * 1.2f;
|
||||
Line[] lines = SplitLines(text, paint, area.Width);
|
||||
List<Line> lines = SplitLines(text, paint, area.Width);
|
||||
if (lines == null)
|
||||
{
|
||||
yPos = (int)area.Top;
|
||||
|
|
@ -53,22 +80,45 @@ namespace FModel.Creator.Texts
|
|||
}
|
||||
|
||||
float y = area.Top;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
SKShaper shaper = (ELanguage)Settings.Default.AssetsLanguage == ELanguage.Arabic ? new SKShaper(paint.Typeface) : null;
|
||||
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
float x = side switch
|
||||
{
|
||||
ETextSide.Center => area.MidX - lines[i].Width / 2,
|
||||
ETextSide.Right => size - margin - lines[i].Width,
|
||||
ETextSide.Center => area.MidX - line.Width / 2,
|
||||
ETextSide.Right => size - margin - line.Width,
|
||||
ETextSide.Left => area.Left,
|
||||
_ => area.MidX - lines[i].Width / 2
|
||||
_ => area.MidX - line.Width / 2
|
||||
};
|
||||
canvas.DrawText(lines[i].Value.TrimEnd(), x, y, paint);
|
||||
|
||||
string lineText = line.Value.TrimEnd();
|
||||
|
||||
if (shaper == null)
|
||||
{
|
||||
canvas.DrawText(lineText, x, y, paint);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (side == ETextSide.Center)
|
||||
{
|
||||
SKShaper.Result shapedText = shaper.Shape(lineText, paint);
|
||||
float shapedTextWidth = shapedText.Points[^1].X + paint.TextSize / 2f;
|
||||
canvas.DrawShapedText(shaper, lineText, (area.Width - shapedTextWidth) / 2f, y, paint);
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas.DrawShapedText(shaper, lineText, x, y, paint);
|
||||
}
|
||||
}
|
||||
|
||||
y += lineHeight;
|
||||
}
|
||||
yPos = (int)area.Top + ((int)lineHeight * lines.Length);
|
||||
yPos = (int)area.Top + ((int)lineHeight * lines.Count);
|
||||
}
|
||||
|
||||
public static Line[] SplitLines(string text, SKPaint paint, float maxWidth)
|
||||
public static List<Line> SplitLines(string text, SKPaint paint, float maxWidth)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return null;
|
||||
|
|
@ -84,7 +134,7 @@ namespace FModel.Creator.Texts
|
|||
|
||||
float width = 0;
|
||||
var lineResult = new StringBuilder();
|
||||
string[] words = lines[i].Split(' ', StringSplitOptions.None);
|
||||
string[] words = lines[i].Split(' ');
|
||||
foreach (var word in words)
|
||||
{
|
||||
float wordWidth = paint.MeasureText(word);
|
||||
|
|
@ -105,7 +155,7 @@ namespace FModel.Creator.Texts
|
|||
}
|
||||
ret.Add(new Line { Value = lineResult.ToString(), Width = width });
|
||||
}
|
||||
return ret.ToArray();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
using FModel.Creator.Bases;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FModel.Creator.Bases;
|
||||
using FModel.Properties;
|
||||
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
|
||||
using SkiaSharp;
|
||||
using System.Collections.Generic;
|
||||
using SkiaSharp.HarfBuzz;
|
||||
|
||||
namespace FModel.Creator.Texts
|
||||
{
|
||||
|
|
@ -17,7 +23,7 @@ namespace FModel.Creator.Texts
|
|||
|
||||
public static string GetTextPropertyBase(TextProperty t)
|
||||
{
|
||||
if (t.Value is FText text)
|
||||
if (t.Value is { } text)
|
||||
if (text.Text is FTextHistory.None n)
|
||||
return n.CultureInvariantString;
|
||||
else if (text.Text is FTextHistory.Base b)
|
||||
|
|
@ -51,7 +57,7 @@ namespace FModel.Creator.Texts
|
|||
|
||||
public static (string, string, string) GetTextPropertyBases(TextProperty t)
|
||||
{
|
||||
if (t.Value is FText text && text.Text is FTextHistory.Base b)
|
||||
if (t.Value is { } text && text.Text is FTextHistory.Base b)
|
||||
return (b.Namespace, b.Key, b.SourceString);
|
||||
return (string.Empty, string.Empty, string.Empty);
|
||||
}
|
||||
|
|
@ -62,7 +68,8 @@ namespace FModel.Creator.Texts
|
|||
{
|
||||
if (o1.TryGetValue("Value", out var c) && c is FloatProperty value && value.Value != -1) // old way
|
||||
return $"MaxStackSize : {value.Value}";
|
||||
else if (
|
||||
|
||||
if (
|
||||
o1.TryGetValue("Curve", out var c1) && c1 is StructProperty curve && curve.Value is UObject o2 &&
|
||||
o2.TryGetValue("CurveTable", out var c2) && c2 is ObjectProperty curveTable &&
|
||||
o2.TryGetValue("RowName", out var c3) && c3 is NameProperty rowName) // new way
|
||||
|
|
@ -75,7 +82,7 @@ namespace FModel.Creator.Texts
|
|||
{
|
||||
if (table.TryGetValue(rowName.Value.String, out var v1) && v1 is UObject maxStackAmount &&
|
||||
maxStackAmount.TryGetValue("Keys", out var v2) && v2 is ArrayProperty keys &&
|
||||
keys.Value.Length > 0 && (keys.Value[0] as StructProperty).Value is FSimpleCurveKey amount &&
|
||||
keys.Value.Length > 0 && (keys.Value[0] as StructProperty)?.Value is FSimpleCurveKey amount &&
|
||||
amount.KeyValue != -1)
|
||||
{
|
||||
return $"MaxStackSize : {amount.KeyValue}";
|
||||
|
|
@ -104,7 +111,7 @@ namespace FModel.Creator.Texts
|
|||
{
|
||||
if (table.TryGetValue(rowName.Value.String, out var v1) && v1 is UObject maxStackAmount &&
|
||||
maxStackAmount.TryGetValue("Keys", out var v2) && v2 is ArrayProperty keys &&
|
||||
keys.Value.Length > 0 && (keys.Value[0] as StructProperty).Value is FSimpleCurveKey amount &&
|
||||
keys.Value.Length > 0 && (keys.Value[0] as StructProperty)?.Value is FSimpleCurveKey amount &&
|
||||
amount.KeyValue != -1)
|
||||
{
|
||||
return $"{amount.KeyValue} Xp";
|
||||
|
|
@ -118,14 +125,14 @@ namespace FModel.Creator.Texts
|
|||
|
||||
public static void DrawBackground(SKCanvas c, IBase icon)
|
||||
{
|
||||
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
|
||||
switch ((EIconDesign)Settings.Default.AssetsIconDesign)
|
||||
{
|
||||
case EIconDesign.Flat:
|
||||
{
|
||||
var pathBottom = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
pathBottom.MoveTo(icon.Margin, icon.Height - icon.Margin);
|
||||
pathBottom.LineTo(icon.Margin, icon.Height - icon.Margin - (icon.Height / 17 * 2.5f));
|
||||
pathBottom.LineTo(icon.Width - icon.Margin, icon.Height - icon.Margin - (icon.Height / 17 * 4.5f));
|
||||
pathBottom.LineTo(icon.Margin, icon.Height - icon.Margin - icon.Height / 17 * 2.5f);
|
||||
pathBottom.LineTo(icon.Width - icon.Margin, icon.Height - icon.Margin - icon.Height / 17 * 4.5f);
|
||||
pathBottom.LineTo(icon.Width - icon.Margin, icon.Height - icon.Margin);
|
||||
pathBottom.Close();
|
||||
c.DrawPath(pathBottom, new SKPaint
|
||||
|
|
@ -158,12 +165,12 @@ namespace FModel.Creator.Texts
|
|||
SKTextAlign side = SKTextAlign.Center;
|
||||
int x = icon.Width / 2;
|
||||
int y = _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE;
|
||||
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
|
||||
switch ((EIconDesign)Settings.Default.AssetsIconDesign)
|
||||
{
|
||||
case EIconDesign.Mini:
|
||||
{
|
||||
_NAME_TEXT_SIZE = 47;
|
||||
text = text.ToUpper();
|
||||
text = text.ToUpperInvariant();
|
||||
break;
|
||||
}
|
||||
case EIconDesign.Flat:
|
||||
|
|
@ -182,16 +189,41 @@ namespace FModel.Creator.Texts
|
|||
Typeface = TypeFaces.DisplayNameTypeface,
|
||||
TextSize = _NAME_TEXT_SIZE,
|
||||
Color = SKColors.White,
|
||||
TextAlign = side,
|
||||
TextAlign = side
|
||||
};
|
||||
|
||||
// resize if too long
|
||||
while (namePaint.MeasureText(text) > (icon.Width - (icon.Margin * 2)))
|
||||
if ((ELanguage)Settings.Default.AssetsLanguage == ELanguage.Arabic)
|
||||
{
|
||||
namePaint.TextSize = _NAME_TEXT_SIZE -= 2;
|
||||
}
|
||||
SKShaper shaper = new SKShaper(namePaint.Typeface);
|
||||
float shapedTextWidth;
|
||||
|
||||
c.DrawText(text, x, y, namePaint);
|
||||
while (true)
|
||||
{
|
||||
SKShaper.Result shapedText = shaper.Shape(text, namePaint);
|
||||
shapedTextWidth = shapedText.Points[^1].X + namePaint.TextSize / 2f;
|
||||
|
||||
if (shapedTextWidth > icon.Width - icon.Margin * 2)
|
||||
{
|
||||
namePaint.TextSize = _NAME_TEXT_SIZE -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c.DrawShapedText(shaper, text, (icon.Width - shapedTextWidth) / 2f, y, namePaint);
|
||||
}
|
||||
else
|
||||
{
|
||||
// resize if too long
|
||||
while (namePaint.MeasureText(text) > icon.Width - icon.Margin * 2)
|
||||
{
|
||||
namePaint.TextSize = _NAME_TEXT_SIZE -= 1;
|
||||
}
|
||||
|
||||
c.DrawText(text, x, y, namePaint);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawDescription(SKCanvas c, IBase icon)
|
||||
|
|
@ -200,7 +232,7 @@ namespace FModel.Creator.Texts
|
|||
_BOTTOM_TEXT_SIZE = 15;
|
||||
string text = icon.Description;
|
||||
ETextSide side = ETextSide.Center;
|
||||
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
|
||||
switch ((EIconDesign)Settings.Default.AssetsIconDesign)
|
||||
{
|
||||
case EIconDesign.Mini:
|
||||
{
|
||||
|
|
@ -243,7 +275,23 @@ namespace FModel.Creator.Texts
|
|||
TextAlign = side == ETextSide.Left ? SKTextAlign.Left : SKTextAlign.Right,
|
||||
};
|
||||
|
||||
c.DrawText(text, side == ETextSide.Left ? icon.Margin * 2.5f : icon.Size - (icon.Margin * 2.5f), icon.Size - (icon.Margin * 2.5f), shortDescriptionPaint);
|
||||
if (side == ETextSide.Left)
|
||||
{
|
||||
if ((ELanguage)Settings.Default.AssetsLanguage == ELanguage.Arabic)
|
||||
{
|
||||
shortDescriptionPaint.TextSize -= 4f;
|
||||
SKShaper shaper = new SKShaper(shortDescriptionPaint.Typeface);
|
||||
c.DrawShapedText(shaper, text, icon.Margin * 2.5f, icon.Size - icon.Margin * 2.5f - shortDescriptionPaint.TextSize * .5f /* ¯\_(ツ)_/¯ */, shortDescriptionPaint);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.DrawText(text, icon.Margin * 2.5f, icon.Size - icon.Margin * 2.5f, shortDescriptionPaint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c.DrawText(text, icon.Size - icon.Margin * 2.5f, icon.Size - icon.Margin * 2.5f, shortDescriptionPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@
|
|||
<PackageReference Include="NVorbis" Version="0.10.1" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.80.2" />
|
||||
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.80.2" />
|
||||
<PackageReference Include="ToastNotifications" Version="2.5.1" />
|
||||
<PackageReference Include="ToastNotifications.Messages" Version="2.5.1" />
|
||||
<PackageReference Include="WriteableBitmapEx" Version="1.6.7" />
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace FModel.Grabber.Paks
|
|||
{
|
||||
static class PaksGrabber
|
||||
{
|
||||
private static readonly Regex _pakFileRegex = new Regex(@"^FortniteGame/Content/Paks/.+\.pak$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _pakFileRegex = new Regex(@"^FortniteGame/Content/Paks/.+\.pak$", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||
|
||||
public static async Task PopulateMenu()
|
||||
{
|
||||
|
|
@ -41,9 +41,10 @@ namespace FModel.Grabber.Paks
|
|||
}
|
||||
|
||||
// Add Pak Files
|
||||
if (Properties.Settings.Default.PakPath.EndsWith(".manifest") && await ManifestGrabber.TryGetLatestManifestInfo().ConfigureAwait(false) is ManifestInfo manifestInfo)
|
||||
if (Properties.Settings.Default.PakPath.EndsWith(".manifest"))
|
||||
{
|
||||
var manifestData = await manifestInfo.DownloadManifestDataAsync();
|
||||
ManifestInfo manifestInfo = await ManifestGrabber.TryGetLatestManifestInfo().ConfigureAwait(false);
|
||||
byte[] manifestData = await manifestInfo.DownloadManifestDataAsync().ConfigureAwait(false);
|
||||
Manifest manifest = new Manifest(manifestData, new ManifestOptions
|
||||
{
|
||||
ChunkBaseUri = new Uri("http://download.epicgames.com/Builds/Fortnite/CloudDir/ChunksV3/", UriKind.Absolute),
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ namespace FModel.ViewModels.ImageBox
|
|||
{
|
||||
Title = vm.Name,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
||||
Width = vm.Image.Width,
|
||||
Height = vm.Image.Height
|
||||
Width = vm.Image.Width + 16,
|
||||
Height = vm.Image.Height + 39
|
||||
};
|
||||
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
if (vm.Image.Height > 1000)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user