创建 WoW 插件 - 第 11 部分:告诉我们的插件创建我们的复选框(设置)

Part 11: Telling Our Addon to Create Checkboxes
第 11 部分:告诉我们的插件创建复选框

Difficulty: ?? Medium  难度: ?? 中等

**Now that we have our CreateCheckboxes function setup, we can finally tell the addon to create those checkboxes by looping through our settings table.
**现在我们已经设置了 CreateCheckboxes 函数,我们终于可以通过循环访问我们的设置表来告诉插件创建这些复选框。


Step 1: Creating Our Checkboxes with a for loop
第 1 步:使用 for 循环创建我们的复选框

First, we'll need an invisible frame in our Settings.lua file to listen for the "PLAYER_LOGIN" event.
首先,我们需要在 Settings.lua 文件中有一个不可见的帧来监听 “PLAYER_LOGIN” 事件。

Let's add the following code to do so:
为此,我们添加以下代码:

local eventListenerFrame = CreateFrame("Frame", "MyAddonSettingsEventListenerFrame", UIParent)

eventListenerFrame:RegisterEvent("PLAYER_LOGIN")

eventListenerFrame:SetScript("OnEvent", function(self, event)
  if event == "PLAYER_LOGIN" then
    for _, setting in pairs(settings) do
        CreateCheckbox(setting.settingText, setting.settingKey, setting.settingTooltip)
    end
  end
end)

The above code creates an invisible frame, very similarly to the frame we created to listen to events in our other .lua file.
上面的代码创建了一个不可见的帧,与我们创建的用于侦听其他 .lua 文件中的事件的帧非常相似。

Instead, this frame is registered to the "PLAYER_LOGIN" event. When that event fires, the CreateCheckbox() function is called, which creates all the checkboxes it needs by "looping" through our settings table.
相反,此帧已注册到 “PLAYER_LOGIN” 事件。当该事件触发时,将调用 CreateCheckbox() 函数,该函数通过“循环”我们的设置表来创建它需要的所有复选框。

You'll notice that it loops through the settings table, shown in ()'s of the for loop. At each stop of the settings table, we're defining that specific table as setting and we can access the components of that table by using a . and its variable name within that table.
你会注意到它遍历设置表,如 for 循环的 () 所示。在 settings 表的每个停止点,我们将该特定表定义为 setting,并且我们可以通过使用该表中的 .及其变量名称来访问该表的组件。

For instance, in our for loop, setting.settingText will equal "Enable tracking of Kills" on the first loop.
例如,在我们的 for 循环中,setting.settingText 将等于第一个循环中的 “Enable tracking of Kills”。

The line for _, setting in pairs(settings) do is an example of a "for loop", starting with for, giving a condition, and ending with do and end.
该行 for _, setting in pairs(settings) do 是 “for 循环” 的一个示例,以 for 开头,给出一个条件,以 do 和 end 结束。

In this case, the condition isn't especially noticeable, but in english the for loop is basically stating:
在这种情况下,条件不是特别明显,但在英语中,for 循环基本上是这样说的:

FOR 

For every...  对于每一个...

_, SETTING in PAIRS(settings)
_, PAIRS(设置) 中的 SETTING

Entry in the settings table
设置表中输入

DO 

Do the following until we reach the end of the settings table
执行以下操作,直到到达设置表的末尾

Another example of a for loop is shown below:
for 循环的另一个示例如下所示:

for i = 1, 10 do
    print(i)
end

This for loop counts from 1 to 10 and prints out the number it is at each loop. Every time the code inside of the for loop is executed, i increases by 1 until it reaches the for loop condition, which is 10.
这个 for 循环从 1 到 10 计数,并打印出每个循环的数字。每次执行 for 循环中的代码时,i 都会增加 1,直到达到 for 循环条件,即 10

Next, we'll need to define our MyAddonDB.settingsKeys table. Let's do so by appending the following code inside of our "PLAYER_LOGIN" eventHandler event, at the top:
接下来,我们需要定义 MyAddonDB.settingsKeys 表。为此,我们将以下代码附加到 “PLAYER_LOGIN”eventHandler 事件的顶部:

if not MyAddonDB.settingsKeys then
    MyAddonDB.settingsKeys = {}
end

Our full "PLAYER_LOGIN" event should appear as such:
我们完整的 “PLAYER_LOGIN” 事件应如下所示:

if event == "PLAYER_LOGIN" then
    if not MyAddonDB.settingsKeys then
        MyAddonDB.settingsKeys = {}
    end

    for _, setting in pairs(settings) do
        CreateCheckbox(setting.settingText, setting.settingKey, setting.settingTooltip)
    end
