From c3f55249d2ea31be1ab90197096b7cce9f922a88 Mon Sep 17 00:00:00 2001
From: Ottermandias <70807659+Ottermandias@users.noreply.github.com>
Date: Wed, 15 Jun 2022 20:45:48 +0200
Subject: [PATCH] FileDialog extensions (#881)
* Fix ImGuiFileDialogFlags to be actually flags.
* Add customization points for quick access and window flags to FileDialog and FileDialogManager.
* Some general cleanup for FileDialog.
---
.../ImGuiFileDialog/FileDialog.Files.cs | 16 ++--
.../ImGuiFileDialog/FileDialog.Structs.cs | 9 +-
.../ImGuiFileDialog/FileDialog.UI.cs | 93 ++++++++-----------
.../Interface/ImGuiFileDialog/FileDialog.cs | 45 +++++++++
.../ImGuiFileDialog/FileDialogManager.cs | 10 ++
.../ImGuiFileDialog/ImGuiFileDialogFlags.cs | 16 ++--
6 files changed, 114 insertions(+), 75 deletions(-)
diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs
index 05e69b4f5..98c48164f 100644
--- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Files.cs
@@ -303,7 +303,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
{
this.drives.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.Server,
+ Icon = FontAwesomeIcon.Server,
Location = drive.Name,
Text = drive.Name,
});
@@ -313,14 +313,14 @@ namespace Dalamud.Interface.ImGuiFileDialog
this.quickAccess.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.Desktop,
+ Icon = FontAwesomeIcon.Desktop,
Location = Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
Text = "Desktop",
});
this.quickAccess.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.File,
+ Icon = FontAwesomeIcon.File,
Location = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
Text = "Documents",
});
@@ -329,7 +329,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
{
this.quickAccess.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.Download,
+ Icon = FontAwesomeIcon.Download,
Location = Path.Combine(personal, "Downloads"),
Text = "Downloads",
});
@@ -337,28 +337,28 @@ namespace Dalamud.Interface.ImGuiFileDialog
this.quickAccess.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.Star,
+ Icon = FontAwesomeIcon.Star,
Location = Environment.GetFolderPath(Environment.SpecialFolder.Favorites),
Text = "Favorites",
});
this.quickAccess.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.Music,
+ Icon = FontAwesomeIcon.Music,
Location = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic),
Text = "Music",
});
this.quickAccess.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.Image,
+ Icon = FontAwesomeIcon.Image,
Location = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
Text = "Pictures",
});
this.quickAccess.Add(new SideBarItem
{
- Icon = (char)FontAwesomeIcon.Video,
+ Icon = FontAwesomeIcon.Video,
Location = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos),
Text = "Videos",
});
diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs
index e6dd5e3a4..05dea4db9 100644
--- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.Structs.cs
@@ -19,12 +19,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
public string FileModifiedDate;
}
- private struct SideBarItem
- {
- public char Icon;
- public string Text;
- public string Location;
- }
+ private record struct SideBarItem(string Text, string Location, FontAwesomeIcon Icon);
private struct FilterStruct
{
@@ -50,7 +45,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
private struct IconColorItem
{
- public char Icon;
+ public FontAwesomeIcon Icon;
public Vector4 Color;
}
}
diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.UI.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.UI.cs
index d5010f13c..d768bbe81 100644
--- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.UI.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.UI.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Numerics;
using ImGuiNET;
@@ -43,11 +44,11 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (this.isModal && !this.okResultToConfirm)
{
ImGui.OpenPopup(name);
- windowVisible = ImGui.BeginPopupModal(name, ref this.visible, ImGuiWindowFlags.NoScrollbar);
+ windowVisible = ImGui.BeginPopupModal(name, ref this.visible, this.WindowFlags);
}
else
{
- windowVisible = ImGui.Begin(name, ref this.visible, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoNav);
+ windowVisible = ImGui.Begin(name, ref this.visible, this.WindowFlags);
}
bool wasClosed = false;
@@ -99,7 +100,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
return wasClosed || this.ConfirmOrOpenOverWriteFileDialogIfNeeded(res);
}
- private static void AddToIconMap(string[] extensions, char icon, Vector4 color)
+ private static void AddToIconMap(string[] extensions, FontAwesomeIcon icon, Vector4 color)
{
foreach (var ext in extensions)
{
@@ -116,19 +117,19 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (iconMap == null)
{
iconMap = new();
- AddToIconMap(new[] { "mp4", "gif", "mov", "avi" }, (char)FontAwesomeIcon.FileVideo, miscTextColor);
- AddToIconMap(new[] { "pdf" }, (char)FontAwesomeIcon.FilePdf, miscTextColor);
- AddToIconMap(new[] { "png", "jpg", "jpeg", "tiff" }, (char)FontAwesomeIcon.FileImage, imageTextColor);
- AddToIconMap(new[] { "cs", "json", "cpp", "h", "py", "xml", "yaml", "js", "html", "css", "ts", "java" }, (char)FontAwesomeIcon.FileCode, codeTextColor);
- AddToIconMap(new[] { "txt", "md" }, (char)FontAwesomeIcon.FileAlt, standardTextColor);
- AddToIconMap(new[] { "zip", "7z", "gz", "tar" }, (char)FontAwesomeIcon.FileArchive, miscTextColor);
- AddToIconMap(new[] { "mp3", "m4a", "ogg", "wav" }, (char)FontAwesomeIcon.FileAudio, miscTextColor);
- AddToIconMap(new[] { "csv" }, (char)FontAwesomeIcon.FileCsv, miscTextColor);
+ AddToIconMap(new[] { "mp4", "gif", "mov", "avi" }, FontAwesomeIcon.FileVideo, miscTextColor);
+ AddToIconMap(new[] { "pdf" }, FontAwesomeIcon.FilePdf, miscTextColor);
+ AddToIconMap(new[] { "png", "jpg", "jpeg", "tiff" }, FontAwesomeIcon.FileImage, imageTextColor);
+ AddToIconMap(new[] { "cs", "json", "cpp", "h", "py", "xml", "yaml", "js", "html", "css", "ts", "java" }, FontAwesomeIcon.FileCode, codeTextColor);
+ AddToIconMap(new[] { "txt", "md" }, FontAwesomeIcon.FileAlt, standardTextColor);
+ AddToIconMap(new[] { "zip", "7z", "gz", "tar" }, FontAwesomeIcon.FileArchive, miscTextColor);
+ AddToIconMap(new[] { "mp3", "m4a", "ogg", "wav" }, FontAwesomeIcon.FileAudio, miscTextColor);
+ AddToIconMap(new[] { "csv" }, FontAwesomeIcon.FileCsv, miscTextColor);
}
return iconMap.TryGetValue(ext.ToLower(), out var icon) ? icon : new IconColorItem
{
- Icon = (char)FontAwesomeIcon.File,
+ Icon = FontAwesomeIcon.File,
Color = standardTextColor,
};
}
@@ -222,7 +223,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (!this.createDirectoryMode)
{
ImGui.SameLine();
- ImGui.Text("Search :");
+ ImGui.TextUnformatted("Search :");
ImGui.SameLine();
ImGui.PushItemWidth(ImGui.GetContentRegionAvail().X);
var edited = ImGui.InputText("##InputImGuiFileDialogSearchField", ref this.searchBuffer, 255);
@@ -239,7 +240,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (this.flags.HasFlag(ImGuiFileDialogFlags.DisableCreateDirectoryButton)) return;
ImGui.PushFont(UiBuilder.IconFont);
- if (ImGui.Button($"{(char)FontAwesomeIcon.FolderPlus}"))
+ if (ImGui.Button(FontAwesomeIcon.FolderPlus.ToIconString()))
{
if (!this.createDirectoryMode)
{
@@ -258,7 +259,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (this.createDirectoryMode)
{
ImGui.SameLine();
- ImGui.Text("New Directory Name");
+ ImGui.TextUnformatted("New Directory Name");
ImGui.SameLine();
ImGui.PushItemWidth(ImGui.GetContentRegionAvail().X - 100f);
@@ -317,41 +318,29 @@ namespace Dalamud.Interface.ImGuiFileDialog
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 5);
- foreach (var drive in this.drives)
+ var idx = 0;
+ foreach (var (name, location, icon) in this.drives.Concat(this.quickAccess))
{
- ImGui.PushFont(UiBuilder.IconFont);
- if (ImGui.Selectable($"{drive.Icon}##{drive.Text}", drive.Text == this.selectedSideBar))
- {
- this.SetPath(drive.Location);
- this.selectedSideBar = drive.Text;
- }
-
- ImGui.PopFont();
-
- ImGui.SameLine(25);
-
- ImGui.Text(drive.Text);
- }
-
- foreach (var quick in this.quickAccess)
- {
- if (string.IsNullOrEmpty(quick.Location))
+ if (string.IsNullOrEmpty(location) || !Directory.Exists(location))
{
continue;
}
- ImGui.PushFont(UiBuilder.IconFont);
- if (ImGui.Selectable($"{quick.Icon}##{quick.Text}", quick.Text == this.selectedSideBar))
+ ImGui.PushID(idx++);
+ ImGui.SetCursorPosX(25);
+ if (ImGui.Selectable(name, name == this.selectedSideBar))
{
- this.SetPath(quick.Location);
- this.selectedSideBar = quick.Text;
+ this.SetPath(location);
+ this.selectedSideBar = name;
}
+ ImGui.PushFont(UiBuilder.IconFont);
+ ImGui.SameLine();
+ ImGui.SetCursorPosX(0);
+ ImGui.TextUnformatted(icon.ToIconString());
+
ImGui.PopFont();
-
- ImGui.SameLine(25);
-
- ImGui.Text(quick.Text);
+ ImGui.PopID();
}
ImGui.EndChild();
@@ -429,7 +418,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
var item = !dir ? GetIcon(file.Ext) : new IconColorItem
{
Color = dirTextColor,
- Icon = (char)FontAwesomeIcon.Folder,
+ Icon = FontAwesomeIcon.Folder,
};
ImGui.PushStyleColor(ImGuiCol.Text, item.Color);
@@ -444,18 +433,18 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (ImGui.TableNextColumn())
{
- ImGui.Text(file.Ext);
+ ImGui.TextUnformatted(file.Ext);
}
if (ImGui.TableNextColumn())
{
if (file.Type == FileStructType.File)
{
- ImGui.Text(file.FormattedFileSize + " ");
+ ImGui.TextUnformatted(file.FormattedFileSize + " ");
}
else
{
- ImGui.Text(" ");
+ ImGui.TextUnformatted(" ");
}
}
@@ -463,7 +452,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
{
var sz = ImGui.CalcTextSize(file.FileModifiedDate);
ImGui.PushItemWidth(sz.X + 5);
- ImGui.Text(file.FileModifiedDate + " ");
+ ImGui.TextUnformatted(file.FileModifiedDate + " ");
ImGui.PopItemWidth();
}
@@ -503,13 +492,13 @@ namespace Dalamud.Interface.ImGuiFileDialog
ImGui.EndChild();
}
- private bool SelectableItem(FileStruct file, bool selected, char icon)
+ private bool SelectableItem(FileStruct file, bool selected, FontAwesomeIcon icon)
{
- var flags = ImGuiSelectableFlags.AllowDoubleClick | ImGuiSelectableFlags.SpanAllColumns;
+ const ImGuiSelectableFlags flags = ImGuiSelectableFlags.AllowDoubleClick | ImGuiSelectableFlags.SpanAllColumns;
ImGui.PushFont(UiBuilder.IconFont);
- ImGui.Text($"{icon}");
+ ImGui.TextUnformatted(icon.ToIconString());
ImGui.PopFont();
ImGui.SameLine(25f);
@@ -712,11 +701,11 @@ namespace Dalamud.Interface.ImGuiFileDialog
if (this.IsDirectoryMode())
{
- ImGui.Text("Directory Path :");
+ ImGui.TextUnformatted("Directory Path :");
}
else
{
- ImGui.Text("File Name :");
+ ImGui.TextUnformatted("File Name :");
}
ImGui.SameLine();
@@ -839,7 +828,7 @@ namespace Dalamud.Interface.ImGuiFileDialog
ImGui.OpenPopup(name);
if (ImGui.BeginPopupModal(name, ref open, ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove))
{
- ImGui.Text("Would you like to Overwrite it ?");
+ ImGui.TextUnformatted("Would you like to Overwrite it ?");
if (ImGui.Button("Confirm"))
{
this.okResultToConfirm = false;
diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs
index 924dc68c3..2a2116296 100644
--- a/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/FileDialog.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using ImGuiNET;
namespace Dalamud.Interface.ImGuiFileDialog
{
@@ -10,6 +11,11 @@ namespace Dalamud.Interface.ImGuiFileDialog
///
public partial class FileDialog
{
+ ///
+ /// The flags used to draw the file picker window.
+ ///
+ public ImGuiWindowFlags WindowFlags;
+
private readonly string title;
private readonly int selectionCountMax;
private readonly ImGuiFileDialogFlags flags;
@@ -74,6 +80,9 @@ namespace Dalamud.Interface.ImGuiFileDialog
this.flags = flags;
this.selectionCountMax = selectionCountMax;
this.isModal = isModal;
+ this.WindowFlags = ImGuiWindowFlags.NoNav;
+ if (!isModal)
+ this.WindowFlags |= ImGuiWindowFlags.NoScrollbar;
this.currentPath = path;
this.defaultExtension = defaultExtension;
@@ -161,6 +170,42 @@ namespace Dalamud.Interface.ImGuiFileDialog
return this.currentPath;
}
+ ///
+ /// Set or remove a quick access folder for the navigation panel.
+ ///
+ /// The displayed name of the folder. If this name already exists, it will be overwritten.
+ /// The new linked path. If this is empty, no link will be added and existing links will be removed.
+ /// The FontAwesomeIcon-ID of the icon displayed before the name.
+ /// An optional position at which to insert the new link. If the link is updated, having this less than zero will keep its position.
+ /// Otherwise, invalid indices will insert it at the end.
+ public void SetQuickAccess(string name, string path, FontAwesomeIcon icon, int position = -1)
+ {
+ var idx = this.quickAccess.FindIndex(q => q.Text.Equals(name, StringComparison.InvariantCultureIgnoreCase));
+ if (idx >= 0)
+ {
+ if (position >= 0 || path.Length == 0)
+ {
+ this.quickAccess.RemoveAt(idx);
+ }
+ else
+ {
+ this.quickAccess[idx] = new SideBarItem(name, path, icon);
+ return;
+ }
+ }
+
+ if (path.Length == 0) return;
+
+ if (position < 0 || position >= this.quickAccess.Count)
+ {
+ this.quickAccess.Add(new SideBarItem(name, path, icon));
+ }
+ else
+ {
+ this.quickAccess.Insert(position, new SideBarItem(name, path, icon));
+ }
+ }
+
private string GetFilePathName()
{
var path = this.GetCurrentPath();
diff --git a/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs b/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs
index f9cd06290..05d6a040e 100644
--- a/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/FileDialogManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using ImGuiNET;
namespace Dalamud.Interface.ImGuiFileDialog
{
@@ -8,6 +9,12 @@ namespace Dalamud.Interface.ImGuiFileDialog
///
public class FileDialogManager
{
+ /// Additional quick access items for the side bar.
+ public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = new();
+
+ /// Additional flags with which to draw the window.
+ public ImGuiWindowFlags AddedWindowFlags = ImGuiWindowFlags.None;
+
private FileDialog? dialog;
private Action? callback;
private Action>? multiCallback;
@@ -181,6 +188,9 @@ namespace Dalamud.Interface.ImGuiFileDialog
}
this.dialog = new FileDialog(id, title, filters, path, defaultFileName, defaultExtension, selectionCountMax, isModal, flags);
+ this.dialog.WindowFlags |= this.AddedWindowFlags;
+ foreach (var (name, location, icon, position) in this.CustomSideBarItems)
+ this.dialog.SetQuickAccess(name, location, icon, position);
this.dialog.Show();
}
}
diff --git a/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs b/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs
index 7ed959796..fd5ee2531 100644
--- a/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs
+++ b/Dalamud/Interface/ImGuiFileDialog/ImGuiFileDialogFlags.cs
@@ -16,41 +16,41 @@ namespace Dalamud.Interface.ImGuiFileDialog
///
/// Confirm the selection when choosing a file which already exists.
///
- ConfirmOverwrite = 1,
+ ConfirmOverwrite = 0x01,
///
/// Only allow selection of files or folders which currently exist.
///
- SelectOnly = 2,
+ SelectOnly = 0x02,
///
/// Hide files or folders which start with a period.
///
- DontShowHiddenFiles = 3,
+ DontShowHiddenFiles = 0x04,
///
/// Disable the creation of new folders within the dialog.
///
- DisableCreateDirectoryButton = 4,
+ DisableCreateDirectoryButton = 0x08,
///
/// Hide the type column.
///
- HideColumnType = 5,
+ HideColumnType = 0x10,
///
/// Hide the file size column.
///
- HideColumnSize = 6,
+ HideColumnSize = 0x20,
///
/// Hide the last modified date column.
///
- HideColumnDate = 7,
+ HideColumnDate = 0x40,
///
/// Hide the quick access sidebar.
///
- HideSideBar = 8,
+ HideSideBar = 0x80,
}
}