호출 방법
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.
인수
| 이름 | 유형 | 하는 일 |
|---|---|---|
parent | table | Condition widget group the control is added to. |
spec | number | nil | Specialization the editor is for; on progression clients a value from 1 to 4 also selects the talent group to read. |
value | table | Saved TALENT condition settings; the control reads and rewrites its layout, tree, talent, node, entry, operator and value fields. |
update | function | Called 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)
의존성
PLACEHOLDER(builtin:Conditions/talent.lua:PLACEHOLDER)block→Conditions.talent.blockclassSpecs→Conditions.talent.classSpecsdropdown→Conditions.talent.dropdowngroupLabel→Conditions.talent.groupLabelicon→Conditions.talent.iconinfo→Conditions.talent.infoownTrees→Conditions.talent.ownTreesplatform(builtin:Conditions/talent.lua:platform)text→Conditions.talent.texttraitShape→Conditions.talent.traitShape
소스
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()