end

Let's move on and put these settings to use in our addon!
让我们继续在这些设置在我们的插件中使用!


Step 2: Using Our Settings in Our Addon
第 2 步:在我们的插件中使用我们的设置

To access the value of one of our settings, we need to access it in the database.
要访问我们其中一个设置的值,我们需要在数据库中访问它。

Think of each step as "hopping into a box, and then another box, then another..."
将每个步骤视为“跳入一个盒子,然后跳入另一个盒子,然后又跳进另一个盒子......”

MyAddonDB > settingsKeys > key

The above, concatenated with .'s becomes...
上面与 .' 连接在一起s 变为...

MyAddonDB.settingsKeys.enableKillTracking

In our main addon .lua file, we will want to find this line of code: if event == "COMBAT_LOG_EVENT_UNFILTERED" then. Once we find this line, we're going to change it to this:
在我们的主插件 .lua 文件中,我们需要找到这行代码: if event == "COMBAT_LOG_EVENT_UNFILTERED" then .找到这一行后,我们要把它改成这样:

if event == "COMBAT_LOG_EVENT_UNFILTERED" and MyAddonDB.settingsKeys.enableKillTracking then

Since both conditions in the if then statement need to be true, the following code inside of it will not run unless the event equals "COMBAT_LOG_EVENT_UNFILTERED" and MyAddonDB.settingsKeys.enableKillTracking is true.
由于 if then 语句中的两个条件都需要为 true,因此除非事件等于 “COMBAT_LOG_EVENT_UNFILTERED” 且 MyAddonDB.settingsKeys.enableKillTracking 为 true,否则其中的以下代码不会运行。

The other main addon event we can modify with our setting is elseif event == "CHAT_MSG_MONEY" then. We can modify this to instead be:
我们可以使用设置修改的另一个主要插件事件是 elseif event == "CHAT_MSG_MONEY" then 。我们可以将其修改为:

elseif event == "CHAT_MSG_MONEY" and MyAddonDB.settingsKeys.enableCurrencyTracking then

In our Settings.lua file, we made sure that these settings are a default of true if the setting has never loaded before, so we don't have to worry about our addon not working "right out of the box."
在我们的 Settings.lua 文件中,如果这些设置以前从未加载过,我们确保这些设置是默认的 true,因此我们不必担心我们的插件无法“开箱即用”。

The player will have to go into the settings menu to disable these manually.
播放器必须进入设置菜单才能手动禁用这些。

Now, the question is...  现在,问题是......

How are players going to open the settings for this addon?
玩家将如何打开此插件的设置?



创建 WoW 插件 - 第 12 部分:创建小地图按钮

Part 12: Creating a Minimap Button
第 12 部分:创建 Minimap 按钮

Using LibDBIcon 1.0 and Ace3 (WoW Addon Libraries)
使用 LibDBIcon 1.0 和 Ace3(WoW 插件库)

Difficulty: ?? Medium  难度: ?? 中等

We've made it pretty far! This will bet the second to last step of our addon creation, where we'll be covering quality of life changes in Part 13! Let's get started with using libraries!
我们已经走得很远了!这将押注我们插件创建的倒数第二步,我们将在第 13 部分中介绍生活质量的变化!让我们开始使用吧!


Step 1: Downloading and Installing the Libraries
第 1 步:下载和安装库

The very first thing we'll need to do is to download and install two libraries to the folder for our addon, and an image for our minimap button icon:
我们需要做的第一件事是将两个库下载并安装到我们的插件文件夹中,以及一个小地图按钮图标的一张图片:

  • Download LibDBIcon-1.0  下载 LibDBIcon-1.0

  • Download Ace3  下载 Ace3

  • Download Image  下载图片

Let's find these resources below.
让我们在下面找到这些资源。

  1. We can find the LibDBIcon-1.0 Library download here.
    我们可以在此处找到 LibDBIcon-1.0 库下载。

  2. We can find the Ace3 Library download here.
    我们可以在此处找到 Ace3 库下载。

  3. We're also going to need to download an image for our minimap button. This image needs to be a power of 2 in order to work, and typically should be in .TGA format. I recommend using a 512px square image. If you cannot find a suitable image, you can download and use the image here.
    我们还需要为我们的小地图按钮下载一张图片。此图像需要是 2 的幂数才能工作,并且通常应为 。TGA 格式。我建议使用 512 像素的方形图像。如果您找不到合适的图像,您可以在此处下载并使用该图像。

