init
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- This file contains function for the bank/gbank frame
|
||||
|
||||
-- loads the localization table --
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster")
|
||||
|
||||
-- load the parent file (TSM) into a local variable and register this file as a module
|
||||
local TSM = select(2, ...)
|
||||
local BankUI = TSM:NewModule("BankUI", "AceEvent-3.0")
|
||||
local AceGUI = LibStub("AceGUI-3.0") -- load the AceGUI librarie
|
||||
|
||||
local ui
|
||||
local bankFrame, bankType
|
||||
local bFrame = nil
|
||||
local container = nil
|
||||
local registeredModules = {}
|
||||
local private = {}
|
||||
TSMAPI:RegisterForTracing(private, "TradeSkillMaster.BankUI_private")
|
||||
private.bankUiButtons = {}
|
||||
|
||||
function BankUI:OnEnable()
|
||||
BankUI:RegisterEvent("GUILDBANKFRAME_OPENED", function(event)
|
||||
bankType = "guild"
|
||||
TSMAPI:CreateTimeDelay(0.1, function()
|
||||
bankFrame = BankUI:getBankFrame("guildbank")
|
||||
if TSM.db.profile.isBankui then
|
||||
if #private.bankUiButtons > 0 then
|
||||
if ui then
|
||||
BankUI:resetPoints(ui)
|
||||
ui:Show()
|
||||
if TSM.db.global.bankUITab then
|
||||
for index, info in ipairs(private.bankUiButtons) do
|
||||
if info.moduleName == TSM.db.global.bankUITab then
|
||||
ui.buttons[index]:Click()
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
ui.buttons[1]:Click()
|
||||
end
|
||||
return
|
||||
end
|
||||
ui = BankUI:getFrame(bankFrame)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
BankUI:RegisterEvent("BANKFRAME_OPENED", function(event)
|
||||
bankType = "bank"
|
||||
TSMAPI:CreateTimeDelay(0.1, function()
|
||||
bankFrame = BankUI:getBankFrame("bank")
|
||||
if TSM.db.profile.isBankui then
|
||||
if #private.bankUiButtons > 0 then
|
||||
if ui then
|
||||
BankUI:resetPoints(ui)
|
||||
ui:Show()
|
||||
if TSM.db.global.bankUITab then
|
||||
for index, info in ipairs(private.bankUiButtons) do
|
||||
if info.moduleName == TSM.db.global.bankUITab then
|
||||
ui.buttons[index]:Click()
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
ui.buttons[1]:Click()
|
||||
end
|
||||
return
|
||||
end
|
||||
ui = BankUI:getFrame(bankFrame)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
BankUI:RegisterEvent("GUILDBANKFRAME_CLOSED", function(event, addon)
|
||||
if ui then ui:Hide() end
|
||||
bankType = nil
|
||||
end)
|
||||
|
||||
BankUI:RegisterEvent("BANKFRAME_CLOSED", function(event)
|
||||
if ui then ui:Hide() end
|
||||
bankType = nil
|
||||
end)
|
||||
end
|
||||
|
||||
local function createCloseButton(text, parent, func)
|
||||
local btn = TSMAPI.GUI:CreateButton(bFrame, 18, "Button")
|
||||
btn:SetText(text)
|
||||
btn:SetHeight(20)
|
||||
btn:SetWidth(20)
|
||||
return btn
|
||||
end
|
||||
|
||||
function TSM:RegisterBankUiButton(moduleName, callback)
|
||||
if registeredModules[moduleName] then return end
|
||||
registeredModules[moduleName] = true
|
||||
local info = {}
|
||||
info.moduleName = moduleName
|
||||
info.callback = callback
|
||||
tinsert(private.bankUiButtons, info)
|
||||
sort(private.bankUiButtons, function(a, b)
|
||||
if a.moduleName == "Warehousing" then
|
||||
return true
|
||||
elseif b.moduleName == "Warehousing" then
|
||||
return false
|
||||
else
|
||||
return a.moduleName < b.moduleName
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function BankUI:getBankFrame(bank)
|
||||
if BagnonFrameguildbank and BagnonFrameguildbank:IsVisible() then
|
||||
return BagnonFrameguildbank
|
||||
elseif BagnonFramebank and BagnonFramebank:IsVisible() then
|
||||
return BagnonFramebank
|
||||
elseif GuildBankFrame and GuildBankFrame:IsVisible() then
|
||||
return GuildBankFrame
|
||||
elseif BankFrame and BankFrame:IsVisible() then
|
||||
return BankFrame
|
||||
elseif (famBankFrame and famBankFrame:IsVisible()) then
|
||||
return famBankFrame
|
||||
elseif (ARKINV_Frame4 and ARKINV_Frame4:IsVisible()) then
|
||||
return ARKINV_Frame4
|
||||
elseif (ARKINV_Frame3 and ARKINV_Frame3:IsVisible()) then
|
||||
return ARKINV_Frame3
|
||||
elseif (OneBankFrame and OneBankFrame:IsVisible()) then
|
||||
return OneBankFrame
|
||||
elseif (TukuiBank and TukuiBank:IsShown()) then
|
||||
return TukuiBank
|
||||
elseif (ElvUI_BankContainerFrame and ElvUI_BankContainerFrame:IsVisible()) then
|
||||
return ElvUI_BankContainerFrame
|
||||
elseif (LUIBank and LUIBank:IsVisible()) then
|
||||
return LUIBank
|
||||
elseif (AdiBagsContainer1 and AdiBagsContainer1.isBank and AdiBagsContainer1:IsVisible()) then
|
||||
return AdiBagsContainer1
|
||||
elseif (AdiBagsContainer2 and AdiBagsContainer2.isBank and AdiBagsContainer2:IsVisible()) then
|
||||
return AdiBagsContainer2
|
||||
elseif (BagsFrameBank and BagsFrameBank:IsVisible()) then
|
||||
return BagsFrameBank
|
||||
elseif AspUIBank and AspUIBank:IsVisible() then
|
||||
return AspUIBank
|
||||
elseif NivayacBniv_Bank and NivayacBniv_Bank:IsVisible() then
|
||||
return NivayacBniv_Bank
|
||||
elseif DufUIBank and DufUIBank:IsVisible() then
|
||||
return DufUIBank
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function BankUI:getFrame(frameType)
|
||||
bFrame = CreateFrame("Frame", nil, UIParent)
|
||||
bFrame:Hide()
|
||||
--size--
|
||||
bFrame:SetWidth(275)
|
||||
bFrame:SetHeight(470)
|
||||
bFrame:SetPoint("CENTER", UIParent)
|
||||
|
||||
--for moving--
|
||||
bFrame:SetScript("OnMouseDown", bFrame.StartMoving)
|
||||
bFrame:SetScript("OnMouseUp", function(...) bFrame.StopMovingOrSizing(...)
|
||||
if bankType == "guild" then
|
||||
TSM.db.factionrealm.bankUIGBankFramePosition = { bFrame:GetLeft(), bFrame:GetBottom() }
|
||||
else
|
||||
TSM.db.factionrealm.bankUIBankFramePosition = { bFrame:GetLeft(), bFrame:GetBottom() }
|
||||
end
|
||||
end)
|
||||
bFrame:SetMovable(true)
|
||||
bFrame:EnableMouse(true)
|
||||
|
||||
bFrame:SetPoint("CENTER", UIParent)
|
||||
|
||||
local function OnFrameShow(self)
|
||||
self:SetFrameLevel(0)
|
||||
self:ClearAllPoints()
|
||||
if bankType == "guild" then
|
||||
self:SetPoint("BOTTOMLEFT", UIParent, unpack(TSM.db.factionrealm.bankUIGBankFramePosition))
|
||||
else
|
||||
self:SetPoint("BOTTOMLEFT", UIParent, unpack(TSM.db.factionrealm.bankUIBankFramePosition))
|
||||
end
|
||||
end
|
||||
|
||||
TSMAPI.Design:SetFrameBackdropColor(bFrame)
|
||||
bFrame:SetScript("OnShow", OnFrameShow)
|
||||
bFrame:Show()
|
||||
|
||||
local title = TSMAPI.GUI:CreateLabel(bFrame)
|
||||
title:SetPoint("TOPLEFT", 40, -3)
|
||||
title:SetPoint("BOTTOMRIGHT", bFrame, "TOPRIGHT", -5, -23)
|
||||
title:SetJustifyH("CENTER")
|
||||
title:SetJustifyV("CENTER")
|
||||
title:SetText("TradeSkillMaster - " .. TSM._version)
|
||||
TSMAPI.Design:SetTitleTextColor(title)
|
||||
|
||||
local title2 = TSMAPI.GUI:CreateLabel(bFrame)
|
||||
title2:SetPoint("TOPLEFT", title, "BOTTOMLEFT")
|
||||
title2:SetPoint("TOPRIGHT", title, "BOTTOMRIGHT")
|
||||
title2:SetJustifyH("CENTER")
|
||||
title2:SetJustifyV("CENTER")
|
||||
title2:SetText(L["BankUI"])
|
||||
TSMAPI.Design:SetTitleTextColor(title2)
|
||||
|
||||
|
||||
bFrame.btnClose = createCloseButton("X", bFrame, nil)
|
||||
bFrame.btnClose:SetPoint("TOPRIGHT", bFrame, "TOPRIGHT")
|
||||
bFrame.btnClose:SetScript("OnClick", function(self)
|
||||
if bFrame then bFrame:Hide() end
|
||||
TSM.db.profile.isBankui = false
|
||||
TSM:Print(L["You have closed the bankui. Use '/tsm bankui' to view again."])
|
||||
end)
|
||||
|
||||
-- module buttons
|
||||
bFrame.buttons = {}
|
||||
|
||||
local iconFrame = CreateFrame("Frame", nil, bFrame)
|
||||
iconFrame:SetPoint("CENTER", bFrame, "TOPLEFT", 25, -25)
|
||||
iconFrame:SetHeight(80)
|
||||
iconFrame:SetWidth(80)
|
||||
local icon = iconFrame:CreateTexture(nil, "ARTWORK")
|
||||
icon:SetAllPoints()
|
||||
icon:SetTexture("Interface\\Addons\\TradeSkillMaster\\Media\\TSM_Icon_Big")
|
||||
local ag = iconFrame:CreateAnimationGroup()
|
||||
local spin = ag:CreateAnimation("Rotation")
|
||||
spin:SetOrder(1)
|
||||
spin:SetDuration(2)
|
||||
spin:SetDegrees(90)
|
||||
local spin = ag:CreateAnimation("Rotation")
|
||||
spin:SetOrder(2)
|
||||
spin:SetDuration(4)
|
||||
spin:SetDegrees(-180)
|
||||
local spin = ag:CreateAnimation("Rotation")
|
||||
spin:SetOrder(3)
|
||||
spin:SetDuration(2)
|
||||
spin:SetDegrees(90)
|
||||
ag:SetLooping("REPEAT")
|
||||
iconFrame:SetScript("OnEnter", function() ag:Play() end)
|
||||
iconFrame:SetScript("OnLeave", function() ag:Stop() end)
|
||||
|
||||
container = CreateFrame("Frame", nil, bFrame)
|
||||
container:SetPoint("TOPLEFT", 5, -60)
|
||||
container:SetPoint("BOTTOMRIGHT", -5, 5)
|
||||
TSMAPI.Design:SetFrameColor(container)
|
||||
|
||||
for _, info in ipairs(private.bankUiButtons) do
|
||||
info.bankTab = info.callback(container)
|
||||
private:CreateBankButton(info.moduleName)
|
||||
end
|
||||
|
||||
if TSM.db.global.bankUITab then
|
||||
for index, info in ipairs(private.bankUiButtons) do
|
||||
if info.moduleName == TSM.db.global.bankUITab then
|
||||
bFrame.buttons[index]:Click()
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
bFrame.buttons[1]:Click()
|
||||
end
|
||||
return bFrame
|
||||
end
|
||||
|
||||
function BankUI:resetPoints(container)
|
||||
if bankType == "guild" then
|
||||
container:SetPoint("BOTTOMLEFT", UIParent, unpack(TSM.db.factionrealm.bankUIGBankFramePosition))
|
||||
else
|
||||
container:SetPoint("BOTTOMLEFT", UIParent, unpack(TSM.db.factionrealm.bankUIBankFramePosition))
|
||||
end
|
||||
end
|
||||
|
||||
function private:CreateBankButton(module)
|
||||
local buttonIndex
|
||||
for record, info in ipairs(private.bankUiButtons) do
|
||||
if info.moduleName == module then
|
||||
buttonIndex = record
|
||||
end
|
||||
end
|
||||
|
||||
local function OnButtonClick(self)
|
||||
for _, info in ipairs(private.bankUiButtons) do
|
||||
info.bankTab:Hide()
|
||||
end
|
||||
|
||||
for index, button in ipairs(bFrame.buttons) do
|
||||
button:UnlockHighlight()
|
||||
if self == button then
|
||||
private.bankUiButtons[index].bankTab:Show()
|
||||
end
|
||||
end
|
||||
self:LockHighlight()
|
||||
end
|
||||
|
||||
local button = TSMAPI.GUI:CreateButton(bFrame, 12)
|
||||
if buttonIndex == 1 then
|
||||
button:SetPoint("TOPLEFT", 70, -40)
|
||||
else
|
||||
button:SetPoint("TOPLEFT", bFrame.buttons[buttonIndex - 1], "TOPRIGHT", 5, 0)
|
||||
end
|
||||
button:SetHeight(20)
|
||||
button:SetWidth(70)
|
||||
button:SetText(module)
|
||||
button:SetScript("OnClick", OnButtonClick)
|
||||
tinsert(bFrame.buttons, button)
|
||||
end
|
||||
|
||||
function TSM:toggleBankUI()
|
||||
if TSM:areBanksVisible() then
|
||||
if ui then
|
||||
if ui:IsShown() then
|
||||
ui:Hide()
|
||||
else
|
||||
ui:Show()
|
||||
end
|
||||
else
|
||||
ui = BankUI:getFrame(bankFrame)
|
||||
TSM.db.profile.isBankui = true
|
||||
end
|
||||
else
|
||||
TSM:Print(L["There are no visible banks."])
|
||||
end
|
||||
end
|
||||
|
||||
function TSM:getBankTabs()
|
||||
local tabs = {}
|
||||
for record, info in ipairs(private.bankUiButtons) do
|
||||
tabs[info.moduleName] = info.moduleName
|
||||
end
|
||||
return tabs
|
||||
end
|
||||
|
||||
function TSM:ResetBankUIFramePosition()
|
||||
TSM.db.factionrealm.bankUIGBankFramePosition = { 100, 300 }
|
||||
TSM.db.factionrealm.bankUIBankFramePosition = { 100, 300 }
|
||||
if ui then
|
||||
ui:Hide()
|
||||
ui:Show()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,433 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local TSM = select(2, ...)
|
||||
local AceGUI = LibStub("AceGUI-3.0") -- load the AceGUI libraries
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
||||
local lib = TSMAPI
|
||||
local customPriceFrame
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
TSMAPI:BuildPage() Support Functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function CreateCustomPriceFrame()
|
||||
local frame = CreateFrame("Frame", nil, TSMMainFrame1)
|
||||
TSMAPI.Design:SetFrameBackdropColor(frame)
|
||||
frame:Hide()
|
||||
frame:SetPoint("TOPLEFT", TSMMainFrame1, "TOPRIGHT", 2, 0)
|
||||
frame:SetWidth(300)
|
||||
frame:SetHeight(400)
|
||||
|
||||
local container = AceGUI:Create("TSMScrollFrame")
|
||||
container:SetLayout("Flow")
|
||||
container.frame:SetParent(frame)
|
||||
container.frame:SetPoint("TOPLEFT", 5, -5)
|
||||
container.frame:SetPoint("BOTTOMRIGHT", -5, 5)
|
||||
|
||||
local page = {
|
||||
{
|
||||
type = "Label",
|
||||
relativeWidth = 1,
|
||||
text = L["Below are various ways you can set the value of the current editbox. Any combination of these methods is also supported."],
|
||||
},
|
||||
{
|
||||
type = "HeadingLine",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = TSMAPI.Design:GetInlineColor("category")..L["Fixed Gold Value"].."|r",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = L["A simple, fixed gold amount."],
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "HeadingLine",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = TSMAPI.Design:GetInlineColor("category")..L["Percent of Price Source"].."|r",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = L["Type '/tsm sources' to print out all available price sources."],
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "HeadingLine",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = TSMAPI.Design:GetInlineColor("category")..L["More Advanced Methods"].."|r",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = format("See %s for more info.", TSMAPI.Design:GetInlineColor("link").."http://bit.ly/TSMCP|r"),
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "HeadingLine",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = TSMAPI.Design:GetInlineColor("category")..L["Examples"].."|r",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = "20g50s",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = "120% crafting",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = "100% vendor + 5g",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = "max(150% dbmarket, 1.2 * crafting)",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
{
|
||||
type = "Label",
|
||||
text = "max(vendor, 120% crafting)",
|
||||
relativeWidth = 1,
|
||||
},
|
||||
}
|
||||
|
||||
TSMAPI:BuildPage(container, page)
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
local function FormatCopperCustomPrice(value)
|
||||
value = gsub(value, TSMAPI:StrEscape(TSM.GOLD_TEXT), "g")
|
||||
value = gsub(value, TSMAPI:StrEscape(TSM.SILVER_TEXT), "s")
|
||||
value = gsub(value, TSMAPI:StrEscape(TSM.COPPER_TEXT), "c")
|
||||
local goldPart = select(3, strfind(value, "([0-9]+g)"))
|
||||
local silverPart = select(3, strfind(value, "([0-9]+s)"))
|
||||
local copperPart = select(3, strfind(value, "([0-9]+c)"))
|
||||
if copperPart then
|
||||
value = gsub(value, copperPart, gsub(copperPart, "c", TSM.COPPER_TEXT))
|
||||
end
|
||||
if silverPart then
|
||||
value = gsub(value, silverPart, gsub(silverPart, "s", TSM.SILVER_TEXT))
|
||||
end
|
||||
if goldPart then
|
||||
value = gsub(value, goldPart, gsub(goldPart, "g", TSM.GOLD_TEXT))
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local function AddTooltip(widget, text, title)
|
||||
if not text then return end
|
||||
widget:SetCallback("OnEnter", function(self)
|
||||
GameTooltip:SetOwner(self.frame, "ANCHOR_NONE")
|
||||
GameTooltip:SetPoint("BOTTOM", self.frame, "TOP")
|
||||
if title then
|
||||
GameTooltip:SetText(title, 1, .82, 0, 1)
|
||||
end
|
||||
if type(text) == "number" then
|
||||
GameTooltip:SetHyperlink("item:" .. text)
|
||||
elseif tonumber(text) then
|
||||
GameTooltip:SetHyperlink("enchant:"..text)
|
||||
elseif type(text) == "string" and (strfind(text, "item:")) then
|
||||
TSMAPI:SafeTooltipLink(text)
|
||||
else
|
||||
GameTooltip:AddLine(text, 1, 1, 1, 1)
|
||||
end
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
widget:SetCallback("OnLeave", function()
|
||||
-- BattlePetTooltip:Hide()
|
||||
GameTooltip:ClearLines()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
end
|
||||
|
||||
local function CreateContainer(cType, parent, args)
|
||||
local container = AceGUI:Create(cType)
|
||||
if not container then return end
|
||||
container:SetLayout(args.layout)
|
||||
if args.title then container:SetTitle(args.title) end
|
||||
container:SetRelativeWidth(args.relativeWidth or 1)
|
||||
container:SetFullHeight(args.fullHeight)
|
||||
parent:AddChild(container)
|
||||
return container
|
||||
end
|
||||
|
||||
local function CreateWidget(wType, parent, args)
|
||||
local widget = AceGUI:Create(wType)
|
||||
if args.settingInfo then
|
||||
args.value = args.value or args.settingInfo[1][args.settingInfo[2]]
|
||||
if args.acceptCustom then
|
||||
if tonumber(args.value) then
|
||||
args.value = TSMAPI:FormatTextMoney(args.value)
|
||||
elseif args.value then
|
||||
args.value = FormatCopperCustomPrice(args.value)
|
||||
end
|
||||
end
|
||||
local oldCallback = args.callback
|
||||
args.callback = function(...)
|
||||
local value = select(3, ...)
|
||||
if type(value) == "string" then value = value:trim() end
|
||||
if args.multiselect then
|
||||
local key = value
|
||||
value = select(4, ...)
|
||||
args.settingInfo[1][args.settingInfo[2]][key] = value
|
||||
else
|
||||
args.settingInfo[1][args.settingInfo[2]] = value
|
||||
end
|
||||
if oldCallback then oldCallback(...) end
|
||||
end
|
||||
end
|
||||
if args.text then widget:SetText(args.text) end
|
||||
if args.label then widget:SetLabel(args.label) end
|
||||
if args.width then
|
||||
widget:SetWidth(args.width)
|
||||
elseif args.relativeWidth then
|
||||
if args.relativeWidth == 1 then
|
||||
widget:SetFullWidth(true)
|
||||
else
|
||||
widget:SetRelativeWidth(args.relativeWidth)
|
||||
end
|
||||
end
|
||||
if args.height then widget:SetHeight(args.height) end
|
||||
if widget.SetDisabled then widget:SetDisabled(args.disabled) end
|
||||
AddTooltip(widget, args.tooltip, args.label)
|
||||
parent:AddChild(widget)
|
||||
return widget
|
||||
end
|
||||
|
||||
local Add = {
|
||||
InlineGroup = function(parent, args)
|
||||
local container = CreateContainer("TSMInlineGroup", parent, args)
|
||||
container:HideTitle(not args.title)
|
||||
container:HideBorder(args.noBorder)
|
||||
container:SetBackdrop(args.backdrop)
|
||||
return container
|
||||
end,
|
||||
|
||||
SimpleGroup = function(parent, args)
|
||||
local container = CreateContainer("TSMSimpleGroup", parent, args)
|
||||
if args.height then container:SetHeight(args.height) end
|
||||
return container
|
||||
end,
|
||||
|
||||
ScrollFrame = function(parent, args)
|
||||
return CreateContainer("TSMScrollFrame", parent, args)
|
||||
end,
|
||||
|
||||
Image = function(parent, args)
|
||||
local image = CreateWidget("TSMImage", parent, args)
|
||||
image:SetImage(args.image)
|
||||
image:SetSizeRatio(args.sizeRatio)
|
||||
return image
|
||||
end,
|
||||
|
||||
Label = function(parent, args)
|
||||
local labelWidget = CreateWidget("TSMLabel", parent, args)
|
||||
labelWidget:SetColor(args.colorRed, args.colorGreen, args.colorBlue)
|
||||
return labelWidget
|
||||
end,
|
||||
|
||||
MultiLabel = function(parent, args)
|
||||
local labelWidget = CreateWidget("TSMMultiLabel", parent, args)
|
||||
labelWidget:SetLabels(args.labelInfo)
|
||||
return labelWidget
|
||||
end,
|
||||
|
||||
InteractiveLabel = function(parent, args)
|
||||
local iLabelWidget = CreateWidget("TSMInteractiveLabel", parent, args)
|
||||
iLabelWidget:SetCallback("OnClick", args.callback)
|
||||
return iLabelWidget
|
||||
end,
|
||||
|
||||
Button = function(parent, args)
|
||||
local buttonWidget = CreateWidget("TSMButton", parent, args)
|
||||
buttonWidget:SetCallback("OnClick", args.callback)
|
||||
return buttonWidget
|
||||
end,
|
||||
|
||||
GroupItemList = function(parent, args)
|
||||
local groupItemList = CreateWidget("TSMGroupItemList", parent, args)
|
||||
groupItemList:SetIgnoreVisible(args.showIgnore)
|
||||
groupItemList:SetTitle("left", args.leftTitle)
|
||||
groupItemList:SetTitle("right", args.rightTitle)
|
||||
groupItemList:SetListCallback(args.listCallback)
|
||||
groupItemList:SetCallback("OnAddClicked", args.onAdd)
|
||||
groupItemList:SetCallback("OnRemoveClicked", args.onRemove)
|
||||
return groupItemList
|
||||
end,
|
||||
|
||||
MacroButton = function(parent, args)
|
||||
local macroButtonWidget = CreateWidget("TSMMacroButton", parent, args)
|
||||
macroButtonWidget.frame:SetAttribute("type", "macro")
|
||||
macroButtonWidget.frame:SetAttribute("macrotext", args.macroText)
|
||||
return macroButtonWidget
|
||||
end,
|
||||
|
||||
EditBox = function(parent, args)
|
||||
local editBoxWidget = CreateWidget("TSMEditBox", parent, args)
|
||||
editBoxWidget:SetText(args.value)
|
||||
editBoxWidget:DisableButton(args.onTextChanged)
|
||||
editBoxWidget:SetAutoComplete(args.autoComplete)
|
||||
local function callback(self, event, value)
|
||||
if args.acceptCustom then
|
||||
local badPriceSource = type(args.acceptCustom) == "string" and strlower(args.acceptCustom)
|
||||
local customPrice, err = TSMAPI:ParseCustomPrice(value, badPriceSource)
|
||||
if customPrice then
|
||||
self:SetText(FormatCopperCustomPrice(value))
|
||||
self:ClearFocus()
|
||||
args.callback(self, event, value)
|
||||
else
|
||||
TSM:Print(L["Invalid custom price."].." "..err)
|
||||
self:SetFocus()
|
||||
end
|
||||
else
|
||||
args.callback(self, event, value)
|
||||
end
|
||||
end
|
||||
editBoxWidget:SetCallback(args.onTextChanged and "OnTextChanged" or "OnEnterPressed", callback)
|
||||
if args.acceptCustom then
|
||||
customPriceFrame = customPriceFrame or CreateCustomPriceFrame()
|
||||
editBoxWidget:SetCallback("OnEditFocusGained", function() customPriceFrame:Show() end)
|
||||
editBoxWidget:SetCallback("OnEditFocusLost", function() customPriceFrame:Hide() end)
|
||||
end
|
||||
return editBoxWidget
|
||||
end,
|
||||
|
||||
GroupBox = function(parent, args)
|
||||
local groupBoxWidget = CreateWidget("TSMGroupBox", parent, args)
|
||||
groupBoxWidget:SetText(args.value)
|
||||
groupBoxWidget:SetCallback("OnValueChanged", args.callback)
|
||||
return groupBoxWidget
|
||||
end,
|
||||
|
||||
CheckBox = function(parent, args)
|
||||
local checkBoxWidget = CreateWidget("TSMCheckBox", parent, args)
|
||||
checkBoxWidget:SetType(args.cbType or "checkbox")
|
||||
checkBoxWidget:SetValue(args.value)
|
||||
if args.label then checkBoxWidget:SetLabel(args.label) end
|
||||
if not args.width and not args.relativeWidth then
|
||||
checkBoxWidget:SetRelativeWidth(0.5)
|
||||
end
|
||||
checkBoxWidget:SetCallback("OnValueChanged", args.callback)
|
||||
return checkBoxWidget
|
||||
end,
|
||||
|
||||
Slider = function(parent, args)
|
||||
local sliderWidget = CreateWidget("TSMSlider", parent, args)
|
||||
sliderWidget:SetValue(args.value)
|
||||
sliderWidget:SetSliderValues(args.min, args.max, args.step)
|
||||
sliderWidget:SetIsPercent(args.isPercent)
|
||||
sliderWidget:SetCallback("OnValueChanged", args.callback)
|
||||
return sliderWidget
|
||||
end,
|
||||
|
||||
Icon = function(parent, args)
|
||||
local iconWidget = CreateWidget("Icon", parent, args)
|
||||
iconWidget:SetImage(args.image)
|
||||
iconWidget:SetImageSize(args.imageWidth, args.imageHeight)
|
||||
iconWidget:SetCallback("OnClick", args.callback)
|
||||
return iconWidget
|
||||
end,
|
||||
|
||||
Dropdown = function(parent, args)
|
||||
local dropdownWidget = CreateWidget("TSMDropdown", parent, args)
|
||||
dropdownWidget:SetList(args.list, args.order)
|
||||
dropdownWidget:SetMultiselect(args.multiselect)
|
||||
if type(args.value) == "table" then
|
||||
for name, value in pairs(args.value) do
|
||||
dropdownWidget:SetItemValue(name, value)
|
||||
end
|
||||
else
|
||||
dropdownWidget:SetValue(args.value)
|
||||
end
|
||||
dropdownWidget:SetCallback("OnValueChanged", args.callback)
|
||||
return dropdownWidget
|
||||
end,
|
||||
|
||||
ColorPicker = function(parent, args)
|
||||
local colorPicker = CreateWidget("TSMColorPicker", parent, args)
|
||||
colorPicker:SetHasAlpha(args.hasAlpha)
|
||||
if type(args.value) == "table" then
|
||||
colorPicker:SetColor(unpack(args.value))
|
||||
end
|
||||
colorPicker:SetCallback("OnValueChanged", args.callback)
|
||||
colorPicker:SetCallback("OnValueConfirmed", args.callback)
|
||||
return colorPicker
|
||||
end,
|
||||
|
||||
Spacer = function(parent, args)
|
||||
args.quantity = args.quantity or 1
|
||||
for i=1, args.quantity do
|
||||
local spacer = parent:Add({type="Label", text=" ", relativeWidth=1})
|
||||
end
|
||||
end,
|
||||
|
||||
HeadingLine = function(parent, args)
|
||||
local heading = AceGUI:Create("Heading")
|
||||
heading:SetText("")
|
||||
heading:SetRelativeWidth(args.relativeWidth or 1)
|
||||
parent:AddChild(heading)
|
||||
end,
|
||||
}
|
||||
|
||||
-- creates a widget or container as detailed in the passed table (iTable) and adds it as a child of the passed parent
|
||||
function lib.AddGUIElement(parent, iTable)
|
||||
assert(Add[iTable.type], "Invalid Widget or Container Type: "..iTable.type)
|
||||
return Add[iTable.type](parent, iTable)
|
||||
end
|
||||
|
||||
-- goes through a page-table and draws out all the containers and widgets for that page
|
||||
function TSMAPI:BuildPage(oContainer, oPageTable, noPause)
|
||||
local function recursive(container, pageTable)
|
||||
for _, data in pairs(pageTable) do
|
||||
local parentElement = container:Add(data)
|
||||
if data.children then
|
||||
parentElement:PauseLayout()
|
||||
-- yay recursive function calls!
|
||||
recursive(parentElement, data.children)
|
||||
parentElement:ResumeLayout()
|
||||
parentElement:DoLayout()
|
||||
end
|
||||
end
|
||||
end
|
||||
if not oContainer.Add then
|
||||
local container = AceGUI:Create("TSMSimpleGroup")
|
||||
container:SetLayout("fill")
|
||||
container:SetFullWidth(true)
|
||||
container:SetFullHeight(true)
|
||||
oContainer:AddChild(container)
|
||||
oContainer = container
|
||||
end
|
||||
if not noPause then
|
||||
oContainer:PauseLayout()
|
||||
recursive(oContainer, oPageTable)
|
||||
oContainer:ResumeLayout()
|
||||
oContainer:DoLayout()
|
||||
else
|
||||
recursive(oContainer, oPageTable)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,128 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- This file contains support code for the custom TSM widgets
|
||||
local TSM = select(2, ...)
|
||||
local lib = TSMAPI
|
||||
|
||||
TSMAPI.Design = {}
|
||||
local Design = TSMAPI.Design
|
||||
local coloredFrames = {}
|
||||
local coloredTexts = {}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function expandColor(tbl)
|
||||
tbl = CopyTable(tbl)
|
||||
for i=1, 3 do
|
||||
tbl[i] = tbl[i] / 255
|
||||
end
|
||||
return unpack(tbl)
|
||||
end
|
||||
|
||||
local function SetFrameColor(obj, colorKey)
|
||||
local color = TSM.db.profile.design.frameColors[colorKey]
|
||||
if not obj then return expandColor(color.backdrop) end
|
||||
coloredFrames[obj] = {obj, colorKey}
|
||||
if obj:IsObjectType("Frame") then
|
||||
obj:SetBackdrop({bgFile="Interface\\Buttons\\WHITE8X8", edgeFile="Interface\\Buttons\\WHITE8X8", edgeSize=TSM.db.profile.design.edgeSize})
|
||||
obj:SetBackdropColor(expandColor(color.backdrop))
|
||||
obj:SetBackdropBorderColor(expandColor(color.border))
|
||||
else
|
||||
obj:SetTexture(expandColor(color.backdrop))
|
||||
end
|
||||
end
|
||||
|
||||
local function SetTextColor(obj, colorKey, isDisabled)
|
||||
local color = TSM.db.profile.design.textColors[colorKey]
|
||||
if not obj then return expandColor(color.enabled) end
|
||||
coloredTexts[obj] = {obj, colorKey, isDisabled}
|
||||
if obj:IsObjectType("Texture") then
|
||||
obj:SetTexture(expandColor(color.enabled))
|
||||
else
|
||||
if isDisabled then
|
||||
obj:SetTextColor(expandColor(color.disabled))
|
||||
else
|
||||
obj:SetTextColor(expandColor(color.enabled))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Design API functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
function Design:SetFrameBackdropColor(obj)
|
||||
return SetFrameColor(obj, "frameBG")
|
||||
end
|
||||
|
||||
function Design:SetFrameColor(obj)
|
||||
return SetFrameColor(obj, "frame")
|
||||
end
|
||||
|
||||
function Design:SetContentColor(obj)
|
||||
return SetFrameColor(obj, "content")
|
||||
end
|
||||
|
||||
function Design:SetIconRegionColor(obj)
|
||||
return SetTextColor(obj, "iconRegion")
|
||||
end
|
||||
|
||||
function Design:SetWidgetTextColor(obj, isDisabled)
|
||||
return SetTextColor(obj, "text", isDisabled)
|
||||
end
|
||||
|
||||
function Design:SetWidgetLabelColor(obj, isDisabled)
|
||||
return SetTextColor(obj, "label", isDisabled)
|
||||
end
|
||||
|
||||
function Design:SetTitleTextColor(obj)
|
||||
return SetTextColor(obj, "title")
|
||||
end
|
||||
|
||||
function Design:GetContentFont(size)
|
||||
size = size or "normal"
|
||||
TSM.db.profile.design.fontSizes[size] = TSM.db.profile.design.fontSizes[size] or TSM.designDefaults.fontSizes[size]
|
||||
assert(TSM.db.profile.design.fontSizes[size], format("Invalid font size '%s", tostring(size)))
|
||||
return TSM.db.profile.design.fonts.content, TSM.db.profile.design.fontSizes[size]
|
||||
end
|
||||
|
||||
function Design:GetBoldFont()
|
||||
return TSM.db.profile.design.fonts.bold
|
||||
end
|
||||
|
||||
function Design:GetInlineColor(key)
|
||||
TSM.db.profile.design.inlineColors[key] = TSM.db.profile.design.inlineColors[key] or CopyTable(TSM.designDefaults.inlineColors[key])
|
||||
local r, g, b, a = unpack(TSM.db.profile.design.inlineColors[key])
|
||||
return format("|c%02X%02X%02X%02X", a, r, g, b)
|
||||
end
|
||||
|
||||
function Design:ColorText(text, key)
|
||||
local color = Design:GetInlineColor(key)
|
||||
return color..text.."|r"
|
||||
end
|
||||
|
||||
|
||||
function TSMAPI:UpdateDesign()
|
||||
-- set any missing fields
|
||||
TSM:SetDesignDefaults(TSM.designDefaults, TSM.db.profile.design)
|
||||
local oldTbl = coloredFrames
|
||||
coloredFrames = {}
|
||||
for _, args in pairs(oldTbl) do
|
||||
SetFrameColor(unpack(args))
|
||||
end
|
||||
|
||||
oldTbl = coloredTexts
|
||||
coloredTexts = {}
|
||||
for _, args in pairs(oldTbl) do
|
||||
SetTextColor(unpack(args))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,373 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local TSM = select(2, ...)
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
||||
|
||||
local COUNT = 1
|
||||
local ROW_HEIGHT = 14
|
||||
|
||||
|
||||
local function UpdateTree(self)
|
||||
self.statusText:SetText("")
|
||||
local rowData = {}
|
||||
local groupPathList, disabledGroupPaths = TSM:GetGroupPathList(self.module)
|
||||
|
||||
for i, groupPath in ipairs(groupPathList) do
|
||||
if not disabledGroupPaths[groupPath] then
|
||||
local pathParts = { TSM.GROUP_SEP:split(groupPath) }
|
||||
local leader = ""
|
||||
for i = 1, #pathParts - 1 do
|
||||
leader = leader .. " "
|
||||
end
|
||||
local hasSubGroups = (groupPathList[i + 1] and (groupPathList[i + 1] == groupPath or strfind(groupPathList[i + 1], "^" .. TSMAPI:StrEscape(groupPath) .. TSM.GROUP_SEP)))
|
||||
local parent = #pathParts > 1 and table.concat(pathParts, TSM.GROUP_SEP, 1, #pathParts - 1) or nil
|
||||
local index = #rowData + 1
|
||||
if self.selectedGroups[groupPath] == nil then
|
||||
-- select group by default
|
||||
self.selectedGroups[groupPath] = true
|
||||
end
|
||||
local groupNameText = pathParts[#pathParts]
|
||||
if TSM.db.profile.colorGroupName then
|
||||
groupNameText = TSMAPI:ColorGroupName(groupNameText, #pathParts)
|
||||
end
|
||||
rowData[index] = {
|
||||
value = leader .. format("%s %s%s|r", groupNameText, TSMAPI.Design:GetInlineColor("link"), hasSubGroups and (self.collapsed[groupPath] and "[+]" or "[-]") or ""),
|
||||
groupName = pathParts[#pathParts],
|
||||
parent = parent,
|
||||
groupPath = groupPath,
|
||||
hasSubGroups = hasSubGroups,
|
||||
index = index,
|
||||
isSelected = not self.isGroupBox and self.selectedGroups[groupPath], -- select all rows by default (unless it's for a GroupBox)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if #rowData == 0 then
|
||||
if #groupPathList == 0 then
|
||||
self.statusText:SetText(L["You currently don't have any groups setup. Type '/tsm' and click on the 'TradeSkillMaster Groups' button to setup TSM groups."])
|
||||
else
|
||||
self.statusText:SetText(format(L["None of your groups have %s operations assigned. Type '/tsm' and click on the 'TradeSkillMaster Groups' button to assign operations to your TSM groups."], self.module))
|
||||
end
|
||||
else
|
||||
self.statusText:SetText("")
|
||||
end
|
||||
|
||||
self.rowData = rowData
|
||||
self:RefreshRows()
|
||||
end
|
||||
|
||||
local function SelectAll(self)
|
||||
for i = 1, #self.st.rowData do
|
||||
self.st.selectedGroups[self.st.rowData[i].groupPath] = true
|
||||
self.st.rowData[i].isSelected = true
|
||||
end
|
||||
self.st:RefreshRows()
|
||||
for _, row in ipairs(self.st.rows) do
|
||||
row.highlight:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local function DeselectAll(self)
|
||||
for i = 1, #self.st.rowData do
|
||||
self.st.selectedGroups[self.st.rowData[i].groupPath] = false
|
||||
self.st.rowData[i].isSelected = nil
|
||||
end
|
||||
self.st:RefreshRows()
|
||||
for _, row in ipairs(self.st.rows) do
|
||||
row.highlight:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local methods = {
|
||||
GetRowIndex = function(self, value)
|
||||
for i, v in pairs(self.rowData) do
|
||||
if v.groupPath == value then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end,
|
||||
RefreshRows = function(self)
|
||||
local offset = FauxScrollFrame_GetOffset(self.scrollFrame)
|
||||
self.offset = offset
|
||||
|
||||
for i = #self.rowData, 1, -1 do
|
||||
local data = self.rowData[i]
|
||||
if not self.isGroupBox and not data.isSelected and data.parent then
|
||||
local index = self:GetRowIndex(data.parent)
|
||||
if index then
|
||||
self.rowData[index].isSelected = self.selectedGroups[self.rowData[index].groupPath]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local displayRows = {}
|
||||
for i = 1, #self.rowData do
|
||||
local pathParts = { TSM.GROUP_SEP:split(self.rowData[i].groupPath) }
|
||||
local isCollapsed = false
|
||||
for i = 1, #pathParts - 1 do
|
||||
local path = table.concat(pathParts, TSM.GROUP_SEP, 1, i)
|
||||
if self.collapsed[path] then
|
||||
isCollapsed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not isCollapsed then
|
||||
if self.collapsed[self.rowData[i].groupPath] then
|
||||
self.rowData[i].value = gsub(self.rowData[i].value, TSMAPI:StrEscape("[-]"), "[+]")
|
||||
else
|
||||
self.rowData[i].value = gsub(self.rowData[i].value, TSMAPI:StrEscape("[+]"), "[-]")
|
||||
end
|
||||
tinsert(displayRows, self.rowData[i])
|
||||
end
|
||||
end
|
||||
FauxScrollFrame_Update(self.scrollFrame, #displayRows, self.NUM_ROWS, ROW_HEIGHT)
|
||||
|
||||
for i = 1, self.NUM_ROWS do
|
||||
if i > #displayRows then
|
||||
self.rows[i]:Hide()
|
||||
self.rows[i].data = nil
|
||||
else
|
||||
self.rows[i]:Show()
|
||||
local data = displayRows[i + offset]
|
||||
if not data then return end
|
||||
self.rows[i].data = data
|
||||
|
||||
if data.isSelected or self.rows[i]:IsMouseOver() then
|
||||
self.rows[i].highlight:Show()
|
||||
else
|
||||
self.rows[i].highlight:Hide()
|
||||
end
|
||||
self.rows[i]:SetText(data.value)
|
||||
end
|
||||
end
|
||||
end,
|
||||
SetSelection = function(self, rowNum, isSelected)
|
||||
self.selectedGroups[self.rowData[rowNum].groupPath] = isSelected or false
|
||||
self.rowData[rowNum].isSelected = isSelected
|
||||
self:RefreshRows()
|
||||
end,
|
||||
GetSelectedGroupInfo = function(self, rowNum)
|
||||
local groupInfo = {}
|
||||
for _, data in ipairs(self.rowData) do
|
||||
if data.isSelected then
|
||||
groupInfo[data.groupPath] = { operations = TSM:GetGroupOperations(data.groupPath, self.module), items = TSM:GetGroupItems(data.groupPath) }
|
||||
if self.module and not groupInfo[data.groupPath].operations then
|
||||
groupInfo[data.groupPath] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
return groupInfo
|
||||
end,
|
||||
ClearSelection = function(self)
|
||||
for i = 1, #self.rowData do
|
||||
self.selectedGroups[self.rowData[i].groupPath] = false
|
||||
self.rowData[i].isSelected = nil
|
||||
end
|
||||
self.groupBoxSelection = nil
|
||||
self:RefreshRows()
|
||||
end,
|
||||
SetGropBoxSelection = function(self, groupPath)
|
||||
if self.groupBoxSelection then
|
||||
self.groupBoxSelection.isSelected = nil
|
||||
self.groupBoxSelection = nil
|
||||
end
|
||||
for i = 1, #self.rowData do
|
||||
if self.rowData[i].groupPath == groupPath then
|
||||
self.rowData[i].isSelected = true
|
||||
self.groupBoxSelection = self.rowData[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
end,
|
||||
GetGroupBoxSelection = function(self)
|
||||
return self.groupBoxSelection and self.groupBoxSelection.groupPath
|
||||
end,
|
||||
}
|
||||
|
||||
local defaultColScripts = {
|
||||
OnEnter = function(self)
|
||||
local tooltipLines = {}
|
||||
tinsert(tooltipLines, format(L["%sLeft-Click|r to select / deselect this group."], TSMAPI.Design:GetInlineColor("link")))
|
||||
if self.data.hasSubGroups then
|
||||
tinsert(tooltipLines, format(L["%sRight-Click|r to collapse / expand this group."], TSMAPI.Design:GetInlineColor("link")))
|
||||
end
|
||||
|
||||
local operations = TSM:GetGroupOperations(self.data.groupPath, self.st.module)
|
||||
local operationLine = operations and table.concat(operations, ", ") or L["<No Operation>"]
|
||||
tinsert(tooltipLines, "")
|
||||
tinsert(tooltipLines, format(L["Operations: %s"], operationLine))
|
||||
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOP")
|
||||
GameTooltip:AddLine(table.concat(tooltipLines, "\n"), 1, 1, 1)
|
||||
GameTooltip:Show()
|
||||
|
||||
self.highlight:Show()
|
||||
end,
|
||||
OnLeave = function(self)
|
||||
GameTooltip:Hide()
|
||||
if not self.data.isSelected then
|
||||
self.highlight:Hide()
|
||||
end
|
||||
end,
|
||||
OnClick = function(self, button)
|
||||
if button == "RightButton" then
|
||||
self.st.collapsed[self.data.groupPath] = not self.st.collapsed[self.data.groupPath]
|
||||
self.st:RefreshRows()
|
||||
return
|
||||
end
|
||||
if self.st.isGroupBox then
|
||||
if self.data ~= self.st.groupBoxSelection then
|
||||
if self.st.groupBoxSelection then
|
||||
self.st.groupBoxSelection.isSelected = false
|
||||
end
|
||||
self.st.groupBoxSelection = self.data
|
||||
end
|
||||
self.data.isSelected = true
|
||||
else
|
||||
self.data.isSelected = not self.data.isSelected
|
||||
self.st.selectedGroups[self.data.groupPath] = self.data.isSelected or false
|
||||
if self.data.hasSubGroups then
|
||||
for i = 1, #self.st.rowData do
|
||||
if self.st.rowData[i].groupPath == self.data.groupPath or strfind(self.st.rowData[i].groupPath, "^" .. TSMAPI:StrEscape(self.data.groupPath) .. TSM.GROUP_SEP) then
|
||||
self.st.selectedGroups[self.st.rowData[i].groupPath] = self.data.isSelected or false
|
||||
self.st.rowData[i].isSelected = self.data.isSelected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.st:RefreshRows()
|
||||
if self.data.isSelected then
|
||||
self.highlight:Show()
|
||||
else
|
||||
self.highlight:Hide()
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
function TSMAPI:CreateGroupTree(parent, module, label, isGroupBox)
|
||||
assert(type(parent) == "table", format(L["Invalid parent argument type. Expected table, got %s."], type(parent)))
|
||||
|
||||
local name = "TSMGroupTree" .. COUNT
|
||||
COUNT = COUNT + 1
|
||||
local st = CreateFrame("Frame", name, parent)
|
||||
st:SetAllPoints()
|
||||
st:SetScript("OnShow", UpdateTree)
|
||||
st.NUM_ROWS = floor((parent:GetHeight() - (isGroupBox and 0 or 20)) / ROW_HEIGHT)
|
||||
st.isGroupBox = isGroupBox
|
||||
st.groupBoxSelection = nil
|
||||
st.module = module
|
||||
if label or module then
|
||||
label = label or module
|
||||
if not TSM.db.profile.groupTreeSelectedGroupStatus[label] then
|
||||
TSMAPI:CreateTimeDelay(0, function() SelectAll({st=st}) end)
|
||||
end
|
||||
TSM.db.profile.groupTreeCollapsedStatus[label] = TSM.db.profile.groupTreeCollapsedStatus[label] or {}
|
||||
TSM.db.profile.groupTreeSelectedGroupStatus[label] = TSM.db.profile.groupTreeSelectedGroupStatus[label] or {}
|
||||
st.collapsed = TSM.db.profile.groupTreeCollapsedStatus[label]
|
||||
st.selectedGroups = TSM.db.profile.groupTreeSelectedGroupStatus[label]
|
||||
else
|
||||
st.collapsed = {}
|
||||
st.selectedGroups = {}
|
||||
end
|
||||
|
||||
local contentFrame = CreateFrame("Frame", name .. "Content", st)
|
||||
contentFrame:SetPoint("TOPLEFT")
|
||||
contentFrame:SetPoint("BOTTOMRIGHT", -15, isGroupBox and 0 or 18)
|
||||
st.contentFrame = contentFrame
|
||||
|
||||
if not isGroupBox then
|
||||
local btn = TSMAPI.GUI:CreateButton(st, 14)
|
||||
btn:SetPoint("BOTTOMLEFT", 0, 2)
|
||||
btn:SetPoint("BOTTOMRIGHT", st, "BOTTOM", -2, 2)
|
||||
btn:SetHeight(16)
|
||||
btn:SetText(L["Select All Groups"])
|
||||
btn:SetScript("OnClick", SelectAll)
|
||||
btn.st = st
|
||||
|
||||
local btn = TSMAPI.GUI:CreateButton(st, 14)
|
||||
btn:SetPoint("BOTTOMLEFT", st, "BOTTOM", 2, 2)
|
||||
btn:SetPoint("BOTTOMRIGHT", 0, 2)
|
||||
btn:SetHeight(16)
|
||||
btn:SetText(L["Deselect All Groups"])
|
||||
btn:SetScript("OnClick", DeselectAll)
|
||||
btn.st = st
|
||||
end
|
||||
|
||||
-- frame to hold the rows
|
||||
local scrollFrame = CreateFrame("ScrollFrame", name .. "ScrollFrame", st, "FauxScrollFrameTemplate")
|
||||
scrollFrame:SetScript("OnVerticalScroll", function(self, offset)
|
||||
FauxScrollFrame_OnVerticalScroll(self, offset, ROW_HEIGHT, function() st:RefreshRows() end)
|
||||
end)
|
||||
scrollFrame:SetAllPoints(contentFrame)
|
||||
st.scrollFrame = scrollFrame
|
||||
|
||||
-- make the scroll bar consistent with the TSM theme
|
||||
local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
|
||||
scrollBar:ClearAllPoints()
|
||||
scrollBar:SetPoint("BOTTOMRIGHT", st, -1, isGroupBox and 1 or 19)
|
||||
scrollBar:SetPoint("TOPRIGHT", st, -1, -1)
|
||||
scrollBar:SetWidth(12)
|
||||
local thumbTex = scrollBar:GetThumbTexture()
|
||||
thumbTex:SetPoint("CENTER")
|
||||
TSMAPI.Design:SetContentColor(thumbTex)
|
||||
thumbTex:SetHeight(50)
|
||||
thumbTex:SetWidth(scrollBar:GetWidth())
|
||||
_G[scrollBar:GetName() .. "ScrollUpButton"]:Hide()
|
||||
_G[scrollBar:GetName() .. "ScrollDownButton"]:Hide()
|
||||
|
||||
local text = st:CreateFontString()
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
text:SetJustifyH("CENTER")
|
||||
text:SetJustifyV("CENTER")
|
||||
text:SetPoint("LEFT", 5, 0)
|
||||
text:SetPoint("RIGHT", -5, 0)
|
||||
text:SetHeight(100)
|
||||
text:SetNonSpaceWrap(true)
|
||||
st.statusText = text
|
||||
|
||||
-- create the rows
|
||||
st.rows = {}
|
||||
for i = 1, st.NUM_ROWS do
|
||||
local row = CreateFrame("Button", name .. "Row" .. i, st.contentFrame)
|
||||
row:SetHeight(ROW_HEIGHT)
|
||||
row:RegisterForClicks("AnyUp")
|
||||
if i == 1 then
|
||||
row:SetPoint("TOPLEFT")
|
||||
row:SetPoint("TOPRIGHT")
|
||||
else
|
||||
row:SetPoint("TOPLEFT", st.rows[i - 1], "BOTTOMLEFT")
|
||||
row:SetPoint("TOPRIGHT", st.rows[i - 1], "BOTTOMRIGHT")
|
||||
end
|
||||
local highlight = row:CreateTexture()
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetTexture(1, .9, 0, .2)
|
||||
highlight:Hide()
|
||||
row.highlight = highlight
|
||||
local text = row:CreateFontString()
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("medium"))
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetJustifyV("CENTER")
|
||||
text:SetPoint("TOPLEFT", 1, -1)
|
||||
text:SetPoint("BOTTOMRIGHT", -1, 1)
|
||||
row:SetFontString(text)
|
||||
for name, func in pairs(defaultColScripts) do
|
||||
row:SetScript(name, func)
|
||||
end
|
||||
row.st = st
|
||||
tinsert(st.rows, row)
|
||||
end
|
||||
|
||||
for name, func in pairs(methods) do
|
||||
st[name] = func
|
||||
end
|
||||
|
||||
UpdateTree(st)
|
||||
|
||||
return st
|
||||
end
|
||||
@@ -0,0 +1,338 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- This module holds some GUI helper functions for modules to use.
|
||||
|
||||
local TSM = select(2, ...)
|
||||
local private = {}
|
||||
TSMAPI:RegisterForTracing(private, "TradeSkillMaster.Gui_private")
|
||||
private.frames = {}
|
||||
|
||||
TSMAPI.GUI = {}
|
||||
|
||||
|
||||
-- Tooltips!
|
||||
local function ShowTooltip(self)
|
||||
if self.link then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
|
||||
TSMAPI:SafeTooltipLink(self.link)
|
||||
GameTooltip:Show()
|
||||
elseif type(self.tooltip) == "function" then
|
||||
local text = self.tooltip(self)
|
||||
if type(text) == "string" then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOP")
|
||||
--GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
|
||||
GameTooltip:SetText(text, 1, 1, 1, 1, true)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
elseif self.tooltip then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOP")
|
||||
--GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
|
||||
GameTooltip:SetText(self.tooltip, 1, 1, 1, 1, true)
|
||||
GameTooltip:Show()
|
||||
elseif self.frame.tooltip then
|
||||
GameTooltip:SetOwner(self.frame, "ANCHOR_TOP")
|
||||
--GameTooltip:SetOwner(self.frame, "ANCHOR_BOTTOMRIGHT")
|
||||
GameTooltip:SetText(self.frame.tooltip, 1, 1, 1, 1, true)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local function HideTooltip()
|
||||
-- BattlePetTooltip:Hide()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateButton(parent, textHeight, name, isSecure)
|
||||
local btn = CreateFrame("Button", name, parent, isSecure and "SecureActionButtonTemplate")
|
||||
TSMAPI.Design:SetContentColor(btn)
|
||||
local highlight = btn:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetTexture(1, 1, 1, .2)
|
||||
highlight:SetBlendMode("BLEND")
|
||||
btn.highlight = highlight
|
||||
btn:SetScript("OnEnter", function(self) if self.tooltip then ShowTooltip(self) end end)
|
||||
btn:SetScript("OnLeave", HideTooltip)
|
||||
btn:Show()
|
||||
local label = btn:CreateFontString()
|
||||
label:SetFont(TSMAPI.Design:GetContentFont(), textHeight)
|
||||
label:SetPoint("CENTER")
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetHeight(textHeight)
|
||||
TSMAPI.Design:SetWidgetTextColor(label)
|
||||
btn:SetFontString(label)
|
||||
TSM:Hook(btn, "Enable", function() TSMAPI.Design:SetWidgetTextColor(label) end, true)
|
||||
TSM:Hook(btn, "Disable", function() TSMAPI.Design:SetWidgetTextColor(label, true) end, true)
|
||||
return btn
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateHorizontalLine(parent, ofsy, relativeFrame, invertedColor)
|
||||
relativeFrame = relativeFrame or parent
|
||||
local barTex = parent:CreateTexture()
|
||||
barTex:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", 2, ofsy)
|
||||
barTex:SetPoint("TOPRIGHT", relativeFrame, "TOPRIGHT", -2, ofsy)
|
||||
barTex:SetHeight(2)
|
||||
if invertedColor then
|
||||
TSMAPI.Design:SetFrameColor(barTex)
|
||||
else
|
||||
TSMAPI.Design:SetContentColor(barTex)
|
||||
end
|
||||
return barTex
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateVerticalLine(parent, ofsx, relativeFrame, invertedColor)
|
||||
relativeFrame = relativeFrame or parent
|
||||
local barTex = parent:CreateTexture()
|
||||
barTex:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", ofsx, -2)
|
||||
barTex:SetPoint("BOTTOMLEFT", relativeFrame, "BOTTOMLEFT", ofsx, 2)
|
||||
barTex:SetWidth(2)
|
||||
if invertedColor then
|
||||
TSMAPI.Design:SetFrameColor(barTex)
|
||||
else
|
||||
TSMAPI.Design:SetContentColor(barTex)
|
||||
end
|
||||
return barTex
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateInputBox(parent, name, autoComplete)
|
||||
local function OnEscapePressed(self)
|
||||
self:ClearFocus()
|
||||
self:HighlightText(0, 0)
|
||||
end
|
||||
|
||||
local eb = CreateFrame("EditBox", name, parent)
|
||||
eb:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
eb:SetShadowColor(0, 0, 0, 0)
|
||||
TSMAPI.Design:SetContentColor(eb)
|
||||
eb:SetAutoFocus(false)
|
||||
eb:SetScript("OnEscapePressed", function(self) self:ClearFocus() self:HighlightText(0, 0) end)
|
||||
eb:SetScript("OnEnter", function(self) if self.tooltip then ShowTooltip(self) end end)
|
||||
eb:SetScript("OnLeave", HideTooltip)
|
||||
return eb
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:SetAutoComplete(inputBox, params)
|
||||
local autoCompleteHandlers = {"OnTabPressed", "OnEnterPressed", "OnTextChanged", "OnChar", "OnEditFocusLost", "OnEscapePressed"}--, "OnArrowPressed"}
|
||||
if params then
|
||||
if inputBox._priorTSMHandlers then return end -- already done
|
||||
inputBox.autoCompleteParams = params
|
||||
inputBox._priorTSMHandlers = {}
|
||||
for _, name in ipairs(autoCompleteHandlers) do
|
||||
inputBox._priorTSMHandlers[name] = inputBox:GetScript(name)
|
||||
inputBox:SetScript(name, function(self, ...) return _G["AutoCompleteEditBox_"..name](self, ...) or (self._priorTSMHandlers[name] and self._priorTSMHandlers[name](self, ...)) end)
|
||||
end
|
||||
else
|
||||
if not inputBox._priorTSMHandlers then return end -- already done
|
||||
for _, name in ipairs(autoCompleteHandlers) do
|
||||
inputBox:SetScript(name, inputBox._priorTSMHandlers[name])
|
||||
end
|
||||
inputBox._priorTSMHandlers = nil
|
||||
end
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateLabel(parent, size)
|
||||
local label = parent:CreateFontString()
|
||||
label:SetFont(TSMAPI.Design:GetContentFont(size))
|
||||
TSMAPI.Design:SetWidgetLabelColor(label)
|
||||
return label
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateTitleLabel(parent, size)
|
||||
local label = parent:CreateFontString()
|
||||
label:SetFont(TSMAPI.Design:GetBoldFont(), size)
|
||||
TSMAPI.Design:SetTitleTextColor(label)
|
||||
return label
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateStatusBar(parent, baseName)
|
||||
local function UpdateStatus(self, majorStatus, minorStatus)
|
||||
if majorStatus then
|
||||
self.majorStatusBar:SetValue(majorStatus)
|
||||
if majorStatus == 100 then
|
||||
self.majorStatusBar.ag:Stop()
|
||||
elseif not self.majorStatusBar.ag:IsPlaying() then
|
||||
self.majorStatusBar.ag:Play()
|
||||
end
|
||||
end
|
||||
if minorStatus then
|
||||
self.minorStatusBar:SetValue(minorStatus)
|
||||
if minorStatus == 100 then
|
||||
self.minorStatusBar.ag:Stop()
|
||||
elseif not self.minorStatusBar.ag:IsPlaying() then
|
||||
self.minorStatusBar.ag:Play()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function SetStatusText(self, text)
|
||||
self.text:SetText(text)
|
||||
end
|
||||
|
||||
local level = parent:GetFrameLevel()
|
||||
local frame = CreateFrame("Frame", nil, parent)
|
||||
frame:SetHeight(25)
|
||||
frame:SetPoint("TOPLEFT", 2, -3)
|
||||
frame:SetPoint("TOPRIGHT", -2, -3)
|
||||
frame:SetFrameLevel(level+1)
|
||||
frame.UpdateStatus = UpdateStatus
|
||||
frame.SetStatusText = SetStatusText
|
||||
|
||||
-- minor status bar (gray one)
|
||||
local statusBar = CreateFrame("STATUSBAR", baseName.."-Minor", frame, "TextStatusBar")
|
||||
statusBar:SetOrientation("HORIZONTAL")
|
||||
statusBar:SetMinMaxValues(0, 100)
|
||||
statusBar:SetAllPoints()
|
||||
statusBar:SetStatusBarTexture("Interface\\Buttons\\WHITE8X8")
|
||||
statusBar:SetStatusBarColor(.42, .42, .42, .7)
|
||||
statusBar:SetFrameLevel(level+2)
|
||||
local ag = statusBar:CreateAnimationGroup()
|
||||
local alpha = ag:CreateAnimation("Alpha")
|
||||
alpha:SetDuration(1)
|
||||
alpha:SetChange(-.5)
|
||||
ag:SetLooping("Bounce")
|
||||
statusBar.ag = ag
|
||||
frame.minorStatusBar = statusBar
|
||||
|
||||
-- major status bar (main blue one)
|
||||
local statusBar = CreateFrame("STATUSBAR", baseName.."-Major", frame, "TextStatusBar")
|
||||
statusBar:SetOrientation("HORIZONTAL")
|
||||
statusBar:SetMinMaxValues(0, 100)
|
||||
statusBar:SetAllPoints()
|
||||
statusBar:SetStatusBarTexture("Interface\\Buttons\\WHITE8X8")
|
||||
statusBar:SetStatusBarColor(.19, .22, .33, .9)
|
||||
statusBar:SetFrameLevel(level+3)
|
||||
local ag = statusBar:CreateAnimationGroup()
|
||||
local alpha = ag:CreateAnimation("Alpha")
|
||||
alpha:SetDuration(1)
|
||||
alpha:SetChange(-.5)
|
||||
ag:SetLooping("Bounce")
|
||||
statusBar.ag = ag
|
||||
frame.majorStatusBar = statusBar
|
||||
|
||||
local textFrame = CreateFrame("Frame", nil, frame)
|
||||
textFrame:SetFrameLevel(level+4)
|
||||
textFrame:SetAllPoints(frame)
|
||||
-- Text for the StatusBar
|
||||
local text = TSMAPI.GUI:CreateLabel(textFrame)
|
||||
TSMAPI.Design:SetWidgetTextColor(text)
|
||||
text:SetPoint("CENTER")
|
||||
frame.text = text
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateDropdown(parent, list, tooltip)
|
||||
local dd = LibStub("AceGUI-3.0"):Create("TSMDropdown")
|
||||
dd:SetDisabled()
|
||||
dd:SetMultiselect(false)
|
||||
dd:SetList(list)
|
||||
dd.frame:SetParent(parent)
|
||||
dd.frame:Show()
|
||||
dd.frame.tooltip = tooltip
|
||||
dd:SetCallback("OnEnter", ShowTooltip)
|
||||
dd:SetCallback("OnLeave", HideTooltip)
|
||||
return dd
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateCheckBox(parent, tooltip)
|
||||
local cb = LibStub("AceGUI-3.0"):Create("TSMCheckBox")
|
||||
cb.frame:SetParent(parent)
|
||||
cb.frame:Show()
|
||||
cb.frame.tooltip = tooltip
|
||||
cb:SetCallback("OnEnter", ShowTooltip)
|
||||
cb:SetCallback("OnLeave", HideTooltip)
|
||||
return cb
|
||||
end
|
||||
|
||||
function TSMAPI.GUI:CreateItemLinkLabel(parent, textHeight)
|
||||
local btn = CreateFrame("Button", nil, parent)
|
||||
btn:SetScript("OnEnter", function(self) if self.link then ShowTooltip(self) end end)
|
||||
btn:SetScript("OnLeave", HideTooltip)
|
||||
btn:SetScript("OnClick", function(self) if self.link then HandleModifiedItemClick(self.link) end end)
|
||||
btn:SetHeight(textHeight)
|
||||
btn:Show()
|
||||
local text = btn:CreateFontString()
|
||||
text:SetFont(TSMAPI.Design:GetContentFont(), textHeight)
|
||||
text:SetPoint("TOPLEFT")
|
||||
text:SetPoint("BOTTOMLEFT")
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetJustifyV("CENTER")
|
||||
btn:SetFontString(text)
|
||||
return btn
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Registers a movable/resizable frame which TSM will keep track of and persistently store its position / size.
|
||||
-- The frame must be named for this function to work.
|
||||
-- Required defaults
|
||||
-- x - x position
|
||||
-- y - y position
|
||||
-- width - width
|
||||
-- height - height
|
||||
-- scale - scale
|
||||
function TSMAPI:CreateMovableFrame(name, defaults, parent)
|
||||
local options = TSM.db.global.frameStatus[name] or CopyTable(defaults)
|
||||
options.defaults = defaults
|
||||
TSM.db.global.frameStatus[name] = options
|
||||
options.hasLoaded = nil
|
||||
|
||||
local frame = CreateFrame("Frame", name, parent)
|
||||
frame:Hide()
|
||||
frame:SetHeight(options.height)
|
||||
frame:SetWidth(options.width)
|
||||
frame:SetScale(UIParent:GetScale()*options.scale)
|
||||
frame:SetPoint("CENTER", frame:GetParent())
|
||||
frame:SetToplevel(true)
|
||||
frame:EnableMouse(true)
|
||||
frame:SetMovable(true)
|
||||
frame:SetClampedToScreen(true)
|
||||
frame:SetClampRectInsets(options.width-50, -(options.width-50), -(options.height-50), options.height-50)
|
||||
frame.SavePositionAndSize = function(self)
|
||||
if not options.hasLoaded then return end
|
||||
options.width = self:GetWidth()
|
||||
options.height = self:GetHeight()
|
||||
options.x = self:GetLeft()
|
||||
options.y = self:GetBottom()
|
||||
self:SetClampRectInsets(options.width-50, -(options.width-50), -(options.height-50), options.height-50)
|
||||
end
|
||||
frame:SetScript("OnMouseDown", frame.StartMoving)
|
||||
frame:SetScript("OnMouseUp", function(self) self:StopMovingOrSizing() self:SavePositionAndSize() end)
|
||||
frame:SetScript("OnSizeChanged", frame.SavePositionAndSize)
|
||||
frame.RefreshPosition = function(self)
|
||||
options.hasLoaded = true
|
||||
self:SetScale(UIParent:GetScale()*options.scale)
|
||||
self:SetFrameLevel(0)
|
||||
self:ClearAllPoints()
|
||||
self:SetPoint("BOTTOMLEFT", UIParent, options.x, options.y)
|
||||
self:SetWidth(options.width)
|
||||
self:SetHeight(options.height)
|
||||
end
|
||||
frame:SetScript("OnShow", frame.RefreshPosition)
|
||||
frame.options = options
|
||||
tinsert(private.frames, frame)
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
function TSM:ResetFrames()
|
||||
for _, frame in ipairs(private.frames) do
|
||||
-- reset all fields to the default values without breaking any table references
|
||||
local options = TSM.db.global.frameStatus[frame:GetName()]
|
||||
options.hasLoaded = true
|
||||
local defaults = options.defaults
|
||||
for i, v in pairs(defaults) do options[i] = v end
|
||||
if frame and frame:IsVisible() then
|
||||
frame:RefreshPosition()
|
||||
end
|
||||
end
|
||||
|
||||
-- explicitly reset bankui since it can't easily use TSMAPI:CreateMovableFrame
|
||||
TSM:ResetBankUIFramePosition()
|
||||
end
|
||||
@@ -0,0 +1,140 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- This file contains all the APIs regarding TSM's main frame (what shows when you type '/tsm').
|
||||
|
||||
local TSM = select(2, ...)
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
||||
local AceGUI = LibStub("AceGUI-3.0") -- load the AceGUI libraries
|
||||
|
||||
local private = {icons={}, currentIcon=0}
|
||||
TSMAPI:RegisterForTracing(private, "TradeSkillMaster.MainFrame_private")
|
||||
local lib = TSMAPI
|
||||
|
||||
|
||||
--- Opens the main TSM window.
|
||||
function TSMAPI:OpenFrame()
|
||||
if not TSM.Frame then return end
|
||||
TSM.Frame:Show()
|
||||
if #TSM.Frame.children > 0 then
|
||||
TSM.Frame:ReleaseChildren()
|
||||
else
|
||||
TSMAPI:SelectIcon("TradeSkillMaster", L["TSM Status / Options"])
|
||||
end
|
||||
if TSM.db.global.infoMessage < 1001 then
|
||||
TSM.db.global.infoMessage = 1001
|
||||
StaticPopupDialogs["TSM_INFO_MESSAGE"] = StaticPopupDialogs["TSM_INFO_MESSAGE"] or {
|
||||
text = format(L["More advanced options are now designated by %sred text|r. Beginners are encourages to come back to these once they have a solid understanding of the basics."], TSMAPI.Design:GetInlineColor("advanced")),
|
||||
button1 = OKAY,
|
||||
OnAccept = function()
|
||||
TSM:Printf(L["More advanced options are now designated by %sred text|r. Beginners are encourages to come back to these once they have a solid understanding of the basics."], TSMAPI.Design:GetInlineColor("advanced"))
|
||||
end,
|
||||
timeout = 0,
|
||||
preferredIndex = 3,
|
||||
}
|
||||
TSMAPI:ShowStaticPopupDialog("TSM_INFO_MESSAGE")
|
||||
end
|
||||
end
|
||||
|
||||
--- Closes the main TSM window.
|
||||
function TSMAPI:CloseFrame()
|
||||
TSM.Frame:Hide()
|
||||
end
|
||||
|
||||
function TSM:RegisterMainFrameIcon(displayName, icon, loadGUI, moduleName, side)
|
||||
if not (displayName and icon and loadGUI and moduleName) then
|
||||
return nil, "invalid args", displayName, icon, loadGUI, moduleName
|
||||
end
|
||||
|
||||
if side and not (side == "module" or side == "options") then
|
||||
return nil, "invalid side", side
|
||||
end
|
||||
|
||||
local icon = {name=displayName, moduleName=moduleName, icon=icon, loadGUI=loadGUI, side=(strlower(side or "module"))}
|
||||
if TSM.Frame then
|
||||
icon.texture = icon.icon
|
||||
if icon.side == "options" then
|
||||
icon.where = "topLeft"
|
||||
else
|
||||
icon.where = "topRight"
|
||||
end
|
||||
|
||||
TSM.Frame:AddIcon(icon)
|
||||
end
|
||||
|
||||
tinsert(private.icons, icon)
|
||||
end
|
||||
|
||||
--- Selects an icon in the main TSM window once it's open.
|
||||
-- @param moduleName Which module the icon belongs to (unlocalized).
|
||||
-- @param iconName The text that shows in the tooltip of the icon to be clicked (localized).
|
||||
-- @return Returns an error message as the second return value upon error.
|
||||
function TSMAPI:SelectIcon(moduleName, iconName)
|
||||
if not moduleName then return nil, "no moduleName passed" end
|
||||
|
||||
for _, data in ipairs(private.icons) do
|
||||
if data.moduleName == moduleName and data.name == iconName then
|
||||
data.frame:Click()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TSMAPI:ShowOperationOptions(moduleName, operation, groupPath)
|
||||
TSMAPI:OpenFrame()
|
||||
TSM.loadModuleOptionsTab = {module=moduleName, operation=operation, group=groupPath}
|
||||
TSMAPI:SelectIcon("TradeSkillMaster", L["Module Operations / Options"])
|
||||
TSM.loadModuleOptionsTab = nil
|
||||
end
|
||||
|
||||
|
||||
function TSM:CreateMainFrame()
|
||||
local mainFrame = AceGUI:Create("TSMMainFrame")
|
||||
local version = TSM._version
|
||||
mainFrame:SetIconText(version)
|
||||
mainFrame:SetIconLabels(L["Options"], L["Modules"])
|
||||
mainFrame:SetLayout("Fill")
|
||||
|
||||
for _, icon in ipairs(private.icons) do
|
||||
icon.texture = icon.icon
|
||||
if icon.side == "crafting" then
|
||||
icon.where = "bottom"
|
||||
elseif icon.side == "options" then
|
||||
icon.where = "topLeft"
|
||||
else
|
||||
icon.where = "topRight"
|
||||
end
|
||||
|
||||
mainFrame:AddIcon(icon)
|
||||
end
|
||||
TSM.Frame = mainFrame
|
||||
|
||||
TSMAPI:CreateTimeDelay("mainFrameSize", .5, function() mainFrame:SetWidth(mainFrame.frame.options.width) mainFrame:SetHeight(mainFrame.frame.options.height) end)
|
||||
end
|
||||
|
||||
|
||||
function TSM:TSMFrameIsVisible()
|
||||
return TSM.Frame and TSM.Frame:IsVisible()
|
||||
end
|
||||
|
||||
function private:FramePathHelper(frame, path)
|
||||
if not frame.children or not frame.children[1] then return end
|
||||
frame = frame.children[1]
|
||||
if frame.type == "TSMTreeGroup" then
|
||||
tinsert(path, {type="TreeGroup", value={("\001"):split(frame.status.selected)}})
|
||||
elseif frame.type == "TSMTabGroup" then
|
||||
tinsert(path, {type="TabGroup", value=frame.localstatus.selected})
|
||||
end
|
||||
return private:FramePathHelper(frame, path)
|
||||
end
|
||||
function TSM:GetTSMFrameSelectionPath()
|
||||
if not TSM:TSMFrameIsVisible() then return end
|
||||
local path = {}
|
||||
tinsert(path, {type="Icon", value=TSM.Frame.selected.info.name})
|
||||
private:FramePathHelper(TSM.Frame, path)
|
||||
return path
|
||||
end
|
||||
@@ -0,0 +1,390 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local TSM = select(2, ...)
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
||||
|
||||
local RT_COUNT = 1
|
||||
|
||||
local HEAD_HEIGHT = 27
|
||||
local HEAD_SPACE = 4
|
||||
|
||||
|
||||
local function OnSizeChanged(st, width, height)
|
||||
width = width - 14
|
||||
if st.headCols then
|
||||
-- adjust head col widths
|
||||
for i, col in ipairs(st.headCols) do
|
||||
col:SetWidth(col.info.width*width)
|
||||
end
|
||||
end
|
||||
|
||||
-- calculate new number of rows
|
||||
st.NUM_ROWS = max(floor((height-st.HEAD_HEIGHT-HEAD_SPACE)/st.ROW_HEIGHT), 0)
|
||||
|
||||
-- hide all extra rows and clear their data
|
||||
for i=st.NUM_ROWS+1, #st.rows do
|
||||
st.rows[i]:Hide()
|
||||
st.rows[i].data = nil
|
||||
end
|
||||
|
||||
while #st.rows < st.NUM_ROWS do
|
||||
st:AddRow()
|
||||
end
|
||||
|
||||
-- adjust rows widths
|
||||
for _, row in ipairs(st.rows) do
|
||||
for i, col in ipairs(row.cols) do
|
||||
if st.headCols then
|
||||
col:SetWidth(st.headCols[i].info.width*width)
|
||||
else
|
||||
col:SetWidth(width)
|
||||
end
|
||||
if col.text.fontHeight < 13 then
|
||||
col.text:SetFont(TSMAPI.Design:GetContentFont(), 13)
|
||||
col.text.fontHeight = 13
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
st:RefreshRows()
|
||||
end
|
||||
|
||||
local function GetTableIndex(tbl, value)
|
||||
for i, v in pairs(tbl) do
|
||||
if value == v then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function OnColumnClick(self, button, ...)
|
||||
if self.st.sortInfo.enabled and button == "LeftButton" then
|
||||
if self.st.sortInfo.col == self.colNum then
|
||||
self.st.sortInfo.ascending = not self.st.sortInfo.ascending
|
||||
else
|
||||
self.st.sortInfo.col = self.colNum
|
||||
self.st.sortInfo.ascending = true
|
||||
end
|
||||
self.st.updateSort = true
|
||||
self.st:RefreshRows()
|
||||
end
|
||||
if self.st.handlers.OnColumnClick then
|
||||
self.st.handlers.OnColumnClick(self, button, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local defaultColScripts = {
|
||||
OnEnter = function(self, ...)
|
||||
if not self.row.data then return end
|
||||
if not self.st.highlightDisabled then
|
||||
self.row.highlight:Show()
|
||||
end
|
||||
|
||||
local handler = self.st.handlers.OnEnter
|
||||
if handler then
|
||||
handler(self.st, self.row.data, self, ...)
|
||||
end
|
||||
end,
|
||||
|
||||
OnLeave = function(self, ...)
|
||||
if not self.row.data then return end
|
||||
if self.st.selectionDisabled or not self.st.selected or self.st.selected ~= GetTableIndex(self.st.rowData, self.row.data) then
|
||||
self.row.highlight:Hide()
|
||||
end
|
||||
|
||||
local handler = self.st.handlers.OnLeave
|
||||
if handler then
|
||||
handler(self.st, self.row.data, self, ...)
|
||||
end
|
||||
end,
|
||||
|
||||
OnClick = function(self, ...)
|
||||
if not self.row.data then return end
|
||||
self.st:ClearSelection()
|
||||
self.st.selected = GetTableIndex(self.st.rowData, self.row.data)
|
||||
self.row.highlight:Show()
|
||||
|
||||
local handler = self.st.handlers.OnClick
|
||||
if handler then
|
||||
handler(self.st, self.row.data, self, ...)
|
||||
end
|
||||
end,
|
||||
|
||||
OnDoubleClick = function(self, ...)
|
||||
if not self.row.data then return end
|
||||
local handler = self.st.handlers.OnDoubleClick
|
||||
if handler then
|
||||
handler(self.st, self.row.data, self, ...)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local methods = {
|
||||
RefreshRows = function(st)
|
||||
if not st.rowData then return end
|
||||
FauxScrollFrame_Update(st.scrollFrame, #st.rowData, st.NUM_ROWS, st.ROW_HEIGHT)
|
||||
local offset = FauxScrollFrame_GetOffset(st.scrollFrame)
|
||||
st.offset = offset
|
||||
|
||||
-- hide all rows and clear their data
|
||||
for i=1, st.NUM_ROWS do
|
||||
st.rows[i]:Hide()
|
||||
st.rows[i].data = nil
|
||||
end
|
||||
|
||||
-- do sorting if enabled
|
||||
if st.sortInfo.enabled and st.sortInfo.col and st.updateSort then
|
||||
local function SortHelper(rowA, rowB)
|
||||
local sortArgA = rowA.cols[st.sortInfo.col].sortArg
|
||||
local sortArgB = rowB.cols[st.sortInfo.col].sortArg
|
||||
|
||||
if st.sortInfo.ascending then
|
||||
return sortArgA < sortArgB
|
||||
else
|
||||
return sortArgA > sortArgB
|
||||
end
|
||||
end
|
||||
sort(st.rowData, SortHelper)
|
||||
st.updateSort = nil
|
||||
end
|
||||
|
||||
-- set row data
|
||||
for i=1, min(st.NUM_ROWS, #st.rowData) do
|
||||
st.rows[i]:Show()
|
||||
local data = st.rowData[i+offset]
|
||||
if not data then break end
|
||||
st.rows[i].data = data
|
||||
|
||||
if (st.selected == GetTableIndex(st.rowData, data) and not st.selectionDisabled) or st.rows[i]:IsMouseOver() or (st.highlighted and st.highlighted == GetTableIndex(st.rowData, data)) then
|
||||
st.rows[i].highlight:Show()
|
||||
else
|
||||
st.rows[i].highlight:Hide()
|
||||
end
|
||||
|
||||
for j, col in ipairs(st.rows[i].cols) do
|
||||
local colData = data.cols[j]
|
||||
if type(colData.value) == "function" then
|
||||
col:SetText(colData.value(unpack(colData.args)))
|
||||
else
|
||||
col:SetText(colData.value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
SetData = function(st, rowData)
|
||||
st.rowData = rowData
|
||||
st.updateSort = true
|
||||
st:RefreshRows()
|
||||
end,
|
||||
|
||||
SetSelection = function(st, rowNum)
|
||||
st.selected = rowNum
|
||||
st:RefreshRows()
|
||||
end,
|
||||
|
||||
GetSelection = function(st)
|
||||
return st.selected
|
||||
end,
|
||||
|
||||
ClearSelection = function(st)
|
||||
st.selected = nil
|
||||
st:RefreshRows()
|
||||
end,
|
||||
|
||||
DisableSelection = function(st, value)
|
||||
st.selectionDisabled = value
|
||||
end,
|
||||
|
||||
EnableSorting = function(st, value, defaultCol)
|
||||
st.sortInfo.enabled = value
|
||||
st.sortInfo.col = abs(defaultCol or 1)
|
||||
st.sortInfo.ascending = not defaultCol or defaultCol > 0
|
||||
st.updateSort = true
|
||||
st:RefreshRows()
|
||||
end,
|
||||
|
||||
DisableHighlight = function(st, value)
|
||||
st.highlightDisabled = value
|
||||
end,
|
||||
|
||||
SetScrollOffset = function(st, offset)
|
||||
local maxOffset = max(#st.rowData - st.NUM_ROWS, 0)
|
||||
if not offset or offset < 0 or offset > maxOffset then
|
||||
return -- invalid offset
|
||||
end
|
||||
|
||||
local scrollPercent = offset / maxOffset
|
||||
local maxPixelOffset = st.scrollFrame:GetVerticalScrollRange() + st.ROW_HEIGHT * 2
|
||||
local pixelOffset = scrollPercent * maxPixelOffset
|
||||
FauxScrollFrame_SetOffset(st.scrollFrame, offset)
|
||||
st.scrollFrame:SetVerticalScroll(pixelOffset)
|
||||
end,
|
||||
|
||||
SetHighlighted = function(st, row)
|
||||
st.highlighted = row
|
||||
st:RefreshRows()
|
||||
end,
|
||||
|
||||
AddRow = function(st)
|
||||
local row = CreateFrame("Frame", nil, st.contentFrame)
|
||||
row:SetHeight(st.ROW_HEIGHT)
|
||||
if #st.rows == 0 then
|
||||
row:SetPoint("TOPLEFT", 0, -(st.HEAD_HEIGHT+HEAD_SPACE))
|
||||
row:SetPoint("TOPRIGHT", 0, -(st.HEAD_HEIGHT+HEAD_SPACE))
|
||||
else
|
||||
row:SetPoint("TOPLEFT", st.rows[#st.rows], "BOTTOMLEFT")
|
||||
row:SetPoint("TOPRIGHT", st.rows[#st.rows], "BOTTOMRIGHT")
|
||||
end
|
||||
local highlight = row:CreateTexture()
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetTexture(1, .9, 0, .2)
|
||||
highlight:Hide()
|
||||
row.highlight = highlight
|
||||
row.st = st
|
||||
|
||||
row.cols = {}
|
||||
for j, info in ipairs(st.colInfo or {{}}) do
|
||||
local col = CreateFrame("Button", nil, row)
|
||||
local text = col:CreateFontString()
|
||||
text:SetFont(TSMAPI.Design:GetContentFont(), min(13, st.ROW_HEIGHT))
|
||||
text:SetJustifyH(info.align or "LEFT")
|
||||
text:SetJustifyV("CENTER")
|
||||
text:SetPoint("TOPLEFT", 1, -1)
|
||||
text:SetPoint("BOTTOMRIGHT", -1, 1)
|
||||
text.fontHeight = min(13, st.ROW_HEIGHT)
|
||||
col.text = text
|
||||
col:SetFontString(text)
|
||||
col:SetHeight(st.ROW_HEIGHT)
|
||||
col:RegisterForClicks("AnyUp")
|
||||
for name, func in pairs(defaultColScripts) do
|
||||
col:SetScript(name, func)
|
||||
end
|
||||
col.st = st
|
||||
col.row = row
|
||||
|
||||
if j == 1 then
|
||||
col:SetPoint("TOPLEFT")
|
||||
else
|
||||
col:SetPoint("TOPLEFT", row.cols[j-1], "TOPRIGHT")
|
||||
end
|
||||
tinsert(row.cols, col)
|
||||
end
|
||||
|
||||
tinsert(st.rows, row)
|
||||
end,
|
||||
}
|
||||
|
||||
function TSMAPI:CreateScrollingTable(parent, colInfo, handlers, headFontSize)
|
||||
assert(type(parent) == "table", format("Invalid parent argument. Type is %s.", type(parent)))
|
||||
|
||||
local rtName = "TSMScrollingTable"..RT_COUNT
|
||||
RT_COUNT = RT_COUNT + 1
|
||||
local st = CreateFrame("Frame", rtName, parent)
|
||||
if not colInfo then
|
||||
st.HEAD_HEIGHT = -HEAD_SPACE
|
||||
elseif headFontSize then
|
||||
st.HEAD_HEIGHT = headFontSize + 4
|
||||
else
|
||||
st.HEAD_HEIGHT = HEAD_HEIGHT
|
||||
end
|
||||
st.ROW_HEIGHT = 15
|
||||
st.NUM_ROWS = floor((parent:GetHeight()-st.HEAD_HEIGHT-HEAD_SPACE)/st.ROW_HEIGHT)
|
||||
st.colInfo = colInfo
|
||||
st:SetScript("OnSizeChanged", OnSizeChanged)
|
||||
|
||||
local contentFrame = CreateFrame("Frame", rtName.."Content", st)
|
||||
contentFrame:SetPoint("TOPLEFT")
|
||||
contentFrame:SetPoint("BOTTOMRIGHT", -15, 0)
|
||||
st.contentFrame = contentFrame
|
||||
|
||||
-- frame to hold the header columns and the rows
|
||||
local scrollFrame = CreateFrame("ScrollFrame", rtName.."ScrollFrame", st, "FauxScrollFrameTemplate")
|
||||
scrollFrame:SetScript("OnVerticalScroll", function(self, offset)
|
||||
FauxScrollFrame_OnVerticalScroll(self, offset, st.ROW_HEIGHT, function() st:RefreshRows() end)
|
||||
end)
|
||||
scrollFrame:SetAllPoints(contentFrame)
|
||||
st.scrollFrame = scrollFrame
|
||||
|
||||
-- make the scroll bar consistent with the TSM theme
|
||||
local scrollBar = _G[scrollFrame:GetName().."ScrollBar"]
|
||||
scrollBar:ClearAllPoints()
|
||||
scrollBar:SetPoint("BOTTOMRIGHT", st, -1, 1)
|
||||
scrollBar:SetPoint("TOPRIGHT", st, -1, -st.HEAD_HEIGHT-HEAD_SPACE)
|
||||
scrollBar:SetWidth(12)
|
||||
local thumbTex = scrollBar:GetThumbTexture()
|
||||
thumbTex:SetPoint("CENTER")
|
||||
TSMAPI.Design:SetContentColor(thumbTex)
|
||||
thumbTex:SetHeight(50)
|
||||
thumbTex:SetWidth(scrollBar:GetWidth())
|
||||
_G[scrollBar:GetName().."ScrollUpButton"]:Hide()
|
||||
_G[scrollBar:GetName().."ScrollDownButton"]:Hide()
|
||||
|
||||
-- create the header columns
|
||||
if colInfo then
|
||||
st.headCols = {}
|
||||
for i, info in ipairs(colInfo) do
|
||||
local col = CreateFrame("Button", rtName.."HeadCol"..i, st.contentFrame)
|
||||
col:SetHeight(st.HEAD_HEIGHT)
|
||||
if i == 1 then
|
||||
col:SetPoint("TOPLEFT")
|
||||
else
|
||||
col:SetPoint("TOPLEFT", st.headCols[i-1], "TOPRIGHT")
|
||||
end
|
||||
col.info = info
|
||||
col.st = st
|
||||
col.colNum = i
|
||||
col:RegisterForClicks("AnyUp")
|
||||
col:SetScript("OnClick", OnColumnClick)
|
||||
|
||||
local text = col:CreateFontString()
|
||||
text:SetJustifyH(info.headAlign or "CENTER")
|
||||
text:SetJustifyV("CENTER")
|
||||
if headFontSize then
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"), headFontSize)
|
||||
else
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
end
|
||||
TSMAPI.Design:SetWidgetTextColor(text)
|
||||
col:SetFontString(text)
|
||||
col:SetText(info.name or "")
|
||||
text:SetAllPoints()
|
||||
|
||||
local tex = col:CreateTexture()
|
||||
tex:SetAllPoints()
|
||||
tex:SetTexture("Interface\\Buttons\\UI-Listbox-Highlight")
|
||||
tex:SetTexCoord(0.025, 0.957, 0.087, 0.931)
|
||||
tex:SetAlpha(0.2)
|
||||
col:SetHighlightTexture(tex)
|
||||
|
||||
tinsert(st.headCols, col)
|
||||
end
|
||||
|
||||
TSMAPI.GUI:CreateHorizontalLine(st, -st.HEAD_HEIGHT)
|
||||
end
|
||||
|
||||
-- set all methods
|
||||
for name, func in pairs(methods) do
|
||||
st[name] = func
|
||||
end
|
||||
|
||||
-- create the rows
|
||||
st.rows = {}
|
||||
for i=1, st.NUM_ROWS do
|
||||
st:AddRow()
|
||||
end
|
||||
|
||||
st:SetAllPoints()
|
||||
st.displayRows = {}
|
||||
st.handlers = handlers or {}
|
||||
st.sortInfo = {enabled=nil}
|
||||
|
||||
return st
|
||||
end
|
||||
@@ -0,0 +1,120 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Button.lua
|
||||
-- This Button widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMButton", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local _G = _G
|
||||
local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Button_OnClick(frame, ...)
|
||||
AceGUI:ClearFocus()
|
||||
PlaySound("igMainMenuOption")
|
||||
frame.obj:Fire("OnClick", ...)
|
||||
end
|
||||
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetHeight(24)
|
||||
self:SetWidth(200)
|
||||
self:SetDisabled(false)
|
||||
self:SetText()
|
||||
self.btn:GetFontString():SetTextColor(1, 1, 1, 1)
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.btn:SetText(text)
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.btn:Disable()
|
||||
self.btn:GetFontString():SetTextColor(1, 1, 1, 0.5)
|
||||
else
|
||||
self.btn:Enable()
|
||||
self.btn:GetFontString():SetTextColor(1, 1, 1, 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local name = "TSMButton" .. AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
local btn = CreateFrame("Button", name, frame)
|
||||
btn:Hide()
|
||||
btn:EnableMouse(true)
|
||||
btn:SetPoint("TOPLEFT", 0, -2)
|
||||
btn:SetPoint("BOTTOMRIGHT", 0, 2)
|
||||
TSMAPI.Design:SetContentColor(btn)
|
||||
local highlight = btn:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetTexture(1, 1, 1, .2)
|
||||
highlight:SetBlendMode("BLEND")
|
||||
btn.highlight = highlight
|
||||
btn:SetScript("OnClick", Button_OnClick)
|
||||
btn:SetScript("OnEnter", Control_OnEnter)
|
||||
btn:SetScript("OnLeave", Control_OnLeave)
|
||||
btn:Show()
|
||||
|
||||
local label = btn:CreateFontString()
|
||||
label:SetPoint("CENTER")
|
||||
label:SetHeight(15)
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
TSMAPI.Design:SetWidgetTextColor(label)
|
||||
btn:SetFontString(label)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
btn = btn,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
btn.obj = widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,181 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
|
||||
-- This CheckBox widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMCheckBox", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local select, pairs = select, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function CheckBox_OnMouseDown(frame)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
self.text:SetPoint("LEFT", self.btn, "RIGHT", 1, -1)
|
||||
end
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function CheckBox_OnMouseUp(frame, button)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
self.text:SetPoint("LEFT", self.btn, "RIGHT", 0, 0)
|
||||
self:ToggleChecked()
|
||||
|
||||
if self.checked then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
else
|
||||
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||
end
|
||||
|
||||
self:Fire("OnValueChanged", self.checked)
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetType()
|
||||
self:SetValue()
|
||||
self:SetWidth(200)
|
||||
self:SetDisabled()
|
||||
self:SetHeight(24)
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.text, disabled)
|
||||
if disabled then
|
||||
self.frame:Disable()
|
||||
local r, g, b = self.btn:GetBackdropColor()
|
||||
self.btn:SetBackdropColor(r, g, b, .5)
|
||||
SetDesaturation(self.check, true)
|
||||
else
|
||||
self.frame:Enable()
|
||||
local r, g, b = self.btn:GetBackdropColor()
|
||||
self.btn:SetBackdropColor(r, g, b, 1)
|
||||
SetDesaturation(self.check, false)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetValue"] = function(self,value)
|
||||
local check = self.check
|
||||
self.checked = value
|
||||
SetDesaturation(self.check, false)
|
||||
if value then
|
||||
self.check:Show()
|
||||
else
|
||||
self.check:Hide()
|
||||
end
|
||||
self:SetDisabled(self.disabled)
|
||||
end,
|
||||
|
||||
["GetValue"] = function(self)
|
||||
return self.checked
|
||||
end,
|
||||
|
||||
["SetType"] = function(self, type)
|
||||
local check = self.check
|
||||
|
||||
if type == "radio" then
|
||||
self.btn:SetWidth(10)
|
||||
self.btn:SetHeight(10)
|
||||
self.btn:SetPoint("TOPLEFT", 7, -7)
|
||||
self.check:SetPoint("TOPLEFT", -1, 5)
|
||||
else
|
||||
self.btn:SetWidth(16)
|
||||
self.btn:SetHeight(16)
|
||||
self.btn:SetPoint("TOPLEFT", 4, -4)
|
||||
self.check:SetPoint("TOPLEFT")
|
||||
end
|
||||
end,
|
||||
|
||||
["ToggleChecked"] = function(self)
|
||||
self:SetValue(not self:GetValue())
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, label)
|
||||
self.text:SetText(label)
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Button", nil, UIParent)
|
||||
frame:Hide()
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
frame:SetScript("OnMouseDown", CheckBox_OnMouseDown)
|
||||
frame:SetScript("OnMouseUp", CheckBox_OnMouseUp)
|
||||
|
||||
local btn = CreateFrame("Button", nil, frame)
|
||||
btn:EnableMouse(false)
|
||||
btn:SetWidth(16)
|
||||
btn:SetHeight(16)
|
||||
btn:SetPoint("TOPLEFT", 4, -4)
|
||||
TSMAPI.Design:SetContentColor(btn)
|
||||
local highlight = btn:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetTexture(1, 1, 1, .2)
|
||||
highlight:SetBlendMode("BLEND")
|
||||
|
||||
local check = btn:CreateTexture(nil, "OVERLAY")
|
||||
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
||||
check:SetTexCoord(.12, .88, .12, .88)
|
||||
check:SetBlendMode("BLEND")
|
||||
check:SetPoint("BOTTOMRIGHT")
|
||||
|
||||
local text = frame:CreateFontString(nil, "OVERLAY")
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetHeight(18)
|
||||
text:SetPoint("LEFT", btn, "RIGHT")
|
||||
text:SetPoint("RIGHT")
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
|
||||
local widget = {
|
||||
btn = btn,
|
||||
check = check,
|
||||
text = text,
|
||||
highlight = highlight,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
frame.obj = widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,187 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
|
||||
-- This ColorPicker widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMColorPicker", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: ShowUIPanel, HideUIPanel, ColorPickerFrame, OpacitySliderFrame
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function ColorCallback(self, r, g, b, a, isAlpha)
|
||||
if not self.HasAlpha then
|
||||
a = 1
|
||||
end
|
||||
self:SetColor(r, g, b, a)
|
||||
if ColorPickerFrame:IsVisible() then
|
||||
--colorpicker is still open
|
||||
self:Fire("OnValueChanged", r, g, b, a)
|
||||
else
|
||||
--colorpicker is closed, color callback is first, ignore it,
|
||||
--alpha callback is the final call after it closes so confirm now
|
||||
if isAlpha then
|
||||
self:Fire("OnValueConfirmed", r, g, b, a)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function ColorSwatch_OnClick(frame)
|
||||
HideUIPanel(ColorPickerFrame)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
ColorPickerFrame.func = function()
|
||||
local r, g, b = ColorPickerFrame:GetColorRGB()
|
||||
local a = 1 - OpacitySliderFrame:GetValue()
|
||||
ColorCallback(self, r, g, b, a)
|
||||
end
|
||||
|
||||
ColorPickerFrame.hasOpacity = self.HasAlpha
|
||||
ColorPickerFrame.opacityFunc = function()
|
||||
local r, g, b = ColorPickerFrame:GetColorRGB()
|
||||
local a = 1 - OpacitySliderFrame:GetValue()
|
||||
ColorCallback(self, r, g, b, a, true)
|
||||
end
|
||||
|
||||
local r, g, b, a = self.r, self.g, self.b, self.a
|
||||
if self.HasAlpha then
|
||||
ColorPickerFrame.opacity = 1 - (a or 0)
|
||||
end
|
||||
ColorPickerFrame:SetColorRGB(r, g, b)
|
||||
|
||||
ColorPickerFrame.cancelFunc = function()
|
||||
ColorCallback(self, r, g, b, a, true)
|
||||
end
|
||||
|
||||
ShowUIPanel(ColorPickerFrame)
|
||||
end
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetHeight(24)
|
||||
self:SetWidth(200)
|
||||
self:SetHasAlpha(false)
|
||||
self:SetColor(0, 0, 0, 1)
|
||||
self:SetDisabled(nil)
|
||||
self:SetLabel(nil)
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
self.text:SetText(text)
|
||||
end,
|
||||
|
||||
["SetColor"] = function(self, r, g, b, a)
|
||||
self.r = r
|
||||
self.g = g
|
||||
self.b = b
|
||||
self.a = a or 1
|
||||
self.colorSwatch:SetVertexColor(r, g, b, a)
|
||||
end,
|
||||
|
||||
["SetHasAlpha"] = function(self, HasAlpha)
|
||||
self.HasAlpha = HasAlpha
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.text, disabled)
|
||||
if self.disabled then
|
||||
self.frame:Disable()
|
||||
else
|
||||
self.frame:Enable()
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Button", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
frame:SetScript("OnClick", ColorSwatch_OnClick)
|
||||
|
||||
local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
|
||||
colorSwatch:SetWidth(19)
|
||||
colorSwatch:SetHeight(19)
|
||||
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
|
||||
colorSwatch:SetPoint("LEFT")
|
||||
|
||||
local texture = frame:CreateTexture(nil, "BACKGROUND")
|
||||
texture:SetWidth(16)
|
||||
texture:SetHeight(16)
|
||||
texture:SetTexture(1, 1, 1)
|
||||
texture:SetPoint("CENTER", colorSwatch)
|
||||
texture:Show()
|
||||
|
||||
local checkers = frame:CreateTexture(nil, "BACKGROUND")
|
||||
checkers:SetWidth(14)
|
||||
checkers:SetHeight(14)
|
||||
checkers:SetTexture("Tileset\\Generic\\Checkers")
|
||||
checkers:SetTexCoord(.25, 0, 0.5, .25)
|
||||
checkers:SetDesaturated(true)
|
||||
checkers:SetVertexColor(1, 1, 1, 0.75)
|
||||
checkers:SetPoint("CENTER", colorSwatch)
|
||||
checkers:Show()
|
||||
|
||||
local text = frame:CreateFontString(nil,"OVERLAY")
|
||||
text:SetHeight(24)
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetTextColor(1, 1, 1)
|
||||
text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
|
||||
text:SetPoint("RIGHT")
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
|
||||
local widget = {
|
||||
colorSwatch = colorSwatch,
|
||||
text = text,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,258 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Dropdown-Items.lua
|
||||
-- This Dropdown-Items widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
|
||||
-- Lua APIs
|
||||
local select, assert = select, assert
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
|
||||
local ItemBase = {}
|
||||
do
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function fixlevels(parent,...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
while child do
|
||||
child:SetFrameLevel(parent:GetFrameLevel()+1)
|
||||
fixlevels(child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Frame_OnEnter(this)
|
||||
local self = this.obj
|
||||
|
||||
if self.useHighlight then
|
||||
self.highlight:Show()
|
||||
end
|
||||
self:Fire("OnEnter")
|
||||
|
||||
if self.specialOnEnter then
|
||||
self.specialOnEnter(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function Frame_OnLeave(this)
|
||||
local self = this.obj
|
||||
|
||||
self.highlight:Hide()
|
||||
self:Fire("OnLeave")
|
||||
|
||||
if self.specialOnLeave then
|
||||
self.specialOnLeave(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetDisabled()
|
||||
self.frame:SetToplevel(true)
|
||||
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self:SetDisabled()
|
||||
self.pullout = nil
|
||||
self.frame:SetParent(nil)
|
||||
self.frame:ClearAllPoints()
|
||||
self.frame:Hide()
|
||||
end,
|
||||
|
||||
["SetPullout"] = function(self, pullout)
|
||||
self.pullout = pullout
|
||||
|
||||
self.frame:SetParent(nil)
|
||||
self.frame:SetParent(pullout.itemFrame)
|
||||
self.parent = pullout.itemFrame
|
||||
fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren())
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.text:SetText(text or "")
|
||||
end,
|
||||
|
||||
["GetText"] = function(self)
|
||||
return self.text:GetText()
|
||||
end,
|
||||
|
||||
["SetPoint"] = function(self, ...)
|
||||
self.frame:SetPoint(...)
|
||||
end,
|
||||
|
||||
["Show"] = function(self)
|
||||
self.frame:Show()
|
||||
end,
|
||||
|
||||
["Hide"] = function(self)
|
||||
self.frame:Hide()
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
TSMAPI.Design:SetWidgetTextColor(self.text, disabled)
|
||||
self.useHighlight = not disabled
|
||||
end,
|
||||
|
||||
["SetOnLeave"] = function(self, func)
|
||||
self.specialOnLeave = func
|
||||
end,
|
||||
|
||||
["SetOnEnter"] = function(self, func)
|
||||
self.specialOnEnter = func
|
||||
end,
|
||||
}
|
||||
|
||||
function ItemBase.Create(type)
|
||||
local count = AceGUI:GetNextWidgetNum(type)
|
||||
local frame = CreateFrame("Button", "TSMDropDownItem"..count)
|
||||
|
||||
frame:SetHeight(17)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
local text = frame:CreateFontString(nil,"OVERLAY")
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetPoint("TOPLEFT",frame,"TOPLEFT",18,0)
|
||||
text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-8,0)
|
||||
|
||||
local highlight = frame:CreateTexture(nil, "OVERLAY")
|
||||
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
||||
highlight:SetBlendMode("ADD")
|
||||
highlight:SetHeight(14)
|
||||
highlight:ClearAllPoints()
|
||||
highlight:SetPoint("RIGHT",frame,"RIGHT",-3,0)
|
||||
highlight:SetPoint("LEFT",frame,"LEFT",5,0)
|
||||
highlight:Hide()
|
||||
|
||||
local check = frame:CreateTexture("OVERLAY")
|
||||
check:SetWidth(16)
|
||||
check:SetHeight(16)
|
||||
check:SetPoint("LEFT",frame,"LEFT",3,-1)
|
||||
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
||||
check:Hide()
|
||||
|
||||
local sub = frame:CreateTexture("OVERLAY")
|
||||
sub:SetWidth(16)
|
||||
sub:SetHeight(16)
|
||||
sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1)
|
||||
sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
|
||||
sub:Hide()
|
||||
|
||||
frame:SetScript("OnEnter", Frame_OnEnter)
|
||||
frame:SetScript("OnLeave", Frame_OnLeave)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
text = text,
|
||||
highlight = highlight,
|
||||
check = check,
|
||||
sub = sub,
|
||||
useHighlight = true,
|
||||
origMethods = methods,
|
||||
type = type,
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
frame.obj = widget
|
||||
|
||||
return widget
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
local Type, Version = "TSMDropdown-Item-Execute", 2
|
||||
|
||||
local function Frame_OnClick(this)
|
||||
local self = this.obj
|
||||
if self.disabled then return end
|
||||
self:Fire("OnClick")
|
||||
if self.pullout then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local item = ItemBase.Create(Type)
|
||||
item.frame:SetScript("OnClick", Frame_OnClick)
|
||||
return AceGUI:RegisterAsWidget(item)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
local Type, Version = "TSMDropdown-Item-Toggle", 2
|
||||
|
||||
local function Frame_OnClick(this, button)
|
||||
local self = this.obj
|
||||
if self.disabled then return end
|
||||
self.value = not self.value
|
||||
if self.value then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
else
|
||||
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||
end
|
||||
self:UpdateToggle()
|
||||
self:Fire("OnValueChanged", self.value)
|
||||
end
|
||||
|
||||
local methods = {
|
||||
["UpdateToggle"] = function(self)
|
||||
if self.value then
|
||||
self.check:Show()
|
||||
else
|
||||
self.check:Hide()
|
||||
end
|
||||
end,
|
||||
|
||||
["SetValue"] = function(self, value)
|
||||
self.value = value
|
||||
self:UpdateToggle()
|
||||
end,
|
||||
|
||||
["GetValue"] = function(self)
|
||||
return self.value
|
||||
end,
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local item = ItemBase.Create(Type)
|
||||
item.frame:SetScript("OnClick", Frame_OnClick)
|
||||
for method, func in pairs(methods) do
|
||||
item[method] = func
|
||||
end
|
||||
return AceGUI:RegisterAsWidget(item)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
end
|
||||
@@ -0,0 +1,315 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Dropdown.lua
|
||||
-- This Dropdown-Pullout widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
local Type, Version = "TSMDropdown-Pullout", 2
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local min, max, floor = math.min, math.max, math.floor
|
||||
local select, pairs, ipairs, type = select, pairs, ipairs, type
|
||||
local tsort = table.sort
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local UIParent, CreateFrame = UIParent, CreateFrame
|
||||
local _G = _G
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Globals
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local sliderBackdrop = {
|
||||
bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
|
||||
edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 8,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
}
|
||||
|
||||
local DEFAULT_WIDTH = 200
|
||||
local DEFAULT_MAX_HEIGHT = 600
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function fixstrata(strata, parent, ...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
parent:SetFrameStrata(strata)
|
||||
while child do
|
||||
fixstrata(strata, child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function OnEnter(item)
|
||||
local self = item.pullout
|
||||
for k, v in ipairs(self.items) do
|
||||
if v.CloseMenu and v ~= item then
|
||||
v:CloseMenu()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- See the note in Constructor() for each scroll related function
|
||||
local function OnMouseWheel(this, value)
|
||||
this.obj:MoveScroll(value)
|
||||
end
|
||||
|
||||
local function OnScrollValueChanged(this, value)
|
||||
this.obj:SetScroll(value)
|
||||
end
|
||||
|
||||
local function OnSizeChanged(this)
|
||||
this.obj:FixScroll()
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self.frame:SetParent(UIParent)
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self:Clear()
|
||||
self.frame:ClearAllPoints()
|
||||
self.frame:Hide()
|
||||
end,
|
||||
|
||||
["SetScroll"] = function(self, value)
|
||||
local status = self.scrollStatus
|
||||
local frame, child = self.scrollFrame, self.itemFrame
|
||||
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
||||
|
||||
local offset
|
||||
if height > viewheight then
|
||||
offset = 0
|
||||
else
|
||||
offset = floor((viewheight - height) / 1000 * value)
|
||||
end
|
||||
child:ClearAllPoints()
|
||||
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
|
||||
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset)
|
||||
status.offset = offset
|
||||
status.scrollvalue = value
|
||||
end,
|
||||
|
||||
["MoveScroll"] = function(self, value)
|
||||
local status = self.scrollStatus
|
||||
local frame, child = self.scrollFrame, self.itemFrame
|
||||
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
||||
|
||||
if height > viewheight then
|
||||
self.slider:Hide()
|
||||
else
|
||||
self.slider:Show()
|
||||
local diff = height - viewheight
|
||||
local delta = 1
|
||||
if value < 0 then
|
||||
delta = -1
|
||||
end
|
||||
self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
|
||||
end
|
||||
end,
|
||||
|
||||
["FixScroll"] = function(self)
|
||||
local status = self.scrollStatus
|
||||
local frame, child = self.scrollFrame, self.itemFrame
|
||||
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
||||
local offset = status.offset or 0
|
||||
|
||||
if viewheight < height then
|
||||
self.slider:Hide()
|
||||
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset)
|
||||
self.slider:SetValue(0)
|
||||
else
|
||||
self.slider:Show()
|
||||
local value = (offset / (viewheight - height) * 1000)
|
||||
if value > 1000 then value = 1000 end
|
||||
self.slider:SetValue(value)
|
||||
self:SetScroll(value)
|
||||
if value < 1000 then
|
||||
child:ClearAllPoints()
|
||||
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
|
||||
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, offset)
|
||||
status.offset = offset
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["AddItem"] = function(self, item)
|
||||
self.items[#self.items + 1] = item
|
||||
|
||||
local h = #self.items * 16
|
||||
self.itemFrame:SetHeight(h)
|
||||
self.frame:SetHeight(min(h + 20, self.maxHeight))
|
||||
|
||||
item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
|
||||
item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
|
||||
|
||||
item:SetPullout(self)
|
||||
item:SetOnEnter(OnEnter)
|
||||
end,
|
||||
|
||||
["Open"] = function(self, point, relFrame, relPoint, x, y)
|
||||
local items = self.items
|
||||
local frame = self.frame
|
||||
local itemFrame = self.itemFrame
|
||||
|
||||
frame:SetPoint(point, relFrame, relPoint, x, y)
|
||||
|
||||
local height = 8
|
||||
for i, item in pairs(items) do
|
||||
if i == 1 then
|
||||
item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
|
||||
else
|
||||
item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
|
||||
end
|
||||
|
||||
item:Show()
|
||||
|
||||
height = height + 16
|
||||
end
|
||||
itemFrame:SetHeight(height)
|
||||
fixstrata("TOOLTIP", frame, frame:GetChildren())
|
||||
frame:Show()
|
||||
self:Fire("OnOpen")
|
||||
end,
|
||||
|
||||
["Close"] = function(self)
|
||||
self.frame:Hide()
|
||||
self:Fire("OnClose")
|
||||
end,
|
||||
|
||||
["Clear"] = function(self)
|
||||
local items = self.items
|
||||
for i, item in pairs(items) do
|
||||
AceGUI:Release(item)
|
||||
items[i] = nil
|
||||
end
|
||||
end,
|
||||
|
||||
["IterateItems"] = function(self)
|
||||
return ipairs(self.items)
|
||||
end,
|
||||
|
||||
["SetHideOnLeave"] = function(self, val)
|
||||
self.hideOnLeave = val
|
||||
end,
|
||||
|
||||
["SetMaxHeight"] = function(self, height)
|
||||
self.maxHeight = height or DEFAULT_MAX_HEIGHT
|
||||
if self.frame:GetHeight() > height then
|
||||
self.frame:SetHeight(height)
|
||||
elseif (self.itemFrame:GetHeight()+20) < height then
|
||||
self.frame:SetHeight(self.itemFrame:GetHeight()+20) -- see :AddItem
|
||||
end
|
||||
end,
|
||||
|
||||
["GetRightBorderWidth"] = function(self)
|
||||
return 6 + (self.slider:IsShown() and 12 or 0)
|
||||
end,
|
||||
|
||||
["GetLeftBorderWidth"] = function(self)
|
||||
return 6
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local count = AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local frame = CreateFrame("Frame", "TSMPullout"..count, UIParent)
|
||||
TSMAPI.Design:SetContentColor(frame)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
frame:SetClampedToScreen(true)
|
||||
frame:SetWidth(DEFAULT_WIDTH)
|
||||
frame:SetHeight(DEFAULT_MAX_HEIGHT)
|
||||
|
||||
local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
|
||||
local itemFrame = CreateFrame("Frame", nil, scrollFrame)
|
||||
|
||||
local slider = CreateFrame("Slider", "TSMPulloutScrollbar"..count, scrollFrame)
|
||||
slider:SetOrientation("VERTICAL")
|
||||
slider:SetHitRectInsets(0, 0, -10, 0)
|
||||
slider:SetBackdrop(sliderBackdrop)
|
||||
slider:SetWidth(8)
|
||||
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical")
|
||||
slider:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
scrollFrame:SetScrollChild(itemFrame)
|
||||
scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -4)
|
||||
scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -4, 4)
|
||||
scrollFrame:EnableMouseWheel(true)
|
||||
scrollFrame:SetScript("OnMouseWheel", OnMouseWheel)
|
||||
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
|
||||
scrollFrame:SetToplevel(true)
|
||||
scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0)
|
||||
itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0)
|
||||
itemFrame:SetHeight(400)
|
||||
itemFrame:SetToplevel(true)
|
||||
itemFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0)
|
||||
slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0)
|
||||
|
||||
scrollFrame:Show()
|
||||
itemFrame:Show()
|
||||
slider:Hide()
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
slider = slider,
|
||||
scrollFrame = scrollFrame,
|
||||
itemFrame = itemFrame,
|
||||
maxHeight = DEFAULT_MAX_HEIGHT,
|
||||
scrollStatus = {scrollvalue=0},
|
||||
count = count,
|
||||
items = {},
|
||||
type = Type,
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
frame.obj = widget
|
||||
scrollFrame.obj = widget
|
||||
itemFrame.obj = widget
|
||||
slider.obj = widget
|
||||
|
||||
slider:SetScript("OnValueChanged", OnScrollValueChanged)
|
||||
slider:SetMinMaxValues(0, 1000)
|
||||
slider:SetValueStep(1)
|
||||
slider:SetValue(0)
|
||||
widget:FixScroll()
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,413 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Dropdown.lua
|
||||
-- This Dropdown widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
local Type, Version = "TSMDropdown", 2
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local min, max, floor = math.min, math.max, math.floor
|
||||
local select, pairs, ipairs, type = select, pairs, ipairs, type
|
||||
local tsort = table.sort
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local UIParent, CreateFrame = UIParent, CreateFrame
|
||||
local _G = _G
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function fixlevels(parent,...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
while child do
|
||||
child:SetFrameLevel(parent:GetFrameLevel()+1)
|
||||
fixlevels(child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local function fixstrata(strata, parent, ...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
parent:SetFrameStrata(strata)
|
||||
while child do
|
||||
fixstrata(strata, child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Control_OnEnter(this)
|
||||
this.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(this)
|
||||
this.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Dropdown_OnHide(this)
|
||||
local self = this.obj
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end
|
||||
|
||||
local function Dropdown_TogglePullout(this, button)
|
||||
local self = this.obj
|
||||
if self.disabled then return end
|
||||
PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound
|
||||
if self.open then
|
||||
self.open = nil
|
||||
self.pullout:Close()
|
||||
AceGUI:ClearFocus()
|
||||
else
|
||||
self.open = true
|
||||
-- self.pullout:SetWidth(self.dropdown:GetWidth())
|
||||
self.pullout:SetWidth(self.frame:GetWidth()-8)
|
||||
self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0)
|
||||
AceGUI:SetFocus(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function OnPulloutOpen(this)
|
||||
local self = this.userdata.obj
|
||||
local value = self.value
|
||||
|
||||
if not self.multiselect then
|
||||
for i, item in this:IterateItems() do
|
||||
item:SetValue(item.userdata.value == value)
|
||||
end
|
||||
end
|
||||
|
||||
self.open = true
|
||||
end
|
||||
|
||||
local function OnPulloutClose(this)
|
||||
local self = this.userdata.obj
|
||||
self.open = nil
|
||||
self:Fire("OnClosed")
|
||||
end
|
||||
|
||||
local function ShowMultiText(self)
|
||||
local text
|
||||
for i, widget in self.pullout:IterateItems() do
|
||||
if widget.type == "TSMDropdown-Item-Toggle" then
|
||||
if widget:GetValue() then
|
||||
if text then
|
||||
text = text..", "..widget:GetText()
|
||||
else
|
||||
text = widget:GetText()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self:SetText(text)
|
||||
end
|
||||
|
||||
local function OnItemValueChanged(this, event, checked)
|
||||
local self = this.userdata.obj
|
||||
|
||||
if self.multiselect then
|
||||
self:Fire("OnValueChanged", this.userdata.value, checked)
|
||||
ShowMultiText(self)
|
||||
else
|
||||
if checked then
|
||||
self:SetValue(this.userdata.value)
|
||||
self:Fire("OnValueChanged", this.userdata.value)
|
||||
else
|
||||
this:SetValue(true)
|
||||
end
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
local pullout = AceGUI:Create("TSMDropdown-Pullout")
|
||||
self.pullout = pullout
|
||||
pullout.userdata.obj = self
|
||||
pullout:SetCallback("OnClose", OnPulloutClose)
|
||||
pullout:SetCallback("OnOpen", OnPulloutOpen)
|
||||
self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
|
||||
fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
|
||||
|
||||
self:SetHeight(44)
|
||||
self:SetWidth(200)
|
||||
self:SetLabel()
|
||||
self:ClearMultiselectChecked()
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
AceGUI:Release(self.pullout)
|
||||
self.pullout = nil
|
||||
|
||||
self:SetText("")
|
||||
self:SetDisabled(false)
|
||||
self:SetMultiselect(false)
|
||||
|
||||
self.value = nil
|
||||
self.list = nil
|
||||
self.open = nil
|
||||
self.hasClose = nil
|
||||
|
||||
self.frame:ClearAllPoints()
|
||||
self.frame:Hide()
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
TSMAPI.Design:SetWidgetTextColor(self.text, disabled)
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.label, disabled)
|
||||
if disabled then
|
||||
self.button:Disable()
|
||||
else
|
||||
self.button:Enable()
|
||||
end
|
||||
end,
|
||||
|
||||
["ClearFocus"] = function(self)
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.text:SetText(text or "")
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
if text and text ~= "" then
|
||||
self.label:SetText(text)
|
||||
self.label:Show()
|
||||
self.dropdown:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 2, -18)
|
||||
self:SetHeight(44)
|
||||
self.alignoffset = 30
|
||||
else
|
||||
self.label:SetText("")
|
||||
self.label:Hide()
|
||||
self.dropdown:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 2, 0)
|
||||
self:SetHeight(26)
|
||||
self.alignoffset = 12
|
||||
end
|
||||
end,
|
||||
|
||||
["SetValue"] = function(self, value)
|
||||
if self.list then
|
||||
self:SetText(self.list[value] or "")
|
||||
end
|
||||
self.value = value
|
||||
end,
|
||||
|
||||
["GetValue"] = function(self)
|
||||
return self.value
|
||||
end,
|
||||
|
||||
["SetItemValue"] = function(self, item, value)
|
||||
if not self.multiselect then return end
|
||||
for i, widget in self.pullout:IterateItems() do
|
||||
if widget.userdata.value == item then
|
||||
if widget.SetValue then
|
||||
widget:SetValue(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
ShowMultiText(self)
|
||||
end,
|
||||
|
||||
["SetItemDisabled"] = function(self, item, disabled)
|
||||
for i, widget in self.pullout:IterateItems() do
|
||||
if widget.userdata.value == item then
|
||||
widget:SetDisabled(disabled)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["AddListItem"] = function(self, value, text, itemType)
|
||||
itemType = itemType or "TSMDropdown-Item-Toggle"
|
||||
local exists = AceGUI:GetWidgetVersion(itemType)
|
||||
if not exists then error(("The given item type, %q, does not exist within AceGUI-3.0"):format(tostring(itemType)), 2) end
|
||||
|
||||
local item = AceGUI:Create(itemType)
|
||||
item:SetText(text)
|
||||
item.userdata.obj = self
|
||||
item.userdata.value = value
|
||||
item:SetValue()
|
||||
item:SetCallback("OnValueChanged", OnItemValueChanged)
|
||||
self.pullout:AddItem(item)
|
||||
end,
|
||||
|
||||
["AddCloseButton"] = function(self)
|
||||
if not self.hasClose then
|
||||
local close = AceGUI:Create("TSMDropdown-Item-Execute")
|
||||
close:SetText(CLOSE)
|
||||
self.pullout:AddItem(close)
|
||||
self.hasClose = true
|
||||
end
|
||||
end,
|
||||
|
||||
["SetList"] = function(self, list, order, itemType)
|
||||
self.sortlist = self.sortlist or {}
|
||||
self.list = list
|
||||
self.pullout:Clear()
|
||||
self.hasClose = nil
|
||||
if not list then return end
|
||||
|
||||
if type(order) ~= "table" then
|
||||
for v in pairs(list) do
|
||||
self.sortlist[#self.sortlist + 1] = v
|
||||
end
|
||||
tsort(self.sortlist)
|
||||
|
||||
for i, key in ipairs(self.sortlist) do
|
||||
self:AddListItem(key, list[key], itemType)
|
||||
self.sortlist[i] = nil
|
||||
end
|
||||
else
|
||||
for i, key in ipairs(order) do
|
||||
self:AddListItem(key, list[key], itemType)
|
||||
end
|
||||
end
|
||||
if self.multiselect then
|
||||
ShowMultiText(self)
|
||||
self:AddCloseButton()
|
||||
end
|
||||
end,
|
||||
|
||||
["AddItem"] = function(self, value, text, itemType)
|
||||
if self.list then
|
||||
self.list[value] = text
|
||||
self:AddListItem(value, text, itemType)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetMultiselect"] = function(self, multi)
|
||||
self.multiselect = multi
|
||||
if multi then
|
||||
ShowMultiText(self)
|
||||
self:AddCloseButton()
|
||||
end
|
||||
end,
|
||||
|
||||
["GetMultiselect"] = function(self)
|
||||
return self.multiselect
|
||||
end,
|
||||
|
||||
["ClearMultiselectChecked"] = function(self)
|
||||
for i, widget in self.pullout:IterateItems() do
|
||||
if widget.type == "TSMDropdown-Item-Toggle" then
|
||||
widget:SetValue()
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local count = AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
local dropdown = CreateFrame("Frame", "TSMDropDown"..count, frame, "UIDropDownMenuTemplate")
|
||||
|
||||
frame:SetScript("OnHide", Dropdown_OnHide)
|
||||
|
||||
dropdown:ClearAllPoints()
|
||||
dropdown:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -7, 0)
|
||||
dropdown:SetScript("OnHide", nil)
|
||||
dropdown:SetScript("OnEnter", Control_OnEnter)
|
||||
dropdown:SetScript("OnLeave", Control_OnLeave)
|
||||
dropdown:SetScript("OnMouseUp", function(self, button) Dropdown_TogglePullout(self.obj.button, button) end)
|
||||
TSMAPI.Design:SetContentColor(dropdown)
|
||||
|
||||
local left = _G[dropdown:GetName().."Left"]
|
||||
local middle = _G[dropdown:GetName().."Middle"]
|
||||
local right = _G[dropdown:GetName().."Right"]
|
||||
|
||||
middle:ClearAllPoints()
|
||||
right:ClearAllPoints()
|
||||
|
||||
middle:SetPoint("LEFT", left, "RIGHT", 0, 0)
|
||||
middle:SetPoint("RIGHT", right, "LEFT", 0, 0)
|
||||
right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17)
|
||||
|
||||
local button = _G[dropdown:GetName().."Button"]
|
||||
button:RegisterForClicks("AnyUp")
|
||||
button:SetScript("OnEnter", Control_OnEnter)
|
||||
button:SetScript("OnLeave", Control_OnLeave)
|
||||
button:SetScript("OnClick", Dropdown_TogglePullout)
|
||||
button:ClearAllPoints()
|
||||
button:SetPoint("RIGHT", dropdown, 0, 0)
|
||||
|
||||
local text = _G[dropdown:GetName().."Text"]
|
||||
text:ClearAllPoints()
|
||||
text:SetPoint("RIGHT", button, "LEFT", -2, 0)
|
||||
text:SetPoint("LEFT", dropdown, "LEFT", 8, 0)
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
text:SetShadowColor(0, 0, 0, 0)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY")
|
||||
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
|
||||
label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, 0)
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetHeight(18)
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("small"))
|
||||
label:SetShadowColor(0, 0, 0, 0)
|
||||
label:Hide()
|
||||
|
||||
left:Hide()
|
||||
middle:Hide()
|
||||
right:Hide()
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
label = label,
|
||||
dropdown = dropdown,
|
||||
text = text,
|
||||
button = button,
|
||||
count = count,
|
||||
alignoffset = 30,
|
||||
type = Type,
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
frame.obj = widget
|
||||
dropdown.obj = widget
|
||||
text.obj = widget
|
||||
button.obj = widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,283 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
|
||||
-- This EditBox widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMEditBox", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local tostring, pairs = tostring, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local GetCursorInfo, ClearCursor, GetSpellInfo = GetCursorInfo, ClearCursor, GetSpellInfo
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
local _G = _G
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
if not TSMEditBoxInsertLink then
|
||||
-- upgradeable hook
|
||||
hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.TSMEditBoxInsertLink(...) end)
|
||||
end
|
||||
|
||||
function _G.TSMEditBoxInsertLink(text)
|
||||
for i = 1, AceGUI:GetWidgetCount(Type) do
|
||||
local editbox = _G["TSMEditBox"..i]
|
||||
if editbox and editbox:IsVisible() and editbox:HasFocus() then
|
||||
editbox:Insert(text)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ShowButton(self)
|
||||
if not self.disablebutton then
|
||||
self.button:Show()
|
||||
self.editbox:SetTextInsets(0, 20, 3, 3)
|
||||
end
|
||||
end
|
||||
|
||||
local function HideButton(self)
|
||||
self.button:Hide()
|
||||
self.editbox:SetTextInsets(0, 0, 3, 3)
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Frame_OnShowFocus(frame)
|
||||
frame.obj.editbox:SetFocus()
|
||||
frame:SetScript("OnShow", nil)
|
||||
end
|
||||
|
||||
local function EditBox_OnEscapePressed(frame)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function EditBox_OnEnterPressed(frame)
|
||||
local self = frame.obj
|
||||
local value = frame:GetText()
|
||||
self:ClearFocus()
|
||||
local cancel = self:Fire("OnEnterPressed", value)
|
||||
if not cancel then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
HideButton(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function EditBox_OnReceiveDrag(frame)
|
||||
local self = frame.obj
|
||||
local type, id, info = GetCursorInfo()
|
||||
if type == "item" then
|
||||
self:SetText(info)
|
||||
self:Fire("OnEnterPressed", info)
|
||||
ClearCursor()
|
||||
elseif type == "spell" then
|
||||
local name = GetSpellInfo(id, info)
|
||||
self:SetText(name)
|
||||
self:Fire("OnEnterPressed", name)
|
||||
ClearCursor()
|
||||
end
|
||||
HideButton(self)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function EditBox_OnTextChanged(frame)
|
||||
local self = frame.obj
|
||||
local value = frame:GetText()
|
||||
if tostring(value) ~= tostring(self.lasttext) then
|
||||
self:Fire("OnTextChanged", value)
|
||||
self.lasttext = value
|
||||
ShowButton(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function EditBox_OnFocusGained(frame)
|
||||
AceGUI:SetFocus(frame.obj)
|
||||
frame.obj:Fire("OnEditFocusGained")
|
||||
end
|
||||
|
||||
local function EditBox_OnFocusLost(frame)
|
||||
frame.obj:Fire("OnEditFocusLost")
|
||||
end
|
||||
|
||||
local function Button_OnClick(frame)
|
||||
local editbox = frame.obj.editbox
|
||||
editbox:ClearFocus()
|
||||
EditBox_OnEnterPressed(editbox)
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- height is controlled by SetLabel
|
||||
self:SetWidth(200)
|
||||
self:SetDisabled()
|
||||
self:SetLabel()
|
||||
self:SetText()
|
||||
self:DisableButton()
|
||||
self:SetMaxLetters(0)
|
||||
TSMAPI.GUI:SetAutoComplete(self.editbox, nil)
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self:ClearFocus()
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
TSMAPI.Design:SetWidgetTextColor(self.editbox, disabled)
|
||||
self.editbox:EnableMouse(not disabled)
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.label, disabled)
|
||||
if disabled then
|
||||
self.editbox:ClearFocus()
|
||||
end
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
if self.disabled and text then
|
||||
text = gsub(text, "|cff([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])", "")
|
||||
text = gsub(text, "|r", "")
|
||||
end
|
||||
self.lasttext = text or ""
|
||||
self.editbox:SetText(text or "")
|
||||
self.editbox:SetCursorPosition(0)
|
||||
HideButton(self)
|
||||
end,
|
||||
|
||||
["GetText"] = function(self, text)
|
||||
return self.editbox:GetText()
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
if text and text ~= "" then
|
||||
self.label:SetText(text)
|
||||
self.label:Show()
|
||||
self.editbox:SetPoint("TOPLEFT", 2, -18)
|
||||
self:SetHeight(44)
|
||||
self.alignoffset = 30
|
||||
else
|
||||
self.label:SetText("")
|
||||
self.label:Hide()
|
||||
self.editbox:SetPoint("TOPLEFT", 2, 0)
|
||||
self:SetHeight(26)
|
||||
self.alignoffset = 12
|
||||
end
|
||||
end,
|
||||
|
||||
["DisableButton"] = function(self, disabled)
|
||||
self.disablebutton = disabled
|
||||
if disabled then
|
||||
HideButton(self)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetMaxLetters"] = function (self, num)
|
||||
self.editbox:SetMaxLetters(num or 0)
|
||||
end,
|
||||
|
||||
["ClearFocus"] = function(self)
|
||||
self.editbox:ClearFocus()
|
||||
self.frame:SetScript("OnShow", nil)
|
||||
end,
|
||||
|
||||
["SetFocus"] = function(self)
|
||||
self.editbox:SetFocus()
|
||||
if not self.frame:IsShown() then
|
||||
self.frame:SetScript("OnShow", Frame_OnShowFocus)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetAutoComplete"] = function(self, params)
|
||||
TSMAPI.GUI:SetAutoComplete(self.editbox, params)
|
||||
end,
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local editbox = CreateFrame("EditBox", "TSMEditBox"..num, frame)
|
||||
editbox:SetAutoFocus(false)
|
||||
editbox:SetScript("OnEnter", Control_OnEnter)
|
||||
editbox:SetScript("OnLeave", Control_OnLeave)
|
||||
editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
|
||||
editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
|
||||
editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
|
||||
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
|
||||
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
|
||||
editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
|
||||
editbox:SetScript("OnEditFocusLost", EditBox_OnFocusLost)
|
||||
editbox:SetTextInsets(0, 0, 3, 3)
|
||||
editbox:SetMaxLetters(256)
|
||||
editbox:SetPoint("BOTTOMRIGHT", -6, 0)
|
||||
editbox:SetHeight(19)
|
||||
editbox:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
editbox:SetShadowColor(0, 0, 0, 0)
|
||||
TSMAPI.Design:SetContentColor(editbox)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY")
|
||||
label:SetPoint("TOPLEFT", 0, -2)
|
||||
label:SetPoint("TOPRIGHT", 0, -2)
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetHeight(18)
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
label:SetShadowColor(0, 0, 0, 0)
|
||||
|
||||
local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
|
||||
button:SetWidth(40)
|
||||
button:SetHeight(20)
|
||||
button:SetPoint("RIGHT", -2, 0)
|
||||
button:SetText(OKAY)
|
||||
button:SetScript("OnClick", Button_OnClick)
|
||||
button:Hide()
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
alignoffset = 30,
|
||||
editbox = editbox,
|
||||
label = label,
|
||||
button = button,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
editbox.obj, button.obj = widget, widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,231 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
|
||||
-- This EditBox widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMGroupBox", 2
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local tostring, pairs = tostring, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local GetCursorInfo, ClearCursor, GetSpellInfo = GetCursorInfo, ClearCursor, GetSpellInfo
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
local _G = _G
|
||||
|
||||
-- local variables
|
||||
local groupSelectionFrame
|
||||
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function CreateGroupSelectionFrame()
|
||||
if groupSelectionFrame then return end
|
||||
groupSelectionFrame = CreateFrame("Frame", nil, TSMMainFrame1)
|
||||
TSMAPI.Design:SetFrameBackdropColor(groupSelectionFrame)
|
||||
groupSelectionFrame:SetWidth(300)
|
||||
groupSelectionFrame:SetHeight(400)
|
||||
groupSelectionFrame:SetPoint("CENTER")
|
||||
|
||||
local label = TSMAPI.GUI:CreateLabel(groupSelectionFrame)
|
||||
label:SetPoint("TOPLEFT", 5, -2)
|
||||
label:SetPoint("TOPRIGHT", -5, -2)
|
||||
label:SetHeight(40)
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetText(L["Select a group from the list below and click 'OK' at the bottom."])
|
||||
|
||||
local container = CreateFrame("Frame", nil, groupSelectionFrame)
|
||||
container:SetPoint("TOPLEFT", 5, -45)
|
||||
container:SetPoint("BOTTOMRIGHT", -5, 45)
|
||||
TSMAPI.Design:SetFrameColor(container)
|
||||
groupSelectionFrame.groupTree = TSMAPI:CreateGroupTree(container, nil, nil, true)
|
||||
|
||||
local function OnBtnClick(btn)
|
||||
if btn.which == "clear" then
|
||||
groupSelectionFrame.groupTree:ClearSelection()
|
||||
elseif btn.which == "cancel" then
|
||||
groupSelectionFrame:Hide()
|
||||
elseif btn.which == "okay" then
|
||||
local groupBox = groupSelectionFrame.obj
|
||||
local groupPath = groupSelectionFrame.groupTree:GetGroupBoxSelection()
|
||||
groupBox:SetText(TSMAPI:FormatGroupPath(groupPath))
|
||||
groupBox:Fire("OnValueChanged", groupPath)
|
||||
groupSelectionFrame:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local btn = TSMAPI.GUI:CreateButton(groupSelectionFrame, 14)
|
||||
btn:SetPoint("BOTTOMLEFT", 5, 5)
|
||||
btn:SetWidth(90)
|
||||
btn:SetHeight(24)
|
||||
btn:SetText(L["Clear"])
|
||||
btn:SetScript("OnClick", OnBtnClick)
|
||||
btn.which = "clear"
|
||||
groupSelectionFrame.clearBtn = btn
|
||||
|
||||
local btn = TSMAPI.GUI:CreateButton(groupSelectionFrame, 14)
|
||||
btn:SetPoint("BOTTOMLEFT", groupSelectionFrame.clearBtn, "BOTTOMRIGHT", 5, 0)
|
||||
btn:SetWidth(90)
|
||||
btn:SetHeight(24)
|
||||
btn:SetText(CANCEL)
|
||||
btn:SetScript("OnClick", OnBtnClick)
|
||||
btn.which = "cancel"
|
||||
groupSelectionFrame.cancelBtn = btn
|
||||
|
||||
local btn = TSMAPI.GUI:CreateButton(groupSelectionFrame, 14)
|
||||
btn:SetPoint("BOTTOMLEFT", groupSelectionFrame.cancelBtn, "BOTTOMRIGHT", 5, 0)
|
||||
btn:SetPoint("BOTTOMRIGHT", -5, 5)
|
||||
btn:SetWidth(90)
|
||||
btn:SetHeight(24)
|
||||
btn:SetText(OKAY)
|
||||
btn:SetScript("OnClick", OnBtnClick)
|
||||
btn.which = "okay"
|
||||
groupSelectionFrame.okBtn = btn
|
||||
|
||||
groupSelectionFrame:Hide()
|
||||
end
|
||||
|
||||
local function ShowGroupSelectionFrame(parent, obj)
|
||||
groupSelectionFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
groupSelectionFrame:Show()
|
||||
groupSelectionFrame:SetPoint("CENTER", parent)
|
||||
groupSelectionFrame.obj = obj
|
||||
groupSelectionFrame.groupTree:SetGropBoxSelection(obj:GetText())
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Control_OnClick(frame)
|
||||
frame.obj.editbox:ClearFocus()
|
||||
ShowGroupSelectionFrame(frame, frame.obj)
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- height is controlled by SetLabel
|
||||
self:SetWidth(200)
|
||||
self:SetDisabled()
|
||||
self:SetLabel()
|
||||
self:SetText()
|
||||
self:SetMaxLetters(0)
|
||||
CreateGroupSelectionFrame()
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
TSMAPI.Design:SetWidgetTextColor(self.editbox, disabled)
|
||||
self.editbox:EnableMouse(not disabled)
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.label, disabled)
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.editbox:SetText(text or "")
|
||||
self.editbox:SetCursorPosition(0)
|
||||
end,
|
||||
|
||||
["GetText"] = function(self, text)
|
||||
return self.editbox:GetText()
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
if text and text ~= "" then
|
||||
self.label:SetText(text)
|
||||
self.label:Show()
|
||||
self.editbox:SetPoint("TOPLEFT", 2, -18)
|
||||
self:SetHeight(44)
|
||||
self.alignoffset = 30
|
||||
else
|
||||
self.label:SetText("")
|
||||
self.label:Hide()
|
||||
self.editbox:SetPoint("TOPLEFT", 2, 0)
|
||||
self:SetHeight(26)
|
||||
self.alignoffset = 12
|
||||
end
|
||||
end,
|
||||
|
||||
["SetMaxLetters"] = function (self, num)
|
||||
self.editbox:SetMaxLetters(num or 0)
|
||||
end,
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local editbox = CreateFrame("EditBox", "TSMGroupBox"..num, frame)
|
||||
editbox:SetAutoFocus(false)
|
||||
editbox:SetScript("OnEnter", Control_OnEnter)
|
||||
editbox:SetScript("OnLeave", Control_OnLeave)
|
||||
editbox:SetScript("OnEditFocusGained", Control_OnClick)
|
||||
editbox:SetTextInsets(0, 0, 3, 3)
|
||||
editbox:SetMaxLetters(256)
|
||||
editbox:SetPoint("BOTTOMRIGHT", -6, 0)
|
||||
editbox:SetHeight(19)
|
||||
editbox:SetFont(TSMAPI.Design:GetContentFont("small"))
|
||||
editbox:SetShadowColor(0, 0, 0, 0)
|
||||
TSMAPI.Design:SetContentColor(editbox)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY")
|
||||
label:SetPoint("TOPLEFT", 0, -2)
|
||||
label:SetPoint("TOPRIGHT", 0, -2)
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetHeight(18)
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
label:SetShadowColor(0, 0, 0, 0)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
alignoffset = 30,
|
||||
editbox = editbox,
|
||||
label = label,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
frame.obj = widget
|
||||
editbox.obj = widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,515 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Group Item List Widget
|
||||
Provides two scroll lists with buttons to move selected items from one list to the other.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMGroupItemList", 1
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
local ROW_HEIGHT = 16
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function ShowIcon(row)
|
||||
row.iconFrame:Show()
|
||||
row.label:SetPoint("TOPLEFT", 20, 0)
|
||||
row.label:SetPoint("BOTTOMRIGHT")
|
||||
end
|
||||
|
||||
local function HideIcon(row)
|
||||
row.iconFrame:Hide()
|
||||
row.label:SetPoint("TOPLEFT", 0, 0)
|
||||
row.label:SetPoint("BOTTOMRIGHT")
|
||||
end
|
||||
|
||||
local function UpdateScrollFrame(self)
|
||||
local parent = self:GetParent()
|
||||
if not parent.obj.GetListCallback then return end
|
||||
parent.items = parent.obj.GetListCallback(parent == parent.obj.leftFrame and "left" or "right")
|
||||
if not parent.list then
|
||||
parent.list = {}
|
||||
local usedItems = {}
|
||||
for _, itemLink in ipairs(parent.items) do
|
||||
local itemString = TSMAPI:GetItemString(itemLink)
|
||||
local name, link, _, _, _, _, _, _, _, texture = TSMAPI:GetSafeItemInfo(itemString)
|
||||
if itemString and name and texture and not usedItems[itemString] then
|
||||
usedItems[itemString] = true
|
||||
tinsert(parent.list, {value=itemString, link=link, icon=texture, sortText=strlower(name)})
|
||||
end
|
||||
end
|
||||
sort(parent.list, function(a, b) return a.sortText < b.sortText end)
|
||||
end
|
||||
|
||||
local rows = self.rows
|
||||
-- clear all the rows
|
||||
for _, v in pairs(rows) do
|
||||
v.value = nil
|
||||
v.label:SetText("")
|
||||
v.iconFrame.icon:SetTexture("")
|
||||
v:Hide()
|
||||
end
|
||||
|
||||
local rowData = {}
|
||||
for _, data in ipairs(self:GetParent().list) do
|
||||
if not data.filtered then
|
||||
tinsert(rowData, data)
|
||||
end
|
||||
end
|
||||
|
||||
local maxRows = floor((self.height-5)/(ROW_HEIGHT+2))
|
||||
FauxScrollFrame_Update(self, #(rowData), maxRows-1, ROW_HEIGHT)
|
||||
local offset = FauxScrollFrame_GetOffset(self)
|
||||
local displayIndex = 0
|
||||
|
||||
-- make the rows bigger if the scroller isn't showing
|
||||
if self:IsVisible() then
|
||||
rows[1]:SetPoint("TOPRIGHT", self:GetParent(), -26, 0)
|
||||
else
|
||||
rows[1]:SetPoint("TOPRIGHT", self:GetParent(), -10, 0)
|
||||
end
|
||||
|
||||
for index, data in ipairs(rowData) do
|
||||
if index >= offset and displayIndex < maxRows then
|
||||
displayIndex = displayIndex + 1
|
||||
local row = rows[displayIndex]
|
||||
|
||||
row.label:SetText(data.link)
|
||||
row.value = data.value
|
||||
row.data = data
|
||||
|
||||
if data.selected then
|
||||
row:LockHighlight()
|
||||
else
|
||||
row:UnlockHighlight()
|
||||
end
|
||||
|
||||
if data.icon then
|
||||
row.iconFrame.icon:SetTexture(data.icon)
|
||||
ShowIcon(row)
|
||||
else
|
||||
HideIcon(row)
|
||||
end
|
||||
row:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateRows(parent)
|
||||
local numRows = floor((parent.height-5)/(ROW_HEIGHT+2))
|
||||
parent.rows = parent.rows or {}
|
||||
for i=1, numRows do
|
||||
if not parent.rows[i] then
|
||||
local row = CreateFrame("Button", parent:GetName().."Row"..i, parent:GetParent())
|
||||
row:SetHeight(ROW_HEIGHT)
|
||||
row:SetScript("OnClick", function(self)
|
||||
self.data.selected = not self.data.selected
|
||||
if self.data.selected then
|
||||
self:LockHighlight()
|
||||
else
|
||||
self:UnlockHighlight()
|
||||
end
|
||||
end)
|
||||
row:SetScript("OnEnter", function(self)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_NONE")
|
||||
GameTooltip:SetPoint("LEFT", parent:GetParent():GetParent(), "RIGHT")
|
||||
TSMAPI:SafeTooltipLink(self.data.link)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
-- row:SetScript("OnLeave", function() GameTooltip:Hide() BattlePetTooltip:Hide() end)
|
||||
row:SetScript("OnLeave", function() GameTooltip:Hide() end)
|
||||
|
||||
if i > 1 then
|
||||
row:SetPoint("TOPLEFT", parent.rows[i-1], "BOTTOMLEFT", 0, -2)
|
||||
row:SetPoint("TOPRIGHT", parent.rows[i-1], "BOTTOMRIGHT", 0, -2)
|
||||
else
|
||||
row:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, 0)
|
||||
row:SetPoint("TOPRIGHT", parent, "TOPRIGHT", 4, 0)
|
||||
end
|
||||
|
||||
-- highlight / selection texture for the row
|
||||
local highlightTex = row:CreateTexture()
|
||||
highlightTex:SetTexture("Interface\\Buttons\\UI-Listbox-Highlight")
|
||||
highlightTex:SetPoint("TOPRIGHT", row, "TOPRIGHT", 0, 0)
|
||||
highlightTex:SetPoint("BOTTOMLEFT")
|
||||
highlightTex:SetAlpha(0.7)
|
||||
row:SetHighlightTexture(highlightTex)
|
||||
|
||||
-- icon that goes to the left of the text
|
||||
local iconFrame = CreateFrame("Frame", nil, row)
|
||||
iconFrame:SetHeight(ROW_HEIGHT-2)
|
||||
iconFrame:SetWidth(ROW_HEIGHT-2)
|
||||
iconFrame:SetPoint("TOPLEFT")
|
||||
row.iconFrame = iconFrame
|
||||
|
||||
-- texture that goes inside the iconFrame
|
||||
local iconTexture = iconFrame:CreateTexture(nil, "BACKGROUND")
|
||||
iconTexture:SetAllPoints(iconFrame)
|
||||
iconTexture:SetVertexColor(1, 1, 1)
|
||||
iconFrame.icon = iconTexture
|
||||
|
||||
local label = row:CreateFontString(nil, "OVERLAY")
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetPoint("TOPLEFT", 20, 0)
|
||||
label:SetPoint("BOTTOMRIGHT", 10, 0)
|
||||
TSMAPI.Design:SetWidgetTextColor(label)
|
||||
row.label = label
|
||||
|
||||
parent.rows[i] = row
|
||||
end
|
||||
end
|
||||
UpdateScrollFrame(parent)
|
||||
end
|
||||
|
||||
local function OnButtonClick(self)
|
||||
local selected = {}
|
||||
local rows, rowData
|
||||
|
||||
if self.type == "Add" then
|
||||
rows = self.obj.leftFrame.scrollFrame.rows
|
||||
rowData = self.obj.leftFrame.list
|
||||
elseif self.type == "Remove" then
|
||||
rows = self.obj.rightFrame.scrollFrame.rows
|
||||
rowData = self.obj.rightFrame.list
|
||||
end
|
||||
if not rows then error("Invalid type") end
|
||||
|
||||
local temp = {}
|
||||
for _, row in pairs(rows) do
|
||||
if row.data and row.data.selected and row.value then
|
||||
row.data.selected = false
|
||||
row:UnlockHighlight()
|
||||
temp[row.value] = true
|
||||
tinsert(selected, row.value)
|
||||
end
|
||||
end
|
||||
|
||||
for _, data in pairs(rowData) do
|
||||
if data.selected and data.value and not temp[data.value] then
|
||||
data.selected = false
|
||||
tinsert(selected, data.value)
|
||||
end
|
||||
end
|
||||
|
||||
self.obj:Fire("On"..self.type.."Clicked", selected)
|
||||
end
|
||||
|
||||
local function OnFilterSet(self)
|
||||
self:ClearFocus()
|
||||
local text = strlower(TSMAPI:StrEscape(self:GetText():trim()))
|
||||
|
||||
local filterStr, minLevel, maxLevel, minILevel, maxILevel
|
||||
for _, part in ipairs({("/"):split(text)}) do
|
||||
part = part:trim()
|
||||
if part ~= "" then
|
||||
local lvl = tonumber(part)
|
||||
local ilvl = gsub(part, "^i", "")
|
||||
ilvl = tonumber(ilvl)
|
||||
if lvl then
|
||||
if not minLevel then
|
||||
minLevel = lvl
|
||||
elseif not maxLevel then
|
||||
maxLevel = lvl
|
||||
else
|
||||
return TSM:Print(L["Invalid filter."])
|
||||
end
|
||||
elseif ilvl then
|
||||
if not minILevel then
|
||||
minILevel = ilvl
|
||||
elseif not maxILevel then
|
||||
maxILevel = ilvl
|
||||
else
|
||||
return TSM:Print(L["Invalid filter."])
|
||||
end
|
||||
else
|
||||
if filterStr then
|
||||
return TSM:Print(L["Invalid filter."])
|
||||
end
|
||||
filterStr = part
|
||||
end
|
||||
end
|
||||
end
|
||||
filterStr = filterStr or ""
|
||||
minLevel = minLevel or 0
|
||||
maxLevel = maxLevel or math.huge
|
||||
minILevel = minILevel or 0
|
||||
maxILevel = maxILevel or math.huge
|
||||
|
||||
for _, info in ipairs(self.obj.leftFrame.list) do
|
||||
local name, _, _, ilvl, lvl = TSMAPI:GetSafeItemInfo(info.link)
|
||||
local selected = (strfind(strlower(name), filterStr) and ilvl >= minILevel and ilvl <= maxILevel and lvl >= minLevel and lvl <= maxLevel)
|
||||
info.selected = selected
|
||||
info.filtered = not selected
|
||||
end
|
||||
for _, info in ipairs(self.obj.rightFrame.list) do
|
||||
local name, _, _, ilvl, lvl = TSMAPI:GetSafeItemInfo(info.link)
|
||||
local selected = (strfind(strlower(name), filterStr) and ilvl >= minILevel and ilvl <= maxILevel and lvl >= minLevel and lvl <= maxLevel)
|
||||
info.selected = selected
|
||||
info.filtered = not selected
|
||||
end
|
||||
FauxScrollFrame_SetOffset(self.obj.leftFrame.scrollFrame, 0)
|
||||
FauxScrollFrame_SetOffset(self.obj.rightFrame.scrollFrame, 0)
|
||||
UpdateScrollFrame(self.obj.leftFrame.scrollFrame)
|
||||
UpdateScrollFrame(self.obj.rightFrame.scrollFrame)
|
||||
end
|
||||
|
||||
local function OnClearButtonClicked(self)
|
||||
for _, info in ipairs(self.obj.leftFrame.list) do
|
||||
info.selected = false
|
||||
end
|
||||
for _, info in ipairs(self.obj.rightFrame.list) do
|
||||
info.selected = false
|
||||
end
|
||||
UpdateScrollFrame(self.obj.leftFrame.scrollFrame)
|
||||
UpdateScrollFrame(self.obj.rightFrame.scrollFrame)
|
||||
end
|
||||
|
||||
local function OnIgnoreChanged(self, _, value)
|
||||
TSM.db.global.ignoreRandomEnchants = value
|
||||
self.obj.leftFrame.list = nil
|
||||
UpdateScrollFrame(self.obj.leftFrame.scrollFrame)
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- restore default values
|
||||
self:SetHeight(550)
|
||||
TSMAPI:CreateTimeDelay(0.05, function() self.parent:DoLayout() end)
|
||||
self.filter:SetText("")
|
||||
self.ignoreCheckBox:SetValue(TSM.db.global.ignoreRandomEnchants)
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
-- clear any points / other values
|
||||
wipe(self.leftFrame.list)
|
||||
wipe(self.rightFrame.list)
|
||||
self.frame.leftTitle:SetText("")
|
||||
self.frame.rightTitle:SetText("")
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
if height == 100 then return end
|
||||
self.leftScrollFrame.height = self.frame:GetHeight() - 85
|
||||
self.rightScrollFrame.height = self.frame:GetHeight() - 85
|
||||
UpdateRows(self.leftScrollFrame)
|
||||
UpdateRows(self.rightScrollFrame)
|
||||
end,
|
||||
|
||||
["SetListCallback"] = function(self, callback)
|
||||
self.GetListCallback = callback
|
||||
self.leftFrame.list = nil
|
||||
self.rightFrame.list = nil
|
||||
UpdateScrollFrame(self.leftScrollFrame)
|
||||
UpdateScrollFrame(self.rightScrollFrame)
|
||||
end,
|
||||
|
||||
["SetTitle"] = function(self, side, title)
|
||||
if strlower(side) == "left" then
|
||||
self.frame.leftTitle:SetText(title)
|
||||
elseif strlower(side) == "right" then
|
||||
self.frame.rightTitle:SetText(title)
|
||||
elseif title then
|
||||
error("Invalid side passed. Expected 'left' or 'right'")
|
||||
end
|
||||
end,
|
||||
|
||||
["SetIgnoreVisible"] = function(self, shown)
|
||||
if shown then
|
||||
self.ignoreCheckBox.frame:Show()
|
||||
else
|
||||
self.ignoreCheckBox.frame:Hide()
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local borderColor = TSM.db.profile.frameBackdropColor
|
||||
local name = "TSMGroupItemList" .. AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame", name, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local leftFrame = CreateFrame("Frame", name.."LeftFrame", frame)
|
||||
leftFrame:SetPoint("TOPLEFT", 0, -80)
|
||||
leftFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -7, 0)
|
||||
TSMAPI.Design:SetContentColor(leftFrame)
|
||||
leftFrame.list = {}
|
||||
frame.leftFrame = leftFrame
|
||||
|
||||
local leftTitle = frame:CreateFontString(nil, "OVERLAY")
|
||||
leftTitle:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
TSMAPI.Design:SetTitleTextColor(leftTitle)
|
||||
leftTitle:SetJustifyH("LEFT")
|
||||
leftTitle:SetJustifyV("BOTTOM")
|
||||
leftTitle:SetHeight(15)
|
||||
leftTitle:SetPoint("BOTTOMLEFT", leftFrame, "TOPLEFT", 8, 0)
|
||||
leftTitle:SetPoint("BOTTOMRIGHT", leftFrame, "TOPRIGHT", -8, 0)
|
||||
frame.leftTitle = leftTitle
|
||||
|
||||
local leftSF = CreateFrame("ScrollFrame", name.."LeftFrameScrollFrame", leftFrame, "FauxScrollFrameTemplate")
|
||||
leftSF:SetPoint("TOPLEFT", 5, -5)
|
||||
leftSF:SetPoint("BOTTOMRIGHT", -5, 5)
|
||||
leftSF:SetScript("OnVerticalScroll", function(self, offset)
|
||||
FauxScrollFrame_OnVerticalScroll(self, offset, ROW_HEIGHT, function() UpdateScrollFrame(self) end)
|
||||
end)
|
||||
leftFrame.scrollFrame = leftSF
|
||||
|
||||
local leftScrollBar = _G[leftSF:GetName().."ScrollBar"]
|
||||
leftScrollBar:ClearAllPoints()
|
||||
leftScrollBar:SetPoint("BOTTOMRIGHT")
|
||||
leftScrollBar:SetPoint("TOPRIGHT")
|
||||
leftScrollBar:SetWidth(12)
|
||||
|
||||
local thumbTex = leftScrollBar:GetThumbTexture()
|
||||
thumbTex:SetPoint("CENTER")
|
||||
TSMAPI.Design:SetFrameColor(thumbTex)
|
||||
thumbTex:SetHeight(150)
|
||||
thumbTex:SetWidth(leftScrollBar:GetWidth())
|
||||
_G[leftScrollBar:GetName().."ScrollUpButton"]:Hide()
|
||||
_G[leftScrollBar:GetName().."ScrollDownButton"]:Hide()
|
||||
|
||||
local rightFrame = CreateFrame("Frame", name.."RightFrame", frame)
|
||||
rightFrame:SetPoint("TOPLEFT", frame, "TOP", 7, -80)
|
||||
rightFrame:SetPoint("BOTTOMRIGHT", 0, 0)
|
||||
TSMAPI.Design:SetContentColor(rightFrame)
|
||||
rightFrame.list = {}
|
||||
frame.rightFrame = rightFrame
|
||||
|
||||
local rightTitle = frame:CreateFontString(nil, "OVERLAY")
|
||||
rightTitle:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
TSMAPI.Design:SetTitleTextColor(rightTitle)
|
||||
rightTitle:SetJustifyH("LEFT")
|
||||
rightTitle:SetJustifyV("BOTTOM")
|
||||
rightTitle:SetHeight(15)
|
||||
rightTitle:SetPoint("BOTTOMLEFT", rightFrame, "TOPLEFT", 8, 0)
|
||||
rightTitle:SetPoint("BOTTOMRIGHT", rightFrame, "TOPRIGHT", -8, 0)
|
||||
frame.rightTitle = rightTitle
|
||||
|
||||
local rightSF = CreateFrame("ScrollFrame", name.."RightFrameScrollFrame", rightFrame, "FauxScrollFrameTemplate")
|
||||
rightSF:SetPoint("TOPLEFT", 5, -5)
|
||||
rightSF:SetPoint("BOTTOMRIGHT", -5, 5)
|
||||
rightSF:SetScript("OnVerticalScroll", function(self, offset)
|
||||
FauxScrollFrame_OnVerticalScroll(self, offset, ROW_HEIGHT, function() UpdateScrollFrame(self) end)
|
||||
end)
|
||||
rightFrame.scrollFrame = rightSF
|
||||
|
||||
local rightScrollBar = _G[rightSF:GetName().."ScrollBar"]
|
||||
rightScrollBar:ClearAllPoints()
|
||||
rightScrollBar:SetPoint("BOTTOMRIGHT")
|
||||
rightScrollBar:SetPoint("TOPRIGHT")
|
||||
rightScrollBar:SetWidth(12)
|
||||
|
||||
local thumbTex = rightScrollBar:GetThumbTexture()
|
||||
thumbTex:SetPoint("CENTER")
|
||||
TSMAPI.Design:SetFrameColor(thumbTex)
|
||||
thumbTex:SetHeight(150)
|
||||
thumbTex:SetWidth(rightScrollBar:GetWidth())
|
||||
_G[rightScrollBar:GetName().."ScrollUpButton"]:Hide()
|
||||
_G[rightScrollBar:GetName().."ScrollDownButton"]:Hide()
|
||||
|
||||
|
||||
|
||||
local label = TSMAPI.GUI:CreateLabel(frame, "normal")
|
||||
label:SetText("Filter:")
|
||||
label:SetPoint("TOPLEFT", 0, -5)
|
||||
label:SetHeight(20)
|
||||
label:SetJustifyV("CENTER")
|
||||
|
||||
local filter = TSMAPI.GUI:CreateInputBox(frame)
|
||||
filter:SetPoint("BOTTOMLEFT", label, "BOTTOMRIGHT", 2, 0)
|
||||
filter:SetHeight(20)
|
||||
filter:SetWidth(150)
|
||||
filter:SetScript("OnEnterPressed", OnFilterSet)
|
||||
filter.tooltip = L["All items with names containing the specified filter will be selected. This makes it easier to add/remove multiple items at a time."]
|
||||
|
||||
local line = TSMAPI.GUI:CreateHorizontalLine(frame, 0)
|
||||
line:SetPoint("TOPLEFT", 0, -58)
|
||||
line:SetPoint("TOPRIGHT", 0, -58)
|
||||
local line = TSMAPI.GUI:CreateVerticalLine(frame, 0)
|
||||
line:ClearAllPoints()
|
||||
line:SetPoint("TOP", 0, -60)
|
||||
line:SetPoint("BOTTOM")
|
||||
|
||||
local ignoreCheckBox = TSMAPI.GUI:CreateCheckBox(frame, L["When checked, random enchants will be ignored for ungrouped items.\n\nNB: This will not affect parent group items that were already added with random enchants\n\nIf you have this checked when adding an ungrouped randomly enchanted item, it will act as all possible random enchants of that item."])
|
||||
ignoreCheckBox:SetLabel(L["Ignore Random Enchants on Ungrouped Items"])
|
||||
ignoreCheckBox:SetPoint("BOTTOMLEFT", filter, "BOTTOMRIGHT", 20, 5)
|
||||
ignoreCheckBox:SetPoint("TOPRIGHT", 0, -2)
|
||||
ignoreCheckBox:SetCallback("OnValueChanged", OnIgnoreChanged)
|
||||
|
||||
local addBtn = TSMAPI.GUI:CreateButton(frame, 18)
|
||||
addBtn:SetPoint("TOPLEFT", 0, -33)
|
||||
addBtn:SetWidth(170)
|
||||
addBtn:SetHeight(20)
|
||||
addBtn:SetText(L["Add >>>"])
|
||||
addBtn.type = "Add"
|
||||
addBtn:SetScript("OnClick", OnButtonClick)
|
||||
|
||||
local removeBtn = TSMAPI.GUI:CreateButton(frame, 18)
|
||||
removeBtn:SetPoint("TOPRIGHT", 0, -33)
|
||||
removeBtn:SetWidth(170)
|
||||
removeBtn:SetHeight(20)
|
||||
removeBtn:SetText(L["<<< Remove"])
|
||||
removeBtn.type = "Remove"
|
||||
removeBtn:SetScript("OnClick", OnButtonClick)
|
||||
removeBtn.tooltip = L["You can hold shift while clicking this button to remove the items from ALL groups rather than keeping them in the parent group (if one exists)."]
|
||||
|
||||
local clearBtn = TSMAPI.GUI:CreateButton(frame, 16)
|
||||
clearBtn:SetPoint("BOTTOMLEFT", addBtn, "BOTTOMRIGHT", 15, 0)
|
||||
clearBtn:SetPoint("BOTTOMRIGHT", removeBtn, "BOTTOMLEFT", -15, 0)
|
||||
clearBtn:SetHeight(20)
|
||||
clearBtn:SetText(L["Clear Selection"])
|
||||
clearBtn:SetScript("OnClick", OnClearButtonClicked)
|
||||
clearBtn.tooltip = L["Deselects all items in both columns."]
|
||||
|
||||
|
||||
local widget = {
|
||||
leftFrame = leftFrame,
|
||||
leftScrollFrame = leftSF,
|
||||
rightFrame = rightFrame,
|
||||
rightScrollFrame = rightSF,
|
||||
ignoreCheckBox = ignoreCheckBox,
|
||||
filter = filter,
|
||||
clearBtn = clearBtn,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
addBtn.obj = widget
|
||||
removeBtn.obj = widget
|
||||
widget.ignoreCheckBox.obj = widget
|
||||
widget.filter.obj = widget
|
||||
widget.clearBtn.obj = widget
|
||||
widget.leftFrame.obj = widget
|
||||
widget.rightFrame.obj = widget
|
||||
widget.frame.obj = widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,71 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMImage", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetSizeRatio(0.5)
|
||||
self:SetWidth(100)
|
||||
self:SetText()
|
||||
self:SetImage()
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, w)
|
||||
self:SetHeight(w*self.ratio)
|
||||
end,
|
||||
|
||||
["SetSizeRatio"] = function(self, ratio)
|
||||
self.ratio = ratio
|
||||
end,
|
||||
|
||||
["SetImage"] = function(self, image)
|
||||
self.image:SetTexture(image)
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.text:SetText(text)
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
local image = frame:CreateTexture(nil, "ARTWORK")
|
||||
image:SetAllPoints()
|
||||
local text = frame:CreateFontString()
|
||||
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
text:SetTextColor(1, 1, 1, 1)
|
||||
text:SetPoint("BOTTOMRIGHT", -2, 2)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
image = image,
|
||||
text = text,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,68 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
|
||||
-- This InlineGroup container is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
local Type, Version = "TSMInlineGroup", 2
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
local function Constructor()
|
||||
local container = AceGUI:Create("InlineGroup")
|
||||
container.type = Type
|
||||
container.Add = TSMAPI.AddGUIElement
|
||||
|
||||
container.bgFrame = container.content:GetParent()
|
||||
container.border = container.content:GetParent()
|
||||
container.content:SetParent(container.frame)
|
||||
|
||||
local title = container.frame:CreateFontString(nil, "BACKGROUND")
|
||||
title:SetPoint("TOPLEFT", 10, 0)
|
||||
title:SetPoint("TOPRIGHT", -14, 0)
|
||||
title:SetJustifyH("LEFT")
|
||||
title:SetJustifyV("BOTTOM")
|
||||
title:SetFont(TSMAPI.Design:GetBoldFont(), 18)
|
||||
TSMAPI.Design:SetTitleTextColor(title)
|
||||
container.titletext = title
|
||||
|
||||
container.HideTitle = function(self, hideTitle)
|
||||
local frame = self.content:GetParent()
|
||||
frame:ClearAllPoints()
|
||||
if hideTitle then
|
||||
self:SetTitle()
|
||||
frame:SetPoint("TOPLEFT", 0, 0)
|
||||
frame:SetPoint("BOTTOMRIGHT", -1, 3)
|
||||
else
|
||||
frame:SetPoint("TOPLEFT", 0, -17)
|
||||
frame:SetPoint("BOTTOMRIGHT", -1, 3)
|
||||
end
|
||||
end
|
||||
|
||||
container.HideBorder = function(self, hideBorder)
|
||||
if hideBorder then
|
||||
self.border:Hide()
|
||||
else
|
||||
self.border:Show()
|
||||
end
|
||||
end
|
||||
|
||||
container.SetBackdrop = function(self, backdrop)
|
||||
if backdrop then
|
||||
TSMAPI.Design:SetContentColor(self.bgFrame)
|
||||
else
|
||||
TSMAPI.Design:SetFrameColor(self.bgFrame)
|
||||
self.bgFrame:SetBackdropColor(0, 0, 0, 0)
|
||||
end
|
||||
end
|
||||
|
||||
AceGUI:RegisterAsContainer(container)
|
||||
return container
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,113 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Interactive.lua
|
||||
-- This InteractiveLabel widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMInteractiveLabel", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
|
||||
-- Lua APIs
|
||||
local select, pairs = select, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: GameFontHighlightSmall
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Label_OnClick(frame, button)
|
||||
frame.obj:Fire("OnClick", button)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:LabelOnAcquire()
|
||||
self:SetHighlight()
|
||||
self:SetHighlightTexCoord()
|
||||
self:SetDisabled(false)
|
||||
end,
|
||||
|
||||
["SetHighlight"] = function(self, ...)
|
||||
self.highlight:SetTexture(...)
|
||||
end,
|
||||
|
||||
["SetHighlightTexCoord"] = function(self, ...)
|
||||
local c = select("#", ...)
|
||||
if c == 4 or c == 8 then
|
||||
self.highlight:SetTexCoord(...)
|
||||
else
|
||||
self.highlight:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self,disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.frame:EnableMouse(false)
|
||||
self.label:SetTextColor(0.5, 0.5, 0.5)
|
||||
else
|
||||
self.frame:EnableMouse(true)
|
||||
self.label:SetTextColor(1, 1, 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
-- create a Label type that we will hijack
|
||||
local label = AceGUI:Create("TSMLabel")
|
||||
|
||||
local frame = label.frame
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
frame:SetScript("OnMouseDown", Label_OnClick)
|
||||
|
||||
local bg = frame:CreateTexture(nil, "BACKGROUND")
|
||||
bg:SetPoint("TOPLEFT", -2, 2)
|
||||
bg:SetPoint("BOTTOMRIGHT", label.label, 2, -2)
|
||||
TSMAPI.Design:SetContentColor(bg)
|
||||
|
||||
local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetTexture(nil)
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetBlendMode("ADD")
|
||||
|
||||
label.highlight = highlight
|
||||
label.type = Type
|
||||
label.LabelOnAcquire = label.OnAcquire
|
||||
for method, func in pairs(methods) do
|
||||
label[method] = func
|
||||
end
|
||||
|
||||
return label
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,107 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Label.lua
|
||||
-- This Label widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMLabel", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local max, select, pairs = math.max, select, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function UpdateLabelAnchor(self)
|
||||
if self.resizing then return end
|
||||
local frame = self.frame
|
||||
local width = frame.width or frame:GetWidth() or 0
|
||||
local label = self.label
|
||||
local height
|
||||
|
||||
label:ClearAllPoints()
|
||||
label:SetPoint("TOPLEFT")
|
||||
label:SetWidth(min(label:GetStringWidth(), width))
|
||||
height = label:GetHeight()
|
||||
|
||||
self.resizing = true
|
||||
frame:SetHeight(height)
|
||||
frame.height = height
|
||||
self.resizing = nil
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- set the flag to stop constant size updates
|
||||
self.resizing = true
|
||||
-- height is set dynamically by the text and image size
|
||||
self:SetWidth(200)
|
||||
self:SetText()
|
||||
self:SetColor()
|
||||
|
||||
-- reset the flag
|
||||
self.resizing = nil
|
||||
-- run the update explicitly
|
||||
UpdateLabelAnchor(self)
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
UpdateLabelAnchor(self)
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.label:SetText(text)
|
||||
UpdateLabelAnchor(self)
|
||||
end,
|
||||
|
||||
["SetColor"] = function(self, r, g, b)
|
||||
if not (r and b and g) then
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.label)
|
||||
else
|
||||
self.label:SetTextColor(r, g, b)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local label = frame:CreateFontString(nil, "BACKGROUND")
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetJustifyV("TOP")
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
|
||||
-- create widget
|
||||
local widget = {
|
||||
label = label,
|
||||
frame = frame,
|
||||
type = Type,
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,388 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
|
||||
-- This Frame container is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMMainFrame", 2
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
local ICON_TEXT_COLOR = {165/255, 168/255, 188/255, .7}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Frame_OnClose(frame)
|
||||
frame.obj:Fire("OnClose")
|
||||
end
|
||||
|
||||
local function CloseButton_OnClick(frame)
|
||||
PlaySound("gsTitleOptionExit")
|
||||
frame.obj:Hide()
|
||||
end
|
||||
|
||||
local function Frame_OnMouseDown(frame)
|
||||
frame.toMove:GetScript("OnMouseDown")(frame.toMove)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Frame_OnMouseUp(frame)
|
||||
frame.toMove:GetScript("OnMouseUp")(frame.toMove)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Sizer_OnMouseUp(mover)
|
||||
local frame = mover:GetParent()
|
||||
frame:StopMovingOrSizing()
|
||||
frame:SavePositionAndSize()
|
||||
local self = frame.obj
|
||||
local status = self.status or self.localstatus
|
||||
status.width = frame:GetWidth()
|
||||
status.height = frame:GetHeight()
|
||||
status.top = frame:GetTop()
|
||||
status.left = frame:GetLeft()
|
||||
end
|
||||
|
||||
local function Sizer_OnMouseDown(frame)
|
||||
frame:GetParent():StartSizing("BOTTOMRIGHT")
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Icon_OnEnter(btn)
|
||||
btn.dark:Hide()
|
||||
GameTooltip:SetOwner(btn, btn:GetParent().tooltipAnchor)
|
||||
GameTooltip:SetText(btn.title)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
local function Icon_OnLeave(btn)
|
||||
if btn.obj.selected ~= btn then
|
||||
btn.dark:Show()
|
||||
end
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self.frame:RefreshPosition()
|
||||
self.frame:SetFrameStrata("MEDIUM")
|
||||
self:SetTitle()
|
||||
self:ApplyStatus()
|
||||
self:Show()
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
wipe(self.localstatus)
|
||||
end,
|
||||
|
||||
["LayoutIcons"] = function(self)
|
||||
for _, container in ipairs({self.topLeftIcons, self.topRightIcons}) do
|
||||
if type(container.icons) == "table" and container.icons[1] then
|
||||
local numIcons = #container.icons
|
||||
local iconSize = container.icons[1]:GetHeight()
|
||||
local spacing = (container:GetWidth() - numIcons * iconSize) / (numIcons + 1)
|
||||
local width = iconSize
|
||||
if spacing < 1 then
|
||||
spacing = 1
|
||||
width = (container:GetWidth() - (numIcons - 1) * spacing) / numIcons
|
||||
end
|
||||
for i, icon in ipairs(container.icons) do
|
||||
icon:SetPoint("TOPLEFT", spacing+(i-1)*(width+spacing), 0)
|
||||
icon:SetWidth(width)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
self.content.width = self.content:GetWidth()
|
||||
|
||||
self.topLeftIcons:ClearAllPoints()
|
||||
self.topLeftIcons:SetPoint("TOPLEFT", 5, 20)
|
||||
self.topLeftIcons:SetPoint("TOPRIGHT", self.frame, "TOP", -115, 20)
|
||||
self.topLeftIcons:SetHeight(51)
|
||||
|
||||
self.topRightIcons:ClearAllPoints()
|
||||
self.topRightIcons:SetPoint("TOPRIGHT", -5, 20)
|
||||
self.topRightIcons:SetPoint("TOPLEFT", self.frame, "TOP", 115, 20)
|
||||
self.topRightIcons:SetHeight(51)
|
||||
|
||||
self:LayoutIcons()
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
self.content.height = self.content:GetHeight()
|
||||
end,
|
||||
|
||||
["SetTitle"] = function(self, title)
|
||||
self.titletext:SetText(title)
|
||||
end,
|
||||
|
||||
["SetIconText"] = function(self, title)
|
||||
self.icontext:SetText(title)
|
||||
end,
|
||||
|
||||
["SetIconLabels"] = function(self, topLeft, topRight)
|
||||
self.topLeftIcons.label = topLeft
|
||||
self.topRightIcons.label = topRight
|
||||
end,
|
||||
|
||||
["Hide"] = function(self)
|
||||
self.frame:Hide()
|
||||
end,
|
||||
|
||||
["Show"] = function(self)
|
||||
self.frame:Show()
|
||||
end,
|
||||
|
||||
["UpdateSelected"] = function(self)
|
||||
for _, container in ipairs({self.topLeftIcons, self.topRightIcons}) do
|
||||
if type(container.icons) == "table" then
|
||||
for _, icon in ipairs(container.icons) do
|
||||
icon.dark:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
self.selected.dark:Hide()
|
||||
end,
|
||||
|
||||
["AddIcon"] = function(self, info)
|
||||
local container = self[info.where.."Icons"]
|
||||
assert(container, "Invalid icon container.")
|
||||
|
||||
local size = 51
|
||||
|
||||
local btn = CreateFrame("Button", nil, container)
|
||||
btn:SetBackdrop({edgeFile="Interface\\Buttons\\WHITE8X8", edgeSize=2})
|
||||
btn:SetBackdropBorderColor(0, 0, 0, 0.5)
|
||||
btn:SetHeight(size)
|
||||
btn:SetWidth(size)
|
||||
btn.title = info.name
|
||||
btn.info = info
|
||||
btn.obj = self
|
||||
info.frame = btn
|
||||
|
||||
local image = btn:CreateTexture(nil, "BACKGROUND")
|
||||
image:SetAllPoints()
|
||||
image:SetTexture(info.texture)
|
||||
image:SetTexCoord(0.08, 0.922, 0.09, 0.918)
|
||||
image:SetVertexColor(1, 1, 1)
|
||||
btn.image = image
|
||||
|
||||
local dark = btn:CreateTexture(nil, "OVERLAY")
|
||||
dark:SetAllPoints(image)
|
||||
dark:SetTexture(0, 0, 0, .3)
|
||||
dark:SetBlendMode("BLEND")
|
||||
btn.dark = dark
|
||||
btn:SetScript("OnEnter", Icon_OnEnter)
|
||||
btn:SetScript("OnLeave", Icon_OnLeave)
|
||||
btn:SetScript("OnClick", function(btn)
|
||||
if #self.children > 0 then
|
||||
self:ReleaseChildren()
|
||||
end
|
||||
self:SetTitle(btn.title)
|
||||
btn.info.loadGUI(self)
|
||||
self.selected = btn
|
||||
self:UpdateSelected()
|
||||
end)
|
||||
|
||||
local highlight = btn:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetAllPoints(image)
|
||||
highlight:SetTexture(1, 1, 1, .2)
|
||||
highlight:SetBlendMode("ADD")
|
||||
btn.highlight = highlight
|
||||
|
||||
container.icons = container.icons or {}
|
||||
tinsert(container.icons, btn)
|
||||
|
||||
self:LayoutIcons()
|
||||
|
||||
if not container.textLabel then
|
||||
local label = container:CreateFontString()
|
||||
label:SetHeight(12)
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("small"))
|
||||
TSMAPI.Design:SetIconRegionColor(label)
|
||||
label:SetText(container.label)
|
||||
label:SetPoint("TOP", 0, -53)
|
||||
container.tooltipAnchor = "ANCHOR_TOP"
|
||||
container.textLabel = label
|
||||
|
||||
-- make the lines that extend the width of the container out from the label
|
||||
local leftHLine = container:CreateTexture()
|
||||
leftHLine:SetPoint("TOPRIGHT", label, "TOPLEFT", -2, -6)
|
||||
leftHLine:SetHeight(1)
|
||||
TSMAPI.Design:SetIconRegionColor(leftHLine)
|
||||
local rightHLine = container:CreateTexture()
|
||||
rightHLine:SetPoint("TOPLEFT", label, "TOPRIGHT", 2, -6)
|
||||
rightHLine:SetHeight(1)
|
||||
TSMAPI.Design:SetIconRegionColor(rightHLine)
|
||||
leftHLine:SetPoint("TOPLEFT", 20, -59)
|
||||
rightHLine:SetPoint("TOPRIGHT", -20, -59)
|
||||
end
|
||||
end,
|
||||
|
||||
-- called to set an external table to store status in
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
self:ApplyStatus()
|
||||
end,
|
||||
|
||||
["ApplyStatus"] = function(self)
|
||||
local status = self.status or self.localstatus
|
||||
local frame = self.frame
|
||||
self:SetWidth(status.width or self.frame:GetWidth())
|
||||
self:SetHeight(status.height or self.frame:GetHeight())
|
||||
frame:ClearAllPoints()
|
||||
if status.top and status.left then
|
||||
frame:SetPoint("TOP", UIParent, "BOTTOM", 0, status.top)
|
||||
frame:SetPoint("LEFT", UIParent, "LEFT", status.left, 0)
|
||||
else
|
||||
frame:SetPoint("CENTER")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frameName = Type..AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local frameDefaults = {
|
||||
x = UIParent:GetWidth()/2,
|
||||
y = UIParent:GetHeight()/2,
|
||||
width = 823,
|
||||
height = 686,
|
||||
scale = 1,
|
||||
}
|
||||
local frame = TSMAPI:CreateMovableFrame(frameName, frameDefaults)
|
||||
frame:SetFrameStrata("MEDIUM")
|
||||
TSMAPI.Design:SetFrameBackdropColor(frame)
|
||||
frame:SetResizable(true)
|
||||
frame:SetMinResize(600, 400)
|
||||
frame:SetScript("OnHide", Frame_OnClose)
|
||||
frame.toMove = frame
|
||||
tinsert(UISpecialFrames, frameName)
|
||||
|
||||
local closebutton = CreateFrame("Button", nil, frame)
|
||||
TSMAPI.Design:SetContentColor(closebutton)
|
||||
local highlight = closebutton:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetTexture(1, 1, 1, .2)
|
||||
highlight:SetBlendMode("BLEND")
|
||||
closebutton.highlight = highlight
|
||||
closebutton:SetPoint("BOTTOMRIGHT", -29, -14)
|
||||
closebutton:SetHeight(29)
|
||||
closebutton:SetWidth(86)
|
||||
closebutton:SetScript("OnClick", CloseButton_OnClick)
|
||||
closebutton:Show()
|
||||
local label = closebutton:CreateFontString()
|
||||
label:SetPoint("TOP")
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetJustifyV("CENTER")
|
||||
label:SetHeight(28)
|
||||
label:SetFont(TSMAPI.Design:GetContentFont(), 28)
|
||||
TSMAPI.Design:SetWidgetTextColor(label)
|
||||
label:SetText(CLOSE)
|
||||
closebutton:SetFontString(label)
|
||||
|
||||
local iconBtn = CreateFrame("Button", nil, frame)
|
||||
iconBtn:SetWidth(286)
|
||||
iconBtn:SetHeight(286)
|
||||
iconBtn:SetPoint("TOP", 0, 174)
|
||||
iconBtn:SetScript("OnMouseDown", Frame_OnMouseDown)
|
||||
iconBtn:SetScript("OnMouseUp", Frame_OnMouseUp)
|
||||
iconBtn.toMove = frame
|
||||
local icon = iconBtn:CreateTexture()
|
||||
icon:SetAllPoints()
|
||||
icon:SetTexture("Interface\\Addons\\TradeSkillMaster\\Media\\TSM_Icon_Pocket")
|
||||
frame.icon = icon
|
||||
|
||||
local sizer = CreateFrame("Frame", nil, frame)
|
||||
sizer:SetPoint("BOTTOMRIGHT", -2, 2)
|
||||
sizer:SetWidth(20)
|
||||
sizer:SetHeight(20)
|
||||
sizer:EnableMouse()
|
||||
sizer:SetScript("OnMouseDown",Sizer_OnMouseDown)
|
||||
sizer:SetScript("OnMouseUp", Sizer_OnMouseUp)
|
||||
local image = sizer:CreateTexture(nil, "BACKGROUND")
|
||||
image:SetAllPoints()
|
||||
image:SetTexture("Interface\\Addons\\TradeSkillMaster\\Media\\Sizer")
|
||||
|
||||
local content = CreateFrame("Frame", nil, frame)
|
||||
content:SetPoint("TOPLEFT", 11, -62)
|
||||
content:SetPoint("BOTTOMRIGHT", -11, 20)
|
||||
|
||||
local titletext = frame:CreateFontString()
|
||||
titletext:SetPoint("TOP", 0, -32)
|
||||
titletext:SetHeight(22)
|
||||
titletext:SetJustifyH("CENTER")
|
||||
titletext:SetJustifyV("CENTER")
|
||||
titletext:SetFont(TSMAPI.Design:GetContentFont(), 22)
|
||||
TSMAPI.Design:SetTitleTextColor(titletext)
|
||||
|
||||
local icontext = iconBtn:CreateFontString(nil, "OVERLAY")
|
||||
icontext:SetPoint("TOP", frame, "TOP", 0, 14)
|
||||
icontext:SetHeight(29)
|
||||
icontext:SetJustifyH("CENTER")
|
||||
icontext:SetJustifyV("CENTER")
|
||||
icontext:SetFont(TSMAPI.Design:GetContentFont(), 27)
|
||||
icontext:SetTextColor(unpack(ICON_TEXT_COLOR))
|
||||
|
||||
-- local helpButton = CreateFrame("Button", nil, frame, "MainHelpPlateButton")
|
||||
local helpButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
||||
helpButton:SetPoint("BOTTOMLEFT", -10, -30)
|
||||
helpButton:SetScript("OnEnter", function(self)
|
||||
HelpPlateTooltip.ArrowRIGHT:Show()
|
||||
HelpPlateTooltip.ArrowGlowRIGHT:Show()
|
||||
HelpPlateTooltip:SetPoint("LEFT", self, "RIGHT", 10, 0)
|
||||
HelpPlateTooltip.Text:SetText(L["Click this to open TSM Assistant."])
|
||||
HelpPlateTooltip:Show()
|
||||
end)
|
||||
helpButton:SetScript("OnLeave", function(self)
|
||||
HelpPlateTooltip.ArrowRIGHT:Hide()
|
||||
HelpPlateTooltip.ArrowGlowRIGHT:Hide()
|
||||
HelpPlateTooltip:ClearAllPoints()
|
||||
HelpPlateTooltip:Hide()
|
||||
end)
|
||||
helpButton:SetScript("OnClick", TSM.Assistant.Open)
|
||||
|
||||
local widget = {
|
||||
type = Type,
|
||||
localstatus = {},
|
||||
frame = frame,
|
||||
-- container for children
|
||||
content = content,
|
||||
-- changable labels
|
||||
titletext = titletext,
|
||||
icontext = icontext,
|
||||
-- containers for the icons - size/pos set by OnWidthSet
|
||||
topLeftIcons = CreateFrame("Frame", nil, frame),
|
||||
topRightIcons = CreateFrame("Frame", nil, frame),
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
closebutton.obj = widget
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,85 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-MultiLabel.lua
|
||||
-- This MultiLabel widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMMultiLabel", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- height is set dynamically by the text size
|
||||
self:SetWidth(200)
|
||||
for i=1, #self.labels do
|
||||
self.labels[i]:SetText()
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
self:SetLabels(self.info)
|
||||
end,
|
||||
|
||||
["SetLabels"] = function(self, info)
|
||||
self.info = info
|
||||
local totalWidth = self.frame:GetWidth() or 0
|
||||
local usedWidth = 0
|
||||
local maxHeight = 0
|
||||
for i=1, #info do
|
||||
if not self.labels[i] then
|
||||
self.labels[i] = self.frame:CreateFontString(nil, "BACKGROUND")
|
||||
self.labels[i]:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.labels[i])
|
||||
self.labels[i]:SetJustifyH("LEFT")
|
||||
self.labels[i]:SetJustifyV("TOP")
|
||||
end
|
||||
self.labels[i]:SetText(info[i].text)
|
||||
self.labels[i]:SetPoint("TOPLEFT", self.frame, "TOPLEFT", usedWidth, 0)
|
||||
|
||||
local labelWidth = totalWidth*(info[i].relativeWidth or 0)
|
||||
labelWidth = min(labelWidth, totalWidth-usedWidth)
|
||||
self.labels[i]:SetWidth(labelWidth)
|
||||
usedWidth = usedWidth + labelWidth
|
||||
|
||||
if self.labels[i]:GetHeight() > maxHeight then
|
||||
maxHeight = self.labels[i]:GetHeight()
|
||||
end
|
||||
end
|
||||
self.frame:SetHeight(maxHeight)
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local widget = {
|
||||
labels = {},
|
||||
info = {},
|
||||
frame = frame,
|
||||
type = Type,
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,21 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-TSMMultiLineEditBox.lua
|
||||
-- This TSMMultiLineEditBox widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMMultiLineEditBox", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
local function Constructor()
|
||||
local widget = AceGUI:Create("MultiLineEditBox")
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,223 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
|
||||
-- This ScrollFrame container is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMScrollFrame", 2
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, assert, type = pairs, assert, type
|
||||
local min, max, floor, abs = math.min, math.max, math.floor, math.abs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function FixScrollOnUpdate(frame)
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
frame.obj:FixScroll()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function ScrollFrame_OnMouseWheel(frame, value)
|
||||
frame.obj:MoveScroll(value)
|
||||
end
|
||||
|
||||
local function ScrollFrame_OnSizeChanged(frame)
|
||||
frame:SetScript("OnUpdate", FixScrollOnUpdate)
|
||||
end
|
||||
|
||||
local function ScrollBar_OnScrollValueChanged(frame, value)
|
||||
frame.obj:SetScroll(value)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetScroll(0)
|
||||
self:FixScroll()
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
for k in pairs(self.localstatus) do
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
self.scrollframe:SetPoint("BOTTOMRIGHT")
|
||||
self.scrollbar:Hide()
|
||||
self.scrollBarShown = nil
|
||||
self.content.height, self.content.width = nil, nil
|
||||
end,
|
||||
|
||||
["SetScroll"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
local viewheight = self.scrollframe:GetHeight()
|
||||
local height = self.content:GetHeight()
|
||||
local offset
|
||||
|
||||
if viewheight > height then
|
||||
offset = 0
|
||||
else
|
||||
offset = floor((height - viewheight) / 1000.0 * value)
|
||||
end
|
||||
self.content:ClearAllPoints()
|
||||
self.content:SetPoint("TOPLEFT", 0, offset)
|
||||
self.content:SetPoint("TOPRIGHT", 0, offset)
|
||||
status.offset = offset
|
||||
status.scrollvalue = value
|
||||
end,
|
||||
|
||||
["MoveScroll"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
|
||||
|
||||
if self.scrollBarShown then
|
||||
local diff = height - viewheight
|
||||
local delta = 1
|
||||
if value < 0 then
|
||||
delta = -1
|
||||
end
|
||||
self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
|
||||
end
|
||||
end,
|
||||
|
||||
["FixScroll"] = function(self)
|
||||
if self.updateLock then return end
|
||||
self.updateLock = true
|
||||
local status = self.status or self.localstatus
|
||||
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
|
||||
local offset = status.offset or 0
|
||||
local curvalue = self.scrollbar:GetValue()
|
||||
-- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
|
||||
-- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
|
||||
if viewheight < height + 2 then
|
||||
if self.scrollBarShown then
|
||||
self.scrollBarShown = nil
|
||||
self.scrollbar:Hide()
|
||||
self.scrollbar:SetValue(0)
|
||||
self.scrollframe:SetPoint("BOTTOMRIGHT")
|
||||
self:DoLayout()
|
||||
end
|
||||
else
|
||||
if not self.scrollBarShown then
|
||||
self.scrollBarShown = true
|
||||
self.scrollbar:Show()
|
||||
self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
|
||||
self:DoLayout()
|
||||
end
|
||||
local value = (offset / (viewheight - height) * 1000)
|
||||
if value > 1000 then value = 1000 end
|
||||
self.scrollbar:SetValue(value)
|
||||
self:SetScroll(value)
|
||||
if value < 1000 then
|
||||
self.content:ClearAllPoints()
|
||||
self.content:SetPoint("TOPLEFT", 0, offset)
|
||||
self.content:SetPoint("TOPRIGHT", 0, offset)
|
||||
status.offset = offset
|
||||
end
|
||||
end
|
||||
self.updateLock = nil
|
||||
end,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
self.content:SetHeight(height or (0 + 20))
|
||||
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
|
||||
|
||||
-- no idea why, but this MUST be here to avoid glitches with the scrollbar not showing up when it should
|
||||
self.content:GetHeight()
|
||||
end,
|
||||
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
if not status.scrollvalue then
|
||||
status.scrollvalue = 0
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
content.width = width
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
content.height = height
|
||||
end
|
||||
}
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local scrollframe = CreateFrame("ScrollFrame", nil, frame)
|
||||
scrollframe:SetPoint("TOPLEFT")
|
||||
scrollframe:SetPoint("BOTTOMRIGHT")
|
||||
scrollframe:EnableMouseWheel(true)
|
||||
scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
|
||||
scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
|
||||
|
||||
local scrollbar = CreateFrame("Slider", ("TSMScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
|
||||
scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 6, -4)
|
||||
scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 6, 4)
|
||||
scrollbar:SetMinMaxValues(0, 1000)
|
||||
scrollbar:SetValueStep(1)
|
||||
scrollbar:SetValue(0)
|
||||
scrollbar:SetWidth(12)
|
||||
scrollbar:Hide()
|
||||
scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
|
||||
|
||||
local thumbTex = scrollbar:GetThumbTexture()
|
||||
thumbTex:SetPoint("CENTER")
|
||||
TSMAPI.Design:SetContentColor(thumbTex)
|
||||
thumbTex:SetHeight(150)
|
||||
thumbTex:SetWidth(scrollbar:GetWidth())
|
||||
|
||||
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
|
||||
scrollbg:SetAllPoints(scrollbar)
|
||||
TSMAPI.Design:SetFrameColor(scrollbg)
|
||||
|
||||
_G[scrollbar:GetName().."ScrollUpButton"]:Hide()
|
||||
_G[scrollbar:GetName().."ScrollDownButton"]:Hide()
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, scrollframe)
|
||||
content:SetPoint("TOPLEFT")
|
||||
content:SetPoint("TOPRIGHT")
|
||||
content:SetHeight(400)
|
||||
scrollframe:SetScrollChild(content)
|
||||
|
||||
local widget = {
|
||||
localstatus = { scrollvalue = 0 },
|
||||
scrollframe = scrollframe,
|
||||
scrollbar = scrollbar,
|
||||
content = content,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
scrollframe.obj, scrollbar.obj = widget, widget
|
||||
widget.Add = TSMAPI.AddGUIElement
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,21 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- This SimpleGroup container is modified to fit TSM's theme / needs
|
||||
local Type, Version = "TSMSimpleGroup", 2
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
local function Constructor()
|
||||
local container = AceGUI:Create("SimpleGroup")
|
||||
container.type = Type
|
||||
container.Add = TSMAPI.AddGUIElement
|
||||
return AceGUI:RegisterAsContainer(container)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,279 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
|
||||
-- This Slider widget is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMSlider", 2
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local min, max, floor = math.min, math.max, math.floor
|
||||
local tonumber, pairs = tonumber, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function UpdateText(self)
|
||||
local value = self.value or 0
|
||||
if self.ispercent then
|
||||
self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
|
||||
else
|
||||
self.editbox:SetText(floor(value * 100 + 0.5) / 100)
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateLabels(self)
|
||||
local min, max = (self.min or 0), (self.max or 100)
|
||||
if self.ispercent then
|
||||
self.lowtext:SetFormattedText("%s%%", (min * 100))
|
||||
self.hightext:SetFormattedText("%s%%", (max * 100))
|
||||
else
|
||||
self.lowtext:SetText(min)
|
||||
self.hightext:SetText(max)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Frame_OnMouseDown(frame)
|
||||
frame.obj.slider:EnableMouseWheel(true)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Slider_OnValueChanged(frame)
|
||||
local self = frame.obj
|
||||
if not frame.setup then
|
||||
local newvalue = frame:GetValue()
|
||||
-- workaround for 5.4 issues
|
||||
if self.step and self.step > 0 then
|
||||
local min_value = self.min or 0
|
||||
newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value
|
||||
end
|
||||
if newvalue ~= self.value and not self.disabled then
|
||||
self.value = newvalue
|
||||
self:Fire("OnValueChanged", newvalue)
|
||||
end
|
||||
if self.value then
|
||||
UpdateText(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Slider_OnMouseUp(frame, button)
|
||||
local self = frame.obj
|
||||
self.slider:EnableMouseWheel(true)
|
||||
self:Fire("OnMouseUp", self.value)
|
||||
end
|
||||
|
||||
local function Slider_OnMouseWheel(frame, v)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
local value = self.value
|
||||
if v > 0 then
|
||||
value = min(value + (self.step or 1), self.max)
|
||||
else
|
||||
value = max(value - (self.step or 1), self.min)
|
||||
end
|
||||
self.slider:SetValue(value)
|
||||
end
|
||||
end
|
||||
|
||||
local function EditBox_OnMouseUp(frame)
|
||||
local self = frame.obj
|
||||
end
|
||||
|
||||
local function EditBox_OnEscapePressed(frame)
|
||||
frame:ClearFocus()
|
||||
end
|
||||
|
||||
local function EditBox_OnEnterPressed(frame)
|
||||
local self = frame.obj
|
||||
local value = frame:GetText()
|
||||
if self.ispercent then
|
||||
value = value:gsub('%%', '')
|
||||
value = tonumber(value) / 100
|
||||
else
|
||||
value = tonumber(value)
|
||||
end
|
||||
|
||||
if value then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
self.slider:SetValue(value)
|
||||
self:Fire("OnMouseUp", value)
|
||||
frame:ClearFocus()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetWidth(200)
|
||||
self:SetHeight(44)
|
||||
self:SetDisabled(false)
|
||||
self:SetIsPercent(nil)
|
||||
self:SetSliderValues(0,100,1)
|
||||
self:SetValue(0)
|
||||
self.slider:EnableMouseWheel(false)
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
TSMAPI.Design:SetWidgetTextColor(self.editbox, disabled)
|
||||
self.slider:EnableMouse(not disabled)
|
||||
self.editbox:EnableMouse(not disabled)
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.label, disabled)
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.hightext, disabled)
|
||||
TSMAPI.Design:SetWidgetLabelColor(self.lowtext, disabled)
|
||||
if disabled then
|
||||
self.editbox:ClearFocus()
|
||||
end
|
||||
end,
|
||||
|
||||
["SetValue"] = function(self, value)
|
||||
self.slider.setup = true
|
||||
self.slider:SetValue(value)
|
||||
self.value = value
|
||||
UpdateText(self)
|
||||
self.slider.setup = nil
|
||||
end,
|
||||
|
||||
["GetValue"] = function(self)
|
||||
return self.value
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
self.label:SetText(text)
|
||||
end,
|
||||
|
||||
["SetSliderValues"] = function(self, min, max, step)
|
||||
local frame = self.slider
|
||||
frame.setup = true
|
||||
self.min = min
|
||||
self.max = max
|
||||
self.step = step
|
||||
frame:SetMinMaxValues(min or 0,max or 100)
|
||||
UpdateLabels(self)
|
||||
frame:SetValueStep(step or 1)
|
||||
if self.value then
|
||||
frame:SetValue(self.value)
|
||||
end
|
||||
frame.setup = nil
|
||||
end,
|
||||
|
||||
["SetIsPercent"] = function(self, value)
|
||||
self.ispercent = value
|
||||
UpdateLabels(self)
|
||||
UpdateText(self)
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY")
|
||||
label:SetPoint("TOPLEFT", 0, -2)
|
||||
label:SetPoint("TOPRIGHT", 0, -2)
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetHeight(15)
|
||||
label:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
|
||||
local slider = CreateFrame("Slider", nil, frame)
|
||||
slider:SetOrientation("HORIZONTAL")
|
||||
slider:SetHeight(6)
|
||||
slider:SetHitRectInsets(0, 0, -10, 0)
|
||||
slider:SetPoint("TOPLEFT", label, "BOTTOMLEFT", 3, -4)
|
||||
slider:SetPoint("TOPRIGHT", label, "BOTTOMRIGHT", -20, -4)
|
||||
slider:SetValue(0)
|
||||
slider:SetScript("OnValueChanged",Slider_OnValueChanged)
|
||||
slider:SetScript("OnEnter", Control_OnEnter)
|
||||
slider:SetScript("OnLeave", Control_OnLeave)
|
||||
slider:SetScript("OnMouseUp", Slider_OnMouseUp)
|
||||
slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
|
||||
TSMAPI.Design:SetFrameColor(slider)
|
||||
local thumbTex = slider:CreateTexture(nil, "ARTWORK")
|
||||
thumbTex:SetPoint("CENTER")
|
||||
TSMAPI.Design:SetContentColor(thumbTex)
|
||||
thumbTex:SetHeight(15)
|
||||
thumbTex:SetWidth(8)
|
||||
slider:SetThumbTexture(thumbTex)
|
||||
|
||||
local lowtext = slider:CreateFontString(nil, "ARTWORK")
|
||||
lowtext:SetFont(TSMAPI.Design:GetContentFont("small"))
|
||||
lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, -4)
|
||||
|
||||
local hightext = slider:CreateFontString(nil, "ARTWORK")
|
||||
hightext:SetFont(TSMAPI.Design:GetContentFont("small"))
|
||||
hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, -4)
|
||||
|
||||
local editbox = CreateFrame("EditBox", nil, frame)
|
||||
editbox:SetAutoFocus(false)
|
||||
editbox:SetPoint("TOP", slider, "BOTTOM", 0, -6)
|
||||
editbox:SetHeight(15)
|
||||
editbox:SetWidth(70)
|
||||
editbox:SetJustifyH("CENTER")
|
||||
editbox:EnableMouse(true)
|
||||
TSMAPI.Design:SetContentColor(editbox)
|
||||
editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
|
||||
editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
|
||||
editbox:SetScript("OnEnter", Control_OnEnter)
|
||||
editbox:SetScript("OnLeave", Control_OnLeave)
|
||||
editbox:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
editbox:SetShadowColor(0, 0, 0, 0)
|
||||
|
||||
local widget = {
|
||||
label = label,
|
||||
slider = slider,
|
||||
lowtext = lowtext,
|
||||
hightext = hightext,
|
||||
editbox = editbox,
|
||||
alignoffset = 25,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
slider.obj, editbox.obj, frame.obj = widget, widget, widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,312 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
|
||||
-- This TabGroup container is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMTabGroup", 2
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function TabResize(tab, padding, width)
|
||||
local tabName = tab:GetName()
|
||||
|
||||
local sideWidths = 8
|
||||
tab:SetWidth(width + padding + sideWidths)
|
||||
end
|
||||
|
||||
local function UpdateTabLook(frame)
|
||||
if frame.disabled then
|
||||
TSMAPI.Design:SetWidgetLabelColor(frame.text, true)
|
||||
frame:Disable()
|
||||
frame.text = frame:GetText()
|
||||
frame.bottom:Hide()
|
||||
elseif frame.selected then
|
||||
TSMAPI.Design:SetWidgetLabelColor(frame.text)
|
||||
frame:Disable()
|
||||
TSMAPI.Design:SetFrameColor(frame.image)
|
||||
frame.bottom:Show()
|
||||
frame:SetHeight(29)
|
||||
|
||||
if GameTooltip:IsOwned(frame) then
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
else
|
||||
TSMAPI.Design:SetWidgetTextColor(frame.text)
|
||||
frame:Enable()
|
||||
TSMAPI.Design:SetContentColor(frame.image)
|
||||
frame.bottom:Hide()
|
||||
frame:SetHeight(24)
|
||||
end
|
||||
end
|
||||
|
||||
local function Tab_SetText(frame, text)
|
||||
frame:_SetText(text)
|
||||
local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
|
||||
TabResize(frame, 0, frame:GetFontString():GetStringWidth())
|
||||
end
|
||||
|
||||
local function Tab_SetSelected(frame, selected)
|
||||
frame.selected = selected
|
||||
UpdateTabLook(frame)
|
||||
end
|
||||
|
||||
local function Tab_SetDisabled(frame, disabled)
|
||||
frame.disabled = disabled
|
||||
UpdateTabLook(frame)
|
||||
end
|
||||
|
||||
local function BuildTabsOnUpdate(frame)
|
||||
local self = frame.obj
|
||||
self:BuildTabs()
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Tab_OnClick(frame)
|
||||
if not (frame.selected or frame.disabled) then
|
||||
PlaySound("igCharacterInfoTab")
|
||||
frame.obj:SelectTab(frame.value)
|
||||
end
|
||||
end
|
||||
|
||||
local function Tab_OnEnter(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
|
||||
end
|
||||
|
||||
local function Tab_OnLeave(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self) end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
for k in pairs(self.localstatus) do
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
self.tablist = nil
|
||||
for _, tab in pairs(self.tabs) do
|
||||
tab:Hide()
|
||||
end
|
||||
end,
|
||||
|
||||
["CreateTab"] = function(self, id)
|
||||
local tabname = ("TSMTabGroup%dTab%d"):format(self.num, id)
|
||||
local tab = CreateFrame("Button", tabname, self.border)
|
||||
tab.obj = self
|
||||
tab.id = id
|
||||
tab:SetHeight(24)
|
||||
TSMAPI.Design:SetFrameColor(tab)
|
||||
tab:SetBackdropColor(0, 0, 0, 0)
|
||||
local image = tab:CreateTexture(nil, "BACKGROUND")
|
||||
image:SetAllPoints()
|
||||
TSMAPI.Design:SetContentColor(image)
|
||||
tab.image = image
|
||||
local bottom = tab:CreateTexture(nil, "OVERLAY")
|
||||
bottom:SetHeight(2)
|
||||
bottom:SetPoint("BOTTOMLEFT", 1, -1)
|
||||
bottom:SetPoint("BOTTOMRIGHT", -1, -1)
|
||||
TSMAPI.Design:SetFrameColor(bottom)
|
||||
tab.bottom = bottom
|
||||
local highlight = tab:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetTexture(1, 1, 1, .2)
|
||||
highlight:SetBlendMode("BLEND")
|
||||
tab.highlight = highlight
|
||||
|
||||
tab.text = tab:CreateFontString()
|
||||
tab.text:SetPoint("LEFT", 3, -1)
|
||||
tab.text:SetPoint("RIGHT", -3, -1)
|
||||
tab.text:SetJustifyH("CENTER")
|
||||
tab.text:SetJustifyV("CENTER")
|
||||
tab.text:SetFont(TSMAPI.Design:GetContentFont(), 18)
|
||||
tab:SetFontString(tab.text)
|
||||
|
||||
tab:SetScript("OnClick", Tab_OnClick)
|
||||
tab:SetScript("OnEnter", Tab_OnEnter)
|
||||
tab:SetScript("OnLeave", Tab_OnLeave)
|
||||
|
||||
tab._SetText = tab.SetText
|
||||
tab.SetText = Tab_SetText
|
||||
tab.SetSelected = Tab_SetSelected
|
||||
tab.SetDisabled = Tab_SetDisabled
|
||||
|
||||
return tab
|
||||
end,
|
||||
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
end,
|
||||
|
||||
["SelectTab"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
local found
|
||||
for i, v in ipairs(self.tabs) do
|
||||
if v.value == value then
|
||||
v:SetSelected(true)
|
||||
found = true
|
||||
else
|
||||
v:SetSelected(false)
|
||||
end
|
||||
end
|
||||
status.selected = value
|
||||
if found then
|
||||
self:Fire("OnGroupSelected", value)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetTabs"] = function(self, tabs)
|
||||
self.tablist = tabs
|
||||
self:BuildTabs()
|
||||
end,
|
||||
|
||||
["ReloadTab"] = function(self)
|
||||
local status = self.status or self.localstatus
|
||||
if status and status.selected then
|
||||
self:Fire("OnGroupSelected", status.selected)
|
||||
end
|
||||
end,
|
||||
|
||||
["BuildTabs"] = function(self)
|
||||
local status = self.status or self.localstatus
|
||||
local tablist = self.tablist
|
||||
local tabs = self.tabs
|
||||
|
||||
if not tablist then return end
|
||||
|
||||
local numTabs = #tablist
|
||||
local width = self.frame.width or self.frame:GetWidth() or 0
|
||||
|
||||
-- Show tabs and set text.
|
||||
for i, v in ipairs(tablist) do
|
||||
local tab = tabs[i]
|
||||
if not tab then
|
||||
tab = self:CreateTab(i)
|
||||
tabs[i] = tab
|
||||
end
|
||||
|
||||
tab:Show()
|
||||
tab:SetText(v.text)
|
||||
tab:SetDisabled(v.disabled)
|
||||
tab.value = v.value
|
||||
end
|
||||
|
||||
-- hide tabs which aren't in use
|
||||
for i=numTabs+1, #tabs do
|
||||
tabs[i]:Hide()
|
||||
end
|
||||
|
||||
--anchor the rows as defined and resize tabs
|
||||
for i=1, numTabs do
|
||||
local tab = tabs[i]
|
||||
tab:ClearAllPoints()
|
||||
if i == 1 then
|
||||
tab:SetPoint("BOTTOMLEFT", self.frame, "TOPLEFT", 5, -31)
|
||||
else
|
||||
tab:SetPoint("BOTTOMLEFT", tabs[i-1], "BOTTOMRIGHT", 4, 0)
|
||||
end
|
||||
end
|
||||
|
||||
for i=1, numTabs do
|
||||
TabResize(tabs[i], 4, tabs[i]:GetFontString():GetStringWidth())
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 60
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
self:BuildTabs(self)
|
||||
self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 30
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
if self.noAutoHeight then return end
|
||||
self:SetHeight((height or 0) + 30)
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local PaneBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame",nil,UIParent)
|
||||
frame:SetHeight(100)
|
||||
frame:SetWidth(100)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
local border = CreateFrame("Frame", nil, frame)
|
||||
border:SetPoint("TOPLEFT", 1, -30)
|
||||
border:SetPoint("BOTTOMRIGHT", -1, 3)
|
||||
TSMAPI.Design:SetFrameColor(border)
|
||||
|
||||
local content = CreateFrame("Frame", nil, border)
|
||||
content:SetPoint("TOPLEFT", 8, -8)
|
||||
content:SetPoint("BOTTOMRIGHT", -8, 8)
|
||||
|
||||
local widget = {
|
||||
num = num,
|
||||
frame = frame,
|
||||
localstatus = {},
|
||||
border = border,
|
||||
tabs = {},
|
||||
content = content,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
widget.Add = TSMAPI.AddGUIElement
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,735 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
|
||||
-- This TreeGroup container is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMTreeGroup", 2
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
|
||||
local math_min, math_max, floor = math.min, math.max, floor
|
||||
local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Recycling functions
|
||||
local new, del
|
||||
do
|
||||
local pool = setmetatable({},{__mode='k'})
|
||||
function new()
|
||||
local t = next(pool)
|
||||
if t then
|
||||
pool[t] = nil
|
||||
return t
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
function del(t)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
pool[t] = true
|
||||
end
|
||||
end
|
||||
|
||||
local DEFAULT_TREE_WIDTH = 175
|
||||
local DEFAULT_TREE_SIZABLE = true
|
||||
local HIGHLIGHT_COLOR = {80/255, 180/255, 180/255}
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function GetButtonUniqueValue(line)
|
||||
local parent = line.parent
|
||||
if parent and parent.value then
|
||||
return GetButtonUniqueValue(parent).."\001"..line.value
|
||||
else
|
||||
return line.value
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
|
||||
local self = button.obj
|
||||
local toggle = button.toggle
|
||||
local frame = self.frame
|
||||
local text = treeline.text or ""
|
||||
local icon = treeline.icon
|
||||
local iconCoords = treeline.iconCoords
|
||||
local level = treeline.level
|
||||
local value = treeline.value
|
||||
local uniquevalue = treeline.uniquevalue
|
||||
local disabled = treeline.disabled
|
||||
|
||||
button.treeline = treeline
|
||||
button.value = value
|
||||
button.uniquevalue = uniquevalue
|
||||
if selected then
|
||||
button:LockHighlight()
|
||||
button.selected = true
|
||||
else
|
||||
button:UnlockHighlight()
|
||||
button.selected = false
|
||||
end
|
||||
local normalTexture = button:GetNormalTexture()
|
||||
local line = button.line
|
||||
button.level = level
|
||||
if level == 1 then
|
||||
button.text:SetFont(TSMAPI.Design:GetBoldFont(), 15)
|
||||
TSMAPI.Design:SetTitleTextColor(button.text)
|
||||
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
|
||||
else
|
||||
button.text:SetFont(TSMAPI.Design:GetContentFont("normal"))
|
||||
TSMAPI.Design:SetWidgetLabelColor(button.text)
|
||||
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
|
||||
end
|
||||
|
||||
if disabled then
|
||||
button:EnableMouse(false)
|
||||
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
|
||||
else
|
||||
button.text:SetText(text)
|
||||
button:EnableMouse(true)
|
||||
end
|
||||
|
||||
if icon then
|
||||
button.icon:SetTexture(icon)
|
||||
button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1)
|
||||
else
|
||||
button.icon:SetTexture(nil)
|
||||
end
|
||||
|
||||
if iconCoords then
|
||||
button.icon:SetTexCoord(unpack(iconCoords))
|
||||
else
|
||||
button.icon:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
|
||||
if canExpand then
|
||||
if not isExpanded then
|
||||
toggle.text:SetFont(TSMAPI.Design:GetBoldFont(), 24)
|
||||
toggle.text:SetText("+")
|
||||
else
|
||||
toggle.text:SetFont(TSMAPI.Design:GetBoldFont(), 30)
|
||||
toggle.text:SetText("-")
|
||||
end
|
||||
toggle:Show()
|
||||
else
|
||||
toggle:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function ShouldDisplayLevel(tree)
|
||||
local result = false
|
||||
for k, v in ipairs(tree) do
|
||||
if v.children == nil and v.visible ~= false then
|
||||
result = true
|
||||
elseif v.children then
|
||||
result = result or ShouldDisplayLevel(v.children)
|
||||
end
|
||||
if result then return result end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function addLine(self, v, tree, level, parent)
|
||||
local line = new()
|
||||
line.value = v.value
|
||||
line.text = v.text
|
||||
line.icon = v.icon
|
||||
line.iconCoords = v.iconCoords
|
||||
line.disabled = v.disabled
|
||||
line.tree = tree
|
||||
line.level = level
|
||||
line.parent = parent
|
||||
line.visible = v.visible
|
||||
line.uniquevalue = GetButtonUniqueValue(line)
|
||||
if v.children then
|
||||
line.hasChildren = true
|
||||
else
|
||||
line.hasChildren = nil
|
||||
end
|
||||
self.lines[#self.lines+1] = line
|
||||
return line
|
||||
end
|
||||
|
||||
--fire an update after one frame to catch the treeframes height
|
||||
local function FirstFrameUpdate(frame)
|
||||
local self = frame.obj
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
self:RefreshTree()
|
||||
end
|
||||
|
||||
local function BuildUniqueValue(...)
|
||||
local n = select('#', ...)
|
||||
if n == 1 then
|
||||
return ...
|
||||
else
|
||||
return (...).."\001"..BuildUniqueValue(select(2,...))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Expand_OnClick(frame)
|
||||
local button = frame.button
|
||||
local self = button.obj
|
||||
local status = (self.status or self.localstatus).groups
|
||||
status[button.uniquevalue] = not status[button.uniquevalue]
|
||||
self:RefreshTree()
|
||||
end
|
||||
|
||||
local function Button_OnClick(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnClick", frame.uniquevalue, frame.selected)
|
||||
if not frame.selected then
|
||||
self:SetSelected(frame.uniquevalue)
|
||||
frame.selected = true
|
||||
frame:LockHighlight()
|
||||
self:RefreshTree()
|
||||
end
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Button_OnDoubleClick(button)
|
||||
local self = button.obj
|
||||
local status = self.status or self.localstatus
|
||||
local status = (self.status or self.localstatus).groups
|
||||
status[button.uniquevalue] = not status[button.uniquevalue]
|
||||
self:RefreshTree()
|
||||
end
|
||||
|
||||
local function Button_OnEnter(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnButtonEnter", frame.uniquevalue, frame)
|
||||
|
||||
if self.enabletooltips then
|
||||
GameTooltip:SetOwner(frame, "ANCHOR_NONE")
|
||||
GameTooltip:SetPoint("LEFT",frame,"RIGHT")
|
||||
-- strip out color codes
|
||||
local text = frame.text:GetText() or ""
|
||||
text = gsub(text, "|cff[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]", "")
|
||||
text = gsub(text, "|r", "")
|
||||
GameTooltip:SetText(text, 1, .82, 0, 1)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local function Button_OnLeave(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnButtonLeave", frame.uniquevalue, frame)
|
||||
|
||||
if self.enabletooltips then
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function OnScrollValueChanged(frame, value)
|
||||
if frame.obj.noupdate then return end
|
||||
local self = frame.obj
|
||||
local status = self.status or self.localstatus
|
||||
status.scrollvalue = floor(value + 0.5)
|
||||
self:RefreshTree()
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Tree_OnSizeChanged(frame)
|
||||
frame.obj:RefreshTree()
|
||||
end
|
||||
|
||||
local function Tree_OnMouseWheel(frame, delta)
|
||||
local self = frame.obj
|
||||
if self.showscroll then
|
||||
local scrollbar = self.scrollbar
|
||||
local min, max = scrollbar:GetMinMaxValues()
|
||||
local value = scrollbar:GetValue()
|
||||
local newvalue = math_min(max,math_max(min,value - delta))
|
||||
if value ~= newvalue then
|
||||
scrollbar:SetValue(newvalue)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Dragger_OnLeave(frame)
|
||||
frame:SetBackdropColor(1, 1, 1, 0)
|
||||
end
|
||||
|
||||
local function Dragger_OnEnter(frame)
|
||||
frame:SetBackdropColor(1, 1, 1, 0.8)
|
||||
end
|
||||
|
||||
local function Dragger_OnMouseDown(frame)
|
||||
local treeframe = frame:GetParent()
|
||||
treeframe:StartSizing("RIGHT")
|
||||
end
|
||||
|
||||
local function Dragger_OnMouseUp(frame)
|
||||
local treeframe = frame:GetParent()
|
||||
local self = treeframe.obj
|
||||
local frame = treeframe:GetParent()
|
||||
treeframe:StopMovingOrSizing()
|
||||
treeframe:SetUserPlaced(false)
|
||||
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
|
||||
treeframe:SetHeight(0)
|
||||
treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0)
|
||||
treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
|
||||
|
||||
local status = self.status or self.localstatus
|
||||
status.treewidth = treeframe:GetWidth()
|
||||
|
||||
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
|
||||
-- recalculate the content width
|
||||
treeframe.obj:OnWidthSet(status.fullwidth)
|
||||
-- update the layout of the content
|
||||
treeframe.obj:DoLayout()
|
||||
end
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
|
||||
self:EnableButtonTooltips(true)
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
for k, v in pairs(self.localstatus) do
|
||||
if k == "groups" then
|
||||
for k2 in pairs(v) do
|
||||
v[k2] = nil
|
||||
end
|
||||
else
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
end
|
||||
self.localstatus.scrollvalue = 0
|
||||
self.localstatus.treewidth = DEFAULT_TREE_WIDTH
|
||||
self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
|
||||
end,
|
||||
|
||||
["EnableButtonTooltips"] = function(self, enable)
|
||||
self.enabletooltips = enable
|
||||
end,
|
||||
|
||||
["CreateButton"] = function(self)
|
||||
local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
|
||||
local button = CreateFrame("Button", ("TSMTreeButton%d"):format(num), self.treeframe, "OptionsListButtonTemplate")
|
||||
button.obj = self
|
||||
|
||||
local icon = button:CreateTexture(nil, "OVERLAY")
|
||||
icon:SetWidth(14)
|
||||
icon:SetHeight(14)
|
||||
button.icon = icon
|
||||
|
||||
button.text:SetShadowColor(0, 0, 0, 0)
|
||||
button.text:SetPoint("CENTER")
|
||||
|
||||
button:SetScript("OnClick",Button_OnClick)
|
||||
button:SetScript("OnDoubleClick", Button_OnDoubleClick)
|
||||
button:SetScript("OnEnter",Button_OnEnter)
|
||||
button:SetScript("OnLeave",Button_OnLeave)
|
||||
|
||||
HIGHLIGHT_COLOR[4] = .5
|
||||
button.highlight:SetVertexColor(unpack(HIGHLIGHT_COLOR))
|
||||
|
||||
button.toggle.button = button
|
||||
button.toggle:SetScript("OnClick", Expand_OnClick)
|
||||
local tex = button.toggle:CreateTexture()
|
||||
tex:SetTexture(0, 0, 0, 0)
|
||||
button.toggle:SetNormalTexture(tex)
|
||||
button.toggle:SetPushedTexture(tex)
|
||||
HIGHLIGHT_COLOR[4] = 1
|
||||
button.toggle:GetHighlightTexture():SetVertexColor(unpack(HIGHLIGHT_COLOR))
|
||||
button.toggle:GetHighlightTexture():SetBlendMode("ADD")
|
||||
local text = button.toggle:CreateFontString()
|
||||
TSMAPI.Design:SetWidgetLabelColor(text)
|
||||
text:SetPoint("CENTER")
|
||||
button.toggle.text = text
|
||||
|
||||
return button
|
||||
end,
|
||||
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
if not status.groups then
|
||||
status.groups = {}
|
||||
end
|
||||
if not status.scrollvalue then
|
||||
status.scrollvalue = 0
|
||||
end
|
||||
if not status.treewidth then
|
||||
status.treewidth = DEFAULT_TREE_WIDTH
|
||||
end
|
||||
if status.treesizable == nil then
|
||||
status.treesizable = DEFAULT_TREE_SIZABLE
|
||||
end
|
||||
self:SetTreeWidth(status.treewidth,status.treesizable)
|
||||
self:RefreshTree()
|
||||
end,
|
||||
|
||||
--sets the tree to be displayed
|
||||
["SetTree"] = function(self, tree, filter)
|
||||
self.filter = filter
|
||||
if tree then
|
||||
assert(type(tree) == "table")
|
||||
end
|
||||
self.tree = tree
|
||||
self:RefreshTree()
|
||||
end,
|
||||
|
||||
["BuildLevel"] = function(self, tree, level, parent)
|
||||
local groups = (self.status or self.localstatus).groups
|
||||
local hasChildren = self.hasChildren
|
||||
|
||||
for i, v in ipairs(tree) do
|
||||
if v.children then
|
||||
if not self.filter or ShouldDisplayLevel(v.children) then
|
||||
local line = addLine(self, v, tree, level, parent)
|
||||
if groups[line.uniquevalue] then
|
||||
self:BuildLevel(v.children, level+1, line)
|
||||
end
|
||||
end
|
||||
elseif v.visible ~= false or not self.filter then
|
||||
addLine(self, v, tree, level, parent)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["RefreshTree"] = function(self,scrollToSelection)
|
||||
local buttons = self.buttons
|
||||
local lines = self.lines
|
||||
|
||||
for i, v in ipairs(buttons) do
|
||||
v:Hide()
|
||||
end
|
||||
while lines[1] do
|
||||
local t = tremove(lines)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
del(t)
|
||||
end
|
||||
|
||||
if not self.tree then return end
|
||||
--Build the list of visible entries from the tree and status tables
|
||||
local status = self.status or self.localstatus
|
||||
local groupstatus = status.groups
|
||||
local tree = self.tree
|
||||
|
||||
local treeframe = self.treeframe
|
||||
|
||||
status.scrollToSelection = status.scrollToSelection or scrollToSelection -- needs to be cached in case the control hasn't been drawn yet (code bails out below)
|
||||
|
||||
self:BuildLevel(tree, 1)
|
||||
|
||||
local numlines = #lines
|
||||
|
||||
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
|
||||
if maxlines <= 0 then return end
|
||||
|
||||
local first, last
|
||||
|
||||
scrollToSelection = status.scrollToSelection
|
||||
status.scrollToSelection = nil
|
||||
|
||||
if numlines <= maxlines then
|
||||
--the whole tree fits in the frame
|
||||
status.scrollvalue = 0
|
||||
self:ShowScroll(false)
|
||||
first, last = 1, numlines
|
||||
else
|
||||
self:ShowScroll(true)
|
||||
--scrolling will be needed
|
||||
self.noupdate = true
|
||||
self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
|
||||
--check if we are scrolled down too far
|
||||
if numlines - status.scrollvalue < maxlines then
|
||||
status.scrollvalue = numlines - maxlines
|
||||
end
|
||||
self.noupdate = nil
|
||||
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
|
||||
--show selection?
|
||||
if scrollToSelection and status.selected then
|
||||
local show
|
||||
for i,line in ipairs(lines) do -- find the line number
|
||||
if line.uniquevalue==status.selected then
|
||||
show=i
|
||||
end
|
||||
end
|
||||
if not show then
|
||||
-- selection was deleted or something?
|
||||
elseif show>=first and show<=last then
|
||||
-- all good
|
||||
else
|
||||
-- scrolling needed!
|
||||
if show<first then
|
||||
status.scrollvalue = show-1
|
||||
else
|
||||
status.scrollvalue = show-maxlines
|
||||
end
|
||||
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
|
||||
end
|
||||
end
|
||||
if self.scrollbar:GetValue() ~= status.scrollvalue then
|
||||
self.scrollbar:SetValue(status.scrollvalue)
|
||||
end
|
||||
end
|
||||
|
||||
local buttonnum = 1
|
||||
for i = first, min(last, #lines) do
|
||||
local line = lines[i]
|
||||
local button = buttons[buttonnum]
|
||||
if not button then
|
||||
button = self:CreateButton()
|
||||
|
||||
buttons[buttonnum] = button
|
||||
button:SetParent(treeframe)
|
||||
button:SetFrameLevel(treeframe:GetFrameLevel()+1)
|
||||
button:ClearAllPoints()
|
||||
if buttonnum == 1 then
|
||||
if self.showscroll then
|
||||
button:SetPoint("TOPRIGHT", -22, -10)
|
||||
button:SetPoint("TOPLEFT", 0, -10)
|
||||
else
|
||||
button:SetPoint("TOPRIGHT", 0, -10)
|
||||
button:SetPoint("TOPLEFT", 0, -10)
|
||||
end
|
||||
else
|
||||
button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
|
||||
button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
|
||||
end
|
||||
end
|
||||
|
||||
UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
|
||||
button:Show()
|
||||
buttonnum = buttonnum + 1
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
["SetSelected"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
if status.selected ~= value then
|
||||
status.selected = value
|
||||
self:Fire("OnGroupSelected", value)
|
||||
end
|
||||
end,
|
||||
|
||||
["Select"] = function(self, uniquevalue, ...)
|
||||
self.filter = false
|
||||
local status = self.status or self.localstatus
|
||||
local groups = status.groups
|
||||
local path = {...}
|
||||
for i = 1, #path do
|
||||
groups[tconcat(path, "\001", 1, i)] = true
|
||||
end
|
||||
status.selected = uniquevalue
|
||||
self:RefreshTree(true)
|
||||
self:Fire("OnGroupSelected", uniquevalue)
|
||||
end,
|
||||
|
||||
["SelectByPath"] = function(self, ...)
|
||||
self:Select(BuildUniqueValue(...), ...)
|
||||
end,
|
||||
|
||||
["SelectByValue"] = function(self, uniquevalue)
|
||||
self:Select(uniquevalue, ("\001"):split(uniquevalue))
|
||||
end,
|
||||
|
||||
["ShowScroll"] = function(self, show)
|
||||
self.showscroll = show
|
||||
if show then
|
||||
self.scrollbar:Show()
|
||||
if self.buttons[1] then
|
||||
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
|
||||
end
|
||||
else
|
||||
self.scrollbar:Hide()
|
||||
if self.buttons[1] then
|
||||
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local treeframe = self.treeframe
|
||||
local status = self.status or self.localstatus
|
||||
status.fullwidth = width
|
||||
|
||||
local contentwidth = width - status.treewidth - 20
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
|
||||
local maxtreewidth = math_min(400, width - 50)
|
||||
|
||||
if maxtreewidth > 100 and status.treewidth > maxtreewidth then
|
||||
self:SetTreeWidth(maxtreewidth, status.treesizable)
|
||||
end
|
||||
treeframe:SetMaxResize(maxtreewidth, 1600)
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 20
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
|
||||
["SetTreeWidth"] = function(self, treewidth, resizable)
|
||||
if not resizable then
|
||||
if type(treewidth) == 'number' then
|
||||
resizable = false
|
||||
elseif type(treewidth) == 'boolean' then
|
||||
resizable = treewidth
|
||||
treewidth = DEFAULT_TREE_WIDTH
|
||||
else
|
||||
resizable = false
|
||||
treewidth = DEFAULT_TREE_WIDTH
|
||||
end
|
||||
end
|
||||
self.treeframe:SetWidth(treewidth)
|
||||
self.dragger:EnableMouse(resizable)
|
||||
|
||||
local status = self.status or self.localstatus
|
||||
status.treewidth = treewidth
|
||||
status.treesizable = resizable
|
||||
|
||||
-- recalculate the content width
|
||||
if status.fullwidth then
|
||||
self:OnWidthSet(status.fullwidth)
|
||||
end
|
||||
end,
|
||||
|
||||
["GetTreeWidth"] = function(self)
|
||||
local status = self.status or self.localstatus
|
||||
return status.treewidth or DEFAULT_TREE_WIDTH
|
||||
end,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
if self.noAutoHeight then return end
|
||||
self:SetHeight((height or 0) + 20)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local DraggerBackdrop = {
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
edgeFile = nil,
|
||||
tile = true, tileSize = 16, edgeSize = 0,
|
||||
insets = { left = 3, right = 3, top = 7, bottom = 7 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
|
||||
local treeframe = CreateFrame("Frame", nil, frame)
|
||||
treeframe:SetPoint("TOPLEFT")
|
||||
treeframe:SetPoint("BOTTOMLEFT")
|
||||
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
|
||||
treeframe:EnableMouseWheel(true)
|
||||
treeframe:SetResizable(true)
|
||||
treeframe:SetMinResize(100, 1)
|
||||
treeframe:SetMaxResize(400, 1600)
|
||||
treeframe:SetScript("OnUpdate", FirstFrameUpdate)
|
||||
treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
|
||||
treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel)
|
||||
TSMAPI.Design:SetFrameColor(treeframe)
|
||||
|
||||
local dragger = CreateFrame("Frame", nil, treeframe)
|
||||
dragger:SetWidth(10)
|
||||
dragger:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
|
||||
dragger:SetPoint("BOTTOMLEFT", treeframe, "BOTTOMRIGHT")
|
||||
dragger:SetBackdrop(DraggerBackdrop)
|
||||
dragger:SetBackdropColor(1, 1, 1, 0)
|
||||
dragger:SetScript("OnEnter", Dragger_OnEnter)
|
||||
dragger:SetScript("OnLeave", Dragger_OnLeave)
|
||||
dragger:SetScript("OnMouseDown", Dragger_OnMouseDown)
|
||||
dragger:SetScript("OnMouseUp", Dragger_OnMouseUp)
|
||||
|
||||
local scrollbar = CreateFrame("Slider", ("TSMTreeGroup%dScrollBar"):format(num), treeframe, "UIPanelScrollBarTemplate")
|
||||
scrollbar:SetScript("OnValueChanged", nil)
|
||||
scrollbar:SetPoint("TOPRIGHT", -10, -26)
|
||||
scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
|
||||
scrollbar:SetMinMaxValues(0,0)
|
||||
scrollbar:SetValueStep(1)
|
||||
scrollbar:SetValue(0)
|
||||
scrollbar:SetWidth(12)
|
||||
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
|
||||
|
||||
local thumbTex = scrollbar:GetThumbTexture()
|
||||
thumbTex:SetPoint("CENTER")
|
||||
TSMAPI.Design:SetContentColor(thumbTex)
|
||||
thumbTex:SetHeight(150)
|
||||
thumbTex:SetWidth(scrollbar:GetWidth())
|
||||
|
||||
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
|
||||
scrollbg:SetAllPoints(scrollbar)
|
||||
TSMAPI.Design:SetFrameColor(scrollbg)
|
||||
|
||||
_G[scrollbar:GetName().."ScrollUpButton"]:Hide()
|
||||
_G[scrollbar:GetName().."ScrollDownButton"]:Hide()
|
||||
|
||||
local border = CreateFrame("Frame",nil,frame)
|
||||
border:SetPoint("TOPLEFT", dragger, "TOPRIGHT", -1, 0)
|
||||
border:SetPoint("BOTTOMRIGHT")
|
||||
TSMAPI.Design:SetFrameColor(border)
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, border)
|
||||
content:SetPoint("TOPLEFT", 6, -6)
|
||||
content:SetPoint("BOTTOMRIGHT", -6, 6)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
lines = {},
|
||||
levels = {},
|
||||
buttons = {},
|
||||
hasChildren = {},
|
||||
localstatus = {groups={}, scrollvalue=0},
|
||||
filter = false,
|
||||
treeframe = treeframe,
|
||||
dragger = dragger,
|
||||
scrollbar = scrollbar,
|
||||
border = border,
|
||||
content = content,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
treeframe.obj, dragger.obj, scrollbar.obj = widget, widget, widget
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,169 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- http://www.curse.com/addons/wow/tradeskill-master --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
-- Much of this code is copied from .../AceGUI-3.0/widgets/AceGUIWidget-Window.lua
|
||||
-- This Window container is modified to fit TSM's theme / needs
|
||||
local TSM = select(2, ...)
|
||||
local Type, Version = "TSMWindow", 2
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, assert, type = pairs, assert, type
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function frameOnClose(this)
|
||||
this.obj:Fire("OnClose")
|
||||
end
|
||||
|
||||
local function closeOnClick(this)
|
||||
PlaySound("gsTitleOptionExit")
|
||||
this.obj:Hide()
|
||||
end
|
||||
|
||||
local function frameOnMouseDown(this)
|
||||
this:StartMoving()
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function frameOnMouseUp(this)
|
||||
this:StopMovingOrSizing()
|
||||
end
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self.frame:SetParent(UIParent)
|
||||
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
self:ApplyStatus()
|
||||
self:Show()
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
for k in pairs(self.localstatus) do
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
end,
|
||||
|
||||
["Show"] = function(self)
|
||||
self.frame:Show()
|
||||
end,
|
||||
|
||||
["Hide"] = function(self)
|
||||
self.frame:Hide()
|
||||
end,
|
||||
|
||||
["SetTitle"] = function(self,title)
|
||||
self.titletext:SetText(title)
|
||||
end,
|
||||
|
||||
["ApplyStatus"] = function(self)
|
||||
local status = self.status or self.localstatus
|
||||
local frame = self.frame
|
||||
self:SetWidth(status.width or 700)
|
||||
self:SetHeight(status.height or 500)
|
||||
if status.top and status.left then
|
||||
frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
|
||||
frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
|
||||
else
|
||||
frame:SetPoint("CENTER",UIParent,"CENTER")
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 34
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 57
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame")
|
||||
frame:SetWidth(700)
|
||||
frame:SetHeight(500)
|
||||
frame:SetPoint("CENTER")
|
||||
frame:EnableMouse(true)
|
||||
frame:SetMovable(true)
|
||||
frame:SetResizable(true)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
frame:SetScript("OnMouseDown", frameOnMouseDown)
|
||||
frame:SetScript("OnMouseUp", frameOnMouseUp)
|
||||
frame:SetScript("OnHide", frameOnClose)
|
||||
TSMAPI.Design:SetFrameBackdropColor(frame)
|
||||
|
||||
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
|
||||
close:SetPoint("TOPRIGHT", 2, 1)
|
||||
close:SetScript("OnClick", closeOnClick)
|
||||
|
||||
local titletext = frame:CreateFontString(nil, "ARTWORK")
|
||||
titletext:SetFont(TSMAPI.Design:GetBoldFont(), 18)
|
||||
TSMAPI.Design:SetTitleTextColor(titletext)
|
||||
titletext:SetPoint("TOP", 0, -4)
|
||||
|
||||
local line = frame:CreateTexture()
|
||||
line:SetPoint("TOPLEFT", 2, -28)
|
||||
line:SetPoint("TOPRIGHT", -2, -28)
|
||||
line:SetHeight(2)
|
||||
TSMAPI.Design:SetIconRegionColor(line)
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, frame)
|
||||
content:SetPoint("TOPLEFT", frame, "TOPLEFT", 12, -32)
|
||||
content:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -12, 13)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
type = Type,
|
||||
localstatus = {},
|
||||
content = content,
|
||||
title = title,
|
||||
titletext = titletext,
|
||||
closebutton = close,
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
frame.obj, content.obj, close.obj = widget, widget, widget
|
||||
|
||||
widget.Add = TSMAPI.AddGUIElement
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type,Constructor,Version)
|
||||
Reference in New Issue
Block a user