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.
This commit is contained in:
Ottermandias 2022-06-15 20:45:48 +02:00 committed by GitHub
parent e2dc8802f7
commit c3f55249d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 75 deletions

View file

@ -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",
});

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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
/// </summary>
public partial class FileDialog
{
/// <summary>
/// The flags used to draw the file picker window.
/// </summary>
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;
}
/// <summary>
/// Set or remove a quick access folder for the navigation panel.
/// </summary>
/// <param name="name">The displayed name of the folder. If this name already exists, it will be overwritten.</param>
/// <param name="path">The new linked path. If this is empty, no link will be added and existing links will be removed.</param>
/// <param name="icon">The FontAwesomeIcon-ID of the icon displayed before the name.</param>
/// <param name="position">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.</param>
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();

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using ImGuiNET;
namespace Dalamud.Interface.ImGuiFileDialog
{
@ -8,6 +9,12 @@ namespace Dalamud.Interface.ImGuiFileDialog
/// </summary>
public class FileDialogManager
{
/// <summary> Additional quick access items for the side bar.</summary>
public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = new();
/// <summary> Additional flags with which to draw the window. </summary>
public ImGuiWindowFlags AddedWindowFlags = ImGuiWindowFlags.None;
private FileDialog? dialog;
private Action<bool, string>? callback;
private Action<bool, List<string>>? 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();
}
}

View file

@ -16,41 +16,41 @@ namespace Dalamud.Interface.ImGuiFileDialog
/// <summary>
/// Confirm the selection when choosing a file which already exists.
/// </summary>
ConfirmOverwrite = 1,
ConfirmOverwrite = 0x01,
/// <summary>
/// Only allow selection of files or folders which currently exist.
/// </summary>
SelectOnly = 2,
SelectOnly = 0x02,
/// <summary>
/// Hide files or folders which start with a period.
/// </summary>
DontShowHiddenFiles = 3,
DontShowHiddenFiles = 0x04,
/// <summary>
/// Disable the creation of new folders within the dialog.
/// </summary>
DisableCreateDirectoryButton = 4,
DisableCreateDirectoryButton = 0x08,
/// <summary>
/// Hide the type column.
/// </summary>
HideColumnType = 5,
HideColumnType = 0x10,
/// <summary>
/// Hide the file size column.
/// </summary>
HideColumnSize = 6,
HideColumnSize = 0x20,
/// <summary>
/// Hide the last modified date column.
/// </summary>
HideColumnDate = 7,
HideColumnDate = 0x40,
/// <summary>
/// Hide the quick access sidebar.
/// </summary>
HideSideBar = 8,
HideSideBar = 0x80,
}
}