레퍼런스 › 함수 레퍼런스 › Conditions

Conditions.talent.traitsWidget

의존성

호출 방법

Conditions.talent.traitsWidget(parent, spec, value, update)

의존성 Conditions.talent.traitsWidget을(를) 기록한 뒤 그 이름으로 호출하세요. 네임스페이스 호출은 self를 넘기지 않으므로 콜론 호출을 쓰거나 객체를 직접 넘기세요.

하는 일

Builds the TALENT editor controls for trait talents: a talent tree dropdown when there are several, a talent dropdown, Talent Node ID and Choice Entry ID edit boxes, and a Rank comparison. Picking a talent or entering a node switches value to the traits layout (defaulting to a rank of at least 1) and calls update; notes appear when talents cannot be listed or the saved reference belongs to another layout.

인수

이름유형하는 일
parenttableCondition widget group the control is added to.
specnumber | nilSpecialization the editor is for; on progression clients a value from 1 to 4 also selects the talent group to read.
valuetableSaved TALENT condition settings; the control reads and rewrites its layout, tree, talent, node, entry, operator and value fields.
updatefunctionCalled with no arguments after every change so the editor can refresh.

반환값

없음.

버전

기본 제공 도우미는 모든 버전에 등록됩니다. 다른 점은 읽는 게임 API이며, API가 없으면 도우미는 대체 동작을 하거나 이유와 함께 nil을 반환합니다.

게임 API를 직접 읽지 않습니다.

애드온에서 호출하는 방식

  • 특성 (widget)
    elseif current=="traits" then traitsWidget(parent,spec,value,update)

의존성

소스

Conditions/talent.lua, 312번째 줄. 게임에서는 읽기 전용이며, 복제하면 편집 가능한 사본이 생깁니다.

