Projektdateien hinzufügen.
This commit is contained in:
24
Pilz.Dalamud/Tools/Strings/StringChange.cs
Normal file
24
Pilz.Dalamud/Tools/Strings/StringChange.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Dalamud.Tools.Strings
|
||||
{
|
||||
public class StringChange
|
||||
{
|
||||
/// <summary>
|
||||
/// The payloads to use for inserting/replacing.
|
||||
/// </summary>
|
||||
public List<Payload> Payloads { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Defines if only one anchor payload should be used, if using anchor payloads.
|
||||
/// With this true the single anchor payload will be used in StringUpdateFactory instead of the anchor payload list.
|
||||
/// Not needed to be true for the most cases.
|
||||
/// </summary>
|
||||
public bool ForceUsingSingleAnchorPayload { get; set; } = false;
|
||||
}
|
||||
}
|
||||
40
Pilz.Dalamud/Tools/Strings/StringChanges.cs
Normal file
40
Pilz.Dalamud/Tools/Strings/StringChanges.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Dalamud.Tools.Strings
|
||||
{
|
||||
public class StringChanges
|
||||
{
|
||||
private readonly Dictionary<StringPosition, StringChange> changes = new();
|
||||
|
||||
public StringChanges()
|
||||
{
|
||||
changes.Add(StringPosition.Before, new StringChange());
|
||||
changes.Add(StringPosition.After, new StringChange());
|
||||
changes.Add(StringPosition.Replace, new StringChange());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a change of the position of your choice where you can add your payloads.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of your choice.</param>
|
||||
/// <returns></returns>
|
||||
public StringChange GetChange(StringPosition position)
|
||||
{
|
||||
return changes[position];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if there is any string change listed.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Any()
|
||||
{
|
||||
return changes.Sum(n => n.Value.Payloads.Count) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Pilz.Dalamud/Tools/Strings/StringChangesProps.cs
Normal file
31
Pilz.Dalamud/Tools/Strings/StringChangesProps.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Dalamud.Tools.Strings
|
||||
{
|
||||
public class StringChangesProps
|
||||
{
|
||||
/// <summary>
|
||||
/// The string where the changes should be applied.
|
||||
/// </summary>
|
||||
public SeString Destination { get; set; }
|
||||
/// <summary>
|
||||
/// The changes that should be applied to the destination.
|
||||
/// </summary>
|
||||
public StringChanges StringChanges { get; set; }
|
||||
/// <summary>
|
||||
/// Payloads to use as anchor where the changes should be applied to.
|
||||
/// </summary>
|
||||
public List<Payload> AnchorPayloads { get; set; }
|
||||
/// <summary>
|
||||
/// A single payload to use as anchor where the changes should be applied to.
|
||||
/// This property will only be used if StringChange.ForceSingleAnchorPayload is true.
|
||||
/// </summary>
|
||||
public Payload AnchorPayload { get; set; }
|
||||
}
|
||||
}
|
||||
15
Pilz.Dalamud/Tools/Strings/StringPosition.cs
Normal file
15
Pilz.Dalamud/Tools/Strings/StringPosition.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Dalamud.Tools.Strings
|
||||
{
|
||||
public enum StringPosition
|
||||
{
|
||||
Before,
|
||||
After,
|
||||
Replace
|
||||
}
|
||||
}
|
||||
132
Pilz.Dalamud/Tools/Strings/StringUpdateFactory.cs
Normal file
132
Pilz.Dalamud/Tools/Strings/StringUpdateFactory.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Lumina.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Dalamud.Tools.Strings
|
||||
{
|
||||
public static class StringUpdateFactory
|
||||
{
|
||||
public static void ApplyStringChanges(StringChangesProps props)
|
||||
{
|
||||
if (props.StringChanges.Any())
|
||||
{
|
||||
var seString = props.Destination;
|
||||
List<StringPosition> stringPositionsOrdered = GetOrderedStringPositions(props);
|
||||
|
||||
foreach (var stringPosition in stringPositionsOrdered)
|
||||
{
|
||||
var stringChange = props.StringChanges.GetChange(stringPosition);
|
||||
if (stringChange != null && stringChange.Payloads.Any())
|
||||
{
|
||||
AddSpacesBetweenTextPayloads(stringChange.Payloads, stringPosition);
|
||||
|
||||
if (stringPosition == StringPosition.Before)
|
||||
{
|
||||
Payload anchorFirst = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.FirstOrDefault();
|
||||
|
||||
if (anchorFirst != null)
|
||||
{
|
||||
var anchorPayloadIndex = seString.Payloads.IndexOf(anchorFirst);
|
||||
seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads);
|
||||
}
|
||||
else
|
||||
seString.Payloads.InsertRange(0, stringChange.Payloads);
|
||||
}
|
||||
else if (stringPosition == StringPosition.After)
|
||||
{
|
||||
Payload anchorLast = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.LastOrDefault();
|
||||
|
||||
if (anchorLast != null)
|
||||
{
|
||||
var anchorPayloadIndex = seString.Payloads.IndexOf(anchorLast);
|
||||
seString.Payloads.InsertRange(anchorPayloadIndex + 1, stringChange.Payloads);
|
||||
}
|
||||
else
|
||||
seString.Payloads.AddRange(stringChange.Payloads);
|
||||
}
|
||||
else if (stringPosition == StringPosition.Replace)
|
||||
{
|
||||
Payload anchorReplace = props.AnchorPayload;
|
||||
|
||||
if (anchorReplace != null)
|
||||
{
|
||||
var anchorPayloadIndex = seString.Payloads.IndexOf(anchorReplace);
|
||||
seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads);
|
||||
seString.Remove(anchorReplace);
|
||||
}
|
||||
else
|
||||
{
|
||||
seString.Payloads.Clear();
|
||||
seString.Payloads.AddRange(stringChange.Payloads);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddSpacesBetweenTextPayloads(List<Payload> payloads, StringPosition tagPosition)
|
||||
{
|
||||
if (payloads != null && payloads.Any())
|
||||
{
|
||||
var indicesToInsertSpacesAt = new List<int>();
|
||||
var lastTextPayloadIndex = -1;
|
||||
|
||||
static TextPayload getNewTextPayload() => new(" ");
|
||||
|
||||
foreach (var payload in payloads.Reverse<Payload>())
|
||||
{
|
||||
if (payload is IconPayload iconPayload)
|
||||
lastTextPayloadIndex = -1;
|
||||
else if (payload is TextPayload textPayload)
|
||||
{
|
||||
if (lastTextPayloadIndex != -1)
|
||||
indicesToInsertSpacesAt.Add(payloads.IndexOf(textPayload) + 1);
|
||||
lastTextPayloadIndex = payloads.IndexOf(textPayload);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var indexToInsertSpaceAt in indicesToInsertSpacesAt)
|
||||
payloads.Insert(indexToInsertSpaceAt, getNewTextPayload());
|
||||
|
||||
// Decide whether to add a space to the end
|
||||
if (tagPosition == StringPosition.Before)
|
||||
{
|
||||
var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload);
|
||||
if (significantPayloads.Last() is TextPayload)
|
||||
payloads.Add(getNewTextPayload());
|
||||
}
|
||||
// Decide whether to add a space to the beginning
|
||||
else if (tagPosition == StringPosition.After)
|
||||
{
|
||||
var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload);
|
||||
if (significantPayloads.First() is TextPayload)
|
||||
payloads.Insert(0, getNewTextPayload());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<StringPosition> GetOrderedStringPositions(StringChangesProps props)
|
||||
{
|
||||
var tagPositionsOrdered = new List<StringPosition>();
|
||||
|
||||
// If there's no anchor payload, do replaces first so that befores and afters are based on the replaced data
|
||||
if (props.AnchorPayloads == null || !props.AnchorPayloads.Any())
|
||||
tagPositionsOrdered.Add(StringPosition.Replace);
|
||||
|
||||
tagPositionsOrdered.Add(StringPosition.Before);
|
||||
tagPositionsOrdered.Add(StringPosition.After);
|
||||
|
||||
// If there is an anchor payload, do replaces last so that we still know which payload needs to be removed
|
||||
if (props.AnchorPayloads != null && props.AnchorPayloads.Any())
|
||||
tagPositionsOrdered.Add(StringPosition.Replace);
|
||||
|
||||
return tagPositionsOrdered;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user