FFXIV插件配置界面Dalamud:ImGui对话框集成

FFXIV插件配置界面Dalamud:ImGui对话框集成

【免费下载链接】Dalamud FFXIV plugin framework and API 【免费下载链接】Dalamud 项目地址: 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消息通知

实现原理

对话框状态管理

mermaid

模态对话框处理

// 模态对话框绘制逻辑
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;
    }
}

实际应用场景

插件配置界面

mermaid

主题定制界面

// 主题配置对话框示例
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插件开发提供了强大的用户界面构建能力。通过文件对话框、字体选择器、通知系统等组件的有机结合,开发者可以创建出专业级的插件配置界面。关键优势包括:

  1. 原生集成:与游戏UI无缝融合
  2. 高性能:基于ImGui的即时模式渲染
  3. 易用性:简洁的API设计和丰富的预设功能
  4. 可扩展性:支持自定义组件和布局

掌握这些对话框技术将显著提升插件的用户体验和配置灵活性,是每个FFXIV插件开发者必备的技能。

【免费下载链接】Dalamud FFXIV plugin framework and API 【免费下载链接】Dalamud 项目地址: https://gitcode.com/GitHub_Trending/da/Dalamud

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值