Make sure to download the .zip files and don't install the addons directly to World of Warcraft, as this won't do much for us.
确保下载 .zip 文件,不要将插件直接安装到魔兽世界,因为这对我们没有多大帮助。

Once you have the files downloaded, extract the folders inside to the folder that contains your main .lua file.
下载文件后,将其中的文件夹解压缩到包含主 .lua 文件的文件夹中。

The image file should be in the same folder that contains your main .lua file for the purposes of this tutorial. It should be named minimap.tga, as the code below will be looking for that image specifically.
对于本教程,图像文件应位于包含主 .lua 文件的同一文件夹中。它应该命名为 minimap.tga,因为下面的代码将专门查找该图像。

But, let's take it a step further, and create a NEW folder for our libraries to live inside of. In your addon's folder, create a new folder called libs. Place our LibDBIcon-1.0 folder and Ace3 folder inside of it.
但是,让我们更进一步,为我们的库创建一个 NEW 文件夹。在插件的文件夹中,创建一个名为 libs 的新文件夹。将我们的 LibDBIcon-1.0 文件夹和 Ace3 文件夹放入其中。

Your folder structure should now align as follows:
您的文件夹结构现在应按如下方式对齐:

  • MyAddon (your addon folder)
    MyAddon (您的插件文件夹)

    • libs (folder)  libs(文件夹)

      • LibDBIcon-1.0 (folder)  LibDBIcon-1.0 (文件夹)

      • Ace3 (folder)  Ace3 (文件夹)

    • minimap.tga (image)  minimap.tga (图片)

    • MyAddon.lua

    • MyAddon.toc

    • Settings.lua  Settings.lua (设置.lua)

Once you have LibDBIcon and Ace3 installed into the libs folder for your addon, we'll need to tell our .toc file about them.
将 LibDBIcon 和 Ace3 安装到插件的 libs 文件夹中后,我们需要告诉我们的 .toc 文件它们。

Let's modify our .toc file to appear as such:
让我们修改 .toc 文件,使其如下所示:

## Interface: 11502
## Title: MyAddon
## Notes: A description here.
## Author: Your Name
## Version: 1.0.0
## RequiredDeps:
## X-Curse-Project-ID: 99999
## SavedVariables:
## SavedVariablesPerCharacter: MyAddonDB
# Libraries
libs/Ace3/AceAddon-3.0/AceAddon-3.0.lua
libs/Ace3/AceDB-3.0/AceDB-3.0.lua
libs/LibDBIcon-1.0/embeds.xml

# Main Files
MyAddon.lua
Settings.lua

We added #Libraries and #Main Files to our .toc file for ease of organization. Your library files should always load first, so they are above our other .lua files.
我们将 #Libraries 和 #Main 文件添加到 .toc 文件中,以便于组织。您的库文件应始终首先加载,因此它们位于其他 .lua 文件的上方

Now that we have our .toc file updated and our LibDBIcon files installed, let's create our button!
现在我们已经更新了 .toc 文件并安装了 LibDBIcon 文件,让我们创建按钮!


Step 2: Creating the Minimap Button
第 2 步:创建 Minimap 按钮

To create the minimap button, we need to register our addon with the Ace3 and LibDBIcon-1.0 libraries by declaring a couple variables. Let's throw all of this code at the bottom of our Settings.lua file so we can keep track of it.
要创建小地图按钮,我们需要通过声明几个变量来向 Ace3 和 LibDBIcon-1.0 库注册我们的插件。让我们将所有这些代码放在 Settings.lua 文件的底部,以便我们可以跟踪它。

Go ahead and append the following code to the bottom of Settings.lua:
继续将以下代码附加到 Settings.lua 的底部:

local addon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
MyAddonMinimapButton = LibStub("LibDBIcon-1.0", true)

The code above allows us to register "MyAddon" with the Ace3 and LibDBIcon-1.0 libraries through LibStub().
上面的代码允许我们通过 LibStub() 向 Ace3 和 LibDBIcon-1.0 库注册 “MyAddon”。

Now that we're registered, let's go ahead and put the rest of our code for the minimap button below the above code we added:
现在我们已经注册了,让我们继续将小地图按钮的其余代码放在我们添加的上述代码下方:

