专业编程基础技术教程

网站首页 > 基础教程 正文

【温达】插件制作-添加系统级菜单

ccvgpt 2025-01-23 15:41:11 基础教程 13 ℃

上篇我们成功把winda迁移到了赛季服,插件也如预期很好的加载之前写过的内容;

今天继续给winda增加新的功能,添加系统级别的菜单;

【温达】插件制作-添加系统级菜单

新增关闭按钮

前面说到使用宏命令/wd,打开一个我们自己设置的窗口f,这个f加载了一张自制的png图片;

我们也在小地图增加了按钮,以方便打开和关闭它

为了更加便于图形化操作,我们要给这个窗口添加一个关闭按钮;

基于美观的考虑,我们还用figma做一个关闭图标;记得宽高的像素必须是2的幂次方(这里我们导出32x32的),保存到winda插件目录下;

在代码中添加一个按钮,并把它放到显示的窗口上

-- 在f上创建一个可以显示的取消按钮
-- 使点击时关闭这个窗口
local cf = CreateFrame("Button", nil, f)
cf:SetPoint("TOPRIGHT", -5, -5)
cf:SetWidth(20); cf:SetHeight(20)
cf:SetFrameStrata("HIGH")
cf:SetFrameLevel(2)
local texture = cf:CreateTexture(nil, "BACKGROUND")
texture:SetTexture("Interface/AddOns/winda/cancel.png")
texture:SetAllPoints()

我们还需要给新加的按钮cf添加一个点击事件,点击时把前面显示的窗口f关闭掉,如下面这一段:

cf:RegisterForClicks("AnyUp", "AnyDown")
cf:SetScript("OnClick", function (self, button, down)
    -- 点击隐藏大窗口
    if down then
        f:Hide()
    end
end)

完成这一步后,窗口f就有了两种打开和三种关闭的方法:分别是宏命令、小地图按钮和窗口按钮;

ESC菜单按钮

我们平时使用的集成插件,像ElvUI和NDui,通常会在按下ESC键时,有一个对应的设置菜单; 接下来我们就一起实现它,在ESC系统菜单里添加一个winda设置按钮,用作以后插件的控制台;

在添加之前首先应该知道,这个按钮需要添加到什么地方;我们之前的窗口都是添加到系统的窗口,系统窗口覆盖了整个屏幕,它的名字叫做UIParent

我们自己写的窗口,都是默认加到这个UIParent上的;添加到它上的所有可见内容,都有这样的从属关系:被添加的窗口是新加的窗口的父视图

而如果想在系统菜单窗口上添加一个按钮,那么我们就一定要知道系统菜单的名字;

“系统很神秘,但仍有迹可循”

暴雪API提供的宏/fstack是一个相当神级的命令,它可以查看当前窗口下一切可显示的窗口层级,我们不妨在游戏中用一下这个宏;

你会发现,鼠标所到之处一片绿色;这片绿色表示当前鼠标位置的窗口,同时还会显示这个窗口的层级信息;

按ESC打开系统菜单,使用宏/fstack,并把鼠标指向它,可以看到菜单的名字GameMenuFrame

然后我们自己创建一个按钮gui把它放到菜单上

-- 添加一个系统菜单按钮
-- 在添加之前,我们应该知道这个按钮需要添加到哪
-- 添加到系统菜单 GameMenuFrame 上
local gui = CreateFrame("Button", "WindaGUIButton", GameMenuFrame,
"GameMenuButtonTemplate, BackdropTemplate")
gui:SetText("winda 控制台")
gui:SetPoint("TOP", GameMenuFrame, "TOP", 0, -35)
GameMenuFrame:HookScript("OnShow", function(self)
    GameMenuButtonHelp:SetPoint("TOP", gui, "BOTTOM", 0, -5)
    self:SetHeight(self:GetHeight() + gui:GetHeight() + 22)
end)

创建完按钮后再添加一个事件,让之前的窗口f显示出来,并且把菜单隐藏掉

-- 再来添加点击该按钮的事件
-- 点击显示窗口f
-- 并隐藏掉系统菜单
gui:SetScript("OnClick", function ()
    print("打开winda系统菜单")
    f:Show()
    HideUIPanel(GameMenuFrame)
end)

保存代码重新reload一下,winda控制台就神奇的出现了,点击按钮也显示出了我们的winda

设置选项插件标签

最后再来添加一种方式,将自制的窗口添加到设置选项里;

我们平时使用的插件,有些会将功能放到设置选项的插件标签页下;这是暴雪系统API对插件开放的另一种能力,下面我们就把winda及版本号显示在里面

-- 在设置选项菜单的插件标签下添加一个winda文字显示
-- 这次的父窗口叫做 InterfaceOptionsFramePanelContainer
local sf = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
sf:SetScript("OnEvent", function (self, event, loadedAddon)
    if loadedAddon ~= "winda" then return end
end)

新建一个叫做sf的窗口,它的父视图叫做InterfaceOptionsFramePanelContainer;它将要显示的时候,添加加一个标题,用于显示插件名称和版本号;

sf:RegisterEvent("ADDON_LOADED")
sf:SetScript("OnShow", function (sf)
    -- 显示标题
    local title = sf:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT", 16, -16)
    title:SetText("winda".." v"..tostring(GetAddOnMetadata("winda", "Version")))
    
    -- 只在显示时加载
    sf:SetScript("OnShow", nil)
end)
sf.name = "winda"
sf:Hide()

这次在创建完成后利用系统API把它添加到设置选项中

InterfaceOptions_AddCategory(sf)

保存进入游戏看下最终的效果

以上

如上两种系统菜单的添加方法,我们可以猜想到,如果能获取所有窗口的名称,那么就可以在任意窗口上添加想要的内容;以此类推,写插件就是这么简单,像叠图片一样

我在听风,也在等你。

最近发表
标签列表