mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
834 lines
27 KiB
C#
834 lines
27 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface.Internal;
|
|
using Dalamud.Interface.Utility;
|
|
using Dalamud.Utility;
|
|
|
|
namespace Dalamud.Interface.ImGuiFileDialog;
|
|
|
|
/// <summary>
|
|
/// A file or folder picker.
|
|
/// </summary>
|
|
public partial class FileDialog
|
|
{
|
|
private static Vector4 pathDecompColor = new(0.188f, 0.188f, 0.2f, 1f);
|
|
private static Vector4 selectedTextColor = new(1.00000000000f, 0.33333333333f, 0.33333333333f, 1f);
|
|
private static Vector4 dirTextColor = new(0.54509803922f, 0.91372549020f, 0.99215686275f, 1f);
|
|
private static Vector4 codeTextColor = new(0.94509803922f, 0.98039215686f, 0.54901960784f, 1f);
|
|
private static Vector4 miscTextColor = new(1.00000000000f, 0.47450980392f, 0.77647058824f, 1f);
|
|
private static Vector4 imageTextColor = new(0.31372549020f, 0.98039215686f, 0.48235294118f, 1f);
|
|
private static Vector4 standardTextColor = new(1f);
|
|
|
|
private static Dictionary<string, IconColorItem> iconMap;
|
|
|
|
/// <summary>
|
|
/// Draws the dialog.
|
|
/// </summary>
|
|
/// <returns>Whether a selection or cancel action was performed.</returns>
|
|
public bool Draw()
|
|
{
|
|
if (!this.visible) return false;
|
|
|
|
var res = false;
|
|
var name = this.title + "###" + this.id;
|
|
|
|
bool windowVisible;
|
|
this.isOk = false;
|
|
this.wantsToQuit = false;
|
|
|
|
this.ResetEvents();
|
|
|
|
ImGui.SetNextWindowSize(ImGuiHelpers.ScaledVector2(800, 500), ImGuiCond.FirstUseEver);
|
|
|
|
if (this.isModal && !this.okResultToConfirm)
|
|
{
|
|
ImGui.OpenPopup(name);
|
|
windowVisible = ImGui.BeginPopupModal(name, ref this.visible, this.WindowFlags);
|
|
}
|
|
else
|
|
{
|
|
windowVisible = ImGui.Begin(name, ref this.visible, this.WindowFlags);
|
|
}
|
|
|
|
bool wasClosed = false;
|
|
if (windowVisible)
|
|
{
|
|
if (!this.visible)
|
|
{ // window closed
|
|
this.isOk = false;
|
|
wasClosed = true;
|
|
}
|
|
else
|
|
{
|
|
if (this.selectedFilter.Empty() && (this.filters.Count > 0))
|
|
{
|
|
this.selectedFilter = this.filters[0];
|
|
}
|
|
|
|
if (this.files.Count == 0)
|
|
{
|
|
if (!string.IsNullOrEmpty(this.defaultFileName))
|
|
{
|
|
this.SetDefaultFileName();
|
|
this.SetSelectedFilterWithExt(this.defaultExtension);
|
|
}
|
|
else if (this.IsDirectoryMode())
|
|
{
|
|
this.SetDefaultFileName();
|
|
}
|
|
|
|
this.ScanDir(this.currentPath);
|
|
}
|
|
|
|
this.DrawHeader();
|
|
this.DrawContent();
|
|
res = this.DrawFooter();
|
|
}
|
|
|
|
if (this.isModal && !this.okResultToConfirm)
|
|
{
|
|
ImGui.EndPopup();
|
|
}
|
|
}
|
|
|
|
if (!this.isModal || this.okResultToConfirm)
|
|
{
|
|
ImGui.End();
|
|
}
|
|
|
|
return wasClosed || this.ConfirmOrOpenOverWriteFileDialogIfNeeded(res);
|
|
}
|
|
|
|
private static float Scaled(float value)
|
|
=> value * ImGuiHelpers.GlobalScale;
|
|
|
|
private static void AddToIconMap(string[] extensions, FontAwesomeIcon icon, Vector4 color)
|
|
{
|
|
foreach (var ext in extensions)
|
|
{
|
|
iconMap[ext] = new IconColorItem
|
|
{
|
|
Icon = icon,
|
|
Color = color,
|
|
};
|
|
}
|
|
}
|
|
|
|
private static IconColorItem GetIcon(string ext)
|
|
{
|
|
if (iconMap == null)
|
|
{
|
|
iconMap = new();
|
|
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.ToLowerInvariant(), out var icon) ? icon : new IconColorItem
|
|
{
|
|
Icon = FontAwesomeIcon.File,
|
|
Color = standardTextColor,
|
|
};
|
|
}
|
|
|
|
private void DrawHeader()
|
|
{
|
|
this.DrawPathComposer();
|
|
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + Scaled(2));
|
|
ImGui.Separator();
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + Scaled(2));
|
|
|
|
this.DrawSearchBar();
|
|
}
|
|
|
|
private void DrawPathComposer()
|
|
{
|
|
ImGui.PushFont(InterfaceManager.IconFont);
|
|
if (ImGui.Button(this.pathInputActivated ? FontAwesomeIcon.Times.ToIconString() : FontAwesomeIcon.Edit.ToIconString()))
|
|
{
|
|
this.pathInputActivated = !this.pathInputActivated;
|
|
}
|
|
|
|
ImGui.PopFont();
|
|
|
|
ImGui.SameLine();
|
|
|
|
if (this.pathDecomposition.Count > 0)
|
|
{
|
|
if (this.pathInputActivated)
|
|
{
|
|
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
|
ImGui.InputText("##pathedit", ref this.pathInputBuffer, 255);
|
|
}
|
|
else
|
|
{
|
|
for (var idx = 0; idx < this.pathDecomposition.Count; idx++)
|
|
{
|
|
if (idx > 0)
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() - Scaled(3));
|
|
}
|
|
|
|
ImGui.PushID(idx);
|
|
ImGui.PushStyleColor(ImGuiCol.Button, pathDecompColor);
|
|
var click = ImGui.Button(this.pathDecomposition[idx]);
|
|
ImGui.PopStyleColor();
|
|
ImGui.PopID();
|
|
|
|
if (click)
|
|
{
|
|
this.currentPath = ComposeNewPath(this.pathDecomposition.GetRange(0, idx + 1));
|
|
this.pathClicked = true;
|
|
break;
|
|
}
|
|
|
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
|
{
|
|
this.pathInputBuffer = ComposeNewPath(this.pathDecomposition.GetRange(0, idx + 1));
|
|
this.pathInputActivated = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawSearchBar()
|
|
{
|
|
ImGui.PushFont(InterfaceManager.IconFont);
|
|
if (ImGui.Button(FontAwesomeIcon.Home.ToIconString()))
|
|
{
|
|
this.SetPath(".");
|
|
}
|
|
|
|
ImGui.PopFont();
|
|
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
ImGui.SetTooltip("Reset to current directory");
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
|
|
this.DrawDirectoryCreation();
|
|
|
|
if (!this.createDirectoryMode)
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.TextUnformatted("Search :");
|
|
ImGui.SameLine();
|
|
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
|
if (ImGui.InputText("##InputImGuiFileDialogSearchField", ref this.searchBuffer, 255))
|
|
{
|
|
this.ApplyFilteringOnFileList();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawDirectoryCreation()
|
|
{
|
|
if (this.flags.HasFlag(ImGuiFileDialogFlags.DisableCreateDirectoryButton)) return;
|
|
|
|
ImGui.PushFont(InterfaceManager.IconFont);
|
|
if (ImGui.Button(FontAwesomeIcon.FolderPlus.ToIconString()) && !this.createDirectoryMode)
|
|
{
|
|
this.createDirectoryMode = true;
|
|
this.createDirectoryBuffer = string.Empty;
|
|
}
|
|
|
|
ImGui.PopFont();
|
|
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
ImGui.SetTooltip("Create Directory");
|
|
}
|
|
|
|
if (this.createDirectoryMode)
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.TextUnformatted("New Directory Name");
|
|
|
|
ImGui.SameLine();
|
|
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - Scaled(100));
|
|
ImGui.InputText("##DirectoryFileName", ref this.createDirectoryBuffer, 255);
|
|
|
|
ImGui.SameLine();
|
|
|
|
if (ImGui.Button("Ok"))
|
|
{
|
|
if (this.CreateDir(this.createDirectoryBuffer))
|
|
{
|
|
this.SetPath(Path.Combine(this.currentPath, this.createDirectoryBuffer));
|
|
}
|
|
|
|
this.createDirectoryMode = false;
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
|
|
if (ImGui.Button("Cancel"))
|
|
{
|
|
this.createDirectoryMode = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawContent()
|
|
{
|
|
var size = ImGui.GetContentRegionAvail() - new Vector2(0, this.footerHeight);
|
|
|
|
if (!this.flags.HasFlag(ImGuiFileDialogFlags.HideSideBar))
|
|
{
|
|
if (ImGui.BeginChild("##FileDialog_ColumnChild", size))
|
|
{
|
|
ImGui.Columns(2, "##FileDialog_Columns");
|
|
|
|
this.DrawSideBar(size with { X = Scaled(150) });
|
|
|
|
ImGui.SetColumnWidth(0, Scaled(150));
|
|
ImGui.NextColumn();
|
|
|
|
this.DrawFileListView(size - new Vector2(Scaled(160), 0));
|
|
|
|
ImGui.Columns(1);
|
|
}
|
|
|
|
ImGui.EndChild();
|
|
}
|
|
else
|
|
{
|
|
this.DrawFileListView(size);
|
|
}
|
|
}
|
|
|
|
private void DrawSideBar(Vector2 size)
|
|
{
|
|
if (ImGui.BeginChild("##FileDialog_SideBar", size))
|
|
{
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + Scaled(5));
|
|
|
|
var idx = 0;
|
|
foreach (var qa in this.GetDrives().Concat(this.quickAccess).Where(qa => !qa.Location.IsNullOrEmpty()))
|
|
{
|
|
ImGui.PushID(idx++);
|
|
ImGui.SetCursorPosX(Scaled(25));
|
|
if (ImGui.Selectable(qa.Text, qa.Text == this.selectedSideBar) && qa.CheckExistence())
|
|
{
|
|
this.SetPath(qa.Location);
|
|
this.selectedSideBar = qa.Text;
|
|
}
|
|
|
|
ImGui.PushFont(InterfaceManager.IconFont);
|
|
ImGui.SameLine();
|
|
ImGui.SetCursorPosX(0);
|
|
ImGui.TextUnformatted(qa.Icon.ToIconString());
|
|
|
|
ImGui.PopFont();
|
|
ImGui.PopID();
|
|
}
|
|
}
|
|
|
|
ImGui.EndChild();
|
|
}
|
|
|
|
private unsafe void DrawFileListView(Vector2 size)
|
|
{
|
|
if (!ImGui.BeginChild("##FileDialog_FileList", size))
|
|
{
|
|
ImGui.EndChild();
|
|
return;
|
|
}
|
|
|
|
const ImGuiTableFlags tableFlags = ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg | ImGuiTableFlags.Hideable | ImGuiTableFlags.ScrollY | ImGuiTableFlags.NoHostExtendX;
|
|
if (ImGui.BeginTable("##FileTable", 4, tableFlags, size))
|
|
{
|
|
ImGui.TableSetupScrollFreeze(0, 1);
|
|
|
|
var hideType = this.flags.HasFlag(ImGuiFileDialogFlags.HideColumnType);
|
|
var hideSize = this.flags.HasFlag(ImGuiFileDialogFlags.HideColumnSize);
|
|
var hideDate = this.flags.HasFlag(ImGuiFileDialogFlags.HideColumnDate);
|
|
|
|
ImGui.TableSetupColumn(" File Name", ImGuiTableColumnFlags.WidthStretch, -1, 0);
|
|
ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthFixed | (hideType ? ImGuiTableColumnFlags.DefaultHide : ImGuiTableColumnFlags.None), -1, 1);
|
|
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed | (hideSize ? ImGuiTableColumnFlags.DefaultHide : ImGuiTableColumnFlags.None), -1, 2);
|
|
ImGui.TableSetupColumn("Date", ImGuiTableColumnFlags.WidthFixed | (hideDate ? ImGuiTableColumnFlags.DefaultHide : ImGuiTableColumnFlags.None), -1, 3);
|
|
|
|
ImGui.TableNextRow(ImGuiTableRowFlags.Headers);
|
|
for (var column = 0; column < 4; column++)
|
|
{
|
|
ImGui.TableSetColumnIndex(column);
|
|
var columnName = ImGui.TableGetColumnName(column);
|
|
ImGui.PushID(column);
|
|
ImGui.TableHeader(columnName);
|
|
ImGui.PopID();
|
|
if (ImGui.IsItemClicked())
|
|
{
|
|
var sorting = this.GetNewSorting(column);
|
|
this.SortFields(sorting);
|
|
}
|
|
}
|
|
|
|
if (this.filteredFiles.Count > 0)
|
|
{
|
|
var clipper = ImGui.ImGuiListClipper();
|
|
|
|
lock (this.filesLock)
|
|
{
|
|
clipper.Begin(this.filteredFiles.Count);
|
|
while (clipper.Step())
|
|
{
|
|
for (var i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
|
{
|
|
if (i < 0) continue;
|
|
|
|
var file = this.filteredFiles[i];
|
|
var selected = this.selectedFileNames.Contains(file.FileName);
|
|
var needToBreak = false;
|
|
|
|
var dir = file.Type == FileStructType.Directory;
|
|
var item = !dir ? GetIcon(file.Ext) : new IconColorItem
|
|
{
|
|
Color = dirTextColor,
|
|
Icon = FontAwesomeIcon.Folder,
|
|
};
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.Text, selected ? selectedTextColor : item.Color);
|
|
|
|
ImGui.TableNextRow();
|
|
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
needToBreak = this.SelectableItem(file, selected, item.Icon);
|
|
}
|
|
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
ImGui.TextUnformatted(file.Ext);
|
|
}
|
|
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
if (file.Type == FileStructType.File)
|
|
{
|
|
ImGui.TextUnformatted(file.FormattedFileSize + " ");
|
|
}
|
|
else
|
|
{
|
|
ImGui.TextUnformatted(" ");
|
|
}
|
|
}
|
|
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
var sz = ImGui.CalcTextSize(file.FileModifiedDate);
|
|
ImGui.SetNextItemWidth(sz.X + Scaled(5));
|
|
ImGui.TextUnformatted(file.FileModifiedDate + " ");
|
|
}
|
|
|
|
ImGui.PopStyleColor();
|
|
|
|
if (needToBreak) break;
|
|
}
|
|
}
|
|
|
|
clipper.End();
|
|
clipper.Destroy();
|
|
}
|
|
}
|
|
|
|
if (this.pathInputActivated)
|
|
{
|
|
if (ImGui.IsKeyReleased(ImGuiKey.Enter))
|
|
{
|
|
if (Directory.Exists(this.pathInputBuffer)) this.SetPath(this.pathInputBuffer);
|
|
this.pathInputActivated = false;
|
|
}
|
|
|
|
if (ImGui.IsKeyReleased(ImGuiKey.Escape))
|
|
{
|
|
this.pathInputActivated = false;
|
|
}
|
|
}
|
|
|
|
ImGui.EndTable();
|
|
}
|
|
|
|
if (this.pathClicked)
|
|
{
|
|
this.SetPath(this.currentPath);
|
|
}
|
|
|
|
ImGui.EndChild();
|
|
}
|
|
|
|
private bool SelectableItem(FileStruct file, bool selected, FontAwesomeIcon icon)
|
|
{
|
|
const ImGuiSelectableFlags flags = ImGuiSelectableFlags.AllowDoubleClick | ImGuiSelectableFlags.SpanAllColumns;
|
|
|
|
ImGui.PushFont(InterfaceManager.IconFont);
|
|
|
|
ImGui.TextUnformatted(icon.ToIconString());
|
|
ImGui.PopFont();
|
|
|
|
ImGui.SameLine(Scaled(25f));
|
|
|
|
if (ImGui.Selectable(file.FileName, selected, flags))
|
|
{
|
|
if (file.Type == FileStructType.Directory)
|
|
{
|
|
if (ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left))
|
|
{
|
|
this.pathClicked = this.SelectDirectory(file);
|
|
return true;
|
|
}
|
|
|
|
if (this.IsDirectoryMode())
|
|
{
|
|
this.SelectFileName(file);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.SelectFileName(file);
|
|
if (ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left))
|
|
{
|
|
this.wantsToQuit = true;
|
|
this.isOk = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool SelectDirectory(FileStruct file)
|
|
{
|
|
var pathClick = false;
|
|
|
|
if (file.FileName == "..")
|
|
{
|
|
if (this.pathDecomposition.Count > 1)
|
|
{
|
|
this.currentPath = ComposeNewPath(this.pathDecomposition.GetRange(0, this.pathDecomposition.Count - 1));
|
|
pathClick = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var newPath = Path.Combine(this.currentPath, file.FileName);
|
|
|
|
if (Directory.Exists(newPath))
|
|
{
|
|
this.currentPath = newPath;
|
|
}
|
|
|
|
pathClick = true;
|
|
}
|
|
|
|
return pathClick;
|
|
}
|
|
|
|
private void SelectFileName(FileStruct file)
|
|
{
|
|
if (ImGui.GetIO().KeyCtrl)
|
|
{
|
|
if (this.selectionCountMax == 0)
|
|
{ // infinite select
|
|
if (!this.selectedFileNames.Contains(file.FileName))
|
|
{
|
|
this.AddFileNameInSelection(file.FileName, true);
|
|
}
|
|
else
|
|
{
|
|
this.RemoveFileNameInSelection(file.FileName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (this.selectedFileNames.Count < this.selectionCountMax)
|
|
{
|
|
if (!this.selectedFileNames.Contains(file.FileName))
|
|
{
|
|
this.AddFileNameInSelection(file.FileName, true);
|
|
}
|
|
else
|
|
{
|
|
this.RemoveFileNameInSelection(file.FileName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (ImGui.GetIO().KeyShift)
|
|
{
|
|
if (this.selectionCountMax != 1)
|
|
{ // can select a block
|
|
this.selectedFileNames.Clear();
|
|
|
|
var startMultiSelection = false;
|
|
var fileNameToSelect = file.FileName;
|
|
var savedLastSelectedFileName = string.Empty;
|
|
|
|
foreach (var f in this.filteredFiles)
|
|
{
|
|
// select top-to-bottom
|
|
if (f.FileName == this.lastSelectedFileName)
|
|
{ // start (the previously selected one)
|
|
startMultiSelection = true;
|
|
this.AddFileNameInSelection(this.lastSelectedFileName, false);
|
|
}
|
|
else if (startMultiSelection)
|
|
{
|
|
if (this.selectionCountMax == 0)
|
|
{
|
|
this.AddFileNameInSelection(f.FileName, false);
|
|
}
|
|
else
|
|
{
|
|
if (this.selectedFileNames.Count < this.selectionCountMax)
|
|
{
|
|
this.AddFileNameInSelection(f.FileName, false);
|
|
}
|
|
else
|
|
{
|
|
startMultiSelection = false;
|
|
if (!string.IsNullOrEmpty(savedLastSelectedFileName))
|
|
{
|
|
this.lastSelectedFileName = savedLastSelectedFileName;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// select bottom-to-top
|
|
if (f.FileName == fileNameToSelect)
|
|
{
|
|
if (!startMultiSelection)
|
|
{
|
|
savedLastSelectedFileName = this.lastSelectedFileName;
|
|
this.lastSelectedFileName = fileNameToSelect;
|
|
fileNameToSelect = savedLastSelectedFileName;
|
|
startMultiSelection = true;
|
|
this.AddFileNameInSelection(this.lastSelectedFileName, false);
|
|
}
|
|
else
|
|
{
|
|
startMultiSelection = false;
|
|
if (!string.IsNullOrEmpty(savedLastSelectedFileName))
|
|
{
|
|
this.lastSelectedFileName = savedLastSelectedFileName;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.selectedFileNames.Clear();
|
|
this.fileNameBuffer = string.Empty;
|
|
this.AddFileNameInSelection(file.FileName, true);
|
|
}
|
|
}
|
|
|
|
private void AddFileNameInSelection(string name, bool setLastSelection)
|
|
{
|
|
this.selectedFileNames.Add(name);
|
|
if (this.selectedFileNames.Count == 1)
|
|
{
|
|
this.fileNameBuffer = name;
|
|
}
|
|
else
|
|
{
|
|
this.fileNameBuffer = $"{this.selectedFileNames.Count} files Selected";
|
|
}
|
|
|
|
if (setLastSelection)
|
|
{
|
|
this.lastSelectedFileName = name;
|
|
}
|
|
}
|
|
|
|
private void RemoveFileNameInSelection(string name)
|
|
{
|
|
this.selectedFileNames.Remove(name);
|
|
if (this.selectedFileNames.Count == 1)
|
|
{
|
|
this.fileNameBuffer = name;
|
|
}
|
|
else
|
|
{
|
|
this.fileNameBuffer = $"{this.selectedFileNames.Count} files Selected";
|
|
}
|
|
}
|
|
|
|
private bool DrawFooter()
|
|
{
|
|
var posY = ImGui.GetCursorPosY();
|
|
|
|
if (this.IsDirectoryMode())
|
|
{
|
|
ImGui.TextUnformatted("Directory Path :");
|
|
}
|
|
else
|
|
{
|
|
ImGui.TextUnformatted("File Name :");
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
|
|
var width = ImGui.GetContentRegionAvail().X - Scaled(100);
|
|
if (this.filters.Count > 0)
|
|
{
|
|
width -= Scaled(150);
|
|
}
|
|
|
|
var selectOnly = this.flags.HasFlag(ImGuiFileDialogFlags.SelectOnly);
|
|
|
|
ImGui.SetNextItemWidth(width);
|
|
if (selectOnly) ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 0.5f);
|
|
ImGui.InputText("##FileName", ref this.fileNameBuffer, 255, selectOnly ? ImGuiInputTextFlags.ReadOnly : ImGuiInputTextFlags.None);
|
|
if (selectOnly) ImGui.PopStyleVar();
|
|
|
|
if (this.filters.Count > 0)
|
|
{
|
|
ImGui.SameLine();
|
|
var needToApplyNewFilter = false;
|
|
|
|
ImGui.SetNextItemWidth(Scaled(150f));
|
|
if (ImGui.BeginCombo("##Filters", this.selectedFilter.Filter, ImGuiComboFlags.None))
|
|
{
|
|
var idx = 0;
|
|
foreach (var filter in this.filters)
|
|
{
|
|
var selected = filter.Filter == this.selectedFilter.Filter;
|
|
ImGui.PushID(idx++);
|
|
if (ImGui.Selectable(filter.Filter, selected))
|
|
{
|
|
this.selectedFilter = filter;
|
|
needToApplyNewFilter = true;
|
|
}
|
|
|
|
ImGui.PopID();
|
|
}
|
|
|
|
ImGui.EndCombo();
|
|
}
|
|
|
|
if (needToApplyNewFilter)
|
|
{
|
|
this.SetPath(this.currentPath);
|
|
}
|
|
}
|
|
|
|
var res = false;
|
|
|
|
ImGui.SameLine();
|
|
|
|
var disableOk = string.IsNullOrEmpty(this.fileNameBuffer) || (selectOnly && !this.IsItemSelected());
|
|
if (disableOk) ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 0.5f);
|
|
|
|
if (ImGui.Button("Ok") && !disableOk)
|
|
{
|
|
this.isOk = true;
|
|
res = true;
|
|
}
|
|
|
|
if (disableOk) ImGui.PopStyleVar();
|
|
|
|
ImGui.SameLine();
|
|
|
|
if (ImGui.Button("Cancel"))
|
|
{
|
|
this.isOk = false;
|
|
res = true;
|
|
}
|
|
|
|
this.footerHeight = ImGui.GetCursorPosY() - posY;
|
|
|
|
if (this.wantsToQuit && this.isOk)
|
|
{
|
|
res = true;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
private bool IsItemSelected()
|
|
{
|
|
if (this.selectedFileNames.Count > 0) return true;
|
|
if (this.IsDirectoryMode()) return true; // current directory
|
|
return false;
|
|
}
|
|
|
|
private bool ConfirmOrOpenOverWriteFileDialogIfNeeded(bool lastAction)
|
|
{
|
|
if (this.IsDirectoryMode()) return lastAction;
|
|
if (!this.isOk && lastAction) return true; // no need to confirm anything, since it was cancelled
|
|
|
|
var confirmOverwrite = this.flags.HasFlag(ImGuiFileDialogFlags.ConfirmOverwrite);
|
|
|
|
if (this.isOk && lastAction && !confirmOverwrite) return true;
|
|
|
|
if (this.okResultToConfirm || (this.isOk && lastAction && confirmOverwrite))
|
|
{ // if waiting on a confirmation, or need to start one
|
|
if (this.isOk)
|
|
{
|
|
if (!File.Exists(this.GetFilePathName()))
|
|
{ // quit dialog, it doesn't exist anyway
|
|
return true;
|
|
}
|
|
|
|
// already exists, open dialog to confirm overwrite
|
|
this.isOk = false;
|
|
this.okResultToConfirm = true;
|
|
}
|
|
|
|
var name = $"The file Already Exists !##{this.title}{this.id}OverWriteDialog";
|
|
var res = false;
|
|
var open = true;
|
|
|
|
ImGui.OpenPopup(name);
|
|
if (ImGui.BeginPopupModal(name, ref open, ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove))
|
|
{
|
|
ImGui.TextUnformatted("Would you like to Overwrite it ?");
|
|
if (ImGui.Button("Confirm"))
|
|
{
|
|
this.okResultToConfirm = false;
|
|
this.isOk = true;
|
|
res = true;
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
if (ImGui.Button("Cancel"))
|
|
{
|
|
this.okResultToConfirm = false;
|
|
this.isOk = false;
|
|
res = false;
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui.EndPopup();
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|