local miniButton = LibStub("LibDataBroker-1.1"):NewDataObject("MyAddon", {
	type = "data source",
	text = "MyAddon",
	icon = "Interface\\AddOns\\MyAddon\\minimap.tga",
	OnClick = function(self, btn)
        if btn == "LeftButton" then
		    MyAddon:ToggleMainFrame()
        elseif btn == "RightButton" then
            if settingsFrame:IsShown() then
                settingsFrame:Hide()
            else
                settingsFrame:Show()
            end
        end
	end,

	OnTooltipShow = function(tooltip)
		if not tooltip or not tooltip.AddLine then
			return
		end

		tooltip:AddLine("MyAddon\n\nLeft-click: Open MyAddon\nRight-click: Open MyAddon Settings", nil, nil, nil, nil)
	end,
})

function addon:OnInitialize()
	self.db = LibStub("AceDB-3.0"):New("MyAddonMinimapPOS", {
		profile = {
			minimap = {
				hide = false,
			},
		},
	})

	MyAddonMinimapButton:Register("MyAddon", miniButton, self.db.profile.minimap)
end

MyAddonMinimapButton:Show("MyAddon")

We won't go into great detail how this code works, as most of this is pulled from the documentation provided by the libraries. But, we can pick out a couple things to note:
我们不会详细介绍此代码的工作原理,因为其中大部分内容都是从库提供的文档中提取的。但是,我们可以挑选出几点需要注意:

  • We have an OnClick function being called, and within that function there is another function we have not yet written called MyAddon:ToggleMainFrame(). We will write this function in our other .lua file in a moment.
    我们有一个正在调用的 OnClick 函数,在该函数中还有另一个我们尚未编写的函数,称为 MyAddon:ToggleMainFrame()。我们稍后会在另一个 .lua 文件中编写此函数。

  • There is a tooltip:AddLine() function being called. This will show a tooltip when a person hovers over the minimap button. We always want to make sure this gives instructions to the user on how to operate the minimap button.
    有一个 tooltip:AddLine() 函数正在被调用。当一个人将鼠标悬停在小地图按钮上时,这将显示一个工具提示。我们始终希望确保这为用户提供了如何操作小地图按钮的说明。

Now, let's get to creating our MyAddon:ToggleMainFrame() function.
现在,让我们开始创建 MyAddon:ToggleMainFrame() 函数。


Step 3: Creating the MyAddon:ToggleMainFrame() Function
第 3 步:创建 MyAddon:ToggleMainFrame() 函数

This code is fairly simple, and we've already used it previously, but we're defining it as a global variable so we can call it across files.
这段代码相当简单,我们之前已经使用过它,但我们将其定义为全局变量,以便我们可以跨文件调用它。

First, we're going to throw this code at the top of our main .lua file.
首先,我们将把这段代码放在主 .lua 文件的顶部。

MyAddon = MyAddon or {}

Here, we initialized MyAddon with a blank or nil state.
在这里,我们使用 blank 或 nil 状态初始化 MyAddon

Next, put the below code at the bottom of your other main .lua file.
接下来,将以下代码放在另一个主 .lua 文件的底部

function MyAddon:ToggleMainFrame()
    if not mainFrame:IsShown() then
        mainFrame:Show()
    else
        mainFrame:Hide()
    end
end

You'll notice that we did not declare this function using local, meaning this can be called by any addon that wants to call it.
你会注意到我们没有使用 local 声明这个函数,这意味着任何想要调用它的插件都可以调用它。

This is useful if you ever create an addon that another addon may want to use as a dependency, or for API purposes that gathers information that your addon can easily access.
如果您曾经创建一个插件,另一个插件可能想要用作依赖项,或者用于收集您的插件可以轻松访问的信息的 API,这将非常有用。

In our case, we're defining it globally so we can call it inside of our Settings.lua file from our main .lua file.
在我们的例子中,我们全局定义它,以便我们可以在主 .lua 文件中的 Settings.lua 文件中调用它。

Now... 现在。。。

We're officially done developing MyAddon!
我们正式完成了 MyAddon 的开发!

Congratulations on developing your first World of Warcraft addon! Go ahead and test it! Play around with it! Make changes to it! Delete it and start your own addon! Whatever you want to do from here is all you!
恭喜您开发了您的第一个魔兽世界插件!快来测试吧!玩弄它!对其进行更改!删除它并开始您自己的插件!无论你想从这里做什么,就是你的全部!

However, there is still more to learn!
但是,还有更多东西需要学习!

The next tutorial is going to be a quaility of life tutorial, and you can find me in Part 13 for that.
下一个教程将是一个 qualility of life 教程,你可以在 Part 13 中找到我

At the end of that tutorial, there will be a bonus task set that I think you'll really like. At the end of that tutorial, we will be providing all the code to the addon in that state.
在该教程的结尾,将有一个我认为您会非常喜欢的奖励任务集。在该教程结束时,我们将向处于该状态的插件提供所有代码。