You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
388 lines
14 KiB
388 lines
14 KiB
|
2 years ago
|
local COMPAT, _, T = select(4, GetBuildInfo()), ...
|
||
|
|
local XU, MODERN, type = T.exUI, COMPAT > 10e4, type
|
||
|
|
local assert, getWidgetData, newWidgetData, setWidgetData, AddObjectMethods, CallObjectScript = XU:GetImpl()
|
||
|
|
|
||
|
|
local HOLD_HOVER_HINT_DURATION, ICON_FILE_NAMES, LookupIconName = 0.2, nil
|
||
|
|
local IconSelector, IconSelectorData, internal = {}, {}, {}
|
||
|
|
local IconSelectorProps = {
|
||
|
|
api=IconSelector,
|
||
|
|
scripts={"OnIconSelect", "OnEditFocusGained", "OnEditFocusLost"},
|
||
|
|
lastVisibleIcon=-1,
|
||
|
|
selectedAsset=nil,
|
||
|
|
viewIndexOffset=0,
|
||
|
|
firstAsset=nil,
|
||
|
|
firstAssetValue=nil,
|
||
|
|
firstAssetIsAtlas=false,
|
||
|
|
columns=14,
|
||
|
|
rows=7,
|
||
|
|
cellWidth=36,
|
||
|
|
cellHeight=36,
|
||
|
|
pendingGridSync=true,
|
||
|
|
manualInputHintText="",
|
||
|
|
}
|
||
|
|
AddObjectMethods({"IconSelector"}, IconSelectorProps)
|
||
|
|
|
||
|
|
function IconSelector:SetSelectedAsset()
|
||
|
|
local d = assert(getWidgetData(self, IconSelectorData), "Invalid object type")
|
||
|
|
return d.selectedAsset
|
||
|
|
end
|
||
|
|
function IconSelector:SetSelectedAsset(asset)
|
||
|
|
local d = assert(getWidgetData(self, IconSelectorData), "Invalid object type")
|
||
|
|
assert(asset == nil or type(asset) == "string" or type(asset) == "number", 'Syntax: IconSelector:SetSelectedAsset(asset)')
|
||
|
|
d.selectedAsset = asset
|
||
|
|
internal.RenderView(d, d.viewIndexOffset)
|
||
|
|
internal.SyncHintText(d)
|
||
|
|
end
|
||
|
|
function IconSelector:SetFirstAsset(value, overrideAsset)
|
||
|
|
local d = assert(getWidgetData(self, IconSelectorData), "Invalid object type")
|
||
|
|
local asset = overrideAsset or value
|
||
|
|
assert(asset == nil or type(asset) == "number" or type(asset) == "string", 'Syntax: IconSelector:SetFirstAsset(value[, overrideAsset])')
|
||
|
|
d.firstAssetIsAtlas = type(asset) == "string" and not GetFileIDFromPath(asset) and C_Texture.GetAtlasInfo(asset) and true
|
||
|
|
d.firstAssetValue, d.firstAsset = value, asset
|
||
|
|
internal.RenderView(d, d.viewIndexOffset)
|
||
|
|
end
|
||
|
|
function IconSelector:SetManualInputHintText(text)
|
||
|
|
local d = assert(getWidgetData(self, IconSelectorData), "Invalid object type")
|
||
|
|
assert(type(text) == "string", 'Syntax: IconSelector:SetManualInputHintText("text")')
|
||
|
|
d.manualInputHintText = text
|
||
|
|
internal.SyncHintText(d)
|
||
|
|
end
|
||
|
|
function IconSelector:SetGridSize(rows, cols)
|
||
|
|
local d = assert(getWidgetData(self, IconSelectorData), "Invalid object type")
|
||
|
|
assert(type(rows) == "number" and rows > 0 and rows % 1 == 0
|
||
|
|
and type(cols) == "number" and cols > 0 and cols % 1 == 0
|
||
|
|
, 'Syntax: IconSelector:SetGridSize(rows, cols)')
|
||
|
|
d.pendingGridSync, d.rows, d.columns = true, rows, cols
|
||
|
|
if d.proto.super.IsShown(d.self) then
|
||
|
|
internal.ConfigureIconGrid(d)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function IconSelector:FocusManualInput()
|
||
|
|
local d = assert(getWidgetData(self, IconSelectorData), "Invalid object type")
|
||
|
|
d.manualInput:SetFocus()
|
||
|
|
end
|
||
|
|
function IconSelector:IsSearchPossible()
|
||
|
|
return not not (ICON_FILE_NAMES or LookupIconName and LookupIconName(0) or ICON_FILE_NAMES)
|
||
|
|
end
|
||
|
|
|
||
|
|
local GetAllIcons do
|
||
|
|
local function GetAbilityIcons(into)
|
||
|
|
local AB = T.ActionBook and T.ActionBook:compatible(2,40)
|
||
|
|
local cc, ni, _, ic = AB and AB:GetNumCategories() >= 1 and AB:GetCategoryContents(1), #into+1
|
||
|
|
for i=1, cc and #cc or 0 do
|
||
|
|
_, _, ic = AB:GetActionDescription(cc(i))
|
||
|
|
if ic then
|
||
|
|
into[ni], ni = ic, ni + 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function GetAllIcons()
|
||
|
|
local a, m, ni = {}, {}, 1
|
||
|
|
for i=1,5 do
|
||
|
|
local fixLoose = i == 3 or i == 5
|
||
|
|
select(i, GetAbilityIcons, GetMacroIcons, GetLooseMacroIcons, GetMacroItemIcons, GetLooseMacroItemIcons)(a)
|
||
|
|
for i=ni, #a do
|
||
|
|
local ai = a[i]
|
||
|
|
local fid = type(ai) == "string" and GetFileIDFromPath(ai) or ai
|
||
|
|
if fixLoose and not fid then
|
||
|
|
local c1 = ai:gsub("%.$", "")
|
||
|
|
local c2, c3 = "Interface/Icons/" .. c1, "Interface/Icons/" .. ai
|
||
|
|
ai = GetFileIDFromPath(c1) and c1 or GetFileIDFromPath(c2) and c2 or GetFileIDFromPath(c3) and c3
|
||
|
|
fid = ai and GetFileIDFromPath(ai)
|
||
|
|
end
|
||
|
|
if fid and m[fid] == nil then
|
||
|
|
a[ni], m[fid], m[ai], ni = ai, ni, ni, ni + 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
for i=#a, ni, -1 do
|
||
|
|
a[i] = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
GetAllIcons = function() return a end
|
||
|
|
return a
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function LookupIconName(fid)
|
||
|
|
LookupIconName = nil
|
||
|
|
if select(5, (C_AddOns.GetAddOnInfo or GetAddOnInfo)("IconFileNames")) == "DEMAND_LOADED"
|
||
|
|
and not (C_AddOns.IsAddOnLoaded or IsAddOnLoaded)("IconFileNames") then
|
||
|
|
(C_AddOns.LoadAddOn or LoadAddOn)("IconFileNames")
|
||
|
|
end
|
||
|
|
ICON_FILE_NAMES = _G.ICON_FILE_NAMES
|
||
|
|
ICON_FILE_NAMES = type(ICON_FILE_NAMES) == "table" and ICON_FILE_NAMES or nil
|
||
|
|
return ICON_FILE_NAMES and ICON_FILE_NAMES[fid]
|
||
|
|
end
|
||
|
|
|
||
|
|
function internal:OnHide()
|
||
|
|
local d = getWidgetData(self, IconSelectorData)
|
||
|
|
d.hoverIcon, d.hoverIconLT = nil
|
||
|
|
self:GetParent():Hide()
|
||
|
|
end
|
||
|
|
function internal:OnIconClick(_button, _down)
|
||
|
|
local d, checked = getWidgetData(self:GetParent(), IconSelectorData), self:GetChecked()
|
||
|
|
local idx = checked and self:GetID()+d.viewIndexOffset or nil
|
||
|
|
local tex = idx and (idx == 0 and d.firstAssetValue or idx > 0 and d.iconList[idx] or nil)
|
||
|
|
if d.selectedButton then
|
||
|
|
d.selectedButton:SetChecked(nil)
|
||
|
|
end
|
||
|
|
d.selectedAsset, d.selectedButton = tex, checked and self or nil
|
||
|
|
PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON)
|
||
|
|
CallObjectScript(d.self, "OnIconSelect", tex)
|
||
|
|
end
|
||
|
|
function internal:OnIconEnter()
|
||
|
|
local d = getWidgetData(self:GetParent(), IconSelectorData)
|
||
|
|
d.hoverIcon, d.hoverIconLT = self, nil
|
||
|
|
internal.SyncHintText(d)
|
||
|
|
end
|
||
|
|
function internal:OnUpdateTick()
|
||
|
|
local d = getWidgetData(self, IconSelectorData)
|
||
|
|
if d.hoverIconLT and d.hoverIconLT + HOLD_HOVER_HINT_DURATION > GetTime() then
|
||
|
|
return
|
||
|
|
elseif d.hoverIconLT then
|
||
|
|
d.hoverIcon = nil
|
||
|
|
end
|
||
|
|
self:SetScript("OnUpdate", nil)
|
||
|
|
internal.SyncHintText(d)
|
||
|
|
end
|
||
|
|
function internal:OnIconLeave()
|
||
|
|
local d = getWidgetData(self:GetParent(), IconSelectorData)
|
||
|
|
if d.hoverIcon == self then
|
||
|
|
d.hoverIconLT = GetTime()
|
||
|
|
d.clipRoot:SetScript("OnUpdate", internal.OnUpdateTick)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function internal.CreateIconButton(parent, pool, id)
|
||
|
|
local f, sz = CreateFrame("CheckButton", nil, parent, nil, id), 32
|
||
|
|
f:SetSize(sz, sz)
|
||
|
|
f:SetNormalTexture("")
|
||
|
|
f:SetHighlightTexture("Interface/Buttons/ButtonHilight-Square")
|
||
|
|
f:GetHighlightTexture():SetBlendMode("ADD")
|
||
|
|
f:SetCheckedTexture("Interface/Buttons/CheckButtonHilight")
|
||
|
|
f:GetCheckedTexture():SetBlendMode("ADD")
|
||
|
|
f:SetPushedTexture("Interface/Buttons/UI-Quickslot-Depress")
|
||
|
|
f:SetScript("OnClick", internal.OnIconClick)
|
||
|
|
f:SetScript("OnEnter", internal.OnIconEnter)
|
||
|
|
f:SetScript("OnLeave", internal.OnIconLeave)
|
||
|
|
local tex = f:CreateTexture(nil, "ARTWORK")
|
||
|
|
tex:SetAllPoints()
|
||
|
|
local bg = f:CreateTexture(nil, "BACKGROUND", nil, -1)
|
||
|
|
bg:SetTexture("Interface/Buttons/UI-EmptySlot-Disabled")
|
||
|
|
bg:SetPoint("CENTER", tex, "CENTER")
|
||
|
|
bg:SetSize(1.5*sz, 1.5*sz)
|
||
|
|
local edge = f:CreateTexture(nil, "OVERLAY", nil, -1)
|
||
|
|
edge:SetTexture("Interface/Buttons/UI-Quickslot2")
|
||
|
|
edge:SetSize(1.625*sz, 1.625*sz)
|
||
|
|
edge:SetPoint("CENTER", tex, "CENTER", 0.25, -0.25)
|
||
|
|
if MODERN then
|
||
|
|
local m = f:CreateMaskTexture()
|
||
|
|
m:SetTexture("Interface/FrameGeneral/UIFrameIconMask")
|
||
|
|
m:SetAllPoints(tex)
|
||
|
|
tex:AddMaskTexture(m)
|
||
|
|
end
|
||
|
|
f.tex, f.background, f.edge = tex, bg, edge
|
||
|
|
pool[id] = f
|
||
|
|
return f
|
||
|
|
end
|
||
|
|
function internal:OnScroll(value, interaction)
|
||
|
|
local d, co = getWidgetData(self, IconSelectorData), value % 1
|
||
|
|
d.origin:SetPoint("TOPLEFT", 0, co*d.cellHeight)
|
||
|
|
internal.RenderView(d, (value - co) * d.columns, true)
|
||
|
|
if interaction and d.hoverIconLT then
|
||
|
|
internal.SyncHintText(d)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function internal.RenderView(d, value, allowSkip)
|
||
|
|
if allowSkip and d.viewIndexOffset == value then return end
|
||
|
|
local icons, icontex, sel, selectedButton = d.pool, d.iconList, d.selectedAsset
|
||
|
|
for i=0, d.lastVisibleIcon do
|
||
|
|
local ico, tex = icons[i].tex, i == 0 and value == 0 and (d.firstAsset or "Interface/Icons/INV_Misc_QuestionMark") or icontex[i+value]
|
||
|
|
icons[i]:SetShown(not not tex)
|
||
|
|
if tex then
|
||
|
|
if i == 0 and value == 0 and d.firstAssetIsAtlas then
|
||
|
|
ico:SetAtlas(tex)
|
||
|
|
else
|
||
|
|
ico:SetTexture(tex)
|
||
|
|
end
|
||
|
|
local check = sel and (tex == sel or ico:GetTexture() == sel)
|
||
|
|
icons[i]:SetChecked(check)
|
||
|
|
selectedButton = check and icons[i] or selectedButton
|
||
|
|
end
|
||
|
|
end
|
||
|
|
d.viewIndexOffset, d.selectedButton = value, selectedButton
|
||
|
|
end
|
||
|
|
function internal.ConfigureIconGrid(d)
|
||
|
|
local sb, pool, icontex, origin = d.scrollBar, d.pool, d.iconList, d.origin
|
||
|
|
local rows, cols, cw, ch = d.rows, d.columns, d.cellWidth, d.cellHeight
|
||
|
|
sb:SetStepsPerPage(rows, math.min(math.max(1, rows-2), 5))
|
||
|
|
sb:SetWindowRange(rows)
|
||
|
|
sb:SetMinMaxValues(0, math.ceil((#icontex-cols*rows)/cols))
|
||
|
|
d.self:SetSize(42+cols*cw, 40+ch*rows)
|
||
|
|
local usedIcons = (cols*(rows+1))-1
|
||
|
|
for i=0, usedIcons do
|
||
|
|
local w = pool[i] or internal.CreateIconButton(d.clipRoot, d.pool, i)
|
||
|
|
w:SetPoint("TOPLEFT", origin, (i % cols)*cw, - ch*math.floor(i / cols))
|
||
|
|
end
|
||
|
|
for i=usedIcons+1, d.lastVisibleIcon do
|
||
|
|
pool[i]:Hide()
|
||
|
|
end
|
||
|
|
d.lastVisibleIcon, d.pendingGridSync = usedIcons, nil
|
||
|
|
end
|
||
|
|
function internal:OnShow()
|
||
|
|
local d = getWidgetData(self, IconSelectorData)
|
||
|
|
internal.SetIconList(d, GetAllIcons(), nil, -1)
|
||
|
|
if d.pendingGridSync then
|
||
|
|
internal.ConfigureIconGrid(d)
|
||
|
|
end
|
||
|
|
d.scrollBar:SetValue(0, true)
|
||
|
|
local p, kbf = d.self:GetParent(), GetCurrentKeyBoardFocus()
|
||
|
|
d.self:SetFrameLevel(math.max(d.self:GetFrameLevel(), p and p:GetFrameLevel()+200))
|
||
|
|
if kbf then
|
||
|
|
kbf:ClearFocus()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function internal.SyncHintText(d)
|
||
|
|
if d.manualInput:HasFocus() then
|
||
|
|
d.manualInputHint:Hide()
|
||
|
|
d.manualInputFS:Show()
|
||
|
|
elseif d.hoverIcon and d.hoverIcon == GetMouseFocus() then
|
||
|
|
d.manualInputHint:Show()
|
||
|
|
local idx = d.hoverIcon:GetID() + d.viewIndexOffset
|
||
|
|
local asset = idx == 0 and d.firstAsset or d.iconList[idx]
|
||
|
|
local fn = ICON_FILE_NAMES and ICON_FILE_NAMES[asset] or LookupIconName and securecall(LookupIconName, asset)
|
||
|
|
d.manualInputHint:SetText(fn and asset .. " |cff606060[|r" .. fn .. "|cff606060]|r" or asset or "")
|
||
|
|
d.manualInputFS:Hide()
|
||
|
|
elseif d.selectedAsset then
|
||
|
|
d.manualInput:SetText(d.selectedAsset)
|
||
|
|
d.manualInputFS:Show()
|
||
|
|
d.manualInputHint:Hide()
|
||
|
|
else
|
||
|
|
d.manualInputHint:SetText(d.manualInputHintText)
|
||
|
|
d.manualInputHint:Show()
|
||
|
|
d.manualInput:SetText("")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function internal:OnEditFocusChange()
|
||
|
|
local d = getWidgetData(self, IconSelectorData)
|
||
|
|
internal.SyncHintText(d)
|
||
|
|
CallObjectScript(d.self, self:HasFocus() and "OnEditFocusGained" or "OnEditFocusLost", self)
|
||
|
|
end
|
||
|
|
function internal:OnEnterPressed()
|
||
|
|
local d, text = getWidgetData(self, IconSelectorData), self:GetText()
|
||
|
|
if IsAltKeyDown() and (ICON_FILE_NAMES or LookupIconName and securecall(LookupIconName, 0) or ICON_FILE_NAMES) then
|
||
|
|
return internal.FilterIcons(d, text, self)
|
||
|
|
end
|
||
|
|
if text:match("%S") then
|
||
|
|
local fid0, nt = GetFileIDFromPath(text), tonumber(text) or 0
|
||
|
|
local fid1 = not fid0 and GetFileIDFromPath("Interface/Icons/" .. text)
|
||
|
|
local path = fid0 and (fid0 < 0 and text or fid0) or
|
||
|
|
fid1 and (fid1 < 0 and "Interface/Icons/" .. text or fid1) or
|
||
|
|
C_Texture.GetAtlasInfo(text) and text or
|
||
|
|
nt > 0 and nt or
|
||
|
|
GetSpellTexture(text)
|
||
|
|
if not path then
|
||
|
|
return self:HighlightText()
|
||
|
|
end
|
||
|
|
d.selectedAsset = path
|
||
|
|
CallObjectScript(d.self, "OnIconSelect", path)
|
||
|
|
end
|
||
|
|
self:ClearFocus()
|
||
|
|
end
|
||
|
|
function internal:OnEscapePressed()
|
||
|
|
self:ClearFocus()
|
||
|
|
end
|
||
|
|
function internal.FilterIcons(d, query, _editbox)
|
||
|
|
local of, nf = d.filter, query:lower():gsub("[.%%%[%]%-+*?()]", ""):match(".+")
|
||
|
|
if of == nf then
|
||
|
|
return
|
||
|
|
elseif not nf then
|
||
|
|
internal.SetIconList(d, GetAllIcons(), nil)
|
||
|
|
else
|
||
|
|
local t, ni, p, smatch = {}, 1, nf:gsub(" +", ".*"), nf.match
|
||
|
|
local ot = nf:match(of or "") and d.iconList or GetAllIcons()
|
||
|
|
for i=1, #ot do
|
||
|
|
local fn = ICON_FILE_NAMES[ot[i]]
|
||
|
|
if fn and smatch(fn, p) then
|
||
|
|
t[ni], ni = ot[i], ni + 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
internal.SetIconList(d, t, nf)
|
||
|
|
end
|
||
|
|
internal.RenderView(d, d.viewIndexOffset)
|
||
|
|
end
|
||
|
|
function internal.SetIconList(d, iconList, filter, viewIndexOffset)
|
||
|
|
d.iconList, d.filter, d.viewIndexOffset = iconList, filter, viewIndexOffset or d.viewIndexOffset
|
||
|
|
d.scrollBar:SetMinMaxValues(0, math.ceil((#d.iconList-d.columns*d.rows)/d.columns))
|
||
|
|
end
|
||
|
|
|
||
|
|
local function CreateIconSelector(name, parent, outerTemplate, id)
|
||
|
|
local f, d, t, a = CreateFrame("Frame", name, parent, outerTemplate, id)
|
||
|
|
d = newWidgetData(f, IconSelectorData, IconSelectorProps)
|
||
|
|
d.pool, d.backdrop = {}, XU:Create("Backdrop", f, {bgFile = "Interface/ChatFrame/ChatFrameBackground", edgeFile = "Interface/DialogFrame/UI-DialogBox-Border", tile = true, tileSize = 32, edgeSize = 32, insets = { left = 11, right = 11, top = 11, bottom = 10 }, bgColor=0xd8000000})
|
||
|
|
f:EnableMouse(1)
|
||
|
|
f:SetToplevel(1)
|
||
|
|
f:Hide()
|
||
|
|
t = CreateFrame("Frame", nil, f)
|
||
|
|
t:SetPoint("TOPLEFT", 12, -32)
|
||
|
|
t:SetPoint("BOTTOMRIGHT", -31, 12)
|
||
|
|
t:SetClipsChildren(true)
|
||
|
|
t:SetScript("OnHide", internal.OnHide)
|
||
|
|
t:SetScript("OnShow", internal.OnShow)
|
||
|
|
setWidgetData(t, IconSelectorData, d)
|
||
|
|
t, d.clipRoot = CreateFrame("Frame", nil, t), t
|
||
|
|
t:SetSize(1,1)
|
||
|
|
t:SetPoint("TOPLEFT")
|
||
|
|
t:Hide()
|
||
|
|
t, d.origin = XU:Create("ScrollBar", nil, f), t
|
||
|
|
t:SetStyle("common")
|
||
|
|
t:SetPoint("TOPRIGHT", -9, -28)
|
||
|
|
t:SetPoint("BOTTOMRIGHT", -9, 9)
|
||
|
|
t:SetWheelScrollTarget(d.clipRoot, -2, -5, -2, -1)
|
||
|
|
t:SetCoverTarget(d.clipRoot)
|
||
|
|
t:SetScript("OnValueChanged", internal.OnScroll)
|
||
|
|
setWidgetData(t, IconSelectorData, d)
|
||
|
|
t, d.scrollBar = XU:Create("LineInput", nil, f), t
|
||
|
|
t:SetStyle("chat")
|
||
|
|
t:SetPoint("TOPLEFT", 11, -7)
|
||
|
|
t:SetPoint("TOPRIGHT", -34, -7)
|
||
|
|
setWidgetData(t, IconSelectorData, d)
|
||
|
|
t:SetScript("OnEditFocusGained", internal.OnEditFocusChange)
|
||
|
|
t:SetScript("OnEditFocusLost", internal.OnEditFocusChange)
|
||
|
|
t:SetScript("OnEnterPressed", internal.OnEnterPressed)
|
||
|
|
t:SetScript("OnEscapePressed", internal.OnEscapePressed)
|
||
|
|
d.manualInputFS = t:GetRegions()
|
||
|
|
a, d.manualInput = t:CreateFontString(nil, "OVERLAY", "GameFontHighlight"), t
|
||
|
|
a:SetPoint("CENTER")
|
||
|
|
a:SetTextColor(0.85, 0.85, 0.85)
|
||
|
|
d.manualInputHint = a
|
||
|
|
t = CreateFrame("Button", nil, f, "UIPanelCloseButton")
|
||
|
|
if MODERN then
|
||
|
|
t:SetPoint("TOPRIGHT", -6.5, -5.5)
|
||
|
|
t:SetSize(24,24)
|
||
|
|
t:SetHitRectInsets(2, 2, 2, 3)
|
||
|
|
a = t:CreateMaskTexture()
|
||
|
|
a:SetTexture("Interface/common/common-iconmask")
|
||
|
|
a:SetPoint("TOPLEFT", 2.4, -2.4)
|
||
|
|
a:SetPoint("BOTTOMRIGHT", -2.8, 4)
|
||
|
|
t:GetNormalTexture():AddMaskTexture(a)
|
||
|
|
t:GetPushedTexture():AddMaskTexture(a)
|
||
|
|
t:GetHighlightTexture():AddMaskTexture(a)
|
||
|
|
a = t:CreateMaskTexture()
|
||
|
|
a:SetTexture("Interface/common/common-mask-diamond")
|
||
|
|
a:SetSize(30,30)
|
||
|
|
a:SetPoint("RIGHT", 3, 0.5)
|
||
|
|
t:GetNormalTexture():AddMaskTexture(a)
|
||
|
|
t:GetPushedTexture():AddMaskTexture(a)
|
||
|
|
t:GetHighlightTexture():AddMaskTexture(a)
|
||
|
|
else
|
||
|
|
t:SetPoint("TOPRIGHT", -2, -1)
|
||
|
|
t:SetHitRectInsets(4, 4, 4, 6)
|
||
|
|
end
|
||
|
|
t, d.closeButton = t:CreateTexture(nil, "BACKGROUND", nil, -5), t
|
||
|
|
t:SetTexture("Interface/ChatFrame/UI-ChatInputBorder-Mid2")
|
||
|
|
t:SetPoint("BOTTOMLEFT", d.manualInput, "BOTTOMRIGHT", 7, -6.25)
|
||
|
|
t:SetSize(18.75, 8)
|
||
|
|
t:SetTexCoord(0,1, 0.75,1)
|
||
|
|
return f
|
||
|
|
end
|
||
|
|
|
||
|
|
XU:RegisterFactory("IconSelector", CreateIconSelector)
|