mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-13 19:37:44 +01:00
244 lines
10 KiB
C#
244 lines
10 KiB
C#
using System.Collections.Generic;
|
|
|
|
using Dalamud.Bindings.ImGui;
|
|
|
|
namespace Dalamud.Interface.ImGuiFileDialog;
|
|
|
|
/// <summary>
|
|
/// A manager for the <see cref="FileDialog"/> class.
|
|
/// </summary>
|
|
public class FileDialogManager
|
|
{
|
|
/// <summary> Gets or sets a function that returns the desired default sort order in the file dialog. </summary>
|
|
public Func<FileDialog.SortingField>? GetDefaultSortOrder { get; set; }
|
|
|
|
/// <summary> Gets or sets an action to invoke when a file dialog changes its sort order. </summary>
|
|
public Action<FileDialog.SortingField>? SetDefaultSortOrder { get; set; }
|
|
|
|
#pragma warning disable SA1401
|
|
#pragma warning disable SA1201
|
|
/// <summary> Additional quick access items for the sidebar.</summary>
|
|
public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = [];
|
|
|
|
/// <summary> Additional flags with which to draw the window. </summary>
|
|
public ImGuiWindowFlags AddedWindowFlags = ImGuiWindowFlags.None;
|
|
#pragma warning restore SA1401
|
|
#pragma warning restore SA1201
|
|
|
|
private FileDialog? dialog;
|
|
private Action<bool, string>? callback;
|
|
private Action<bool, List<string>>? multiCallback;
|
|
private string savedPath = ".";
|
|
|
|
public event EventHandler<string>? SelectionChanged;
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects an already existing folder.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
public void OpenFolderDialog(string title, Action<bool, string> callback)
|
|
{
|
|
this.SetDialog("OpenFolderDialog", title, string.Empty, this.savedPath, ".", string.Empty, 1, false, ImGuiFileDialogFlags.SelectOnly, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects an already existing folder.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
/// <param name="startPath">The directory which the dialog should start inside of. The last path this manager was in is used if this is null.</param>
|
|
/// <param name="isModal">Whether the dialog should be a modal popup.</param>
|
|
public void OpenFolderDialog(string title, Action<bool, string> callback, string? startPath, bool isModal = false)
|
|
{
|
|
this.SetDialog("OpenFolderDialog", title, string.Empty, startPath ?? this.savedPath, ".", string.Empty, 1, isModal, ImGuiFileDialogFlags.SelectOnly, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects an already existing folder or new folder.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="defaultFolderName">The default name to use when creating a new folder.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
public void SaveFolderDialog(string title, string defaultFolderName, Action<bool, string> callback)
|
|
{
|
|
this.SetDialog("SaveFolderDialog", title, string.Empty, this.savedPath, defaultFolderName, string.Empty, 1, false, ImGuiFileDialogFlags.None, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects an already existing folder or new folder.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="defaultFolderName">The default name to use when creating a new folder.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
/// <param name="startPath">The directory which the dialog should start inside of. The last path this manager was in is used if this is null.</param>
|
|
/// <param name="isModal">Whether the dialog should be a modal popup.</param>
|
|
public void SaveFolderDialog(string title, string defaultFolderName, Action<bool, string> callback, string? startPath, bool isModal = false)
|
|
{
|
|
this.SetDialog("SaveFolderDialog", title, string.Empty, startPath ?? this.savedPath, defaultFolderName, string.Empty, 1, isModal, ImGuiFileDialogFlags.None, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects a single, already existing file.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="filters">Which files to show in the dialog.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
public void OpenFileDialog(string title, string filters, Action<bool, string> callback)
|
|
{
|
|
this.SetDialog("OpenFileDialog", title, filters, this.savedPath, ".", string.Empty, 1, false, ImGuiFileDialogFlags.SelectOnly, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects already existing files.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="filters">Which files to show in the dialog.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
/// <param name="selectionCountMax">The maximum amount of files or directories which can be selected. Set to 0 for an infinite number.</param>
|
|
/// <param name="startPath">The directory which the dialog should start inside of. The last path this manager was in is used if this is null.</param>
|
|
/// <param name="isModal">Whether the dialog should be a modal popup.</param>
|
|
public void OpenFileDialog(
|
|
string title,
|
|
string filters,
|
|
Action<bool, List<string>> callback,
|
|
int selectionCountMax,
|
|
string? startPath = null,
|
|
bool isModal = false)
|
|
{
|
|
this.SetDialog("OpenFileDialog", title, filters, startPath ?? this.savedPath, ".", string.Empty, selectionCountMax, isModal, ImGuiFileDialogFlags.SelectOnly, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects an already existing folder or new file.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="filters">Which files to show in the dialog.</param>
|
|
/// <param name="defaultFileName">The default name to use when creating a new file.</param>
|
|
/// <param name="defaultExtension">The extension to use when creating a new file.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
public void SaveFileDialog(
|
|
string title,
|
|
string filters,
|
|
string defaultFileName,
|
|
string defaultExtension,
|
|
Action<bool, string> callback)
|
|
{
|
|
this.SetDialog("SaveFileDialog", title, filters, this.savedPath, defaultFileName, defaultExtension, 1, false, ImGuiFileDialogFlags.None, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a dialog which selects an already existing folder or new file.
|
|
/// </summary>
|
|
/// <param name="title">The header title of the dialog.</param>
|
|
/// <param name="filters">Which files to show in the dialog.</param>
|
|
/// <param name="defaultFileName">The default name to use when creating a new file.</param>
|
|
/// <param name="defaultExtension">The extension to use when creating a new file.</param>
|
|
/// <param name="callback">The action to execute when the dialog is finished.</param>
|
|
/// <param name="startPath">The directory which the dialog should start inside of. The last path this manager was in is used if this is null.</param>
|
|
/// <param name="isModal">Whether the dialog should be a modal popup.</param>
|
|
public void SaveFileDialog(
|
|
string title,
|
|
string filters,
|
|
string defaultFileName,
|
|
string defaultExtension,
|
|
Action<bool, string> callback,
|
|
string? startPath,
|
|
bool isModal = false)
|
|
{
|
|
this.SetDialog("SaveFileDialog", title, filters, startPath ?? this.savedPath, defaultFileName, defaultExtension, 1, isModal, ImGuiFileDialogFlags.None, callback);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws the current dialog, if any, and executes the callback if it is finished.
|
|
/// </summary>
|
|
public void Draw()
|
|
{
|
|
if (this.dialog == null) return;
|
|
if (this.dialog.Draw())
|
|
{
|
|
var isOk = this.dialog.GetIsOk();
|
|
var results = this.dialog.GetResults();
|
|
this.callback?.Invoke(isOk, results.Count > 0 ? results[0] : string.Empty);
|
|
this.multiCallback?.Invoke(isOk, results);
|
|
this.savedPath = this.dialog.GetCurrentPath();
|
|
this.Reset();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes the current dialog, if any.
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
this.dialog?.Hide();
|
|
this.dialog = null;
|
|
this.callback = null;
|
|
this.multiCallback = null;
|
|
}
|
|
|
|
private void OnSelectionChange(object sender, string path) => this.SelectionChanged?.Invoke(sender, path);
|
|
|
|
private void SetDialog(
|
|
string id,
|
|
string title,
|
|
string filters,
|
|
string path,
|
|
string defaultFileName,
|
|
string defaultExtension,
|
|
int selectionCountMax,
|
|
bool isModal,
|
|
ImGuiFileDialogFlags flags,
|
|
Delegate callback)
|
|
{
|
|
this.Reset();
|
|
if (callback is Action<bool, List<string>> multi)
|
|
{
|
|
this.multiCallback = multi;
|
|
}
|
|
else
|
|
{
|
|
this.callback = callback as Action<bool, string>;
|
|
}
|
|
|
|
if (this.dialog is not null)
|
|
{
|
|
this.dialog.SortOrderChanged -= this.OnSortOrderChange;
|
|
this.dialog.SelectionChanged -= this.OnSelectionChange;
|
|
}
|
|
|
|
this.dialog = new FileDialog(id, title, filters, path, defaultFileName, defaultExtension, selectionCountMax, isModal, flags);
|
|
|
|
if (this.GetDefaultSortOrder is not null)
|
|
{
|
|
try
|
|
{
|
|
var order = this.GetDefaultSortOrder();
|
|
this.dialog.SortFields(order);
|
|
}
|
|
catch
|
|
{
|
|
// ignored.
|
|
}
|
|
}
|
|
|
|
this.dialog.SortOrderChanged += this.OnSortOrderChange;
|
|
this.dialog.SelectionChanged += this.OnSelectionChange;
|
|
this.dialog.WindowFlags |= this.AddedWindowFlags;
|
|
foreach (var (name, location, icon, position) in this.CustomSideBarItems)
|
|
this.dialog.SetQuickAccess(name, location, icon, position);
|
|
this.dialog.Show();
|
|
}
|
|
|
|
private void OnSortOrderChange(FileDialog.SortingField sortOrder)
|
|
{
|
|
try
|
|
{
|
|
this.SetDefaultSortOrder?.Invoke(sortOrder);
|
|
}
|
|
catch
|
|
{
|
|
// ignored.
|
|
}
|
|
}
|
|
}
|