local addonName, addon = ...
local ui = addon:NewModule("Options.UI")
local L = LibStub("AceLocale-3.0"):GetLocale(addonName)
LibStub("Libra"):EmbedWidgets(ui)
local function compByName(a, b)
return a:GetText():lower() < b:GetText():lower()
end
local function createSeparator(parent, from, to)
local line = parent:CreateTexture()
line:SetPoint(unpack(from))
line:SetPoint(unpack(to))
line:SetHeight(1)
line:SetTexture(0.8, 0.8, 0.8, 0.5)
end
function ui:CreateSeparator(parent)
if parent.label then
parent:SetPoint("RIGHT", -31, 0)
parent:SetHeight(1)
parent.label:ClearAllPoints()
parent.label:SetPoint("CENTER")
createSeparator(parent, {"LEFT", parent}, {"RIGHT", parent.label, "LEFT", -5, 0})
createSeparator(parent, {"RIGHT", parent}, {"LEFT", parent.label, "RIGHT", 5, 0})
else
local relativeTo = parent.desc or parent
createSeparator(parent, {"BOTTOMLEFT", parent.desc, 0, 0}, {"BOTTOMRIGHT", parent.desc, 0, 0})
end
end
function ui:CreateListItem()
local frame = CreateFrame("Button")
frame:SetSize(220, 16)
frame:SetPushedTextOffset(0, 0)
frame:SetHighlightTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]])
local font = frame:CreateFontString(nil, nil, "GameFontHighlight")
font:SetJustifyH("LEFT")
font:SetAllPoints()
frame:SetFontString(font)
local item = {}
function item:Select()
frame.selected = true
frame:LockHighlight()
end
function item:Deselect()
frame.selected = false
frame:UnlockHighlight()
end
function item:Remove()
self:Deselect()
font:Hide()
font:SetText(nil)
font:ClearAllPoints()
font = nil
frame:Hide()
frame:SetScript("OnClick", nil)
frame:SetParent(nil)
frame:ClearAllPoints()
frame = nil
item = nil;
end
function item:IsSelected()
return frame.selected
end
function item:SetText(value)
frame:SetText(value)
end
function item:GetText()
return frame:GetText()
end
function item:Copy(destItem)
destItem:SetText(self:GetText())
end
frame:SetScript("OnClick", function()
if not item:IsSelected() then
item:Select()
else
item:Deselect()
end
end)
item.frame = frame
return item
end
function ui:CreateList(parent)
parent = parent.frame or parent
local frame = CreateFrame("Frame", nil, parent)
local title = frame:CreateFontString(nil, nil, "GameFontNormal")
title:SetPoint("TOP", 0, 20)
title:SetText(name)
title:SetSize(220, 16)
local bg = frame:CreateTexture(nil, "BORDER")
bg:SetTexture(0.3, 0.3, 0.3)
bg:SetBlendMode("MOD")
bg:SetAllPoints()
local border = frame:CreateTexture(nil, "BORDER", nil, -1)
border:SetTexture(0.5, 0.5, 0.5, 0.3)
border:SetPoint("TOPLEFT", bg, -1, 1)
border:SetPoint("BOTTOMRIGHT", bg, 1, -1)
local count = 0
local list, items = {}, {}
function list:SetTitle(value)
title:SetText(value)
end
function list:SetSize(width, height)
frame:SetSize(width, height)
end
function list:SetPoint(point, relativeTo, ...)
frame:SetPoint(point, type(relativeTo) == "table" and relativeTo.frame or relativeTo, ...)
end
function list:AddItem(item)
count = count + 1
table.insert(items, item)
local child = item.frame
child:SetParent(frame)
if count == 1 then
child:SetPoint("TOPLEFT", frame, 10, -10)
else
local parent = items[count - 1].frame
child:SetPoint("TOP", parent, "BOTTOM")
end
end
function list:RemoveItem(index)
local item = table.remove(items, index)
if not item then
return
end
if item:IsSelected() then
item:Deselect()
end
item:Remove();
count = count - 1
end
function list:Update()
for i, item in ipairs(items) do
local child = item.frame
child:ClearAllPoints()
if i == 1 then
child:SetPoint("TOPLEFT", frame, 10, -10)
else
local parent = items[i - 1].frame
child:SetPoint("TOP", parent, "BOTTOM")
end
end
end
function list:Items()
return ipairs(items)
end
local function reverse()
local i = #items + 1
return function ()
i = i - 1
if i > 0 then return i, items[i] end
end
end
function list:Sort(comp)
table.sort(items, comp)
self:Update()
end
function list:CopyItem(item)
local destItem = ui:CreateListItem()
item:Copy(destItem)
self:AddItem(destItem)
end
function list:MoveSelectedTo(destList)
for i, item in reverse() do
if item:IsSelected() then
destList:CopyItem(item)
self:RemoveItem(i)
end
end
destList:Sort(compByName)
self:Sort(compByName)
end
local function selectedItems()
local i = 0
local n = 0
local max = #items
return function ()
while n <= max do
n = n + 1
local item = items[n]
if item and item:IsSelected() then
i = i + 1
return i, n, item
end
end
return nil
end
end
local function swap(sourceIndex, destIndex)
items[sourceIndex], items[destIndex] = items[destIndex], items[sourceIndex]
end
local function moveSelected(up)
local selectedIndices = {}
for i, n in selectedItems() do
selectedIndices[i] = n
end
local i = up and 1 or #selectedIndices
local selectedIndex = selectedIndices[i]
while selectedIndex do
local index = up and selectedIndex - 1 or selectedIndex + 1
if count >= index and index > 0 then
swap(selectedIndex, index)
end
i = up and i + 1 or i - 1
selectedIndex = selectedIndices[i]
end
end
function list:MoveSelectedDown()
moveSelected()
self:Update()
end
function list:MoveSelectedUp()
moveSelected(true)
self:Update()
end
function list:Clear()
for i in reverse() do
self:RemoveItem(i)
end
end
list.frame = frame
return list
end
function ui:CreateButton(parent)
parent = parent.frame or parent
local frame = CreateFrame("Button", nil, parent)
frame:SetSize(24, 24)
frame:SetHighlightTexture([[Interface\Buttons\UI-Common-MouseHilight]])
local button = {}
function button:SetSize(width, height)
frame:SetSize(width, height)
end
function button:SetPoint(point, relativeTo, ...)
frame:SetPoint(point, type(relativeTo) == "table" and relativeTo.frame or relativeTo, ...)
end
function button:SetNormalTexture(texture)
frame:SetNormalTexture(texture)
end
function button:SetPushedTexture(texture)
frame:SetPushedTexture(texture)
end
function button:OnClick(handler)
frame:SetScript("OnClick", function()
handler()
end)
end
button.frame = frame
return button
end