使用魔兽世界中的界面选项插件代码问题

时间:2010-02-09 18:08:18

标签: xml lua add-on world-of-warcraft

我正在为预先存在的插件编写UI。或者,更具体地说,添加配置选项并尝试利用接口选项插件(IOA)面板。我一直在引用wowwiki,特别是page that talks about using that panel,但更常见的是一堆页面。

我遇到了一个问题,我确信这只是因为我没有经验写作插件(我写了一些,但每次都是学习经历)。基本概念是:

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

有效的方法是:

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

我遇到的问题是:

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

我到目前为止的代码(为简洁而剪裁)位于消息的底部。任何帮助/建议将不仅仅是值得赞赏。我知道代码部分有很多内容,但我想尽可能清楚地知道我在做什么。

请注意,我在官方的魔兽争霸UI论坛上发布过这个帖子,但无法在那里得到任何帮助。

embeds.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 Code

...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...

1 个答案:

答案 0 :(得分: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”中,那么该文件适用于嵌入在插件中的libs的一组包含,而不是用于管理帧,但是当然WoW不知道它会起作用。代码应该更像MyAddon.xml,MyAddon.lua


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

让我知道什么是没有意义或工作的。