Add ITextureProvider.CreateTextureFromSeString

This commit is contained in:
Soreepeong 2025-07-01 19:02:32 +09:00
parent d3bd5f1dce
commit c19ea6ace3
19 changed files with 629 additions and 215 deletions

View file

@ -6,10 +6,12 @@ using System.Text;
using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
using Dalamud.Game;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.ImGuiNotification.Internal;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.Windows.Data.Widgets;
using Dalamud.Interface.Textures.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Serilog;
@ -33,6 +35,14 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
this.interfaceManager.Draw += this.InterfaceManagerOnDraw;
}
private enum ContextMenuActionType
{
None,
SaveAsFile,
CopyToClipboard,
SendToTexWidget,
}
/// <inheritdoc/>
void IInternalDisposableService.DisposeService() => this.interfaceManager.Draw -= this.InterfaceManagerOnDraw;
@ -66,15 +76,16 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
var textureManager = await Service<TextureManager>.GetAsync();
var popupName = $"{nameof(this.ShowTextureSaveMenuAsync)}_{textureWrap.Handle.Handle:X}";
ContextMenuActionType action;
BitmapCodecInfo? encoder;
{
var first = true;
var encoders = textureManager.Wic.GetSupportedEncoderInfos().ToList();
var tcs = new TaskCompletionSource<BitmapCodecInfo?>(
var tcs = new TaskCompletionSource<(ContextMenuActionType Action, BitmapCodecInfo? Codec)>(
TaskCreationOptions.RunContinuationsAsynchronously);
Service<InterfaceManager>.Get().Draw += DrawChoices;
encoder = await tcs.Task;
(action, encoder) = await tcs.Task;
[SuppressMessage("ReSharper", "AccessToDisposedClosure", Justification = "This shall not escape")]
void DrawChoices()
@ -98,13 +109,20 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
}
if (ImGui.Selectable("Copy"u8))
tcs.TrySetResult(null);
tcs.TrySetResult((ContextMenuActionType.CopyToClipboard, null));
if (ImGui.Selectable("Send to TexWidget"u8))
tcs.TrySetResult((ContextMenuActionType.SendToTexWidget, null));
ImGui.Separator();
foreach (var encoder2 in encoders)
{
if (ImGui.Selectable(encoder2.Name))
tcs.TrySetResult(encoder2);
tcs.TrySetResult((ContextMenuActionType.SaveAsFile, encoder2));
}
ImGui.Separator();
const float previewImageWidth = 320;
var size = textureWrap.Size;
if (size.X > previewImageWidth)
@ -120,50 +138,68 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
}
}
if (encoder is null)
switch (action)
{
isCopy = true;
await textureManager.CopyToClipboardAsync(textureWrap, name, true);
}
else
{
var props = new Dictionary<string, object>();
if (encoder.ContainerGuid == GUID.GUID_ContainerFormatTiff)
props["CompressionQuality"] = 1.0f;
else if (encoder.ContainerGuid == GUID.GUID_ContainerFormatJpeg ||
encoder.ContainerGuid == GUID.GUID_ContainerFormatHeif ||
encoder.ContainerGuid == GUID.GUID_ContainerFormatWmp)
props["ImageQuality"] = 1.0f;
case ContextMenuActionType.CopyToClipboard:
isCopy = true;
await textureManager.CopyToClipboardAsync(textureWrap, name, true);
break;
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
this.fileDialogManager.SaveFileDialog(
"Save texture...",
$"{encoder.Name.Replace(',', '.')}{{{string.Join(',', encoder.Extensions)}}}",
name + encoder.Extensions.First(),
encoder.Extensions.First(),
(ok, path2) =>
{
if (!ok)
tcs.SetCanceled();
else
tcs.SetResult(path2);
});
var path = await tcs.Task.ConfigureAwait(false);
await textureManager.SaveToFileAsync(textureWrap, encoder.ContainerGuid, path, props: props);
var notif = Service<NotificationManager>.Get().AddNotification(
new()
{
Content = $"File saved to: {path}",
Title = initiatorName,
Type = NotificationType.Success,
});
notif.Click += n =>
case ContextMenuActionType.SendToTexWidget:
{
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
n.Notification.DismissNow();
};
var framework = await Service<Framework>.GetAsync();
var dalamudInterface = await Service<DalamudInterface>.GetAsync();
await framework.RunOnFrameworkThread(
() =>
{
var texWidget = dalamudInterface.GetDataWindowWidget<TexWidget>();
dalamudInterface.SetDataWindowWidget(texWidget);
texWidget.AddTexture(Task.FromResult(textureWrap.CreateWrapSharingLowLevelResource()));
});
break;
}
case ContextMenuActionType.SaveAsFile when encoder is not null:
{
var props = new Dictionary<string, object>();
if (encoder.ContainerGuid == GUID.GUID_ContainerFormatTiff)
props["CompressionQuality"] = 1.0f;
else if (encoder.ContainerGuid == GUID.GUID_ContainerFormatJpeg ||
encoder.ContainerGuid == GUID.GUID_ContainerFormatHeif ||
encoder.ContainerGuid == GUID.GUID_ContainerFormatWmp)
props["ImageQuality"] = 1.0f;
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
this.fileDialogManager.SaveFileDialog(
"Save texture...",
$"{encoder.Name.Replace(',', '.')}{{{string.Join(',', encoder.Extensions)}}}",
name + encoder.Extensions.First(),
encoder.Extensions.First(),
(ok, path2) =>
{
if (!ok)
tcs.SetCanceled();
else
tcs.SetResult(path2);
});
var path = await tcs.Task.ConfigureAwait(false);
await textureManager.SaveToFileAsync(textureWrap, encoder.ContainerGuid, path, props: props);
var notif = Service<NotificationManager>.Get().AddNotification(
new()
{
Content = $"File saved to: {path}",
Title = initiatorName,
Type = NotificationType.Success,
});
notif.Click += n =>
{
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
n.Notification.DismissNow();
};
break;
}
}
}
catch (Exception e)