Conditions.talent.traitsWidget(parent, spec, value, update)
    -- Retail: the talents of the rotation's specialization, which need not be
    -- the one being played (shown can be switched). Forever: the loadout.
    local specs=classSpecs()
    local shown
    if specs then
        for _,choice in ipairs(specs) do if choice.id==spec then shown=spec end end
        if not shown and platform.GetPlayerSpecializationID then shown=platform:GetPlayerSpecializationID() end
    end
    if not traitShape(value) and (value.tree~=nil or value.value~=nil) then
        text(parent,L["This reference belongs to another talent layout. Selecting a talent explicitly replaces it; viewing does not convert it."])
    end
    local box=block(parent)
    local note=addon:CreateConditionLabel();note:SetFullWidth(true);parent:AddChild(note)
    local groups,selectedGroup,selectedTalent={},nil,nil
    local groupNames,groupOrder={},{}
    -- The talent list contains only the selected class, specialization or hero tree.
    local list,order,positions={},{},{}
    local talentIcon,talentPicker,groupPicker,nodeBox,entryBox,operators,specPicker,treeButton
    local treeOwner={}
    local function rebuild()
        list,order,positions={},{},{}
        for groupIndex,candidate in ipairs(groups) do
            if groupIndex==selectedGroup then
                for talentIndex,talent in ipairs(candidate.talents) do
                    list[#list+1]={text=talent.entry and string.format(L["%s (choice)"],talent.name) or talent.name,icon=talent.icon}
                    order[#order+1]=#list;positions[#list]={group=groupIndex,talent=talentIndex}
                end
            end
        end
    end
    local function flatIndex(groupIndex,talentIndex)
        for index,position in pairs(positions) do
            if position.group==groupIndex and position.talent==talentIndex then return index end
        end
    end
    local function reload()
        -- The game names the talents of the class being played: another class's
        -- rotation (a Built In, a shared one) gets no list.
        local own=ownTrees()
        local listed,reason
        if own then listed,reason=platform:GetTraitTalents(shown) end
        groups=listed or {}
        if not own then note:SetText(L["Talents can be listed only for your own class. A node ID entered below is kept and evaluated."])
        elseif listed then note:SetText("")
        elseif reason=="in-combat" then note:SetText(L["Talents of another specialization cannot be loaded during combat. A node ID entered below is kept and evaluated."])
        else note:SetText(string.format(L["Your talents cannot be listed right now (%s). A node ID entered below is kept and evaluated."],tostring(reason))) end
        selectedGroup,selectedTalent=nil,nil
        local matchedGroup,matchedTalent
        if traitShape(value) then
            for groupIndex,candidate in ipairs(groups) do
                for talentIndex,talent in ipairs(candidate.talents) do
                    if talent.node==value.node and talent.entry==value.entry then matchedGroup,matchedTalent=groupIndex,talentIndex end
                end
            end
        end
        selectedGroup=matchedGroup or (#groups>0 and 1 or nil)
        groupNames,groupOrder={},{}
        for index,candidate in ipairs(groups) do groupNames[index]=groupLabel(candidate);groupOrder[#groupOrder+1]=index end
        rebuild()
        if matchedGroup then selectedTalent=flatIndex(matchedGroup,matchedTalent) end
    end
    local function show()
        if groupPicker then groupPicker:SetList(groupNames,groupOrder);groupPicker:SetValue(selectedGroup);groupPicker:SetDisabled(#groupOrder<2) end
        talentPicker:SetList(list,order);talentPicker:SetValue(selectedTalent);talentPicker:SetDisabled(#order==0)
        if treeButton then treeButton:SetDisabled(value.disabled==true or #groups==0) end
    end
    local function adopt()
        if not traitShape(value) then value.operator,value.value="GREATERTHANOREQUALS",1 end
        value.layout,value.tree,value.talent="traits",nil,nil
        if operators and operators.Refresh then operators.Refresh() end
    end
    talentIcon=icon(box,value,spec)
    if specs then
        local specNames,specOrder={},{}
        for index,choice in ipairs(specs) do
            specNames[choice.id]={text=choice.name,icon=choice.icon};specOrder[index]=choice.id
        end
        specPicker=dropdown(box,L["Specialization"],function(selected)
            if selected==shown then return end
            shown=selected;reload();show()
        end)
        specPicker.configure=function() specPicker:SetList(specNames,specOrder);specPicker:SetValue(shown) end
    end
    reload()
    groupPicker=dropdown(box,L["Talent Tree"],function(selected)
        if selected==selectedGroup then return end
        selectedGroup,selectedTalent=selected,nil;rebuild()
        talentPicker:SetList(list,order);talentPicker:SetValue(nil);talentPicker:SetDisabled(#order==0)
    end)
    groupPicker.configure=show
    local function currentSelection()
        if traitShape(value) and value.node then return {node=value.node,entry=value.entry,spell=value.spell} end
    end
    -- Keeps the open talent tree (if it is this editor's) on the condition's talent.
    local function refreshTree()
        if not addon.RefreshTalentTree then return end
        local current=info(value,spec)
        addon:RefreshTalentTree(treeOwner,currentSelection(),current and current.name)
    end
    local function apply(talent)
        adopt()
        value.node,value.entry,value.spell=talent.node,talent.entry,talent.spellID
        nodeBox:SetText(tostring(talent.node));entryBox:SetText(talent.entry and tostring(talent.entry) or "")
        talentIcon:SetImage(talent.icon or PLACEHOLDER);update()
    end
    talentPicker=dropdown(box,L["Talent"],function(selected)
        local position=positions[selected]
        local talent=position and groups[position.group] and groups[position.group].talents[position.talent]
        if not talent then return end
        selectedTalent=selected;apply(talent);refreshTree()
    end)
    talentPicker.configure=show
    -- A button for the drawn tree sits beside the talent list when the client
    -- can show one. It reads the same tree the lists do, so it is off while the
    -- lists could not be filled.
    if platform.HasTalentTreeProvider and addon.OpenTalentTree and platform:HasTalentTreeProvider() then
        treeButton=addon:CreateConditionButton();treeButton:SetText(L["Show talent tree"]);treeButton:SetAutoWidth(true)
        treeButton:SetUserData("side",true)
        treeButton.frame.tooltip=L["Opens the talent tree of the rotation's specialization. Click a talent to choose it for this condition."]
        treeButton:SetDisabled(value.disabled==true or #groups==0)
        treeButton:SetCallback("OnClick",function()
            local current=info(value,spec)
            addon:OpenTalentTree({owner=treeOwner,spec=shown,selection=currentSelection(),selectionName=current and current.name,
                specs=specs,
                onSelect=function(selection)
                    -- Clicking the chosen talent again clears the choice.
                    if not selection then
                        value.node,value.entry,value.spell=nil,nil,nil
                        selectedTalent=nil
                        nodeBox:SetText("");entryBox:SetText("")
                        talentIcon:SetImage(PLACEHOLDER);update();show()
                        return
                    end
                    local found,foundGroup,foundTalent
                    for groupIndex,candidate in ipairs(groups) do
                        for talentIndex,talent in ipairs(candidate.talents) do
                            if talent.node==selection.node and talent.entry==selection.entry then foundGroup,foundTalent,found=groupIndex,talentIndex,talent end
                        end
                    end
                    if found then selectedGroup=foundGroup end
                    rebuild()
                    selectedTalent=found and flatIndex(foundGroup,foundTalent) or nil
                    apply({node=selection.node,entry=selection.entry,spellID=selection.spell,icon=found and found.icon or selection.icon})
                    show()
                end,
                -- The tree and the lists show the same specialization.
                onSpec=function(chosen)
                    if chosen==shown then return end
                    shown=chosen;reload();show()
                    if specPicker then specPicker:SetValue(shown) end
                end})
        end)
        treeButton:SetCallback("OnRelease",function() addon:CloseTalentTree(treeOwner) end)
        box:AddChild(treeButton)
    end
    local function identifier(entered)
        local number=tonumber(entered)
        if number and number>0 and number<2147483648 and number%1==0 then return number end
    end
    nodeBox=addon:CreateConditionEditBox();nodeBox:SetLabel(L["Talent Node ID"])
    if traitShape(value) and value.node~=nil then nodeBox:SetText(tostring(value.node)) end
    nodeBox:SetCallback("OnEnterPressed",function(_,_,entered)
        local number=identifier(entered)
        if not number then nodeBox:SetText(traitShape(value) and value.node and tostring(value.node) or "");return end
        -- A node typed by hand no longer goes with the spell of the talent picked before.
        adopt();value.node,value.spell=number,nil;selectedTalent=nil;talentPicker:SetValue(nil)
        local current=info(value,spec);talentIcon:SetImage(current and current.icon or PLACEHOLDER);update();refreshTree()
    end)
    parent:AddChild(nodeBox)
    entryBox=addon:CreateConditionEditBox();entryBox:SetLabel(L["Choice Entry ID"])
    if traitShape(value) and value.entry~=nil then entryBox:SetText(tostring(value.entry)) end
    entryBox:SetCallback("OnEnterPressed",function(_,_,entered)
        local number=identifier(entered)
        if entered~="" and entered~=nil and not number then entryBox:SetText(value.entry and tostring(value.entry) or "");return end
        if not traitShape(value) then return end
        value.entry,value.spell=number,nil;selectedTalent=nil;talentPicker:SetValue(nil)
        local current=info(value,spec);talentIcon:SetImage(current and current.icon or PLACEHOLDER);update();refreshTree()
    end)
    parent:AddChild(entryBox)
    operators=addon:Widget_OperatorWidget(value,L["Rank"],update);parent:AddChild(operators)
    show()

함수 레퍼런스(으)로 돌아가기