代码之家  ›  专栏  ›  技术社区  ›  RHSeeger

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

  •  2
  • RHSeeger  · 技术社区  · 14 年前

    我正在为预先存在的插件编写UI。或者,更具体地说,添加配置选项并尝试利用Interface options Addons(IOA)面板。我指的是沃维基,特别是 page that talks about using that panel ,但通常是一堆页。

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

    • 使用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...
    
    1 回复  |  直到 10 年前
        1
  •  1
  •   Beeeaaar    13 年前

    是的,默认情况下,子帧绘制在其父帧之上。这是一个基本房客。

    我认为这里的脱节部分是因为你认为你需要添加所有元素作为你的主框架的子元素。事实并非如此。

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

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

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

    因此,如果您希望特定框架后面的可见元素在位置和可见性上都是其子元素。否则你应该创建另一个框架。如果将父对象隐藏,则其子对象将被隐藏。如果移动父对象,其子对象将移动,因为它们与父对象具有相对位置。

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


    <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的一组include,而不是用于管理框架,但WoW当然不知道这样做是否可行。代码应该更像MyAddon.xml、MyAddon.lua


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

    让我知道还有什么是没有意义的或没有用的。

    推荐文章
    cFx  ·  WoW添加到REST API
    9 年前