3

我正在为预先存在的插件编写 UI。或者,更具体地说,添加配置选项并尝试利用 Interface Options Addons (IOA) 面板。我一直在参考 wowwiki,特别是讨论使用该面板的页面,但更普遍的是一堆页面。

我遇到了一个问题,我敢肯定这只是我没有编写插件的经验(我写了一些,但每次都是学习经验)。基本概念是:

  • 创建主面板 - 使用 XML
  • 为应该在主面板上可见的内容创建子项(即全局选项) - 使用 XML
  • 为每个子项(配置类别)创建一个子面板——使用Lua(子面板的数量和名称是动态的)
  • 为每个子面板创建子项 - 使用 Lua

有效的事情是:

  • 主面板显示在 IOA 面板中
  • 子面板显示在 IOA 面板中,作为主面板的子项
  • 我放在子面板上的纹理显示在它们上

我遇到的问题是:

  • 如果我将子面板创建为主面板的子面板,它们会显示在主面板的顶部
  • 如果我创建的子面板是 UIParent 的子面板,它们会显示在主屏幕上(当 IOA 窗口未打开时可见
  • 我在 XML 文件中创建的任何内容都没有显示为主面板的子框架

我到目前为止的代码(为简洁起见已剪辑)位于消息的底部。任何帮助/建议将不胜感激。我知道代码部分有很多内容,但我想尽可能清楚地了解我在做什么。

请注意,我确实在《魔兽争霸》UI 官方论坛上发布了有关此问题的帖子,但在那里无法获得任何帮助。

嵌入.xml

...snip...
<Frame name="MyAddonFrame" parent="UIParent" hidden="false">
  <Scripts>
    <OnLoad>
      self:RegisterEvent("UNIT_TARGET");
      self:RegisterEvent("PLAYER_ENTERING_WORLD");
      MyAddon_OnLoad(self);
    </OnLoad>
    <OnEvent function="MyAddon_OnEvent" />
    </Scripts>

    <Frames>
      <Frame parent="MyAddonFrame" inherits="UIDropDownMenuTemplate">
        <Frames>
          <Button name="MyAddon_MacroSelectDropdownButton">
            <Anchors>
              <Anchor point="CENTER"/>
            </Anchors>

            <Scripts>
              <OnLoad>
                UIDropDownMenu_Initialize(this,
                MyAddon_MacroSelectDropdown_OnLoad);
              </OnLoad>
              <OnClick>
                MyAddon_MacroSelectDropdownButton_OnClick();
              </OnClick>
            </Scripts>
          </Button>
          <MessageFrame>
            <Anchors>
              <Anchor point="CENTER"/>
            </Anchors>
          <FontString text="Message Frame"/>
        </MessageFrame>
      </Frames>
    </Frame>
  </Frames>
</Frame>
...snip...

Lua 代码

...snip...
function MyAddon_OnLoad(panel)
    MyAddon_CreateOptionsPanel(panel);
    MyAddon_ConsoleMessage("Loaded MyAddon: " .. tostring(panel));
end

function MyAddon_CreateOptionsPanel(panel)
    panel.name = "MyAddon " .. GetAddOnMetadata("MyAddon", "Version");  -- Set the name for the Category for the Panel
    panel.okay = function (self) MyAddonFrame_Close(); end;                 -- When the player clicks okay, run this function.
    panel.cancel = function (self)  MyAddonFrame_CancelOrLoad();  end;  -- When the player clicks cancel, run this function.
    InterfaceOptions_AddCategory(panel);                                    -- Add the panel to the Interface Options

    for name,text in pairs(ConfigData) do
        MyAddon_CreateMacroPanel(name, panel, panel.name);
    end
end

function MyAddon_CreateMacroPanel(macroName, parent, parentName)
    MyAddon_ConsoleMessage("Added macro option pane: " .. macroName);
    panel = CreateFrame( "Frame", "MyAddon_MacroPanel_" .. macroName, parent);
    panel.name = macroName;
    panel.parent = parentName;
    InterfaceOptions_AddCategory(panel);

    -- create a backdrop so we can see that the panel is created
    panel:SetFrameStrata("BACKGROUND");
    panel:SetWidth(128); -- Set these to whatever height/width is needed 
    panel:SetHeight(64); -- for your Texture

    local t = panel:CreateTexture(nil,"BACKGROUND");
    t:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Factions.blp");
    t:SetAllPoints(panel);
    panel.texture = t;

    panel:SetPoint("CENTER",0,0);
end



-- MyAddon_MacroSelectDropdown
function MyAddon_MacroSelectDropdown_OnLoad()
    info            = {};
    info.text       = "Auto";
    info.value      = "Auto";
    -- FunctionCalledWhenOptionIsClicked 
    info.func       = function (self) MyAddon_SetMacroAuto(); end;
    UIDropDownMenu_AddButton(info);
    for index,macro in pairs(ConfigData) do
        info.text       = name;
        info.value      = name;
        -- FunctionCalledWhenOptionIsClicked 
        info.func       = function (self) MyAddon_SetMacroByName(name); end;
        UIDropDownMenu_AddButton(info);
    end
    -- can also be done as function() FunctionCalledWhenOptionIsClicked() end;
end
...snip...
4

1 回答 1

1

是的,默认情况下,子框架绘制在其父框架之上。这是一个基本租户。

我认为这里的断开部分是因为您需要将所有元素添加为主框架的子元素。这不是这样的。

对于两个独立的“面板”,即框架,您可以拥有:

<frame>...</frame>
<frame>...</frame>

如果第一个是你的“主框架”,或者你打算接收你的插件主要事件的那个,比如 ADDON_LOADED,那么第二个可能是其他的,但它仍然是你的。好吧,实际上两者都不是“您的”,它们位于所有插件共享的全局共享范围内。

因此,如果您想要跟随特定框架的可见元素,无论是位置还是可见性,它们都应该是它的子元素。否则,您应该创建另一个框架。如果您将父级隐藏,则其子级将被隐藏。如果您移动父级,则其子级会移动,因为它们与父级具有相对位置。

这些是默认行为,但除非您真的需要做一些棘手的事情,例如真正变形的框架,否则遵循默认行为并创建单独的框架要容易得多。


<Frame name="MyAddonFrame" parent="UIParent" hidden="false">
  <Scripts>
    <OnLoad>
      self:RegisterEvent("UNIT_TARGET");
      self:RegisterEvent("PLAYER_ENTERING_WORLD");
      MyAddon_OnLoad(self);
    </OnLoad>
    <OnEvent function="MyAddon_OnEvent" />
    </Scripts>

    <Frames>
      <Frame parent="MyAddonFrame" inherits="UIDropDownMenuTemplate">

您不需要像上面那样设置父母,但如果您打算直接在该框架中的事件之外的 lua 代码中引用该框架,您应该给它一个名称:

    <Frames>
      <Frame name="$parentDropDownMenu" inherits="UIDropDownMenuTemplate">

如果这是在“embeds.xml”中,从技术上讲,该文件是用于一组嵌入在插件中的库的包含,而不是用于管理框架,但当然 WoW 不知道它会起作用。代码应该更像 MyAddon.xml、MyAddon.lua


大多数情况下,您需要制作尺寸合适的框架并将它们注册为选项面板的一部分,这是对它的简单解释。

让我知道剩下的没有意义或工作。

于 2011-08-31T23:27:03.193 回答