FFXIV插件配置界面Dalamud:ImGui对话框集成
【免费下载链接】Dalamud FFXIV plugin framework and API 项目地址: https://gitcode.com/GitHub_Trending/da/Dalamud
概述
Dalamud作为FFXIV(最终幻想14)的插件框架,提供了强大的ImGui(Immediate Mode GUI)对话框集成能力。通过ImGui,开发者可以创建直观、响应式的配置界面,为用户提供无缝的插件配置体验。本文将深入探讨Dalamud中ImGui对话框的实现原理、核心组件以及最佳实践。
ImGui对话框核心组件
文件对话框系统
Dalamud提供了完整的文件对话框系统,支持打开、保存文件和文件夹选择:
// 文件对话框管理器示例
public class FileDialogManager
{
// 打开文件夹对话框
public void OpenFolderDialog(string title, Action<bool, string> callback)
{
this.SetDialog("OpenFolderDialog", title, string.Empty,
this.savedPath, ".", string.Empty, 1, false,
ImGuiFileDialogFlags.SelectOnly, callback);
}
// 打开文件对话框(多选支持)
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);
}
}
字体选择对话框
// 字体选择对话框实现
public sealed class SingleFontChooserDialog : IDisposable
{
private const float MinFontSizePt = 1;
private const float MaxFontSizePt = 127;
// 字体大小预设列表
private static readonly (string Name, float Value)[] FontSizeList =
{
("9.6", 9.6f), ("10", 10f), ("12", 12f), ("14", 14f),
("16", 16f), ("18", 18f), ("18.4", 18.4f), ("20", 20),
("23", 23), ("34", 34), ("36", 36), ("40", 40),
("45", 45), ("46", 46), ("68", 68), ("90", 90),
};
}
通知系统
// 通知消息系统
public sealed record Notification : INotification
{
public string Content { get; set; } = string.Empty;
public string? Title { get; set; }
public NotificationType Type { get; set; } = NotificationType.None;
public TimeSpan InitialDuration { get; set; } = DefaultDuration;
public bool UserDismissable { get; set; } = true;
public float Progress { get; set; } = 1f;
}
对话框类型对比
| 对话框类型 | 用途 | 模态支持 | 多选支持 | 文件过滤 |
|---|---|---|---|---|
| OpenFolderDialog | 文件夹选择 | ✅ | ❌ | ❌ |
| OpenFileDialog | 文件选择 | ✅ | ✅ | ✅ |
| SaveFileDialog | 文件保存 | ✅ | ❌ | ✅ |
| FontChooserDialog | 字体选择 | ✅ | ❌ | ❌ |
| Notification | 消息通知 | ❌ | ❌ | ❌ |
实现原理
对话框状态管理
模态对话框处理
// 模态对话框绘制逻辑
public void Draw()
{
if (this.IsModal)
{
var open = true;
if (!ImGui.BeginPopupModal(this.popupImGuiName, ref open, this.WindowFlags) || !open)
{
this.Cancel();
return;
}
}
else
{
var open = true;
if (!ImGui.Begin(this.popupImGuiName, ref open, this.WindowFlags) || !open)
{
ImGui.End();
this.Cancel();
return;
}
}
// 对话框内容绘制...
}
最佳实践
1. 对话框布局优化
// 响应式布局示例
private void DrawChoices()
{
var lineHeight = ImGui.GetTextLineHeight();
var previewHeight = (ImGui.GetFrameHeightWithSpacing() - lineHeight) +
Math.Max(lineHeight, this.selectedFont.LineHeightPx * 2);
// 使用表格布局
if (ImGui.BeginTable("##table", 3, ImGuiTableFlags.None))
{
ImGui.TableSetupColumn("字体", ImGuiTableColumnFlags.WidthStretch, 0.4f);
ImGui.TableSetupColumn("样式", ImGuiTableColumnFlags.WidthStretch, 0.4f);
ImGui.TableSetupColumn("大小", ImGuiTableColumnFlags.WidthStretch, 0.2f);
ImGui.TableHeadersRow();
// 表格内容...
ImGui.EndTable();
}
}
2. 异步操作处理
// 异步字体加载
private Task<List<IFontFamilyId>>? fontFamilies;
private void LoadFontsAsync()
{
this.fontFamilies = Task.Run(() =>
{
// 异步加载字体列表
return FontManager.GetAvailableFontFamilies();
});
}
3. 错误处理机制
// 健壮的错误处理
public void Draw()
{
try
{
if (this.fontHandle?.LoadException is { } loadException)
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGui.Text(loadException.Message);
ImGui.PopStyleColor();
}
else if (!this.fontHandle?.Available ?? true)
{
ImGui.Text("加载字体中...");
}
}
catch (Exception ex)
{
Log.Error(ex, "对话框绘制失败");
}
}
高级特性
自定义侧边栏项目
// 添加自定义快速访问项
public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = [];
public void AddCustomSidebarItem(string name, string path, FontAwesomeIcon icon, int position)
{
this.CustomSideBarItems.Add((name, path, icon, position));
if (this.dialog != null)
{
this.dialog.SetQuickAccess(name, path, icon, position);
}
}
对话框标志系统
// 对话框行为控制标志
[Flags]
public enum ImGuiFileDialogFlags
{
None = 0,
SelectOnly = 1 << 0,
DontShowHiddenFiles = 1 << 1,
DisableCreateDirectoryButton = 1 << 2,
HideSideBar = 1 << 3,
HideColumnType = 1 << 4,
HideColumnSize = 1 << 5,
HideColumnDate = 1 << 6,
ConfirmOverwrite = 1 << 7,
}
性能优化建议
1. 资源复用
// 字体句柄复用
private IFontHandle? fontHandle;
private void UpdateFontHandle()
{
if (this.fontHandle != null &&
this.fontHandle.FontSpec.Equals(this.selectedFont))
{
return; // 无需重新创建
}
this.fontHandle?.Dispose();
this.fontHandle = this.selectedFont.CreateFontHandle(this.atlas);
}
2. 延迟加载
// 按需加载资源
private bool resourcesLoaded = false;
public void EnsureResourcesLoaded()
{
if (!this.resourcesLoaded)
{
this.LoadFontsAsync();
this.LoadIcons();
this.resourcesLoaded = true;
}
}
实际应用场景
插件配置界面
主题定制界面
// 主题配置对话框示例
public class ThemeConfigDialog
{
private readonly FileDialogManager fileDialogManager;
private readonly SingleFontChooserDialog fontChooser;
public void DrawThemeConfig()
{
if (ImGui.Button("选择背景图片"))
{
this.fileDialogManager.OpenFileDialog(
"选择背景图片",
"图片文件|*.png;*.jpg;*.jpeg",
this.OnBackgroundSelected,
1);
}
if (ImGui.Button("选择字体"))
{
this.fontChooser.Show();
}
}
private void OnBackgroundSelected(bool success, List<string> files)
{
if (success && files.Count > 0)
{
this.currentTheme.BackgroundImage = files[0];
}
}
}
总结
Dalamud的ImGui对话框系统为FFXIV插件开发提供了强大的用户界面构建能力。通过文件对话框、字体选择器、通知系统等组件的有机结合,开发者可以创建出专业级的插件配置界面。关键优势包括:
- 原生集成:与游戏UI无缝融合
- 高性能:基于ImGui的即时模式渲染
- 易用性:简洁的API设计和丰富的预设功能
- 可扩展性:支持自定义组件和布局
掌握这些对话框技术将显著提升插件的用户体验和配置灵活性,是每个FFXIV插件开发者必备的技能。
【免费下载链接】Dalamud FFXIV plugin framework and API 项目地址: https://gitcode.com/GitHub_Trending/da/Dalamud
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



