From 8c6b599a07b0a32d36a6e19ee2bd9b80e21dcc87 Mon Sep 17 00:00:00 2001
From: Ottermandias <70807659+Ottermandias@users.noreply.github.com>
Date: Sat, 23 Apr 2022 16:43:16 +0200
Subject: [PATCH] File Selector (#807)
---
.../Interface/ImGuiFileDialog/FileDialog.cs | 21 ++-
.../ImGuiFileDialog/FileDialogManager.cs | 121 ++++++++++++++----
2 files changed, 110 insertions(+), 32 deletions(-)
diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs
index 98b70a3ab..924dc68c3 100644
--- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs
@@ -115,22 +115,31 @@ namespace Dalamud.Interface.ImGuiFileDialog
///
/// Gets the result of the selection.
///
- /// The separator to put between multiple selected entries.
- /// The result of the selection (file or folder path). If multiple entries were selected, they are separated with the given separator, which is a comma by default.
- public string GetResult(char separator = ',')
+ /// The result of the selection (file or folder path). If multiple entries were selected, they are separated with commas.
+ [Obsolete("Use GetResults() instead.", true)]
+ public string GetResult()
+ {
+ return string.Join(',', this.GetResults());
+ }
+
+ ///
+ /// Gets the result of the selection.
+ ///
+ /// The list of selected paths.
+ public List GetResults()
{
if (!this.flags.HasFlag(ImGuiFileDialogFlags.SelectOnly))
{
- return this.GetFilePathName();
+ return new List { this.GetFilePathName() };
}
if (this.IsDirectoryMode() && this.selectedFileNames.Count == 0)
{
- return this.GetFilePathName(); // current directory
+ return new List { this.GetFilePathName() }; // current directory
}
var fullPaths = this.selectedFileNames.Where(x => !string.IsNullOrEmpty(x)).Select(x => Path.Combine(this.currentPath, x));
- return string.Join(separator, fullPaths.ToArray());
+ return fullPaths.ToList();
}
///
diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs
index 2c1bab735..e5c5854db 100644
--- a/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace Dalamud.Interface.ImGuiFileDialog
{
@@ -7,21 +8,33 @@ namespace Dalamud.Interface.ImGuiFileDialog
///
public class FileDialogManager
{
- private FileDialog dialog;
+ private FileDialog? dialog;
+ private Action? callback;
+ private Action>? multiCallback;
private string savedPath = ".";
- private Action callback;
- private char selectionSeparator;
///
/// Create a dialog which selects an already existing folder.
///
/// The header title of the dialog.
/// The action to execute when the dialog is finished.
- /// The directory which the dialog should start inside of.
- /// Whether the dialog should be a modal popup.
- public void OpenFolderDialog(string title, Action callback, string? startPath = null, bool isModal = false)
+ public void OpenFolderDialog(string title, Action callback)
{
- this.SetDialog("OpenFolderDialog", title, string.Empty, startPath ?? this.savedPath, ".", string.Empty, 1, isModal, ImGuiFileDialogFlags.SelectOnly, callback);
+ this.SetCallback(callback);
+ this.SetDialog("OpenFolderDialog", title, string.Empty, this.savedPath, ".", string.Empty, 1, false, ImGuiFileDialogFlags.SelectOnly);
+ }
+
+ ///
+ /// Create a dialog which selects an already existing folder.
+ ///
+ /// The header title of the dialog.
+ /// The action to execute when the dialog is finished.
+ /// The directory which the dialog should start inside of. The last path this manager was in is used if this is null.
+ /// Whether the dialog should be a modal popup.
+ public void OpenFolderDialog(string title, Action callback, string? startPath, bool isModal = false)
+ {
+ this.SetCallback(callback);
+ this.SetDialog("OpenFolderDialog", title, string.Empty, startPath ?? this.savedPath, ".", string.Empty, 1, isModal, ImGuiFileDialogFlags.SelectOnly);
}
///
@@ -30,34 +43,57 @@ namespace Dalamud.Interface.ImGuiFileDialog
/// The header title of the dialog.
/// The default name to use when creating a new folder.
/// The action to execute when the dialog is finished.
- /// The directory which the dialog should start inside of.
- /// Whether the dialog should be a modal popup.
- public void SaveFolderDialog(string title, string defaultFolderName, Action callback, string? startPath = null, bool isModal = false)
+ public void SaveFolderDialog(string title, string defaultFolderName, Action callback)
{
- this.SetDialog("SaveFolderDialog", title, string.Empty, startPath ?? this.savedPath, defaultFolderName, string.Empty, 1, isModal, ImGuiFileDialogFlags.None, callback);
+ this.SetCallback(callback);
+ this.SetDialog("SaveFolderDialog", title, string.Empty, this.savedPath, defaultFolderName, string.Empty, 1, false, ImGuiFileDialogFlags.None);
}
///
- /// Create a dialog which selects an already existing file.
+ /// Create a dialog which selects an already existing folder or new folder.
+ ///
+ /// The header title of the dialog.
+ /// The default name to use when creating a new folder.
+ /// The action to execute when the dialog is finished.
+ /// The directory which the dialog should start inside of. The last path this manager was in is used if this is null.
+ /// Whether the dialog should be a modal popup.
+ public void SaveFolderDialog(string title, string defaultFolderName, Action callback, string? startPath, bool isModal = false)
+ {
+ this.SetCallback(callback);
+ this.SetDialog("SaveFolderDialog", title, string.Empty, startPath ?? this.savedPath, defaultFolderName, string.Empty, 1, isModal, ImGuiFileDialogFlags.None);
+ }
+
+ ///
+ /// Create a dialog which selects a single, already existing file.
///
/// The header title of the dialog.
/// Which files to show in the dialog.
/// The action to execute when the dialog is finished.
- /// The directory which the dialog should start inside of.
+ public void OpenFileDialog(string title, string filters, Action callback)
+ {
+ this.SetCallback(callback);
+ this.SetDialog("OpenFileDialog", title, filters, this.savedPath, ".", string.Empty, 1, false, ImGuiFileDialogFlags.SelectOnly);
+ }
+
+ ///
+ /// Create a dialog which selects already existing files.
+ ///
+ /// The header title of the dialog.
+ /// Which files to show in the dialog.
+ /// The action to execute when the dialog is finished.
+ /// The directory which the dialog should start inside of. The last path this manager was in is used if this is null.
/// The maximum amount of files or directories which can be selected. Set to 0 for an infinite number.
- /// The separator to put between multiple selected entries.
/// Whether the dialog should be a modal popup.
public void OpenFileDialog(
string title,
string filters,
- Action callback,
+ Action> callback,
string? startPath = null,
int selectionCountMax = 1,
- char selectionSeparator = '\0',
bool isModal = false)
{
- this.selectionSeparator = selectionSeparator;
- this.SetDialog("OpenFileDialog", title, filters, startPath ?? this.savedPath, ".", string.Empty, selectionCountMax, isModal, ImGuiFileDialogFlags.SelectOnly, callback);
+ this.SetCallback(callback);
+ this.SetDialog("OpenFileDialog", title, filters, startPath ?? this.savedPath, ".", string.Empty, selectionCountMax, isModal, ImGuiFileDialogFlags.SelectOnly);
}
///
@@ -68,7 +104,26 @@ namespace Dalamud.Interface.ImGuiFileDialog
/// The default name to use when creating a new file.
/// The extension to use when creating a new file.
/// The action to execute when the dialog is finished.
- /// The directory which the dialog should start inside of.
+ public void SaveFileDialog(
+ string title,
+ string filters,
+ string defaultFileName,
+ string defaultExtension,
+ Action callback)
+ {
+ this.SetCallback(callback);
+ this.SetDialog("SaveFileDialog", title, filters, this.savedPath, defaultFileName, defaultExtension, 1, false, ImGuiFileDialogFlags.None);
+ }
+
+ ///
+ /// Create a dialog which selects an already existing folder or new file.
+ ///
+ /// The header title of the dialog.
+ /// Which files to show in the dialog.
+ /// The default name to use when creating a new file.
+ /// The extension to use when creating a new file.
+ /// The action to execute when the dialog is finished.
+ /// The directory which the dialog should start inside of. The last path this manager was in is used if this is null.
/// Whether the dialog should be a modal popup.
public void SaveFileDialog(
string title,
@@ -76,10 +131,11 @@ namespace Dalamud.Interface.ImGuiFileDialog
string defaultFileName,
string defaultExtension,
Action callback,
- string? startPath = null,
+ string? startPath,
bool isModal = false)
{
- this.SetDialog("SaveFileDialog", title, filters, startPath ?? this.savedPath, defaultFileName, defaultExtension, 1, isModal, ImGuiFileDialogFlags.None, callback);
+ this.SetCallback(callback);
+ this.SetDialog("SaveFileDialog", title, filters, startPath ?? this.savedPath, defaultFileName, defaultExtension, 1, isModal, ImGuiFileDialogFlags.None);
}
///
@@ -90,7 +146,10 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (this.dialog == null) return;
if (this.dialog.Draw())
{
- this.callback(this.dialog.GetIsOk(), this.dialog.GetResult(this.selectionSeparator));
+ 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();
}
@@ -104,7 +163,19 @@ namespace Dalamud.Interface.ImGuiFileDialog
this.dialog?.Hide();
this.dialog = null;
this.callback = null;
- this.selectionSeparator = '\0';
+ this.multiCallback = null;
+ }
+
+ private void SetCallback(Action action)
+ {
+ this.callback = action;
+ this.multiCallback = null;
+ }
+
+ private void SetCallback(Action> action)
+ {
+ this.multiCallback = action;
+ this.callback = null;
}
private void SetDialog(
@@ -116,11 +187,9 @@ namespace Dalamud.Interface.ImGuiFileDialog
string defaultExtension,
int selectionCountMax,
bool isModal,
- ImGuiFileDialogFlags flags,
- Action callback)
+ ImGuiFileDialogFlags flags)
{
this.Reset();
- this.callback = callback;
this.dialog = new FileDialog(id, title, filters, path, defaultFileName, defaultExtension, selectionCountMax, isModal, flags);
this.dialog.Show();
}