ascension: 4.4.2 → vendored 4.4.2-2-g3b02ee4 (in-game AddOns dir)

Imported from /srv/add01/wow-ascension/Interface/AddOns/Bartender4 — the
build Ascension's WotLK 3.3.5 client ships.

Single vendored drop: Ascension's build process bundles their custom
patches with the standard CurseForge packager output (embedded libs),
and the individual patches aren't published separately.

Net delta vs Nevcairiel 4.4.2, excluding bundled libs and CRLF
normalization: 21 files, 2213+/52- — the Ascension-specific
adaptations for WotLK 3.3.5 hero classes / custom action systems.

License: All rights reserved (per .toc).
This commit is contained in:
2026-05-08 03:45:58 +02:00
parent 97d989dd93
commit 57a5cdabdf
110 changed files with 23249 additions and 6220 deletions
-16
View File
@@ -1,16 +0,0 @@
package-as: Bartender4
externals:
libs/LibStub: svn://svn.wowace.com/wow/libstub/mainline/tags/1.0
libs/CallbackHandler-1.0: svn://svn.wowace.com/wow/callbackhandler/mainline/trunk/CallbackHandler-1.0
libs/AceAddon-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceAddon-3.0
libs/AceConsole-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceConsole-3.0
libs/AceEvent-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceEvent-3.0
libs/AceHook-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceHook-3.0
libs/AceDB-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceDB-3.0
libs/AceDBOptions-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceDBOptions-3.0
libs/AceLocale-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceLocale-3.0
libs/AceGUI-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceGUI-3.0
libs/AceConfig-3.0: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceConfig-3.0
libs/LibKeyBound-1.0: svn://svn.wowace.com/wow/libkeybound-1-0/mainline/trunk/LibKeyBound-1.0
libs/LibDBIcon-1.0: svn://svn.wowace.com/wow/libdbicon-1-0/mainline/trunk/LibDBIcon-1.0
libs/LibWindow-1.1: svn://svn.wowace.com/wow/libwindow-1-1/mainline/trunk/LibWindow-1.1
+119 -119
View File
@@ -1,119 +1,119 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local StateBar = Bartender4.StateBar.prototype
local ActionBar = setmetatable({}, {__index = StateBar})
Bartender4.ActionBar = ActionBar
--[[===================================================================================
ActionBar Prototype
===================================================================================]]--
local initialPosition
do
-- Sets the Bar to its initial Position in the Center of the Screen
function initialPosition(bar)
bar:ClearSetPoint("CENTER", 0, -250 + (bar.id-1) * 38)
bar:SavePosition()
end
end
-- Apply the specified config to the bar and refresh all settings
function ActionBar:ApplyConfig(config)
StateBar.ApplyConfig(self, config)
if not self.config.position.x then initialPosition(self) end
self:UpdateButtons()
end
-- Update the number of buttons in our bar, creating new ones if necessary
function ActionBar:UpdateButtons(numbuttons)
if numbuttons then
self.config.buttons = min(numbuttons, 12)
else
numbuttons = min(self.config.buttons, 12)
end
local buttons = self.buttons or {}
local updateBindings = (numbuttons > #buttons)
-- create more buttons if needed
for i = (#buttons+1), numbuttons do
buttons[i] = Bartender4.Button:Create(i, self)
end
-- show active buttons
for i = 1, numbuttons do
buttons[i]:SetParent(self)
buttons[i]:Show()
buttons[i]:SetAttribute("statehidden", nil)
buttons[i]:Update()
end
-- hide inactive buttons
for i = (numbuttons + 1), #buttons do
buttons[i]:Hide()
buttons[i]:SetParent(UIParent)
buttons[i]:SetAttribute("statehidden", true)
end
self.numbuttons = numbuttons
self.buttons = buttons
self:UpdateButtonLayout()
self:SetGrid()
if updateBindings and self.id == "1" then
self.module:ReassignBindings()
end
-- need to re-set clickthrough after creating new buttons
self:SetClickThrough()
self:UpdateSelfCast() -- update selfcast and states
end
function ActionBar:SkinChanged(...)
StateBar.SkinChanged(self, ...)
self:ForAll("Update")
end
--[[===================================================================================
ActionBar Config Interface
===================================================================================]]--
-- get the current number of buttons
function ActionBar:GetButtons()
return self.config.buttons
end
-- set the number of buttons and refresh layout
ActionBar.SetButtons = ActionBar.UpdateButtons
function ActionBar:GetEnabled()
return true
end
function ActionBar:SetEnabled(state)
if not state then
self.module:DisableBar(self.id)
end
end
function ActionBar:GetGrid()
return self.config.showgrid
end
function ActionBar:SetGrid(state)
if state ~= nil then
self.config.showgrid = state
end
if self.config.showgrid then
self:ForAll("ShowGrid")
else
self:ForAll("HideGrid")
end
self:ForAll("UpdateGrid")
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local StateBar = Bartender4.StateBar.prototype
local ActionBar = setmetatable({}, {__index = StateBar})
Bartender4.ActionBar = ActionBar
--[[===================================================================================
ActionBar Prototype
===================================================================================]]--
local initialPosition
do
-- Sets the Bar to its initial Position in the Center of the Screen
function initialPosition(bar)
bar:ClearSetPoint("CENTER", 0, -250 + (bar.id-1) * 38)
bar:SavePosition()
end
end
-- Apply the specified config to the bar and refresh all settings
function ActionBar:ApplyConfig(config)
StateBar.ApplyConfig(self, config)
if not self.config.position.x then initialPosition(self) end
self:UpdateButtons()
end
-- Update the number of buttons in our bar, creating new ones if necessary
function ActionBar:UpdateButtons(numbuttons)
if numbuttons then
self.config.buttons = min(numbuttons, 12)
else
numbuttons = min(self.config.buttons, 12)
end
local buttons = self.buttons or {}
local updateBindings = (numbuttons > #buttons)
-- create more buttons if needed
for i = (#buttons+1), numbuttons do
buttons[i] = Bartender4.Button:Create(i, self)
end
-- show active buttons
for i = 1, numbuttons do
buttons[i]:SetParent(self)
buttons[i]:Show()
buttons[i]:SetAttribute("statehidden", nil)
buttons[i]:Update()
end
-- hide inactive buttons
for i = (numbuttons + 1), #buttons do
buttons[i]:Hide()
buttons[i]:SetParent(UIParent)
buttons[i]:SetAttribute("statehidden", true)
end
self.numbuttons = numbuttons
self.buttons = buttons
self:UpdateButtonLayout()
self:SetGrid()
if updateBindings and self.id == "1" then
self.module:ReassignBindings()
end
-- need to re-set clickthrough after creating new buttons
self:SetClickThrough()
self:UpdateSelfCast() -- update selfcast and states
end
function ActionBar:SkinChanged(...)
StateBar.SkinChanged(self, ...)
self:ForAll("Update")
end
--[[===================================================================================
ActionBar Config Interface
===================================================================================]]--
-- get the current number of buttons
function ActionBar:GetButtons()
return self.config.buttons
end
-- set the number of buttons and refresh layout
ActionBar.SetButtons = ActionBar.UpdateButtons
function ActionBar:GetEnabled()
return true
end
function ActionBar:SetEnabled(state)
if not state then
self.module:DisableBar(self.id)
end
end
function ActionBar:GetGrid()
return self.config.showgrid
end
function ActionBar:SetGrid(state)
if state ~= nil then
self.config.showgrid = state
end
if self.config.showgrid then
self:ForAll("ShowGrid")
else
self:ForAll("HideGrid")
end
self:ForAll("UpdateGrid")
end
+235 -234
View File
@@ -1,234 +1,235 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local BT4ActionBars = Bartender4:NewModule("ActionBars", "AceEvent-3.0")
local ActionBar, ActionBar_MT
local abdefaults = {
['**'] = Bartender4:Merge({
enabled = true,
buttons = 12,
hidemacrotext = false,
showgrid = false,
}, Bartender4.StateBar.defaults),
[1] = {
states = {
enabled = true,
possess = true,
actionbar = true,
stance = {
DRUID = { bear = 9, cat = 7, prowl = 8 },
WARRIOR = { battle = 7, def = 8, berserker = 9 },
ROGUE = { stealth = 7, shadowdance = 7 }
},
},
visibility = {
vehicleui = false,
},
},
[7] = {
enabled = false,
},
[8] = {
enabled = false,
},
[9] = {
enabled = false,
},
[10] = {
enabled = false,
},
}
local defaults = {
profile = {
actionbars = abdefaults,
}
}
function BT4ActionBars:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("ActionBars", defaults)
-- fetch the prototype information
ActionBar = Bartender4.ActionBar
ActionBar_MT = {__index = ActionBar}
end
local LBF = LibStub("LibButtonFacade", true)
-- setup the 10 actionbars
local first = true
function BT4ActionBars:OnEnable()
if first then
self.playerclass = select(2, UnitClass("player"))
self.actionbars = {}
for i=1,10 do
local config = self.db.profile.actionbars[i]
if config.enabled then
self.actionbars[i] = self:Create(i, config)
else
self:CreateBarOption(i, self.disabledoptions)
end
end
first = nil
end
self:RegisterEvent("UPDATE_BINDINGS", "ReassignBindings")
self:ReassignBindings()
end
function BT4ActionBars:SetupOptions()
if not self.options then
-- empty table to hold the bar options
self.options = {}
-- template for disabled bars
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = {
type = "toggle",
name = L["Enabled"],
desc = L["Enable/Disable the bar."],
set = function(info, v) if v then BT4ActionBars:EnableBar(info[2]) end end,
get = function() return false end,
}
}
}
}
-- iterate over bars and create their option tables
for i=1,10 do
local config = self.db.profile.actionbars[i]
if config.enabled then
self:CreateBarOption(i)
else
self:CreateBarOption(i, self.disabledoptions)
end
end
end
end
-- Applys the config in the current profile to all active Bars
function BT4ActionBars:ApplyConfig()
for i=1,10 do
local config = self.db.profile.actionbars[i]
-- make sure the bar has its current config object if it exists already
if self.actionbars[i] then
self.actionbars[i].config = config
end
if config.enabled then
self:EnableBar(i)
else
self:DisableBar(i)
end
end
end
-- we do not allow to disable the actionbars module
function BT4ActionBars:ToggleModule()
return
end
function BT4ActionBars:UpdateButtons(force)
for i,v in ipairs(self.actionbars) do
for j,button in ipairs(v.buttons) do
button:UpdateAction(force)
end
end
end
function BT4ActionBars:ReassignBindings()
if InCombatLockdown() then return end
if not self.actionbars or not self.actionbars[1] then return end
local frame = self.actionbars[1]
ClearOverrideBindings(frame)
for i = 1,min(#frame.buttons, 12) do
local button, real_button = ("ACTIONBUTTON%d"):format(i), ("BT4Button%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
SetOverrideBindingClick(frame, false, key, real_button)
end
end
for i = 1, 120 do
-- rename old bindings from <buttonname>Secure to only <buttonname>
local button, real_button = ("CLICK BT4Button%dSecure:LeftButton"):format(i), ("BT4Button%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
if key and key ~= "" then
SetBindingClick(key, real_button, "LeftButton")
end
end
end
SaveBindings(GetCurrentBindingSet() or 1)
end
-- Creates a new bar object based on the id and the specified config
function BT4ActionBars:Create(id, config)
local id = tostring(id)
local bar = setmetatable(Bartender4.StateBar:Create(id, config, (L["Bar %s"]):format(id)), ActionBar_MT)
bar.module = self
self:CreateBarOption(id)
bar:ApplyConfig()
return bar
end
function BT4ActionBars:DisableBar(id)
id = tonumber(id)
local bar = self.actionbars[id]
if not bar then return end
bar.config.enabled = false
bar:Disable()
self:CreateBarOption(id, self.disabledoptions)
end
function BT4ActionBars:EnableBar(id)
id = tonumber(id)
local bar = self.actionbars[id]
local config = self.db.profile.actionbars[id]
config.enabled = true
if not bar then
bar = self:Create(id, config)
self.actionbars[id] = bar
else
bar.disabled = nil
self:CreateBarOption(id)
bar:ApplyConfig(config)
end
if not Bartender4.Locked then
bar:Unlock()
end
end
function BT4ActionBars:GetAll()
return pairs(self.actionbars)
end
function BT4ActionBars:ForAll(method, ...)
for _, bar in self:GetAll() do
local func = bar[method]
if func then
func(bar, ...)
end
end
end
function BT4ActionBars:ForAllButtons(...)
self:ForAll("ForAll", ...)
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local BT4ActionBars = Bartender4:NewModule("ActionBars", "AceEvent-3.0")
local ActionBar, ActionBar_MT
local abdefaults = {
['**'] = Bartender4:Merge({
enabled = true,
buttons = 12,
hidemacrotext = false,
showgrid = false,
}, Bartender4.StateBar.defaults),
[1] = {
states = {
enabled = true,
possess = true,
actionbar = true,
stance = {
DRUID = { bear = 9, cat = 7, prowl = 8 },
WARRIOR = { battle = 7, def = 8, berserker = 9 },
ROGUE = { stealth = 7, shadowdance = 7 },
HERO = { bear = 9, cat = 7, prowl = 8, stealth = 7, shadowdance = 7, battle = 7, def = 8, berserker = 9 },
},
},
visibility = {
vehicleui = false,
},
},
[7] = {
enabled = false,
},
[8] = {
enabled = false,
},
[9] = {
enabled = false,
},
[10] = {
enabled = false,
},
}
local defaults = {
profile = {
actionbars = abdefaults,
}
}
function BT4ActionBars:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("ActionBars", defaults)
-- fetch the prototype information
ActionBar = Bartender4.ActionBar
ActionBar_MT = {__index = ActionBar}
end
local LBF = LibStub("LibButtonFacade", true)
-- setup the 10 actionbars
local first = true
function BT4ActionBars:OnEnable()
if first then
self.playerclass = select(2, UnitClass("player"))
self.actionbars = {}
for i=1,10 do
local config = self.db.profile.actionbars[i]
if config.enabled then
self.actionbars[i] = self:Create(i, config)
else
self:CreateBarOption(i, self.disabledoptions)
end
end
first = nil
end
self:RegisterEvent("UPDATE_BINDINGS", "ReassignBindings")
self:ReassignBindings()
end
function BT4ActionBars:SetupOptions()
if not self.options then
-- empty table to hold the bar options
self.options = {}
-- template for disabled bars
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = {
type = "toggle",
name = L["Enabled"],
desc = L["Enable/Disable the bar."],
set = function(info, v) if v then BT4ActionBars:EnableBar(info[2]) end end,
get = function() return false end,
}
}
}
}
-- iterate over bars and create their option tables
for i=1,10 do
local config = self.db.profile.actionbars[i]
if config.enabled then
self:CreateBarOption(i)
else
self:CreateBarOption(i, self.disabledoptions)
end
end
end
end
-- Applys the config in the current profile to all active Bars
function BT4ActionBars:ApplyConfig()
for i=1,10 do
local config = self.db.profile.actionbars[i]
-- make sure the bar has its current config object if it exists already
if self.actionbars[i] then
self.actionbars[i].config = config
end
if config.enabled then
self:EnableBar(i)
else
self:DisableBar(i)
end
end
end
-- we do not allow to disable the actionbars module
function BT4ActionBars:ToggleModule()
return
end
function BT4ActionBars:UpdateButtons(force)
for i,v in ipairs(self.actionbars) do
for j,button in ipairs(v.buttons) do
button:UpdateAction(force)
end
end
end
function BT4ActionBars:ReassignBindings()
if InCombatLockdown() then return end
if not self.actionbars or not self.actionbars[1] then return end
local frame = self.actionbars[1]
ClearOverrideBindings(frame)
for i = 1,min(#frame.buttons, 12) do
local button, real_button = ("ACTIONBUTTON%d"):format(i), ("BT4Button%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
SetOverrideBindingClick(frame, false, key, real_button)
end
end
for i = 1, 120 do
-- rename old bindings from <buttonname>Secure to only <buttonname>
local button, real_button = ("CLICK BT4Button%dSecure:LeftButton"):format(i), ("BT4Button%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
if key and key ~= "" then
SetBindingClick(key, real_button, "LeftButton")
end
end
end
SaveBindings(GetCurrentBindingSet() or 1)
end
-- Creates a new bar object based on the id and the specified config
function BT4ActionBars:Create(id, config)
local id = tostring(id)
local bar = setmetatable(Bartender4.StateBar:Create(id, config, (L["Bar %s"]):format(id)), ActionBar_MT)
bar.module = self
self:CreateBarOption(id)
bar:ApplyConfig()
return bar
end
function BT4ActionBars:DisableBar(id)
id = tonumber(id)
local bar = self.actionbars[id]
if not bar then return end
bar.config.enabled = false
bar:Disable()
self:CreateBarOption(id, self.disabledoptions)
end
function BT4ActionBars:EnableBar(id)
id = tonumber(id)
local bar = self.actionbars[id]
local config = self.db.profile.actionbars[id]
config.enabled = true
if not bar then
bar = self:Create(id, config)
self.actionbars[id] = bar
else
bar.disabled = nil
self:CreateBarOption(id)
bar:ApplyConfig(config)
end
if not Bartender4.Locked then
bar:Unlock()
end
end
function BT4ActionBars:GetAll()
return pairs(self.actionbars)
end
function BT4ActionBars:ForAll(method, ...)
for _, bar in self:GetAll() do
local func = bar[method]
if func then
func(bar, ...)
end
end
end
function BT4ActionBars:ForAllButtons(...)
self:ForAll("ForAll", ...)
end
+515 -514
View File
File diff suppressed because it is too large Load Diff
+124 -124
View File
@@ -1,124 +1,124 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local BagBarMod = Bartender4:NewModule("BagBar", "AceHook-3.0")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
local LBF = LibStub("LibButtonFacade", true)
-- create prototype information
local BagBar = setmetatable({}, {__index = ButtonBar})
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = true,
keyring = false,
onebag = false,
visibility = {
possess = false,
},
}, Bartender4.ButtonBar.defaults) }
function BagBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("BagBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
local noopFunc = function() end
function BagBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("BagBar", self.db.profile, L["Bag Bar"]), {__index = BagBar})
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function BagBarMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
function BagBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", 142, -18)
self:SavePosition()
end
self:FeedButtons()
self:UpdateButtonLayout()
end
function clearSetPoint(btn, ...)
btn:ClearAllPoints()
btn:SetPoint(...)
end
BagBar.button_width = 30
BagBar.button_height = 30
BagBarMod.button_count = 5
function BagBar:FeedButtons()
local count = 1
if self.buttons then
while next(self.buttons) do
local btn = table.remove(self.buttons)
btn:Hide()
btn:SetParent(UIParent)
btn:ClearSetPoint("CENTER")
if btn ~= KeyRingButton and btn.LBFButtonData then
local group = self.LBFGroup
group:RemoveButton(btn)
end
end
else
self.buttons = {}
end
if self.config.keyring then
table_insert(self.buttons, KeyRingButton)
count = count + 1
end
if not self.config.onebag then
table_insert(self.buttons, CharacterBag3Slot)
table_insert(self.buttons, CharacterBag2Slot)
table_insert(self.buttons, CharacterBag1Slot)
table_insert(self.buttons, CharacterBag0Slot)
count = count + 4
end
table_insert(self.buttons, MainMenuBarBackpackButton)
for i,v in pairs(self.buttons) do
v:SetParent(self)
v:Show()
if v ~= KeyRingButton then
v:SetNormalTexture("")
if LBF then
local group = self.LBFGroup
if not v.LBFButtonData then
v.LBFButtonData = {
Button = v,
Icon = _G[v:GetName() .. "IconTexture"],
}
end
group:AddButton(v, v.LBFButtonData)
end
end
v.ClearSetPoint = clearSetPoint
end
BagBarMod.button_count = count
if BagBarMod.optionobject then
BagBarMod.optionobject.table.general.args.rows.max = count
end
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local BagBarMod = Bartender4:NewModule("BagBar", "AceHook-3.0")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
local LBF = LibStub("LibButtonFacade", true)
-- create prototype information
local BagBar = setmetatable({}, {__index = ButtonBar})
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = true,
keyring = false,
onebag = false,
visibility = {
possess = false,
},
}, Bartender4.ButtonBar.defaults) }
function BagBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("BagBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
local noopFunc = function() end
function BagBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("BagBar", self.db.profile, L["Bag Bar"]), {__index = BagBar})
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function BagBarMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
function BagBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", 142, -18)
self:SavePosition()
end
self:FeedButtons()
self:UpdateButtonLayout()
end
function clearSetPoint(btn, ...)
btn:ClearAllPoints()
btn:SetPoint(...)
end
BagBar.button_width = 30
BagBar.button_height = 30
BagBarMod.button_count = 5
function BagBar:FeedButtons()
local count = 1
if self.buttons then
while next(self.buttons) do
local btn = table.remove(self.buttons)
btn:Hide()
btn:SetParent(UIParent)
btn:ClearSetPoint("CENTER")
if btn ~= KeyRingButton and btn.LBFButtonData then
local group = self.LBFGroup
group:RemoveButton(btn)
end
end
else
self.buttons = {}
end
if self.config.keyring then
table_insert(self.buttons, KeyRingButton)
count = count + 1
end
if not self.config.onebag then
table_insert(self.buttons, CharacterBag3Slot)
table_insert(self.buttons, CharacterBag2Slot)
table_insert(self.buttons, CharacterBag1Slot)
table_insert(self.buttons, CharacterBag0Slot)
count = count + 4
end
table_insert(self.buttons, MainMenuBarBackpackButton)
for i,v in pairs(self.buttons) do
v:SetParent(self)
v:Show()
if v ~= KeyRingButton then
v:SetNormalTexture("")
if LBF then
local group = self.LBFGroup
if not v.LBFButtonData then
v.LBFButtonData = {
Button = v,
Icon = _G[v:GetName() .. "IconTexture"],
}
end
group:AddButton(v, v.LBFButtonData)
end
end
v.ClearSetPoint = clearSetPoint
end
BagBarMod.button_count = count
if BagBarMod.optionobject then
BagBarMod.optionobject.table.general.args.rows.max = count
end
end
+519 -519
View File
File diff suppressed because it is too large Load Diff
+439 -439
View File
@@ -1,439 +1,439 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local AceAddon = LibStub("AceAddon-3.0")
Bartender4 = AceAddon:NewAddon("Bartender4", "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local LDB = LibStub("LibDataBroker-1.1", true)
local LDBIcon = LibStub("LibDBIcon-1.0", true)
local defaults = {
profile = {
tooltip = "enabled",
buttonlock = false,
outofrange = "button",
colors = { range = { r = 0.8, g = 0.1, b = 0.1 }, mana = { r = 0.5, g = 0.5, b = 1.0 } },
selfcastmodifier = true,
focuscastmodifier = true,
selfcastrightclick = false,
snapping = true,
blizzardVehicle = false,
minimapIcon = {},
}
}
Bartender4.CONFIG_VERSION = 3
function Bartender4:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("Bartender4DB", defaults)
self.db.RegisterCallback(self, "OnProfileChanged", "UpdateModuleConfigs")
self.db.RegisterCallback(self, "OnProfileCopied", "UpdateModuleConfigs")
self.db.RegisterCallback(self, "OnProfileReset", "UpdateModuleConfigs")
self:SetupOptions()
self.Locked = true
self:RegisterEvent("PLAYER_REGEN_DISABLED", "CombatLockdown")
self:HideBlizzard()
self:UpdateBlizzardVehicle()
if LDB then
createLDBLauncher()
end
BINDING_HEADER_Bartender4 = "Bartender4"
BINDING_CATEGORY_Bartender4 = "Action Bars"
for i=1,10 do
if i > 1 then
_G[('BINDING_CATEGORY_BT4BLANK%d'):format(i)] = "Action Bars" -- myBindings2 compat
_G[('BINDING_HEADER_BT4BLANK%d'):format(i)] = "Bartender4 " .. L["Bar %s"]:format(i)
end
for k=1,12 do
_G[("BINDING_NAME_CLICK BT4Button%d:LeftButton"):format(((i-1)*12)+k)] = ("Bartender4 %s %s"):format(L["Bar %s"]:format(i), L["Button %s"]:format(k))
end
end
BINDING_HEADER_BT4PET = "Bartender4 " .. L["Pet Bar"]
BINDING_CATEGORY_BT4PET = "Action Bars"
BINDING_HEADER_BT4STANCE = "Bartender4 " .. L["Stance Bar"]
BINDING_CATEGORY_BT4STANCE = "Action Bars"
for k=1,10 do
_G[("BINDING_NAME_CLICK BT4PetButton%d:LeftButton"):format(k)] = ("Bartender4 %s %s"):format(L["Pet Bar"], L["Button %s"]:format(k))
_G[("BINDING_NAME_CLICK BT4StanceButton%d:LeftButton"):format(k)] = ("Bartender4 %s %s"):format(L["Stance Bar"], L["Button %s"]:format(k))
end
end
function Bartender4:HideBlizzard()
--MultiActionBar_Update = function() end
MultiActionBar_UpdateGrid = function() end
-- Hide MultiBar Buttons, but keep the bars alive
for i=1,12 do
_G["ActionButton" .. i]:Hide()
_G["ActionButton" .. i]:UnregisterAllEvents()
_G["MultiBarBottomLeftButton" .. i]:Hide()
_G["MultiBarBottomLeftButton" .. i]:UnregisterAllEvents()
_G["MultiBarBottomRightButton" .. i]:Hide()
_G["MultiBarBottomRightButton" .. i]:UnregisterAllEvents()
_G["MultiBarRightButton" .. i]:Hide()
_G["MultiBarRightButton" .. i]:UnregisterAllEvents()
_G["MultiBarLeftButton" .. i]:Hide()
_G["MultiBarLeftButton" .. i]:UnregisterAllEvents()
end
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarRight'] = nil
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarLeft'] = nil
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarBottomLeft'] = nil
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarBottomRight'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['MainMenuBar'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['ShapeshiftBarFrame'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['PossessBarFrame'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['PETACTIONBAR_YPOS'] = nil
MainMenuBar:UnregisterAllEvents()
MainMenuBar:Hide()
--MainMenuBarArtFrame:UnregisterEvent("PLAYER_ENTERING_WORLD")
--MainMenuBarArtFrame:UnregisterEvent("BAG_UPDATE")
MainMenuBarArtFrame:UnregisterEvent("ACTIONBAR_PAGE_CHANGED")
--MainMenuBarArtFrame:UnregisterEvent("KNOWN_CURRENCY_TYPES_UPDATE")
--MainMenuBarArtFrame:UnregisterEvent("CURRENCY_DISPLAY_UPDATE")
MainMenuBarArtFrame:UnregisterEvent("ADDON_LOADED")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERING_VEHICLE")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERED_VEHICLE")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITING_VEHICLE")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITED_VEHICLE")
MainMenuBarArtFrame:Hide()
--MainMenuExpBar:UnregisterAllEvents()
--MainMenuExpBar:Hide()
ShapeshiftBarFrame:UnregisterAllEvents()
ShapeshiftBarFrame:Hide()
BonusActionBarFrame:UnregisterAllEvents()
BonusActionBarFrame:Hide()
PossessBarFrame:UnregisterAllEvents()
PossessBarFrame:Hide()
if PlayerTalentFrame then
PlayerTalentFrame:UnregisterEvent('ACTIVE_TALENT_GROUP_CHANGED')
else
hooksecurefunc('TalentFrame_LoadUI', function() PlayerTalentFrame:UnregisterEvent('ACTIVE_TALENT_GROUP_CHANGED') end)
end
end
--[[ function Bartender4:OnEnable()
--
end
--]]
function Bartender4:RegisterDefaultsKey(key, subdefaults)
defaults.profile[key] = subdefaults
self.db:RegisterDefaults(defaults)
end
function Bartender4:UpdateModuleConfigs()
local unlock = false
if not self.Locked then
self:Lock()
unlock = true
end
for k,v in AceAddon:IterateModulesOfAddon(self) do
v:ToggleModule()
if v:IsEnabled() and type(v.ApplyConfig) == "function" then
v:ApplyConfig()
end
end
if LDB and LDBIcon then
LDBIcon:Refresh("Bartender4", Bartender4.db.profile.minimapIcon)
end
self:UpdateBlizzardVehicle()
if unlock then
self:Unlock()
end
end
function Bartender4:UpdateBlizzardVehicle()
if self.db.profile.blizzardVehicle then
MainMenuBarArtFrame:RegisterEvent("UNIT_ENTERING_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("UNIT_EXITING_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
local vehicleModule = Bartender4:GetModule("Vehicle", true)
vehicleModule:Disable()
vehicleModule.blizzardVehicle = true
RegisterStateDriver(MainMenuBar, "visibility", "hide")
RegisterStateDriver(ShapeshiftBarFrame, "visibility", "hide")
RegisterStateDriver(PossessBarFrame, "visibility", "hide")
if not self.vehicleController then
self.vehicleController = CreateFrame("Frame", nil, UIParent, "SecureHandlerStateTemplate")
self.vehicleController:SetAttribute("_onstate-vehicle", [[
if newstate == "vehicle" then
for i=1,6 do
local button, vbutton = ("ACTIONBUTTON%d"):format(i), ("VehicleMenuBarActionButton%d"):format(i)
for k=1,select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
self:SetBindingClick(true, key, vbutton)
end
end
else
self:ClearBindings()
end
]])
end
RegisterStateDriver(self.vehicleController, "vehicle", "[vehicleui]vehicle;novehicle")
local btn = "VehicleMenuBarActionButton%d"
for i=1,6 do
local name = btn:format(i)
local button = _G[name]
button.UpdateUsable = Bartender4.Button.prototype.UpdateUsable
button:SetScript("OnUpdate", Bartender4.Button.onUpdate)
button.icon = _G[("%sIcon"):format(name)]
button.border = _G[("%sBorder"):format(name)]
button.cooldown = _G[("%sCooldown"):format(name)]
button.macroName = _G[("%sName"):format(name)]
button.hotkey = _G[("%sHotKey"):format(name)]
button.count = _G[("%sCount"):format(name)]
button.flash = _G[("%sFlash"):format(name)]
button.BT4init = true
button:SetParent(VehicleMenuBarActionButtonFrame)
end
else
MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERING_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERED_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITING_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITED_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("PLAYER_ENTERING_WORLD")
local vehicleModule = Bartender4:GetModule("Vehicle")
vehicleModule.blizzardVehicle = nil
if vehicleModule.db and vehicleModule.db.profile.enabled then
vehicleModule:Enable()
end
UnregisterStateDriver(MainMenuBar, "visibility")
UnregisterStateDriver(ShapeshiftBarFrame, "visibility")
UnregisterStateDriver(PossessBarFrame, "visibility")
if self.vehicleController then
UnregisterStateDriver(self.vehicleController, "vehicle")
end
local btn = "VehicleMenuBarActionButton%d"
for i=1,6 do
local name = btn:format(i)
local button = _G[name]
button.BT4init = nil
button:SetScript("OnUpdate", ActionButton_OnUpdate)
end
end
end
function Bartender4:CombatLockdown()
self:Lock()
LibStub("AceConfigDialog-3.0"):Close("Bartender4")
end
function Bartender4:ToggleLock()
if self.Locked then
self:Unlock()
else
self:Lock()
end
end
local getSnap, setSnap
do
function getSnap()
return Bartender4.db.profile.snapping
end
function setSnap(value)
Bartender4.Bar:ForAll("StopDragging")
Bartender4.db.profile.snapping = value
LibStub("AceConfigRegistry-3.0"):NotifyChange("Bartender4")
end
end
function Bartender4:ShowUnlockDialog()
if not self.unlock_dialog then
local f = CreateFrame('Frame', 'Bartender4Dialog', UIParent)
f:SetFrameStrata('DIALOG')
f:SetToplevel(true)
f:EnableMouse(true)
f:SetClampedToScreen(true)
f:SetWidth(360)
f:SetHeight(110)
f:SetBackdrop{
bgFile='Interface\\DialogFrame\\UI-DialogBox-Background' ,
edgeFile='Interface\\DialogFrame\\UI-DialogBox-Border',
tile = true,
insets = {left = 11, right = 12, top = 12, bottom = 11},
tileSize = 32,
edgeSize = 32,
}
f:SetPoint('TOP', 0, -50)
f:Hide()
f:SetScript('OnShow', function() PlaySound('igMainMenuOption') end)
f:SetScript('OnHide', function() PlaySound('gsTitleOptionExit') end)
local tr = f:CreateTitleRegion()
tr:SetAllPoints(f)
local header = f:CreateTexture(nil, 'ARTWORK')
header:SetTexture('Interface\\DialogFrame\\UI-DialogBox-Header')
header:SetWidth(256); header:SetHeight(64)
header:SetPoint('TOP', 0, 12)
local title = f:CreateFontString('ARTWORK')
title:SetFontObject('GameFontNormal')
title:SetPoint('TOP', header, 'TOP', 0, -14)
title:SetText(L["Bartender4"])
local desc = f:CreateFontString('ARTWORK')
desc:SetFontObject('GameFontHighlight')
desc:SetJustifyV('TOP')
desc:SetJustifyH('LEFT')
desc:SetPoint('TOPLEFT', 18, -32)
desc:SetPoint('BOTTOMRIGHT', -18, 48)
desc:SetText(L["Bars unlocked. Move them now and click Lock when you are done."])
local snapping = CreateFrame('CheckButton', 'Bartender4Snapping', f, 'OptionsCheckButtonTemplate')
_G[snapping:GetName() .. 'Text']:SetText(L["Bar Snapping"])
snapping:SetScript('OnShow', function(self)
self:SetChecked(getSnap())
end)
snapping:SetScript('OnClick', function(self)
setSnap(snapping:GetChecked())
end)
local lockBars = CreateFrame('CheckButton', 'Bartender4DialogLock', f, 'OptionsButtonTemplate')
getglobal(lockBars:GetName() .. 'Text'):SetText(L["Lock"])
lockBars:SetScript('OnClick', function(self)
Bartender4:Lock()
LibStub("AceConfigRegistry-3.0"):NotifyChange("Bartender4")
end)
--position buttons
snapping:SetPoint('BOTTOMLEFT', 14, 10)
lockBars:SetPoint('BOTTOMRIGHT', -14, 14)
self.unlock_dialog = f
end
self.unlock_dialog:Show()
end
function Bartender4:HideUnlockDialog()
if self.unlock_dialog then
self.unlock_dialog:Hide()
end
end
function Bartender4:Unlock()
if self.Locked then
self.Locked = false
Bartender4.Bar:ForAll("Unlock")
self:ShowUnlockDialog()
end
end
function Bartender4:Lock()
if not self.Locked then
self.Locked = true
Bartender4.Bar:ForAll("Lock")
self:HideUnlockDialog()
end
end
function Bartender4:Merge(target, source)
if type(target) ~= "table" then target = {} end
for k,v in pairs(source) do
if type(v) == "table" then
target[k] = self:Merge(target[k], v)
elseif not target[k] then
target[k] = v
end
end
return target
end
Bartender4.modulePrototype = {}
function Bartender4.modulePrototype:ToggleModule(info, value)
if value ~= nil then
self.db.profile.enabled = value
else
value = self.db.profile.enabled
end
if value and not self:IsEnabled() then
self:Enable()
elseif not value and self:IsEnabled() then
self:Disable()
end
end
function Bartender4.modulePrototype:ToggleOptions()
if self.options then
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
end
function Bartender4.modulePrototype:OnDisable()
if not self.bar then return end
-- assign new config table
self.bar.config = self.db.profile
self.bar:Disable()
self:ToggleOptions()
end
Bartender4:SetDefaultModulePrototype(Bartender4.modulePrototype)
function createLDBLauncher()
local L_BT_LEFT = L["|cffffff00Click|r to toggle bar lock"]
local L_BT_RIGHT = L["|cffffff00Right-click|r to open the options menu"]
local LDBObj = LibStub("LibDataBroker-1.1"):NewDataObject("Bartender4", {
type = "launcher",
label = "Bartender4",
OnClick = function(_, msg)
if msg == "LeftButton" then
if Bartender4.Locked then
Bartender4["Unlock"](Bartender4)
else
Bartender4["Lock"](Bartender4)
end
elseif msg == "RightButton" then
if LibStub("AceConfigDialog-3.0").OpenFrames["Bartender4"] then
LibStub("AceConfigDialog-3.0"):Close("Bartender4")
else
LibStub("AceConfigDialog-3.0"):Open("Bartender4")
end
end
end,
icon = "Interface\\Icons\\INV_Drink_05",
OnTooltipShow = function(tooltip)
if not tooltip or not tooltip.AddLine then return end
tooltip:AddLine("Bartender4")
tooltip:AddLine(L_BT_LEFT)
tooltip:AddLine(L_BT_RIGHT)
end,
})
if LDBIcon then
LDBIcon:Register("Bartender4", LDBObj, Bartender4.db.profile.minimapIcon)
end
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local AceAddon = LibStub("AceAddon-3.0")
Bartender4 = AceAddon:NewAddon("Bartender4", "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local LDB = LibStub("LibDataBroker-1.1", true)
local LDBIcon = LibStub("LibDBIcon-1.0", true)
local defaults = {
profile = {
tooltip = "enabled",
buttonlock = false,
outofrange = "button",
colors = { range = { r = 0.8, g = 0.1, b = 0.1 }, mana = { r = 0.5, g = 0.5, b = 1.0 } },
selfcastmodifier = true,
focuscastmodifier = true,
selfcastrightclick = false,
snapping = true,
blizzardVehicle = false,
minimapIcon = {},
}
}
Bartender4.CONFIG_VERSION = 3
function Bartender4:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("Bartender4DB", defaults)
self.db.RegisterCallback(self, "OnProfileChanged", "UpdateModuleConfigs")
self.db.RegisterCallback(self, "OnProfileCopied", "UpdateModuleConfigs")
self.db.RegisterCallback(self, "OnProfileReset", "UpdateModuleConfigs")
self:SetupOptions()
self.Locked = true
self:RegisterEvent("PLAYER_REGEN_DISABLED", "CombatLockdown")
self:HideBlizzard()
self:UpdateBlizzardVehicle()
if LDB then
createLDBLauncher()
end
BINDING_HEADER_Bartender4 = "Bartender4"
BINDING_CATEGORY_Bartender4 = "Action Bars"
for i=1,10 do
if i > 1 then
_G[('BINDING_CATEGORY_BT4BLANK%d'):format(i)] = "Action Bars" -- myBindings2 compat
_G[('BINDING_HEADER_BT4BLANK%d'):format(i)] = "Bartender4 " .. L["Bar %s"]:format(i)
end
for k=1,12 do
_G[("BINDING_NAME_CLICK BT4Button%d:LeftButton"):format(((i-1)*12)+k)] = ("Bartender4 %s %s"):format(L["Bar %s"]:format(i), L["Button %s"]:format(k))
end
end
BINDING_HEADER_BT4PET = "Bartender4 " .. L["Pet Bar"]
BINDING_CATEGORY_BT4PET = "Action Bars"
BINDING_HEADER_BT4STANCE = "Bartender4 " .. L["Stance Bar"]
BINDING_CATEGORY_BT4STANCE = "Action Bars"
for k=1,10 do
_G[("BINDING_NAME_CLICK BT4PetButton%d:LeftButton"):format(k)] = ("Bartender4 %s %s"):format(L["Pet Bar"], L["Button %s"]:format(k))
_G[("BINDING_NAME_CLICK BT4StanceButton%d:LeftButton"):format(k)] = ("Bartender4 %s %s"):format(L["Stance Bar"], L["Button %s"]:format(k))
end
end
function Bartender4:HideBlizzard()
--MultiActionBar_Update = function() end
MultiActionBar_UpdateGrid = function() end
-- Hide MultiBar Buttons, but keep the bars alive
for i=1,12 do
_G["ActionButton" .. i]:Hide()
_G["ActionButton" .. i]:UnregisterAllEvents()
_G["MultiBarBottomLeftButton" .. i]:Hide()
_G["MultiBarBottomLeftButton" .. i]:UnregisterAllEvents()
_G["MultiBarBottomRightButton" .. i]:Hide()
_G["MultiBarBottomRightButton" .. i]:UnregisterAllEvents()
_G["MultiBarRightButton" .. i]:Hide()
_G["MultiBarRightButton" .. i]:UnregisterAllEvents()
_G["MultiBarLeftButton" .. i]:Hide()
_G["MultiBarLeftButton" .. i]:UnregisterAllEvents()
end
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarRight'] = nil
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarLeft'] = nil
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarBottomLeft'] = nil
--UIPARENT_MANAGED_FRAME_POSITIONS['MultiBarBottomRight'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['MainMenuBar'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['ShapeshiftBarFrame'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['PossessBarFrame'] = nil
UIPARENT_MANAGED_FRAME_POSITIONS['PETACTIONBAR_YPOS'] = nil
MainMenuBar:UnregisterAllEvents()
MainMenuBar:Hide()
--MainMenuBarArtFrame:UnregisterEvent("PLAYER_ENTERING_WORLD")
--MainMenuBarArtFrame:UnregisterEvent("BAG_UPDATE")
MainMenuBarArtFrame:UnregisterEvent("ACTIONBAR_PAGE_CHANGED")
--MainMenuBarArtFrame:UnregisterEvent("KNOWN_CURRENCY_TYPES_UPDATE")
--MainMenuBarArtFrame:UnregisterEvent("CURRENCY_DISPLAY_UPDATE")
MainMenuBarArtFrame:UnregisterEvent("ADDON_LOADED")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERING_VEHICLE")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERED_VEHICLE")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITING_VEHICLE")
--MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITED_VEHICLE")
MainMenuBarArtFrame:Hide()
--MainMenuExpBar:UnregisterAllEvents()
--MainMenuExpBar:Hide()
ShapeshiftBarFrame:UnregisterAllEvents()
ShapeshiftBarFrame:Hide()
BonusActionBarFrame:UnregisterAllEvents()
BonusActionBarFrame:Hide()
PossessBarFrame:UnregisterAllEvents()
PossessBarFrame:Hide()
if PlayerTalentFrame then
PlayerTalentFrame:UnregisterEvent('ACTIVE_TALENT_GROUP_CHANGED')
else
hooksecurefunc('TalentFrame_LoadUI', function() PlayerTalentFrame:UnregisterEvent('ACTIVE_TALENT_GROUP_CHANGED') end)
end
end
--[[ function Bartender4:OnEnable()
--
end
--]]
function Bartender4:RegisterDefaultsKey(key, subdefaults)
defaults.profile[key] = subdefaults
self.db:RegisterDefaults(defaults)
end
function Bartender4:UpdateModuleConfigs()
local unlock = false
if not self.Locked then
self:Lock()
unlock = true
end
for k,v in AceAddon:IterateModulesOfAddon(self) do
v:ToggleModule()
if v:IsEnabled() and type(v.ApplyConfig) == "function" then
v:ApplyConfig()
end
end
if LDB and LDBIcon then
LDBIcon:Refresh("Bartender4", Bartender4.db.profile.minimapIcon)
end
self:UpdateBlizzardVehicle()
if unlock then
self:Unlock()
end
end
function Bartender4:UpdateBlizzardVehicle()
if self.db.profile.blizzardVehicle then
MainMenuBarArtFrame:RegisterEvent("UNIT_ENTERING_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("UNIT_EXITING_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
MainMenuBarArtFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
local vehicleModule = Bartender4:GetModule("Vehicle", true)
vehicleModule:Disable()
vehicleModule.blizzardVehicle = true
RegisterStateDriver(MainMenuBar, "visibility", "hide")
RegisterStateDriver(ShapeshiftBarFrame, "visibility", "hide")
RegisterStateDriver(PossessBarFrame, "visibility", "hide")
if not self.vehicleController then
self.vehicleController = CreateFrame("Frame", nil, UIParent, "SecureHandlerStateTemplate")
self.vehicleController:SetAttribute("_onstate-vehicle", [[
if newstate == "vehicle" then
for i=1,6 do
local button, vbutton = ("ACTIONBUTTON%d"):format(i), ("VehicleMenuBarActionButton%d"):format(i)
for k=1,select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
self:SetBindingClick(true, key, vbutton)
end
end
else
self:ClearBindings()
end
]])
end
RegisterStateDriver(self.vehicleController, "vehicle", "[vehicleui]vehicle;novehicle")
local btn = "VehicleMenuBarActionButton%d"
for i=1,6 do
local name = btn:format(i)
local button = _G[name]
button.UpdateUsable = Bartender4.Button.prototype.UpdateUsable
button:SetScript("OnUpdate", Bartender4.Button.onUpdate)
button.icon = _G[("%sIcon"):format(name)]
button.border = _G[("%sBorder"):format(name)]
button.cooldown = _G[("%sCooldown"):format(name)]
button.macroName = _G[("%sName"):format(name)]
button.hotkey = _G[("%sHotKey"):format(name)]
button.count = _G[("%sCount"):format(name)]
button.flash = _G[("%sFlash"):format(name)]
button.BT4init = true
button:SetParent(VehicleMenuBarActionButtonFrame)
end
else
MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERING_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("UNIT_ENTERED_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITING_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("UNIT_EXITED_VEHICLE")
MainMenuBarArtFrame:UnregisterEvent("PLAYER_ENTERING_WORLD")
local vehicleModule = Bartender4:GetModule("Vehicle")
vehicleModule.blizzardVehicle = nil
if vehicleModule.db and vehicleModule.db.profile.enabled then
vehicleModule:Enable()
end
UnregisterStateDriver(MainMenuBar, "visibility")
UnregisterStateDriver(ShapeshiftBarFrame, "visibility")
UnregisterStateDriver(PossessBarFrame, "visibility")
if self.vehicleController then
UnregisterStateDriver(self.vehicleController, "vehicle")
end
local btn = "VehicleMenuBarActionButton%d"
for i=1,6 do
local name = btn:format(i)
local button = _G[name]
button.BT4init = nil
button:SetScript("OnUpdate", ActionButton_OnUpdate)
end
end
end
function Bartender4:CombatLockdown()
self:Lock()
LibStub("AceConfigDialog-3.0"):Close("Bartender4")
end
function Bartender4:ToggleLock()
if self.Locked then
self:Unlock()
else
self:Lock()
end
end
local getSnap, setSnap
do
function getSnap()
return Bartender4.db.profile.snapping
end
function setSnap(value)
Bartender4.Bar:ForAll("StopDragging")
Bartender4.db.profile.snapping = value
LibStub("AceConfigRegistry-3.0"):NotifyChange("Bartender4")
end
end
function Bartender4:ShowUnlockDialog()
if not self.unlock_dialog then
local f = CreateFrame('Frame', 'Bartender4Dialog', UIParent)
f:SetFrameStrata('DIALOG')
f:SetToplevel(true)
f:EnableMouse(true)
f:SetClampedToScreen(true)
f:SetWidth(360)
f:SetHeight(110)
f:SetBackdrop{
bgFile='Interface\\DialogFrame\\UI-DialogBox-Background' ,
edgeFile='Interface\\DialogFrame\\UI-DialogBox-Border',
tile = true,
insets = {left = 11, right = 12, top = 12, bottom = 11},
tileSize = 32,
edgeSize = 32,
}
f:SetPoint('TOP', 0, -50)
f:Hide()
f:SetScript('OnShow', function() PlaySound('igMainMenuOption') end)
f:SetScript('OnHide', function() PlaySound('gsTitleOptionExit') end)
local tr = f:CreateTitleRegion()
tr:SetAllPoints(f)
local header = f:CreateTexture(nil, 'ARTWORK')
header:SetTexture('Interface\\DialogFrame\\UI-DialogBox-Header')
header:SetWidth(256); header:SetHeight(64)
header:SetPoint('TOP', 0, 12)
local title = f:CreateFontString('ARTWORK')
title:SetFontObject('GameFontNormal')
title:SetPoint('TOP', header, 'TOP', 0, -14)
title:SetText(L["Bartender4"])
local desc = f:CreateFontString('ARTWORK')
desc:SetFontObject('GameFontHighlight')
desc:SetJustifyV('TOP')
desc:SetJustifyH('LEFT')
desc:SetPoint('TOPLEFT', 18, -32)
desc:SetPoint('BOTTOMRIGHT', -18, 48)
desc:SetText(L["Bars unlocked. Move them now and click Lock when you are done."])
local snapping = CreateFrame('CheckButton', 'Bartender4Snapping', f, 'OptionsCheckButtonTemplate')
_G[snapping:GetName() .. 'Text']:SetText(L["Bar Snapping"])
snapping:SetScript('OnShow', function(self)
self:SetChecked(getSnap())
end)
snapping:SetScript('OnClick', function(self)
setSnap(snapping:GetChecked())
end)
local lockBars = CreateFrame('CheckButton', 'Bartender4DialogLock', f, 'OptionsButtonTemplate')
getglobal(lockBars:GetName() .. 'Text'):SetText(L["Lock"])
lockBars:SetScript('OnClick', function(self)
Bartender4:Lock()
LibStub("AceConfigRegistry-3.0"):NotifyChange("Bartender4")
end)
--position buttons
snapping:SetPoint('BOTTOMLEFT', 14, 10)
lockBars:SetPoint('BOTTOMRIGHT', -14, 14)
self.unlock_dialog = f
end
self.unlock_dialog:Show()
end
function Bartender4:HideUnlockDialog()
if self.unlock_dialog then
self.unlock_dialog:Hide()
end
end
function Bartender4:Unlock()
if self.Locked then
self.Locked = false
Bartender4.Bar:ForAll("Unlock")
self:ShowUnlockDialog()
end
end
function Bartender4:Lock()
if not self.Locked then
self.Locked = true
Bartender4.Bar:ForAll("Lock")
self:HideUnlockDialog()
end
end
function Bartender4:Merge(target, source)
if type(target) ~= "table" then target = {} end
for k,v in pairs(source) do
if type(v) == "table" then
target[k] = self:Merge(target[k], v)
elseif not target[k] then
target[k] = v
end
end
return target
end
Bartender4.modulePrototype = {}
function Bartender4.modulePrototype:ToggleModule(info, value)
if value ~= nil then
self.db.profile.enabled = value
else
value = self.db.profile.enabled
end
if value and not self:IsEnabled() then
self:Enable()
elseif not value and self:IsEnabled() then
self:Disable()
end
end
function Bartender4.modulePrototype:ToggleOptions()
if self.options then
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
end
function Bartender4.modulePrototype:OnDisable()
if not self.bar then return end
-- assign new config table
self.bar.config = self.db.profile
self.bar:Disable()
self:ToggleOptions()
end
Bartender4:SetDefaultModulePrototype(Bartender4.modulePrototype)
function createLDBLauncher()
local L_BT_LEFT = L["|cffffff00Click|r to toggle bar lock"]
local L_BT_RIGHT = L["|cffffff00Right-click|r to open the options menu"]
local LDBObj = LibStub("LibDataBroker-1.1"):NewDataObject("Bartender4", {
type = "launcher",
label = "Bartender4",
OnClick = function(_, msg)
if msg == "LeftButton" then
if Bartender4.Locked then
Bartender4["Unlock"](Bartender4)
else
Bartender4["Lock"](Bartender4)
end
elseif msg == "RightButton" then
if LibStub("AceConfigDialog-3.0").OpenFrames["Bartender4"] then
LibStub("AceConfigDialog-3.0"):Close("Bartender4")
else
LibStub("AceConfigDialog-3.0"):Open("Bartender4")
end
end
end,
icon = "Interface\\Icons\\INV_Drink_05",
OnTooltipShow = function(tooltip)
if not tooltip or not tooltip.AddLine then return end
tooltip:AddLine("Bartender4")
tooltip:AddLine(L_BT_LEFT)
tooltip:AddLine(L_BT_RIGHT)
end,
})
if LDBIcon then
LDBIcon:Register("Bartender4", LDBObj, Bartender4.db.profile.minimapIcon)
end
end
+73 -69
View File
@@ -1,69 +1,73 @@
## Interface: 30300
## Title: Bartender4
## Notes: Simple and Advanced combined - Bartender4 ActionBar AddOn
## Version: @project-version@
## Author: Nevcairiel
## X-Email: h.leppkes at gmail dot com
## X-Category: Action Bars
## X-Website: http://www.wowace.com/projects/bartender4/
## X-License: All rights reserved.
## SavedVariables: Bartender4DB
## OptionalDeps: Ace3, ButtonFacade, LibKeyBound-1.0, LibDBIcon-1.0, LibWindow-1.1
#@no-lib-strip@
libs\LibStub\LibStub.lua
libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
#@end-no-lib-strip@
libs\LibDataBroker-1.1.lua
#@no-lib-strip@
libs\AceAddon-3.0\AceAddon-3.0.xml
libs\AceDB-3.0\AceDB-3.0.xml
libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
libs\AceEvent-3.0\AceEvent-3.0.xml
libs\AceConsole-3.0\AceConsole-3.0.xml
libs\AceHook-3.0\AceHook-3.0.xml
libs\AceLocale-3.0\AceLocale-3.0.xml
libs\AceGUI-3.0\AceGUI-3.0.xml
libs\AceConfig-3.0\AceConfig-3.0.xml
libs\LibKeyBound-1.0\lib.xml
libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
libs\LibWindow-1.1\LibWindow-1.1.lua
#@end-no-lib-strip@
libs\SimpleSticky.lua
locale\locale.xml
## Core ##
Bartender4.lua
## Prototypes ##
Bar.lua
ButtonBar.lua
StateBar.lua
ActionBar.lua
## Buttons ##
ActionButton.lua
PetButton.lua
## Modules ##
ActionBars.lua
BagBar.lua
PetBar.lua
StanceBar.lua
MicroMenu.lua
RepXPBar.lua
VehicleBar.lua
MultiCastBar.lua
## Options ##
Options\Options.xml
## Interface: 30300
## X-Curse-Packaged-Version: 4.4.2-2-g3b02ee4
## X-Curse-Project-Name: Bartender4
## X-Curse-Project-ID: bartender4
## X-Curse-Repository-ID: wow/bartender4/mainline
## Title: Bartender4
## Notes: Simple and Advanced combined - Bartender4 ActionBar AddOn
## Version: 4.4.2-2-g3b02ee4
## Author: Nevcairiel
## X-Email: h.leppkes at gmail dot com
## X-Category: Action Bars
## X-Website: http://www.wowace.com/projects/bartender4/
## X-License: All rights reserved.
## SavedVariables: Bartender4DB
## OptionalDeps: Ace3, ButtonFacade, LibKeyBound-1.0, LibDBIcon-1.0, LibWindow-1.1
#@no-lib-strip@
libs\LibStub\LibStub.lua
libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
#@end-no-lib-strip@
libs\LibDataBroker-1.1.lua
#@no-lib-strip@
libs\AceAddon-3.0\AceAddon-3.0.xml
libs\AceDB-3.0\AceDB-3.0.xml
libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
libs\AceEvent-3.0\AceEvent-3.0.xml
libs\AceConsole-3.0\AceConsole-3.0.xml
libs\AceHook-3.0\AceHook-3.0.xml
libs\AceLocale-3.0\AceLocale-3.0.xml
libs\AceGUI-3.0\AceGUI-3.0.xml
libs\AceConfig-3.0\AceConfig-3.0.xml
libs\LibKeyBound-1.0\lib.xml
libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
libs\LibWindow-1.1\LibWindow-1.1.lua
#@end-no-lib-strip@
libs\SimpleSticky.lua
locale\locale.xml
## Core ##
Bartender4.lua
## Prototypes ##
Bar.lua
ButtonBar.lua
StateBar.lua
ActionBar.lua
## Buttons ##
ActionButton.lua
PetButton.lua
## Modules ##
ActionBars.lua
BagBar.lua
PetBar.lua
StanceBar.lua
MicroMenu.lua
RepXPBar.lua
VehicleBar.lua
MultiCastBar.lua
## Options ##
Options\Options.xml
+149 -141
View File
@@ -1,142 +1,150 @@
<Bindings>
<Binding name="CLICK BT4Button1:LeftButton" header="Bartender4" />
<Binding name="CLICK BT4Button2:LeftButton" />
<Binding name="CLICK BT4Button3:LeftButton" />
<Binding name="CLICK BT4Button4:LeftButton" />
<Binding name="CLICK BT4Button5:LeftButton" />
<Binding name="CLICK BT4Button6:LeftButton" />
<Binding name="CLICK BT4Button7:LeftButton" />
<Binding name="CLICK BT4Button8:LeftButton" />
<Binding name="CLICK BT4Button9:LeftButton" />
<Binding name="CLICK BT4Button10:LeftButton" />
<Binding name="CLICK BT4Button11:LeftButton" />
<Binding name="CLICK BT4Button12:LeftButton" />
<Binding name="CLICK BT4Button13:LeftButton" header="BT4BLANK2" />
<Binding name="CLICK BT4Button14:LeftButton" />
<Binding name="CLICK BT4Button15:LeftButton" />
<Binding name="CLICK BT4Button16:LeftButton" />
<Binding name="CLICK BT4Button17:LeftButton" />
<Binding name="CLICK BT4Button18:LeftButton" />
<Binding name="CLICK BT4Button19:LeftButton" />
<Binding name="CLICK BT4Button20:LeftButton" />
<Binding name="CLICK BT4Button21:LeftButton" />
<Binding name="CLICK BT4Button22:LeftButton" />
<Binding name="CLICK BT4Button23:LeftButton" />
<Binding name="CLICK BT4Button24:LeftButton" />
<Binding name="CLICK BT4Button25:LeftButton" header="BT4BLANK3" />
<Binding name="CLICK BT4Button26:LeftButton" />
<Binding name="CLICK BT4Button27:LeftButton" />
<Binding name="CLICK BT4Button28:LeftButton" />
<Binding name="CLICK BT4Button29:LeftButton" />
<Binding name="CLICK BT4Button30:LeftButton" />
<Binding name="CLICK BT4Button31:LeftButton" />
<Binding name="CLICK BT4Button32:LeftButton" />
<Binding name="CLICK BT4Button33:LeftButton" />
<Binding name="CLICK BT4Button34:LeftButton" />
<Binding name="CLICK BT4Button35:LeftButton" />
<Binding name="CLICK BT4Button36:LeftButton" />
<Binding name="CLICK BT4Button37:LeftButton" header="BT4BLANK4" />
<Binding name="CLICK BT4Button38:LeftButton" />
<Binding name="CLICK BT4Button39:LeftButton" />
<Binding name="CLICK BT4Button40:LeftButton" />
<Binding name="CLICK BT4Button41:LeftButton" />
<Binding name="CLICK BT4Button42:LeftButton" />
<Binding name="CLICK BT4Button43:LeftButton" />
<Binding name="CLICK BT4Button44:LeftButton" />
<Binding name="CLICK BT4Button45:LeftButton" />
<Binding name="CLICK BT4Button46:LeftButton" />
<Binding name="CLICK BT4Button47:LeftButton" />
<Binding name="CLICK BT4Button48:LeftButton" />
<Binding name="CLICK BT4Button49:LeftButton" header="BT4BLANK5" />
<Binding name="CLICK BT4Button50:LeftButton" />
<Binding name="CLICK BT4Button51:LeftButton" />
<Binding name="CLICK BT4Button52:LeftButton" />
<Binding name="CLICK BT4Button53:LeftButton" />
<Binding name="CLICK BT4Button54:LeftButton" />
<Binding name="CLICK BT4Button55:LeftButton" />
<Binding name="CLICK BT4Button56:LeftButton" />
<Binding name="CLICK BT4Button57:LeftButton" />
<Binding name="CLICK BT4Button58:LeftButton" />
<Binding name="CLICK BT4Button59:LeftButton" />
<Binding name="CLICK BT4Button60:LeftButton" />
<Binding name="CLICK BT4Button61:LeftButton" header="BT4BLANK6" />
<Binding name="CLICK BT4Button62:LeftButton" />
<Binding name="CLICK BT4Button63:LeftButton" />
<Binding name="CLICK BT4Button64:LeftButton" />
<Binding name="CLICK BT4Button65:LeftButton" />
<Binding name="CLICK BT4Button66:LeftButton" />
<Binding name="CLICK BT4Button67:LeftButton" />
<Binding name="CLICK BT4Button68:LeftButton" />
<Binding name="CLICK BT4Button69:LeftButton" />
<Binding name="CLICK BT4Button70:LeftButton" />
<Binding name="CLICK BT4Button71:LeftButton" />
<Binding name="CLICK BT4Button72:LeftButton" />
<Binding name="CLICK BT4Button73:LeftButton" header="BT4BLANK7" />
<Binding name="CLICK BT4Button74:LeftButton" />
<Binding name="CLICK BT4Button75:LeftButton" />
<Binding name="CLICK BT4Button76:LeftButton" />
<Binding name="CLICK BT4Button77:LeftButton" />
<Binding name="CLICK BT4Button78:LeftButton" />
<Binding name="CLICK BT4Button79:LeftButton" />
<Binding name="CLICK BT4Button80:LeftButton" />
<Binding name="CLICK BT4Button81:LeftButton" />
<Binding name="CLICK BT4Button82:LeftButton" />
<Binding name="CLICK BT4Button83:LeftButton" />
<Binding name="CLICK BT4Button84:LeftButton" />
<Binding name="CLICK BT4Button85:LeftButton" header="BT4BLANK8" />
<Binding name="CLICK BT4Button86:LeftButton" />
<Binding name="CLICK BT4Button87:LeftButton" />
<Binding name="CLICK BT4Button88:LeftButton" />
<Binding name="CLICK BT4Button89:LeftButton" />
<Binding name="CLICK BT4Button90:LeftButton" />
<Binding name="CLICK BT4Button91:LeftButton" />
<Binding name="CLICK BT4Button92:LeftButton" />
<Binding name="CLICK BT4Button93:LeftButton" />
<Binding name="CLICK BT4Button94:LeftButton" />
<Binding name="CLICK BT4Button95:LeftButton" />
<Binding name="CLICK BT4Button96:LeftButton" />
<Binding name="CLICK BT4Button97:LeftButton" header="BT4BLANK9" />
<Binding name="CLICK BT4Button98:LeftButton" />
<Binding name="CLICK BT4Button99:LeftButton" />
<Binding name="CLICK BT4Button100:LeftButton" />
<Binding name="CLICK BT4Button101:LeftButton" />
<Binding name="CLICK BT4Button102:LeftButton" />
<Binding name="CLICK BT4Button103:LeftButton" />
<Binding name="CLICK BT4Button104:LeftButton" />
<Binding name="CLICK BT4Button105:LeftButton" />
<Binding name="CLICK BT4Button106:LeftButton" />
<Binding name="CLICK BT4Button107:LeftButton" />
<Binding name="CLICK BT4Button108:LeftButton" />
<Binding name="CLICK BT4Button109:LeftButton" header="BT4BLANK10" />
<Binding name="CLICK BT4Button110:LeftButton" />
<Binding name="CLICK BT4Button111:LeftButton" />
<Binding name="CLICK BT4Button112:LeftButton" />
<Binding name="CLICK BT4Button113:LeftButton" />
<Binding name="CLICK BT4Button114:LeftButton" />
<Binding name="CLICK BT4Button115:LeftButton" />
<Binding name="CLICK BT4Button116:LeftButton" />
<Binding name="CLICK BT4Button117:LeftButton" />
<Binding name="CLICK BT4Button118:LeftButton" />
<Binding name="CLICK BT4Button119:LeftButton" />
<Binding name="CLICK BT4Button120:LeftButton" />
<Binding name="CLICK BT4PetButton1:LeftButton" header="BT4PET" />
<Binding name="CLICK BT4PetButton2:LeftButton" />
<Binding name="CLICK BT4PetButton3:LeftButton" />
<Binding name="CLICK BT4PetButton4:LeftButton" />
<Binding name="CLICK BT4PetButton5:LeftButton" />
<Binding name="CLICK BT4PetButton6:LeftButton" />
<Binding name="CLICK BT4PetButton7:LeftButton" />
<Binding name="CLICK BT4PetButton8:LeftButton" />
<Binding name="CLICK BT4PetButton9:LeftButton" />
<Binding name="CLICK BT4PetButton10:LeftButton" />
<Binding name="CLICK BT4StanceButton1:LeftButton" header="BT4STANCE" />
<Binding name="CLICK BT4StanceButton2:LeftButton" />
<Binding name="CLICK BT4StanceButton3:LeftButton" />
<Binding name="CLICK BT4StanceButton4:LeftButton" />
<Binding name="CLICK BT4StanceButton5:LeftButton" />
<Binding name="CLICK BT4StanceButton6:LeftButton" />
<Binding name="CLICK BT4StanceButton7:LeftButton" />
<Binding name="CLICK BT4StanceButton8:LeftButton" />
<Binding name="CLICK BT4StanceButton9:LeftButton" />
<Binding name="CLICK BT4StanceButton10:LeftButton" />
<Bindings>
<Binding name="BTTOGGLEACTIONBARLOCK" header="Bartender4" >
if InCombatLockdown() then
print("Cannot change the button lock during combat.")
return
end
Bartender4.db.profile.buttonlock = not Bartender4.db.profile.buttonlock
Bartender4.Bar:ForAll("ForAll", "SetAttribute", "buttonlock", Bartender4.db.profile.buttonlock)
</Binding>
<Binding name="CLICK BT4Button1:LeftButton" />
<Binding name="CLICK BT4Button2:LeftButton" />
<Binding name="CLICK BT4Button3:LeftButton" />
<Binding name="CLICK BT4Button4:LeftButton" />
<Binding name="CLICK BT4Button5:LeftButton" />
<Binding name="CLICK BT4Button6:LeftButton" />
<Binding name="CLICK BT4Button7:LeftButton" />
<Binding name="CLICK BT4Button8:LeftButton" />
<Binding name="CLICK BT4Button9:LeftButton" />
<Binding name="CLICK BT4Button10:LeftButton" />
<Binding name="CLICK BT4Button11:LeftButton" />
<Binding name="CLICK BT4Button12:LeftButton" />
<Binding name="CLICK BT4Button13:LeftButton" header="BT4BLANK2" />
<Binding name="CLICK BT4Button14:LeftButton" />
<Binding name="CLICK BT4Button15:LeftButton" />
<Binding name="CLICK BT4Button16:LeftButton" />
<Binding name="CLICK BT4Button17:LeftButton" />
<Binding name="CLICK BT4Button18:LeftButton" />
<Binding name="CLICK BT4Button19:LeftButton" />
<Binding name="CLICK BT4Button20:LeftButton" />
<Binding name="CLICK BT4Button21:LeftButton" />
<Binding name="CLICK BT4Button22:LeftButton" />
<Binding name="CLICK BT4Button23:LeftButton" />
<Binding name="CLICK BT4Button24:LeftButton" />
<Binding name="CLICK BT4Button25:LeftButton" header="BT4BLANK3" />
<Binding name="CLICK BT4Button26:LeftButton" />
<Binding name="CLICK BT4Button27:LeftButton" />
<Binding name="CLICK BT4Button28:LeftButton" />
<Binding name="CLICK BT4Button29:LeftButton" />
<Binding name="CLICK BT4Button30:LeftButton" />
<Binding name="CLICK BT4Button31:LeftButton" />
<Binding name="CLICK BT4Button32:LeftButton" />
<Binding name="CLICK BT4Button33:LeftButton" />
<Binding name="CLICK BT4Button34:LeftButton" />
<Binding name="CLICK BT4Button35:LeftButton" />
<Binding name="CLICK BT4Button36:LeftButton" />
<Binding name="CLICK BT4Button37:LeftButton" header="BT4BLANK4" />
<Binding name="CLICK BT4Button38:LeftButton" />
<Binding name="CLICK BT4Button39:LeftButton" />
<Binding name="CLICK BT4Button40:LeftButton" />
<Binding name="CLICK BT4Button41:LeftButton" />
<Binding name="CLICK BT4Button42:LeftButton" />
<Binding name="CLICK BT4Button43:LeftButton" />
<Binding name="CLICK BT4Button44:LeftButton" />
<Binding name="CLICK BT4Button45:LeftButton" />
<Binding name="CLICK BT4Button46:LeftButton" />
<Binding name="CLICK BT4Button47:LeftButton" />
<Binding name="CLICK BT4Button48:LeftButton" />
<Binding name="CLICK BT4Button49:LeftButton" header="BT4BLANK5" />
<Binding name="CLICK BT4Button50:LeftButton" />
<Binding name="CLICK BT4Button51:LeftButton" />
<Binding name="CLICK BT4Button52:LeftButton" />
<Binding name="CLICK BT4Button53:LeftButton" />
<Binding name="CLICK BT4Button54:LeftButton" />
<Binding name="CLICK BT4Button55:LeftButton" />
<Binding name="CLICK BT4Button56:LeftButton" />
<Binding name="CLICK BT4Button57:LeftButton" />
<Binding name="CLICK BT4Button58:LeftButton" />
<Binding name="CLICK BT4Button59:LeftButton" />
<Binding name="CLICK BT4Button60:LeftButton" />
<Binding name="CLICK BT4Button61:LeftButton" header="BT4BLANK6" />
<Binding name="CLICK BT4Button62:LeftButton" />
<Binding name="CLICK BT4Button63:LeftButton" />
<Binding name="CLICK BT4Button64:LeftButton" />
<Binding name="CLICK BT4Button65:LeftButton" />
<Binding name="CLICK BT4Button66:LeftButton" />
<Binding name="CLICK BT4Button67:LeftButton" />
<Binding name="CLICK BT4Button68:LeftButton" />
<Binding name="CLICK BT4Button69:LeftButton" />
<Binding name="CLICK BT4Button70:LeftButton" />
<Binding name="CLICK BT4Button71:LeftButton" />
<Binding name="CLICK BT4Button72:LeftButton" />
<Binding name="CLICK BT4Button73:LeftButton" header="BT4BLANK7" />
<Binding name="CLICK BT4Button74:LeftButton" />
<Binding name="CLICK BT4Button75:LeftButton" />
<Binding name="CLICK BT4Button76:LeftButton" />
<Binding name="CLICK BT4Button77:LeftButton" />
<Binding name="CLICK BT4Button78:LeftButton" />
<Binding name="CLICK BT4Button79:LeftButton" />
<Binding name="CLICK BT4Button80:LeftButton" />
<Binding name="CLICK BT4Button81:LeftButton" />
<Binding name="CLICK BT4Button82:LeftButton" />
<Binding name="CLICK BT4Button83:LeftButton" />
<Binding name="CLICK BT4Button84:LeftButton" />
<Binding name="CLICK BT4Button85:LeftButton" header="BT4BLANK8" />
<Binding name="CLICK BT4Button86:LeftButton" />
<Binding name="CLICK BT4Button87:LeftButton" />
<Binding name="CLICK BT4Button88:LeftButton" />
<Binding name="CLICK BT4Button89:LeftButton" />
<Binding name="CLICK BT4Button90:LeftButton" />
<Binding name="CLICK BT4Button91:LeftButton" />
<Binding name="CLICK BT4Button92:LeftButton" />
<Binding name="CLICK BT4Button93:LeftButton" />
<Binding name="CLICK BT4Button94:LeftButton" />
<Binding name="CLICK BT4Button95:LeftButton" />
<Binding name="CLICK BT4Button96:LeftButton" />
<Binding name="CLICK BT4Button97:LeftButton" header="BT4BLANK9" />
<Binding name="CLICK BT4Button98:LeftButton" />
<Binding name="CLICK BT4Button99:LeftButton" />
<Binding name="CLICK BT4Button100:LeftButton" />
<Binding name="CLICK BT4Button101:LeftButton" />
<Binding name="CLICK BT4Button102:LeftButton" />
<Binding name="CLICK BT4Button103:LeftButton" />
<Binding name="CLICK BT4Button104:LeftButton" />
<Binding name="CLICK BT4Button105:LeftButton" />
<Binding name="CLICK BT4Button106:LeftButton" />
<Binding name="CLICK BT4Button107:LeftButton" />
<Binding name="CLICK BT4Button108:LeftButton" />
<Binding name="CLICK BT4Button109:LeftButton" header="BT4BLANK10" />
<Binding name="CLICK BT4Button110:LeftButton" />
<Binding name="CLICK BT4Button111:LeftButton" />
<Binding name="CLICK BT4Button112:LeftButton" />
<Binding name="CLICK BT4Button113:LeftButton" />
<Binding name="CLICK BT4Button114:LeftButton" />
<Binding name="CLICK BT4Button115:LeftButton" />
<Binding name="CLICK BT4Button116:LeftButton" />
<Binding name="CLICK BT4Button117:LeftButton" />
<Binding name="CLICK BT4Button118:LeftButton" />
<Binding name="CLICK BT4Button119:LeftButton" />
<Binding name="CLICK BT4Button120:LeftButton" />
<Binding name="CLICK BT4PetButton1:LeftButton" header="BT4PET" />
<Binding name="CLICK BT4PetButton2:LeftButton" />
<Binding name="CLICK BT4PetButton3:LeftButton" />
<Binding name="CLICK BT4PetButton4:LeftButton" />
<Binding name="CLICK BT4PetButton5:LeftButton" />
<Binding name="CLICK BT4PetButton6:LeftButton" />
<Binding name="CLICK BT4PetButton7:LeftButton" />
<Binding name="CLICK BT4PetButton8:LeftButton" />
<Binding name="CLICK BT4PetButton9:LeftButton" />
<Binding name="CLICK BT4PetButton10:LeftButton" />
<Binding name="CLICK BT4StanceButton1:LeftButton" header="BT4STANCE" />
<Binding name="CLICK BT4StanceButton2:LeftButton" />
<Binding name="CLICK BT4StanceButton3:LeftButton" />
<Binding name="CLICK BT4StanceButton4:LeftButton" />
<Binding name="CLICK BT4StanceButton5:LeftButton" />
<Binding name="CLICK BT4StanceButton6:LeftButton" />
<Binding name="CLICK BT4StanceButton7:LeftButton" />
<Binding name="CLICK BT4StanceButton8:LeftButton" />
<Binding name="CLICK BT4StanceButton9:LeftButton" />
<Binding name="CLICK BT4StanceButton10:LeftButton" />
</Bindings>
+259 -259
View File
@@ -1,259 +1,259 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
--[[ Generic Template for a Bar which contains Buttons ]]
local Bar = Bartender4.Bar.prototype
local ButtonBar = setmetatable({}, {__index = Bar})
local ButtonBar_MT = {__index = ButtonBar}
local defaults = Bartender4:Merge({
padding = 2,
rows = 1,
hidemacrotext = false,
hidehotkey = false,
skin = {
ID = "DreamLayout",
Backdrop = true,
Gloss = 0,
Zoom = false,
Colors = {},
},
}, Bartender4.Bar.defaults)
Bartender4.ButtonBar = {}
Bartender4.ButtonBar.prototype = ButtonBar
Bartender4.ButtonBar.defaults = defaults
local LBF = LibStub("LibButtonFacade", true)
function Bartender4.ButtonBar:Create(id, config, name)
local bar = setmetatable(Bartender4.Bar:Create(id, config, name), ButtonBar_MT)
if LBF then
bar.LBFGroup = LBF:Group("Bartender4", tostring(id))
bar.LBFGroup.SkinID = config.skin.ID or "Blizzard"
bar.LBFGroup.Backdrop = config.skin.Backdrop
bar.LBFGroup.Gloss = config.skin.Gloss
bar.LBFGroup.Colors = config.skin.Colors
LBF:RegisterSkinCallback("Bartender4", self.SkinChanged, self)
end
return bar
end
local barregistry = Bartender4.Bar.barregistry
function Bartender4.ButtonBar:SkinChanged(SkinID, Gloss, Backdrop, Group, Button, Colors)
local bar = barregistry[tostring(Group)]
if not bar then return end
bar:SkinChanged(SkinID, Gloss, Backdrop, Colors, Button)
end
ButtonBar.BT4BarType = "ButtonBar"
function ButtonBar:UpdateSkin()
if not self.LBFGroup then return end
local config = self.config
self.LBFGroup:Skin(config.skin.ID, config.skin.Gloss, config.skin.Backdrop, config.skin.Colors)
end
function ButtonBar:ApplyConfig(config)
Bar.ApplyConfig(self, config)
ButtonBar.UpdateSkin(self)
-- any module inherting this template should call UpdateButtonLayout after setting up its buttons, we cannot call it here
--self:UpdateButtonLayout()
end
-- get the current padding
function ButtonBar:GetPadding()
return self.config.padding
end
-- set the padding and refresh layout
function ButtonBar:SetPadding(pad)
if pad ~= nil then
self.config.padding = pad
end
self:UpdateButtonLayout()
end
-- get the current number of rows
function ButtonBar:GetRows()
return self.config.rows
end
-- set the number of rows and refresh layout
function ButtonBar:SetRows(rows)
if rows ~= nil then
self.config.rows = rows
end
self:UpdateButtonLayout()
end
function ButtonBar:GetZoom()
return self.config.skin.Zoom
end
function ButtonBar:SetZoom(zoom)
self.config.skin.Zoom = zoom
self:UpdateButtonLayout()
end
function ButtonBar:SetHideMacroText(state)
if state ~= nil then
self.config.hidemacrotext = state
end
self:ForAll("Update")
end
function ButtonBar:GetHideMacroText()
return self.config.hidemacrotext
end
function ButtonBar:SetHideHotkey(state)
if state ~= nil then
self.config.hidehotkey = state
end
self:ForAll("Update")
end
function ButtonBar:GetHideHotkey()
return self.config.hidehotkey
end
function ButtonBar:SetHGrowth(value)
self.config.position.growHorizontal = value
self:AnchorOverlay()
self:UpdateButtonLayout()
end
function ButtonBar:GetHGrowth()
return self.config.position.growHorizontal
end
function ButtonBar:SetVGrowth(value)
self.config.position.growVertical = value
self:AnchorOverlay()
self:UpdateButtonLayout()
end
function ButtonBar:GetVGrowth()
return self.config.position.growVertical
end
ButtonBar.ClickThroughSupport = true
function ButtonBar:SetClickThrough(click)
if click ~= nil then
self.config.clickthrough = click
end
self:ForAll("EnableMouse", not self.config.clickthrough)
end
local math_floor = math.floor
local math_ceil = math.ceil
-- align the buttons and correct the size of the bar overlay frame
ButtonBar.button_width = 36
ButtonBar.button_height = 36
function ButtonBar:UpdateButtonLayout()
local buttons = self.buttons
local pad = self:GetPadding()
local numbuttons = self.numbuttons or #buttons
-- bail out if the bar has no buttons, for whatever reason
-- (eg. stanceless class, or no stances learned yet, etc.)
if numbuttons == 0 then return end
local Rows = self:GetRows()
local ButtonPerRow = math_ceil(numbuttons / Rows) -- just a precaution
Rows = math_ceil(numbuttons / ButtonPerRow)
if Rows > numbuttons then
Rows = numbuttons
ButtonPerRow = 1
end
local hpad = pad + (self.hpad_offset or 0)
local vpad = pad + (self.vpad_offset or 0)
self:SetSize((self.button_width + hpad) * ButtonPerRow - pad + 10, (self.button_height + vpad) * Rows - pad + 10)
local h1, h2, v1, v2
local xOff, yOff
if self.config.position.growHorizontal == "RIGHT" then
h1, h2 = "LEFT", "RIGHT"
xOff = 5
else
h1, h2 = "RIGHT", "LEFT"
xOff = -3
hpad = -hpad
end
if self.config.position.growVertical == "DOWN" then
v1, v2 = "TOP", "BOTTOM"
yOff = -3
else
v1, v2 = "BOTTOM", "TOP"
yOff = 5
vpad = -vpad
end
-- anchor button 1
local anchor = self:GetAnchor()
buttons[1]:ClearSetPoint(anchor, self, anchor, xOff - (self.hpad_offset or 0), yOff - (self.vpad_offset or 0))
-- and anchor all other buttons relative to our button 1
for i = 2, numbuttons do
-- jump into a new row
if ((i-1) % ButtonPerRow) == 0 then
buttons[i]:ClearSetPoint(v1 .. h1, buttons[i-ButtonPerRow], v2 .. h1, 0, -vpad)
-- align to the previous button
else
buttons[i]:ClearSetPoint("TOP" .. h1, buttons[i-1], "TOP" .. h2, hpad, 0)
end
end
if not LBF then
for i = 1, #buttons do
local button = buttons[i]
if button.icon and self.config.skin.Zoom then
button.icon:SetTexCoord(0.07,0.93,0.07,0.93)
elseif button.icon then
button.icon:SetTexCoord(0,1,0,1)
end
end
end
end
function ButtonBar:SkinChanged(SkinID, Gloss, Backdrop, Colors)
self.config.skin.ID = SkinID
self.config.skin.Gloss = Gloss
self.config.skin.Backdrop = Backdrop
self.config.skin.Colors = Colors
end
--[[===================================================================================
Utility function
===================================================================================]]--
-- get a iterator over all buttons
function ButtonBar:GetAll()
return pairs(self.buttons)
end
-- execute a member function on all buttons
function ButtonBar:ForAll(method, ...)
if not self.buttons then return end
for _, button in self:GetAll() do
local func = button[method]
if func then
func(button, ...)
end
end
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
--[[ Generic Template for a Bar which contains Buttons ]]
local Bar = Bartender4.Bar.prototype
local ButtonBar = setmetatable({}, {__index = Bar})
local ButtonBar_MT = {__index = ButtonBar}
local defaults = Bartender4:Merge({
padding = 2,
rows = 1,
hidemacrotext = false,
hidehotkey = false,
skin = {
ID = "DreamLayout",
Backdrop = true,
Gloss = 0,
Zoom = false,
Colors = {},
},
}, Bartender4.Bar.defaults)
Bartender4.ButtonBar = {}
Bartender4.ButtonBar.prototype = ButtonBar
Bartender4.ButtonBar.defaults = defaults
local LBF = LibStub("LibButtonFacade", true)
function Bartender4.ButtonBar:Create(id, config, name)
local bar = setmetatable(Bartender4.Bar:Create(id, config, name), ButtonBar_MT)
if LBF then
bar.LBFGroup = LBF:Group("Bartender4", tostring(id))
bar.LBFGroup.SkinID = config.skin.ID or "Blizzard"
bar.LBFGroup.Backdrop = config.skin.Backdrop
bar.LBFGroup.Gloss = config.skin.Gloss
bar.LBFGroup.Colors = config.skin.Colors
LBF:RegisterSkinCallback("Bartender4", self.SkinChanged, self)
end
return bar
end
local barregistry = Bartender4.Bar.barregistry
function Bartender4.ButtonBar:SkinChanged(SkinID, Gloss, Backdrop, Group, Button, Colors)
local bar = barregistry[tostring(Group)]
if not bar then return end
bar:SkinChanged(SkinID, Gloss, Backdrop, Colors, Button)
end
ButtonBar.BT4BarType = "ButtonBar"
function ButtonBar:UpdateSkin()
if not self.LBFGroup then return end
local config = self.config
self.LBFGroup:Skin(config.skin.ID, config.skin.Gloss, config.skin.Backdrop, config.skin.Colors)
end
function ButtonBar:ApplyConfig(config)
Bar.ApplyConfig(self, config)
ButtonBar.UpdateSkin(self)
-- any module inherting this template should call UpdateButtonLayout after setting up its buttons, we cannot call it here
--self:UpdateButtonLayout()
end
-- get the current padding
function ButtonBar:GetPadding()
return self.config.padding
end
-- set the padding and refresh layout
function ButtonBar:SetPadding(pad)
if pad ~= nil then
self.config.padding = pad
end
self:UpdateButtonLayout()
end
-- get the current number of rows
function ButtonBar:GetRows()
return self.config.rows
end
-- set the number of rows and refresh layout
function ButtonBar:SetRows(rows)
if rows ~= nil then
self.config.rows = rows
end
self:UpdateButtonLayout()
end
function ButtonBar:GetZoom()
return self.config.skin.Zoom
end
function ButtonBar:SetZoom(zoom)
self.config.skin.Zoom = zoom
self:UpdateButtonLayout()
end
function ButtonBar:SetHideMacroText(state)
if state ~= nil then
self.config.hidemacrotext = state
end
self:ForAll("Update")
end
function ButtonBar:GetHideMacroText()
return self.config.hidemacrotext
end
function ButtonBar:SetHideHotkey(state)
if state ~= nil then
self.config.hidehotkey = state
end
self:ForAll("Update")
end
function ButtonBar:GetHideHotkey()
return self.config.hidehotkey
end
function ButtonBar:SetHGrowth(value)
self.config.position.growHorizontal = value
self:AnchorOverlay()
self:UpdateButtonLayout()
end
function ButtonBar:GetHGrowth()
return self.config.position.growHorizontal
end
function ButtonBar:SetVGrowth(value)
self.config.position.growVertical = value
self:AnchorOverlay()
self:UpdateButtonLayout()
end
function ButtonBar:GetVGrowth()
return self.config.position.growVertical
end
ButtonBar.ClickThroughSupport = true
function ButtonBar:SetClickThrough(click)
if click ~= nil then
self.config.clickthrough = click
end
self:ForAll("EnableMouse", not self.config.clickthrough)
end
local math_floor = math.floor
local math_ceil = math.ceil
-- align the buttons and correct the size of the bar overlay frame
ButtonBar.button_width = 36
ButtonBar.button_height = 36
function ButtonBar:UpdateButtonLayout()
local buttons = self.buttons
local pad = self:GetPadding()
local numbuttons = self.numbuttons or #buttons
-- bail out if the bar has no buttons, for whatever reason
-- (eg. stanceless class, or no stances learned yet, etc.)
if numbuttons == 0 then return end
local Rows = self:GetRows()
local ButtonPerRow = math_ceil(numbuttons / Rows) -- just a precaution
Rows = math_ceil(numbuttons / ButtonPerRow)
if Rows > numbuttons then
Rows = numbuttons
ButtonPerRow = 1
end
local hpad = pad + (self.hpad_offset or 0)
local vpad = pad + (self.vpad_offset or 0)
self:SetSize((self.button_width + hpad) * ButtonPerRow - pad + 10, (self.button_height + vpad) * Rows - pad + 10)
local h1, h2, v1, v2
local xOff, yOff
if self.config.position.growHorizontal == "RIGHT" then
h1, h2 = "LEFT", "RIGHT"
xOff = 5
else
h1, h2 = "RIGHT", "LEFT"
xOff = -3
hpad = -hpad
end
if self.config.position.growVertical == "DOWN" then
v1, v2 = "TOP", "BOTTOM"
yOff = -3
else
v1, v2 = "BOTTOM", "TOP"
yOff = 5
vpad = -vpad
end
-- anchor button 1
local anchor = self:GetAnchor()
buttons[1]:ClearSetPoint(anchor, self, anchor, xOff - (self.hpad_offset or 0), yOff - (self.vpad_offset or 0))
-- and anchor all other buttons relative to our button 1
for i = 2, numbuttons do
-- jump into a new row
if ((i-1) % ButtonPerRow) == 0 then
buttons[i]:ClearSetPoint(v1 .. h1, buttons[i-ButtonPerRow], v2 .. h1, 0, -vpad)
-- align to the previous button
else
buttons[i]:ClearSetPoint("TOP" .. h1, buttons[i-1], "TOP" .. h2, hpad, 0)
end
end
if not LBF then
for i = 1, #buttons do
local button = buttons[i]
if button.icon and self.config.skin.Zoom then
button.icon:SetTexCoord(0.07,0.93,0.07,0.93)
elseif button.icon then
button.icon:SetTexCoord(0,1,0,1)
end
end
end
end
function ButtonBar:SkinChanged(SkinID, Gloss, Backdrop, Colors)
self.config.skin.ID = SkinID
self.config.skin.Gloss = Gloss
self.config.skin.Backdrop = Backdrop
self.config.skin.Colors = Colors
end
--[[===================================================================================
Utility function
===================================================================================]]--
-- get a iterator over all buttons
function ButtonBar:GetAll()
return pairs(self.buttons)
end
-- execute a member function on all buttons
function ButtonBar:ForAll(method, ...)
if not self.buttons then return end
for _, button in self:GetAll() do
local func = button[method]
if func then
func(button, ...)
end
end
end
@@ -0,0 +1,3 @@
Hendrik Leppkes:
- Improved sliders in the options with softMin/softMax and bigStep to offer more freedom in configuration.
- Remove old unused option code snippet
+98 -97
View File
@@ -1,97 +1,98 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local MicroMenuMod = Bartender4:NewModule("MicroMenu", "AceHook-3.0")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local MicroMenuBar = setmetatable({}, {__index = ButtonBar})
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = true,
vertical = false,
visibility = {
possess = false,
},
padding = -3,
position = {
scale = 0.8,
},
}, Bartender4.ButtonBar.defaults) }
function MicroMenuMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("MicroMenu", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function MicroMenuMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("MicroMenu", self.db.profile, L["Micro Menu"]), {__index = MicroMenuBar})
local buttons = {}
table_insert(buttons, CharacterMicroButton)
table_insert(buttons, SpellbookMicroButton)
table_insert(buttons, TalentMicroButton)
table_insert(buttons, AchievementMicroButton)
table_insert(buttons, QuestLogMicroButton)
table_insert(buttons, SocialsMicroButton)
table_insert(buttons, PVPMicroButton)
table_insert(buttons, LFDMicroButton)
table_insert(buttons, MainMenuMicroButton)
table_insert(buttons, HelpMicroButton)
self.bar.buttons = buttons
MicroMenuMod.button_count = #buttons
self:SecureHook("UpdateMicroButtons")
for i,v in pairs(buttons) do
v:SetParent(self.bar)
v:Show()
v:SetFrameLevel(self.bar:GetFrameLevel() + 1)
v.ClearSetPoint = self.bar.ClearSetPoint
end
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function MicroMenuMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
function MicroMenuMod:RestoreButtons()
if not self:IsEnabled() then return end
for k,v in pairs(self.bar.buttons) do
v:SetParent(self.bar)
v:Show()
end
self.bar:UpdateButtonLayout()
end
function MicroMenuMod:UpdateMicroButtons()
if MainMenuBar.state == "player" then
self:RestoreButtons()
end
end
MicroMenuBar.button_width = 28
MicroMenuBar.button_height = 58
MicroMenuBar.vpad_offset = -21
function MicroMenuBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", -105, 30)
self:SavePosition()
end
self:UpdateButtonLayout()
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local MicroMenuMod = Bartender4:NewModule("MicroMenu", "AceHook-3.0")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local MicroMenuBar = setmetatable({}, {__index = ButtonBar})
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = true,
vertical = false,
visibility = {
possess = false,
},
padding = -3,
position = {
scale = 0.8,
},
}, Bartender4.ButtonBar.defaults) }
function MicroMenuMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("MicroMenu", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function MicroMenuMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("MicroMenu", self.db.profile, L["Micro Menu"]), {__index = MicroMenuBar})
local buttons = {}
table_insert(buttons, CharacterMicroButton)
table_insert(buttons, SpellbookMicroButton)
table_insert(buttons, TalentMicroButton)
table_insert(buttons, AchievementMicroButton)
table_insert(buttons, QuestLogMicroButton)
table_insert(buttons, SocialsMicroButton)
table_insert(buttons, LFDMicroButton)
table_insert(buttons, PathToAscensionMicroButton)
table_insert(buttons, MainMenuMicroButton)
table_insert(buttons, HelpMicroButton)
table_insert(buttons, ChallengesMicroButton)
self.bar.buttons = buttons
MicroMenuMod.button_count = #buttons
self:SecureHook("UpdateMicroButtons")
for i,v in pairs(buttons) do
v:SetParent(self.bar)
v:Show()
v:SetFrameLevel(self.bar:GetFrameLevel() + 1)
v.ClearSetPoint = self.bar.ClearSetPoint
end
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function MicroMenuMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
function MicroMenuMod:RestoreButtons()
if not self:IsEnabled() then return end
for k,v in pairs(self.bar.buttons) do
v:SetParent(self.bar)
v:Show()
end
self.bar:UpdateButtonLayout()
end
function MicroMenuMod:UpdateMicroButtons()
if MainMenuBar.state == "player" then
self:RestoreButtons()
end
end
MicroMenuBar.button_width = 27
MicroMenuBar.button_height = 40
MicroMenuBar.vpad_offset = 0
function MicroMenuBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", -105, 30)
self:SavePosition()
end
self:UpdateButtonLayout()
end
+74 -61
View File
@@ -1,61 +1,74 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
if not HasMultiCastActionBar or select(2, UnitClass("player")) ~= "SHAMAN" then return end
-- fetch upvalues
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local defaults = { profile = Bartender4:Merge({
enabled = true,
}, Bartender4.Bar.defaults) }
-- register module
local MultiCastMod = Bartender4:NewModule("MultiCast")
-- create prototype information
local MultiCastBar = setmetatable({}, {__index = Bar})
function MultiCastMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("MultiCast", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function MultiCastMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.Bar:Create("MultiCast", self.db.profile, L["Totem Bar"]), {__index = MultiCastBar})
self.bar.content = MultiCastActionBarFrame
self.bar.content:SetScript("OnShow", nil)
self.bar.content:SetScript("OnHide", nil)
self.bar.content:SetScript("OnUpdate", nil)
self.bar.content.ignoreFramePositionManager = true
self.bar.content:SetParent(self.bar)
self.bar.content:Show()
self.bar.content:SetFrameLevel(self.bar:GetFrameLevel() + 1)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function MultiCastMod:ApplyConfig()
if not self:IsEnabled() then return end
self.bar:ApplyConfig(self.db.profile)
end
function MultiCastBar:ApplyConfig(config)
Bar.ApplyConfig(self, config)
self:PerformLayout()
end
function MultiCastBar:PerformLayout()
self:SetSize(230, 40)
local bar = self.content
bar:ClearAllPoints()
bar:SetPoint("TOPLEFT", self, "TOPLEFT", 3, 1)
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
if not HasMultiCastActionBar then return end
local classMask = UnitClassMask("player")
if not bit.contains(EnumUtil.CombineMasks(Enum.ClassMask.SHAMAN, Enum.ClassMask.HERO), classMask) then
return
end
-- fetch upvalues
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local defaults = { profile = Bartender4:Merge({
enabled = true,
}, Bartender4.Bar.defaults) }
-- register module
local MultiCastMod = Bartender4:NewModule("MultiCast")
-- create prototype information
local MultiCastBar = setmetatable({}, {__index = Bar})
local function OnShowMultiCastActionBar()
if MultiCastMod:IsEnabled() then
MultiCastMod:ApplyConfig()
end
end
function MultiCastMod:OnInitialize()
hooksecurefunc("ShowMultiCastActionBar", OnShowMultiCastActionBar)
self.db = Bartender4.db:RegisterNamespace("MultiCast", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function MultiCastMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.Bar:Create("MultiCast", self.db.profile, L["Totem Bar"]), {__index = MultiCastBar})
self.bar.content = MultiCastActionBarFrame
self.bar.content:SetScript("OnShow", nil)
self.bar.content:SetScript("OnHide", nil)
self.bar.content:SetScript("OnUpdate", nil)
self.bar.content.ignoreFramePositionManager = true
self.bar.content:SetParent(self.bar)
self.bar.content:Show()
self.bar.content:SetFrameLevel(self.bar:GetFrameLevel() + 1)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function MultiCastMod:ApplyConfig()
if not self:IsEnabled() then return end
self.bar:ApplyConfig(self.db.profile)
end
function MultiCastBar:ApplyConfig(config)
Bar.ApplyConfig(self, config)
self:PerformLayout()
end
function MultiCastBar:PerformLayout()
self:SetSize(230, 40)
local bar = self.content
bar:ClearAllPoints()
bar:SetPoint("TOPLEFT", self, "TOPLEFT", 3, 1)
end
+216 -216
View File
@@ -1,216 +1,216 @@
local AceGUI = LibStub("AceGUI-3.0")
--------------------------
-- Edit box --
--------------------------
--[[
Events :
OnTextChanged
OnEnterPressed
]]
do
local Type = "NumberEditBox"
local Version = 1
local function OnAcquire(self)
self:SetDisabled(false)
self.showbutton = true
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self:SetDisabled(false)
end
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
local function EditBox_OnEscapePressed(this)
this:ClearFocus()
end
local function ShowButton(self)
if self.showbutton 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
local function EditBox_OnEnterPressed(this)
local self = this.obj
local value = tonumber(this:GetText()) or 0
local cancel = self:Fire("OnEnterPressed",value)
if not cancel then
HideButton(self)
end
end
local function Button_OnClick(this)
local editbox = this.obj.editbox
editbox:ClearFocus()
EditBox_OnEnterPressed(editbox)
end
local function EditBox_OnTextChanged(this)
local self = this.obj
local value = tonumber(this:GetText()) or 0
if value ~= self.lastvalue then
self:Fire("OnTextChanged",value)
self.lastvalue = value
ShowButton(self)
end
end
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.editbox:EnableMouse(false)
self.editbox:ClearFocus()
self.editbox:SetTextColor(0.5,0.5,0.5)
self.label:SetTextColor(0.5,0.5,0.5)
else
self.editbox:EnableMouse(true)
self.editbox:SetTextColor(1,1,1)
self.label:SetTextColor(1,.82,0)
end
end
local function SetText(self, text)
self.lastvalue = tonumber(text) or 0
self.editbox:SetText(tostring(self.lastvalue))
self.editbox:SetCursorPosition(0)
HideButton(self)
end
local function SetWidth(self, width)
self.frame:SetWidth(width)
end
local function SetLabel(self, text)
if text and text ~= "" then
self.label:SetText(text)
self.label:Show()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
self.frame:SetHeight(60)
self.alignoffset = 30
else
self.label:SetText("")
self.label:Hide()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
self.frame:SetHeight(42)
self.alignoffset = 12
end
end
local function ModButton_OnClick(self)
local value = self.obj.lastvalue
value = math.floor(value + 0.5) + self.adjust
self.obj.editbox:SetText(tostring(value))
EditBox_OnEnterPressed(self.obj.editbox)
end
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame",nil,UIParent)
local editbox = CreateFrame("EditBox","AceGUI-3.0NumberEditBox"..num,frame,"InputBoxTemplate")
local self = {}
self.type = Type
self.num = num
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetDisabled = SetDisabled
self.SetText = SetText
self.SetWidth = SetWidth
self.SetLabel = SetLabel
self.frame = frame
frame.obj = self
self.editbox = editbox
editbox.obj = self
self.alignoffset = 30
frame:SetHeight(60)
frame:SetWidth(200)
editbox:SetScript("OnEnter",Control_OnEnter)
editbox:SetScript("OnLeave",Control_OnLeave)
editbox:SetAutoFocus(false)
editbox:SetFontObject(ChatFontNormal)
editbox:SetScript("OnEscapePressed",EditBox_OnEscapePressed)
editbox:SetScript("OnEnterPressed",EditBox_OnEnterPressed)
editbox:SetScript("OnTextChanged",EditBox_OnTextChanged)
editbox:SetTextInsets(0,0,3,3)
editbox:SetMaxLetters(256)
editbox:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",6,15)
editbox:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,15)
editbox:SetHeight(19)
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-2)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
self.label = label
local button = CreateFrame("Button",nil,editbox,"UIPanelButtonTemplate")
button:SetWidth(40)
button:SetHeight(20)
button:SetPoint("RIGHT",editbox,"RIGHT",-2,0)
button:SetText(OKAY)
button:SetScript("OnClick", Button_OnClick)
button:Hide()
self.button = button
button.obj = self
local minus = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
minus:SetWidth(20)
minus:SetHeight(15)
minus:SetPoint("TOPLEFT", editbox, "BOTTOMLEFT", -4, 0)
minus:SetText("-")
minus:Show()
minus.adjust = -1
minus:SetScript("OnClick", ModButton_OnClick)
minus:SetFrameLevel(editbox:GetFrameLevel() + 2)
self.minus = minus
minus.obj = self
local plus = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
plus:SetWidth(20)
plus:SetHeight(15)
plus:SetPoint("TOPRIGHT", editbox, "BOTTOMRIGHT", -2, 0)
plus:SetText("+")
plus:Show()
plus.adjust = 1
plus:SetScript("OnClick", ModButton_OnClick)
plus:SetFrameLevel(editbox:GetFrameLevel() + 2)
self.plus = plus
plus.obj = self
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
local AceGUI = LibStub("AceGUI-3.0")
--------------------------
-- Edit box --
--------------------------
--[[
Events :
OnTextChanged
OnEnterPressed
]]
do
local Type = "NumberEditBox"
local Version = 1
local function OnAcquire(self)
self:SetDisabled(false)
self.showbutton = true
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self:SetDisabled(false)
end
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
local function EditBox_OnEscapePressed(this)
this:ClearFocus()
end
local function ShowButton(self)
if self.showbutton 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
local function EditBox_OnEnterPressed(this)
local self = this.obj
local value = tonumber(this:GetText()) or 0
local cancel = self:Fire("OnEnterPressed",value)
if not cancel then
HideButton(self)
end
end
local function Button_OnClick(this)
local editbox = this.obj.editbox
editbox:ClearFocus()
EditBox_OnEnterPressed(editbox)
end
local function EditBox_OnTextChanged(this)
local self = this.obj
local value = tonumber(this:GetText()) or 0
if value ~= self.lastvalue then
self:Fire("OnTextChanged",value)
self.lastvalue = value
ShowButton(self)
end
end
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.editbox:EnableMouse(false)
self.editbox:ClearFocus()
self.editbox:SetTextColor(0.5,0.5,0.5)
self.label:SetTextColor(0.5,0.5,0.5)
else
self.editbox:EnableMouse(true)
self.editbox:SetTextColor(1,1,1)
self.label:SetTextColor(1,.82,0)
end
end
local function SetText(self, text)
self.lastvalue = tonumber(text) or 0
self.editbox:SetText(tostring(self.lastvalue))
self.editbox:SetCursorPosition(0)
HideButton(self)
end
local function SetWidth(self, width)
self.frame:SetWidth(width)
end
local function SetLabel(self, text)
if text and text ~= "" then
self.label:SetText(text)
self.label:Show()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
self.frame:SetHeight(60)
self.alignoffset = 30
else
self.label:SetText("")
self.label:Hide()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
self.frame:SetHeight(42)
self.alignoffset = 12
end
end
local function ModButton_OnClick(self)
local value = self.obj.lastvalue
value = math.floor(value + 0.5) + self.adjust
self.obj.editbox:SetText(tostring(value))
EditBox_OnEnterPressed(self.obj.editbox)
end
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame",nil,UIParent)
local editbox = CreateFrame("EditBox","AceGUI-3.0NumberEditBox"..num,frame,"InputBoxTemplate")
local self = {}
self.type = Type
self.num = num
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetDisabled = SetDisabled
self.SetText = SetText
self.SetWidth = SetWidth
self.SetLabel = SetLabel
self.frame = frame
frame.obj = self
self.editbox = editbox
editbox.obj = self
self.alignoffset = 30
frame:SetHeight(60)
frame:SetWidth(200)
editbox:SetScript("OnEnter",Control_OnEnter)
editbox:SetScript("OnLeave",Control_OnLeave)
editbox:SetAutoFocus(false)
editbox:SetFontObject(ChatFontNormal)
editbox:SetScript("OnEscapePressed",EditBox_OnEscapePressed)
editbox:SetScript("OnEnterPressed",EditBox_OnEnterPressed)
editbox:SetScript("OnTextChanged",EditBox_OnTextChanged)
editbox:SetTextInsets(0,0,3,3)
editbox:SetMaxLetters(256)
editbox:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",6,15)
editbox:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,15)
editbox:SetHeight(19)
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-2)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
self.label = label
local button = CreateFrame("Button",nil,editbox,"UIPanelButtonTemplate")
button:SetWidth(40)
button:SetHeight(20)
button:SetPoint("RIGHT",editbox,"RIGHT",-2,0)
button:SetText(OKAY)
button:SetScript("OnClick", Button_OnClick)
button:Hide()
self.button = button
button.obj = self
local minus = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
minus:SetWidth(20)
minus:SetHeight(15)
minus:SetPoint("TOPLEFT", editbox, "BOTTOMLEFT", -4, 0)
minus:SetText("-")
minus:Show()
minus.adjust = -1
minus:SetScript("OnClick", ModButton_OnClick)
minus:SetFrameLevel(editbox:GetFrameLevel() + 2)
self.minus = minus
minus.obj = self
local plus = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
plus:SetWidth(20)
plus:SetHeight(15)
plus:SetPoint("TOPRIGHT", editbox, "BOTTOMRIGHT", -2, 0)
plus:SetText("+")
plus:Show()
plus.adjust = 1
plus:SetScript("OnClick", ModButton_OnClick)
plus:SetFrameLevel(editbox:GetFrameLevel() + 2)
self.plus = plus
plus.obj = self
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
+121 -121
View File
@@ -1,121 +1,121 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local StateBar = Bartender4.StateBar.prototype
local ActionBar = Bartender4.ActionBar
--[[===================================================================================
ActionBar Options
===================================================================================]]--
local module = Bartender4:GetModule("ActionBars")
-- option utilty functions
local optGetter, optSetter
do
local optionMap, getBar, callFunc
-- maps option keys to function names
optionMap = {
buttons = "Buttons",
enabled = "Enabled",
grid = "Grid",
}
-- retrieves a valid bar object from the modules actionbars table
function getBar(id)
local bar = module.actionbars[tonumber(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Get", option)
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Set", option, ...)
end
end
-- returns the option table used for all action bars
-- creates it, if the first time called
-- the Universal Bar option table is merged into this, alot of stuff gets inherited.
function module:GetOptionsTable()
return self:GetOptionsObject().table
end
function module:GetOptionsObject()
if not self.baroptions then
local obj = StateBar.GetOptionObject(self)
local cat_general = {
enabled ={
order = 4,
name = L["Enabled"],
desc = L["Enable/Disable the bar."],
type = "toggle",
set = optSetter,
get = optGetter,
},
grid = {
order = 60,
type = "toggle",
name = L["Button Grid"],
desc = L["Toggle the button grid."],
set = optSetter,
get = optGetter,
},
buttons = {
order = 50,
name = L["Buttons"],
desc = L["Number of buttons."],
type = "range",
min = 1, max = 12, step = 1,
set = optSetter,
get = optGetter,
},
}
obj:AddElementGroup("general", cat_general)
self.baroptions = obj
end
return self.baroptions
end
function module:CreateBarOption(id, options)
if not self.options then return end
if not options then
options = self:GetOptionsTable()
end
id = tostring(id)
if not self.options[id] then
self.options[id] = {
order = 10 + tonumber(id),
type = "group",
name = (L["Bar %s"]):format(id),
desc = (L["Configure Bar %s"]):format(id),
childGroups = "tab",
}
end
self.options[id].args = options
-- register options in the BT GUI
Bartender4:RegisterBarOptions(id, self.options[id])
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local StateBar = Bartender4.StateBar.prototype
local ActionBar = Bartender4.ActionBar
--[[===================================================================================
ActionBar Options
===================================================================================]]--
local module = Bartender4:GetModule("ActionBars")
-- option utilty functions
local optGetter, optSetter
do
local optionMap, getBar, callFunc
-- maps option keys to function names
optionMap = {
buttons = "Buttons",
enabled = "Enabled",
grid = "Grid",
}
-- retrieves a valid bar object from the modules actionbars table
function getBar(id)
local bar = module.actionbars[tonumber(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Get", option)
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Set", option, ...)
end
end
-- returns the option table used for all action bars
-- creates it, if the first time called
-- the Universal Bar option table is merged into this, alot of stuff gets inherited.
function module:GetOptionsTable()
return self:GetOptionsObject().table
end
function module:GetOptionsObject()
if not self.baroptions then
local obj = StateBar.GetOptionObject(self)
local cat_general = {
enabled ={
order = 4,
name = L["Enabled"],
desc = L["Enable/Disable the bar."],
type = "toggle",
set = optSetter,
get = optGetter,
},
grid = {
order = 60,
type = "toggle",
name = L["Button Grid"],
desc = L["Toggle the button grid."],
set = optSetter,
get = optGetter,
},
buttons = {
order = 50,
name = L["Buttons"],
desc = L["Number of buttons."],
type = "range",
min = 1, max = 12, step = 1,
set = optSetter,
get = optGetter,
},
}
obj:AddElementGroup("general", cat_general)
self.baroptions = obj
end
return self.baroptions
end
function module:CreateBarOption(id, options)
if not self.options then return end
if not options then
options = self:GetOptionsTable()
end
id = tostring(id)
if not self.options[id] then
self.options[id] = {
order = 10 + tonumber(id),
type = "group",
name = (L["Bar %s"]):format(id),
desc = (L["Configure Bar %s"]):format(id),
childGroups = "tab",
}
end
self.options[id].args = options
-- register options in the BT GUI
Bartender4:RegisterBarOptions(id, self.options[id])
end
+68 -68
View File
@@ -1,68 +1,68 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local BagBarMod = Bartender4:GetModule("BagBar")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function BagBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Bag Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
local onebag = {
type = "toggle",
order = 80,
name = L["One Bag"],
desc = L["Only show one Bag Button in the BagBar."],
get = function() return self.db.profile.onebag end,
set = function(info, state) self.db.profile.onebag = state; self.bar:FeedButtons(); self.bar:UpdateButtonLayout() end,
}
self.optionobject:AddElement("general", "onebag", onebag)
local keyring = {
type = "toggle",
order = 80,
name = L["Keyring"],
desc = L["Show the keyring button."],
get = function() return self.db.profile.keyring end,
set = function(info, state) self.db.profile.keyring = state; self.bar:FeedButtons(); self.bar:UpdateButtonLayout() end,
}
self.optionobject:AddElement("general", "keyring", keyring)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Bag Bar"],
desc = L["Configure the Bag Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("BagBar", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local BagBarMod = Bartender4:GetModule("BagBar")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function BagBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Bag Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
local onebag = {
type = "toggle",
order = 80,
name = L["One Bag"],
desc = L["Only show one Bag Button in the BagBar."],
get = function() return self.db.profile.onebag end,
set = function(info, state) self.db.profile.onebag = state; self.bar:FeedButtons(); self.bar:UpdateButtonLayout() end,
}
self.optionobject:AddElement("general", "onebag", onebag)
local keyring = {
type = "toggle",
order = 80,
name = L["Keyring"],
desc = L["Show the keyring button."],
get = function() return self.db.profile.keyring end,
set = function(info, state) self.db.profile.keyring = state; self.bar:FeedButtons(); self.bar:UpdateButtonLayout() end,
}
self.optionobject:AddElement("general", "keyring", keyring)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Bag Bar"],
desc = L["Configure the Bag Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("BagBar", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
+475 -474
View File
@@ -1,474 +1,475 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
--[[===================================================================================
Bar Options
===================================================================================]]--
local barregistry = Bartender4.Bar.barregistry
local function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
-- option utilty functions
local optGetter, optSetter, visibilityGetter, visibilitySetter, customEnabled, customDisabled, customCopy, clickThroughVis, posGet, posSet, centerHorz, centerVert, resetPos
do
local getBar, optionMap, callFunc
-- maps option keys to function names
optionMap = {
alpha = "ConfigAlpha",
scale = "ConfigScale",
fadeout = "FadeOut",
fadeoutalpha = "FadeOutAlpha",
fadeoutdelay = "FadeOutDelay",
clickthrough = "ClickThrough",
}
-- retrieves a valid bar object from the barregistry table
function getBar(id)
local bar = barregistry[tostring(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Get", option)
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Set", option, ...)
end
function visibilityGetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return bar:GetVisibilityOption(option, ...)
end
function visibilitySetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
bar:SetVisibilityOption(option, ...)
end
function customEnabled(info)
local bar = getBar(info[2])
return bar:GetVisibilityOption("custom")
end
function customDisabled(info)
local bar = getBar(info[2])
return not bar:GetVisibilityOption("custom")
end
function customCopy(info)
local bar = getBar(info[2])
bar:CopyCustomConditionals()
end
function clickThroughVis(info)
local bar = getBar(info[2])
return (not bar.ClickThroughSupport)
end
function posGet(info)
local bar = getBar(info[2])
local opt = info.arg or info[#info]
if opt == "x" or opt == "y" then
local v = bar.config.position[opt]
return tostring(round(v, 5))
end
return bar.config.position[opt]
end
function posSet(info, value)
local bar = getBar(info[2])
local opt = info.arg or info[#info]
if opt == "x" or opt == "y" then
value = tonumber(value)
end
bar.config.position[opt] = value
bar:LoadPosition()
end
function centerHorz(info)
local bar = getBar(info[2])
local pos = bar.config.position
local x_mod = (pos.growHorizontal == "RIGHT") and -1 or 1
pos.x = (bar.overlay:GetWidth() / 2) * pos.scale * x_mod
if pos.point == "CENTER" or pos.point == "LEFT" or pos.point == "RIGHT" then -- no special handling
pos.point = "CENTER"
else
pos.point = pos.point:gsub("LEFT", ""):gsub("RIGHT", "")
end
bar:LoadPosition()
end
function centerVert(info)
local bar = getBar(info[2])
local pos = bar.config.position
local y_mod = (pos.growVertical == "DOWN") and 1 or -1
pos.y = (bar.overlay:GetHeight() / 2) * pos.scale * y_mod
if pos.point == "CENTER" or pos.point == "TOP" or pos.point == "BOTTOM" then -- no special handling
pos.point = "CENTER"
else
pos.point = pos.point:gsub("TOP", ""):gsub("BOTTOM", "")
end
bar:LoadPosition()
end
function resetPos(info)
local bar = getBar(info[2])
local pos = bar.config.position
local x_mod = (pos.growHorizontal == "RIGHT") and -1 or 1
local y_mod = (pos.growVertical == "DOWN") and 1 or -1
pos.x = (bar.overlay:GetWidth() / 2) * pos.scale * x_mod
pos.y = (bar.overlay:GetHeight() / 2) * pos.scale * y_mod
pos.point = "CENTER"
bar:LoadPosition()
end
end
local _, class = UnitClass("player")
local stanceClasses = {
DRUID = true,
WARRIOR = true,
WARLOCK = true,
PRIEST = true,
ROGUE = true,
}
local function getStanceTable()
local tbl = {}
if class ~= "WARRIOR" then
tbl[0] = L["No Stance/Form"]
end
local num = GetNumShapeshiftForms()
for i = 1, num do
tbl[i] = select(2, GetShapeshiftFormInfo(i))
end
-- HACK: Metamorphosis work around, it is on slot 1 in GetShapeshiftFormInfo() but stance:2 is active..
if class == "WARLOCK" and tbl[1] == GetSpellInfo(59672) then
tbl[2], tbl[1] = tbl[1], nil
end
if class == "ROGUE" and tbl[1] == GetSpellInfo(51713) then -- shadow dance hack
tbl[3], tbl[1] = tbl[1], nil
end
return tbl
end
local validAnchors = {
CENTER = "CENTER",
LEFT = "LEFT",
RIGHT = "RIGHT",
TOP = "TOP",
TOPLEFT = "TOPLEFT",
TOPRIGHT = "TOPRIGHT",
BOTTOM = "BOTTOM",
BOTTOMLEFT = "BOTTOMLEFT",
BOTTOMRIGHT = "BOTTOMRIGHT",
}
local options
function Bar:GetOptionObject()
local otbl = {
general = {
type = "group",
cmdInline = true,
name = L["General Settings"],
order = 1,
args = {
styleheader = {
order = 10,
type = "header",
name = L["Bar Style & Layout"],
},
alpha = {
order = 20,
name = L["Alpha"],
desc = L["Configure the alpha of the bar."],
type = "range",
min = .1, max = 1, step = 0.05,
isPercent = true,
get = optGetter,
set = optSetter,
},
scale = {
order = 30,
name = L["Scale"],
desc = L["Configure the scale of the bar."],
type = "range",
min = .1, max = 2, step = 0.05,
get = optGetter,
set = optSetter,
},
clickthrough = {
order = 200,
name = L["Click-Through"],
desc = L["Disable any reaction to mouse events on this bar, making the bar click-through."],
type = "toggle",
get = optGetter,
set = optSetter,
hidden = clickThroughVis,
width = "full",
},
},
},
visibility = {
type = "group",
name = L["Visibility"],
order = 2,
get = visibilityGetter,
set = visibilitySetter,
args = {
info = {
order = 1,
type = "description",
name = L["The bar default is to be visible all the time, you can configure conditions here to control when the bar should be hidden."] .. "\n",
},
fadeout = {
order = 5,
name = L["Fade Out"],
desc = L["Enable the FadeOut mode"],
type = "toggle",
get = optGetter,
set = optSetter,
width = "full",
},
fadeoutalpha = {
order = 6,
name = L["Fade Out Alpha"],
desc = L["Configure the Fade Out Alpha"],
type = "range",
min = 0, max = 1, step = 0.05,
isPercent = true,
get = optGetter,
set = optSetter,
},
fadeoutdelay = {
order = 7,
name = L["Fade Out Delay"],
desc = L["Configure the Fade Out Delay"],
type = "range",
min = 0, max = 1, step = 0.01,
get = optGetter,
set = optSetter,
},
fadeNl = {
order = 8,
type = "description",
name = "",
},
always = {
order = 10,
type = "toggle",
name = L["Always Hide"],
desc = L["You can set the bar to be always hidden, if you only wish to access it using key-bindings."],
disabled = customEnabled,
},
possess = {
order = 15,
type = "toggle",
name = L["Hide when Possessing"],
desc = L["Hide this bar when you are possessing a NPC."],
disabled = customEnabled,
},
vehicle = {
order = 16,
type = "toggle",
name = L["Hide on Vehicle"],
desc = L["Hide this bar when you are riding on a vehicle."],
disabled = customEnabled,
},
vehicleui = {
order = 17,
type = "toggle",
name = L["Hide with Vehicle UI"],
desc = L["Hide this bar when the game wants to show a vehicle UI."],
disabled = customEnabled,
},
combat = {
order = 20,
type = "toggle",
name = L["Hide in Combat"],
desc = L["This bar will be hidden once you enter combat."],
disabled = customEnabled,
},
nocombat = {
order = 21,
type = "toggle",
name = L["Hide out of Combat"],
desc = L["This bar will be hidden whenever you are not in combat."],
disabled = customEnabled,
},
pet = {
order = 30,
type = "toggle",
name = L["Hide with pet"],
desc = L["Hide this bar when you have a pet."],
disabled = customEnabled,
},
nopet = {
order = 31,
type = "toggle",
name = L["Hide without pet"],
desc = L["Hide this bar when you have no pet."],
disabled = customEnabled,
},
stance = {
order = 50,
type = "multiselect",
name = L["Hide in Stance/Form"],
desc = L["Hide this bar in a specific Stance or Form."],
values = getStanceTable,
hidden = function() return (not stanceClasses[class]) end,
disabled = customEnabled,
},
customNl = {
order = 98,
type = "description",
name = "\n",
},
customHeader = {
order = 99,
type = "header",
name = L["Custom Conditionals"],
},
custom = {
order = 100,
type = "toggle",
name = L["Use Custom Condition"],
desc = L["Enable the use of a custom condition, disabling all of the above."],
},
customCopy = {
order = 101,
type = "execute",
name = L["Copy Conditionals"],
desc = L["Create a copy of the auto-generated conditionals in the custom configuration as a base template."],
func = customCopy,
},
customDesc = {
order = 102,
type = "description",
name = L["Note: Enabling Custom Conditionals will disable all of the above settings!"],
},
customdata = {
order = 103,
type = "input",
name = L["Custom Conditionals"],
desc = L["You can use any macro conditionals in the custom string, using \"show\" and \"hide\" as values.\n\nExample: [combat]hide;show"],
width = "full",
multiline = true,
disabled = customDisabled,
},
},
},
position = {
type = "group",
name = L["Positioning"],
order = 20,
args = {
info = {
order = 1,
type = "description",
name = L["The Positioning options here will allow you to position the bar to your liking and with an absolute precision."],
},
point = {
order = 10,
type = "select",
name = L["Anchor"],
desc = L["Change the current anchor point of the bar."],
values = validAnchors,
get = posGet,
set = posSet,
},
scale = {
order = 11,
name = L["Scale"],
desc = L["Configure the scale of the bar."],
type = "range",
min = .1, max = 2, step = 0.05,
get = optGetter,
set = optSetter,
},
nl1 = {
order = 12,
type = "description",
name = "",
},
x = {
order = 20,
type = "input",
name = L["X Offset"],
desc = L["Offset in X direction (horizontal) from the given anchor point."],
get = posGet,
set = posSet,
dialogControl = "NumberEditBox",
},
y = {
order = 21,
type = "input",
name = L["Y Offset"],
desc = L["Offset in Y direction (vertical) from the given anchor point."],
get = posGet,
set = posSet,
dialogControl = "NumberEditBox",
},
nl2 = {
order = 25,
type = "description",
name = "",
},
centerhorz = {
order = 31,
type = "execute",
name = L["Center Horizontally"],
desc = L["Centers the bar horizontally on screen."],
func = centerHorz,
},
centervert = {
order = 31,
type = "execute",
name = L["Center Vertically"],
desc = L["Centers the bar vertically on screen."],
func = centerVert,
},
nl2 = {
order = 35,
type = "description",
name = " ",
},
reset = {
order = 40,
type = "execute",
name = L["Reset Position"],
desc = L["Reset the position of this bar completly if it ended up off-screen and you cannot reach it anymore."],
func = resetPos,
},
},
}
}
return Bartender4:NewOptionObject(otbl)
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
--[[===================================================================================
Bar Options
===================================================================================]]--
local barregistry = Bartender4.Bar.barregistry
local function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
-- option utilty functions
local optGetter, optSetter, visibilityGetter, visibilitySetter, customEnabled, customDisabled, customCopy, clickThroughVis, posGet, posSet, centerHorz, centerVert, resetPos
do
local getBar, optionMap, callFunc
-- maps option keys to function names
optionMap = {
alpha = "ConfigAlpha",
scale = "ConfigScale",
fadeout = "FadeOut",
fadeoutalpha = "FadeOutAlpha",
fadeoutdelay = "FadeOutDelay",
clickthrough = "ClickThrough",
}
-- retrieves a valid bar object from the barregistry table
function getBar(id)
local bar = barregistry[tostring(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Get", option)
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Set", option, ...)
end
function visibilityGetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return bar:GetVisibilityOption(option, ...)
end
function visibilitySetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
bar:SetVisibilityOption(option, ...)
end
function customEnabled(info)
local bar = getBar(info[2])
return bar:GetVisibilityOption("custom")
end
function customDisabled(info)
local bar = getBar(info[2])
return not bar:GetVisibilityOption("custom")
end
function customCopy(info)
local bar = getBar(info[2])
bar:CopyCustomConditionals()
end
function clickThroughVis(info)
local bar = getBar(info[2])
return (not bar.ClickThroughSupport)
end
function posGet(info)
local bar = getBar(info[2])
local opt = info.arg or info[#info]
if opt == "x" or opt == "y" then
local v = bar.config.position[opt]
return tostring(round(v, 5))
end
return bar.config.position[opt]
end
function posSet(info, value)
local bar = getBar(info[2])
local opt = info.arg or info[#info]
if opt == "x" or opt == "y" then
value = tonumber(value)
end
bar.config.position[opt] = value
bar:LoadPosition()
end
function centerHorz(info)
local bar = getBar(info[2])
local pos = bar.config.position
local x_mod = (pos.growHorizontal == "RIGHT") and -1 or 1
pos.x = (bar.overlay:GetWidth() / 2) * pos.scale * x_mod
if pos.point == "CENTER" or pos.point == "LEFT" or pos.point == "RIGHT" then -- no special handling
pos.point = "CENTER"
else
pos.point = pos.point:gsub("LEFT", ""):gsub("RIGHT", "")
end
bar:LoadPosition()
end
function centerVert(info)
local bar = getBar(info[2])
local pos = bar.config.position
local y_mod = (pos.growVertical == "DOWN") and 1 or -1
pos.y = (bar.overlay:GetHeight() / 2) * pos.scale * y_mod
if pos.point == "CENTER" or pos.point == "TOP" or pos.point == "BOTTOM" then -- no special handling
pos.point = "CENTER"
else
pos.point = pos.point:gsub("TOP", ""):gsub("BOTTOM", "")
end
bar:LoadPosition()
end
function resetPos(info)
local bar = getBar(info[2])
local pos = bar.config.position
local x_mod = (pos.growHorizontal == "RIGHT") and -1 or 1
local y_mod = (pos.growVertical == "DOWN") and 1 or -1
pos.x = (bar.overlay:GetWidth() / 2) * pos.scale * x_mod
pos.y = (bar.overlay:GetHeight() / 2) * pos.scale * y_mod
pos.point = "CENTER"
bar:LoadPosition()
end
end
local _, class = UnitClass("player")
local stanceClasses = {
DRUID = true,
HERO = true,
WARRIOR = true,
WARLOCK = true,
PRIEST = true,
ROGUE = true,
}
local function getStanceTable()
local tbl = {}
if class ~= "WARRIOR" then
tbl[0] = L["No Stance/Form"]
end
local num = GetNumShapeshiftForms()
for i = 1, num do
tbl[i] = select(2, GetShapeshiftFormInfo(i))
end
-- HACK: Metamorphosis work around, it is on slot 1 in GetShapeshiftFormInfo() but stance:2 is active..
if class == "WARLOCK" and tbl[1] == GetSpellInfo(59672) then
tbl[2], tbl[1] = tbl[1], nil
end
if class == "ROGUE" and tbl[1] == GetSpellInfo(51713) then -- shadow dance hack
tbl[3], tbl[1] = tbl[1], nil
end
return tbl
end
local validAnchors = {
CENTER = "CENTER",
LEFT = "LEFT",
RIGHT = "RIGHT",
TOP = "TOP",
TOPLEFT = "TOPLEFT",
TOPRIGHT = "TOPRIGHT",
BOTTOM = "BOTTOM",
BOTTOMLEFT = "BOTTOMLEFT",
BOTTOMRIGHT = "BOTTOMRIGHT",
}
local options
function Bar:GetOptionObject()
local otbl = {
general = {
type = "group",
cmdInline = true,
name = L["General Settings"],
order = 1,
args = {
styleheader = {
order = 10,
type = "header",
name = L["Bar Style & Layout"],
},
alpha = {
order = 20,
name = L["Alpha"],
desc = L["Configure the alpha of the bar."],
type = "range",
min = 0, max = 1, bigStep = 0.05,
isPercent = true,
get = optGetter,
set = optSetter,
},
scale = {
order = 30,
name = L["Scale"],
desc = L["Configure the scale of the bar."],
type = "range",
min = 0, softMin = .1, softMax = 2, bigStep = 0.05,
get = optGetter,
set = optSetter,
},
clickthrough = {
order = 200,
name = L["Click-Through"],
desc = L["Disable any reaction to mouse events on this bar, making the bar click-through."],
type = "toggle",
get = optGetter,
set = optSetter,
hidden = clickThroughVis,
width = "full",
},
},
},
visibility = {
type = "group",
name = L["Visibility"],
order = 2,
get = visibilityGetter,
set = visibilitySetter,
args = {
info = {
order = 1,
type = "description",
name = L["The bar default is to be visible all the time, you can configure conditions here to control when the bar should be hidden."] .. "\n",
},
fadeout = {
order = 5,
name = L["Fade Out"],
desc = L["Enable the FadeOut mode"],
type = "toggle",
get = optGetter,
set = optSetter,
width = "full",
},
fadeoutalpha = {
order = 6,
name = L["Fade Out Alpha"],
desc = L["Configure the Fade Out Alpha"],
type = "range",
min = 0, max = 1, bigStep = 0.05,
isPercent = true,
get = optGetter,
set = optSetter,
},
fadeoutdelay = {
order = 7,
name = L["Fade Out Delay"],
desc = L["Configure the Fade Out Delay"],
type = "range",
min = 0, softMax = 1, bigStep = 0.01,
get = optGetter,
set = optSetter,
},
fadeNl = {
order = 8,
type = "description",
name = "",
},
always = {
order = 10,
type = "toggle",
name = L["Always Hide"],
desc = L["You can set the bar to be always hidden, if you only wish to access it using key-bindings."],
disabled = customEnabled,
},
possess = {
order = 15,
type = "toggle",
name = L["Hide when Possessing"],
desc = L["Hide this bar when you are possessing a NPC."],
disabled = customEnabled,
},
vehicle = {
order = 16,
type = "toggle",
name = L["Hide on Vehicle"],
desc = L["Hide this bar when you are riding on a vehicle."],
disabled = customEnabled,
},
vehicleui = {
order = 17,
type = "toggle",
name = L["Hide with Vehicle UI"],
desc = L["Hide this bar when the game wants to show a vehicle UI."],
disabled = customEnabled,
},
combat = {
order = 20,
type = "toggle",
name = L["Hide in Combat"],
desc = L["This bar will be hidden once you enter combat."],
disabled = customEnabled,
},
nocombat = {
order = 21,
type = "toggle",
name = L["Hide out of Combat"],
desc = L["This bar will be hidden whenever you are not in combat."],
disabled = customEnabled,
},
pet = {
order = 30,
type = "toggle",
name = L["Hide with pet"],
desc = L["Hide this bar when you have a pet."],
disabled = customEnabled,
},
nopet = {
order = 31,
type = "toggle",
name = L["Hide without pet"],
desc = L["Hide this bar when you have no pet."],
disabled = customEnabled,
},
stance = {
order = 50,
type = "multiselect",
name = L["Hide in Stance/Form"],
desc = L["Hide this bar in a specific Stance or Form."],
values = getStanceTable,
hidden = function() return (not stanceClasses[class]) end,
disabled = customEnabled,
},
customNl = {
order = 98,
type = "description",
name = "\n",
},
customHeader = {
order = 99,
type = "header",
name = L["Custom Conditionals"],
},
custom = {
order = 100,
type = "toggle",
name = L["Use Custom Condition"],
desc = L["Enable the use of a custom condition, disabling all of the above."],
},
customCopy = {
order = 101,
type = "execute",
name = L["Copy Conditionals"],
desc = L["Create a copy of the auto-generated conditionals in the custom configuration as a base template."],
func = customCopy,
},
customDesc = {
order = 102,
type = "description",
name = L["Note: Enabling Custom Conditionals will disable all of the above settings!"],
},
customdata = {
order = 103,
type = "input",
name = L["Custom Conditionals"],
desc = L["You can use any macro conditionals in the custom string, using \"show\" and \"hide\" as values.\n\nExample: [combat]hide;show"],
width = "full",
multiline = true,
disabled = customDisabled,
},
},
},
position = {
type = "group",
name = L["Positioning"],
order = 20,
args = {
info = {
order = 1,
type = "description",
name = L["The Positioning options here will allow you to position the bar to your liking and with an absolute precision."],
},
point = {
order = 10,
type = "select",
name = L["Anchor"],
desc = L["Change the current anchor point of the bar."],
values = validAnchors,
get = posGet,
set = posSet,
},
scale = {
order = 11,
name = L["Scale"],
desc = L["Configure the scale of the bar."],
type = "range",
min = 0, softMin = .1, softMax = 2, bigStep = 0.05,
get = optGetter,
set = optSetter,
},
nl1 = {
order = 12,
type = "description",
name = "",
},
x = {
order = 20,
type = "input",
name = L["X Offset"],
desc = L["Offset in X direction (horizontal) from the given anchor point."],
get = posGet,
set = posSet,
dialogControl = "NumberEditBox",
},
y = {
order = 21,
type = "input",
name = L["Y Offset"],
desc = L["Offset in Y direction (vertical) from the given anchor point."],
get = posGet,
set = posSet,
dialogControl = "NumberEditBox",
},
nl2 = {
order = 25,
type = "description",
name = "",
},
centerhorz = {
order = 31,
type = "execute",
name = L["Center Horizontally"],
desc = L["Centers the bar horizontally on screen."],
func = centerHorz,
},
centervert = {
order = 31,
type = "execute",
name = L["Center Vertically"],
desc = L["Centers the bar vertically on screen."],
func = centerVert,
},
nl2 = {
order = 35,
type = "description",
name = " ",
},
reset = {
order = 40,
type = "execute",
name = L["Reset Position"],
desc = L["Reset the position of this bar completly if it ended up off-screen and you cannot reach it anymore."],
func = resetPos,
},
},
}
}
return Bartender4:NewOptionObject(otbl)
end
+131 -131
View File
@@ -1,131 +1,131 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local ButtonBar = Bartender4.ButtonBar.prototype
--[[===================================================================================
Bar Options
===================================================================================]]--
-- option utilty functions
local optGetter, optSetter
do
local getBar, optionMap, callFunc
local barregistry = Bartender4.Bar.barregistry
-- maps option keys to function names
optionMap = {
rows = "Rows",
padding = "Padding",
zoom = "Zoom",
macrotext = "HideMacroText",
hotkey = "HideHotkey",
vgrowth = "VGrowth",
hgrowth = "HGrowth",
}
-- retrieves a valid bar object from the barregistry table
function getBar(id)
local bar = barregistry[tostring(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Get", option)
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Set", option, ...)
end
end
function ButtonBar:GetOptionObject()
local obj = Bar.GetOptionObject()
local otbl_general = {
padding = {
order = 40,
type = "range",
name = L["Padding"],
desc = L["Configure the padding of the buttons."],
min = -10, max = 20, step = 1,
set = optSetter,
get = optGetter,
},
zoom = {
order = 59,
name = L["Zoom"],
type = "toggle",
desc = L["Toggle Button Zoom\nFor more style options you need to install ButtonFacade"],
get = optGetter,
set = optSetter,
hidden = function() return LibStub("LibButtonFacade", true) and true or false end,
},
rows = {
order = 70,
name = L["Rows"],
desc = L["Number of rows."],
type = "range",
min = 1, max = 12, step = 1,
set = optSetter,
get = optGetter,
},
vgrowth = {
order = 75,
name = L["Vertical Growth"],
desc = L["Vertical growth direction for this bar."],
type = "select",
values = {UP = L["Up"], DOWN = L["Down"]},
set = optSetter,
get = optGetter,
},
hgrowth = {
order = 76,
name = L["Horizontal Growth"],
desc = L["Horizontal growth direction for this bar."],
type = "select",
values = {LEFT = L["Left"], RIGHT = L["Right"]},
set = optSetter,
get = optGetter,
},
hidedesc = {
order = 80,
name = L["Button Look"],
type = "header",
},
macrotext = {
order = 81,
type = "toggle",
name = L["Hide Macro Text"],
desc = L["Hide the Macro Text on the buttons of this bar."],
set = optSetter,
get = optGetter,
},
hotkey = {
order = 82,
type = "toggle",
name = L["Hide Hotkey"],
desc = L["Hide the Hotkey on the buttons of this bar."],
set = optSetter,
get = optGetter,
},
}
obj:AddElementGroup("general", otbl_general)
return obj
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local ButtonBar = Bartender4.ButtonBar.prototype
--[[===================================================================================
Bar Options
===================================================================================]]--
-- option utilty functions
local optGetter, optSetter
do
local getBar, optionMap, callFunc
local barregistry = Bartender4.Bar.barregistry
-- maps option keys to function names
optionMap = {
rows = "Rows",
padding = "Padding",
zoom = "Zoom",
macrotext = "HideMacroText",
hotkey = "HideHotkey",
vgrowth = "VGrowth",
hgrowth = "HGrowth",
}
-- retrieves a valid bar object from the barregistry table
function getBar(id)
local bar = barregistry[tostring(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Get", option)
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info[#info]
return callFunc(bar, "Set", option, ...)
end
end
function ButtonBar:GetOptionObject()
local obj = Bar.GetOptionObject()
local otbl_general = {
padding = {
order = 40,
type = "range",
name = L["Padding"],
desc = L["Configure the padding of the buttons."],
softMin = -10, softMax = 20, bigStep = 1,
set = optSetter,
get = optGetter,
},
zoom = {
order = 59,
name = L["Zoom"],
type = "toggle",
desc = L["Toggle Button Zoom\nFor more style options you need to install ButtonFacade"],
get = optGetter,
set = optSetter,
hidden = function() return LibStub("LibButtonFacade", true) and true or false end,
},
rows = {
order = 70,
name = L["Rows"],
desc = L["Number of rows."],
type = "range",
min = 1, max = 12, step = 1,
set = optSetter,
get = optGetter,
},
vgrowth = {
order = 75,
name = L["Vertical Growth"],
desc = L["Vertical growth direction for this bar."],
type = "select",
values = {UP = L["Up"], DOWN = L["Down"]},
set = optSetter,
get = optGetter,
},
hgrowth = {
order = 76,
name = L["Horizontal Growth"],
desc = L["Horizontal growth direction for this bar."],
type = "select",
values = {LEFT = L["Left"], RIGHT = L["Right"]},
set = optSetter,
get = optGetter,
},
hidedesc = {
order = 80,
name = L["Button Look"],
type = "header",
},
macrotext = {
order = 81,
type = "toggle",
name = L["Hide Macro Text"],
desc = L["Hide the Macro Text on the buttons of this bar."],
set = optSetter,
get = optGetter,
},
hotkey = {
order = 82,
type = "toggle",
name = L["Hide Hotkey"],
desc = L["Hide the Hotkey on the buttons of this bar."],
set = optSetter,
get = optGetter,
},
}
obj:AddElementGroup("general", otbl_general)
return obj
end
+49 -49
View File
@@ -1,49 +1,49 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local MicroMenuMod = Bartender4:GetModule("MicroMenu")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function MicroMenuMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Micro Menu"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Micro Menu"],
desc = L["Configure the Micro Menu"],
childGroups = "tab",
}
self.optionobject.table.general.args.padding.min = -30
Bartender4:RegisterBarOptions("MicroMenu", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local MicroMenuMod = Bartender4:GetModule("MicroMenu")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function MicroMenuMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Micro Menu"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Micro Menu"],
desc = L["Configure the Micro Menu"],
childGroups = "tab",
}
self.optionobject.table.general.args.padding.min = -30
Bartender4:RegisterBarOptions("MicroMenu", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
+55 -49
View File
@@ -1,49 +1,55 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
if not HasMultiCastActionBar or select(2, UnitClass("player")) ~= "SHAMAN" then return end
-- fetch upvalues
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local MultiCastMod = Bartender4:GetModule("MultiCast")
function MultiCastMod:SetupOptions()
if not self.options then
self.optionobject = Bar:GetOptionObject()
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Totem Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 100,
type = "group",
name = L["Totem Bar"],
desc = L["Configure the Totem Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("MultiCast", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
if not HasMultiCastActionBar then return end
local classMask = UnitClassMask("player")
if not bit.contains(EnumUtil.CombineMasks(Enum.ClassMask.SHAMAN, Enum.ClassMask.HERO), classMask) then
return
end
-- fetch upvalues
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local MultiCastMod = Bartender4:GetModule("MultiCast")
function MultiCastMod:SetupOptions()
if not self.options then
self.optionobject = Bar:GetOptionObject()
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Totem Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 100,
type = "group",
name = L["Totem Bar"],
desc = L["Configure the Totem Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("MultiCast", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
+316 -326
View File
@@ -1,326 +1,316 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local getFunc, setFunc
do
function getFunc(info)
return (info.arg and Bartender4.db.profile[info.arg] or Bartender4.db.profile[info[#info]])
end
function setFunc(info, value)
local key = info.arg or info[#info]
Bartender4.db.profile[key] = value
end
end
local KB = LibStub("LibKeyBound-1.0")
local LDBIcon = LibStub("LibDBIcon-1.0", true)
local function getOptions()
if not Bartender4.options then
Bartender4.options = {
type = "group",
name = "Bartender4",
icon = "Interface\\Icons\\INV_Drink_05",
childGroups = "tree",
plugins = {},
args = {
lock = {
order = 1,
type = "toggle",
name = L["Lock"],
desc = L["Lock all bars."],
get = function() return Bartender4.Locked end,
set = function(info, value) Bartender4[value and "Lock" or "Unlock"](Bartender4) end,
width = "half",
},
buttonlock = {
order = 2,
type = "toggle",
name = L["Button Lock"],
desc = L["Lock the buttons."],
get = function() return Bartender4.db.profile.buttonlock end,
set = function(info, value)
Bartender4.db.profile.buttonlock = value
Bartender4.Bar:ForAll("ForAll", "SetAttribute", "buttonlock", value)
end,
},
minimapIcon = {
order = 3,
type = "toggle",
name = L["Minimap Icon"],
desc = L["Show a Icon to open the config at the Minimap"],
get = function() return not Bartender4.db.profile.minimapIcon.hide end,
set = function(info, value) Bartender4.db.profile.minimapIcon.hide = not value; LDBIcon[value and "Show" or "Hide"](LDBIcon, "Bartender4") end,
disabled = function() return not LDBIcon end,
},
kb = {
order = 4,
type = "execute",
name = L["Key Bindings"],
desc = L["Switch to key-binding mode"],
func = function()
KB:Toggle()
AceConfigDialog:Close("Bartender4")
end,
},
bars = {
order = 20,
type = "group",
name = L["Bars"],
args = {
options = {
type = "group",
order = 0,
name = function(info) if info.uiType == "dialog" then return "" else return L["Bar Options"] end end,
guiInline = true,
args = {
blizzardVehicle = {
order = 1,
type = "toggle",
name = L["Use Blizzard Vehicle UI"],
desc = L["Enable the use of the Blizzard Vehicle UI, hiding any Bartender4 bars in the meantime."],
width = "full",
get = getFunc,
set = function(info, value)
if UnitHasVehicleUI("player") then
Bartender4:Print(L["You have to exit the vehicle in order to be able to change the Vehicle UI settings."])
return
end
Bartender4.db.profile.blizzardVehicle = value
Bartender4:UpdateBlizzardVehicle()
end,
},
selfcastmodifier = {
order = 10,
type = "toggle",
name = L["Self-Cast by modifier"],
desc = L["Toggle the use of the modifier-based self-cast functionality."],
get = getFunc,
set = function(info, value)
Bartender4.db.profile.selfcastmodifier = value
Bartender4.Bar:ForAll("UpdateSelfCast")
end,
},
setselfcastmod = {
order = 20,
type = "select",
name = L["Self-Cast Modifier"],
desc = L["Select the Self-Cast Modifier"],
get = function(info) return GetModifiedClick("SELFCAST") end,
set = function(info, value) SetModifiedClick("SELFCAST", value); SaveBindings(GetCurrentBindingSet() or 1) end,
values = { NONE = L["None"], ALT = L["ALT"], SHIFT = L["SHIFT"], CTRL = L["CTRL"] },
},
selfcast_nl = {
order = 30,
type = "description",
name = "",
},
focuscastmodifier = {
order = 50,
type = "toggle",
name = L["Focus-Cast by modifier"],
desc = L["Toggle the use of the modifier-based focus-cast functionality."],
get = getFunc,
set = function(info, value)
Bartender4.db.profile.focuscastmodifier = value
Bartender4.Bar:ForAll("UpdateSelfCast")
end,
},
setfocuscastmod = {
order = 60,
type = "select",
name = L["Focus-Cast Modifier"],
desc = L["Select the Focus-Cast Modifier"],
get = function(info) return GetModifiedClick("FOCUSCAST") end,
set = function(info, value) SetModifiedClick("FOCUSCAST", value); SaveBindings(GetCurrentBindingSet() or 1) end,
values = { NONE = L["None"], ALT = L["ALT"], SHIFT = L["SHIFT"], CTRL = L["CTRL"] },
},
focuscast_nl = {
order = 70,
type = "description",
name = "",
},
selfcastrightclick = {
order = 80,
type = "toggle",
name = L["Right-click Self-Cast"],
desc = L["Toggle the use of the right-click self-cast functionality."],
get = getFunc,
set = function(info, value)
Bartender4.db.profile.selfcastrightclick = value
Bartender4.Bar:ForAll("UpdateSelfCast")
end,
},
rightclickselfcast_nl = {
order = 90,
type = "description",
name = "",
},
range = {
order = 100,
name = L["Out of Range Indicator"],
desc = L["Configure how the Out of Range Indicator should display on the buttons."],
type = "select",
style = "dropdown",
get = function()
return Bartender4.db.profile.outofrange
end,
set = function(info, value)
Bartender4.db.profile.outofrange = value
Bartender4.Bar:ForAll("ApplyConfig")
end,
values = { none = L["No Display"], button = L["Full Button Mode"], hotkey = L["Hotkey Mode"] },
},
colors = {
order = 130,
type = "group",
guiInline = true,
name = L["Colors"],
get = function(info)
local color = Bartender4.db.profile.colors[info[#info]]
return color.r, color.g, color.b
end,
set = function(info, r, g, b)
local color = Bartender4.db.profile.colors[info[#info]]
color.r, color.g, color.b = r, g, b
Bartender4.Bar:ForAll("ApplyConfig")
end,
args = {
range = {
order = 1,
type = "color",
name = L["Out of Range Indicator"],
desc = L["Specify the Color of the Out of Range Indicator"],
},
mana = {
order = 2,
type = "color",
name = L["Out of Mana Indicator"],
desc = L["Specify the Color of the Out of Mana Indicator"],
},
},
},
tooltip = {
order = 200,
name = L["Button Tooltip"],
type = "select",
desc = L["Configure the Button Tooltip."],
values = { ["disabled"] = L["Disabled"], ["nocombat"] = L["Disabled in Combat"], ["enabled"] = L["Enabled"] },
get = function() return Bartender4.db.profile.tooltip end,
set = function(info, value) Bartender4.db.profile.tooltip = value end,
},
},
},
},
},
faq = {
name = L["FAQ"],
desc = L["Frequently Asked Questions"],
type = "group",
order = 200,
args = {
faq = {
type = "description",
name = L["FAQ_TEXT"],
},
},
},
},
}
Bartender4.options.plugins.profiles = { profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(Bartender4.db) }
for k,v in Bartender4:IterateModules() do
if v.SetupOptions then
v:SetupOptions()
end
end
end
return Bartender4.options
end
function Bartender4:ChatCommand(input)
if InCombatLockdown() then
self:Print(L["Cannot access options during combat."])
return
end
if not input or input:trim() == "" then
LibStub("AceConfigDialog-3.0"):Open("Bartender4")
else
LibStub("AceConfigCmd-3.0").HandleCommand(Bartender4, "bt", "Bartender4", input)
end
end
function Bartender4:SetupOptions()
LibStub("AceConfig-3.0"):RegisterOptionsTable("Bartender4", getOptions)
AceConfigDialog:SetDefaultSize("Bartender4", 680,525)
local optFunc = function()
if InCombatLockdown() then return end
AceConfigDialog:Open("Bartender4")
--[[
local status = AceConfigDialog:GetStatusTable("Bartender4")
if not status.groups then status.groups = {} end
if not status.groups.groups then status.groups.groups = {} end
status.groups.groups["actionbars"] = true
]]
end
self:RegisterChatCommand( "bar", "ChatCommand")
self:RegisterChatCommand( "bt", "ChatCommand")
self:RegisterChatCommand( "bt4", "ChatCommand")
self:RegisterChatCommand( "bartender", "ChatCommand")
self:RegisterChatCommand( "bartender4", "ChatCommand")
end
function Bartender4:RegisterModuleOptions(key, table)
if not self.options then
error("Options table has not been created yet, respond to the callback!", 2)
end
self.options.plugins[key] = { [key] = table }
end
function Bartender4:RegisterBarOptions(id, table)
if not self.options then
error("Options table has not been created yet, respond to the callback!", 2)
end
self.options.args.bars.args[id] = table
end
local optionParent = {}
function optionParent:NewCategory(category, data)
self.table[category] = data
end
local ov = nil
function optionParent:AddElement(category, element, data, ...)
local lvl = self.table[category]
for i = 1, select('#', ...) do
local key = select(i, ...)
if not (lvl.args[key] and lvl.args[key].args) then
error(("Sub-Level Key %s does not exist in options group or is no sub-group."):format(key), ov and 3 or 2)
end
lvl = lvl.args[key]
end
lvl.args[element] = data
end
function optionParent:AddElementGroup(category, data, ...)
ov = true
for k,v in pairs(data) do
self:AddElement(category, k, v, ...)
end
ov = nil
end
function Bartender4:NewOptionObject(otbl)
if not otbl then otbl = {} end
local tbl = { table = otbl }
for k, v in pairs(optionParent) do
tbl[k] = v
end
return tbl
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local getFunc, setFunc
do
function getFunc(info)
return (info.arg and Bartender4.db.profile[info.arg] or Bartender4.db.profile[info[#info]])
end
function setFunc(info, value)
local key = info.arg or info[#info]
Bartender4.db.profile[key] = value
end
end
local KB = LibStub("LibKeyBound-1.0")
local LDBIcon = LibStub("LibDBIcon-1.0", true)
local function getOptions()
if not Bartender4.options then
Bartender4.options = {
type = "group",
name = "Bartender4",
icon = "Interface\\Icons\\INV_Drink_05",
childGroups = "tree",
plugins = {},
args = {
lock = {
order = 1,
type = "toggle",
name = L["Lock"],
desc = L["Lock all bars."],
get = function() return Bartender4.Locked end,
set = function(info, value) Bartender4[value and "Lock" or "Unlock"](Bartender4) end,
width = "half",
},
buttonlock = {
order = 2,
type = "toggle",
name = L["Button Lock"],
desc = L["Lock the buttons."],
get = function() return Bartender4.db.profile.buttonlock end,
set = function(info, value)
Bartender4.db.profile.buttonlock = value
Bartender4.Bar:ForAll("ForAll", "SetAttribute", "buttonlock", value)
end,
},
minimapIcon = {
order = 3,
type = "toggle",
name = L["Minimap Icon"],
desc = L["Show a Icon to open the config at the Minimap"],
get = function() return not Bartender4.db.profile.minimapIcon.hide end,
set = function(info, value) Bartender4.db.profile.minimapIcon.hide = not value; LDBIcon[value and "Show" or "Hide"](LDBIcon, "Bartender4") end,
disabled = function() return not LDBIcon end,
},
kb = {
order = 4,
type = "execute",
name = L["Key Bindings"],
desc = L["Switch to key-binding mode"],
func = function()
KB:Toggle()
AceConfigDialog:Close("Bartender4")
end,
},
bars = {
order = 20,
type = "group",
name = L["Bars"],
args = {
options = {
type = "group",
order = 0,
name = function(info) if info.uiType == "dialog" then return "" else return L["Bar Options"] end end,
guiInline = true,
args = {
blizzardVehicle = {
order = 1,
type = "toggle",
name = L["Use Blizzard Vehicle UI"],
desc = L["Enable the use of the Blizzard Vehicle UI, hiding any Bartender4 bars in the meantime."],
width = "full",
get = getFunc,
set = function(info, value)
if UnitHasVehicleUI("player") then
Bartender4:Print(L["You have to exit the vehicle in order to be able to change the Vehicle UI settings."])
return
end
Bartender4.db.profile.blizzardVehicle = value
Bartender4:UpdateBlizzardVehicle()
end,
},
selfcastmodifier = {
order = 10,
type = "toggle",
name = L["Self-Cast by modifier"],
desc = L["Toggle the use of the modifier-based self-cast functionality."],
get = getFunc,
set = function(info, value)
Bartender4.db.profile.selfcastmodifier = value
Bartender4.Bar:ForAll("UpdateSelfCast")
end,
},
setselfcastmod = {
order = 20,
type = "select",
name = L["Self-Cast Modifier"],
desc = L["Select the Self-Cast Modifier"],
get = function(info) return GetModifiedClick("SELFCAST") end,
set = function(info, value) SetModifiedClick("SELFCAST", value); SaveBindings(GetCurrentBindingSet() or 1) end,
values = { NONE = L["None"], ALT = L["ALT"], SHIFT = L["SHIFT"], CTRL = L["CTRL"] },
},
selfcast_nl = {
order = 30,
type = "description",
name = "",
},
focuscastmodifier = {
order = 50,
type = "toggle",
name = L["Focus-Cast by modifier"],
desc = L["Toggle the use of the modifier-based focus-cast functionality."],
get = getFunc,
set = function(info, value)
Bartender4.db.profile.focuscastmodifier = value
Bartender4.Bar:ForAll("UpdateSelfCast")
end,
},
setfocuscastmod = {
order = 60,
type = "select",
name = L["Focus-Cast Modifier"],
desc = L["Select the Focus-Cast Modifier"],
get = function(info) return GetModifiedClick("FOCUSCAST") end,
set = function(info, value) SetModifiedClick("FOCUSCAST", value); SaveBindings(GetCurrentBindingSet() or 1) end,
values = { NONE = L["None"], ALT = L["ALT"], SHIFT = L["SHIFT"], CTRL = L["CTRL"] },
},
focuscast_nl = {
order = 70,
type = "description",
name = "",
},
selfcastrightclick = {
order = 80,
type = "toggle",
name = L["Right-click Self-Cast"],
desc = L["Toggle the use of the right-click self-cast functionality."],
get = getFunc,
set = function(info, value)
Bartender4.db.profile.selfcastrightclick = value
Bartender4.Bar:ForAll("UpdateSelfCast")
end,
},
rightclickselfcast_nl = {
order = 90,
type = "description",
name = "",
},
range = {
order = 100,
name = L["Out of Range Indicator"],
desc = L["Configure how the Out of Range Indicator should display on the buttons."],
type = "select",
style = "dropdown",
get = function()
return Bartender4.db.profile.outofrange
end,
set = function(info, value)
Bartender4.db.profile.outofrange = value
Bartender4.Bar:ForAll("ApplyConfig")
end,
values = { none = L["No Display"], button = L["Full Button Mode"], hotkey = L["Hotkey Mode"] },
},
colors = {
order = 130,
type = "group",
guiInline = true,
name = L["Colors"],
get = function(info)
local color = Bartender4.db.profile.colors[info[#info]]
return color.r, color.g, color.b
end,
set = function(info, r, g, b)
local color = Bartender4.db.profile.colors[info[#info]]
color.r, color.g, color.b = r, g, b
Bartender4.Bar:ForAll("ApplyConfig")
end,
args = {
range = {
order = 1,
type = "color",
name = L["Out of Range Indicator"],
desc = L["Specify the Color of the Out of Range Indicator"],
},
mana = {
order = 2,
type = "color",
name = L["Out of Mana Indicator"],
desc = L["Specify the Color of the Out of Mana Indicator"],
},
},
},
tooltip = {
order = 200,
name = L["Button Tooltip"],
type = "select",
desc = L["Configure the Button Tooltip."],
values = { ["disabled"] = L["Disabled"], ["nocombat"] = L["Disabled in Combat"], ["enabled"] = L["Enabled"] },
get = function() return Bartender4.db.profile.tooltip end,
set = function(info, value) Bartender4.db.profile.tooltip = value end,
},
},
},
},
},
faq = {
name = L["FAQ"],
desc = L["Frequently Asked Questions"],
type = "group",
order = 200,
args = {
faq = {
type = "description",
name = L["FAQ_TEXT"],
},
},
},
},
}
Bartender4.options.plugins.profiles = { profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(Bartender4.db) }
for k,v in Bartender4:IterateModules() do
if v.SetupOptions then
v:SetupOptions()
end
end
end
return Bartender4.options
end
function Bartender4:ChatCommand(input)
if InCombatLockdown() then
self:Print(L["Cannot access options during combat."])
return
end
if not input or input:trim() == "" then
LibStub("AceConfigDialog-3.0"):Open("Bartender4")
else
LibStub("AceConfigCmd-3.0").HandleCommand(Bartender4, "bt", "Bartender4", input)
end
end
function Bartender4:SetupOptions()
LibStub("AceConfig-3.0"):RegisterOptionsTable("Bartender4", getOptions)
AceConfigDialog:SetDefaultSize("Bartender4", 680,525)
self:RegisterChatCommand( "bar", "ChatCommand")
self:RegisterChatCommand( "bt", "ChatCommand")
self:RegisterChatCommand( "bt4", "ChatCommand")
self:RegisterChatCommand( "bartender", "ChatCommand")
self:RegisterChatCommand( "bartender4", "ChatCommand")
end
function Bartender4:RegisterModuleOptions(key, table)
if not self.options then
error("Options table has not been created yet, respond to the callback!", 2)
end
self.options.plugins[key] = { [key] = table }
end
function Bartender4:RegisterBarOptions(id, table)
if not self.options then
error("Options table has not been created yet, respond to the callback!", 2)
end
self.options.args.bars.args[id] = table
end
local optionParent = {}
function optionParent:NewCategory(category, data)
self.table[category] = data
end
local ov = nil
function optionParent:AddElement(category, element, data, ...)
local lvl = self.table[category]
for i = 1, select('#', ...) do
local key = select(i, ...)
if not (lvl.args[key] and lvl.args[key].args) then
error(("Sub-Level Key %s does not exist in options group or is no sub-group."):format(key), ov and 3 or 2)
end
lvl = lvl.args[key]
end
lvl.args[element] = data
end
function optionParent:AddElementGroup(category, data, ...)
ov = true
for k,v in pairs(data) do
self:AddElement(category, k, v, ...)
end
ov = nil
end
function Bartender4:NewOptionObject(otbl)
if not otbl then otbl = {} end
local tbl = { table = otbl }
for k, v in pairs(optionParent) do
tbl[k] = v
end
return tbl
end
+19 -19
View File
@@ -1,19 +1,19 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceGUIWidget-NumberEditBox.lua"/>
<Script file="Options.lua"/>
<Script file="Bar.lua"/>
<Script file="ButtonBar.lua"/>
<Script file="StateBar.lua"/>
<Script file="ActionBar.lua"/>
<Script file="BagBar.lua"/>
<Script file="MicroMenu.lua"/>
<Script file="PetBar.lua"/>
<Script file="StanceBar.lua"/>
<Script file="RepXPBar.lua"/>
<Script file="VehicleBar.lua"/>
<Script file="MultiCastBar.lua"/>
</Ui>
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceGUIWidget-NumberEditBox.lua"/>
<Script file="Options.lua"/>
<Script file="Bar.lua"/>
<Script file="ButtonBar.lua"/>
<Script file="StateBar.lua"/>
<Script file="ActionBar.lua"/>
<Script file="BagBar.lua"/>
<Script file="MicroMenu.lua"/>
<Script file="PetBar.lua"/>
<Script file="StanceBar.lua"/>
<Script file="RepXPBar.lua"/>
<Script file="VehicleBar.lua"/>
<Script file="MultiCastBar.lua"/>
</Ui>
+51 -51
View File
@@ -1,51 +1,51 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local PetBarMod = Bartender4:GetModule("PetBar")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function PetBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = 10
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the PetBar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Pet Bar"],
desc = L["Configure the Pet Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("PetBar", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local PetBarMod = Bartender4:GetModule("PetBar")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function PetBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = 10
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the PetBar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Pet Bar"],
desc = L["Configure the Pet Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("PetBar", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
+85 -85
View File
@@ -1,85 +1,85 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
-- fetch upvalues
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local RepBarMod = Bartender4:GetModule("RepBar")
function RepBarMod:SetupOptions()
if not self.options then
self.optionobject = Bar:GetOptionObject()
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Reputation Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 100,
type = "group",
name = L["Reputation Bar"],
desc = L["Configure the Reputation Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("Rep", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
local XPBarMod = Bartender4:GetModule("XPBar")
function XPBarMod:SetupOptions()
if not self.options then
self.optionobject = Bar:GetOptionObject()
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the XP Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 101,
type = "group",
name = L["XP Bar"],
desc = L["Configure the XP Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("XP", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
-- fetch upvalues
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local RepBarMod = Bartender4:GetModule("RepBar")
function RepBarMod:SetupOptions()
if not self.options then
self.optionobject = Bar:GetOptionObject()
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Reputation Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 100,
type = "group",
name = L["Reputation Bar"],
desc = L["Configure the Reputation Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("Rep", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
local XPBarMod = Bartender4:GetModule("XPBar")
function XPBarMod:SetupOptions()
if not self.options then
self.optionobject = Bar:GetOptionObject()
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the XP Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 101,
type = "group",
name = L["XP Bar"],
desc = L["Configure the XP Bar"],
childGroups = "tab",
}
Bartender4:RegisterBarOptions("XP", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
+51 -51
View File
@@ -1,51 +1,51 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- module
local StanceBarMod = Bartender4:GetModule("StanceBar")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function StanceBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the StanceBar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Stance Bar"],
desc = L["Configure the Stance Bar"],
childGroups = "tab",
disabled = function(info) return GetNumShapeshiftForms() == 0 end,
}
Bartender4:RegisterBarOptions("StanceBar", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- module
local StanceBarMod = Bartender4:GetModule("StanceBar")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function StanceBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the StanceBar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["Stance Bar"],
desc = L["Configure the Stance Bar"],
childGroups = "tab",
disabled = function(info) return GetNumShapeshiftForms() == 0 end,
}
Bartender4:RegisterBarOptions("StanceBar", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
+286 -286
View File
@@ -1,286 +1,286 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local ButtonBar = Bartender4.ButtonBar.prototype
local StateBar = Bartender4.StateBar.prototype
local optGetter, optSetter, getBar
do
local optionMap, callFunc
local barregistry = Bartender4.Bar.barregistry
optionMap = {
stance = "StanceStateOption",
enabled = "StateOption",
def_state = "DefaultState",
states = "StateOption",
actionbar = "StateOption",
possess = "StateOption",
autoassist = "ConfigAutoAssist",
customEnabled = "StateOption",
custom = "StateOption",
customCopy = "CopyCustomConditionals",
}
-- retrieves a valid bar object from the barregistry table
function getBar(id)
local bar = barregistry[tostring(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info.arg or info[#info]
return callFunc(bar, "Get", option, info[#info])
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info.arg or info[#info]
return callFunc(bar, "Set", option, info[#info], ...)
end
end
local hasStances
local validStanceTable = {
[0] = L["Don't Page"],
(L["Page %2d"]):format(1),
(L["Page %2d"]):format(2),
(L["Page %2d"]):format(3),
(L["Page %2d"]):format(4),
(L["Page %2d"]):format(5),
(L["Page %2d"]):format(6),
(L["Page %2d"]):format(7),
(L["Page %2d"]):format(8),
(L["Page %2d"]):format(9),
(L["Page %2d"]):format(10)
}
local _, playerclass = UnitClass("player")
local function createOptionGroup(k, id)
local tbl = {
order = 10 * k,
type = "select",
arg = "stance",
values = validStanceTable,
name = Bartender4.StanceMap[playerclass][k].name,
}
return tbl
end
local disabledFunc = function(info)
local bar = getBar(info[2])
return not bar:GetStateOption("enabled")
end
local stateOffOrCustomOn = function(info)
local bar = getBar(info[2])
return (not bar:GetStateOption("enabled")) or (bar:GetStateOption("customEnabled"))
end
local stateOffOrCustomOff = function(info)
local bar = getBar(info[2])
return (not bar:GetStateOption("enabled")) or (not bar:GetStateOption("customEnabled"))
end
function StateBar:GetOptionObject()
local obj = ButtonBar.GetOptionObject()
local options = {
enabled = {
order = 1,
type = "toggle",
name = L["Enabled"],
desc = L["Enable State-based Button Swaping"],
get = optGetter,
set = optSetter,
},
sep1 = {
order = 2,
type = "description",
name = "",
},
autoassist = {
order = 3,
type = "toggle",
name = L["Auto-Assist"],
desc = L["Enable Auto-Assist for this bar.\n Auto-Assist will automatically try to cast on your target's target if your target is no valid target for the selected spell."],
get = optGetter,
set = optSetter,
width = "full",
},
possess = {
order = 5,
type = "toggle",
name = L["Possess Bar"],
desc = L["Switch this bar to the Possess Bar when possessing a npc (eg. Mind Control)"],
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
},
actionbar = {
order = 6,
type = "toggle",
name = L["ActionBar Paging"],
desc = L["Enable Bar Switching based on the actionbar controls provided by the game. \nSee Blizzard Key Bindings for assignments - Usually Shift-Mouse Wheel and Shift+1 - Shift+6."],
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
},
def_desc = {
order = 10,
type = "description",
name = L["The default behaviour of this bar when no state-based paging option affects it."],
},
def_state = {
order = 11,
type = "select",
name = L["Default Bar State"],
values = validStanceTable,
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
},
modifiers = {
order = 30,
type = "group",
inline = true,
name = "",
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
args = {
header = {
order = 1,
type = "header",
name = L["Modifier Based Switching"],
},
ctrl = {
order = 10,
type = "select",
name = L["CTRL"],
arg = "states",
values = validStanceTable,
desc = (L["Configure actionbar paging when the %s key is down."]):format(L["CTRL"]),
--width = "half",
},
alt = {
order = 15,
type = "select",
name = L["ALT"],
arg = "states",
values = validStanceTable,
desc = (L["Configure actionbar paging when the %s key is down."]):format(L["ALT"]),
--width = "half",
},
shift = {
order = 20,
type = "select",
name = L["SHIFT"],
arg = "states",
values = validStanceTable,
desc = (L["Configure actionbar paging when the %s key is down."]):format(L["SHIFT"]),
--width = "half",
},
},
},
stances = {
order = 20,
type = "group",
inline = true,
name = "",
hidden = function() return not (Bartender4.StanceMap[playerclass]) end,
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
args = {
stance_header = {
order = 1,
type = "header",
name = L["Stance Configuration"],
},
},
},
customNl = {
order = 48,
type = "description",
name = "\n",
},
customHeader = {
order = 49,
type = "header",
name = L["Custom Conditionals"],
},
customEnabled = {
order = 50,
type = "toggle",
name = L["Use Custom Condition"],
desc = L["Enable the use of a custom condition, disabling all of the above."],
get = optGetter,
set = optSetter,
disabled = disabledFunc,
--width = "double",
},
customCopy = {
order = 51,
type = "execute",
name = L["Copy Conditionals"],
desc = L["Create a copy of the auto-generated conditionals in the custom configuration as a base template."],
func = optSetter,
disabled = disabledFunc,
},
customDesc = {
order = 52,
type = "description",
name = L["Note: Enabling Custom Conditionals will disable all of the above settings!"],
},
custom = {
order = 55,
type = "input",
name = L["Custom Conditionals"],
desc = L["You can use any macro conditionals in the custom string, using the number of the bar as target value.\nExample: [form:1]9;0"],
width = "full",
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOff,
multiline = true,
},
}
do
local defstancemap = Bartender4.StanceMap[playerclass]
if defstancemap then
for k,v in pairs(defstancemap) do
if not options.stances.args[v.id] then
options.stances.args[v.id] = createOptionGroup(k, v.id)
end
end
end
end
local states = {
type = "group",
name = L["State Configuration"],
order = 5,
args = options,
}
obj:NewCategory("state", states)
return obj
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local Bar = Bartender4.Bar.prototype
local ButtonBar = Bartender4.ButtonBar.prototype
local StateBar = Bartender4.StateBar.prototype
local optGetter, optSetter, getBar
do
local optionMap, callFunc
local barregistry = Bartender4.Bar.barregistry
optionMap = {
stance = "StanceStateOption",
enabled = "StateOption",
def_state = "DefaultState",
states = "StateOption",
actionbar = "StateOption",
possess = "StateOption",
autoassist = "ConfigAutoAssist",
customEnabled = "StateOption",
custom = "StateOption",
customCopy = "CopyCustomConditionals",
}
-- retrieves a valid bar object from the barregistry table
function getBar(id)
local bar = barregistry[tostring(id)]
assert(bar, ("Invalid bar id in options table. (%s)"):format(id))
return bar
end
-- calls a function on the bar
function callFunc(bar, type, option, ...)
local func = type .. (optionMap[option] or option)
assert(bar[func], ("Invalid get/set function %s in bar %s."):format(func, bar.id))
return bar[func](bar, ...)
end
-- universal function to get a option
function optGetter(info)
local bar = getBar(info[2])
local option = info.arg or info[#info]
return callFunc(bar, "Get", option, info[#info])
end
-- universal function to set a option
function optSetter(info, ...)
local bar = getBar(info[2])
local option = info.arg or info[#info]
return callFunc(bar, "Set", option, info[#info], ...)
end
end
local hasStances
local validStanceTable = {
[0] = L["Don't Page"],
(L["Page %2d"]):format(1),
(L["Page %2d"]):format(2),
(L["Page %2d"]):format(3),
(L["Page %2d"]):format(4),
(L["Page %2d"]):format(5),
(L["Page %2d"]):format(6),
(L["Page %2d"]):format(7),
(L["Page %2d"]):format(8),
(L["Page %2d"]):format(9),
(L["Page %2d"]):format(10)
}
local _, playerclass = UnitClass("player")
local function createOptionGroup(k, id)
local tbl = {
order = 10 * k,
type = "select",
arg = "stance",
values = validStanceTable,
name = Bartender4.StanceMap[playerclass][k].name,
}
return tbl
end
local disabledFunc = function(info)
local bar = getBar(info[2])
return not bar:GetStateOption("enabled")
end
local stateOffOrCustomOn = function(info)
local bar = getBar(info[2])
return (not bar:GetStateOption("enabled")) or (bar:GetStateOption("customEnabled"))
end
local stateOffOrCustomOff = function(info)
local bar = getBar(info[2])
return (not bar:GetStateOption("enabled")) or (not bar:GetStateOption("customEnabled"))
end
function StateBar:GetOptionObject()
local obj = ButtonBar.GetOptionObject()
local options = {
enabled = {
order = 1,
type = "toggle",
name = L["Enabled"],
desc = L["Enable State-based Button Swaping"],
get = optGetter,
set = optSetter,
},
sep1 = {
order = 2,
type = "description",
name = "",
},
autoassist = {
order = 3,
type = "toggle",
name = L["Auto-Assist"],
desc = L["Enable Auto-Assist for this bar.\n Auto-Assist will automatically try to cast on your target's target if your target is no valid target for the selected spell."],
get = optGetter,
set = optSetter,
width = "full",
},
possess = {
order = 5,
type = "toggle",
name = L["Possess Bar"],
desc = L["Switch this bar to the Possess Bar when possessing a npc (eg. Mind Control)"],
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
},
actionbar = {
order = 6,
type = "toggle",
name = L["ActionBar Paging"],
desc = L["Enable Bar Switching based on the actionbar controls provided by the game. \nSee Blizzard Key Bindings for assignments - Usually Shift-Mouse Wheel and Shift+1 - Shift+6."],
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
},
def_desc = {
order = 10,
type = "description",
name = L["The default behaviour of this bar when no state-based paging option affects it."],
},
def_state = {
order = 11,
type = "select",
name = L["Default Bar State"],
values = validStanceTable,
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
},
modifiers = {
order = 30,
type = "group",
inline = true,
name = "",
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
args = {
header = {
order = 1,
type = "header",
name = L["Modifier Based Switching"],
},
ctrl = {
order = 10,
type = "select",
name = L["CTRL"],
arg = "states",
values = validStanceTable,
desc = (L["Configure actionbar paging when the %s key is down."]):format(L["CTRL"]),
--width = "half",
},
alt = {
order = 15,
type = "select",
name = L["ALT"],
arg = "states",
values = validStanceTable,
desc = (L["Configure actionbar paging when the %s key is down."]):format(L["ALT"]),
--width = "half",
},
shift = {
order = 20,
type = "select",
name = L["SHIFT"],
arg = "states",
values = validStanceTable,
desc = (L["Configure actionbar paging when the %s key is down."]):format(L["SHIFT"]),
--width = "half",
},
},
},
stances = {
order = 20,
type = "group",
inline = true,
name = "",
hidden = function() return not (Bartender4.StanceMap[playerclass]) end,
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOn,
args = {
stance_header = {
order = 1,
type = "header",
name = L["Stance Configuration"],
},
},
},
customNl = {
order = 48,
type = "description",
name = "\n",
},
customHeader = {
order = 49,
type = "header",
name = L["Custom Conditionals"],
},
customEnabled = {
order = 50,
type = "toggle",
name = L["Use Custom Condition"],
desc = L["Enable the use of a custom condition, disabling all of the above."],
get = optGetter,
set = optSetter,
disabled = disabledFunc,
--width = "double",
},
customCopy = {
order = 51,
type = "execute",
name = L["Copy Conditionals"],
desc = L["Create a copy of the auto-generated conditionals in the custom configuration as a base template."],
func = optSetter,
disabled = disabledFunc,
},
customDesc = {
order = 52,
type = "description",
name = L["Note: Enabling Custom Conditionals will disable all of the above settings!"],
},
custom = {
order = 55,
type = "input",
name = L["Custom Conditionals"],
desc = L["You can use any macro conditionals in the custom string, using the number of the bar as target value.\nExample: [form:1]9;0"],
width = "full",
get = optGetter,
set = optSetter,
disabled = stateOffOrCustomOff,
multiline = true,
},
}
do
local defstancemap = Bartender4.StanceMap[playerclass]
if defstancemap then
for k,v in pairs(defstancemap) do
if not options.stances.args[v.id] then
options.stances.args[v.id] = createOptionGroup(k, v.id)
end
end
end
end
local states = {
type = "group",
name = L["State Configuration"],
order = 5,
args = options,
}
obj:NewCategory("state", states)
return obj
end
+49 -49
View File
@@ -1,49 +1,49 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local VehicleBarMod = Bartender4:GetModule("Vehicle")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function VehicleBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Vehicle Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["VehicleBar"],
desc = L["Configure the VehicleBar"],
childGroups = "tab",
}
self.optionobject.table.general.args.padding.min = -30
Bartender4:RegisterBarOptions("Vehicle", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
local VehicleBarMod = Bartender4:GetModule("Vehicle")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
function VehicleBarMod:SetupOptions()
if not self.options then
self.optionobject = ButtonBar:GetOptionObject()
self.optionobject.table.general.args.rows.max = self.button_count
local enabled = {
type = "toggle",
order = 1,
name = L["Enabled"],
desc = L["Enable the Vehicle Bar"],
get = function() return self.db.profile.enabled end,
set = "ToggleModule",
handler = self,
}
self.optionobject:AddElement("general", "enabled", enabled)
self.disabledoptions = {
general = {
type = "group",
name = L["General Settings"],
cmdInline = true,
order = 1,
args = {
enabled = enabled,
}
}
}
self.options = {
order = 30,
type = "group",
name = L["VehicleBar"],
desc = L["Configure the VehicleBar"],
childGroups = "tab",
}
self.optionobject.table.general.args.padding.min = -30
Bartender4:RegisterBarOptions("Vehicle", self.options)
end
self.options.args = self:IsEnabled() and self.optionobject.table or self.disabledoptions
end
+110 -110
View File
@@ -1,110 +1,110 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local PetBarMod = Bartender4:NewModule("PetBar", "AceEvent-3.0")
-- fetch upvalues
local ActionBars = Bartender4:GetModule("ActionBars")
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local PetBar = setmetatable({}, {__index = ButtonBar})
local defaults = { profile = Bartender4:Merge({
enabled = true,
hidehotkey = true,
visibility = {
nopet = true,
vehicle = true,
},
}, Bartender4.ButtonBar.defaults) }
function PetBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("PetBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function PetBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("PetBar", self.db.profile, L["Pet Bar"]), {__index = PetBar})
local buttons = {}
for i=1,10 do
buttons[i] = Bartender4.PetButton:Create(i, self.bar)
end
self.bar.buttons = buttons
self.bar:SetScript("OnEvent", PetBar.OnEvent)
end
self.bar:Enable()
self.bar:RegisterEvent("PLAYER_CONTROL_LOST")
self.bar:RegisterEvent("PLAYER_CONTROL_GAINED")
self.bar:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED")
self.bar:RegisterEvent("UNIT_PET")
self.bar:RegisterEvent("UNIT_FLAGS")
self.bar:RegisterEvent("UNIT_AURA")
self.bar:RegisterEvent("PET_BAR_UPDATE")
self.bar:RegisterEvent("PET_BAR_UPDATE_COOLDOWN")
self.bar:RegisterEvent("PET_BAR_SHOWGRID")
self.bar:RegisterEvent("PET_BAR_HIDEGRID")
self:ApplyConfig()
self:ToggleOptions()
self:RegisterEvent("UPDATE_BINDINGS", "ReassignBindings")
self:ReassignBindings()
end
function PetBarMod:ReassignBindings()
if InCombatLockdown() then return end
if not self.bar or not self.bar.buttons then return end
ClearOverrideBindings(self.bar)
for i = 1, 10 do
local button, real_button = ("BONUSACTIONBUTTON%d"):format(i), ("BT4PetButton%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
SetOverrideBindingClick(self.bar, false, key, real_button)
end
end
end
function PetBarMod:ApplyConfig()
if not self:IsEnabled() then return end
self.bar:ApplyConfig(self.db.profile)
self:ReassignBindings()
end
PetBar.button_width = 30
PetBar.button_height = 30
function PetBar:OnEvent(event, arg1)
if event == "PET_BAR_UPDATE" or
(event == "UNIT_PET" and arg1 == "player") or
((event == "UNIT_FLAGS" or event == "UNIT_AURA") and arg1 == "pet") or
event == "PLAYER_CONTROL_LOST" or event == "PLAYER_CONTROL_GAINED" or event == "PLAYER_FARSIGHT_FOCUS_CHANGED"
then
self:ForAll("Update")
elseif event == "PET_BAR_UPDATE_COOLDOWN" then
self:ForAll("UpdateCooldown")
elseif event == "PET_BAR_SHOWGRID" then
self:ForAll("ShowGrid")
elseif event == "PET_BAR_HIDEGRID" then
self:ForAll("HideGrid")
end
end
function PetBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", 0, 70)
self:SavePosition()
end
self:UpdateButtonLayout()
self:ForAll("Update")
self:ForAll("ApplyStyle", self.config.style)
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local PetBarMod = Bartender4:NewModule("PetBar", "AceEvent-3.0")
-- fetch upvalues
local ActionBars = Bartender4:GetModule("ActionBars")
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local PetBar = setmetatable({}, {__index = ButtonBar})
local defaults = { profile = Bartender4:Merge({
enabled = true,
hidehotkey = true,
visibility = {
nopet = true,
vehicle = true,
},
}, Bartender4.ButtonBar.defaults) }
function PetBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("PetBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function PetBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("PetBar", self.db.profile, L["Pet Bar"]), {__index = PetBar})
local buttons = {}
for i=1,10 do
buttons[i] = Bartender4.PetButton:Create(i, self.bar)
end
self.bar.buttons = buttons
self.bar:SetScript("OnEvent", PetBar.OnEvent)
end
self.bar:Enable()
self.bar:RegisterEvent("PLAYER_CONTROL_LOST")
self.bar:RegisterEvent("PLAYER_CONTROL_GAINED")
self.bar:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED")
self.bar:RegisterEvent("UNIT_PET")
self.bar:RegisterEvent("UNIT_FLAGS")
self.bar:RegisterEvent("UNIT_AURA")
self.bar:RegisterEvent("PET_BAR_UPDATE")
self.bar:RegisterEvent("PET_BAR_UPDATE_COOLDOWN")
self.bar:RegisterEvent("PET_BAR_SHOWGRID")
self.bar:RegisterEvent("PET_BAR_HIDEGRID")
self:ApplyConfig()
self:ToggleOptions()
self:RegisterEvent("UPDATE_BINDINGS", "ReassignBindings")
self:ReassignBindings()
end
function PetBarMod:ReassignBindings()
if InCombatLockdown() then return end
if not self.bar or not self.bar.buttons then return end
ClearOverrideBindings(self.bar)
for i = 1, 10 do
local button, real_button = ("BONUSACTIONBUTTON%d"):format(i), ("BT4PetButton%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
SetOverrideBindingClick(self.bar, false, key, real_button)
end
end
end
function PetBarMod:ApplyConfig()
if not self:IsEnabled() then return end
self.bar:ApplyConfig(self.db.profile)
self:ReassignBindings()
end
PetBar.button_width = 30
PetBar.button_height = 30
function PetBar:OnEvent(event, arg1)
if event == "PET_BAR_UPDATE" or
(event == "UNIT_PET" and arg1 == "player") or
((event == "UNIT_FLAGS" or event == "UNIT_AURA") and arg1 == "pet") or
event == "PLAYER_CONTROL_LOST" or event == "PLAYER_CONTROL_GAINED" or event == "PLAYER_FARSIGHT_FOCUS_CHANGED"
then
self:ForAll("Update")
elseif event == "PET_BAR_UPDATE_COOLDOWN" then
self:ForAll("UpdateCooldown")
elseif event == "PET_BAR_SHOWGRID" then
self:ForAll("ShowGrid")
elseif event == "PET_BAR_HIDEGRID" then
self:ForAll("HideGrid")
end
end
function PetBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", 0, 70)
self:SavePosition()
end
self:UpdateButtonLayout()
self:ForAll("Update")
self:ForAll("ApplyStyle", self.config.style)
end
+266 -266
View File
@@ -1,266 +1,266 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
--[[
Pet Button template
]]
local PetButtonPrototype = CreateFrame("CheckButton")
local PetButton_MT = {__index = PetButtonPrototype}
local LBF = LibStub("LibButtonFacade", true)
local KeyBound = LibStub("LibKeyBound-1.0")
-- upvalues
local _G = _G
local format = string.format
local function onEnter(self, ...)
if not (Bartender4.db.profile.tooltip == "nocombat" and InCombatLockdown()) and Bartender4.db.profile.tooltip ~= "disabled" then
self:OnEnter(...)
end
KeyBound:Set(self)
end
local function onDragStart(self)
if InCombatLockdown() then return end
if not Bartender4.db.profile.buttonlock or IsModifiedClick("PICKUPACTION") then
self:SetChecked(0)
PickupPetAction(self.id)
self:Update()
end
end
local function onReceiveDrag(self)
if InCombatLockdown() then return end
self:SetChecked(0)
PickupPetAction(self.id)
self:Update()
end
Bartender4.PetButton = {}
Bartender4.PetButton.prototype = PetButtonPrototype
function Bartender4.PetButton:Create(id, parent)
local name = "BT4PetButton" .. id
local button = setmetatable(CreateFrame("CheckButton", name, parent, "PetActionButtonTemplate"), PetButton_MT)
button.showgrid = 0
button.id = id
button.parent = parent
button:SetFrameStrata("MEDIUM")
button:SetID(id)
button:UnregisterAllEvents()
button:SetScript("OnEvent", nil)
button.OnEnter = button:GetScript("OnEnter")
button:SetScript("OnEnter", onEnter)
button:SetScript("OnDragStart", onDragStart)
button:SetScript("OnReceiveDrag", onReceiveDrag)
button.flash = _G[name .. "Flash"]
button.cooldown = _G[name .. "Cooldown"]
button.icon = _G[name .. "Icon"]
button.autocastable = _G[name .. "AutoCastable"]
button.autocast = _G[name .. "Shine"]
button.hotkey = _G[name .. "HotKey"]
button:SetNormalTexture("")
local oldNT = button:GetNormalTexture()
oldNT:Hide()
button.normalTexture = button:CreateTexture(("%sBTNT"):format(name))
button.normalTexture:SetAllPoints(oldNT)
button.pushedTexture = button:GetPushedTexture()
button.highlightTexture = button:GetHighlightTexture()
button.textureCache = {}
button.textureCache.pushed = button.pushedTexture:GetTexture()
button.textureCache.highlight = button.highlightTexture:GetTexture()
if LBF then
local group = parent.LBFGroup
button.LBFButtonData = {
Button = button,
Normal = button.normalTexture,
}
group:AddButton(button, button.LBFButtonData)
end
return button
end
function PetButtonPrototype:Update()
local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(self.id)
if not isToken then
self.icon:SetTexture(texture)
self.tooltipName = name;
else
self.icon:SetTexture(_G[texture])
self.tooltipName = _G[name]
end
self.isToken = isToken
self.tooltipSubtext = subtext
self:SetChecked(isActive and 1 or 0)
if autoCastAllowed and not autoCastEnabled then
self.autocastable:Show()
AutoCastShine_AutoCastStop(self.autocast)
elseif autoCastAllowed then
self.autocastable:Hide()
AutoCastShine_AutoCastStart(self.autocast)
else
self.autocastable:Hide()
AutoCastShine_AutoCastStop(self.autocast)
end
if texture then
if GetPetActionsUsable() then
SetDesaturation(self.icon, nil)
else
SetDesaturation(self.icon, 1)
end
self.icon:Show()
self.normalTexture:SetTexture("Interface\\Buttons\\UI-Quickslot2")
self.normalTexture:SetTexCoord(0, 0, 0, 0)
self:ShowButton()
self.normalTexture:Show()
if self.overlay then
self.overlay:Show()
end
else
self.icon:Hide()
self.normalTexture:SetTexture("Interface\\Buttons\\UI-Quickslot")
self.normalTexture:SetTexCoord(-0.1, 1.1, -0.1, 1.12)
self:HideButton()
if self.showgrid == 0 and not self.parent.config.showgrid then
self.normalTexture:Hide()
if self.overlay then
self.overlay:Hide()
end
end
end
self:UpdateCooldown()
self:UpdateHotkeys()
end
function PetButtonPrototype:UpdateHotkeys()
local key = self:GetHotkey() or ""
local hotkey = self.hotkey
if key == "" or self.parent.config.hidehotkey then
hotkey:Hide()
else
hotkey:SetText(key)
hotkey:Show()
end
end
function PetButtonPrototype:ShowButton()
self.pushedTexture:SetTexture(self.textureCache.pushed)
self.highlightTexture:SetTexture(self.textureCache.highlight)
if LBF then
local backdrop, gloss = LBF:GetBackdropLayer(self), LBF:GetGlossLayer(self)
if backdrop then
backdrop:Show()
end
if gloss then
gloss:Show()
end
end
end
function PetButtonPrototype:HideButton()
self.textureCache.pushed = self.pushedTexture:GetTexture()
self.textureCache.highlight = self.highlightTexture:GetTexture()
self.pushedTexture:SetTexture("")
self.highlightTexture:SetTexture("")
if LBF then
local backdrop, gloss = LBF:GetBackdropLayer(self), LBF:GetGlossLayer(self)
if backdrop then
backdrop:Hide()
end
if gloss then
gloss:Hide()
end
end
end
function PetButtonPrototype:ShowGrid()
self.showgrid = self.showgrid + 1
self.normalTexture:Show()
end
function PetButtonPrototype:HideGrid()
if self.showgrid > 0 then self.showgrid = self.showgrid - 1 end
if self.showgrid == 0 and not (GetPetActionInfo(self.id)) and not self.parent.config.showgrid then
self.normalTexture:Hide()
end
end
function PetButtonPrototype:UpdateCooldown()
local start, duration, enable = GetPetActionCooldown(self.id)
CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
end
function PetButtonPrototype:GetHotkey()
local key = GetBindingKey(format("BONUSACTIONBUTTON%d", self.id)) or GetBindingKey("CLICK "..self:GetName()..":LeftButton")
return key and KeyBound:ToShortKey(key)
end
function PetButtonPrototype:GetBindings()
local keys, binding = ""
binding = format("BONUSACTIONBUTTON%d", self.id)
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys .. GetBindingText(hotKey,'KEY_')
end
binding = "CLICK "..self:GetName()..":LeftButton"
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys.. GetBindingText(hotKey,'KEY_')
end
return keys
end
function PetButtonPrototype:SetKey(key)
SetBinding(key, format("BONUSACTIONBUTTON%d", self.id))
end
function PetButtonPrototype:ClearBindings()
local binding = format("BONUSACTIONBUTTON%d", self:GetID())
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
binding = "CLICK "..self:GetName()..":LeftButton"
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
end
local actionTmpl = "Pet Button %d (%s)"
function PetButtonPrototype:GetActionName()
local id = self.id
local name, _, _, token = GetPetActionInfo(id)
if token and name then name = _G[name] end
return format(actionTmpl, id, name or "empty")
end
function PetButtonPrototype:ClearSetPoint(...)
self:ClearAllPoints()
self:SetPoint(...)
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
--[[
Pet Button template
]]
local PetButtonPrototype = CreateFrame("CheckButton")
local PetButton_MT = {__index = PetButtonPrototype}
local LBF = LibStub("LibButtonFacade", true)
local KeyBound = LibStub("LibKeyBound-1.0")
-- upvalues
local _G = _G
local format = string.format
local function onEnter(self, ...)
if not (Bartender4.db.profile.tooltip == "nocombat" and InCombatLockdown()) and Bartender4.db.profile.tooltip ~= "disabled" then
self:OnEnter(...)
end
KeyBound:Set(self)
end
local function onDragStart(self)
if InCombatLockdown() then return end
if not Bartender4.db.profile.buttonlock or IsModifiedClick("PICKUPACTION") then
self:SetChecked(0)
PickupPetAction(self.id)
self:Update()
end
end
local function onReceiveDrag(self)
if InCombatLockdown() then return end
self:SetChecked(0)
PickupPetAction(self.id)
self:Update()
end
Bartender4.PetButton = {}
Bartender4.PetButton.prototype = PetButtonPrototype
function Bartender4.PetButton:Create(id, parent)
local name = "BT4PetButton" .. id
local button = setmetatable(CreateFrame("CheckButton", name, parent, "PetActionButtonTemplate"), PetButton_MT)
button.showgrid = 0
button.id = id
button.parent = parent
button:SetFrameStrata("MEDIUM")
button:SetID(id)
button:UnregisterAllEvents()
button:SetScript("OnEvent", nil)
button.OnEnter = button:GetScript("OnEnter")
button:SetScript("OnEnter", onEnter)
button:SetScript("OnDragStart", onDragStart)
button:SetScript("OnReceiveDrag", onReceiveDrag)
button.flash = _G[name .. "Flash"]
button.cooldown = _G[name .. "Cooldown"]
button.icon = _G[name .. "Icon"]
button.autocastable = _G[name .. "AutoCastable"]
button.autocast = _G[name .. "Shine"]
button.hotkey = _G[name .. "HotKey"]
button:SetNormalTexture("")
local oldNT = button:GetNormalTexture()
oldNT:Hide()
button.normalTexture = button:CreateTexture(("%sBTNT"):format(name))
button.normalTexture:SetAllPoints(oldNT)
button.pushedTexture = button:GetPushedTexture()
button.highlightTexture = button:GetHighlightTexture()
button.textureCache = {}
button.textureCache.pushed = button.pushedTexture:GetTexture()
button.textureCache.highlight = button.highlightTexture:GetTexture()
if LBF then
local group = parent.LBFGroup
button.LBFButtonData = {
Button = button,
Normal = button.normalTexture,
}
group:AddButton(button, button.LBFButtonData)
end
return button
end
function PetButtonPrototype:Update()
local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(self.id)
if not isToken then
self.icon:SetTexture(texture)
self.tooltipName = name;
else
self.icon:SetTexture(_G[texture])
self.tooltipName = _G[name]
end
self.isToken = isToken
self.tooltipSubtext = subtext
self:SetChecked(isActive and 1 or 0)
if autoCastAllowed and not autoCastEnabled then
self.autocastable:Show()
AutoCastShine_AutoCastStop(self.autocast)
elseif autoCastAllowed then
self.autocastable:Hide()
AutoCastShine_AutoCastStart(self.autocast)
else
self.autocastable:Hide()
AutoCastShine_AutoCastStop(self.autocast)
end
if texture then
if GetPetActionsUsable() then
SetDesaturation(self.icon, nil)
else
SetDesaturation(self.icon, 1)
end
self.icon:Show()
self.normalTexture:SetTexture("Interface\\Buttons\\UI-Quickslot2")
self.normalTexture:SetTexCoord(0, 0, 0, 0)
self:ShowButton()
self.normalTexture:Show()
if self.overlay then
self.overlay:Show()
end
else
self.icon:Hide()
self.normalTexture:SetTexture("Interface\\Buttons\\UI-Quickslot")
self.normalTexture:SetTexCoord(-0.1, 1.1, -0.1, 1.12)
self:HideButton()
if self.showgrid == 0 and not self.parent.config.showgrid then
self.normalTexture:Hide()
if self.overlay then
self.overlay:Hide()
end
end
end
self:UpdateCooldown()
self:UpdateHotkeys()
end
function PetButtonPrototype:UpdateHotkeys()
local key = self:GetHotkey() or ""
local hotkey = self.hotkey
if key == "" or self.parent.config.hidehotkey then
hotkey:Hide()
else
hotkey:SetText(key)
hotkey:Show()
end
end
function PetButtonPrototype:ShowButton()
self.pushedTexture:SetTexture(self.textureCache.pushed)
self.highlightTexture:SetTexture(self.textureCache.highlight)
if LBF then
local backdrop, gloss = LBF:GetBackdropLayer(self), LBF:GetGlossLayer(self)
if backdrop then
backdrop:Show()
end
if gloss then
gloss:Show()
end
end
end
function PetButtonPrototype:HideButton()
self.textureCache.pushed = self.pushedTexture:GetTexture()
self.textureCache.highlight = self.highlightTexture:GetTexture()
self.pushedTexture:SetTexture("")
self.highlightTexture:SetTexture("")
if LBF then
local backdrop, gloss = LBF:GetBackdropLayer(self), LBF:GetGlossLayer(self)
if backdrop then
backdrop:Hide()
end
if gloss then
gloss:Hide()
end
end
end
function PetButtonPrototype:ShowGrid()
self.showgrid = self.showgrid + 1
self.normalTexture:Show()
end
function PetButtonPrototype:HideGrid()
if self.showgrid > 0 then self.showgrid = self.showgrid - 1 end
if self.showgrid == 0 and not (GetPetActionInfo(self.id)) and not self.parent.config.showgrid then
self.normalTexture:Hide()
end
end
function PetButtonPrototype:UpdateCooldown()
local start, duration, enable = GetPetActionCooldown(self.id)
CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
end
function PetButtonPrototype:GetHotkey()
local key = GetBindingKey(format("BONUSACTIONBUTTON%d", self.id)) or GetBindingKey("CLICK "..self:GetName()..":LeftButton")
return key and KeyBound:ToShortKey(key)
end
function PetButtonPrototype:GetBindings()
local keys, binding = ""
binding = format("BONUSACTIONBUTTON%d", self.id)
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys .. GetBindingText(hotKey,'KEY_')
end
binding = "CLICK "..self:GetName()..":LeftButton"
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys.. GetBindingText(hotKey,'KEY_')
end
return keys
end
function PetButtonPrototype:SetKey(key)
SetBinding(key, format("BONUSACTIONBUTTON%d", self.id))
end
function PetButtonPrototype:ClearBindings()
local binding = format("BONUSACTIONBUTTON%d", self:GetID())
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
binding = "CLICK "..self:GetName()..":LeftButton"
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
end
local actionTmpl = "Pet Button %d (%s)"
function PetButtonPrototype:GetActionName()
local id = self.id
local name, _, _, token = GetPetActionInfo(id)
if token and name then name = _G[name] end
return format(actionTmpl, id, name or "empty")
end
function PetButtonPrototype:ClearSetPoint(...)
self:ClearAllPoints()
self:SetPoint(...)
end
+96 -96
View File
@@ -1,96 +1,96 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- fetch upvalues
local Bar = Bartender4.Bar.prototype
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = false,
}, Bartender4.Bar.defaults) }
-- register module
local RepBarMod = Bartender4:NewModule("RepBar")
-- create prototype information
local RepBar = setmetatable({}, {__index = Bar})
function RepBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("RepBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function RepBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.Bar:Create("Rep", self.db.profile, L["Reputation Bar"]), {__index = RepBar})
self.bar.content = ReputationWatchBar
hooksecurefunc("ReputationWatchBar_Update", function() self.bar:PerformLayout() end)
self.bar.content:SetParent(self.bar)
self.bar.content:Show()
self.bar.content:SetFrameLevel(self.bar:GetFrameLevel() + 1)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function RepBarMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
function RepBar:ApplyConfig(config)
Bar.ApplyConfig(self, config)
self:PerformLayout()
end
function RepBar:PerformLayout()
self:SetSize(1032, 21)
local bar = self.content
bar:ClearAllPoints()
bar:SetPoint("TOPLEFT", self, "TOPLEFT", 5, -3)
end
RepBar.ClickThroughSupport = true
function RepBar:ControlClickThrough()
self.content:EnableMouse(not self.config.clickthrough)
end
-- register module
local XPBarMod = Bartender4:NewModule("XPBar")
-- create prototype information
local XPBar = setmetatable({}, {__index = Bar})
function XPBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("XPBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function XPBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.Bar:Create("XP", self.db.profile, L["XP Bar"]), {__index = XPBar})
self.bar.content = MainMenuExpBar
self.bar.content:SetParent(self.bar)
self.bar.content:Show()
self.bar.content:SetFrameLevel(self.bar:GetFrameLevel() + 1)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
XPBarMod.ApplyConfig = RepBarMod.ApplyConfig
XPBar.ApplyConfig = RepBar.ApplyConfig
XPBar.PerformLayout = RepBar.PerformLayout
XPBar.ClickThroughSupport = true
XPBar.ControlClickThrough = RepBar.ControlClickThrough
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- fetch upvalues
local Bar = Bartender4.Bar.prototype
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = false,
}, Bartender4.Bar.defaults) }
-- register module
local RepBarMod = Bartender4:NewModule("RepBar")
-- create prototype information
local RepBar = setmetatable({}, {__index = Bar})
function RepBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("RepBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function RepBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.Bar:Create("Rep", self.db.profile, L["Reputation Bar"]), {__index = RepBar})
self.bar.content = ReputationWatchBar
hooksecurefunc("ReputationWatchBar_Update", function() self.bar:PerformLayout() end)
self.bar.content:SetParent(self.bar)
self.bar.content:Show()
self.bar.content:SetFrameLevel(self.bar:GetFrameLevel() + 1)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function RepBarMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
function RepBar:ApplyConfig(config)
Bar.ApplyConfig(self, config)
self:PerformLayout()
end
function RepBar:PerformLayout()
self:SetSize(1032, 21)
local bar = self.content
bar:ClearAllPoints()
bar:SetPoint("TOPLEFT", self, "TOPLEFT", 5, -3)
end
RepBar.ClickThroughSupport = true
function RepBar:ControlClickThrough()
self.content:EnableMouse(not self.config.clickthrough)
end
-- register module
local XPBarMod = Bartender4:NewModule("XPBar")
-- create prototype information
local XPBar = setmetatable({}, {__index = Bar})
function XPBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("XPBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function XPBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.Bar:Create("XP", self.db.profile, L["XP Bar"]), {__index = XPBar})
self.bar.content = MainMenuExpBar
self.bar.content:SetParent(self.bar)
self.bar.content:Show()
self.bar.content:SetFrameLevel(self.bar:GetFrameLevel() + 1)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
XPBarMod.ApplyConfig = RepBarMod.ApplyConfig
XPBar.ApplyConfig = RepBar.ApplyConfig
XPBar.PerformLayout = RepBar.PerformLayout
XPBar.ClickThroughSupport = true
XPBar.ControlClickThrough = RepBar.ControlClickThrough
+269 -269
View File
@@ -1,269 +1,269 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local StanceBarMod = Bartender4:NewModule("StanceBar", "AceEvent-3.0")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local StanceBar = setmetatable({}, {__index = ButtonBar})
local StanceButtonPrototype = CreateFrame("CheckButton")
local StanceButton_MT = {__index = StanceButtonPrototype}
local format = string.format
local LBF = LibStub("LibButtonFacade", true)
local KeyBound = LibStub("LibKeyBound-1.0")
local defaults = { profile = Bartender4:Merge({
enabled = true,
position = {
scale = 1.5,
},
hidehotkey = true,
}, Bartender4.ButtonBar.defaults) }
function StanceBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("StanceBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function StanceBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("StanceBar", self.db.profile, L["Stance Bar"]), {__index = StanceBar})
self.bar:SetScript("OnEvent", StanceBar.OnEvent)
end
self.bar:Enable()
self:ToggleOptions()
self.bar:RegisterEvent("PLAYER_ENTERING_WORLD")
self.bar:RegisterEvent("UPDATE_SHAPESHIFT_FORMS")
self.bar:RegisterEvent("SPELL_UPDATE_COOLDOWN")
self.bar:RegisterEvent("SPELL_UPDATE_USABLE")
self.bar:RegisterEvent("PLAYER_AURAS_CHANGED")
self.bar:RegisterEvent("PLAYER_REGEN_ENABLED")
self.bar:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
self:RegisterEvent("UPDATE_BINDINGS", "ReassignBindings")
self:ReassignBindings()
self:ApplyConfig()
end
StanceBarMod.button_count = 10
function StanceBarMod:ApplyConfig()
if not self:IsEnabled() then return end
self.bar:ApplyConfig(self.db.profile)
if GetNumShapeshiftForms() == 0 then
self:Disable()
end
end
function StanceBarMod:ReassignBindings()
if InCombatLockdown() then return end
if not self.bar or not self.bar.buttons then return end
ClearOverrideBindings(self.bar)
for i = 1, min(#self.bar.buttons, 10) do
local button, real_button = ("SHAPESHIFTBUTTON%d"):format(i), ("BT4StanceButton%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
SetOverrideBindingClick(self.bar, false, key, real_button)
end
end
end
function StanceButtonPrototype:Update()
if not self:IsShown() then return end
local id = self:GetID()
local texture, name, isActive, isCastable = GetShapeshiftFormInfo(id)
self.icon:SetTexture(texture)
-- manage cooldowns
if texture then
self.cooldown:Show()
else
self.cooldown:Hide()
end
local start, duration, enable = GetShapeshiftFormCooldown(id)
CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
if isActive then
self:SetChecked(1)
else
self:SetChecked(0)
end
if isCastable then
self.icon:SetVertexColor(1.0, 1.0, 1.0)
else
self.icon:SetVertexColor(0.4, 0.4, 0.4)
end
self:UpdateHotkeys()
end
function StanceButtonPrototype:UpdateHotkeys()
local key = self:GetHotkey() or ""
local hotkey = self.hotkey
if key == "" or self.parent.config.hidehotkey then
hotkey:Hide()
else
hotkey:SetText(key)
hotkey:Show()
end
end
function StanceButtonPrototype:GetHotkey()
local key = GetBindingKey(format("SHAPESHIFTBUTTON%d", self:GetID())) or GetBindingKey("CLICK "..self:GetName()..":LeftButton")
return key and KeyBound:ToShortKey(key)
end
function StanceButtonPrototype:GetBindings()
local keys, binding = ""
binding = format("SHAPESHIFTBUTTON%d", self:GetID())
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys .. GetBindingText(hotKey,'KEY_')
end
binding = "CLICK "..self:GetName()..":LeftButton"
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys.. GetBindingText(hotKey,'KEY_')
end
return keys
end
function StanceButtonPrototype:SetKey(key)
SetBinding(key, format("SHAPESHIFTBUTTON%d", self:GetID()))
end
function StanceButtonPrototype:ClearBindings()
local binding = format("SHAPESHIFTBUTTON%d", self:GetID())
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
binding = "CLICK "..self:GetName()..":LeftButton"
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
end
local actionTmpl = "Stance Button %d (%s)"
function StanceButtonPrototype:GetActionName()
local id = self:GetID()
return format(actionTmpl, id, select(2, GetShapeshiftFormInfo(id)))
end
function StanceButtonPrototype:ClearSetPoint(...)
self:ClearAllPoints()
self:SetPoint(...)
end
local function onEnter(self, ...)
if not (Bartender4.db.profile.tooltip == "nocombat" and InCombatLockdown()) and Bartender4.db.profile.tooltip ~= "disabled" then
self:OnEnter(...)
end
KeyBound:Set(self)
end
function StanceBarMod:CreateStanceButton(id)
local button = setmetatable(CreateFrame("CheckButton", "BT4StanceButton" .. id, self.bar, "ShapeshiftButtonTemplate"), StanceButton_MT)
button.parent = self.bar
button:SetID(id)
button.icon = _G[button:GetName() .. "Icon"]
button.cooldown = _G[button:GetName() .. "Cooldown"]
button.hotkey = _G[button:GetName() .. "HotKey"]
button.normalTexture = button:GetNormalTexture()
button.normalTexture:SetTexture("")
-- button.checkedTexture = button:GetCheckedTexture()
-- button.checkedTexture:SetTexture("")
button.OnEnter = button:GetScript("OnEnter")
button:SetScript("OnEnter", onEnter)
if LBF then
local group = self.bar.LBFGroup
button.LBFButtonData = {
Button = button
}
group:AddButton(button, button.LBFButtonData)
end
return button
end
function StanceBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", -55, -10)
self:SavePosition()
end
self:UpdateStanceButtons()
self:ForAll("ApplyStyle", self.config.style)
end
StanceBar.button_width = 30
StanceBar.button_height = 30
function StanceBar:UpdateStanceButtons()
local buttons = self.buttons or {}
local num_stances = GetNumShapeshiftForms()
local updateBindings = (num_stances > #buttons)
for i = (#buttons+1), num_stances do
buttons[i] = StanceBarMod:CreateStanceButton(i)
end
for i = 1, num_stances do
buttons[i]:Show()
buttons[i]:Update()
end
for i = num_stances+1, #buttons do
buttons[i]:Hide()
end
StanceBarMod.button_count = num_stances
if StanceBarMod.optionobject then
StanceBarMod.optionobject.table.general.args.rows.max = num_stances
end
self.buttons = buttons
self:UpdateButtonLayout()
if updateBindings then
StanceBarMod:ReassignBindings()
end
self.disabled = (GetNumShapeshiftForms() == 0) and true or nil
-- need to re-set clickthrough after creating new buttons
self:SetClickThrough()
end
function StanceBar:OnEvent(event, ...)
if event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORMS" and not InCombatLockdown() then
self:UpdateStanceButtons()
else
self:ForAll("Update")
end
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local StanceBarMod = Bartender4:NewModule("StanceBar", "AceEvent-3.0")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local StanceBar = setmetatable({}, {__index = ButtonBar})
local StanceButtonPrototype = CreateFrame("CheckButton")
local StanceButton_MT = {__index = StanceButtonPrototype}
local format = string.format
local LBF = LibStub("LibButtonFacade", true)
local KeyBound = LibStub("LibKeyBound-1.0")
local defaults = { profile = Bartender4:Merge({
enabled = true,
position = {
scale = 1.5,
},
hidehotkey = true,
}, Bartender4.ButtonBar.defaults) }
function StanceBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("StanceBar", defaults)
self:SetEnabledState(self.db.profile.enabled)
end
function StanceBarMod:OnEnable()
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("StanceBar", self.db.profile, L["Stance Bar"]), {__index = StanceBar})
self.bar:SetScript("OnEvent", StanceBar.OnEvent)
end
self.bar:Enable()
self:ToggleOptions()
self.bar:RegisterEvent("PLAYER_ENTERING_WORLD")
self.bar:RegisterEvent("UPDATE_SHAPESHIFT_FORMS")
self.bar:RegisterEvent("SPELL_UPDATE_COOLDOWN")
self.bar:RegisterEvent("SPELL_UPDATE_USABLE")
self.bar:RegisterEvent("PLAYER_AURAS_CHANGED")
self.bar:RegisterEvent("PLAYER_REGEN_ENABLED")
self.bar:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
self:RegisterEvent("UPDATE_BINDINGS", "ReassignBindings")
self:ReassignBindings()
self:ApplyConfig()
end
StanceBarMod.button_count = 10
function StanceBarMod:ApplyConfig()
if not self:IsEnabled() then return end
self.bar:ApplyConfig(self.db.profile)
if GetNumShapeshiftForms() == 0 then
self:Disable()
end
end
function StanceBarMod:ReassignBindings()
if InCombatLockdown() then return end
if not self.bar or not self.bar.buttons then return end
ClearOverrideBindings(self.bar)
for i = 1, min(#self.bar.buttons, 10) do
local button, real_button = ("SHAPESHIFTBUTTON%d"):format(i), ("BT4StanceButton%d"):format(i)
for k=1, select('#', GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
SetOverrideBindingClick(self.bar, false, key, real_button)
end
end
end
function StanceButtonPrototype:Update()
if not self:IsShown() then return end
local id = self:GetID()
local texture, name, isActive, isCastable = GetShapeshiftFormInfo(id)
self.icon:SetTexture(texture)
-- manage cooldowns
if texture then
self.cooldown:Show()
else
self.cooldown:Hide()
end
local start, duration, enable = GetShapeshiftFormCooldown(id)
CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
if isActive then
self:SetChecked(1)
else
self:SetChecked(0)
end
if isCastable then
self.icon:SetVertexColor(1.0, 1.0, 1.0)
else
self.icon:SetVertexColor(0.4, 0.4, 0.4)
end
self:UpdateHotkeys()
end
function StanceButtonPrototype:UpdateHotkeys()
local key = self:GetHotkey() or ""
local hotkey = self.hotkey
if key == "" or self.parent.config.hidehotkey then
hotkey:Hide()
else
hotkey:SetText(key)
hotkey:Show()
end
end
function StanceButtonPrototype:GetHotkey()
local key = GetBindingKey(format("SHAPESHIFTBUTTON%d", self:GetID())) or GetBindingKey("CLICK "..self:GetName()..":LeftButton")
return key and KeyBound:ToShortKey(key)
end
function StanceButtonPrototype:GetBindings()
local keys, binding = ""
binding = format("SHAPESHIFTBUTTON%d", self:GetID())
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys .. GetBindingText(hotKey,'KEY_')
end
binding = "CLICK "..self:GetName()..":LeftButton"
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys ~= "" then
keys = keys .. ', '
end
keys = keys.. GetBindingText(hotKey,'KEY_')
end
return keys
end
function StanceButtonPrototype:SetKey(key)
SetBinding(key, format("SHAPESHIFTBUTTON%d", self:GetID()))
end
function StanceButtonPrototype:ClearBindings()
local binding = format("SHAPESHIFTBUTTON%d", self:GetID())
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
binding = "CLICK "..self:GetName()..":LeftButton"
while GetBindingKey(binding) do
SetBinding(GetBindingKey(binding), nil)
end
end
local actionTmpl = "Stance Button %d (%s)"
function StanceButtonPrototype:GetActionName()
local id = self:GetID()
return format(actionTmpl, id, select(2, GetShapeshiftFormInfo(id)))
end
function StanceButtonPrototype:ClearSetPoint(...)
self:ClearAllPoints()
self:SetPoint(...)
end
local function onEnter(self, ...)
if not (Bartender4.db.profile.tooltip == "nocombat" and InCombatLockdown()) and Bartender4.db.profile.tooltip ~= "disabled" then
self:OnEnter(...)
end
KeyBound:Set(self)
end
function StanceBarMod:CreateStanceButton(id)
local button = setmetatable(CreateFrame("CheckButton", "BT4StanceButton" .. id, self.bar, "ShapeshiftButtonTemplate"), StanceButton_MT)
button.parent = self.bar
button:SetID(id)
button.icon = _G[button:GetName() .. "Icon"]
button.cooldown = _G[button:GetName() .. "Cooldown"]
button.hotkey = _G[button:GetName() .. "HotKey"]
button.normalTexture = button:GetNormalTexture()
button.normalTexture:SetTexture("")
-- button.checkedTexture = button:GetCheckedTexture()
-- button.checkedTexture:SetTexture("")
button.OnEnter = button:GetScript("OnEnter")
button:SetScript("OnEnter", onEnter)
if LBF then
local group = self.bar.LBFGroup
button.LBFButtonData = {
Button = button
}
group:AddButton(button, button.LBFButtonData)
end
return button
end
function StanceBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", -55, -10)
self:SavePosition()
end
self:UpdateStanceButtons()
self:ForAll("ApplyStyle", self.config.style)
end
StanceBar.button_width = 30
StanceBar.button_height = 30
function StanceBar:UpdateStanceButtons()
local buttons = self.buttons or {}
local num_stances = GetNumShapeshiftForms()
local updateBindings = (num_stances > #buttons)
for i = (#buttons+1), num_stances do
buttons[i] = StanceBarMod:CreateStanceButton(i)
end
for i = 1, num_stances do
buttons[i]:Show()
buttons[i]:Update()
end
for i = num_stances+1, #buttons do
buttons[i]:Hide()
end
StanceBarMod.button_count = num_stances
if StanceBarMod.optionobject then
StanceBarMod.optionobject.table.general.args.rows.max = num_stances
end
self.buttons = buttons
self:UpdateButtonLayout()
if updateBindings then
StanceBarMod:ReassignBindings()
end
self.disabled = (GetNumShapeshiftForms() == 0) and true or nil
-- need to re-set clickthrough after creating new buttons
self:SetClickThrough()
end
function StanceBar:OnEvent(event, ...)
if event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORMS" and not InCombatLockdown() then
self:UpdateStanceButtons()
else
self:ForAll("Update")
end
end
+286 -261
View File
@@ -1,261 +1,286 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
--[[ Generic Template for a ButtonBar with state control ]]
local ButtonBar = Bartender4.ButtonBar.prototype
local StateBar = setmetatable({}, {__index = ButtonBar})
local StateBar_MT = {__index = StateBar}
local defaults = Bartender4:Merge({
autoassist = false,
states = {
enabled = false,
possess = false,
actionbar = false,
default = 0,
ctrl = 0,
alt = 0,
shift = 0,
stance = {
['*'] = {
},
},
},
}, Bartender4.ButtonBar.defaults)
Bartender4.StateBar = {}
Bartender4.StateBar.prototype = StateBar
Bartender4.StateBar.defaults = defaults
function Bartender4.StateBar:Create(id, config, name)
local bar = setmetatable(Bartender4.ButtonBar:Create(id, config, name), StateBar_MT)
return bar
end
StateBar.BT4BarType = "StateBar"
function StateBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
-- We cannot call UpdateStates or UpdateSelfCast now, because the buttons are not yet created *sad*
end
--------------------------------------------------------------
-- Stance Management
local table_insert = table.insert
local table_concat = table.concat
local fmt = string.format
local modifiers = { "ctrl", "alt", "shift" }
local _, playerclass = UnitClass("player")
-- specifiy the available stances for each class
local DefaultStanceMap = setmetatable({}, { __index = function(t,k)
local newT = nil
if k == "WARRIOR" then
newT = {
{ id = "battle", name = GetSpellInfo(2457), index = 1},
{ id = "def", name = GetSpellInfo(71), index = 2 },
{ id = "berserker", name = GetSpellInfo(2458), index = 3 },
}
elseif k == "DRUID" then
newT = {
{ id = "bear", name = GetSpellInfo(5487), index = 3 },
{ id = "cat", name = GetSpellInfo(768), index = 1 },
-- prowl is virtual, no real stance
{ id = "prowl", name = ("%s (%s)"):format((GetSpellInfo(768)), (GetSpellInfo(5215))), index = false},
{ id = "moonkin", name = GetSpellInfo(24858), index = 4 },
{ id = "treeoflife", name = GetSpellInfo(33891), index = 2 },
}
elseif k == "ROGUE" then
newT = {
{ id = "stealth", name = GetSpellInfo(1784), index = 1 },
{ id = "shadowdance", name = GetSpellInfo(51713), index = 2 },
}
elseif k == "PRIEST" then
newT = {
{ id = "shadowform", name = GetSpellInfo(15473), index = 1 },
}
elseif k == "WARLOCK" then
newT = {
{ id = "metamorphosis", name = GetSpellInfo(59672), index = 2, type = "form"},
}
end
rawset(t, k, newT)
return newT
end})
Bartender4.StanceMap = DefaultStanceMap
local stancemap
function StateBar:UpdateStates(returnOnly)
if not self.buttons then return end
self.statebutton = {}
if not stancemap and DefaultStanceMap[playerclass] then
stancemap = DefaultStanceMap[playerclass]
end
local statedriver
if not self:GetStateOption("enabled") then
statedriver = "0"
elseif returnOnly or not self:GetStateOption("customEnabled") then
statedriver = {}
local stateconfig = self.config.states
-- arguments will be parsed from left to right, so we have a priority here
-- possessing will always be the most important change, if enabled
if self:GetStateOption("possess") then
table_insert(statedriver, "[bonusbar:5]11")
end
-- highest priority have our temporary quick-swap keys
for _,v in pairs(modifiers) do
local page = self:GetStateOption(v)
if page and page ~= 0 then
table_insert(statedriver, fmt("[mod:%s]%s", v, page))
end
end
-- second priority the manual changes using the ActionBar options
if self:GetStateOption("actionbar") then
for i=2,6 do
table_insert(statedriver, fmt("[bar:%s]%s", i, i))
end
end
-- third priority the stances
if stancemap then
if not stateconfig.stance[playerclass] then stateconfig.stance[playerclass] = {} end
for i,v in pairs(stancemap) do
local state = self:GetStanceState(v)
if state and state ~= 0 and v.index then
-- hack for druid prowl, since its no real "stance", but we want to handle it anyway
if playerclass == "DRUID" and v.id == "cat" then
local prowl = self:GetStanceState("prowl")
if prowl and prowl ~= 0 then
table_insert(statedriver, fmt("[bonusbar:%s,stealth:1]%s", v.index, prowl))
end
end
table_insert(statedriver, fmt("[%s:%s]%s", v.type or "bonusbar", v.index, state))
end
end
end
table_insert(statedriver, tostring(self:GetDefaultState() or 0))
statedriver = table_concat(statedriver, ";")
if returnOnly then
return statedriver
end
else
statedriver = self:GetStateOption("custom")
end
self:SetAttribute("_onstate-page", [[
self:SetAttribute("state", newstate)
control:ChildUpdate("state", newstate)
]])
UnregisterStateDriver(self, "page")
self:SetAttribute("state-page", "0")
RegisterStateDriver(self, "page", statedriver or "0")
self:SetAttribute("_onstate-assist-help", [[
local state = (newstate ~= "nil") and newstate or nil
control:ChildUpdate("assist-help", state)
]])
self:SetAttribute("_onstate-assist-harm", [[
local state = (newstate ~= "nil") and newstate or nil
control:ChildUpdate("assist-harm", state)
]])
local preSelf = ""
if Bartender4.db.profile.selfcastmodifier then
preSelf = "[mod:SELFCAST]player;"
end
local preFocus = ""
if Bartender4.db.profile.focuscastmodifier then
preFocus = "[mod:FOCUSCAST,target=focus,exists,nodead]focus;"
end
UnregisterStateDriver(self, "assist-help")
self:SetAttribute("state-assist-help", "nil")
UnregisterStateDriver(self, "assist-harm")
self:SetAttribute("state-assist-harm", "nil")
if self.config.autoassist then
RegisterStateDriver(self, "assist-help", ("%s%s[help]nil; [target=targettarget, help]targettarget; nil"):format(preSelf, preFocus))
RegisterStateDriver(self, "assist-harm", ("%s[harm]nil; [target=targettarget, harm]targettarget; nil"):format(preFocus))
end
self:ForAll("UpdateStates")
self:Execute([[
control:ChildUpdate("init")
]])
end
function StateBar:GetStanceState(stance)
local stanceconfig = self.config.states.stance[playerclass]
if type(stance) == "table" then
state = stanceconfig[stance.id]
else
state = stanceconfig[stance]
end
return state or 0
end
function StateBar:GetStanceStateOption(stance)
local state = self:GetStanceState(stance)
return state
end
function StateBar:SetStanceStateOption(stance, state)
local stanceconfig = self.config.states.stance[playerclass]
stanceconfig[stance] = state
self:UpdateStates()
end
function StateBar:GetStateOption(key)
return self.config.states[key]
end
function StateBar:SetStateOption(key, value)
self.config.states[key] = value
self:UpdateStates()
end
function StateBar:GetDefaultState()
return self.config.states.default
end
function StateBar:SetDefaultState(_, value)
self.config.states.default = value
self:UpdateStates()
end
function StateBar:GetConfigAutoAssist()
return self.config.autoassist
end
function StateBar:SetConfigAutoAssist(_, value)
if value ~= nil then
self.config.autoassist = value
end
self:UpdateStates()
end
function StateBar:SetCopyCustomConditionals()
self.config.states.custom = self:UpdateStates(true)
self:UpdateStates()
end
function StateBar:UpdateSelfCast()
self:ForAll("UpdateSelfCast")
self:UpdateStates()
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
--[[ Generic Template for a ButtonBar with state control ]]
local ButtonBar = Bartender4.ButtonBar.prototype
local StateBar = setmetatable({}, {__index = ButtonBar})
local StateBar_MT = {__index = StateBar}
local defaults = Bartender4:Merge({
autoassist = false,
states = {
enabled = false,
possess = false,
actionbar = false,
default = 0,
ctrl = 0,
alt = 0,
shift = 0,
stance = {
['*'] = {
},
},
},
}, Bartender4.ButtonBar.defaults)
Bartender4.StateBar = {}
Bartender4.StateBar.prototype = StateBar
Bartender4.StateBar.defaults = defaults
function Bartender4.StateBar:Create(id, config, name)
local bar = setmetatable(Bartender4.ButtonBar:Create(id, config, name), StateBar_MT)
return bar
end
StateBar.BT4BarType = "StateBar"
function StateBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
-- We cannot call UpdateStates or UpdateSelfCast now, because the buttons are not yet created *sad*
end
--------------------------------------------------------------
-- Stance Management
local table_insert = table.insert
local table_concat = table.concat
local fmt = string.format
local modifiers = { "ctrl", "alt", "shift" }
local _, playerclass = UnitClass("player")
-- specifiy the available stances for each class
local DefaultStanceMap = setmetatable({}, { __index = function(t,k)
local newT = nil
if k == "WARRIOR" then
newT = {
{ id = "battle", name = GetSpellInfo(2457), index = 1},
{ id = "def", name = GetSpellInfo(71), index = 2 },
{ id = "berserker", name = GetSpellInfo(2458), index = 3 },
}
elseif k == "DRUID" then
newT = {
{ id = "bear", name = GetSpellInfo(5487), index = 3 },
{ id = "cat", name = GetSpellInfo(768), index = 1 },
-- prowl is virtual, no real stance
{ id = "prowl", name = ("%s (%s)"):format((GetSpellInfo(768)), (GetSpellInfo(5215))), index = false},
{ id = "moonkin", name = GetSpellInfo(24858), index = 4 },
{ id = "treeoflife", name = GetSpellInfo(33891), index = 2 },
}
elseif k == "ROGUE" then
newT = {
{ id = "stealth", name = GetSpellInfo(1784), index = 1 },
{ id = "shadowdance", name = GetSpellInfo(51713), index = 2 },
}
elseif k == "PRIEST" then
newT = {
{ id = "shadowform", name = GetSpellInfo(15473), index = 1 },
}
elseif k == "WARLOCK" then
newT = {
{ id = "metamorphosis", name = GetSpellInfo(59672), index = 2, type = "form"},
}
elseif k == "HERO" then
newT = {
-- Warrior
{ id = "battle", name = GetSpellInfo(2457), index = 1},
{ id = "def", name = GetSpellInfo(71), index = 2 },
{ id = "berserker", name = GetSpellInfo(2458), index = 3 },
-- Druid
{ id = "bear", name = GetSpellInfo(5487), index = 3 },
{ id = "cat", name = GetSpellInfo(768), index = 1 },
-- prowl is virtual, no real stance
{ id = "prowl", name = ("%s (%s)"):format((GetSpellInfo(768)), (GetSpellInfo(5215))), index = false},
{ id = "moonkin", name = GetSpellInfo(24858), index = 4 },
{ id = "treeoflife", name = GetSpellInfo(33891), index = 2 },
-- Rogue
{ id = "stealth", name = GetSpellInfo(1784), index = 1 },
{ id = "shadowdance", name = GetSpellInfo(51713), index = 2 },
-- Priest
{ id = "shadowform", name = GetSpellInfo(15473), index = 1 },
-- Warlock
{ id = "metamorphosis", name = GetSpellInfo(59672), index = 2, type = "form"},
}
end
rawset(t, k, newT)
return newT
end})
Bartender4.StanceMap = DefaultStanceMap
local stancemap
function StateBar:UpdateStates(returnOnly)
if not self.buttons then return end
self.statebutton = {}
if not stancemap and DefaultStanceMap[playerclass] then
stancemap = DefaultStanceMap[playerclass]
end
local statedriver
if not self:GetStateOption("enabled") then
statedriver = "0"
elseif returnOnly or not self:GetStateOption("customEnabled") then
statedriver = {}
local stateconfig = self.config.states
-- arguments will be parsed from left to right, so we have a priority here
-- possessing will always be the most important change, if enabled
if self:GetStateOption("possess") then
table_insert(statedriver, "[bonusbar:5]11")
end
-- highest priority have our temporary quick-swap keys
for _,v in pairs(modifiers) do
local page = self:GetStateOption(v)
if page and page ~= 0 then
table_insert(statedriver, fmt("[mod:%s]%s", v, page))
end
end
-- second priority the manual changes using the ActionBar options
if self:GetStateOption("actionbar") then
for i=2,6 do
table_insert(statedriver, fmt("[bar:%s]%s", i, i))
end
end
-- third priority the stances
if stancemap then
if not stateconfig.stance[playerclass] then stateconfig.stance[playerclass] = {} end
for i,v in pairs(stancemap) do
local state = self:GetStanceState(v)
if state and state ~= 0 and v.index then
-- hack for druid prowl, since its no real "stance", but we want to handle it anyway
if (playerclass == "DRUID" or playerclass == "HERO") and v.id == "cat" then
local prowl = self:GetStanceState("prowl")
if prowl and prowl ~= 0 then
table_insert(statedriver, fmt("[bonusbar:%s,stealth:1]%s", v.index, prowl))
end
end
table_insert(statedriver, fmt("[%s:%s]%s", v.type or "bonusbar", v.index, state))
end
end
end
table_insert(statedriver, tostring(self:GetDefaultState() or 0))
statedriver = table_concat(statedriver, ";")
if returnOnly then
return statedriver
end
else
statedriver = self:GetStateOption("custom")
end
self:SetAttribute("_onstate-page", [[
self:SetAttribute("state", newstate)
control:ChildUpdate("state", newstate)
]])
UnregisterStateDriver(self, "page")
self:SetAttribute("state-page", "0")
RegisterStateDriver(self, "page", statedriver or "0")
self:SetAttribute("_onstate-assist-help", [[
local state = (newstate ~= "nil") and newstate or nil
control:ChildUpdate("assist-help", state)
]])
self:SetAttribute("_onstate-assist-harm", [[
local state = (newstate ~= "nil") and newstate or nil
control:ChildUpdate("assist-harm", state)
]])
local preSelf = ""
if Bartender4.db.profile.selfcastmodifier then
preSelf = "[mod:SELFCAST]player;"
end
local preFocus = ""
if Bartender4.db.profile.focuscastmodifier then
preFocus = "[mod:FOCUSCAST,target=focus,exists,nodead]focus;"
end
UnregisterStateDriver(self, "assist-help")
self:SetAttribute("state-assist-help", "nil")
UnregisterStateDriver(self, "assist-harm")
self:SetAttribute("state-assist-harm", "nil")
if self.config.autoassist then
RegisterStateDriver(self, "assist-help", ("%s%s[help]nil; [target=targettarget, help]targettarget; nil"):format(preSelf, preFocus))
RegisterStateDriver(self, "assist-harm", ("%s[harm]nil; [target=targettarget, harm]targettarget; nil"):format(preFocus))
end
self:ForAll("UpdateStates")
self:Execute([[
control:ChildUpdate("init")
]])
end
function StateBar:GetStanceState(stance)
local stanceconfig = self.config.states.stance[playerclass]
if type(stance) == "table" then
state = stanceconfig[stance.id]
else
state = stanceconfig[stance]
end
return state or 0
end
function StateBar:GetStanceStateOption(stance)
local state = self:GetStanceState(stance)
return state
end
function StateBar:SetStanceStateOption(stance, state)
local stanceconfig = self.config.states.stance[playerclass]
stanceconfig[stance] = state
self:UpdateStates()
end
function StateBar:GetStateOption(key)
return self.config.states[key]
end
function StateBar:SetStateOption(key, value)
self.config.states[key] = value
self:UpdateStates()
end
function StateBar:GetDefaultState()
return self.config.states.default
end
function StateBar:SetDefaultState(_, value)
self.config.states.default = value
self:UpdateStates()
end
function StateBar:GetConfigAutoAssist()
return self.config.autoassist
end
function StateBar:SetConfigAutoAssist(_, value)
if value ~= nil then
self.config.autoassist = value
end
self:UpdateStates()
end
function StateBar:SetCopyCustomConditionals()
self.config.states.custom = self:UpdateStates(true)
self:UpdateStates()
end
function StateBar:UpdateSelfCast()
self:ForAll("UpdateSelfCast")
self:UpdateStates()
end
+3 -3
View File
@@ -1,4 +1,4 @@
Bartender4 TODO List
- Alignment Menu
Bartender4 TODO List
- Alignment Menu
- Options to control the removal of the Blizzard Artwork Bottom Bar
+126 -126
View File
@@ -1,126 +1,126 @@
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local VehicleBarMod = Bartender4:NewModule("Vehicle")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local VehicleBar = setmetatable({}, {__index = ButtonBar})
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = true,
visibility = {
custom = true,
customdata = "[target=vehicle,exists]show;hide"
},
}, Bartender4.ButtonBar.defaults) }
function VehicleBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("Vehicle", defaults)
if self.blizzardVehicle then
self:SetEnabledState(false)
else
self:SetEnabledState(self.db.profile.enabled)
end
end
function VehicleBarMod:OnEnable()
if self.blizzardVehicle then
self:Disable()
return
end
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("Vehicle", self.db.profile, L["Vehicle Bar"], true), {__index = VehicleBar})
local buttons = {VehicleMenuBarLeaveButton, VehicleMenuBarPitchUpButton, VehicleMenuBarPitchDownButton}
self.bar.buttons = buttons
VehicleBarMod.button_count = 3
for i,v in pairs(buttons) do
v:SetParent(self.bar)
v:Show()
v.ClearSetPoint = self.bar.ClearSetPoint
end
self.bar:SetScript("OnEvent", self.bar.OnEvent)
self.bar:RegisterEvent("UNIT_ENTERED_VEHICLE")
-- setup button skins
VehicleMenuBarPitchUpButton:GetNormalTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Pitch-Up]])
VehicleMenuBarPitchUpButton:GetNormalTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarPitchUpButton:GetPushedTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Pitch-Down]])
VehicleMenuBarPitchUpButton:GetPushedTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarPitchDownButton:GetNormalTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-PitchDown-Up]])
VehicleMenuBarPitchDownButton:GetNormalTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarPitchDownButton:GetPushedTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-PitchDown-Down]])
VehicleMenuBarPitchDownButton:GetPushedTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarLeaveButton:GetNormalTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Exit-Up]])
VehicleMenuBarLeaveButton:GetNormalTexture():SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375)
VehicleMenuBarLeaveButton:GetPushedTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Exit-Down]])
VehicleMenuBarLeaveButton:GetPushedTexture():SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function VehicleBarMod:OnDisable()
Bartender4.modulePrototype.OnDisable(self)
VehicleMenuBarPitchUpButton:SetParent(VehicleMenuBar)
VehicleMenuBarPitchUpButton:ClearAllPoints()
VehicleMenuBarPitchDownButton:SetParent(VehicleMenuBar)
VehicleMenuBarPitchDownButton:ClearAllPoints()
VehicleMenuBarLeaveButton:SetParent(VehicleMenuBar)
VehicleMenuBarLeaveButton:ClearAllPoints()
end
function VehicleBarMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
VehicleBar.button_width = 40
VehicleBar.button_height = 40
VehicleBar.LBFOverride = true
function VehicleBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", 120, 27)
self:SavePosition()
end
self:UpdateButtonLayout()
end
function VehicleBar:OnEvent(event, arg1)
if event == "UNIT_ENTERED_VEHICLE" then
if arg1 == "player" then
self:UpdateButtonVisibility()
end
end
end
function VehicleBar:UpdateButtonVisibility()
if IsVehicleAimAngleAdjustable() then
_G["VehicleMenuBarPitchUpButton"]:Show()
_G["VehicleMenuBarPitchDownButton"]:Show()
else
_G["VehicleMenuBarPitchUpButton"]:Hide()
_G["VehicleMenuBarPitchDownButton"]:Hide()
end
if CanExitVehicle() then
_G["VehicleMenuBarLeaveButton"]:Show()
else
_G["VehicleMenuBarLeaveButton"]:Hide()
end
end
--[[
Copyright (c) 2009, Hendrik "Nevcairiel" Leppkes < h.leppkes at gmail dot com >
All rights reserved.
]]
local L = LibStub("AceLocale-3.0"):GetLocale("Bartender4")
-- register module
local VehicleBarMod = Bartender4:NewModule("Vehicle")
-- fetch upvalues
local ButtonBar = Bartender4.ButtonBar.prototype
-- create prototype information
local VehicleBar = setmetatable({}, {__index = ButtonBar})
local table_insert = table.insert
local defaults = { profile = Bartender4:Merge({
enabled = true,
visibility = {
custom = true,
customdata = "[target=vehicle,exists]show;hide"
},
}, Bartender4.ButtonBar.defaults) }
function VehicleBarMod:OnInitialize()
self.db = Bartender4.db:RegisterNamespace("Vehicle", defaults)
if self.blizzardVehicle then
self:SetEnabledState(false)
else
self:SetEnabledState(self.db.profile.enabled)
end
end
function VehicleBarMod:OnEnable()
if self.blizzardVehicle then
self:Disable()
return
end
if not self.bar then
self.bar = setmetatable(Bartender4.ButtonBar:Create("Vehicle", self.db.profile, L["Vehicle Bar"], true), {__index = VehicleBar})
local buttons = {VehicleMenuBarLeaveButton, VehicleMenuBarPitchUpButton, VehicleMenuBarPitchDownButton}
self.bar.buttons = buttons
VehicleBarMod.button_count = 3
for i,v in pairs(buttons) do
v:SetParent(self.bar)
v:Show()
v.ClearSetPoint = self.bar.ClearSetPoint
end
self.bar:SetScript("OnEvent", self.bar.OnEvent)
self.bar:RegisterEvent("UNIT_ENTERED_VEHICLE")
-- setup button skins
VehicleMenuBarPitchUpButton:GetNormalTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Pitch-Up]])
VehicleMenuBarPitchUpButton:GetNormalTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarPitchUpButton:GetPushedTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Pitch-Down]])
VehicleMenuBarPitchUpButton:GetPushedTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarPitchDownButton:GetNormalTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-PitchDown-Up]])
VehicleMenuBarPitchDownButton:GetNormalTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarPitchDownButton:GetPushedTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-PitchDown-Down]])
VehicleMenuBarPitchDownButton:GetPushedTexture():SetTexCoord(0.21875, 0.765625, 0.234375, 0.78125)
VehicleMenuBarLeaveButton:GetNormalTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Exit-Up]])
VehicleMenuBarLeaveButton:GetNormalTexture():SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375)
VehicleMenuBarLeaveButton:GetPushedTexture():SetTexture([[Interface\Vehicles\UI-Vehicles-Button-Exit-Down]])
VehicleMenuBarLeaveButton:GetPushedTexture():SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375)
end
self.bar:Enable()
self:ToggleOptions()
self:ApplyConfig()
end
function VehicleBarMod:OnDisable()
Bartender4.modulePrototype.OnDisable(self)
VehicleMenuBarPitchUpButton:SetParent(VehicleMenuBar)
VehicleMenuBarPitchUpButton:ClearAllPoints()
VehicleMenuBarPitchDownButton:SetParent(VehicleMenuBar)
VehicleMenuBarPitchDownButton:ClearAllPoints()
VehicleMenuBarLeaveButton:SetParent(VehicleMenuBar)
VehicleMenuBarLeaveButton:ClearAllPoints()
end
function VehicleBarMod:ApplyConfig()
self.bar:ApplyConfig(self.db.profile)
end
VehicleBar.button_width = 40
VehicleBar.button_height = 40
VehicleBar.LBFOverride = true
function VehicleBar:ApplyConfig(config)
ButtonBar.ApplyConfig(self, config)
if not self.config.position.x then
self:ClearSetPoint("CENTER", 120, 27)
self:SavePosition()
end
self:UpdateButtonLayout()
end
function VehicleBar:OnEvent(event, arg1)
if event == "UNIT_ENTERED_VEHICLE" then
if arg1 == "player" then
self:UpdateButtonVisibility()
end
end
end
function VehicleBar:UpdateButtonVisibility()
if IsVehicleAimAngleAdjustable() then
_G["VehicleMenuBarPitchUpButton"]:Show()
_G["VehicleMenuBarPitchDownButton"]:Show()
else
_G["VehicleMenuBarPitchUpButton"]:Hide()
_G["VehicleMenuBarPitchDownButton"]:Hide()
end
if CanExitVehicle() then
_G["VehicleMenuBarLeaveButton"]:Show()
else
_G["VehicleMenuBarLeaveButton"]:Hide()
end
end
+642
View File
@@ -0,0 +1,642 @@
--- **AceAddon-3.0** provides a template for creating addon objects.
-- It'll provide you with a set of callback functions that allow you to simplify the loading
-- process of your addon.\\
-- Callbacks provided are:\\
-- * **OnInitialize**, which is called directly after the addon is fully loaded.
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
-- * **OnDisable**, which is only called when your addon is manually being disabled.
-- @usage
-- -- A small (but complete) addon, that doesn't do anything,
-- -- but shows usage of the callbacks.
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
--
-- function MyAddon:OnInitialize()
-- -- do init tasks here, like loading the Saved Variables,
-- -- or setting up slash commands.
-- end
--
-- function MyAddon:OnEnable()
-- -- Do more initialization here, that really enables the use of your addon.
-- -- Register Events, Hook functions, Create Frames, Get information from
-- -- the game that wasn't available in OnInitialize
-- end
--
-- function MyAddon:OnDisable()
-- -- Unhook, Unregister Events, Hide frames that you created.
-- -- You would probably only use an OnDisable if you want to
-- -- build a "standby" mode, or be able to toggle modules on/off.
-- end
-- @class file
-- @name AceAddon-3.0.lua
-- @release $Id: AceAddon-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
local MAJOR, MINOR = "AceAddon-3.0", 5
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceAddon then return end -- No Upgrade needed.
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
AceAddon.addons = AceAddon.addons or {} -- addons in general
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized
AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
-- Lua APIs
local tinsert, tconcat, tremove = table.insert, table.concat, table.remove
local fmt, tostring = string.format, tostring
local select, pairs, next, type, unpack = select, pairs, next, type, unpack
local loadstring, assert, error = loadstring, assert, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub, IsLoggedIn, geterrorhandler
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
return dispatch
]]
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
local function safecall(func, ...)
-- we check to see if the func is passed is actually a function here and don't error when it isn't
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
-- present execution should continue without hinderance
if type(func) == "function" then
return Dispatchers[select('#', ...)](func, ...)
end
end
-- local functions that will be implemented further down
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
-- used in the addon metatable
local function addontostring( self ) return self.name end
--- Create a new AceAddon-3.0 addon.
-- Any libraries you specified will be embeded, and the addon will be scheduled for
-- its OnInitialize and OnEnable callbacks.
-- The final addon object, with all libraries embeded, will be returned.
-- @paramsig [object ,]name[, lib, ...]
-- @param object Table to use as a base for the addon (optional)
-- @param name Name of the addon object to create
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a simple addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
--
-- -- Create a Addon object based on the table of a frame
-- local MyFrame = CreateFrame("Frame")
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
function AceAddon:NewAddon(objectorname, ...)
local object,name
local i=1
if type(objectorname)=="table" then
object=objectorname
name=...
i=2
else
name=objectorname
end
if type(name)~="string" then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
end
if self.addons[name] then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
end
object = object or {}
object.name = name
local addonmeta = {}
local oldmeta = getmetatable(object)
if oldmeta then
for k, v in pairs(oldmeta) do addonmeta[k] = v end
end
addonmeta.__tostring = addontostring
setmetatable( object, addonmeta )
self.addons[name] = object
object.modules = {}
object.defaultModuleLibraries = {}
Embed( object ) -- embed NewModule, GetModule methods
self:EmbedLibraries(object, select(i,...))
-- add to queue of addons to be initialized upon ADDON_LOADED
tinsert(self.initializequeue, object)
return object
end
--- Get the addon object by its name from the internal AceAddon registry.
-- Throws an error if the addon object cannot be found (except if silent is set).
-- @param name unique name of the addon object
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
function AceAddon:GetAddon(name, silent)
if not silent and not self.addons[name] then
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
end
return self.addons[name]
end
-- - Embed a list of libraries into the specified addon.
-- This function will try to embed all of the listed libraries into the addon
-- and error if a single one fails.
--
-- **Note:** This function is for internal use by :NewAddon/:NewModule
-- @paramsig addon, [lib, ...]
-- @param addon addon object to embed the libs in
-- @param lib List of libraries to embed into the addon
function AceAddon:EmbedLibraries(addon, ...)
for i=1,select("#", ... ) do
local libname = select(i, ...)
self:EmbedLibrary(addon, libname, false, 4)
end
end
-- - Embed a library into the addon object.
-- This function will check if the specified library is registered with LibStub
-- and if it has a :Embed function to call. It'll error if any of those conditions
-- fails.
--
-- **Note:** This function is for internal use by :EmbedLibraries
-- @paramsig addon, libname[, silent[, offset]]
-- @param addon addon object to embed the library in
-- @param libname name of the library to embed
-- @param silent marks an embed to fail silently if the library doesn't exist (optional)
-- @param offset will push the error messages back to said offset, defaults to 2 (optional)
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
local lib = LibStub:GetLibrary(libname, true)
if not lib and not silent then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2)
elseif lib and type(lib.Embed) == "function" then
lib:Embed(addon)
tinsert(self.embeds[addon], libname)
return true
elseif lib then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
end
end
--- Return the specified module from an addon object.
-- Throws an error if the addon object cannot be found (except if silent is set)
-- @name //addon//:GetModule
-- @paramsig name[, silent]
-- @param name unique name of the module
-- @param silent if true, the module is optional, silently return nil if its not found (optional)
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- -- Get the Module
-- MyModule = MyAddon:GetModule("MyModule")
function GetModule(self, name, silent)
if not self.modules[name] and not silent then
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
end
return self.modules[name]
end
local function IsModuleTrue(self) return true end
--- Create a new module for the addon.
-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\
-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as
-- an addon object.
-- @name //addon//:NewModule
-- @paramsig name[, prototype|lib[, lib, ...]]
-- @param name unique name of the module
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a module with some embeded libraries
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
--
-- -- Create a module with a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
function NewModule(self, name, prototype, ...)
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
module.IsModule = IsModuleTrue
module:SetEnabledState(self.defaultModuleState)
module.moduleName = name
if type(prototype) == "string" then
AceAddon:EmbedLibraries(module, prototype, ...)
else
AceAddon:EmbedLibraries(module, ...)
end
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
if not prototype or type(prototype) == "string" then
prototype = self.defaultModulePrototype or nil
end
if type(prototype) == "table" then
local mt = getmetatable(module)
mt.__index = prototype
setmetatable(module, mt) -- More of a Base class type feel.
end
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
self.modules[name] = module
return module
end
--- Returns the real name of the addon or module, without any prefix.
-- @name //addon//:GetName
-- @paramsig
-- @usage
-- print(MyAddon:GetName())
-- -- prints "MyAddon"
function GetName(self)
return self.moduleName or self.name
end
--- Enables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback
-- and enabling all modules of the addon (unless explicitly disabled).\\
-- :Enable() also sets the internal `enableState` variable to true
-- @name //addon//:Enable
-- @paramsig
-- @usage
-- -- Enable MyModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
function Enable(self)
self:SetEnabledState(true)
return AceAddon:EnableAddon(self)
end
--- Disables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback
-- and disabling all modules of the addon.\\
-- :Disable() also sets the internal `enableState` variable to false
-- @name //addon//:Disable
-- @paramsig
-- @usage
-- -- Disable MyAddon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:Disable()
function Disable(self)
self:SetEnabledState(false)
return AceAddon:DisableAddon(self)
end
--- Enables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
-- @name //addon//:EnableModule
-- @paramsig name
-- @usage
-- -- Enable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
--
-- -- Enable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:EnableModule("MyModule")
function EnableModule(self, name)
local module = self:GetModule( name )
return module:Enable()
end
--- Disables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
-- @name //addon//:DisableModule
-- @paramsig name
-- @usage
-- -- Disable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Disable()
--
-- -- Disable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:DisableModule("MyModule")
function DisableModule(self, name)
local module = self:GetModule( name )
return module:Disable()
end
--- Set the default libraries to be mixed into all modules created by this object.
-- Note that you can only change the default module libraries before any module is created.
-- @name //addon//:SetDefaultModuleLibraries
-- @paramsig lib[, lib, ...]
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
-- -- Create a module
-- MyModule = MyAddon:NewModule("MyModule")
function SetDefaultModuleLibraries(self, ...)
if next(self.modules) then
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleLibraries = {...}
end
--- Set the default state in which new modules are being created.
-- Note that you can only change the default state before any module is created.
-- @name //addon//:SetDefaultModuleState
-- @paramsig state
-- @param state Default state for new modules, true for enabled, false for disabled
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Set the default state to "disabled"
-- MyAddon:SetDefaultModuleState(false)
-- -- Create a module and explicilty enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
function SetDefaultModuleState(self, state)
if next(self.modules) then
error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleState = state
end
--- Set the default prototype to use for new modules on creation.
-- Note that you can only change the default prototype before any module is created.
-- @name //addon//:SetDefaultModulePrototype
-- @paramsig prototype
-- @param prototype Default prototype for the new modules (table)
-- @usage
-- -- Define a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- -- Set the default prototype
-- MyAddon:SetDefaultModulePrototype(prototype)
-- -- Create a module and explicitly Enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
-- -- should print "OnEnable called!" now
-- @see NewModule
function SetDefaultModulePrototype(self, prototype)
if next(self.modules) then
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
end
if type(prototype) ~= "table" then
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
end
self.defaultModulePrototype = prototype
end
--- Set the state of an addon or module
-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize.
-- @name //addon//:SetEnabledState
-- @paramsig state
-- @param state the state of an addon or module (enabled=true, disabled=false)
function SetEnabledState(self, state)
self.enabledState = state
end
--- Return an iterator of all modules associated to the addon.
-- @name //addon//:IterateModules
-- @paramsig
-- @usage
-- -- Enable all modules
-- for name, module in MyAddon:IterateModules() do
-- module:Enable()
-- end
local function IterateModules(self) return pairs(self.modules) end
-- Returns an iterator of all embeds in the addon
-- @name //addon//:IterateEmbeds
-- @paramsig
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
--- Query the enabledState of an addon.
-- @name //addon//:IsEnabled
-- @paramsig
-- @usage
-- if MyAddon:IsEnabled() then
-- MyAddon:Disable()
-- end
local function IsEnabled(self) return self.enabledState end
local mixins = {
NewModule = NewModule,
GetModule = GetModule,
Enable = Enable,
Disable = Disable,
EnableModule = EnableModule,
DisableModule = DisableModule,
IsEnabled = IsEnabled,
SetDefaultModuleLibraries = SetDefaultModuleLibraries,
SetDefaultModuleState = SetDefaultModuleState,
SetDefaultModulePrototype = SetDefaultModulePrototype,
SetEnabledState = SetEnabledState,
IterateModules = IterateModules,
IterateEmbeds = IterateEmbeds,
GetName = GetName,
}
local function IsModule(self) return false end
local pmixins = {
defaultModuleState = true,
enabledState = true,
IsModule = IsModule,
}
-- Embed( target )
-- target (object) - target object to embed aceaddon in
--
-- this is a local function specifically since it's meant to be only called internally
function Embed(target)
for k, v in pairs(mixins) do
target[k] = v
end
for k, v in pairs(pmixins) do
target[k] = target[k] or v
end
end
-- - Initialize the addon after creation.
-- This function is only used internally during the ADDON_LOADED event
-- It will call the **OnInitialize** function on the addon object (if present),
-- and the **OnEmbedInitialize** function on all embeded libraries.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- @param addon addon object to intialize
function AceAddon:InitializeAddon(addon)
safecall(addon.OnInitialize, addon)
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
end
-- we don't call InitializeAddon on modules specifically, this is handled
-- from the event handler and only done _once_
end
-- - Enable the addon after creation.
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
-- It will call the **OnEnable** function on the addon object (if present),
-- and the **OnEmbedEnable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Enable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:EnableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if self.statuses[addon.name] or not addon.enabledState then return false end
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
self.statuses[addon.name] = true
safecall(addon.OnEnable, addon)
-- make sure we're still enabled before continueing
if self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
end
-- enable possible modules.
for name, module in pairs(addon.modules) do
self:EnableAddon(module)
end
end
return self.statuses[addon.name] -- return true if we're disabled
end
-- - Disable the addon
-- Note: This function is only used internally.
-- It will call the **OnDisable** function on the addon object (if present),
-- and the **OnEmbedDisable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Disable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:DisableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if not self.statuses[addon.name] then return false end
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
self.statuses[addon.name] = false
safecall( addon.OnDisable, addon )
-- make sure we're still disabling...
if not self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
end
-- disable possible modules.
for name, module in pairs(addon.modules) do
self:DisableAddon(module)
end
end
return not self.statuses[addon.name] -- return true if we're disabled
end
--- Get an iterator over all registered addons.
-- @usage
-- -- Print a list of all installed AceAddon's
-- for name, addon in AceAddon:IterateAddons() do
-- print("Addon: " .. name)
-- end
function AceAddon:IterateAddons() return pairs(self.addons) end
--- Get an iterator over the internal status registry.
-- @usage
-- -- Print a list of all enabled addons
-- for name, status in AceAddon:IterateAddonStatus() do
-- if status then
-- print("EnabledAddon: " .. name)
-- end
-- end
function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
-- Following Iterators are deprecated, and their addon specific versions should be used
-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon)
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
-- Event Handling
local function onEvent(this, event, arg1)
if event == "ADDON_LOADED" or event == "PLAYER_LOGIN" then
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
while(#AceAddon.initializequeue > 0) do
local addon = tremove(AceAddon.initializequeue, 1)
-- this might be an issue with recursion - TODO: validate
if event == "ADDON_LOADED" then addon.baseName = arg1 end
AceAddon:InitializeAddon(addon)
tinsert(AceAddon.enablequeue, addon)
end
if IsLoggedIn() then
while(#AceAddon.enablequeue > 0) do
local addon = tremove(AceAddon.enablequeue, 1)
AceAddon:EnableAddon(addon)
end
end
end
end
AceAddon.frame:RegisterEvent("ADDON_LOADED")
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
AceAddon.frame:SetScript("OnEvent", onEvent)
-- upgrade embeded
for name, addon in pairs(AceAddon.addons) do
Embed(addon)
end
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceAddon-3.0.lua"/>
</Ui>
+57
View File
@@ -0,0 +1,57 @@
--- AceConfig-3.0 wrapper library.
-- Provides an API to register an options table with the config registry,
-- as well as associate it with a slash command.
-- @class file
-- @name AceConfig-3.0
-- @release $Id: AceConfig-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
--[[
AceConfig-3.0
Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
]]
local MAJOR, MINOR = "AceConfig-3.0", 2
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfig then return end
local cfgreg = LibStub("AceConfigRegistry-3.0")
local cfgcmd = LibStub("AceConfigCmd-3.0")
local cfgdlg = LibStub("AceConfigDialog-3.0")
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0")
-- Lua APIs
local pcall, error, type, pairs = pcall, error, type, pairs
-- -------------------------------------------------------------------
-- :RegisterOptionsTable(appName, options, slashcmd, persist)
--
-- - appName - (string) application name
-- - options - table or function ref, see AceConfigRegistry
-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
--- Register a option table with the AceConfig registry.
-- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
-- @paramsig appName, options [, slashcmd]
-- @param appName The application name for the config table.
-- @param options The option table (or a function to generate one on demand)
-- @param slashcmd A slash command to register for the option table, or a table of slash commands.
-- @usage
-- local AceConfig = LibStub("AceConfig-3.0")
-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
if not ok then error(msg, 2) end
if slashcmd then
if type(slashcmd) == "table" then
for _,cmd in pairs(slashcmd) do
cfgcmd:CreateChatCommand(cmd, appName)
end
else
cfgcmd:CreateChatCommand(slashcmd, appName)
end
end
end
+8
View File
@@ -0,0 +1,8 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
<Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/>
<Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
<!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>-->
<Script file="AceConfig-3.0.lua"/>
</Ui>
@@ -0,0 +1,787 @@
--- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
-- @class file
-- @name AceConfigCmd-3.0
-- @release $Id: AceConfigCmd-3.0.lua 904 2009-12-13 11:56:37Z nevcairiel $
--[[
AceConfigCmd-3.0
Handles commandline optionstable access
REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
]]
-- TODO: plugin args
local MAJOR, MINOR = "AceConfigCmd-3.0", 12
local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfigCmd then return end
AceConfigCmd.commands = AceConfigCmd.commands or {}
local commands = AceConfigCmd.commands
local cfgreg = LibStub("AceConfigRegistry-3.0")
local AceConsole -- LoD
local AceConsoleName = "AceConsole-3.0"
-- Lua APIs
local strsub, strsplit, strlower, strmatch, strtrim = string.sub, string.split, string.lower, string.match, string.trim
local format, tonumber, tostring = string.format, tonumber, tostring
local tsort, tinsert = table.sort, table.insert
local select, pairs, next, type = select, pairs, next, type
local error, assert = error, assert
-- WoW APIs
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub, SELECTED_CHAT_FRAME, DEFAULT_CHAT_FRAME
local L = setmetatable({}, { -- TODO: replace with proper locale
__index = function(self,k) return k end
})
local function print(msg)
(SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(msg)
end
-- constants used by getparam() calls below
local handlertypes = {["table"]=true}
local handlermsg = "expected a table"
local functypes = {["function"]=true, ["string"]=true}
local funcmsg = "expected function or member name"
-- pickfirstset() - picks the first non-nil value and returns it
local function pickfirstset(...)
for i=1,select("#",...) do
if select(i,...)~=nil then
return select(i,...)
end
end
end
-- err() - produce real error() regarding malformed options tables etc
local function err(info,inputpos,msg )
local cmdstr=" "..strsub(info.input, 1, inputpos-1)
error(MAJOR..": /" ..info[0] ..cmdstr ..": "..(msg or "malformed options table"), 2)
end
-- usererr() - produce chatframe message regarding bad slash syntax etc
local function usererr(info,inputpos,msg )
local cmdstr=strsub(info.input, 1, inputpos-1);
print("/" ..info[0] .. " "..cmdstr ..": "..(msg or "malformed options table"))
end
-- callmethod() - call a given named method (e.g. "get", "set") with given arguments
local function callmethod(info, inputpos, tab, methodtype, ...)
local method = info[methodtype]
if not method then
err(info, inputpos, "'"..methodtype.."': not set")
end
info.arg = tab.arg
info.option = tab
info.type = tab.type
if type(method)=="function" then
return method(info, ...)
elseif type(method)=="string" then
if type(info.handler[method])~="function" then
err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
end
return info.handler[method](info.handler, info, ...)
else
assert(false) -- type should have already been checked on read
end
end
-- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
local function callfunction(info, tab, methodtype, ...)
local method = tab[methodtype]
info.arg = tab.arg
info.option = tab
info.type = tab.type
if type(method)=="function" then
return method(info, ...)
else
assert(false) -- type should have already been checked on read
end
end
-- do_final() - do the final step (set/execute) along with validation and confirmation
local function do_final(info, inputpos, tab, methodtype, ...)
if info.validate then
local res = callmethod(info,inputpos,tab,"validate",...)
if type(res)=="string" then
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
return
end
end
-- console ignores .confirm
callmethod(info,inputpos,tab,methodtype, ...)
end
-- getparam() - used by handle() to retreive and store "handler", "get", "set", etc
local function getparam(info, inputpos, tab, depth, paramname, types, errormsg)
local old,oldat = info[paramname], info[paramname.."_at"]
local val=tab[paramname]
if val~=nil then
if val==false then
val=nil
elseif not types[type(val)] then
err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
end
info[paramname] = val
info[paramname.."_at"] = depth
end
return old,oldat
end
-- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
local dummytable={}
local function iterateargs(tab)
if not tab.plugins then
return pairs(tab.args)
end
local argtabkey,argtab=next(tab.plugins)
local v
return function(_, k)
while argtab do
k,v = next(argtab, k)
if k then return k,v end
if argtab==tab.args then
argtab=nil
else
argtabkey,argtab = next(tab.plugins, argtabkey)
if not argtabkey then
argtab=tab.args
end
end
end
end
end
local function checkhidden(info, inputpos, tab)
if tab.cmdHidden~=nil then
return tab.cmdHidden
end
local hidden = tab.hidden
if type(hidden) == "function" or type(hidden) == "string" then
info.hidden = hidden
hidden = callmethod(info, inputpos, tab, 'hidden')
info.hidden = nil
end
return hidden
end
local function showhelp(info, inputpos, tab, depth, noHead)
if not noHead then
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
end
local sortTbl = {} -- [1..n]=name
local refTbl = {} -- [name]=tableref
for k,v in iterateargs(tab) do
if not refTbl[k] then -- a plugin overriding something in .args
tinsert(sortTbl, k)
refTbl[k] = v
end
end
tsort(sortTbl, function(one, two)
local o1 = refTbl[one].order or 100
local o2 = refTbl[two].order or 100
if type(o1) == "function" or type(o1) == "string" then
info.order = o1
info[#info+1] = one
o1 = callmethod(info, inputpos, refTbl[one], "order")
info[#info] = nil
info.order = nil
end
if type(o2) == "function" or type(o1) == "string" then
info.order = o2
info[#info+1] = two
o2 = callmethod(info, inputpos, refTbl[two], "order")
info[#info] = nil
info.order = nil
end
if o1<0 and o2<0 then return o1<o2 end
if o2<0 then return true end
if o1<0 then return false end
if o1==o2 then return tostring(one)<tostring(two) end -- compare names
return o1<o2
end)
for i = 1, #sortTbl do
local k = sortTbl[i]
local v = refTbl[k]
if not checkhidden(info, inputpos, v) then
if v.type ~= "description" and v.type ~= "header" then
-- recursively show all inline groups
local name, desc = v.name, v.desc
if type(name) == "function" then
name = callfunction(info, v, 'name')
end
if type(desc) == "function" then
desc = callfunction(info, v, 'desc')
end
if v.type == "group" and pickfirstset(v.cmdInline, v.inline, false) then
print(" "..(desc or name)..":")
local oldhandler,oldhandler_at = getparam(info, inputpos, v, depth, "handler", handlertypes, handlermsg)
showhelp(info, inputpos, v, depth, true)
info.handler,info.handler_at = oldhandler,oldhandler_at
else
local key = k:gsub(" ", "_")
print(" |cffffff78"..key.."|r - "..(desc or name or ""))
end
end
end
end
end
local function keybindingValidateFunc(text)
if text == nil or text == "NONE" then
return nil
end
text = text:upper()
local shift, ctrl, alt
local modifier
while true do
if text == "-" then
break
end
modifier, text = strsplit('-', text, 2)
if text then
if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
return false
end
if modifier == "SHIFT" then
if shift then
return false
end
shift = true
end
if modifier == "CTRL" then
if ctrl then
return false
end
ctrl = true
end
if modifier == "ALT" then
if alt then
return false
end
alt = true
end
else
text = modifier
break
end
end
if text == "" then
return false
end
if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then
return false
end
local s = text
if shift then
s = "SHIFT-" .. s
end
if ctrl then
s = "CTRL-" .. s
end
if alt then
s = "ALT-" .. s
end
return s
end
-- handle() - selfrecursing function that processes input->optiontable
-- - depth - starts at 0
-- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
local function handle(info, inputpos, tab, depth, retfalse)
if not(type(tab)=="table" and type(tab.type)=="string") then err(info,inputpos) end
-------------------------------------------------------------------
-- Grab hold of handler,set,get,func,etc if set (and remember old ones)
-- Note that we do NOT validate if method names are correct at this stage,
-- the handler may change before they're actually used!
local oldhandler,oldhandler_at = getparam(info,inputpos,tab,depth,"handler",handlertypes,handlermsg)
local oldset,oldset_at = getparam(info,inputpos,tab,depth,"set",functypes,funcmsg)
local oldget,oldget_at = getparam(info,inputpos,tab,depth,"get",functypes,funcmsg)
local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
--local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
-------------------------------------------------------------------
-- Act according to .type of this table
if tab.type=="group" then
------------ group --------------------------------------------
if type(tab.args)~="table" then err(info, inputpos) end
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
-- grab next arg from input
local _,nextpos,arg = (info.input):find(" *([^ ]+) *", inputpos)
if not arg then
showhelp(info, inputpos, tab, depth)
return
end
nextpos=nextpos+1
-- loop .args and try to find a key with a matching name
for k,v in iterateargs(tab) do
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
-- is this child an inline group? if so, traverse into it
if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
info[depth+1] = k
if handle(info, inputpos, v, depth+1, true)==false then
info[depth+1] = nil
-- wasn't found in there, but that's ok, we just keep looking down here
else
return -- done, name was found in inline group
end
-- matching name and not a inline group
elseif strlower(arg)==strlower(k:gsub(" ", "_")) then
info[depth+1] = k
return handle(info,nextpos,v,depth+1)
end
end
-- no match
if retfalse then
-- restore old infotable members and return false to indicate failure
info.handler,info.handler_at = oldhandler,oldhandler_at
info.set,info.set_at = oldset,oldset_at
info.get,info.get_at = oldget,oldget_at
info.func,info.func_at = oldfunc,oldfunc_at
info.validate,info.validate_at = oldvalidate,oldvalidate_at
--info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
return false
end
-- couldn't find the command, display error
usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
return
end
local str = strsub(info.input,inputpos);
if tab.type=="execute" then
------------ execute --------------------------------------------
do_final(info, inputpos, tab, "func")
elseif tab.type=="input" then
------------ input --------------------------------------------
local res = true
if tab.pattern then
if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
if not strmatch(str, tab.pattern) then
usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
return
end
end
do_final(info, inputpos, tab, "set", str)
elseif tab.type=="toggle" then
------------ toggle --------------------------------------------
local b
local str = strtrim(strlower(str))
if str=="" then
b = callmethod(info, inputpos, tab, "get")
if tab.tristate then
--cycle in true, nil, false order
if b then
b = nil
elseif b == nil then
b = false
else
b = true
end
else
b = not b
end
elseif str==L["on"] then
b = true
elseif str==L["off"] then
b = false
elseif tab.tristate and str==L["default"] then
b = nil
else
if tab.tristate then
usererr(info, inputpos, format(L["'%s' - expected 'on', 'off' or 'default', or no argument to toggle."], str))
else
usererr(info, inputpos, format(L["'%s' - expected 'on' or 'off', or no argument to toggle."], str))
end
return
end
do_final(info, inputpos, tab, "set", b)
elseif tab.type=="range" then
------------ range --------------------------------------------
local val = tonumber(str)
if not val then
usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
return
end
if type(info.step)=="number" then
val = val- (val % info.step)
end
if type(info.min)=="number" and val<info.min then
usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(info.min)) )
return
end
if type(info.max)=="number" and val>info.max then
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
return
end
do_final(info, inputpos, tab, "set", val)
elseif tab.type=="select" then
------------ select ------------------------------------
local str = strtrim(strlower(str))
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
if str == "" then
local b = callmethod(info, inputpos, tab, "get")
local fmt = "|cffffff78- [%s]|r %s"
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
print(L["Options for |cffffff78"..info[#info].."|r:"])
for k, v in pairs(values) do
if b == k then
print(fmt_sel:format(k, v))
else
print(fmt:format(k, v))
end
end
return
end
local ok
for k,v in pairs(values) do
if strlower(k)==str then
str = k -- overwrite with key (in case of case mismatches)
ok = true
break
end
end
if not ok then
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
return
end
do_final(info, inputpos, tab, "set", str)
elseif tab.type=="multiselect" then
------------ multiselect -------------------------------------------
local str = strtrim(strlower(str))
local values = tab.values
if type(values) == "function" or type(values) == "string" then
info.values = values
values = callmethod(info, inputpos, tab, "values")
info.values = nil
end
if str == "" then
local fmt = "|cffffff78- [%s]|r %s"
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
print(L["Options for |cffffff78"..info[#info].."|r (multiple possible):"])
for k, v in pairs(values) do
if callmethod(info, inputpos, tab, "get", k) then
print(fmt_sel:format(k, v))
else
print(fmt:format(k, v))
end
end
return
end
--build a table of the selections, checking that they exist
--parse for =on =off =default in the process
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
local sels = {}
for v in str:gmatch("[^ ]+") do
--parse option=on etc
local opt, val = v:match('(.+)=(.+)')
--get option if toggling
if not opt then
opt = v
end
--check that the opt is valid
local ok
for k,v in pairs(values) do
if strlower(k)==opt then
opt = k -- overwrite with key (in case of case mismatches)
ok = true
break
end
end
if not ok then
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
return
end
--check that if val was supplied it is valid
if val then
if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
--val is valid insert it
sels[opt] = val
else
if tab.tristate then
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on', 'off' or 'default', or no argument to toggle."], v, val))
else
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
end
return
end
else
-- no val supplied, toggle
sels[opt] = true
end
end
for opt, val in pairs(sels) do
local newval
if (val == true) then
--toggle the option
local b = callmethod(info, inputpos, tab, "get", opt)
if tab.tristate then
--cycle in true, nil, false order
if b then
b = nil
elseif b == nil then
b = false
else
b = true
end
else
b = not b
end
newval = b
else
--set the option as specified
if val==L["on"] then
newval = true
elseif val==L["off"] then
newval = false
elseif val==L["default"] then
newval = nil
end
end
do_final(info, inputpos, tab, "set", opt, newval)
end
elseif tab.type=="color" then
------------ color --------------------------------------------
local str = strtrim(strlower(str))
if str == "" then
--TODO: Show current value
return
end
local r, g, b, a
if tab.hasAlpha then
if str:len() == 8 and str:find("^%x*$") then
--parse a hex string
r,g,b,a = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255, tonumber(str:sub(7, 8), 16) / 255
else
--parse seperate values
r,g,b,a = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
end
if not (r and g and b and a) then
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
return
end
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
--values are valid
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
--values are valid 0..255, convert to 0..1
r = r / 255
g = g / 255
b = b / 255
a = a / 255
else
--values are invalid
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0..1 or 0..255."], str))
end
else
a = 1.0
if str:len() == 6 and str:find("^%x*$") then
--parse a hex string
r,g,b = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255
else
--parse seperate values
r,g,b = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
r,g,b = tonumber(r), tonumber(g), tonumber(b)
end
if not (r and g and b) then
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBB' or 'r g b'."], str))
return
end
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 then
--values are valid
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 then
--values are valid 0..255, convert to 0..1
r = r / 255
g = g / 255
b = b / 255
else
--values are invalid
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
end
end
do_final(info, inputpos, tab, "set", r,g,b,a)
elseif tab.type=="keybinding" then
------------ keybinding --------------------------------------------
local str = strtrim(strlower(str))
if str == "" then
--TODO: Show current value
return
end
local value = keybindingValidateFunc(str:upper())
if value == false then
usererr(info, inputpos, format(L["'%s' - Invalid Keybinding."], str))
return
end
do_final(info, inputpos, tab, "set", value)
elseif tab.type=="description" then
------------ description --------------------
-- ignore description, GUI config only
else
err(info, inputpos, "unknown options table item type '"..tostring(tab.type).."'")
end
end
--- Handle the chat command.
-- This is usually called from a chat command handler to parse the command input as operations on an aceoptions table.\\
-- AceConfigCmd uses this function internally when a slash command is registered with `:CreateChatCommand`
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param input The commandline input (as given by the WoW handler, i.e. without the command itself)
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceConsole-3.0")
-- -- Use AceConsole-3.0 to register a Chat Command
-- MyAddon:RegisterChatCommand("mychat", "ChatCommand")
--
-- -- Show the GUI if no input is supplied, otherwise handle the chat input.
-- function MyAddon:ChatCommand(input)
-- -- Assuming "MyOptions" is the appName of a valid options table
-- if not input or input:trim() == "" then
-- LibStub("AceConfigDialog-3.0"):Open("MyOptions")
-- else
-- LibStub("AceConfigCmd-3.0").HandleCommand(MyAddon, "mychat", "MyOptions", input)
-- end
-- end
function AceConfigCmd:HandleCommand(slashcmd, appName, input)
local optgetter = cfgreg:GetOptionsTable(appName)
if not optgetter then
error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
end
local options = assert( optgetter("cmd", MAJOR) )
local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
[0] = slashcmd,
appName = appName,
options = options,
input = input,
self = self,
handler = self,
uiType = "cmd",
uiName = MAJOR,
}
handle(info, 1, options, 0) -- (info, inputpos, table, depth)
end
--- Utility function to create a slash command handler.
-- Also registers tab completion with AceTab
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
-- @param appName The application name as given to `:RegisterOptionsTable()`
function AceConfigCmd:CreateChatCommand(slashcmd, appName)
if not AceConsole then
AceConsole = LibStub(AceConsoleName)
end
if AceConsole.RegisterChatCommand(self, slashcmd, function(input)
AceConfigCmd.HandleCommand(self, slashcmd, appName, input) -- upgradable
end,
true) then -- succesfully registered so lets get the command -> app table in
commands[slashcmd] = appName
end
end
--- Utility function that returns the options table that belongs to a slashcommand.
-- Designed to be used for the AceTab interface.
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
-- @return The options table associated with the slash command (or nil if the slash command was not registered)
function AceConfigCmd:GetChatCommandOptions(slashcmd)
return commands[slashcmd]
end
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConfigCmd-3.0.lua"/>
</Ui>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConfigDialog-3.0.lua"/>
</Ui>
@@ -0,0 +1,346 @@
--- AceConfigRegistry-3.0 handles central registration of options tables in use by addons and modules.\\
-- Options tables can be registered as raw tables, OR as function refs that return a table.\\
-- Such functions receive three arguments: "uiType", "uiName", "appName". \\
-- * Valid **uiTypes**: "cmd", "dropdown", "dialog". This is verified by the library at call time. \\
-- * The **uiName** field is expected to contain the full name of the calling addon, including version, e.g. "FooBar-1.0". This is verified by the library at call time.\\
-- * The **appName** field is the options table name as given at registration time \\
--
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
-- @class file
-- @name AceConfigRegistry-3.0
-- @release $Id: AceConfigRegistry-3.0.lua 921 2010-05-09 15:49:14Z nevcairiel $
local MAJOR, MINOR = "AceConfigRegistry-3.0", 12
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConfigRegistry then return end
AceConfigRegistry.tables = AceConfigRegistry.tables or {}
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
if not AceConfigRegistry.callbacks then
AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
end
-- Lua APIs
local tinsert, tconcat = table.insert, table.concat
local strfind, strmatch = string.find, string.match
local type, tostring, select, pairs = type, tostring, select, pairs
local error, assert = error, assert
-----------------------------------------------------------------------
-- Validating options table consistency:
AceConfigRegistry.validated = {
-- list of options table names ran through :ValidateOptionsTable automatically.
-- CLEARED ON PURPOSE, since newer versions may have newer validators
cmd = {},
dropdown = {},
dialog = {},
}
local function err(msg, errlvl, ...)
local t = {}
for i=select("#",...),1,-1 do
tinsert(t, (select(i, ...)))
end
error(MAJOR..":ValidateOptionsTable(): "..tconcat(t,".")..msg, errlvl+2)
end
local isstring={["string"]=true, _="string"}
local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
local istable={["table"]=true, _="table"}
local ismethodtable={["table"]=true,["string"]=true,["function"]=true, _="methodname, funcref or table"}
local optstring={["nil"]=true,["string"]=true, _="string"}
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
local optnumber={["nil"]=true,["number"]=true, _="number"}
local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"}
local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"}
local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"}
local optmethodbool={["nil"]=true,["string"]=true,["function"]=true,["boolean"]=true, _="methodname, funcref or boolean"}
local opttable={["nil"]=true,["table"]=true, _="table"}
local optbool={["nil"]=true,["boolean"]=true, _="boolean"}
local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"}
local basekeys={
type=isstring,
name=isstringfunc,
desc=optstringfunc,
descStyle=optstring,
order=optmethodnumber,
validate=optmethodfalse,
confirm=optmethodbool,
confirmText=optstring,
disabled=optmethodbool,
hidden=optmethodbool,
guiHidden=optmethodbool,
dialogHidden=optmethodbool,
dropdownHidden=optmethodbool,
cmdHidden=optmethodbool,
icon=optstringfunc,
iconCoords=optmethodtable,
handler=opttable,
get=optmethodfalse,
set=optmethodfalse,
func=optmethodfalse,
arg={["*"]=true},
width=optstring,
}
local typedkeys={
header={},
description={
image=optstringfunc,
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
fontSize=optstringfunc,
},
group={
args=istable,
plugins=opttable,
inline=optbool,
cmdInline=optbool,
guiInline=optbool,
dropdownInline=optbool,
dialogInline=optbool,
childGroups=optstring,
},
execute={
image=optstringfunc,
imageCoords=optmethodtable,
imageHeight=optnumber,
imageWidth=optnumber,
},
input={
pattern=optstring,
usage=optstring,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
multiline=optboolnumber,
},
toggle={
tristate=optbool,
image=optstringfunc,
imageCoords=optmethodtable,
},
tristate={
},
range={
min=optnumber,
softMin=optnumber,
max=optnumber,
softMax=optnumber,
step=optnumber,
bigStep=optnumber,
isPercent=optbool,
},
select={
values=ismethodtable,
style={
["nil"]=true,
["string"]={dropdown=true,radio=true},
_="string: 'dropdown' or 'radio'"
},
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
multiselect={
values=ismethodtable,
style=optstring,
tristate=optbool,
control=optstring,
dialogControl=optstring,
dropdownControl=optstring,
},
color={
hasAlpha=optbool,
},
keybinding={
-- TODO
},
}
local function validateKey(k,errlvl,...)
errlvl=(errlvl or 0)+1
if type(k)~="string" then
err("["..tostring(k).."] - key is not a string", errlvl,...)
end
if strfind(k, "[%c\127]") then
err("["..tostring(k).."] - key name contained control characters", errlvl,...)
end
end
local function validateVal(v, oktypes, errlvl,...)
errlvl=(errlvl or 0)+1
local isok=oktypes[type(v)] or oktypes["*"]
if not isok then
err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,...)
end
if type(isok)=="table" then -- isok was a table containing specific values to be tested for!
if not isok[v] then
err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,...)
end
end
end
local function validate(options,errlvl,...)
errlvl=(errlvl or 0)+1
-- basic consistency
if type(options)~="table" then
err(": expected a table, got a "..type(options), errlvl,...)
end
if type(options.type)~="string" then
err(".type: expected a string, got a "..type(options.type), errlvl,...)
end
-- get type and 'typedkeys' member
local tk = typedkeys[options.type]
if not tk then
err(".type: unknown type '"..options.type.."'", errlvl,...)
end
-- make sure that all options[] are known parameters
for k,v in pairs(options) do
if not (tk[k] or basekeys[k]) then
err(": unknown parameter", errlvl,tostring(k),...)
end
end
-- verify that required params are there, and that everything is the right type
for k,oktypes in pairs(basekeys) do
validateVal(options[k], oktypes, errlvl,k,...)
end
for k,oktypes in pairs(tk) do
validateVal(options[k], oktypes, errlvl,k,...)
end
-- extra logic for groups
if options.type=="group" then
for k,v in pairs(options.args) do
validateKey(k,errlvl,"args",...)
validate(v, errlvl,k,"args",...)
end
if options.plugins then
for plugname,plugin in pairs(options.plugins) do
if type(plugin)~="table" then
err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",...)
end
for k,v in pairs(plugin) do
validateKey(k,errlvl,tostring(plugname),"plugins",...)
validate(v, errlvl,k,tostring(plugname),"plugins",...)
end
end
end
end
end
--- Validates basic structure and integrity of an options table \\
-- Does NOT verify that get/set etc actually exist, since they can be defined at any depth
-- @param options The table to be validated
-- @param name The name of the table to be validated (shown in any error message)
-- @param errlvl (optional number) error level offset, default 0 (=errors point to the function calling :ValidateOptionsTable)
function AceConfigRegistry:ValidateOptionsTable(options,name,errlvl)
errlvl=(errlvl or 0)+1
name = name or "Optionstable"
if not options.name then
options.name=name -- bit of a hack, the root level doesn't really need a .name :-/
end
validate(options,errlvl,name)
end
--- Fires a "ConfigTableChange" callback for those listening in on it, allowing config GUIs to refresh.
-- You should call this function if your options table changed from any outside event, like a game event
-- or a timer.
-- @param appName The application name as given to `:RegisterOptionsTable()`
function AceConfigRegistry:NotifyChange(appName)
if not AceConfigRegistry.tables[appName] then return end
AceConfigRegistry.callbacks:Fire("ConfigTableChange", appName)
end
-- -------------------------------------------------------------------
-- Registering and retreiving options tables:
-- validateGetterArgs: helper function for :GetOptionsTable (or, rather, the getter functions returned by it)
local function validateGetterArgs(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+2
if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
end
if not strmatch(uiName, "[A-Za-z]%-[0-9]") then -- Expecting e.g. "MyLib-1.2"
error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
end
end
--- Register an options table with the config registry.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param options The options table, OR a function reference that generates it on demand. \\
-- See the top of the page for info on arguments passed to such functions.
function AceConfigRegistry:RegisterOptionsTable(appName, options)
if type(options)=="table" then
if options.type~="group" then -- quick sanity checker
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2)
end
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+1
validateGetterArgs(uiType, uiName, errlvl)
if not AceConfigRegistry.validated[uiType][appName] then
AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
end
return options
end
elseif type(options)=="function" then
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
errlvl=(errlvl or 0)+1
validateGetterArgs(uiType, uiName, errlvl)
local tab = assert(options(uiType, uiName, appName))
if not AceConfigRegistry.validated[uiType][appName] then
AceConfigRegistry:ValidateOptionsTable(tab, appName, errlvl) -- upgradable
AceConfigRegistry.validated[uiType][appName] = true
end
return tab
end
else
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - expected table or function reference", 2)
end
end
--- Returns an iterator of ["appName"]=funcref pairs
function AceConfigRegistry:IterateOptionsTables()
return pairs(AceConfigRegistry.tables)
end
--- Query the registry for a specific options table.
-- If only appName is given, a function is returned which you
-- can call with (uiType,uiName) to get the table.\\
-- If uiType&uiName are given, the table is returned.
-- @param appName The application name as given to `:RegisterOptionsTable()`
-- @param uiType The type of UI to get the table for, one of "cmd", "dropdown", "dialog"
-- @param uiName The name of the library/addon querying for the table, e.g. "MyLib-1.0"
function AceConfigRegistry:GetOptionsTable(appName, uiType, uiName)
local f = AceConfigRegistry.tables[appName]
if not f then
return nil
end
if uiType then
return f(uiType,uiName,1) -- get the table for us
else
return f -- return the function
end
end
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConfigRegistry-3.0.lua"/>
</Ui>
+250
View File
@@ -0,0 +1,250 @@
--- **AceConsole-3.0** provides registration facilities for slash commands.
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
-- to your addons individual needs.
--
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceConsole.
-- @class file
-- @name AceConsole-3.0
-- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $
local MAJOR,MINOR = "AceConsole-3.0", 7
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConsole then return end -- No upgrade needed
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
-- Lua APIs
local tconcat, tostring, select = table.concat, tostring, select
local type, pairs, error = type, pairs, error
local format, strfind, strsub = string.format, string.find, string.sub
local max = math.max
-- WoW APIs
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
local tmp={}
local function Print(self,frame,...)
local n=0
if self ~= AceConsole then
n=n+1
tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
end
for i=1, select("#", ...) do
n=n+1
tmp[n] = tostring(select(i, ...))
end
frame:AddMessage( tconcat(tmp," ",1,n) )
end
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
-- @paramsig [chatframe ,] ...
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param ... List of any values to be printed
function AceConsole:Print(...)
local frame = ...
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
return Print(self, frame, select(2,...))
else
return Print(self, DEFAULT_CHAT_FRAME, ...)
end
end
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
-- @paramsig [chatframe ,] "format"[, ...]
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param format Format string - same syntax as standard Lua format()
-- @param ... Arguments to the format string
function AceConsole:Printf(...)
local frame = ...
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
return Print(self, frame, format(select(2,...)))
else
return Print(self, DEFAULT_CHAT_FRAME, format(...))
end
end
--- Register a simple chat command
-- @param command Chat command to be registered WITHOUT leading "/"
-- @param func Function to call when the slash command is being used (funcref or methodname)
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
function AceConsole:RegisterChatCommand( command, func, persist )
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
local name = "ACECONSOLE_"..command:upper()
if type( func ) == "string" then
SlashCmdList[name] = function(input, editBox)
self[func](self, input, editBox)
end
else
SlashCmdList[name] = func
end
_G["SLASH_"..name.."1"] = "/"..command:lower()
AceConsole.commands[command] = name
-- non-persisting commands are registered for enabling disabling
if not persist then
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
AceConsole.weakcommands[self][command] = func
end
return true
end
--- Unregister a chatcommand
-- @param command Chat command to be unregistered WITHOUT leading "/"
function AceConsole:UnregisterChatCommand( command )
local name = AceConsole.commands[command]
if name then
SlashCmdList[name] = nil
_G["SLASH_" .. name .. "1"] = nil
hash_SlashCmdList["/" .. command:upper()] = nil
AceConsole.commands[command] = nil
end
end
--- Get an iterator over all Chat Commands registered with AceConsole
-- @return Iterator (pairs) over all commands
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
local function nils(n, ...)
if n>1 then
return nil, nils(n-1, ...)
elseif n==1 then
return nil, ...
else
return ...
end
end
--- Retreive one or more space-separated arguments from a string.
-- Treats quoted strings and itemlinks as non-spaced.
-- @param string The raw argument string
-- @param numargs How many arguments to get (default 1)
-- @param startpos Where in the string to start scanning (default 1)
-- @return Returns arg1, arg2, ..., nextposition\\
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
function AceConsole:GetArgs(str, numargs, startpos)
numargs = numargs or 1
startpos = max(startpos or 1, 1)
local pos=startpos
-- find start of new arg
pos = strfind(str, "[^ ]", pos)
if not pos then -- whoops, end of string
return nils(numargs, 1e9)
end
if numargs<1 then
return pos
end
-- quoted or space separated? find out which pattern to use
local delim_or_pipe
local ch = strsub(str, pos, pos)
if ch=='"' then
pos = pos + 1
delim_or_pipe='([|"])'
elseif ch=="'" then
pos = pos + 1
delim_or_pipe="([|'])"
else
delim_or_pipe="([| ])"
end
startpos = pos
while true do
-- find delimiter or hyperlink
local ch,_
pos,_,ch = strfind(str, delim_or_pipe, pos)
if not pos then break end
if ch=="|" then
-- some kind of escape
if strsub(str,pos,pos+1)=="|H" then
-- It's a |H....|hhyper link!|h
pos=strfind(str, "|h", pos+2) -- first |h
if not pos then break end
pos=strfind(str, "|h", pos+2) -- second |h
if not pos then break end
elseif strsub(str,pos, pos+1) == "|T" then
-- It's a |T....|t texture
pos=strfind(str, "|t", pos+2)
if not pos then break end
end
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
else
-- found delimiter, done with this arg
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
end
end
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
return strsub(str, startpos), nils(numargs-1, 1e9)
end
--- embedding and embed handling
local mixins = {
"Print",
"Printf",
"RegisterChatCommand",
"UnregisterChatCommand",
"GetArgs",
}
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceBucket in
function AceConsole:Embed( target )
for k, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
function AceConsole:OnEmbedEnable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
end
end
end
function AceConsole:OnEmbedDisable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
end
end
end
for addon in pairs(AceConsole.embeds) do
AceConsole:Embed(addon)
end
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceConsole-3.0.lua"/>
</Ui>
+728
View File
@@ -0,0 +1,728 @@
--- **AceDB-3.0** manages the SavedVariables of your addon.
-- It offers profile management, smart defaults and namespaces for modules.\\
-- Data can be saved in different data-types, depending on its intended usage.
-- The most common data-type is the `profile` type, which allows the user to choose
-- the active profile, and manage the profiles of all of his characters.\\
-- The following data types are available:
-- * **char** Character-specific data. Every character has its own database.
-- * **realm** Realm-specific data. All of the players characters on the same realm share this database.
-- * **class** Class-specific data. All of the players characters of the same class share this database.
-- * **race** Race-specific data. All of the players characters of the same race share this database.
-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
-- * **global** Global Data. All characters on the same account share this database.
-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
--
-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions
-- of the DBObjectLib listed here. \\
-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note
-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that,
-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
--
-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
--
-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs.
--
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
--
-- -- declare defaults to be used in the DB
-- local defaults = {
-- profile = {
-- setting = true,
-- }
-- }
--
-- function MyAddon:OnInitialize()
-- -- Assuming the .toc says ## SavedVariables: MyAddonDB
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
-- end
-- @class file
-- @name AceDB-3.0.lua
-- @release $Id: AceDB-3.0.lua 914 2010-03-08 12:09:22Z nevcairiel $
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 20
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
if not AceDB then return end -- No upgrade needed
-- Lua APIs
local type, pairs, next, error = type, pairs, next, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
-- WoW APIs
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub
AceDB.db_registry = AceDB.db_registry or {}
AceDB.frame = AceDB.frame or CreateFrame("Frame")
local CallbackHandler
local CallbackDummy = { Fire = function() end }
local DBObjectLib = {}
--[[-------------------------------------------------------------------------
AceDB Utility Functions
---------------------------------------------------------------------------]]
-- Simple shallow copy for copying defaults
local function copyTable(src, dest)
if type(dest) ~= "table" then dest = {} end
if type(src) == "table" then
for k,v in pairs(src) do
if type(v) == "table" then
-- try to index the key first so that the metatable creates the defaults, if set, and use that table
v = copyTable(v, dest[k])
end
dest[k] = v
end
end
return dest
end
-- Called to add defaults to a section of the database
--
-- When a ["*"] default section is indexed with a new key, a table is returned
-- and set in the host table. These tables must be cleaned up by removeDefaults
-- in order to ensure we don't write empty default tables.
local function copyDefaults(dest, src)
-- this happens if some value in the SV overwrites our default value with a non-table
--if type(dest) ~= "table" then return end
for k, v in pairs(src) do
if k == "*" or k == "**" then
if type(v) == "table" then
-- This is a metatable used for table defaults
local mt = {
-- This handles the lookup and creation of new subtables
__index = function(t,k)
if k == nil then return nil end
local tbl = {}
copyDefaults(tbl, v)
rawset(t, k, tbl)
return tbl
end,
}
setmetatable(dest, mt)
-- handle already existing tables in the SV
for dk, dv in pairs(dest) do
if not rawget(src, dk) and type(dv) == "table" then
copyDefaults(dv, v)
end
end
else
-- Values are not tables, so this is just a simple return
local mt = {__index = function(t,k) return k~=nil and v or nil end}
setmetatable(dest, mt)
end
elseif type(v) == "table" then
if not rawget(dest, k) then rawset(dest, k, {}) end
if type(dest[k]) == "table" then
copyDefaults(dest[k], v)
if src['**'] then
copyDefaults(dest[k], src['**'])
end
end
else
if rawget(dest, k) == nil then
rawset(dest, k, v)
end
end
end
end
-- Called to remove all defaults in the default table from the database
local function removeDefaults(db, defaults, blocker)
-- remove all metatables from the db, so we don't accidentally create new sub-tables through them
setmetatable(db, nil)
-- loop through the defaults and remove their content
for k,v in pairs(defaults) do
if k == "*" or k == "**" then
if type(v) == "table" then
-- Loop through all the actual k,v pairs and remove
for key, value in pairs(db) do
if type(value) == "table" then
-- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
if defaults[key] == nil and (not blocker or blocker[key] == nil) then
removeDefaults(value, v)
-- if the table is empty afterwards, remove it
if next(value) == nil then
db[key] = nil
end
-- if it was specified, only strip ** content, but block values which were set in the key table
elseif k == "**" then
removeDefaults(value, v, defaults[key])
end
end
end
elseif k == "*" then
-- check for non-table default
for key, value in pairs(db) do
if defaults[key] == nil and v == value then
db[key] = nil
end
end
end
elseif type(v) == "table" and type(db[k]) == "table" then
-- if a blocker was set, dive into it, to allow multi-level defaults
removeDefaults(db[k], v, blocker and blocker[k])
if next(db[k]) == nil then
db[k] = nil
end
else
-- check if the current value matches the default, and that its not blocked by another defaults table
if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
db[k] = nil
end
end
end
end
-- This is called when a table section is first accessed, to set up the defaults
local function initSection(db, section, svstore, key, defaults)
local sv = rawget(db, "sv")
local tableCreated
if not sv[svstore] then sv[svstore] = {} end
if not sv[svstore][key] then
sv[svstore][key] = {}
tableCreated = true
end
local tbl = sv[svstore][key]
if defaults then
copyDefaults(tbl, defaults)
end
rawset(db, section, tbl)
return tableCreated, tbl
end
-- Metatable to handle the dynamic creation of sections and copying of sections.
local dbmt = {
__index = function(t, section)
local keys = rawget(t, "keys")
local key = keys[section]
if key then
local defaultTbl = rawget(t, "defaults")
local defaults = defaultTbl and defaultTbl[section]
if section == "profile" then
local new = initSection(t, section, "profiles", key, defaults)
if new then
-- Callback: OnNewProfile, database, newProfileKey
t.callbacks:Fire("OnNewProfile", t, key)
end
elseif section == "profiles" then
local sv = rawget(t, "sv")
if not sv.profiles then sv.profiles = {} end
rawset(t, "profiles", sv.profiles)
elseif section == "global" then
local sv = rawget(t, "sv")
if not sv.global then sv.global = {} end
if defaults then
copyDefaults(sv.global, defaults)
end
rawset(t, section, sv.global)
else
initSection(t, section, section, key, defaults)
end
end
return rawget(t, section)
end
}
local function validateDefaults(defaults, keyTbl, offset)
if not defaults then return end
offset = offset or 0
for k in pairs(defaults) do
if not keyTbl[k] or k == "profiles" then
error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
end
end
end
local preserve_keys = {
["callbacks"] = true,
["RegisterCallback"] = true,
["UnregisterCallback"] = true,
["UnregisterAllCallbacks"] = true,
["children"] = true,
}
local realmKey = GetRealmName()
local charKey = UnitName("player") .. " - " .. realmKey
local _, classKey = UnitClass("player")
local _, raceKey = UnitRace("player")
local factionKey = UnitFactionGroup("player")
local factionrealmKey = factionKey .. " - " .. realmKey
-- Actual database initialization function
local function initdb(sv, defaults, defaultProfile, olddb, parent)
-- Generate the database keys for each section
-- map "true" to our "Default" profile
if defaultProfile == true then defaultProfile = "Default" end
local profileKey
if not parent then
-- Make a container for profile keys
if not sv.profileKeys then sv.profileKeys = {} end
-- Try to get the profile selected from the char db
profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
-- save the selected profile for later
sv.profileKeys[charKey] = profileKey
else
-- Use the profile of the parents DB
profileKey = parent.keys.profile or defaultProfile or charKey
-- clear the profileKeys in the DB, namespaces don't need to store them
sv.profileKeys = nil
end
-- This table contains keys that enable the dynamic creation
-- of each section of the table. The 'global' and 'profiles'
-- have a key of true, since they are handled in a special case
local keyTbl= {
["char"] = charKey,
["realm"] = realmKey,
["class"] = classKey,
["race"] = raceKey,
["faction"] = factionKey,
["factionrealm"] = factionrealmKey,
["profile"] = profileKey,
["global"] = true,
["profiles"] = true,
}
validateDefaults(defaults, keyTbl, 1)
-- This allows us to use this function to reset an entire database
-- Clear out the old database
if olddb then
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
end
-- Give this database the metatable so it initializes dynamically
local db = setmetatable(olddb or {}, dbmt)
if not rawget(db, "callbacks") then
-- try to load CallbackHandler-1.0 if it loaded after our library
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
end
-- Copy methods locally into the database object, to avoid hitting
-- the metatable when calling methods
if not parent then
for name, func in pairs(DBObjectLib) do
db[name] = func
end
else
-- hack this one in
db.RegisterDefaults = DBObjectLib.RegisterDefaults
db.ResetProfile = DBObjectLib.ResetProfile
end
-- Set some properties in the database object
db.profiles = sv.profiles
db.keys = keyTbl
db.sv = sv
--db.sv_name = name
db.defaults = defaults
db.parent = parent
-- store the DB in the registry
AceDB.db_registry[db] = true
return db
end
-- handle PLAYER_LOGOUT
-- strip all defaults from all databases
-- and cleans up empty sections
local function logoutHandler(frame, event)
if event == "PLAYER_LOGOUT" then
for db in pairs(AceDB.db_registry) do
db.callbacks:Fire("OnDatabaseShutdown", db)
db:RegisterDefaults(nil)
-- cleanup sections that are empty without defaults
local sv = rawget(db, "sv")
for section in pairs(db.keys) do
if rawget(sv, section) then
-- global is special, all other sections have sub-entrys
-- also don't delete empty profiles on main dbs, only on namespaces
if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then
for key in pairs(sv[section]) do
if not next(sv[section][key]) then
sv[section][key] = nil
end
end
end
if not next(sv[section]) then
sv[section] = nil
end
end
end
end
end
end
AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
AceDB.frame:SetScript("OnEvent", logoutHandler)
--[[-------------------------------------------------------------------------
AceDB Object Method Definitions
---------------------------------------------------------------------------]]
--- Sets the defaults table for the given database object by clearing any
-- that are currently set, and then setting the new defaults.
-- @param defaults A table of defaults for this database
function DBObjectLib:RegisterDefaults(defaults)
if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
end
validateDefaults(defaults, self.keys)
-- Remove any currently set defaults
if self.defaults then
for section,key in pairs(self.keys) do
if self.defaults[section] and rawget(self, section) then
removeDefaults(self[section], self.defaults[section])
end
end
end
-- Set the DBObject.defaults table
self.defaults = defaults
-- Copy in any defaults, only touching those sections already created
if defaults then
for section,key in pairs(self.keys) do
if defaults[section] and rawget(self, section) then
copyDefaults(self[section], defaults[section])
end
end
end
end
--- Changes the profile of the database and all of it's namespaces to the
-- supplied named profile
-- @param name The name of the profile to set as the current profile
function DBObjectLib:SetProfile(name)
if type(name) ~= "string" then
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
end
-- changing to the same profile, dont do anything
if name == self.keys.profile then return end
local oldProfile = self.profile
local defaults = self.defaults and self.defaults.profile
-- Callback: OnProfileShutdown, database
self.callbacks:Fire("OnProfileShutdown", self)
if oldProfile and defaults then
-- Remove the defaults from the old profile
removeDefaults(oldProfile, defaults)
end
self.profile = nil
self.keys["profile"] = name
-- if the storage exists, save the new profile
-- this won't exist on namespaces.
if self.sv.profileKeys then
self.sv.profileKeys[charKey] = name
end
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.SetProfile(db, name)
end
end
-- Callback: OnProfileChanged, database, newProfileKey
self.callbacks:Fire("OnProfileChanged", self, name)
end
--- Returns a table with the names of the existing profiles in the database.
-- You can optionally supply a table to re-use for this purpose.
-- @param tbl A table to store the profile names in (optional)
function DBObjectLib:GetProfiles(tbl)
if tbl and type(tbl) ~= "table" then
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
end
-- Clear the container table
if tbl then
for k,v in pairs(tbl) do tbl[k] = nil end
else
tbl = {}
end
local curProfile = self.keys.profile
local i = 0
for profileKey in pairs(self.profiles) do
i = i + 1
tbl[i] = profileKey
if curProfile and profileKey == curProfile then curProfile = nil end
end
-- Add the current profile, if it hasn't been created yet
if curProfile then
i = i + 1
tbl[i] = curProfile
end
return tbl, i
end
--- Returns the current profile name used by the database
function DBObjectLib:GetCurrentProfile()
return self.keys.profile
end
--- Deletes a named profile. This profile must not be the active profile.
-- @param name The name of the profile to be deleted
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:DeleteProfile(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
end
if self.keys.profile == name then
error("Cannot delete the active profile in an AceDBObject.", 2)
end
if not rawget(self.sv.profiles, name) and not silent then
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
end
self.sv.profiles[name] = nil
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.DeleteProfile(db, name, true)
end
end
-- Callback: OnProfileDeleted, database, profileKey
self.callbacks:Fire("OnProfileDeleted", self, name)
end
--- Copies a named profile into the current profile, overwriting any conflicting
-- settings.
-- @param name The name of the profile to be copied into the current profile
-- @param silent If true, do not raise an error when the profile does not exist
function DBObjectLib:CopyProfile(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
end
if name == self.keys.profile then
error("Cannot have the same source and destination profiles.", 2)
end
if not rawget(self.sv.profiles, name) and not silent then
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
end
-- Reset the profile before copying
DBObjectLib.ResetProfile(self, nil, true)
local profile = self.profile
local source = self.sv.profiles[name]
copyTable(source, profile)
-- populate to child namespaces
if self.children then
for _, db in pairs(self.children) do
DBObjectLib.CopyProfile(db, name, true)
end
end
-- Callback: OnProfileCopied, database, sourceProfileKey
self.callbacks:Fire("OnProfileCopied", self, name)
end
--- Resets the current profile to the default values (if specified).
-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
-- @param noCallbacks if set to true, won't fire the OnProfileReset callback
function DBObjectLib:ResetProfile(noChildren, noCallbacks)
local profile = self.profile
for k,v in pairs(profile) do
profile[k] = nil
end
local defaults = self.defaults and self.defaults.profile
if defaults then
copyDefaults(profile, defaults)
end
-- populate to child namespaces
if self.children and not noChildren then
for _, db in pairs(self.children) do
DBObjectLib.ResetProfile(db, nil, noCallbacks)
end
end
-- Callback: OnProfileReset, database
if not noCallbacks then
self.callbacks:Fire("OnProfileReset", self)
end
end
--- Resets the entire database, using the string defaultProfile as the new default
-- profile.
-- @param defaultProfile The profile name to use as the default
function DBObjectLib:ResetDB(defaultProfile)
if defaultProfile and type(defaultProfile) ~= "string" then
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
end
local sv = self.sv
for k,v in pairs(sv) do
sv[k] = nil
end
local parent = self.parent
initdb(sv, self.defaults, defaultProfile, self)
-- fix the child namespaces
if self.children then
if not sv.namespaces then sv.namespaces = {} end
for name, db in pairs(self.children) do
if not sv.namespaces[name] then sv.namespaces[name] = {} end
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
end
end
-- Callback: OnDatabaseReset, database
self.callbacks:Fire("OnDatabaseReset", self)
-- Callback: OnProfileChanged, database, profileKey
self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
return self
end
--- Creates a new database namespace, directly tied to the database. This
-- is a full scale database in it's own rights other than the fact that
-- it cannot control its profile individually
-- @param name The name of the new namespace
-- @param defaults A table of values to use as defaults
function DBObjectLib:RegisterNamespace(name, defaults)
if type(name) ~= "string" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
end
if defaults and type(defaults) ~= "table" then
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
end
if self.children and self.children[name] then
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
end
local sv = self.sv
if not sv.namespaces then sv.namespaces = {} end
if not sv.namespaces[name] then
sv.namespaces[name] = {}
end
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
if not self.children then self.children = {} end
self.children[name] = newDB
return newDB
end
--- Returns an already existing namespace from the database object.
-- @param name The name of the new namespace
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- local namespace = self.db:GetNamespace('namespace')
-- @return the namespace object if found
function DBObjectLib:GetNamespace(name, silent)
if type(name) ~= "string" then
error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2)
end
if not silent and not (self.children and self.children[name]) then
error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2)
end
if not self.children then self.children = {} end
return self.children[name]
end
--[[-------------------------------------------------------------------------
AceDB Exposed Methods
---------------------------------------------------------------------------]]
--- Creates a new database object that can be used to handle database settings and profiles.
-- By default, an empty DB is created, using a character specific profile.
--
-- You can override the default profile used by passing any profile name as the third argument,
-- or by passing //true// as the third argument to use a globally shared profile called "Default".
--
-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char"
-- will use a profile named "char", and not a character-specific profile.
-- @param tbl The name of variable, or table to use for the database
-- @param defaults A table of database defaults
-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default.
-- You can also pass //true// to use a shared global profile called "Default".
-- @usage
-- -- Create an empty DB using a character-specific default profile.
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB")
-- @usage
-- -- Create a DB using defaults and using a shared default profile
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
function AceDB:New(tbl, defaults, defaultProfile)
if type(tbl) == "string" then
local name = tbl
tbl = _G[name]
if not tbl then
tbl = {}
_G[name] = tbl
end
end
if type(tbl) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
end
if defaults and type(defaults) ~= "table" then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
end
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
end
return initdb(tbl, defaults, defaultProfile)
end
-- upgrade existing databases
for db in pairs(AceDB.db_registry) do
if not db.parent then
for name,func in pairs(DBObjectLib) do
db[name] = func
end
else
db.RegisterDefaults = DBObjectLib.RegisterDefaults
db.ResetProfile = DBObjectLib.ResetProfile
end
end
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceDB-3.0.lua"/>
</Ui>
+420
View File
@@ -0,0 +1,420 @@
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
-- @class file
-- @name AceDBOptions-3.0
-- @release $Id: AceDBOptions-3.0.lua 938 2010-06-13 07:21:38Z nevcairiel $
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 12
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
if not AceDBOptions then return end -- No upgrade needed
-- Lua APIs
local pairs, next = pairs, next
-- WoW APIs
local UnitClass = UnitClass
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: NORMAL_FONT_COLOR_CODE, FONT_COLOR_CODE_CLOSE
AceDBOptions.optionTables = AceDBOptions.optionTables or {}
AceDBOptions.handlers = AceDBOptions.handlers or {}
--[[
Localization of AceDBOptions-3.0
]]
local L = {
default = "Default",
intro = "You can change the active database profile, so you can have different settings for every character.",
reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
reset = "Reset Profile",
reset_sub = "Reset the current profile to the default",
choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.",
new = "New",
new_sub = "Create a new empty profile.",
choose = "Existing Profiles",
choose_sub = "Select one of your currently available profiles.",
copy_desc = "Copy the settings from one existing profile into the currently active profile.",
copy = "Copy From",
delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
delete = "Delete a Profile",
delete_sub = "Deletes a profile from the database.",
delete_confirm = "Are you sure you want to delete the selected profile?",
profiles = "Profiles",
profiles_sub = "Manage Profiles",
current = "Current Profile:",
}
local LOCALE = GetLocale()
if LOCALE == "deDE" then
L["default"] = "Standard"
L["intro"] = "Hier kannst du das aktive Datenbankprofile \195\164ndern, damit du verschiedene Einstellungen f\195\188r jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration m\195\182glich wird."
L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zur\195\188ck, f\195\188r den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
L["reset"] = "Profil zur\195\188cksetzen"
L["reset_sub"] = "Das aktuelle Profil auf Standard zur\195\188cksetzen."
L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder w\195\164hle eines der vorhandenen Profile aus."
L["new"] = "Neu"
L["new_sub"] = "Ein neues Profil erstellen."
L["choose"] = "Vorhandene Profile"
L["choose_sub"] = "W\195\164hlt ein bereits vorhandenes Profil aus."
L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
L["copy"] = "Kopieren von..."
L["delete_desc"] = "L\195\182sche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten."
L["delete"] = "Profil l\195\182schen"
L["delete_sub"] = "L\195\182scht ein Profil aus der Datenbank."
L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?"
L["profiles"] = "Profile"
L["profiles_sub"] = "Profile verwalten"
--L["current"] = "Current Profile:"
elseif LOCALE == "frFR" then
L["default"] = "D\195\169faut"
L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des param\195\168tres diff\195\169rents pour chaque personnage, permettant ainsi d'avoir une configuration tr\195\168s flexible."
L["reset_desc"] = "R\195\169initialise le profil actuel au cas o\195\185 votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
L["reset"] = "R\195\169initialiser le profil"
L["reset_sub"] = "R\195\169initialise le profil actuel avec les param\195\168tres par d\195\169faut."
L["choose_desc"] = "Vous pouvez cr\195\169er un nouveau profil en entrant un nouveau nom dans la bo\195\174te de saisie, ou en choississant un des profils d\195\169j\195\160 existants."
L["new"] = "Nouveau"
L["new_sub"] = "Cr\195\169\195\169e un nouveau profil vierge."
L["choose"] = "Profils existants"
L["choose_sub"] = "Permet de choisir un des profils d\195\169j\195\160 disponibles."
L["copy_desc"] = "Copie les param\195\168tres d'un profil d\195\169j\195\160 existant dans le profil actuellement actif."
L["copy"] = "Copier \195\160 partir de"
L["delete_desc"] = "Supprime les profils existants inutilis\195\169s de la base de donn\195\169es afin de gagner de la place et de nettoyer le fichier SavedVariables."
L["delete"] = "Supprimer un profil"
L["delete_sub"] = "Supprime un profil de la base de donn\195\169es."
L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?"
L["profiles"] = "Profils"
L["profiles_sub"] = "Gestion des profils"
--L["current"] = "Current Profile:"
elseif LOCALE == "koKR" then
L["default"] = "기본값"
L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다."
L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다."
L["reset"] = "프로필 초기화"
L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다"
L["choose_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
L["new"] = "새로운 프로필"
L["new_sub"] = "새로운 프로필을 만듭니다."
L["choose"] = "프로필 선택"
L["choose_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다."
L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다."
L["copy"] = "복사"
L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다."
L["delete"] = "프로필 삭제"
L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?"
L["profiles"] = "프로필"
L["profiles_sub"] = "프로필 설정"
--L["current"] = "Current Profile:"
elseif LOCALE == "esES" or LOCALE == "esMX" then
L["default"] = "Por defecto"
L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones."
L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
L["reset"] = "Reiniciar Perfil"
L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
L["new"] = "Nuevo"
L["new_sub"] = "Crear un nuevo perfil vacio."
L["choose"] = "Perfiles existentes"
L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
L["copy"] = "Copiar de"
L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
L["delete"] = "Borrar un Perfil"
L["delete_sub"] = "Borra un perfil de la base de datos."
L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
L["profiles"] = "Perfiles"
L["profiles_sub"] = "Manejar Perfiles"
--L["current"] = "Current Profile:"
elseif LOCALE == "zhTW" then
L["default"] = "預設"
L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。"
L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。"
L["reset"] = "重置設定檔"
L["reset_sub"] = "將當前的設定檔恢復為預設值"
L["choose_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔。"
L["new"] = "新建"
L["new_sub"] = "新建一個空的設定檔。"
L["choose"] = "現有的設定檔"
L["choose_sub"] = "從當前可用的設定檔裏面選擇一個。"
L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。"
L["copy"] = "複製自"
L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。"
L["delete"] = "刪除一個設定檔"
L["delete_sub"] = "從資料庫裏刪除一個設定檔。"
L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?"
L["profiles"] = "設定檔"
L["profiles_sub"] = "管理設定檔"
--L["current"] = "Current Profile:"
elseif LOCALE == "zhCN" then
L["default"] = "默认"
L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
L["reset"] = "重置配置文件"
L["reset_sub"] = "将当前的配置文件恢复为默认值"
L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
L["new"] = "新建"
L["new_sub"] = "新建一个空的配置文件。"
L["choose"] = "现有的配置文件"
L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
L["copy"] = "复制自"
L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
L["delete"] = "删除一个配置文件"
L["delete_sub"] = "从数据库里删除一个配置文件。"
L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
L["profiles"] = "配置文件"
L["profiles_sub"] = "管理配置文件"
--L["current"] = "Current Profile:"
elseif LOCALE == "ruRU" then
L["default"] = "По умолчанию"
L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа."
L["reset_desc"] = "Если ваша конфигурации испорчена или если вы хотите настроить всё заново - сбросьте текущий профиль на стандартные значения."
L["reset"] = "Сброс профиля"
L["reset_sub"] = "Сброс текущего профиля на стандартный"
L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
L["new"] = "Новый"
L["new_sub"] = "Создать новый чистый профиль"
L["choose"] = "Существующие профили"
L["choose_sub"] = "Выбор одиного из уже доступных профилей"
L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный."
L["copy"] = "Скопировать из"
L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
L["delete"] = "Удалить профиль"
L["delete_sub"] = "Удаление профиля из БД"
L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?"
L["profiles"] = "Профили"
L["profiles_sub"] = "Управление профилями"
--L["current"] = "Current Profile:"
end
local defaultProfiles
local tmpprofiles = {}
-- Get a list of available profiles for the specified database.
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
-- @param db The db object to retrieve the profiles from
-- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet
-- @param nocurrent If true, then getProfileList will not display the current profile in the list
-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
local function getProfileList(db, common, nocurrent)
local profiles = {}
-- copy existing profiles into the table
local currentProfile = db:GetCurrentProfile()
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
if not (nocurrent and v == currentProfile) then
profiles[v] = v
end
end
-- add our default profiles to choose from ( or rename existing profiles)
for k,v in pairs(defaultProfiles) do
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
profiles[k] = v
end
end
return profiles
end
--[[
OptionsHandlerPrototype
prototype class for handling the options in a sane way
]]
local OptionsHandlerPrototype = {}
--[[ Reset the profile ]]
function OptionsHandlerPrototype:Reset()
self.db:ResetProfile()
end
--[[ Set the profile to value ]]
function OptionsHandlerPrototype:SetProfile(info, value)
self.db:SetProfile(value)
end
--[[ returns the currently active profile ]]
function OptionsHandlerPrototype:GetCurrentProfile()
return self.db:GetCurrentProfile()
end
--[[
List all active profiles
you can control the output with the .arg variable
currently four modes are supported
(empty) - return all available profiles
"nocurrent" - returns all available profiles except the currently active profile
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
"both" - common except the active profile
]]
function OptionsHandlerPrototype:ListProfiles(info)
local arg = info.arg
local profiles
if arg == "common" and not self.noDefaultProfiles then
profiles = getProfileList(self.db, true, nil)
elseif arg == "nocurrent" then
profiles = getProfileList(self.db, nil, true)
elseif arg == "both" then -- currently not used
profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true)
else
profiles = getProfileList(self.db)
end
return profiles
end
function OptionsHandlerPrototype:HasNoProfiles(info)
local profiles = self:ListProfiles(info)
return ((not next(profiles)) and true or false)
end
--[[ Copy a profile ]]
function OptionsHandlerPrototype:CopyProfile(info, value)
self.db:CopyProfile(value)
end
--[[ Delete a profile from the db ]]
function OptionsHandlerPrototype:DeleteProfile(info, value)
self.db:DeleteProfile(value)
end
--[[ fill defaultProfiles with some generic values ]]
local function generateDefaultProfiles(db)
defaultProfiles = {
["Default"] = L["default"],
[db.keys.char] = db.keys.char,
[db.keys.realm] = db.keys.realm,
[db.keys.class] = UnitClass("player")
}
end
--[[ create and return a handler object for the db, or upgrade it if it already existed ]]
local function getOptionsHandler(db, noDefaultProfiles)
if not defaultProfiles then
generateDefaultProfiles(db)
end
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
for k,v in pairs(OptionsHandlerPrototype) do
handler[k] = v
end
AceDBOptions.handlers[db] = handler
return handler
end
--[[
the real options table
]]
local optionsTable = {
desc = {
order = 1,
type = "description",
name = L["intro"] .. "\n",
},
descreset = {
order = 9,
type = "description",
name = L["reset_desc"],
},
reset = {
order = 10,
type = "execute",
name = L["reset"],
desc = L["reset_sub"],
func = "Reset",
},
current = {
order = 11,
type = "description",
name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end,
width = "default",
},
choosedesc = {
order = 20,
type = "description",
name = "\n" .. L["choose_desc"],
},
new = {
name = L["new"],
desc = L["new_sub"],
type = "input",
order = 30,
get = false,
set = "SetProfile",
},
choose = {
name = L["choose"],
desc = L["choose_sub"],
type = "select",
order = 40,
get = "GetCurrentProfile",
set = "SetProfile",
values = "ListProfiles",
arg = "common",
},
copydesc = {
order = 50,
type = "description",
name = "\n" .. L["copy_desc"],
},
copyfrom = {
order = 60,
type = "select",
name = L["copy"],
desc = L["copy_desc"],
get = false,
set = "CopyProfile",
values = "ListProfiles",
disabled = "HasNoProfiles",
arg = "nocurrent",
},
deldesc = {
order = 70,
type = "description",
name = "\n" .. L["delete_desc"],
},
delete = {
order = 80,
type = "select",
name = L["delete"],
desc = L["delete_sub"],
get = false,
set = "DeleteProfile",
values = "ListProfiles",
disabled = "HasNoProfiles",
arg = "nocurrent",
confirm = true,
confirmText = L["delete_confirm"],
},
}
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0.
-- @param db The database object to create the options table for.
-- @return The options table to be used in AceConfig-3.0
-- @usage
-- -- Assuming `options` is your top-level options table and `self.db` is your database:
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
local tbl = AceDBOptions.optionTables[db] or {
type = "group",
name = L["profiles"],
desc = L["profiles_sub"],
}
tbl.handler = getOptionsHandler(db, noDefaultProfiles)
tbl.args = optionsTable
AceDBOptions.optionTables[db] = tbl
return tbl
end
-- upgrade existing tables
for db,tbl in pairs(AceDBOptions.optionTables) do
tbl.handler = getOptionsHandler(db)
tbl.args = optionsTable
end
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceDBOptions-3.0.lua"/>
</Ui>
+126
View File
@@ -0,0 +1,126 @@
--- AceEvent-3.0 provides event registration and secure dispatching.
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
-- CallbackHandler, and dispatches all game events or addon message to the registrees.
--
-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceEvent.
-- @class file
-- @name AceEvent-3.0
-- @release $Id: AceEvent-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
local MAJOR, MINOR = "AceEvent-3.0", 3
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
if not AceEvent then return end
-- Lua APIs
local pairs = pairs
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
-- APIs and registry for blizzard events, using CallbackHandler lib
if not AceEvent.events then
AceEvent.events = CallbackHandler:New(AceEvent,
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
end
function AceEvent.events:OnUsed(target, eventname)
AceEvent.frame:RegisterEvent(eventname)
end
function AceEvent.events:OnUnused(target, eventname)
AceEvent.frame:UnregisterEvent(eventname)
end
-- APIs and registry for IPC messages, using CallbackHandler lib
if not AceEvent.messages then
AceEvent.messages = CallbackHandler:New(AceEvent,
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
)
AceEvent.SendMessage = AceEvent.messages.Fire
end
--- embedding and embed handling
local mixins = {
"RegisterEvent", "UnregisterEvent",
"RegisterMessage", "UnregisterMessage",
"SendMessage",
"UnregisterAllEvents", "UnregisterAllMessages",
}
--- Register for a Blizzard Event.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterEvent
-- @class function
-- @paramsig event[, callback [, arg]]
-- @param event The event to register for
-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
--- Unregister an event.
-- @name AceEvent:UnregisterEvent
-- @class function
-- @paramsig event
-- @param event The event to unregister
--- Register for a custom AceEvent-internal message.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterMessage
-- @class function
-- @paramsig message[, callback [, arg]]
-- @param message The message to register for
-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
--- Unregister a message
-- @name AceEvent:UnregisterMessage
-- @class function
-- @paramsig message
-- @param message The message to unregister
--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
-- @name AceEvent:SendMessage
-- @class function
-- @paramsig message, ...
-- @param message The message to send
-- @param ... Any arguments to the message
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceEvent in
function AceEvent:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
-- AceEvent:OnEmbedDisable( target )
-- target (object) - target object that is being disabled
--
-- Unregister all events messages etc when the target disables.
-- this method should be called by the target manually or by an addon framework
function AceEvent:OnEmbedDisable(target)
target:UnregisterAllEvents()
target:UnregisterAllMessages()
end
-- Script to fire blizzard events into the event listeners
local events = AceEvent.events
AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
events:Fire(event, ...)
end)
--- Finally: upgrade our old embeds
for target, v in pairs(AceEvent.embeds) do
AceEvent:Embed(target)
end
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceEvent-3.0.lua"/>
</Ui>
+805
View File
@@ -0,0 +1,805 @@
--- **AceGUI-3.0** provides access to numerous widgets which can be used to create GUIs.
-- AceGUI is used by AceConfigDialog to create the option GUIs, but you can use it by itself
-- to create any custom GUI. There are more extensive examples in the test suite in the Ace3
-- stand-alone distribution.
--
-- **Note**: When using AceGUI-3.0 directly, please do not modify the frames of the widgets directly,
-- as any "unknown" change to the widgets will cause addons that get your widget out of the widget pool
-- to misbehave. If you think some part of a widget should be modifiable, please open a ticket, and we"ll
-- implement a proper API to modify it.
-- @usage
-- local AceGUI = LibStub("AceGUI-3.0")
-- -- Create a container frame
-- local f = AceGUI:Create("Frame")
-- f:SetCallback("OnClose",function(widget) AceGUI:Release(widget) end)
-- f:SetTitle("AceGUI-3.0 Example")
-- f:SetStatusText("Status Bar")
-- f:SetLayout("Flow")
-- -- Create a button
-- local btn = AceGUI:Create("Button")
-- btn:SetWidth(170)
-- btn:SetText("Button !")
-- btn:SetCallback("OnClick", function() print("Click!") end)
-- -- Add the button to the container
-- f:AddChild(btn)
-- @class file
-- @name AceGUI-3.0
-- @release $Id: AceGUI-3.0.lua 924 2010-05-13 15:12:20Z nevcairiel $
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 33
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)
if not AceGUI then return end -- No upgrade needed
-- Lua APIs
local tconcat, tremove, tinsert = table.concat, table.remove, table.insert
local select, pairs, next, type = select, pairs, next, type
local error, assert, loadstring = error, assert, loadstring
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
local math_max = math.max
-- WoW APIs
local UIParent = 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: geterrorhandler, LibStub
--local con = LibStub("AceConsole-3.0",true)
AceGUI.WidgetRegistry = AceGUI.WidgetRegistry or {}
AceGUI.LayoutRegistry = AceGUI.LayoutRegistry or {}
AceGUI.WidgetBase = AceGUI.WidgetBase or {}
AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
-- local upvalues
local WidgetRegistry = AceGUI.WidgetRegistry
local LayoutRegistry = AceGUI.LayoutRegistry
local WidgetVersions = AceGUI.WidgetVersions
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
return dispatch
]]
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
local function safecall(func, ...)
return Dispatchers[select("#", ...)](func, ...)
end
-- Recycling functions
local newWidget, delWidget
do
-- Version Upgrade in Minor 29
-- Internal Storage of the objects changed, from an array table
-- to a hash table, and additionally we introduced versioning on
-- the widgets which would discard all widgets from a pre-29 version
-- anyway, so we just clear the storage now, and don't try to
-- convert the storage tables to the new format.
-- This should generally not cause *many* widgets to end up in trash,
-- since once dialogs are opened, all addons should be loaded already
-- and AceGUI should be on the latest version available on the users
-- setup.
-- -- nevcairiel - Nov 2nd, 2009
if oldminor and oldminor < 29 and AceGUI.objPools then
AceGUI.objPools = nil
end
AceGUI.objPools = AceGUI.objPools or {}
local objPools = AceGUI.objPools
--Returns a new instance, if none are available either returns a new table or calls the given contructor
function newWidget(type)
if not WidgetRegistry[type] then
error("Attempt to instantiate unknown widget type", 2)
end
if not objPools[type] then
objPools[type] = {}
end
local newObj = next(objPools[type])
if not newObj then
newObj = WidgetRegistry[type]()
newObj.AceGUIWidgetVersion = WidgetVersions[type]
else
objPools[type][newObj] = nil
-- if the widget is older then the latest, don't even try to reuse it
-- just forget about it, and grab a new one.
if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[type] then
return newWidget(type)
end
end
return newObj
end
-- Releases an instance to the Pool
function delWidget(obj,type)
if not objPools[type] then
objPools[type] = {}
end
if objPools[type][obj] then
error("Attempt to Release Widget that is already released", 2)
end
objPools[type][obj] = true
end
end
-------------------
-- API Functions --
-------------------
-- Gets a widget Object
--- Create a new Widget of the given type.
-- This function will instantiate a new widget (or use one from the widget pool), and call the
-- OnAcquire function on it, before returning.
-- @param type The type of the widget.
-- @return The newly created widget.
function AceGUI:Create(type)
if WidgetRegistry[type] then
local widget = newWidget(type)
if rawget(widget, "Acquire") then
widget.OnAcquire = widget.Acquire
widget.Acquire = nil
elseif rawget(widget, "Aquire") then
widget.OnAcquire = widget.Aquire
widget.Aquire = nil
end
if rawget(widget, "Release") then
widget.OnRelease = rawget(widget, "Release")
widget.Release = nil
end
if widget.OnAcquire then
widget:OnAcquire()
else
error(("Widget type %s doesn't supply an OnAcquire Function"):format(type))
end
-- Set the default Layout ("List")
safecall(widget.SetLayout, widget, "List")
safecall(widget.ResumeLayout, widget)
return widget
end
end
--- Releases a widget Object.
-- This function calls OnRelease on the widget and places it back in the widget pool.
-- Any data on the widget is being erased, and the widget will be hidden.\\
-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well.
-- @param widget The widget to release
function AceGUI:Release(widget)
safecall(widget.PauseLayout, widget)
widget:Fire("OnRelease")
safecall(widget.ReleaseChildren, widget)
if widget.OnRelease then
widget:OnRelease()
-- else
-- error(("Widget type %s doesn't supply an OnRelease Function"):format(widget.type))
end
for k in pairs(widget.userdata) do
widget.userdata[k] = nil
end
for k in pairs(widget.events) do
widget.events[k] = nil
end
widget.width = nil
widget.relWidth = nil
widget.height = nil
widget.relHeight = nil
widget.noAutoHeight = nil
widget.frame:ClearAllPoints()
widget.frame:Hide()
widget.frame:SetParent(UIParent)
widget.frame.width = nil
widget.frame.height = nil
if widget.content then
widget.content.width = nil
widget.content.height = nil
end
delWidget(widget, widget.type)
end
-----------
-- Focus --
-----------
--- Called when a widget has taken focus.
-- e.g. Dropdowns opening, Editboxes gaining kb focus
-- @param widget The widget that should be focused
function AceGUI:SetFocus(widget)
if self.FocusedWidget and self.FocusedWidget ~= widget then
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
end
self.FocusedWidget = widget
end
--- Called when something has happened that could cause widgets with focus to drop it
-- e.g. titlebar of a frame being clicked
function AceGUI:ClearFocus()
if self.FocusedWidget then
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
self.FocusedWidget = nil
end
end
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
OnAcquire() - Called when the object is acquired, should set everything to a default hidden state
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
:OnRelease() - Called when the object is Released, should remove any additional anchors and clear any data
:OnWidthSet(width) - Called when the width of the widget is changed
:OnHeightSet(height) - Called when the height of the widget is changed
Widgets should not use the OnSizeChanged events of thier frame or content members, use these methods instead
AceGUI already sets a handler to the event
:LayoutFinished(width, height) - called after a layout has finished, the width and height will be the width and height of the
area used for controls. These can be nil if the layout used the existing size to layout the controls.
]]
--------------------------
-- Widget Base Template --
--------------------------
do
local WidgetBase = AceGUI.WidgetBase
WidgetBase.SetParent = function(self, parent)
local frame = self.frame
frame:SetParent(nil)
frame:SetParent(parent.content)
self.parent = parent
end
WidgetBase.SetCallback = function(self, name, func)
if type(func) == "function" then
self.events[name] = func
end
end
WidgetBase.Fire = function(self, name, ...)
if self.events[name] then
local success, ret = safecall(self.events[name], self, name, ...)
if success then
return ret
end
end
end
WidgetBase.SetWidth = function(self, width)
self.frame:SetWidth(width)
self.frame.width = width
if self.OnWidthSet then
self:OnWidthSet(width)
end
end
WidgetBase.SetRelativeWidth = function(self, width)
if width <= 0 or width > 1 then
error(":SetRelativeWidth(width): Invalid relative width.", 2)
end
self.relWidth = width
self.width = "relative"
end
WidgetBase.SetHeight = function(self, height)
self.frame:SetHeight(height)
self.frame.height = height
if self.OnHeightSet then
self:OnHeightSet(height)
end
end
--[[ WidgetBase.SetRelativeHeight = function(self, height)
if height <= 0 or height > 1 then
error(":SetRelativeHeight(height): Invalid relative height.", 2)
end
self.relHeight = height
self.height = "relative"
end ]]
WidgetBase.IsVisible = function(self)
return self.frame:IsVisible()
end
WidgetBase.IsShown= function(self)
return self.frame:IsShown()
end
WidgetBase.Release = function(self)
AceGUI:Release(self)
end
WidgetBase.SetPoint = function(self, ...)
return self.frame:SetPoint(...)
end
WidgetBase.ClearAllPoints = function(self)
return self.frame:ClearAllPoints()
end
WidgetBase.GetNumPoints = function(self)
return self.frame:GetNumPoints()
end
WidgetBase.GetPoint = function(self, ...)
return self.frame:GetPoint(...)
end
WidgetBase.GetUserDataTable = function(self)
return self.userdata
end
WidgetBase.SetUserData = function(self, key, value)
self.userdata[key] = value
end
WidgetBase.GetUserData = function(self, key)
return self.userdata[key]
end
WidgetBase.IsFullHeight = function(self)
return self.height == "fill"
end
WidgetBase.SetFullHeight = function(self, isFull)
if isFull then
self.height = "fill"
else
self.height = nil
end
end
WidgetBase.IsFullWidth = function(self)
return self.width == "fill"
end
WidgetBase.SetFullWidth = function(self, isFull)
if isFull then
self.width = "fill"
else
self.width = nil
end
end
-- local function LayoutOnUpdate(this)
-- this:SetScript("OnUpdate",nil)
-- this.obj:PerformLayout()
-- end
local WidgetContainerBase = AceGUI.WidgetContainerBase
WidgetContainerBase.PauseLayout = function(self)
self.LayoutPaused = true
end
WidgetContainerBase.ResumeLayout = function(self)
self.LayoutPaused = nil
end
WidgetContainerBase.PerformLayout = function(self)
if self.LayoutPaused then
return
end
safecall(self.LayoutFunc, self.content, self.children)
end
--call this function to layout, makes sure layed out objects get a frame to get sizes etc
WidgetContainerBase.DoLayout = function(self)
self:PerformLayout()
-- if not self.parent then
-- self.frame:SetScript("OnUpdate", LayoutOnUpdate)
-- end
end
WidgetContainerBase.AddChild = function(self, child, beforeWidget)
if beforeWidget then
local siblingIndex = 1
for _, widget in pairs(self.children) do
if widget == beforeWidget then
break
end
siblingIndex = siblingIndex + 1
end
tinsert(self.children, siblingIndex, child)
else
tinsert(self.children, child)
end
child:SetParent(self)
child.frame:Show()
self:DoLayout()
end
WidgetContainerBase.AddChildren = function(self, ...)
for i = 1, select("#", ...) do
local child = select(i, ...)
tinsert(self.children, child)
child:SetParent(self)
child.frame:Show()
end
self:DoLayout()
end
WidgetContainerBase.ReleaseChildren = function(self)
local children = self.children
for i = 1,#children do
AceGUI:Release(children[i])
children[i] = nil
end
end
WidgetContainerBase.SetLayout = function(self, Layout)
self.LayoutFunc = AceGUI:GetLayout(Layout)
end
WidgetContainerBase.SetAutoAdjustHeight = function(self, adjust)
if adjust then
self.noAutoHeight = nil
else
self.noAutoHeight = true
end
end
local function FrameResize(this)
local self = this.obj
if this:GetWidth() and this:GetHeight() then
if self.OnWidthSet then
self:OnWidthSet(this:GetWidth())
end
if self.OnHeightSet then
self:OnHeightSet(this:GetHeight())
end
end
end
local function ContentResize(this)
if this:GetWidth() and this:GetHeight() then
this.width = this:GetWidth()
this.height = this:GetHeight()
this.obj:DoLayout()
end
end
setmetatable(WidgetContainerBase, {__index=WidgetBase})
--One of these function should be called on each Widget Instance as part of its creation process
--- Register a widget-class as a container for newly created widgets.
-- @param widget The widget class
function AceGUI:RegisterAsContainer(widget)
widget.children = {}
widget.userdata = {}
widget.events = {}
widget.base = WidgetContainerBase
widget.content.obj = widget
widget.frame.obj = widget
widget.content:SetScript("OnSizeChanged", ContentResize)
widget.frame:SetScript("OnSizeChanged", FrameResize)
setmetatable(widget, {__index = WidgetContainerBase})
widget:SetLayout("List")
return widget
end
--- Register a widget-class as a widget.
-- @param widget The widget class
function AceGUI:RegisterAsWidget(widget)
widget.userdata = {}
widget.events = {}
widget.base = WidgetBase
widget.frame.obj = widget
widget.frame:SetScript("OnSizeChanged", FrameResize)
setmetatable(widget, {__index = WidgetBase})
return widget
end
end
------------------
-- Widget API --
------------------
--- Registers a widget Constructor, this function returns a new instance of the Widget
-- @param Name The name of the widget
-- @param Constructor The widget constructor function
-- @param Version The version of the widget
function AceGUI:RegisterWidgetType(Name, Constructor, Version)
assert(type(Constructor) == "function")
assert(type(Version) == "number")
local oldVersion = WidgetVersions[Name]
if oldVersion and oldVersion >= Version then return end
WidgetVersions[Name] = Version
WidgetRegistry[Name] = Constructor
end
--- Registers a Layout Function
-- @param Name The name of the layout
-- @param LayoutFunc Reference to the layout function
function AceGUI:RegisterLayout(Name, LayoutFunc)
assert(type(LayoutFunc) == "function")
if type(Name) == "string" then
Name = Name:upper()
end
LayoutRegistry[Name] = LayoutFunc
end
--- Get a Layout Function from the registry
-- @param Name The name of the layout
function AceGUI:GetLayout(Name)
if type(Name) == "string" then
Name = Name:upper()
end
return LayoutRegistry[Name]
end
AceGUI.counts = AceGUI.counts or {}
--- A type-based counter to count the number of widgets created.
-- This is used by widgets that require a named frame, e.g. when a Blizzard
-- Template requires it.
-- @param type The widget type
function AceGUI:GetNextWidgetNum(type)
if not self.counts[type] then
self.counts[type] = 0
end
self.counts[type] = self.counts[type] + 1
return self.counts[type]
end
--- Return the number of created widgets for this type.
-- In contrast to GetNextWidgetNum, the number is not incremented.
-- @param type The widget type
function AceGUI:GetWidgetCount(type)
return self.counts[type] or 0
end
--- Return the version of the currently registered widget type.
-- @param type The widget type
function AceGUI:GetWidgetVersion(type)
return WidgetVersions[type]
end
-------------
-- Layouts --
-------------
--[[
A Layout is a func that takes 2 parameters
content - the frame that widgets will be placed inside
children - a table containing the widgets to layout
]]
-- Very simple Layout, Children are stacked on top of each other down the left side
AceGUI:RegisterLayout("List",
function(content, children)
local height = 0
local width = content.width or content:GetWidth() or 0
for i = 1, #children do
local child = children[i]
local frame = child.frame
frame:ClearAllPoints()
frame:Show()
if i == 1 then
frame:SetPoint("TOPLEFT", content)
else
frame:SetPoint("TOPLEFT", children[i-1].frame, "BOTTOMLEFT")
end
if child.width == "fill" then
child:SetWidth(width)
frame:SetPoint("RIGHT", content)
if child.DoLayout then
child:DoLayout()
end
elseif child.width == "relative" then
child:SetWidth(width * child.relWidth)
if child.DoLayout then
child:DoLayout()
end
end
height = height + (frame.height or frame:GetHeight() or 0)
end
safecall(content.obj.LayoutFinished, content.obj, nil, height)
end)
-- A single control fills the whole content area
AceGUI:RegisterLayout("Fill",
function(content, children)
if children[1] then
children[1]:SetWidth(content:GetWidth() or 0)
children[1]:SetHeight(content:GetHeight() or 0)
children[1].frame:SetAllPoints(content)
children[1].frame:Show()
safecall(content.obj.LayoutFinished, content.obj, nil, children[1].frame:GetHeight())
end
end)
AceGUI:RegisterLayout("Flow",
function(content, children)
--used height so far
local height = 0
--width used in the current row
local usedwidth = 0
--height of the current row
local rowheight = 0
local rowoffset = 0
local lastrowoffset
local width = content.width or content:GetWidth() or 0
--control at the start of the row
local rowstart
local rowstartoffset
local lastrowstart
local isfullheight
local frameoffset
local lastframeoffset
local oversize
for i = 1, #children do
local child = children[i]
oversize = nil
local frame = child.frame
local frameheight = frame.height or frame:GetHeight() or 0
local framewidth = frame.width or frame:GetWidth() or 0
lastframeoffset = frameoffset
-- HACK: Why did we set a frameoffset of (frameheight / 2) ?
-- That was moving all widgets half the widgets size down, is that intended?
-- Actually, it seems to be neccessary for many cases, we'll leave it in for now.
-- If widgets seem to anchor weirdly with this, provide a valid alignoffset for them.
-- TODO: Investigate moar!
frameoffset = child.alignoffset or (frameheight / 2)
if child.width == "relative" then
framewidth = width * child.relWidth
end
frame:Show()
frame:ClearAllPoints()
if i == 1 then
-- anchor the first control to the top left
frame:SetPoint("TOPLEFT", content)
rowheight = frameheight
rowoffset = frameoffset
rowstart = frame
rowstartoffset = frameoffset
usedwidth = framewidth
if usedwidth > width then
oversize = true
end
else
-- if there isn't available width for the control start a new row
-- if a control is "fill" it will be on a row of its own full width
if usedwidth == 0 or ((framewidth) + usedwidth > width) or child.width == "fill" then
if isfullheight then
-- a previous row has already filled the entire height, there's nothing we can usefully do anymore
-- (maybe error/warn about this?)
break
end
--anchor the previous row, we will now know its height and offset
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3))
height = height + rowheight + 3
--save this as the rowstart so we can anchor it after the row is complete and we have the max height and offset of controls in it
rowstart = frame
rowstartoffset = frameoffset
rowheight = frameheight
rowoffset = frameoffset
usedwidth = framewidth
if usedwidth > width then
oversize = true
end
-- put the control on the current row, adding it to the width and checking if the height needs to be increased
else
--handles cases where the new height is higher than either control because of the offsets
--math.max(rowheight-rowoffset+frameoffset, frameheight-frameoffset+rowoffset)
--offset is always the larger of the two offsets
rowoffset = math_max(rowoffset, frameoffset)
rowheight = math_max(rowheight, rowoffset + (frameheight / 2))
frame:SetPoint("TOPLEFT", children[i-1].frame, "TOPRIGHT", 0, frameoffset - lastframeoffset)
usedwidth = framewidth + usedwidth
end
end
if child.width == "fill" then
child:SetWidth(width)
frame:SetPoint("RIGHT", content)
usedwidth = 0
rowstart = frame
rowstartoffset = frameoffset
if child.DoLayout then
child:DoLayout()
end
rowheight = frame.height or frame:GetHeight() or 0
rowoffset = child.alignoffset or (rowheight / 2)
rowstartoffset = rowoffset
elseif child.width == "relative" then
child:SetWidth(width * child.relWidth)
if child.DoLayout then
child:DoLayout()
end
elseif oversize then
if width > 1 then
frame:SetPoint("RIGHT", content)
end
end
if child.height == "fill" then
frame:SetPoint("BOTTOM", content)
isfullheight = true
end
end
--anchor the last row, if its full height needs a special case since its height has just been changed by the anchor
if isfullheight then
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -height)
elseif rowstart then
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3))
end
height = height + rowheight + 3
safecall(content.obj.LayoutFinished, content.obj, nil, height)
end)
+28
View File
@@ -0,0 +1,28 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceGUI-3.0.lua"/>
<!-- Container -->
<Script file="widgets\AceGUIContainer-BlizOptionsGroup.lua"/>
<Script file="widgets\AceGUIContainer-DropDownGroup.lua"/>
<Script file="widgets\AceGUIContainer-Frame.lua"/>
<Script file="widgets\AceGUIContainer-InlineGroup.lua"/>
<Script file="widgets\AceGUIContainer-ScrollFrame.lua"/>
<Script file="widgets\AceGUIContainer-SimpleGroup.lua"/>
<Script file="widgets\AceGUIContainer-TabGroup.lua"/>
<Script file="widgets\AceGUIContainer-TreeGroup.lua"/>
<Script file="widgets\AceGUIContainer-Window.lua"/>
<!-- Widgets -->
<Script file="widgets\AceGUIWidget-Button.lua"/>
<Script file="widgets\AceGUIWidget-CheckBox.lua"/>
<Script file="widgets\AceGUIWidget-ColorPicker.lua"/>
<Script file="widgets\AceGUIWidget-DropDown.lua"/>
<Script file="widgets\AceGUIWidget-DropDown-Items.lua"/>
<Script file="widgets\AceGUIWidget-EditBox.lua"/>
<Script file="widgets\AceGUIWidget-Heading.lua"/>
<Script file="widgets\AceGUIWidget-Icon.lua"/>
<Script file="widgets\AceGUIWidget-InteractiveLabel.lua"/>
<Script file="widgets\AceGUIWidget-Keybinding.lua"/>
<Script file="widgets\AceGUIWidget-Label.lua"/>
<Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/>
<Script file="widgets\AceGUIWidget-Slider.lua"/>
</Ui>
@@ -0,0 +1,133 @@
--[[-----------------------------------------------------------------------------
BlizOptionsGroup Container
Simple container widget for the integration of AceGUI into the Blizzard Interface Options
-------------------------------------------------------------------------------]]
local Type, Version = "BlizOptionsGroup", 20
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 = CreateFrame
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function OnShow(frame)
frame.obj:Fire("OnShow")
end
local function OnHide(frame)
frame.obj:Fire("OnHide")
end
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function okay(frame)
frame.obj:Fire("okay")
end
local function cancel(frame)
frame.obj:Fire("cancel")
end
local function defaults(frame)
frame.obj:Fire("defaults")
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetName()
self:SetTitle()
end,
-- ["OnRelease"] = nil,
["OnWidthSet"] = function(self, width)
local content = self.content
local contentwidth = width - 63
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 - 26
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end,
["SetName"] = function(self, name, parent)
self.frame.name = name
self.frame.parent = parent
end,
["SetTitle"] = function(self, title)
local content = self.content
content:ClearAllPoints()
if not title or title == "" then
content:SetPoint("TOPLEFT", 10, -10)
self.label:SetText("")
else
content:SetPoint("TOPLEFT", 10, -40)
self.label:SetText(title)
end
content:SetPoint("BOTTOMRIGHT", -10, 10)
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local frame = CreateFrame("Frame")
frame:Hide()
-- support functions for the Blizzard Interface Options
frame.okay = okay
frame.cancel = cancel
frame.defaults = defaults
frame:SetScript("OnHide", OnHide)
frame:SetScript("OnShow", OnShow)
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
label:SetPoint("TOPLEFT", 10, -15)
label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
--Container Support
local content = CreateFrame("Frame", nil, frame)
content:SetPoint("TOPLEFT", 10, -10)
content:SetPoint("BOTTOMRIGHT", -10, 10)
local widget = {
label = label,
frame = frame,
content = content,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsContainer(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,178 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local assert, pairs, type = assert, pairs, type
-- WoW APIs
local CreateFrame = CreateFrame
--[[
Selection Group controls all have an interface to select a group for thier contents
None of them will auto size to thier contents, and should usually be used with a scrollframe
unless you know that the controls will fit inside
]]
--------------------------
-- Dropdown Group --
--------------------------
--[[
Events :
OnGroupSelected
]]
do
local Type = "DropdownGroup"
local Version = 13
local function OnAcquire(self)
self.dropdown:SetText("")
self:SetDropdownWidth(200)
self:SetTitle("")
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.dropdown.list = nil
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
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 SetTitle(self,title)
self.titletext:SetText(title)
self.dropdown.frame:ClearAllPoints()
if title and title ~= "" then
self.dropdown.frame:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -2, 0)
else
self.dropdown.frame:SetPoint("TOPLEFT", self.frame, "TOPLEFT", -1, 0)
end
end
local function SelectedGroup(self,event,value)
local group = self.parentgroup
local status = group.status or group.localstatus
status.selected = value
self.parentgroup:Fire("OnGroupSelected", value)
end
local function SetGroupList(self,list)
self.dropdown:SetList(list)
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
end
local function SetGroup(self,group)
self.dropdown:SetValue(group)
local status = self.status or self.localstatus
status.selected = group
self:Fire("OnGroupSelected", group)
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 26
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 63
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function LayoutFinished(self, width, height)
self:SetHeight((height or 0) + 63)
end
local function SetDropdownWidth(self, width)
self.dropdown:SetWidth(width)
end
local function Constructor()
local frame = CreateFrame("Frame")
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.SetGroupList = SetGroupList
self.SetGroup = SetGroup
self.SetStatusTable = SetStatusTable
self.SetDropdownWidth = SetDropdownWidth
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.LayoutFinished = LayoutFinished
self.localstatus = {}
self.frame = frame
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
titletext:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -5)
titletext:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -4, -5)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
self.titletext = titletext
local dropdown = AceGUI:Create("Dropdown")
self.dropdown = dropdown
dropdown.frame:SetParent(frame)
dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
dropdown.parentgroup = self
dropdown:SetCallback("OnValueChanged",SelectedGroup)
dropdown.frame:SetPoint("TOPLEFT",frame,"TOPLEFT", -1, 0)
dropdown.frame:Show()
dropdown:SetLabel("")
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-26)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,288 @@
--[[-----------------------------------------------------------------------------
Frame Container
-------------------------------------------------------------------------------]]
local Type, Version = "Frame", 20
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, assert, type = pairs, assert, type
local wipe = table.wipe
-- WoW APIs
local PlaySound = PlaySound
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: CLOSE
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function Button_OnClick(frame)
PlaySound("gsTitleOptionExit")
frame.obj:Hide()
end
local function Frame_OnClose(frame)
frame.obj:Fire("OnClose")
end
local function Frame_OnMouseDown(frame)
AceGUI:ClearFocus()
end
local function Title_OnMouseDown(frame)
frame:GetParent():StartMoving()
AceGUI:ClearFocus()
end
local function MoverSizer_OnMouseUp(mover)
local frame = mover:GetParent()
frame:StopMovingOrSizing()
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 SizerSE_OnMouseDown(frame)
frame:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus()
end
local function SizerS_OnMouseDown(frame)
frame:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus()
end
local function SizerE_OnMouseDown(frame)
frame:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus()
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self:SetTitle()
self:SetStatusText()
self:ApplyStatus()
self:Show()
end,
["OnRelease"] = function(self)
self.status = nil
wipe(self.localstatus)
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,
["SetTitle"] = function(self, title)
self.titletext:SetText(title)
end,
["SetStatusText"] = function(self, text)
self.statustext:SetText(text)
end,
["Hide"] = function(self)
self.frame:Hide()
end,
["Show"] = function(self)
self.frame:Show()
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 700)
self:SetHeight(status.height or 500)
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 FrameBackdrop = {
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 8, right = 8, top = 8, bottom = 8 }
}
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 frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
frame:EnableMouse(true)
frame:SetMovable(true)
frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetBackdrop(FrameBackdrop)
frame:SetBackdropColor(0, 0, 0, 1)
frame:SetMinResize(400, 200)
frame:SetToplevel(true)
frame:SetScript("OnHide", Frame_OnClose)
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
closebutton:SetScript("OnClick", Button_OnClick)
closebutton:SetPoint("BOTTOMRIGHT", -27, 17)
closebutton:SetHeight(20)
closebutton:SetWidth(100)
closebutton:SetText(CLOSE)
local statusbg = CreateFrame("Frame", nil, frame)
statusbg:SetPoint("BOTTOMLEFT", 15, 15)
statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
statusbg:SetHeight(24)
statusbg:SetBackdrop(PaneBackdrop)
statusbg:SetBackdropColor(0.1,0.1,0.1)
statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
statustext:SetPoint("TOPLEFT", 7, -2)
statustext:SetPoint("BOTTOMRIGHT", -7, 2)
statustext:SetHeight(20)
statustext:SetJustifyH("LEFT")
statustext:SetText("")
local titlebg = frame:CreateTexture(nil, "OVERLAY")
titlebg:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg:SetTexCoord(0.31, 0.67, 0, 0.63)
titlebg:SetPoint("TOP", 0, 12)
titlebg:SetWidth(100)
titlebg:SetHeight(40)
local title = CreateFrame("Frame", nil, frame)
title:EnableMouse(true)
title:SetScript("OnMouseDown", Title_OnMouseDown)
title:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
title:SetAllPoints(titlebg)
local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal")
titletext:SetPoint("TOP", titlebg, "TOP", 0, -14)
local titlebg_l = frame:CreateTexture(nil, "OVERLAY")
titlebg_l:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63)
titlebg_l:SetPoint("RIGHT", titlebg, "LEFT")
titlebg_l:SetWidth(30)
titlebg_l:SetHeight(40)
local titlebg_r = frame:CreateTexture(nil, "OVERLAY")
titlebg_r:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63)
titlebg_r:SetPoint("LEFT", titlebg, "RIGHT")
titlebg_r:SetWidth(30)
titlebg_r:SetHeight(40)
local sizer_se = CreateFrame("Frame", nil, frame)
sizer_se:SetPoint("BOTTOMRIGHT")
sizer_se:SetWidth(25)
sizer_se:SetHeight(25)
sizer_se:EnableMouse()
sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown)
sizer_se:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
line1:SetWidth(14)
line1:SetHeight(14)
line1:SetPoint("BOTTOMRIGHT", -8, 8)
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 14/17
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
line2:SetWidth(8)
line2:SetHeight(8)
line2:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 8/17
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local sizer_s = CreateFrame("Frame", nil, frame)
sizer_s:SetPoint("BOTTOMRIGHT", -25, 0)
sizer_s:SetPoint("BOTTOMLEFT")
sizer_s:SetHeight(25)
sizer_s:EnableMouse(true)
sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown)
sizer_s:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
local sizer_e = CreateFrame("Frame", nil, frame)
sizer_e:SetPoint("BOTTOMRIGHT", 0, 25)
sizer_e:SetPoint("TOPRIGHT")
sizer_e:SetWidth(25)
sizer_e:EnableMouse(true)
sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown)
sizer_e:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
--Container Support
local content = CreateFrame("Frame", nil, frame)
content:SetPoint("TOPLEFT", 17, -27)
content:SetPoint("BOTTOMRIGHT", -17, 40)
local widget = {
localstatus = {},
titletext = titletext,
statustext = statustext,
content = content,
frame = frame,
type = Type
}
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,138 @@
local AceGUI = LibStub("AceGUI-3.0")
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Inline Group --
--------------------------
--[[
This is a simple grouping container, no selection
It will resize automatically to the height of the controls added to it
]]
do
local Type = "InlineGroup"
local Version = 6
local function OnAcquire(self)
self:SetWidth(300)
self:SetHeight(100)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
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 SetTitle(self,title)
self.titletext:SetText(title)
end
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 40)
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 20
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.frame = frame
self.LayoutFinished = LayoutFinished
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",14,0)
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-14,0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
self.titletext = titletext
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-17)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-1,3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,241 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local pairs, assert, type = pairs, assert, type
local min, max, floor = math.min, math.max, math.floor
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Scroll Frame --
--------------------------
do
local Type = "ScrollFrame"
local Version = 9
local function OnAcquire(self)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.status = nil
-- do SetScroll after niling status, but before clearing localstatus
-- so the scroll value isnt populated back into status, but not kept in localstatus either
self:SetScroll(0)
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0)
self.scrollbar:Hide()
self.scrollBarShown = nil
self.content.height, self.content.width = nil, nil
end
local function SetScroll(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", self.scrollframe, "TOPLEFT", 0, offset)
self.content:SetPoint("TOPRIGHT", self.scrollframe, "TOPRIGHT", 0, offset)
status.offset = offset
status.scrollvalue = value
end
local function MoveScroll(self, value)
local status = self.status or self.localstatus
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
if height > viewheight then
self.scrollbar:Hide()
else
self.scrollbar:Show()
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
local function FixScroll(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()
if viewheight < height then
if self.scrollBarShown then
self.scrollBarShown = nil
self.scrollbar:Hide()
self.scrollbar:SetValue(0)
self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0)
self:DoLayout()
end
else
if not self.scrollBarShown then
self.scrollBarShown = true
self.scrollbar:Show()
self.scrollframe:SetPoint("BOTTOMRIGHT", self.frame,"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", self.scrollframe, "TOPLEFT", 0, offset)
self.content:SetPoint("TOPRIGHT", self.scrollframe, "TOPRIGHT", 0, offset)
status.offset = offset
end
end
self.updateLock = nil
end
local function OnMouseWheel(this, value)
this.obj:MoveScroll(value)
end
local function OnScrollValueChanged(this, value)
this.obj:SetScroll(value)
end
local function FixScrollOnUpdate(this)
this:SetScript("OnUpdate", nil)
this.obj:FixScroll()
end
local function OnSizeChanged(this)
this:SetScript("OnUpdate", FixScrollOnUpdate)
end
local function LayoutFinished(self, width, height)
self.content:SetHeight(height or 0 + 20)
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
if not status.scrollvalue then
status.scrollvalue = 0
end
end
local function OnWidthSet(self, width)
local content = self.content
content.width = width
end
local function OnHeightSet(self, height)
local content = self.content
content.height = height
end
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.MoveScroll = MoveScroll
self.FixScroll = FixScroll
self.SetScroll = SetScroll
self.LayoutFinished = LayoutFinished
self.SetStatusTable = SetStatusTable
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.localstatus = {}
self.frame = frame
frame.obj = self
--Container Support
local scrollframe = CreateFrame("ScrollFrame", nil, frame)
scrollframe.obj = self
scrollframe:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
scrollframe:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
scrollframe:EnableMouseWheel(true)
scrollframe:SetScript("OnMouseWheel", OnMouseWheel)
scrollframe:SetScript("OnSizeChanged", OnSizeChanged)
self.scrollframe = scrollframe
local content = CreateFrame("Frame", nil, scrollframe)
content.obj = self
content:SetPoint("TOPLEFT", scrollframe, "TOPLEFT", 0, 0)
content:SetPoint("TOPRIGHT", scrollframe, "TOPRIGHT", 0, 0)
content:SetHeight(400)
self.content = content
scrollframe:SetScrollChild(content)
local num = AceGUI:GetNextWidgetNum(Type)
local name = ("AceConfigDialogScrollFrame%dScrollBar"):format(num)
local scrollbar = CreateFrame("Slider", name, scrollframe, "UIPanelScrollBarTemplate")
scrollbar.obj = self
scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
scrollbar:SetMinMaxValues(0, 1000)
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
scrollbar:Hide()
self.scrollbar = scrollbar
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetTexture(0, 0, 0, 0.4)
self.localstatus.scrollvalue = 0
--self:FixScroll()
AceGUI:RegisterAsContainer(self)
--AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,99 @@
local AceGUI = LibStub("AceGUI-3.0")
-- WoW APIs
local CreateFrame, UIParent = CreateFrame, UIParent
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Simple Group --
--------------------------
--[[
This is a simple grouping container, no selection, no borders
It will resize automatically to the height of the controls added to it
]]
do
local Type = "SimpleGroup"
local Version = 5
local function OnAcquire(self)
self:SetWidth(300)
self:SetHeight(100)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight(height or 0)
end
local function OnWidthSet(self, width)
local content = self.content
content:SetWidth(width)
content.width = width
end
local function OnHeightSet(self, height)
local content = self.content
content:SetHeight(height)
content.height = height
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.frame = frame
self.LayoutFinished = LayoutFinished
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,389 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local pairs, ipairs, assert, type = pairs, ipairs, assert, type
-- WoW APIs
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
-------------
-- Widgets --
-------------
--[[
Widgets must provide the following functions
Acquire() - Called when the object is aquired, should set everything to a default hidden state
Release() - Called when the object is Released, should remove any anchors and hide the Widget
And the following members
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
type - the type of the object, same as the name given to :RegisterWidget()
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
It will be cleared automatically when a widget is released
Placing values directly into a widget object should be avoided
If the Widget can act as a container for other Widgets the following
content - frame or derivitive that children will be anchored to
The Widget can supply the following Optional Members
]]
--------------------------
-- Tab Group --
--------------------------
do
local Type = "TabGroup"
local Version = 25
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 OnAcquire(self)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
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
self:SetTitle()
end
local function Tab_SetText(self, text)
self:_SetText(text)
local width = self.obj.frame.width or self.obj.frame:GetWidth() or 0
PanelTemplates_TabResize(self, 0, nil, width)
end
local function UpdateTabLook(self)
if self.disabled then
PanelTemplates_SetDisabledTabState(self)
elseif self.selected then
PanelTemplates_SelectTab(self)
else
PanelTemplates_DeselectTab(self)
end
end
local function Tab_SetSelected(self, selected)
self.selected = selected
UpdateTabLook(self)
end
local function Tab_OnClick(self)
if not (self.selected or self.disabled) then
PlaySound("igCharacterInfoTab")
self.obj:SelectTab(self.value)
end
end
local function Tab_SetDisabled(self, disabled)
self.disabled = disabled
UpdateTabLook(self)
end
local function Tab_OnEnter(this)
local self = this.obj
self:Fire("OnTabEnter", self.tabs[this.id].value, this)
end
local function Tab_OnLeave(this)
local self = this.obj
self:Fire("OnTabLeave", self.tabs[this.id].value, this)
end
local function Tab_OnShow(this)
_G[this:GetName().."HighlightTexture"]:SetWidth(this:GetTextWidth() + 30)
end
local function CreateTab(self, id)
local tabname = "AceGUITabGroup"..self.num.."Tab"..id
local tab = CreateFrame("Button",tabname,self.border,"OptionsFrameTabButtonTemplate")
tab.obj = self
tab.id = id
tab.text = _G[tabname .. "Text"]
tab.text:ClearAllPoints()
tab.text:SetPoint("LEFT", tab, "LEFT", 14, -3)
tab.text:SetPoint("RIGHT", tab, "RIGHT", -12, -3)
tab:SetScript("OnClick",Tab_OnClick)
tab:SetScript("OnEnter",Tab_OnEnter)
tab:SetScript("OnLeave",Tab_OnLeave)
tab:SetScript("OnShow", Tab_OnShow)
tab._SetText = tab.SetText
tab.SetText = Tab_SetText
tab.SetSelected = Tab_SetSelected
tab.SetDisabled = Tab_SetDisabled
return tab
end
local function SetTitle(self, text)
self.titletext:SetText(text or "")
if text and text ~= "" then
self.alignoffset = 25
else
self.alignoffset = 18
end
self:BuildTabs()
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
end
local function SelectTab(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
local function SetTabs(self, tabs)
self.tablist = tabs
self:BuildTabs()
end
local widths = {}
local rowwidths = {}
local rowends = {}
local function BuildTabs(self)
local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
local status = self.status or self.localstatus
local tablist = self.tablist
local tabs = self.tabs
if not tablist then return end
local width = self.frame.width or self.frame:GetWidth() or 0
for i = #widths, 1, -1 do
widths[i] = nil
end
for i = #rowwidths, 1, -1 do
rowwidths[i] = nil
end
for i = #rowends, 1, -1 do
rowends[i] = nil
end
--Place Text into tabs and get thier initial width
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
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
end
for i = (#tablist)+1, #tabs, 1 do
tabs[i]:Hide()
end
--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
local numtabs = #tablist
local numrows = 1
local usedwidth = 0
for i = 1, #tablist do
--If this is not the first tab of a row and there isn't room for it
if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = i - 1
numrows = numrows + 1
usedwidth = 0
end
usedwidth = usedwidth + widths[i]
end
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
rowends[numrows] = #tablist
--Fix for single tabs being left on the last row, move a tab from the row above if applicable
if numrows > 1 then
--if the last row has only one tab
if rowends[numrows-1] == numtabs-1 then
--if there are more than 2 tabs in the 2nd last row
if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
--move 1 tab from the second last row to the last, if there is enough space
if (rowwidths[numrows] + widths[numtabs-1]) <= width then
rowends[numrows-1] = rowends[numrows-1] - 1
rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
end
end
end
end
--anchor the rows as defined and resize tabs to fill thier row
local starttab = 1
for row, endtab in ipairs(rowends) do
local first = true
for tabno = starttab, endtab do
local tab = tabs[tabno]
tab:ClearAllPoints()
if first then
tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
first = false
else
tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
end
end
-- equal padding for each tab to fill the available width,
-- if the used space is above 75% already
local padding = 0
if not (numrows == 1 and rowwidths[1] < width*0.75) then
padding = (width - rowwidths[row]) / (endtab - starttab+1)
end
for i = starttab, endtab do
PanelTemplates_TabResize(tabs[i], padding + 4, nil, width)
end
starttab = endtab + 1
end
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
self.border:SetPoint("TOPLEFT",self.frame,"TOPLEFT",1,-self.borderoffset)
end
local function BuildTabsOnUpdate(this)
BuildTabs(this.obj)
this:SetScript("OnUpdate", nil)
end
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 60
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
BuildTabs(self)
self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - (self.borderoffset + 23)
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + (self.borderoffset + 23))
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.num = AceGUI:GetNextWidgetNum(Type)
self.localstatus = {}
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTitle = SetTitle
self.CreateTab = CreateTab
self.SelectTab = SelectTab
self.BuildTabs = BuildTabs
self.SetStatusTable = SetStatusTable
self.SetTabs = SetTabs
self.LayoutFinished = LayoutFinished
self.frame = frame
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
frame.obj = self
frame:SetHeight(100)
frame:SetWidth(100)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
self.alignoffset = 18
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",14,0)
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-14,0)
titletext:SetJustifyH("LEFT")
titletext:SetHeight(18)
titletext:SetText("")
self.titletext = titletext
local border = CreateFrame("Frame",nil,frame)
self.border = border
self.borderoffset = 27
border:SetPoint("TOPLEFT",frame,"TOPLEFT",1,-27)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-1,3)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
self.tabs = {}
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-7)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,7)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,746 @@
local AceGUI = LibStub("AceGUI-3.0")
-- 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 = select, table.remove, unpack
-- 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: GameTooltip, FONT_COLOR_CODE_CLOSE
-- 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
--------------
-- TreeView --
--------------
do
local Type = "TreeGroup"
local Version = 23
local DEFAULT_TREE_WIDTH = 175
local DEFAULT_TREE_SIZABLE = true
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 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 OnAcquire(self)
self:SetTreeWidth(DEFAULT_TREE_WIDTH,DEFAULT_TREE_SIZABLE)
self:EnableButtonTooltips(true)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
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
local function GetButtonParents(line)
local parent = line.parent
if parent and parent.value then
return parent.value, GetButtonParents(parent)
end
end
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 ButtonOnClick(this)
local self = this.obj
self:Fire("OnClick",this.uniquevalue, this.selected)
if not this.selected then
self:SetSelected(this.uniquevalue)
this.selected = true
this:LockHighlight()
self:RefreshTree()
end
AceGUI:ClearFocus()
end
local function ExpandOnClick(this)
local button = this.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 ButtonOnDoubleClick(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 EnableButtonTooltips(self, enable)
self.enabletooltips = enable
end
local function Button_OnEnter(this)
local self = this.obj
self:Fire("OnButtonEnter", this.uniquevalue, this)
if self.enabletooltips then
GameTooltip:SetOwner(this, "ANCHOR_NONE")
GameTooltip:SetPoint("LEFT",this,"RIGHT")
GameTooltip:SetText(this.text:GetText() or "", 1, .82, 0, 1)
GameTooltip:Show()
end
end
local function Button_OnLeave(this)
local self = this.obj
self:Fire("OnButtonLeave", this.uniquevalue, this)
if self.enabletooltips then
GameTooltip:Hide()
end
end
local buttoncount = 1
local function CreateButton(self)
local button = CreateFrame("Button",("AceGUI30TreeButton%d"):format(buttoncount),self.treeframe, "OptionsListButtonTemplate")
buttoncount = buttoncount + 1
button.obj = self
local icon = button:CreateTexture(nil, "OVERLAY")
icon:SetWidth(14)
icon:SetHeight(14)
button.icon = icon
button:SetScript("OnClick",ButtonOnClick)
button:SetScript("OnDoubleClick", ButtonOnDoubleClick)
button:SetScript("OnEnter",Button_OnEnter)
button:SetScript("OnLeave",Button_OnLeave)
button.toggle.button = button
button.toggle:SetScript("OnClick",ExpandOnClick)
return button
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:SetNormalFontObject("GameFontNormal")
button:SetHighlightFontObject("GameFontHighlight")
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
else
button:SetNormalFontObject("GameFontHighlightSmall")
button:SetHighlightFontObject("GameFontHighlightSmall")
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", button, "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:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
else
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
end
toggle:Show()
else
toggle:Hide()
end
end
local function OnScrollValueChanged(this, value)
if this.obj.noupdate then return end
local self = this.obj
local status = self.status or self.localstatus
status.scrollvalue = value
self:RefreshTree()
AceGUI:ClearFocus()
end
-- called to set an external table to store status in
local function SetStatusTable(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 not status.treesizable then
status.treesizable = DEFAULT_TREE_SIZABLE
end
self:SetTreeWidth(status.treewidth,status.treesizable)
self:RefreshTree()
end
--sets the tree to be displayed
--[[
example tree
Alpha
Bravo
-Charlie
-Delta
-Echo
Foxtrot
tree = {
{
value = "A",
text = "Alpha"
},
{
value = "B",
text = "Bravo",
children = {
{
value = "C",
text = "Charlie"
},
{
value = "D",
text = "Delta"
children = {
{
value = "E",
text = "Echo"
}
}
}
}
},
{
value = "F",
text = "Foxtrot"
},
}
]]
local function SetTree(self, tree, filter)
self.filter = filter
if tree then
assert(type(tree) == "table")
end
self.tree = tree
self:RefreshTree()
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
local function BuildLevel(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
--fire an update after one frame to catch the treeframes height
local function FirstFrameUpdate(this)
local self = this.obj
this:SetScript("OnUpdate",nil)
self:RefreshTree()
end
local function ResizeUpdate(this)
this.obj:RefreshTree()
end
local function RefreshTree(self)
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
self:BuildLevel(tree, 1)
local numlines = #lines
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
local first, last
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
self.scrollbar:SetValue(status.scrollvalue)
end
self.noupdate = nil
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
end
local buttonnum = 1
for i = first, last 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 i == 1 then
if self.showscroll then
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
else
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
button:SetPoint("TOPLEFT", self.treeframe, "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
local function SetSelected(self, value)
local status = self.status or self.localstatus
if status.selected ~= value then
status.selected = value
self:Fire("OnGroupSelected", value)
end
end
local function BuildUniqueValue(...)
local n = select('#', ...)
if n == 1 then
return ...
else
return (...).."\001"..BuildUniqueValue(select(2,...))
end
end
local function Select(self, uniquevalue, ...)
self.filter = false
local status = self.status or self.localstatus
local groups = status.groups
for i = 1, select('#', ...) do
groups[BuildUniqueValue(select(i, ...))] = true
end
status.selected = uniquevalue
self:RefreshTree()
self:Fire("OnGroupSelected", uniquevalue)
end
local function SelectByPath(self, ...)
self:Select(BuildUniqueValue(...), ...)
end
--Selects a tree node by UniqueValue
local function SelectByValue(self, uniquevalue)
self:Select(uniquevalue, ("\001"):split(uniquevalue))
end
local function ShowScroll(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
local function OnWidthSet(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
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 20
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function TreeOnMouseWheel(this, delta)
local self = this.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 SetTreeWidth(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
local function draggerLeave(this)
this:SetBackdropColor(1, 1, 1, 0)
end
local function draggerEnter(this)
this:SetBackdropColor(1, 1, 1, 0.8)
end
local function draggerDown(this)
local treeframe = this:GetParent()
treeframe:StartSizing("RIGHT")
end
local function draggerUp(this)
local treeframe = this:GetParent()
local self = treeframe.obj
local frame = treeframe:GetParent()
treeframe:StopMovingOrSizing()
--treeframe:SetScript("OnUpdate", nil)
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
local function LayoutFinished(self, width, height)
if self.noAutoHeight then return end
self:SetHeight((height or 0) + 20)
end
local createdcount = 0
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.lines = {}
self.levels = {}
self.buttons = {}
self.hasChildren = {}
self.localstatus = {}
self.localstatus.groups = {}
self.filter = false
local treeframe = CreateFrame("Frame",nil,frame)
treeframe.obj = self
treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
treeframe:SetScript("OnUpdate",FirstFrameUpdate)
treeframe:SetScript("OnSizeChanged",ResizeUpdate)
treeframe:EnableMouseWheel(true)
treeframe:SetScript("OnMouseWheel", TreeOnMouseWheel)
treeframe:SetBackdrop(PaneBackdrop)
treeframe:SetBackdropColor(0.1,0.1,0.1,0.5)
treeframe:SetBackdropBorderColor(0.4,0.4,0.4)
treeframe:SetResizable(true)
treeframe:SetMinResize(100, 1)
treeframe:SetMaxResize(400,1600)
local dragger = CreateFrame("Frame", nil, treeframe)
dragger:SetWidth(8)
dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
dragger:SetBackdrop(DraggerBackdrop)
dragger:SetBackdropColor(1, 1, 1, 0)
dragger:SetScript("OnMouseDown", draggerDown)
dragger:SetScript("OnMouseUp", draggerUp)
dragger:SetScript("OnEnter", draggerEnter)
dragger:SetScript("OnLeave", draggerLeave)
self.dragger = dragger
self.treeframe = treeframe
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetTree = SetTree
self.SetTreeWidth = SetTreeWidth
self.RefreshTree = RefreshTree
self.SetStatusTable = SetStatusTable
self.BuildLevel = BuildLevel
self.CreateButton = CreateButton
self.SetSelected = SetSelected
self.ShowScroll = ShowScroll
self.SetStatusTable = SetStatusTable
self.Select = Select
self.SelectByValue = SelectByValue
self.SelectByPath = SelectByPath
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.EnableButtonTooltips = EnableButtonTooltips
--self.Filter = Filter
self.LayoutFinished = LayoutFinished
self.frame = frame
frame.obj = self
createdcount = createdcount + 1
local scrollbar = CreateFrame("Slider",("AceConfigDialogTreeGroup%dScrollBar"):format(createdcount),treeframe,"UIPanelScrollBarTemplate")
self.scrollbar = scrollbar
local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
scrollbg:SetAllPoints(scrollbar)
scrollbg:SetTexture(0,0,0,0.4)
scrollbar.obj = self
self.noupdate = true
scrollbar:SetPoint("TOPRIGHT",treeframe,"TOPRIGHT",-10,-26)
scrollbar:SetPoint("BOTTOMRIGHT",treeframe,"BOTTOMRIGHT",-10,26)
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
scrollbar:SetMinMaxValues(0,0)
self.localstatus.scrollvalue = 0
scrollbar:SetValueStep(1)
scrollbar:SetValue(0)
scrollbar:SetWidth(16)
self.noupdate = nil
local border = CreateFrame("Frame",nil,frame)
self.border = border
border:SetPoint("TOPLEFT",treeframe,"TOPRIGHT", 0,0)
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
border:SetBackdrop(PaneBackdrop)
border:SetBackdropColor(0.1,0.1,0.1,0.5)
border:SetBackdropBorderColor(0.4,0.4,0.4)
--Container Support
local content = CreateFrame("Frame",nil,border)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
AceGUI:RegisterAsContainer(self)
--AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,331 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local pairs, assert, type = pairs, assert, type
-- WoW APIs
local PlaySound = PlaySound
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: GameFontNormal
----------------
-- Main Frame --
----------------
--[[
Events :
OnClose
]]
do
local Type = "Window"
local Version = 4
local function frameOnClose(this)
this.obj:Fire("OnClose")
end
local function closeOnClick(this)
PlaySound("gsTitleOptionExit")
this.obj:Hide()
end
local function frameOnMouseDown(this)
AceGUI:ClearFocus()
end
local function titleOnMouseDown(this)
this:GetParent():StartMoving()
AceGUI:ClearFocus()
end
local function frameOnMouseUp(this)
local frame = this:GetParent()
frame:StopMovingOrSizing()
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 sizerseOnMouseDown(this)
this:GetParent():StartSizing("BOTTOMRIGHT")
AceGUI:ClearFocus()
end
local function sizersOnMouseDown(this)
this:GetParent():StartSizing("BOTTOM")
AceGUI:ClearFocus()
end
local function sizereOnMouseDown(this)
this:GetParent():StartSizing("RIGHT")
AceGUI:ClearFocus()
end
local function sizerOnMouseUp(this)
this:GetParent():StopMovingOrSizing()
end
local function SetTitle(self,title)
self.titletext:SetText(title)
end
local function SetStatusText(self,text)
-- self.statustext:SetText(text)
end
local function Hide(self)
self.frame:Hide()
end
local function Show(self)
self.frame:Show()
end
local function OnAcquire(self)
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
self:ApplyStatus()
self:EnableResize(true)
self:Show()
end
local function OnRelease(self)
self.status = nil
for k in pairs(self.localstatus) do
self.localstatus[k] = nil
end
end
-- called to set an external table to store status in
local function SetStatusTable(self, status)
assert(type(status) == "table")
self.status = status
self:ApplyStatus()
end
local function ApplyStatus(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
local function OnWidthSet(self, width)
local content = self.content
local contentwidth = width - 34
if contentwidth < 0 then
contentwidth = 0
end
content:SetWidth(contentwidth)
content.width = contentwidth
end
local function OnHeightSet(self, height)
local content = self.content
local contentheight = height - 57
if contentheight < 0 then
contentheight = 0
end
content:SetHeight(contentheight)
content.height = contentheight
end
local function EnableResize(self, state)
local func = state and "Show" or "Hide"
self.sizer_se[func](self.sizer_se)
self.sizer_s[func](self.sizer_s)
self.sizer_e[func](self.sizer_e)
end
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = "Window"
self.Hide = Hide
self.Show = Show
self.SetTitle = SetTitle
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetStatusText = SetStatusText
self.SetStatusTable = SetStatusTable
self.ApplyStatus = ApplyStatus
self.OnWidthSet = OnWidthSet
self.OnHeightSet = OnHeightSet
self.EnableResize = EnableResize
self.localstatus = {}
self.frame = frame
frame.obj = self
frame:SetWidth(700)
frame:SetHeight(500)
frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
frame:EnableMouse()
frame:SetMovable(true)
frame:SetResizable(true)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetScript("OnMouseDown", frameOnMouseDown)
frame:SetScript("OnHide",frameOnClose)
frame:SetMinResize(240,240)
frame:SetToplevel(true)
local titlebg = frame:CreateTexture(nil, "BACKGROUND")
titlebg:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Title-Background]])
titlebg:SetPoint("TOPLEFT", 9, -6)
titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24)
local dialogbg = frame:CreateTexture(nil, "BACKGROUND")
dialogbg:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]])
dialogbg:SetPoint("TOPLEFT", 8, -24)
dialogbg:SetPoint("BOTTOMRIGHT", -6, 8)
dialogbg:SetVertexColor(0, 0, 0, .75)
local topleft = frame:CreateTexture(nil, "BORDER")
topleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
topleft:SetWidth(64)
topleft:SetHeight(64)
topleft:SetPoint("TOPLEFT")
topleft:SetTexCoord(0.501953125, 0.625, 0, 1)
local topright = frame:CreateTexture(nil, "BORDER")
topright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
topright:SetWidth(64)
topright:SetHeight(64)
topright:SetPoint("TOPRIGHT")
topright:SetTexCoord(0.625, 0.75, 0, 1)
local top = frame:CreateTexture(nil, "BORDER")
top:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
top:SetHeight(64)
top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
top:SetTexCoord(0.25, 0.369140625, 0, 1)
local bottomleft = frame:CreateTexture(nil, "BORDER")
bottomleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
bottomleft:SetWidth(64)
bottomleft:SetHeight(64)
bottomleft:SetPoint("BOTTOMLEFT")
bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1)
local bottomright = frame:CreateTexture(nil, "BORDER")
bottomright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
bottomright:SetWidth(64)
bottomright:SetHeight(64)
bottomright:SetPoint("BOTTOMRIGHT")
bottomright:SetTexCoord(0.875, 1, 0, 1)
local bottom = frame:CreateTexture(nil, "BORDER")
bottom:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
bottom:SetHeight(64)
bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1)
local left = frame:CreateTexture(nil, "BORDER")
left:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
left:SetWidth(64)
left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
left:SetTexCoord(0.001953125, 0.125, 0, 1)
local right = frame:CreateTexture(nil, "BORDER")
right:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
right:SetWidth(64)
right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
right:SetTexCoord(0.1171875, 0.2421875, 0, 1)
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
close:SetPoint("TOPRIGHT", 2, 1)
close:SetScript("OnClick", closeOnClick)
self.closebutton = close
close.obj = self
local titletext = frame:CreateFontString(nil, "ARTWORK")
titletext:SetFontObject(GameFontNormal)
titletext:SetPoint("TOPLEFT", 12, -8)
titletext:SetPoint("TOPRIGHT", -32, -8)
self.titletext = titletext
local title = CreateFrame("Button", nil, frame)
title:SetPoint("TOPLEFT", titlebg)
title:SetPoint("BOTTOMRIGHT", titlebg)
title:EnableMouse()
title:SetScript("OnMouseDown",titleOnMouseDown)
title:SetScript("OnMouseUp", frameOnMouseUp)
self.title = title
local sizer_se = CreateFrame("Frame",nil,frame)
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
sizer_se:SetWidth(25)
sizer_se:SetHeight(25)
sizer_se:EnableMouse()
sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_se = sizer_se
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
self.line1 = line1
line1:SetWidth(14)
line1:SetHeight(14)
line1:SetPoint("BOTTOMRIGHT", -8, 8)
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 14/17
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
self.line2 = line2
line2:SetWidth(8)
line2:SetHeight(8)
line2:SetPoint("BOTTOMRIGHT", -8, 8)
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
local x = 0.1 * 8/17
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
local sizer_s = CreateFrame("Frame",nil,frame)
sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
sizer_s:SetHeight(25)
sizer_s:EnableMouse()
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_s = sizer_s
local sizer_e = CreateFrame("Frame",nil,frame)
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
sizer_e:SetWidth(25)
sizer_e:EnableMouse()
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
self.sizer_e = sizer_e
--Container Support
local content = CreateFrame("Frame",nil,frame)
self.content = content
content.obj = self
content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32)
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13)
AceGUI:RegisterAsContainer(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,92 @@
--[[-----------------------------------------------------------------------------
Button Widget
Graphical Button.
-------------------------------------------------------------------------------]]
local Type, Version = "Button", 20
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, ...)
PlaySound("igMainMenuOption")
frame.obj:Fire("OnClick", ...)
AceGUI:ClearFocus()
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)
-- restore default values
self:SetHeight(24)
self:SetWidth(200)
self:SetDisabled(false)
self:SetText()
end,
-- ["OnRelease"] = nil,
["SetText"] = function(self, text)
self.text:SetText(text)
end,
["SetDisabled"] = function(self, disabled)
self.disabled = disabled
if disabled then
self.frame:Disable()
else
self.frame:Enable()
end
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate2")
frame:Hide()
frame:EnableMouse(true)
frame:SetScript("OnClick", Button_OnClick)
frame:SetScript("OnEnter", Control_OnEnter)
frame:SetScript("OnLeave", Control_OnLeave)
local text = frame:GetFontString()
text:ClearAllPoints()
text:SetPoint("TOPLEFT", 15, -1)
text:SetPoint("BOTTOMRIGHT", -15, 1)
text:SetJustifyV("MIDDLE")
local widget = {
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,285 @@
--[[-----------------------------------------------------------------------------
Checkbox Widget
-------------------------------------------------------------------------------]]
local Type, Version = "CheckBox", 20
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
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: SetDesaturation, GameFontHighlight
--[[-----------------------------------------------------------------------------
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.checkbg, "RIGHT", 1, -1)
end
AceGUI:ClearFocus()
end
local function CheckBox_OnMouseUp(frame)
local self = frame.obj
if not self.disabled then
self:ToggleChecked()
if self.checked then
PlaySound("igMainMenuOptionCheckBoxOn")
else -- for both nil and false (tristate)
PlaySound("igMainMenuOptionCheckBoxOff")
end
self:Fire("OnValueChanged", self.checked)
self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
end
end
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function AlignImage(self)
local img = self.image:GetTexture()
self.text:ClearAllPoints()
if not img then
self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
self.text:SetPoint("RIGHT")
else
self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0)
self.text:SetPoint("RIGHT")
end
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetType()
self:SetValue(false)
self:SetTriState(nil)
-- height is calculated from the width and required space for the description
self:SetWidth(200)
self:SetImage()
self:SetDisabled(nil)
self:SetDescription(nil)
end,
-- ["OnRelease"] = nil,
["OnWidthSet"] = function(self, width)
if self.desc then
self.desc:SetWidth(width - 30)
if self.desc:GetText() and self.desc:GetText() ~= "" then
self:SetHeight(28 + self.desc:GetHeight())
end
end
end,
["SetDisabled"] = function(self, disabled)
self.disabled = disabled
if disabled then
self.frame:Disable()
self.text:SetTextColor(0.5, 0.5, 0.5)
SetDesaturation(self.check, true)
else
self.frame:Enable()
self.text:SetTextColor(1, 1, 1)
if self.tristate and self.checked == nil then
SetDesaturation(self.check, true)
else
SetDesaturation(self.check, false)
end
end
end,
["SetValue"] = function(self,value)
local check = self.check
self.checked = value
if value then
SetDesaturation(self.check, false)
self.check:Show()
else
--Nil is the unknown tristate value
if self.tristate and value == nil then
SetDesaturation(self.check, true)
self.check:Show()
else
SetDesaturation(self.check, false)
self.check:Hide()
end
end
self:SetDisabled(self.disabled)
end,
["GetValue"] = function(self)
return self.checked
end,
["SetTriState"] = function(self, enabled)
self.tristate = enabled
self:SetValue(self:GetValue())
end,
["SetType"] = function(self, type)
local checkbg = self.checkbg
local check = self.check
local highlight = self.highlight
local size
if type == "radio" then
size = 16
checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton")
checkbg:SetTexCoord(0, 0.25, 0, 1)
check:SetTexture("Interface\\Buttons\\UI-RadioButton")
check:SetTexCoord(0.25, 0.5, 0, 1)
check:SetBlendMode("ADD")
highlight:SetTexture("Interface\\Buttons\\UI-RadioButton")
highlight:SetTexCoord(0.5, 0.75, 0, 1)
else
size = 24
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
checkbg:SetTexCoord(0, 1, 0, 1)
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
check:SetTexCoord(0, 1, 0, 1)
check:SetBlendMode("BLEND")
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
highlight:SetTexCoord(0, 1, 0, 1)
end
checkbg:SetHeight(size)
checkbg:SetWidth(size)
end,
["ToggleChecked"] = function(self)
local value = self:GetValue()
if self.tristate then
--cycle in true, nil, false order
if value then
self:SetValue(nil)
elseif value == nil then
self:SetValue(false)
else
self:SetValue(true)
end
else
self:SetValue(not self:GetValue())
end
end,
["SetLabel"] = function(self, label)
self.text:SetText(label)
end,
["SetDescription"] = function(self, desc)
if desc then
if not self.desc then
local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
desc:ClearAllPoints()
desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
desc:SetWidth(self.frame.width - 30)
desc:SetJustifyH("LEFT")
desc:SetJustifyV("TOP")
self.desc = desc
end
self.desc:Show()
--self.text:SetFontObject(GameFontNormal)
self.desc:SetText(desc)
self:SetHeight(28 + self.desc:GetHeight())
else
if self.desc then
self.desc:SetText("")
self.desc:Hide()
end
--self.text:SetFontObject(GameFontHighlight)
self:SetHeight(24)
end
end,
["SetImage"] = function(self, path, ...)
local image = self.image
image:SetTexture(path)
if image:GetTexture() then
local n = select("#", ...)
if n == 4 or n == 8 then
image:SetTexCoord(...)
else
image:SetTexCoord(0, 1, 0, 1)
end
end
AlignImage(self)
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 checkbg = frame:CreateTexture(nil, "ARTWORK")
checkbg:SetWidth(24)
checkbg:SetHeight(24)
checkbg:SetPoint("TOPLEFT")
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
local check = frame:CreateTexture(nil, "OVERLAY")
check:SetAllPoints(checkbg)
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
text:SetJustifyH("LEFT")
text:SetHeight(18)
text:SetPoint("LEFT", checkbg, "RIGHT")
text:SetPoint("RIGHT")
local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
highlight:SetBlendMode("ADD")
highlight:SetAllPoints(checkbg)
local image = frame:CreateTexture(nil, "OVERLAY")
image:SetHeight(16)
image:SetWidth(16)
image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0)
local widget = {
checkbg = checkbg,
check = check,
text = text,
highlight = highlight,
image = image,
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,186 @@
--[[-----------------------------------------------------------------------------
ColorPicker Widget
-------------------------------------------------------------------------------]]
local Type, Version = "ColorPicker", 20
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,
-- ["OnRelease"] = nil,
["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
if self.disabled then
self.frame:Disable()
self.text:SetTextColor(0.5, 0.5, 0.5)
else
self.frame:Enable()
self.text:SetTextColor(1, 1, 1)
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","GameFontHighlight")
text:SetHeight(24)
text:SetJustifyH("LEFT")
text:SetTextColor(1, 1, 1)
text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
text:SetPoint("RIGHT")
--local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
--highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
--highlight:SetBlendMode("ADD")
--highlight:SetAllPoints(frame)
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,465 @@
--[[ $Id: AceGUIWidget-DropDown-Items.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]--
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local select, assert = select, assert
-- WoW APIs
local PlaySound = PlaySound
local CreateFrame = CreateFrame
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
-- ItemBase is the base "class" for all dropdown items.
-- Each item has to use ItemBase.Create(widgetType) to
-- create an initial 'self' value.
-- ItemBase will add common functions and ui event handlers.
-- Be sure to keep basic usage when you override functions.
local ItemBase = {
-- NOTE: The ItemBase version is added to each item's version number
-- to ensure proper updates on ItemBase changes.
-- Use at least 1000er steps.
version = 1000,
counter = 0,
}
function ItemBase.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
function ItemBase.Frame_OnLeave(this)
local self = this.obj
self.highlight:Hide()
self:Fire("OnLeave")
if self.specialOnLeave then
self.specialOnLeave(self)
end
end
-- exported, AceGUI callback
function ItemBase.OnAcquire(self)
self.frame:SetToplevel(true)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
end
-- exported, AceGUI callback
function ItemBase.OnRelease(self)
self:SetDisabled(false)
self.pullout = nil
self.frame:SetParent(nil)
self.frame:ClearAllPoints()
self.frame:Hide()
end
-- exported
-- NOTE: this is called by a Dropdown-Pullout.
-- Do not call this method directly
function ItemBase.SetPullout(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
-- exported
function ItemBase.SetText(self, text)
self.text:SetText(text or "")
end
-- exported
function ItemBase.GetText(self)
return self.text:GetText()
end
-- exported
function ItemBase.SetPoint(self, ...)
self.frame:SetPoint(...)
end
-- exported
function ItemBase.Show(self)
self.frame:Show()
end
-- exported
function ItemBase.Hide(self)
self.frame:Hide()
end
-- exported
function ItemBase.SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.useHighlight = false
self.text:SetTextColor(.5, .5, .5)
else
self.useHighlight = true
self.text:SetTextColor(1, 1, 1)
end
end
-- exported
-- NOTE: this is called by a Dropdown-Pullout.
-- Do not call this method directly
function ItemBase.SetOnLeave(self, func)
self.specialOnLeave = func
end
-- exported
-- NOTE: this is called by a Dropdown-Pullout.
-- Do not call this method directly
function ItemBase.SetOnEnter(self, func)
self.specialOnEnter = func
end
function ItemBase.Create(type)
-- NOTE: Most of the following code is copied from AceGUI-3.0/Dropdown widget
local count = AceGUI:GetNextWidgetNum(type)
local frame = CreateFrame("Button", "AceGUI30DropDownItem"..count)
local self = {}
self.frame = frame
frame.obj = self
self.type = type
self.useHighlight = true
frame:SetHeight(17)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
text:SetTextColor(1,1,1)
text:SetJustifyH("LEFT")
text:SetPoint("TOPLEFT",frame,"TOPLEFT",18,0)
text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-8,0)
self.text = text
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()
self.highlight = highlight
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()
self.check = check
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()
self.sub = sub
frame:SetScript("OnEnter", ItemBase.Frame_OnEnter)
frame:SetScript("OnLeave", ItemBase.Frame_OnLeave)
self.OnAcquire = ItemBase.OnAcquire
self.OnRelease = ItemBase.OnRelease
self.SetPullout = ItemBase.SetPullout
self.GetText = ItemBase.GetText
self.SetText = ItemBase.SetText
self.SetDisabled = ItemBase.SetDisabled
self.SetPoint = ItemBase.SetPoint
self.Show = ItemBase.Show
self.Hide = ItemBase.Hide
self.SetOnLeave = ItemBase.SetOnLeave
self.SetOnEnter = ItemBase.SetOnEnter
return self
end
--[[
Template for items:
-- Item:
--
do
local widgetType = "Dropdown-Item-"
local widgetVersion = 1
local function Constructor()
local self = ItemBase.Create(widgetType)
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
--]]
-- Item: Header
-- A single text entry.
-- Special: Different text color and no highlight
do
local widgetType = "Dropdown-Item-Header"
local widgetVersion = 1
local function OnEnter(this)
local self = this.obj
self:Fire("OnEnter")
if self.specialOnEnter then
self.specialOnEnter(self)
end
end
local function OnLeave(this)
local self = this.obj
self:Fire("OnLeave")
if self.specialOnLeave then
self.specialOnLeave(self)
end
end
-- exported, override
local function SetDisabled(self, disabled)
ItemBase.SetDisabled(self, disabled)
if not disabled then
self.text:SetTextColor(1, 1, 0)
end
end
local function Constructor()
local self = ItemBase.Create(widgetType)
self.SetDisabled = SetDisabled
self.frame:SetScript("OnEnter", OnEnter)
self.frame:SetScript("OnLeave", OnLeave)
self.text:SetTextColor(1, 1, 0)
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
-- Item: Execute
-- A simple button
do
local widgetType = "Dropdown-Item-Execute"
local widgetVersion = 1
local function Frame_OnClick(this, button)
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 self = ItemBase.Create(widgetType)
self.frame:SetScript("OnClick", Frame_OnClick)
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
-- Item: Toggle
-- Some sort of checkbox for dropdown menus.
-- Does not close the pullout on click.
do
local widgetType = "Dropdown-Item-Toggle"
local widgetVersion = 3
local function UpdateToggle(self)
if self.value then
self.check:Show()
else
self.check:Hide()
end
end
local function OnRelease(self)
ItemBase.OnRelease(self)
self:SetValue(nil)
end
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
UpdateToggle(self)
self:Fire("OnValueChanged", self.value)
end
-- exported
local function SetValue(self, value)
self.value = value
UpdateToggle(self)
end
-- exported
local function GetValue(self)
return self.value
end
local function Constructor()
local self = ItemBase.Create(widgetType)
self.frame:SetScript("OnClick", Frame_OnClick)
self.SetValue = SetValue
self.GetValue = GetValue
self.OnRelease = OnRelease
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
-- Item: Menu
-- Shows a submenu on mouse over
-- Does not close the pullout on click
do
local widgetType = "Dropdown-Item-Menu"
local widgetVersion = 2
local function OnEnter(this)
local self = this.obj
self:Fire("OnEnter")
if self.specialOnEnter then
self.specialOnEnter(self)
end
self.highlight:Show()
if not self.disabled and self.submenu then
self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100)
end
end
local function OnHide(this)
local self = this.obj
if self.submenu then
self.submenu:Close()
end
end
-- exported
local function SetMenu(self, menu)
assert(menu.type == "Dropdown-Pullout")
self.submenu = menu
end
-- exported
local function CloseMenu(self)
self.submenu:Close()
end
local function Constructor()
local self = ItemBase.Create(widgetType)
self.sub:Show()
self.frame:SetScript("OnEnter", OnEnter)
self.frame:SetScript("OnHide", OnHide)
self.SetMenu = SetMenu
self.CloseMenu = CloseMenu
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
-- Item: Separator
-- A single line to separate items
do
local widgetType = "Dropdown-Item-Separator"
local widgetVersion = 1
-- exported, override
local function SetDisabled(self, disabled)
ItemBase.SetDisabled(self, disabled)
self.useHighlight = false
end
local function Constructor()
local self = ItemBase.Create(widgetType)
self.SetDisabled = SetDisabled
local line = self.frame:CreateTexture(nil, "OVERLAY")
line:SetHeight(1)
line:SetTexture(.5, .5, .5)
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
self.text:Hide()
self.useHighlight = false
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
end
@@ -0,0 +1,707 @@
--[[ $Id: AceGUIWidget-DropDown.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]--
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local min, max, floor = math.min, math.max, math.floor
local select, pairs, ipairs = select, pairs, ipairs
local tsort = table.sort
-- WoW APIs
local PlaySound = PlaySound
local UIParent, CreateFrame = UIParent, CreateFrame
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: CLOSE
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
do
local widgetType = "Dropdown-Pullout"
local widgetVersion = 3
--[[ Static data ]]--
local backdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
edgeSize = 32,
tileSize = 32,
tile = true,
insets = { left = 11, right = 12, top = 12, bottom = 11 },
}
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 defaultWidth = 200
local defaultMaxHeight = 600
--[[ UI Event Handlers ]]--
-- HACK: This should be no part of the pullout, but there
-- is no other 'clean' way to response to any item-OnEnter
-- Used to close Submenus when an other item is entered
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
--[[ Exported methods ]]--
-- exported
local function SetScroll(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
-- exported
local function MoveScroll(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
-- exported
local function FixScroll(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
-- exported, AceGUI callback
local function OnAcquire(self)
self.frame:SetParent(UIParent)
--self.itemFrame:SetToplevel(true)
end
-- exported, AceGUI callback
local function OnRelease(self)
self:Clear()
self.frame:ClearAllPoints()
self.frame:Hide()
end
-- exported
local function AddItem(self, item)
self.items[#self.items + 1] = item
local h = #self.items * 16
self.itemFrame:SetHeight(h)
self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement
item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
item:SetPullout(self)
item:SetOnEnter(OnEnter)
end
-- exported
local function Open(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
-- exported
local function Close(self)
self.frame:Hide()
self:Fire("OnClose")
end
-- exported
local function Clear(self)
local items = self.items
for i, item in pairs(items) do
AceGUI:Release(item)
items[i] = nil
end
end
-- exported
local function IterateItems(self)
return ipairs(self.items)
end
-- exported
local function SetHideOnLeave(self, val)
self.hideOnLeave = val
end
-- exported
local function SetMaxHeight(self, height)
self.maxHeight = height or defaultMaxHeight
if self.frame:GetHeight() > height then
self.frame:SetHeight(height)
elseif (self.itemFrame:GetHeight() + 34) < height then
self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem
end
end
-- exported
local function GetRightBorderWidth(self)
return 6 + (self.slider:IsShown() and 12 or 0)
end
-- exported
local function GetLeftBorderWidth(self)
return 6
end
--[[ Constructor ]]--
local function Constructor()
local count = AceGUI:GetNextWidgetNum(widgetType)
local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent)
local self = {}
self.count = count
self.type = widgetType
self.frame = frame
frame.obj = self
self.OnAcquire = OnAcquire
self.OnRelease = OnRelease
self.AddItem = AddItem
self.Open = Open
self.Close = Close
self.Clear = Clear
self.IterateItems = IterateItems
self.SetHideOnLeave = SetHideOnLeave
self.SetScroll = SetScroll
self.MoveScroll = MoveScroll
self.FixScroll = FixScroll
self.SetMaxHeight = SetMaxHeight
self.GetRightBorderWidth = GetRightBorderWidth
self.GetLeftBorderWidth = GetLeftBorderWidth
self.items = {}
self.scrollStatus = {
scrollvalue = 0,
}
self.maxHeight = defaultMaxHeight
frame:SetBackdrop(backdrop)
frame:SetBackdropColor(0, 0, 0)
frame:SetFrameStrata("FULLSCREEN_DIALOG")
frame:SetClampedToScreen(true)
frame:SetWidth(defaultWidth)
frame:SetHeight(self.maxHeight)
--frame:SetToplevel(true)
-- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame
local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
local itemFrame = CreateFrame("Frame", nil, scrollFrame)
self.scrollFrame = scrollFrame
self.itemFrame = itemFrame
scrollFrame.obj = self
itemFrame.obj = self
local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..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")
self.slider = slider
slider.obj = self
scrollFrame:SetScrollChild(itemFrame)
scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12)
scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12)
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)
slider:SetScript("OnValueChanged", OnScrollValueChanged)
slider:SetMinMaxValues(0, 1000)
slider:SetValueStep(1)
slider:SetValue(0)
scrollFrame:Show()
itemFrame:Show()
slider:Hide()
self:FixScroll()
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
end
do
local widgetType = "Dropdown"
local widgetVersion = 22
--[[ Static data ]]--
--[[ UI event handler ]]--
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)
local self = this.obj
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.frame:GetWidth())
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 == "Dropdown-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
--[[ Exported methods ]]--
-- exported, AceGUI callback
local function OnAcquire(self)
local pullout = AceGUI:Create("Dropdown-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)
end
-- exported, AceGUI callback
local function OnRelease(self)
if self.open then
self.pullout:Close()
end
AceGUI:Release(self.pullout)
self.pullout = nil
self:SetText("")
self:SetLabel("")
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
-- exported
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.text:SetTextColor(0.5,0.5,0.5)
self.button:Disable()
self.label:SetTextColor(0.5,0.5,0.5)
else
self.button:Enable()
self.label:SetTextColor(1,.82,0)
self.text:SetTextColor(1,1,1)
end
end
-- exported
local function ClearFocus(self)
if self.open then
self.pullout:Close()
end
end
-- exported
local function SetText(self, text)
self.text:SetText(text or "")
end
-- exported
local function SetLabel(self, text)
if text and text ~= "" then
self.label:SetText(text)
self.label:Show()
self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-18)
self.frame:SetHeight(44)
else
self.label:SetText("")
self.label:Hide()
self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0)
self.frame:SetHeight(26)
end
end
-- exported
local function SetValue(self, value)
if self.list then
self:SetText(self.list[value] or "")
end
self.value = value
end
-- exported
local function GetValue(self)
return self.value
end
-- exported
local function SetItemValue(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
-- exported
local function SetItemDisabled(self, item, disabled)
for i, widget in self.pullout:IterateItems() do
if widget.userdata.value == item then
widget:SetDisabled(disabled)
end
end
end
local function AddListItem(self, value, text)
local item = AceGUI:Create("Dropdown-Item-Toggle")
item:SetText(text)
item.userdata.obj = self
item.userdata.value = value
item:SetCallback("OnValueChanged", OnItemValueChanged)
self.pullout:AddItem(item)
end
local function AddCloseButton(self)
if not self.hasClose then
local close = AceGUI:Create("Dropdown-Item-Execute")
close:SetText(CLOSE)
self.pullout:AddItem(close)
self.hasClose = true
end
end
-- exported
local sortlist = {}
local function SetList(self, list)
self.list = list
self.pullout:Clear()
self.hasClose = nil
if not list then return end
for v in pairs(list) do
sortlist[#sortlist + 1] = v
end
tsort(sortlist)
for i, value in pairs(sortlist) do
AddListItem(self, value, list[value])
sortlist[i] = nil
end
if self.multiselect then
ShowMultiText(self)
AddCloseButton(self)
end
end
-- exported
local function AddItem(self, value, text)
if self.list then
self.list[value] = text
AddListItem(self, value, text)
end
end
-- exported
local function SetMultiselect(self, multi)
self.multiselect = multi
if multi then
ShowMultiText(self)
AddCloseButton(self)
end
end
-- exported
local function GetMultiselect(self)
return self.multiselect
end
--[[ Constructor ]]--
local function Constructor()
local count = AceGUI:GetNextWidgetNum(widgetType)
local frame = CreateFrame("Frame", nil, UIParent)
local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate")
local self = {}
self.type = widgetType
self.frame = frame
self.dropdown = dropdown
self.count = count
frame.obj = self
dropdown.obj = self
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.ClearFocus = ClearFocus
self.SetText = SetText
self.SetValue = SetValue
self.GetValue = GetValue
self.SetList = SetList
self.SetLabel = SetLabel
self.SetDisabled = SetDisabled
self.AddItem = AddItem
self.SetMultiselect = SetMultiselect
self.GetMultiselect = GetMultiselect
self.SetItemValue = SetItemValue
self.SetItemDisabled = SetItemDisabled
self.alignoffset = 31
frame:SetHeight(44)
frame:SetWidth(200)
frame:SetScript("OnHide",Dropdown_OnHide)
dropdown:ClearAllPoints()
dropdown:SetPoint("TOPLEFT",frame,"TOPLEFT",-15,0)
dropdown:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",17,0)
dropdown:SetScript("OnHide", nil)
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"]
self.button = button
button.obj = self
button:SetScript("OnEnter",Control_OnEnter)
button:SetScript("OnLeave",Control_OnLeave)
button:SetScript("OnClick",Dropdown_TogglePullout)
local text = _G[dropdown:GetName() .. "Text"]
self.text = text
text.obj = self
text:ClearAllPoints()
text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2)
text:SetPoint("LEFT", left, "LEFT", 25, 2)
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
label:SetJustifyH("LEFT")
label:SetHeight(18)
label:Hide()
self.label = label
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
end
@@ -0,0 +1,223 @@
--[[-----------------------------------------------------------------------------
EditBox Widget
-------------------------------------------------------------------------------]]
local Type, Version = "EditBox", 20
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, GetSpellName = GetCursorInfo, ClearCursor, GetSpellName
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
if not AceGUIEditBoxInsertLink then
-- upgradeable hook
hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
end
function _G.AceGUIEditBoxInsertLink(text)
for i = 1, AceGUI:GetWidgetCount(Type) do
local editbox = _G["AceGUI-3.0EditBox"..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 EditBox_OnEscapePressed(frame)
AceGUI:ClearFocus()
end
local function EditBox_OnEnterPressed(frame)
local self = frame.obj
local value = frame:GetText()
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, rank = GetSpellName(id, info)
if rank and rank:match("%d") then
name = name.."("..rank..")"
end
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 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(false)
self:SetLabel()
self:SetText()
self:DisableButton(false)
end,
-- ["OnRelease"] = nil,
["SetDisabled"] = function(self, disabled)
self.disabled = disabled
if disabled then
self.editbox:EnableMouse(false)
self.editbox:ClearFocus()
self.editbox:SetTextColor(0.5,0.5,0.5)
self.label:SetTextColor(0.5,0.5,0.5)
else
self.editbox:EnableMouse(true)
self.editbox:SetTextColor(1,1,1)
self.label:SetTextColor(1,.82,0)
end
end,
["SetText"] = function(self, text)
self.lasttext = text or ""
self.editbox:SetText(text or "")
self.editbox:SetCursorPosition(0)
HideButton(self)
end,
["SetLabel"] = function(self, text)
if text and text ~= "" then
self.label:SetText(text)
self.label:Show()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
self:SetHeight(44)
self.alignoffset = 30
else
self.label:SetText("")
self.label:Hide()
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
self:SetHeight(26)
self.alignoffset = 12
end
end,
["DisableButton"] = function(self, disabled)
self.disablebutton = disabled
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
editbox:SetAutoFocus(false)
editbox:SetFontObject(ChatFontNormal)
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:SetTextInsets(0, 0, 3, 3)
editbox:SetMaxLetters(256)
editbox:SetPoint("BOTTOMLEFT", 6, 0)
editbox:SetPoint("BOTTOMRIGHT")
editbox:SetHeight(19)
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("TOPLEFT", 0, -2)
label:SetPoint("TOPRIGHT", 0, -2)
label:SetJustifyH("LEFT")
label:SetHeight(18)
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 = {
alignoffset = 30,
editbox = editbox,
label = label,
button = button,
frame = frame,
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,78 @@
--[[-----------------------------------------------------------------------------
Heading Widget
-------------------------------------------------------------------------------]]
local Type, Version = "Heading", 20
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
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetText()
self:SetFullWidth()
self:SetHeight(18)
end,
-- ["OnRelease"] = nil,
["SetText"] = function(self, text)
self.label:SetText(text or "")
if text and text ~= "" then
self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0)
self.right:Show()
else
self.left:SetPoint("RIGHT", -3, 0)
self.right:Hide()
end
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
label:SetPoint("TOP")
label:SetPoint("BOTTOM")
label:SetJustifyH("CENTER")
local left = frame:CreateTexture(nil, "BACKGROUND")
left:SetHeight(8)
left:SetPoint("LEFT", 3, 0)
left:SetPoint("RIGHT", label, "LEFT", -5, 0)
left:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
left:SetTexCoord(0.81, 0.94, 0.5, 1)
local right = frame:CreateTexture(nil, "BACKGROUND")
right:SetHeight(8)
right:SetPoint("RIGHT", -3, 0)
right:SetPoint("LEFT", label, "RIGHT", 5, 0)
right:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
right:SetTexCoord(0.81, 0.94, 0.5, 1)
local widget = {
label = label,
left = left,
right = right,
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,144 @@
--[[-----------------------------------------------------------------------------
Icon Widget
-------------------------------------------------------------------------------]]
local Type, Version = "Icon", 20
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
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function Control_OnEnter(frame)
frame.obj:Fire("OnEnter")
end
local function Control_OnLeave(frame)
frame.obj:Fire("OnLeave")
end
local function Button_OnClick(frame, button)
frame.obj:Fire("OnClick", button)
AceGUI:ClearFocus()
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetHeight(110)
self:SetWidth(110)
self:SetLabel()
self:SetImage(nil)
self:SetImageSize(64, 64)
self:SetDisabled(false)
end,
-- ["OnRelease"] = nil,
["SetLabel"] = function(self, text)
if text and text ~= "" then
self.label:Show()
self.label:SetText(text)
self:SetHeight(self.image:GetHeight() + 25)
else
self.label:Hide()
self:SetHeight(self.image:GetHeight() + 10)
end
end,
["SetImage"] = function(self, path, ...)
local image = self.image
image:SetTexture(path)
if image:GetTexture() then
local n = select("#", ...)
if n == 4 or n == 8 then
image:SetTexCoord(...)
else
image:SetTexCoord(0, 1, 0, 1)
end
end
end,
["SetImageSize"] = function(self, width, height)
self.image:SetWidth(width)
self.image:SetHeight(height)
--self.frame:SetWidth(width + 30)
if self.label:IsShown() then
self:SetHeight(height + 25)
else
self:SetHeight(height + 10)
end
end,
["SetDisabled"] = function(self, disabled)
self.disabled = disabled
if disabled then
self.frame:Disable()
self.label:SetTextColor(0.5, 0.5, 0.5)
self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5)
else
self.frame:Enable()
self.label:SetTextColor(1, 1, 1)
self.image:SetVertexColor(1, 1, 1)
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", Button_OnClick)
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight")
label:SetPoint("BOTTOMLEFT")
label:SetPoint("BOTTOMRIGHT")
label:SetJustifyH("CENTER")
label:SetJustifyV("TOP")
label:SetHeight(18)
local image = frame:CreateTexture(nil, "BACKGROUND")
image:SetWidth(64)
image:SetHeight(64)
image:SetPoint("TOP", 0, -5)
local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
highlight:SetAllPoints(image)
highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight")
highlight:SetTexCoord(0, 1, 0.23, 0.77)
highlight:SetBlendMode("ADD")
local widget = {
label = label,
image = image,
frame = frame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
-- SetText is deprecated, but keep it around for a while. (say, to WoW 4.0)
if (select(4, GetBuildInfo()) < 40000) then
widget.SetText = widget.SetLabel
else
widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
end
return AceGUI:RegisterAsWidget(widget)
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,101 @@
--[[-----------------------------------------------------------------------------
InteractiveLabel Widget
-------------------------------------------------------------------------------]]
local Type, Version = "InteractiveLabel", 20
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,
-- ["OnRelease"] = nil,
["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("Label")
local frame = label.frame
frame:EnableMouse(true)
frame:SetScript("OnEnter", Control_OnEnter)
frame:SetScript("OnLeave", Control_OnLeave)
frame:SetScript("OnMouseDown", Label_OnClick)
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,230 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
-- WoW APIs
local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
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: NOT_BOUND
--------------------------
-- Keybinding --
--------------------------
do
local Type = "Keybinding"
local Version = 13
local ControlBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 3, bottom = 3 }
}
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
local function keybindingMsgFixWidth(this)
this:SetWidth(this.msg:GetWidth()+10)
this:SetScript("OnUpdate",nil)
end
local function Keybinding_OnClick(this, button)
if button == "LeftButton" or button == "RightButton" then
local self = this.obj
if self.waitingForKey then
this:EnableKeyboard(false)
self.msgframe:Hide()
this:UnlockHighlight()
self.waitingForKey = nil
else
this:EnableKeyboard(true)
self.msgframe:Show()
this:LockHighlight()
self.waitingForKey = true
end
end
AceGUI:ClearFocus()
end
local ignoreKeys = nil
local function Keybinding_OnKeyDown(this, key)
local self = this.obj
if self.waitingForKey then
local keyPressed = key
if keyPressed == "ESCAPE" then
keyPressed = ""
else
if not ignoreKeys then
ignoreKeys = {
["BUTTON1"] = true, ["BUTTON2"] = true,
["UNKNOWN"] = true,
["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
}
end
if ignoreKeys[keyPressed] then return end
if IsShiftKeyDown() then
keyPressed = "SHIFT-"..keyPressed
end
if IsControlKeyDown() then
keyPressed = "CTRL-"..keyPressed
end
if IsAltKeyDown() then
keyPressed = "ALT-"..keyPressed
end
end
this:EnableKeyboard(false)
self.msgframe:Hide()
this:UnlockHighlight()
self.waitingForKey = nil
if not self.disabled then
self:SetKey(keyPressed)
self:Fire("OnKeyChanged",keyPressed)
end
end
end
local function Keybinding_OnMouseDown(this, button)
if button == "LeftButton" or button == "RightButton" then
return
elseif button == "MiddleButton" then
button = "BUTTON3"
elseif button == "Button4" then
button = "BUTTON4"
elseif button == "Button5" then
button = "BUTTON5"
end
Keybinding_OnKeyDown(this, button)
end
local function OnAcquire(self)
self:SetWidth(200)
self:SetHeight(44)
self:SetLabel("")
self:SetKey("")
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.waitingForKey = nil
self.msgframe:Hide()
self:SetDisabled(false)
end
local function SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.button:Disable()
self.label:SetTextColor(0.5,0.5,0.5)
else
self.button:Enable()
self.label:SetTextColor(1,1,1)
end
end
local function SetKey(self, key)
if (key or "") == "" then
self.button:SetText(NOT_BOUND)
self.button:SetNormalFontObject("GameFontNormal")
else
self.button:SetText(key)
self.button:SetNormalFontObject("GameFontHighlight")
end
end
local function SetLabel(self, label)
self.label:SetText(label or "")
if (label or "") == "" then
self.alignoffset = nil
self:SetHeight(24)
else
self.alignoffset = 30
self:SetHeight(44)
end
end
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type)
local frame = CreateFrame("Frame",nil,UIParent)
local button = CreateFrame("Button","AceGUI-3.0 KeybindingButton"..num,frame,"UIPanelButtonTemplate2")
local self = {}
self.type = Type
self.num = num
local text = button:GetFontString()
text:SetPoint("LEFT",button,"LEFT",7,0)
text:SetPoint("RIGHT",button,"RIGHT",-7,0)
button:SetScript("OnClick",Keybinding_OnClick)
button:SetScript("OnKeyDown",Keybinding_OnKeyDown)
button:SetScript("OnEnter",Control_OnEnter)
button:SetScript("OnLeave",Control_OnLeave)
button:SetScript("OnMouseDown",Keybinding_OnMouseDown)
button:RegisterForClicks("AnyDown")
button:EnableMouse()
button:SetHeight(24)
button:SetWidth(200)
button:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
button:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
frame:SetWidth(200)
frame:SetHeight(44)
self.alignoffset = 30
self.button = button
local label = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
label:SetJustifyH("CENTER")
label:SetHeight(18)
self.label = label
local msgframe = CreateFrame("Frame",nil,UIParent)
msgframe:SetHeight(30)
msgframe:SetBackdrop(ControlBackdrop)
msgframe:SetBackdropColor(0,0,0)
msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
msgframe:SetFrameLevel(1000)
self.msgframe = msgframe
local msg = msgframe:CreateFontString(nil,"OVERLAY","GameFontNormal")
msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel")
msgframe.msg = msg
msg:SetPoint("TOPLEFT",msgframe,"TOPLEFT",5,-5)
msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
msgframe:SetPoint("BOTTOM",button,"TOP",0,0)
msgframe:Hide()
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.SetLabel = SetLabel
self.SetDisabled = SetDisabled
self.SetKey = SetKey
self.frame = frame
frame.obj = self
button.obj = self
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
@@ -0,0 +1,162 @@
--[[-----------------------------------------------------------------------------
Label Widget
Displays text and optionally an icon.
-------------------------------------------------------------------------------]]
local Type, Version = "Label", 21
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
-- 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
--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]
local function UpdateImageAnchor(self)
if self.resizing then return end
local frame = self.frame
local width = frame.width or frame:GetWidth() or 0
local image = self.image
local label = self.label
local height
label:ClearAllPoints()
image:ClearAllPoints()
if self.imageshown then
local imagewidth = image:GetWidth()
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
-- image goes on top centered when less than 200 width for the text, or if there is no text
image:SetPoint("TOP")
label:SetPoint("TOP", image, "BOTTOM")
label:SetPoint("LEFT")
label:SetWidth(width)
height = image:GetHeight() + label:GetHeight()
else
-- image on the left
image:SetPoint("TOPLEFT")
label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
label:SetWidth(width - imagewidth - 4)
height = max(image:GetHeight(), label:GetHeight())
end
else
-- no image shown
label:SetPoint("TOPLEFT")
label:SetWidth(width)
height = label:GetHeight()
end
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:SetImage(nil)
self:SetImageSize(16, 16)
self:SetColor()
self:SetFontObject()
-- reset the flag
self.resizing = nil
-- run the update explicitly
UpdateImageAnchor(self)
end,
-- ["OnRelease"] = nil,
["OnWidthSet"] = function(self, width)
UpdateImageAnchor(self)
end,
["SetText"] = function(self, text)
self.label:SetText(text)
UpdateImageAnchor(self)
end,
["SetColor"] = function(self, r, g, b)
if not (r and g and b) then
r, g, b = 1, 1, 1
end
self.label:SetVertexColor(r, g, b)
end,
["SetImage"] = function(self, path, ...)
local image = self.image
image:SetTexture(path)
if image:GetTexture() then
self.imageshown = true
local n = select("#", ...)
if n == 4 or n == 8 then
image:SetTexCoord(...)
else
image:SetTexCoord(0, 1, 0, 1)
end
else
self.imageshown = nil
end
UpdateImageAnchor(self)
end,
["SetFont"] = function(self, font, height, flags)
self.label:SetFont(font, height, flags)
end,
["SetFontObject"] = function(self, font)
self:SetFont((font or GameFontHighlightSmall):GetFont())
end,
["SetImageSize"] = function(self, width, height)
self.image:SetWidth(width)
self.image:SetHeight(height)
UpdateImageAnchor(self)
end,
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
label:SetJustifyH("LEFT")
label:SetJustifyV("TOP")
local image = frame:CreateTexture(nil, "BACKGROUND")
-- create widget
local widget = {
label = label,
image = image,
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,278 @@
local Type, Version = "MultiLineEditBox", 20
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 GetCursorInfo, GetSpellName, ClearCursor = GetCursorInfo, GetSpellName, ClearCursor
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: ACCEPT, ChatFontNormal
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function OnClick(self) -- Button
self = self.obj
self.editBox:ClearFocus()
if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
self.button:Disable()
end
end
local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox
self, y = self.obj.scrollFrame, -y
local offset = self:GetVerticalScroll()
if y < offset then
self:SetVerticalScroll(y)
else
y = y + cursorHeight - self:GetHeight()
if y > offset then
self:SetVerticalScroll(y)
end
end
end
local function OnEditFocusLost(self) -- EditBox
self:HighlightText(0, 0)
end
local function OnEnter(self) -- EditBox / ScrollFrame
self = self.obj
if not self.entered then
self.entered = true
self:Fire("OnEnter")
end
end
local function OnLeave(self) -- EditBox / ScrollFrame
self = self.obj
if self.entered then
self.entered = nil
self:Fire("OnLeave")
end
end
local function OnMouseUp(self) -- ScrollFrame
self = self.obj.editBox
self:SetFocus()
self:SetCursorPosition(self:GetNumLetters())
end
local function OnReceiveDrag(self) -- EditBox / ScrollFrame
local type, id, info = GetCursorInfo()
if type == "spell" then
info, id = GetSpellName(id, info)
if id and id:match("%d") then
info = info .. "(" .. id .. ")"
end
elseif type ~= "item" then
return
end
ClearCursor()
self = self.obj
local editBox = self.editBox
if not editBox:HasFocus() then
editBox:SetFocus()
editBox:SetCursorPosition(editBox:GetNumLetters())
end
editBox:Insert(info)
self.button:Enable()
end
local function OnSizeChanged(self, width, height) -- ScrollFrame
self.obj.editBox:SetWidth(width)
end
local function OnTextChanged(self, userInput) -- EditBox
if userInput then
self = self.obj
self:Fire("OnTextChanged", self.editBox:GetText())
self.button:Enable()
end
end
local function OnTextSet(self) -- EditBox
self:HighlightText(0, 0)
self:SetCursorPosition(self:GetNumLetters())
self:SetCursorPosition(0)
self.obj.button:Disable()
end
local function OnVerticalScroll(self, offset) -- ScrollFrame
local editBox = self.obj.editBox
editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
end
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["GetText"] = function(self)
return self.editBox:GetText()
end,
["OnAcquire"] = function(self)
self.editBox:SetText("")
self:SetDisabled(false)
self:SetWidth(200)
self:SetNumLines()
self.entered = nil
end,
["OnRelease"] = function(self)
self.frame:ClearAllPoints()
self.frame:Hide()
end,
["SetDisabled"] = function(self, disabled)
local editBox = self.editBox
if disabled then
editBox:ClearFocus()
editBox:EnableMouse(false)
editBox:SetTextColor(0.5, 0.5, 0.5)
self.label:SetTextColor(0.5, 0.5, 0.5)
self.scrollFrame:EnableMouse(false)
self.button:Disable()
else
editBox:EnableMouse(true)
editBox:SetTextColor(1, 1, 1)
self.label:SetTextColor(1, 0.82, 0)
self.scrollFrame:EnableMouse(true)
end
end,
["SetLabel"] = function(self, text)
if text and text ~= "" then
self.label:SetText(text)
if self.labelHeight ~= 10 then
self.labelHeight = 10
self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19)
self:SetHeight(self.frame.height + 10)
self.label:Show()
end
elseif self.labelHeight ~= 0 then
self.labelHeight = 0
self.label:Hide()
self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23)
self:SetHeight(self.frame.height - 10)
end
end,
["SetNumLines"] = function(self, value)
if not value or value < 4 then
value = 4
end
self:SetHeight(value * 14 + 41 + self.labelHeight)
end,
["SetText"] = function(self, text)
self.editBox:SetText(text)
end
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local backdrop = {
bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
insets = { left = 4, right = 3, top = 4, bottom = 3 }
}
local function Constructor()
local frame = CreateFrame("Frame", nil, UIParent)
frame:Hide()
local widgetNum = AceGUI:GetNextWidgetNum(Type)
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
label:SetJustifyH("LEFT")
label:SetText(ACCEPT)
label:SetHeight(10)
local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate2")
button:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 0, 4)
button:SetHeight(22)
button:SetWidth(label:GetStringWidth() + 24)
button:SetText(ACCEPT)
button:SetScript("OnClick", OnClick)
button:Disable()
local text = button:GetFontString()
text:ClearAllPoints()
text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
text:SetJustifyV("MIDDLE")
local scrollBG = CreateFrame("Frame", nil, frame)
scrollBG:SetBackdrop(backdrop)
scrollBG:SetBackdropColor(0, 0, 0)
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
scrollBar:ClearAllPoints()
scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19)
scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18)
scrollBar:SetPoint("RIGHT", frame, "RIGHT")
scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19)
scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT")
scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6)
scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4)
scrollFrame:SetScript("OnEnter", OnEnter)
scrollFrame:SetScript("OnLeave", OnLeave)
scrollFrame:SetScript("OnMouseUp", OnMouseUp)
scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
local editBox = CreateFrame("EditBox", nil, scrollFrame)
editBox:SetAllPoints()
editBox:SetFontObject(ChatFontNormal)
editBox:SetMultiLine(true)
editBox:EnableMouse(true)
editBox:SetAutoFocus(false)
editBox:SetCountInvisibleLetters(false)
editBox:SetScript("OnCursorChanged", OnCursorChanged)
editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
editBox:SetScript("OnEnter", OnEnter)
editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
editBox:SetScript("OnLeave", OnLeave)
editBox:SetScript("OnMouseDown", OnReceiveDrag)
editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
editBox:SetScript("OnTextChanged", OnTextChanged)
editBox:SetScript("OnTextSet", OnTextSet)
scrollFrame:SetScrollChild(editBox)
local widget = {
button = button,
editBox = editBox,
frame = frame,
label = label,
labelHeight = 10,
scrollBar = scrollBar,
scrollFrame = scrollFrame,
type = Type
}
for method, func in pairs(methods) do
widget[method] = func
end
button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget
AceGUI:RegisterAsWidget(widget)
return widget
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)
@@ -0,0 +1,285 @@
local AceGUI = LibStub("AceGUI-3.0")
-- Lua APIs
local min, max, floor = math.min, math.max, math.floor
local tonumber = tonumber
-- WoW APIs
local PlaySound = PlaySound
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
--------------------------
-- Slider --
--------------------------
do
local Type = "Slider"
local Version = 11
local function OnAcquire(self)
self:SetWidth(200)
self:SetHeight(44)
self:SetDisabled(false)
self:SetIsPercent(nil)
self:SetSliderValues(0,100,1)
self:SetValue(0)
end
local function OnRelease(self)
self.frame:ClearAllPoints()
self.frame:Hide()
self.slider:EnableMouseWheel(false)
self:SetDisabled(false)
end
local function Control_OnEnter(this)
this.obj:Fire("OnEnter")
end
local function Control_OnLeave(this)
this.obj:Fire("OnLeave")
end
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
local function Slider_OnValueChanged(this)
local self = this.obj
if not this.setup then
local newvalue
newvalue = this:GetValue()
if newvalue ~= self.value and not self.disabled then
self.value = newvalue
self:Fire("OnValueChanged", newvalue)
end
if self.value then
local value = self.value
UpdateText(self)
end
end
end
local function Slider_OnMouseUp(this)
local self = this.obj
self:Fire("OnMouseUp",this:GetValue())
end
local function Slider_OnMouseWheel(this, v)
local self = this.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 SetDisabled(self, disabled)
self.disabled = disabled
if disabled then
self.slider:EnableMouse(false)
self.label:SetTextColor(.5,.5,.5)
self.hightext:SetTextColor(.5,.5,.5)
self.lowtext:SetTextColor(.5,.5,.5)
--self.valuetext:SetTextColor(.5,.5,.5)
self.editbox:SetTextColor(.5,.5,.5)
self.editbox:EnableMouse(false)
self.editbox:ClearFocus()
else
self.slider:EnableMouse(true)
self.label:SetTextColor(1,.82,0)
self.hightext:SetTextColor(1,1,1)
self.lowtext:SetTextColor(1,1,1)
--self.valuetext:SetTextColor(1,1,1)
self.editbox:SetTextColor(1,1,1)
self.editbox:EnableMouse(true)
end
end
local function SetValue(self, value)
self.slider.setup = true
self.slider:SetValue(value)
self.value = value
UpdateText(self)
self.slider.setup = nil
end
local function SetLabel(self, text)
self.label:SetText(text)
end
local function SetSliderValues(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
local function EditBox_OnEscapePressed(this)
this:ClearFocus()
end
local function EditBox_OnEnterPressed(this)
local self = this.obj
local value = this:GetText()
if self.ispercent then
value = value:gsub('%%','')
value = tonumber(value) / 100
else
value = tonumber(value)
end
if value then
PlaySound("igMainMenuOptionCheckBoxOn")
self:Fire("OnValueChanged", value)
self:Fire("OnMouseUp",value)
end
end
local function EditBox_OnEnter(this)
this:SetBackdropBorderColor(0.5,0.5,0.5,1)
end
local function EditBox_OnLeave(this)
this:SetBackdropBorderColor(0.3,0.3,0.3,0.8)
end
local function SetIsPercent(self, value)
self.ispercent = value
UpdateLabels(self)
UpdateText(self)
end
local function FrameOnMouseDown(this)
this.obj.slider:EnableMouseWheel(true)
AceGUI:ClearFocus()
end
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 = 6, bottom = 6 }
}
local ManualBackdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
tile = true, edgeSize = 1, tileSize = 5,
}
local function Constructor()
local frame = CreateFrame("Frame",nil,UIParent)
local self = {}
self.type = Type
self.OnRelease = OnRelease
self.OnAcquire = OnAcquire
self.frame = frame
frame.obj = self
self.SetDisabled = SetDisabled
self.SetValue = SetValue
self.SetSliderValues = SetSliderValues
self.SetLabel = SetLabel
self.SetIsPercent = SetIsPercent
self.alignoffset = 25
frame:EnableMouse(true)
frame:SetScript("OnMouseDown",FrameOnMouseDown)
self.slider = CreateFrame("Slider",nil,frame)
local slider = self.slider
slider:SetScript("OnEnter",Control_OnEnter)
slider:SetScript("OnLeave",Control_OnLeave)
slider:SetScript("OnMouseUp", Slider_OnMouseUp)
slider.obj = self
slider:SetOrientation("HORIZONTAL")
slider:SetHeight(15)
slider:SetHitRectInsets(0,0,-10,0)
slider:SetBackdrop(SliderBackdrop)
--slider:EnableMouseWheel(true)
slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
label:SetJustifyH("CENTER")
label:SetHeight(15)
self.label = label
self.lowtext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
self.lowtext:SetPoint("TOPLEFT",slider,"BOTTOMLEFT",2,3)
self.hightext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
self.hightext:SetPoint("TOPRIGHT",slider,"BOTTOMRIGHT",-2,3)
local editbox = CreateFrame("EditBox",nil,frame)
editbox:SetAutoFocus(false)
editbox:SetFontObject(GameFontHighlightSmall)
editbox:SetPoint("TOP",slider,"BOTTOM",0,0)
editbox:SetHeight(14)
editbox:SetWidth(70)
editbox:SetJustifyH("CENTER")
editbox:EnableMouse(true)
editbox:SetScript("OnEscapePressed",EditBox_OnEscapePressed)
editbox:SetScript("OnEnterPressed",EditBox_OnEnterPressed)
editbox:SetScript("OnEnter",EditBox_OnEnter)
editbox:SetScript("OnLeave",EditBox_OnLeave)
editbox:SetBackdrop(ManualBackdrop)
editbox:SetBackdropColor(0,0,0,0.5)
editbox:SetBackdropBorderColor(0.3,0.3,0.30,0.80)
self.editbox = editbox
editbox.obj = self
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
frame:SetWidth(200)
frame:SetHeight(44)
slider:SetPoint("TOP",label,"BOTTOM",0,0)
slider:SetPoint("LEFT",frame,"LEFT",3,0)
slider:SetPoint("RIGHT",frame,"RIGHT",-3,0)
slider:SetValue(self.value or 0)
slider:SetScript("OnValueChanged",Slider_OnValueChanged)
AceGUI:RegisterAsWidget(self)
return self
end
AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
+514
View File
@@ -0,0 +1,514 @@
--- **AceHook-3.0** offers safe Hooking/Unhooking of functions, methods and frame scripts.
-- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken
-- when you manually restore the original function.
--
-- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceHook itself.\\
-- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceHook.
-- @class file
-- @name AceHook-3.0
-- @release $Id: AceHook-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 5
local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
if not AceHook then return end -- No upgrade needed
AceHook.embeded = AceHook.embeded or {}
AceHook.registry = AceHook.registry or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end })
AceHook.handlers = AceHook.handlers or {}
AceHook.actives = AceHook.actives or {}
AceHook.scripts = AceHook.scripts or {}
AceHook.onceSecure = AceHook.onceSecure or {}
AceHook.hooks = AceHook.hooks or {}
-- local upvalues
local registry = AceHook.registry
local handlers = AceHook.handlers
local actives = AceHook.actives
local scripts = AceHook.scripts
local onceSecure = AceHook.onceSecure
-- Lua APIs
local pairs, next, type = pairs, next, type
local format = string.format
local assert, error = assert, error
-- WoW APIs
local issecurevariable, hooksecurefunc = issecurevariable, hooksecurefunc
local _G = _G
-- functions for later definition
local donothing, createHook, hook
local protectedScripts = {
OnClick = true,
}
-- upgrading of embeded is done at the bottom of the file
local mixins = {
"Hook", "SecureHook",
"HookScript", "SecureHookScript",
"Unhook", "UnhookAll",
"IsHooked",
"RawHook", "RawHookScript"
}
-- AceHook:Embed( target )
-- target (object) - target object to embed AceHook in
--
-- Embeds AceEevent into the target object making the functions from the mixins list available on target:..
function AceHook:Embed( target )
for k, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeded[target] = true
-- inject the hooks table safely
target.hooks = target.hooks or {}
return target
end
-- AceHook:OnEmbedDisable( target )
-- target (object) - target object that is being disabled
--
-- Unhooks all hooks when the target disables.
-- this method should be called by the target manually or by an addon framework
function AceHook:OnEmbedDisable( target )
target:UnhookAll()
end
function createHook(self, handler, orig, secure, failsafe)
local uid
local method = type(handler) == "string"
if failsafe and not secure then
-- failsafe hook creation
uid = function(...)
if actives[uid] then
if method then
self[handler](self, ...)
else
handler(...)
end
end
return orig(...)
end
-- /failsafe hook
else
-- all other hooks
uid = function(...)
if actives[uid] then
if method then
return self[handler](self, ...)
else
return handler(...)
end
elseif not secure then -- backup on non secure
return orig(...)
end
end
-- /hook
end
return uid
end
function donothing() end
function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage)
if not handler then handler = method end
-- These asserts make sure AceHooks's devs play by the rules.
assert(not script or type(script) == "boolean")
assert(not secure or type(secure) == "boolean")
assert(not raw or type(raw) == "boolean")
assert(not forceSecure or type(forceSecure) == "boolean")
assert(usage)
-- Error checking Battery!
if obj and type(obj) ~= "table" then
error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3)
end
if type(method) ~= "string" then
error(format("%s: 'method' - string expected got %s", usage, type(method)), 3)
end
if type(handler) ~= "string" and type(handler) ~= "function" then
error(format("%s: 'handler' - nil, string, or function expected got %s", usage, type(handler)), 3)
end
if type(handler) == "string" and type(self[handler]) ~= "function" then
error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3)
end
if script then
if not secure and obj:IsProtected() and protectedScripts[method] then
error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
end
if not obj or not obj.GetScript or not obj:HasScript(method) then
error(format("%s: You can only hook a script on a frame object", usage), 3)
end
else
local issecure
if obj then
issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method)
else
issecure = onceSecure[method] or issecurevariable(method)
end
if issecure then
if forceSecure then
if obj then
onceSecure[obj] = onceSecure[obj] or {}
onceSecure[obj][method] = true
else
onceSecure[method] = true
end
elseif not secure then
error(format("%s: Attempt to hook secure function %s. Use `SecureHook' or add `true' to the argument list to override.", usage, method), 3)
end
end
end
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
if uid then
if actives[uid] then
-- Only two sane choices exist here. We either a) error 100% of the time or b) always unhook and then hook
-- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a.
error(format("Attempting to rehook already active hook %s.", method))
end
if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak
actives[uid] = true
return
elseif obj then -- is there any reason not to call unhook instead of doing the following several lines?
if self.hooks and self.hooks[obj] then
self.hooks[obj][method] = nil
end
registry[self][obj][method] = nil
else
if self.hooks then
self.hooks[method] = nil
end
registry[self][method] = nil
end
handlers[uid], actives[uid], scripts[uid] = nil, nil, nil
uid = nil
end
local orig
if script then
orig = obj:GetScript(method) or donothing
elseif obj then
orig = obj[method]
else
orig = _G[method]
end
if not orig then
error(format("%s: Attempting to hook a non existing target", usage), 3)
end
uid = createHook(self, handler, orig, secure, not (raw or secure))
if obj then
self.hooks[obj] = self.hooks[obj] or {}
registry[self][obj] = registry[self][obj] or {}
registry[self][obj][method] = uid
if not secure then
self.hooks[obj][method] = orig
end
if script then
-- If the script is empty before, HookScript will not work, so use SetScript instead
-- This will make the hook insecure, but shouldnt matter, since it was empty before.
-- It does not taint the full frame.
if not secure or orig == donothing then
obj:SetScript(method, uid)
elseif secure then
obj:HookScript(method, uid)
end
else
if not secure then
obj[method] = uid
else
hooksecurefunc(obj, method, uid)
end
end
else
registry[self][method] = uid
if not secure then
_G[method] = uid
self.hooks[method] = orig
else
hooksecurefunc(method, uid)
end
end
actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
end
--- Hook a function or a method on an object.
-- The hook created will be a "safe hook", that means that your handler will be called
-- before the hooked function ("Pre-Hook"), and you don't have to call the original function yourself,
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
-- This type of hook is typically used if you need to know if some function got called, and don't want to modify it.
-- @paramsig [object], method, [handler], [hookSecure]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:Hook("ActionButton_UpdateHotkeys", true)
-- end
--
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
-- print(button:GetName() .. " is updating its HotKey")
-- end
function AceHook:Hook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
if handler == true then
handler, hookSecure = nil, true
end
hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
end
--- RawHook a function or a method on an object.
-- The hook created will be a "raw hook", that means that your handler will completly replace
-- the original function, and your handler has to call the original function (or not, depending on your intentions).\\
-- The original function will be stored in `self.hooks[object][method]` or `self.hooks[functionName]` respectively.\\
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
-- or want to control execution of the original function.
-- @paramsig [object], method, [handler], [hookSecure]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
-- self:RawHook("ActionButton_UpdateHotkeys", true)
-- end
--
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
-- if button:GetName() == "MyButton" then
-- -- do stuff here
-- else
-- self.hooks.ActionButton_UpdateHotkeys(button, type)
-- end
-- end
function AceHook:RawHook(object, method, handler, hookSecure)
if type(object) == "string" then
method, handler, hookSecure, object = object, method, handler, nil
end
if handler == true then
handler, hookSecure = nil, true
end
hook(self, object, method, handler, false, false, true, hookSecure or false, "Usage: RawHook([object], method, [handler], [hookSecure])")
end
--- SecureHook a function or a method on an object.
-- This function is a wrapper around the `hooksecurefunc` function in the WoW API. Using AceHook
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
-- required anymore, or the addon is being disabled.\\
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
-- and taint would block execution. Secure Hooks are always called after the original function was called
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
-- @paramsig [object], method, [handler]
-- @param object The object to hook a method from
-- @param method If object was specified, the name of the method, or the name of the function to hook.
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
function AceHook:SecureHook(object, method, handler)
if type(object) == "string" then
method, handler, object = object, method, nil
end
hook(self, object, method, handler, false, true, false, false, "Usage: SecureHook([object], method, [handler])")
end
--- Hook a script handler on a frame.
-- The hook created will be a "safe hook", that means that your handler will be called
-- before the hooked script ("Pre-Hook"), and you don't have to call the original function yourself,
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
-- This is the frame script equivalent of the :Hook safe-hook. It would typically be used to be notified
-- when a certain event happens to a frame.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook the OnShow of FriendsFrame
-- self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
-- function MyAddon:FriendsFrameOnShow(frame)
-- print("The FriendsFrame was shown!")
-- end
function AceHook:HookScript(frame, script, handler)
hook(self, frame, script, handler, true, false, false, false, "Usage: HookScript(object, method, [handler])")
end
--- RawHook a script handler on a frame.
-- The hook created will be a "raw hook", that means that your handler will completly replace
-- the original script, and your handler has to call the original script (or not, depending on your intentions).\\
-- The original script will be stored in `self.hooks[frame][script]`.\\
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
-- or want to control execution of the original script.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
-- @usage
-- -- create an addon with AceHook embeded
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
--
-- function MyAddon:OnEnable()
-- -- Hook the OnShow of FriendsFrame
-- self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
-- end
--
-- function MyAddon:FriendsFrameOnShow(frame)
-- -- Call the original function
-- self.hooks[frame].OnShow(frame)
-- -- Do our processing
-- -- .. stuff
-- end
function AceHook:RawHookScript(frame, script, handler)
hook(self, frame, script, handler, true, false, true, false, "Usage: RawHookScript(object, method, [handler])")
end
--- SecureHook a script handler on a frame.
-- This function is a wrapper around the `frame:HookScript` function in the WoW API. Using AceHook
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
-- required anymore, or the addon is being disabled.\\
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
-- and taint would block execution. Secure Hooks are always called after the original function was called
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
-- @paramsig frame, script, [handler]
-- @param frame The Frame to hook the script on
-- @param script The script to hook
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
function AceHook:SecureHookScript(frame, script, handler)
hook(self, frame, script, handler, true, true, false, false, "Usage: SecureHookScript(object, method, [handler])")
end
--- Unhook from the specified function, method or script.
-- @paramsig [obj], method
-- @param obj The object or frame to unhook from
-- @param method The name of the method, function or script to unhook from.
function AceHook:Unhook(obj, method)
local usage = "Usage: Unhook([obj], method)"
if type(obj) == "string" then
method, obj = obj, nil
end
if obj and type(obj) ~= "table" then
error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2)
end
if type(method) ~= "string" then
error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2)
end
local uid
if obj then
uid = registry[self][obj] and registry[self][obj][method]
else
uid = registry[self][method]
end
if not uid or not actives[uid] then
-- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying.
return false
end
actives[uid], handlers[uid] = nil, nil
if obj then
registry[self][obj][method] = nil
registry[self][obj] = next(registry[self][obj]) and registry[self][obj] or nil
-- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking
if not self.hooks[obj] or not self.hooks[obj][method] then return true end
if scripts[uid] and obj:GetScript(method) == uid then -- unhooks scripts
obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
scripts[uid] = nil
elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods
obj[method] = self.hooks[obj][method]
end
self.hooks[obj][method] = nil
self.hooks[obj] = next(self.hooks[obj]) and self.hooks[obj] or nil
else
registry[self][method] = nil
-- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out
if not self.hooks[method] then return true end
if self.hooks[method] and _G[method] == uid then -- unhooks functions
_G[method] = self.hooks[method]
end
self.hooks[method] = nil
end
return true
end
--- Unhook all existing hooks for this addon.
function AceHook:UnhookAll()
for key, value in pairs(registry[self]) do
if type(key) == "table" then
for method in pairs(value) do
self:Unhook(key, method)
end
else
self:Unhook(key)
end
end
end
--- Check if the specific function, method or script is already hooked.
-- @paramsig [obj], method
-- @param obj The object or frame to unhook from
-- @param method The name of the method, function or script to unhook from.
function AceHook:IsHooked(obj, method)
-- we don't check if registry[self] exists, this is done by evil magicks in the metatable
if type(obj) == "string" then
if registry[self][obj] and actives[registry[self][obj]] then
return true, handlers[registry[self][obj]]
end
else
if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
return true, handlers[registry[self][obj][method]]
end
end
return false, nil
end
--- Upgrade our old embeded
for target, v in pairs( AceHook.embeded ) do
AceHook:Embed( target )
end
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceHook-3.0.lua"/>
</Ui>
+136
View File
@@ -0,0 +1,136 @@
--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
-- @class file
-- @name AceLocale-3.0
-- @release $Id: AceLocale-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
local MAJOR,MINOR = "AceLocale-3.0", 2
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceLocale then return end -- no upgrade needed
-- Lua APIs
local assert, tostring, error = assert, tostring, error
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: GAME_LOCALE, geterrorhandler
local gameLocale = GetLocale()
if gameLocale == "enGB" then
gameLocale = "enUS"
end
AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
-- This metatable is used on all tables returned from GetLocale
local readmeta = {
__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
rawset(self, key, key) -- only need to see the warning once, really
geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
return key
end
}
-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
local readmetasilent = {
__index = function(self, key) -- requesting totally unknown entries: return key
rawset(self, key, key) -- only need to invoke this function once
return key
end
}
-- Remember the locale table being registered right now (it gets set by :NewLocale())
-- NOTE: Do never try to register 2 locale tables at once and mix their definition.
local registering
-- local assert false function
local assertfalse = function() assert(false) end
-- This metatable proxy is used when registering nondefault locales
local writeproxy = setmetatable({}, {
__newindex = function(self, key, value)
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
end,
__index = assertfalse
})
-- This metatable proxy is used when registering the default locale.
-- It refuses to overwrite existing values
-- Reason 1: Allows loading locales in any order
-- Reason 2: If 2 modules have the same string, but only the first one to be
-- loaded has a translation for the current locale, the translation
-- doesn't get overwritten.
--
local writedefaultproxy = setmetatable({}, {
__newindex = function(self, key, value)
if not rawget(registering, key) then
rawset(registering, key, value == true and key or value)
end
end,
__index = assertfalse
})
--- Register a new locale (or extend an existing one) for the specified application.
-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
-- game locale.
-- @paramsig application, locale[, isDefault[, silent]]
-- @param application Unique name of addon / module
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
-- @param silent If true, the locale will not issue warnings for missing keys. Can only be set on the default locale.
-- @usage
-- -- enUS.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
-- L["string1"] = true
--
-- -- deDE.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
-- if not L then return end
-- L["string1"] = "Zeichenkette1"
-- @return Locale Table to add localizations to, or nil if the current locale is not required.
function AceLocale:NewLocale(application, locale, isDefault, silent)
if silent and not isDefault then
error("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' can only be specified for the default locale", 2)
end
-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
-- Ammo: I still think this is a bad idea, for instance an addon that checks for some ingame string will fail, just because some other addon
-- gives the user the illusion that they can run in a different locale? Ditch this whole thing or allow a setting per 'application'. I'm of the
-- opinion to remove this.
local gameLocale = GAME_LOCALE or gameLocale
if locale ~= gameLocale and not isDefault then
return -- nop, we don't need these translations
end
local app = AceLocale.apps[application]
if not app then
app = setmetatable({}, silent and readmetasilent or readmeta)
AceLocale.apps[application] = app
AceLocale.appnames[app] = application
end
registering = app -- remember globally for writeproxy and writedefaultproxy
if isDefault then
return writedefaultproxy
end
return writeproxy
end
--- Returns localizations for the current locale (or default locale if translations are missing).
-- Errors if nothing is registered (spank developer, not just a missing translation)
-- @param application Unique name of addon / module
-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
-- @return The locale table for the current language.
function AceLocale:GetLocale(application, silent)
if not silent and not AceLocale.apps[application] then
error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
end
return AceLocale.apps[application]
end
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceLocale-3.0.lua"/>
</Ui>
@@ -0,0 +1,240 @@
--[[ $Id: CallbackHandler-1.0.lua 13 2009-12-06 21:56:53Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 5
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
if not CallbackHandler then return end -- No upgrade needed
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
-- Lua APIs
local tconcat = table.concat
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: geterrorhandler
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
local method, ARGS
local function call() method(ARGS) end
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
return dispatch
]]
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
registry.recurse = oldrecurse
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
method = method or eventname
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
local regfunc
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId"
if type(self)~="table" and type(self)~="string" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string expected.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
return registry
end
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="CallbackHandler-1.0.lua"/>
</Ui>
+263
View File
@@ -0,0 +1,263 @@
--[[
Name: DBIcon-1.0
Revision: $Rev: 12 $
Author(s): Rabbit (rabbit.magtheridon@gmail.com)
Description: Allows addons to register to recieve a lightweight minimap icon as an alternative to more heavy LDB displays.
Dependencies: LibStub
License: GPL v2 or later.
]]
--[[
Copyright (C) 2008-2009 Rabbit
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
]]
-----------------------------------------------------------------------
-- DBIcon-1.0
--
-- Disclaimer: Most of this code was ripped from Barrel but fixed, streamlined
-- and cleaned up a lot so that it no longer sucks.
--
local DBICON10 = "LibDBIcon-1.0"
local DBICON10_MINOR = tonumber(("$Rev: 12 $"):match("(%d+)"))
if not LibStub then error(DBICON10 .. " requires LibStub.") end
local ldb = LibStub("LibDataBroker-1.1", true)
if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR)
if not lib then return end
lib.disabled = lib.disabled or nil
lib.objects = lib.objects or {}
lib.callbackRegistered = lib.callbackRegistered or nil
lib.notCreated = lib.notCreated or {}
function lib:IconCallback(event, name, key, value, dataobj)
if lib.objects[name] then
lib.objects[name].icon:SetTexture(dataobj.icon)
end
end
if not lib.callbackRegistered then
ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
lib.callbackRegistered = true
end
-- Tooltip code ripped from StatBlockCore by Funkydude
local function getAnchors(frame)
local x,y = frame:GetCenter()
if not x or not y then return "TOPLEFT", "BOTTOMLEFT" end
local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
end
local function onEnter(self)
if self.isMoving then return end
local obj = self.dataObject
if obj.OnTooltipShow then
GameTooltip:SetOwner(self, "ANCHOR_NONE")
GameTooltip:SetPoint(getAnchors(self))
obj.OnTooltipShow(GameTooltip)
GameTooltip:Show()
elseif obj.OnEnter then
obj.OnEnter(self)
end
end
local function onLeave(self)
local obj = self.dataObject
GameTooltip:Hide()
if obj.OnLeave then obj.OnLeave(self) end
end
--------------------------------------------------------------------------------
local minimapShapes = {
["ROUND"] = {true, true, true, true},
["SQUARE"] = {false, false, false, false},
["CORNER-TOPLEFT"] = {true, false, false, false},
["CORNER-TOPRIGHT"] = {false, false, true, false},
["CORNER-BOTTOMLEFT"] = {false, true, false, false},
["CORNER-BOTTOMRIGHT"] = {false, false, false, true},
["SIDE-LEFT"] = {true, true, false, false},
["SIDE-RIGHT"] = {false, false, true, true},
["SIDE-TOP"] = {true, false, true, false},
["SIDE-BOTTOM"] = {false, true, false, true},
["TRICORNER-TOPLEFT"] = {true, true, true, false},
["TRICORNER-TOPRIGHT"] = {true, false, true, true},
["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
["TRICORNER-BOTTOMRIGHT"] = {false, true, true, true},
}
local function updatePosition(button)
local angle = math.rad(button.db.minimapPos or 225)
local x, y, q = math.cos(angle), math.sin(angle), 1
if x < 0 then q = q + 1 end
if y > 0 then q = q + 2 end
local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
local quadTable = minimapShapes[minimapShape]
if quadTable[q] then
x, y = x*80, y*80
else
local diagRadius = 103.13708498985 --math.sqrt(2*(80)^2)-10
x = math.max(-80, math.min(x*diagRadius, 80))
y = math.max(-80, math.min(y*diagRadius, 80))
end
button:SetPoint("CENTER", Minimap, "CENTER", x, y)
end
local function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end
local function onMouseDown(self) self.icon:SetTexCoord(0, 1, 0, 1) end
local function onMouseUp(self) self.icon:SetTexCoord(0.05, 0.95, 0.05, 0.95) end
local function onUpdate(self)
local mx, my = Minimap:GetCenter()
local px, py = GetCursorPosition()
local scale = Minimap:GetEffectiveScale()
px, py = px / scale, py / scale
self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
updatePosition(self)
end
local function onDragStart(self)
self:LockHighlight()
self.icon:SetTexCoord(0, 1, 0, 1)
self:SetScript("OnUpdate", onUpdate)
self.isMoving = true
GameTooltip:Hide()
end
local function onDragStop(self)
self:SetScript("OnUpdate", nil)
self.icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
self:UnlockHighlight()
self.isMoving = nil
end
local function createButton(name, object, db)
local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
button.dataObject = object
button.db = db
button:SetFrameStrata("MEDIUM")
button:SetWidth(31); button:SetHeight(31)
button:SetFrameLevel(8)
button:RegisterForClicks("anyUp")
button:RegisterForDrag("LeftButton")
button:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
local overlay = button:CreateTexture(nil, "OVERLAY")
overlay:SetWidth(53); overlay:SetHeight(53)
overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
overlay:SetPoint("TOPLEFT")
local icon = button:CreateTexture(nil, "BACKGROUND")
icon:SetWidth(20); icon:SetHeight(20)
icon:SetTexture(object.icon)
icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
icon:SetPoint("TOPLEFT", 7, -5)
button.icon = icon
button:SetScript("OnEnter", onEnter)
button:SetScript("OnLeave", onLeave)
button:SetScript("OnClick", onClick)
button:SetScript("OnDragStart", onDragStart)
button:SetScript("OnDragStop", onDragStop)
button:SetScript("OnMouseDown", onMouseDown)
button:SetScript("OnMouseUp", onMouseUp)
lib.objects[name] = button
if lib.loggedIn then
updatePosition(button)
if not db.hide then button:Show()
else button:Hide() end
end
end
-- We could use a metatable.__index on lib.objects, but then we'd create
-- the icons when checking things like :IsRegistered, which is not necessary.
local function check(name)
if lib.notCreated[name] then
createButton(name, lib.notCreated[name][1], lib.notCreated[name][2])
lib.notCreated[name] = nil
end
end
lib.loggedIn = lib.loggedIn or false
-- Wait a bit with the initial positioning to let any GetMinimapShape addons
-- load up.
if not lib.loggedIn then
local f = CreateFrame("Frame")
f:SetScript("OnEvent", function()
for _, object in pairs(lib.objects) do
updatePosition(object)
if not lib.disabled and not object.db.hide then object:Show()
else object:Hide() end
end
lib.loggedIn = true
f:SetScript("OnEvent", nil)
f = nil
end)
f:RegisterEvent("PLAYER_LOGIN")
end
function lib:Register(name, object, db)
if lib.disabled then return end
if not object.icon then error("Can't register LDB objects without icons set!") end
if lib.objects[name] or lib.notCreated[name] then error("Already registered, nubcake.") end
if not db or not db.hide then
createButton(name, object, db)
else
lib.notCreated[name] = {object, db}
end
end
function lib:Hide(name)
if not lib.objects[name] then return end
lib.objects[name]:Hide()
end
function lib:Show(name)
if lib.disabled then return end
check(name)
lib.objects[name]:Show()
updatePosition(lib.objects[name])
end
function lib:IsRegistered(name)
return (lib.objects[name] or lib.notCreated[name]) and true or false
end
function lib:Refresh(name, db)
if lib.disabled then return end
check(name)
local button = lib.objects[name]
if db then button.db = db end
updatePosition(button)
end
function lib:EnableLibrary()
lib.disabled = nil
for name, object in pairs(lib.objects) do
if not object.db or (object.db and not object.db.hide) then
object:Show()
updatePosition(object)
end
end
end
function lib:DisableLibrary()
lib.disabled = true
for name, object in pairs(lib.objects) do
object:Hide()
end
end
+90 -90
View File
@@ -1,90 +1,90 @@
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
if not lib then return end
oldminor = oldminor or 0
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
if oldminor < 2 then
lib.domt = {
__metatable = "access denied",
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
}
end
if oldminor < 3 then
lib.domt.__newindex = function(self, key, value)
if not attributestorage[self] then attributestorage[self] = {} end
if attributestorage[self][key] == value then return end
attributestorage[self][key] = value
local name = namestorage[self]
if not name then return end
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
end
end
if oldminor < 2 then
function lib:NewDataObject(name, dataobj)
if self.proxystorage[name] then return end
if dataobj then
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
self.attributestorage[dataobj] = {}
for i,v in pairs(dataobj) do
self.attributestorage[dataobj][i] = v
dataobj[i] = nil
end
end
dataobj = setmetatable(dataobj or {}, self.domt)
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
return dataobj
end
end
if oldminor < 1 then
function lib:DataObjectIterator()
return pairs(self.proxystorage)
end
function lib:GetDataObjectByName(dataobjectname)
return self.proxystorage[dataobjectname]
end
function lib:GetNameByDataObject(dataobject)
return self.namestorage[dataobject]
end
end
if oldminor < 4 then
local next = pairs(attributestorage)
function lib:pairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
return next, attributestorage[dataobj], nil
end
local ipairs_iter = ipairs(attributestorage)
function lib:ipairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
return ipairs_iter, attributestorage[dataobj], 0
end
end
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
if not lib then return end
oldminor = oldminor or 0
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
if oldminor < 2 then
lib.domt = {
__metatable = "access denied",
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
}
end
if oldminor < 3 then
lib.domt.__newindex = function(self, key, value)
if not attributestorage[self] then attributestorage[self] = {} end
if attributestorage[self][key] == value then return end
attributestorage[self][key] = value
local name = namestorage[self]
if not name then return end
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
end
end
if oldminor < 2 then
function lib:NewDataObject(name, dataobj)
if self.proxystorage[name] then return end
if dataobj then
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
self.attributestorage[dataobj] = {}
for i,v in pairs(dataobj) do
self.attributestorage[dataobj][i] = v
dataobj[i] = nil
end
end
dataobj = setmetatable(dataobj or {}, self.domt)
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
return dataobj
end
end
if oldminor < 1 then
function lib:DataObjectIterator()
return pairs(self.proxystorage)
end
function lib:GetDataObjectByName(dataobjectname)
return self.proxystorage[dataobjectname]
end
function lib:GetNameByDataObject(dataobject)
return self.namestorage[dataobject]
end
end
if oldminor < 4 then
local next = pairs(attributestorage)
function lib:pairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
return next, attributestorage[dataobj], nil
end
local ipairs_iter = ipairs(attributestorage)
function lib:ipairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
return ipairs_iter, attributestorage[dataobj], 0
end
end
+673
View File
@@ -0,0 +1,673 @@
--[[
Name: LibKeyBound-1.0
Revision: $Rev: 95 $
Author(s): Gello, Maul, Toadkiller, Tuller
Website: http://www.wowace.com/wiki/LibKeyBound-1.0
Documentation: http://www.wowace.com/wiki/LibKeyBound-1.0
SVN: http://svn.wowace.com/wowace/trunk/LibKeyBound-1.0
Description: An intuitive keybindings system: mouseover frame, click keys or buttons.
Dependencies: CallbackHandler-1.0
--]]
local MAJOR = 'LibKeyBound-1.0'
local MINOR = tonumber(("$Revision: 95 $"):match("(%d+)")) + 90000
--[[
LibKeyBound-1.0
ClickBinder by Gello and TrinityBinder by Maul -> keyBound by Tuller -> LibKeyBound library by Toadkiller
Functions needed to implement
button:GetHotkey() - returns the current hotkey assigned to the given button
Functions to implement if using a custom keybindings system:
button:SetKey(key) - binds the given key to the given button
button:FreeKey(key) - unbinds the given key from all other buttons
button:ClearBindings() - removes all keys bound to the given button
button:GetBindings() - returns a string listing all bindings of the given button
button:GetActionName() - what we're binding to, used for printing
--]]
local LibKeyBound, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not LibKeyBound then return end -- no upgrade needed
local _G = _G
local NUM_MOUSE_BUTTONS = 31
-- CallbackHandler
LibKeyBound.events = LibKeyBound.events or _G.LibStub('CallbackHandler-1.0'):New(LibKeyBound)
local L = LibKeyBoundLocale10
LibKeyBound.L = L
-- ToDo delete global LibKeyBoundLocale10 at some point
LibKeyBound.Binder = LibKeyBound.Binder or {}
-- #NODOC
function LibKeyBound:Initialize()
do
local f = CreateFrame('Frame', 'KeyboundDialog', UIParent)
f:SetFrameStrata('DIALOG')
f:SetToplevel(true)
f:EnableMouse(true)
f:SetClampedToScreen(true)
f:SetWidth(360)
f:SetHeight(140)
f:SetBackdrop{
bgFile='Interface\\DialogFrame\\UI-DialogBox-Background' ,
edgeFile='Interface\\DialogFrame\\UI-DialogBox-Border',
tile = true,
insets = {left = 11, right = 12, top = 12, bottom = 11},
tileSize = 32,
edgeSize = 32,
}
f:SetPoint('TOP', 0, -24)
f:Hide()
f:SetScript('OnShow', function() PlaySound('igMainMenuOption') end)
f:SetScript('OnHide', function() PlaySound('gsTitleOptionExit') end)
local tr = f:CreateTitleRegion()
tr:SetAllPoints(f)
local header = f:CreateTexture(nil, 'ARTWORK')
header:SetTexture('Interface\\DialogFrame\\UI-DialogBox-Header')
header:SetWidth(256); header:SetHeight(64)
header:SetPoint('TOP', 0, 12)
local title = f:CreateFontString('ARTWORK')
title:SetFontObject('GameFontNormal')
title:SetPoint('TOP', header, 'TOP', 0, -14)
title:SetText(L.BindingMode)
local desc = f:CreateFontString('ARTWORK')
desc:SetFontObject('GameFontHighlight')
desc:SetJustifyV('TOP')
desc:SetJustifyH('LEFT')
desc:SetPoint('TOPLEFT', 18, -32)
desc:SetPoint('BOTTOMRIGHT', -18, 48)
desc:SetText(format(L.BindingsHelp, GetBindingText('ESCAPE', 'KEY_')))
-- Per character bindings checkbox
local perChar = CreateFrame('CheckButton', 'KeyboundDialogCheck', f, 'OptionsCheckButtonTemplate')
_G[perChar:GetName() .. 'Text']:SetText(CHARACTER_SPECIFIC_KEYBINDINGS)
perChar:SetScript('OnShow', function(self)
self:SetChecked(GetCurrentBindingSet() == 2)
end)
local current
perChar:SetScript('OnClick', function(self)
current = (perChar:GetChecked() and 2) or 1
LoadBindings(current)
end)
-- Okay bindings checkbox
local okayBindings = CreateFrame('CheckButton', 'KeyboundDialogOkay', f, 'OptionsButtonTemplate')
getglobal(okayBindings:GetName() .. 'Text'):SetText(OKAY)
okayBindings:SetScript('OnClick', function(self)
current = (perChar:GetChecked() and 2) or 1
if InCombatLockdown() then
self:RegisterEvent('PLAYER_REGEN_ENABLED')
else
SaveBindings(current)
LibKeyBound:Deactivate()
end
end)
okayBindings:SetScript('OnHide', function(self)
current = (perChar:GetChecked() and 2) or 1
if InCombatLockdown() then
self:RegisterEvent('PLAYER_REGEN_ENABLED')
else
SaveBindings(current)
end
end)
okayBindings:SetScript('OnEvent', function(self, event)
SaveBindings(current)
self:UnregisterEvent(event)
LibKeyBound:Deactivate()
end)
-- Cancel bindings checkbox
local cancelBindings = CreateFrame('CheckButton', 'KeyboundDialogCancel', f, 'OptionsButtonTemplate')
getglobal(cancelBindings:GetName() .. 'Text'):SetText(CANCEL)
cancelBindings:SetScript('OnClick', function(self)
if InCombatLockdown() then
self:RegisterEvent('PLAYER_REGEN_ENABLED')
else
LoadBindings(GetCurrentBindingSet())
LibKeyBound:Deactivate()
end
end)
cancelBindings:SetScript('OnEvent', function(self, event)
LoadBindings(GetCurrentBindingSet())
self:UnregisterEvent(event)
LibKeyBound:Deactivate()
end)
--position buttons
perChar:SetPoint('BOTTOMLEFT', 14, 32)
cancelBindings:SetPoint('BOTTOMRIGHT', -14, 14)
okayBindings:SetPoint('RIGHT', cancelBindings, 'LEFT')
self.dialog = f
end
SlashCmdList['LibKeyBoundSlashCOMMAND'] = function() self:Toggle() end
SLASH_LibKeyBoundSlashCOMMAND1 = '/libkeybound'
SLASH_LibKeyBoundSlashCOMMAND2 = '/kb'
SLASH_LibKeyBoundSlashCOMMAND3 = '/lkb'
LibKeyBound.initialized = true
end
-- Default color to indicate bindable frames in your mod.
LibKeyBound.colorKeyBoundMode = LibKeyBound.colorKeyBoundMode or { 0, 1, 1, 0.5 }
--[[
LibKeyBound:SetColorKeyBoundMode([r][, g][, b][, a])
--]]
--[[
Arguments:
number - red, default 0
number - green, default 0
number - blue, default 0
number - alpha, default 1
Example:
if (MyMod.keyBoundMode) then
overlayFrame:SetBackdropColor(LibKeyBound:GetColorKeyBoundMode())
end
...
local r, g, b, a = LibKeyBound:GetColorKeyBoundMode()
Notes:
* Returns the color to use on your participating buttons during KeyBound Mode
* Values are unpacked and ready to use as color arguments
--]]
function LibKeyBound:SetColorKeyBoundMode(r, g, b, a)
r, g, b, a = r or 0, g or 0, b or 0, a or 1
LibKeyBound.colorKeyBoundMode[1] = r
LibKeyBound.colorKeyBoundMode[2] = g
LibKeyBound.colorKeyBoundMode[3] = b
LibKeyBound.colorKeyBoundMode[4] = a
LibKeyBound.events:Fire('LIBKEYBOUND_MODE_COLOR_CHANGED')
end
--[[
Returns:
* number - red
* number - green
* number - blue
* number - alpha
Example:
if (MyMod.keyBoundMode) then
overlayFrame:SetBackdropColor(LibKeyBound:GetColorKeyBoundMode())
end
...
local r, g, b, a = LibKeyBound:GetColorKeyBoundMode()
Notes:
* Returns the color to use on your participating buttons during KeyBound Mode
* Values are unpacked and ready to use as color arguments
--]]
function LibKeyBound:GetColorKeyBoundMode()
return unpack(LibKeyBound.colorKeyBoundMode)
end
function LibKeyBound:PLAYER_REGEN_ENABLED()
if self.enabled then
UIErrorsFrame:AddMessage(L.CombatBindingsEnabled, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
self.dialog:Hide()
end
end
function LibKeyBound:PLAYER_REGEN_DISABLED()
if self.enabled then
self:Set(nil)
UIErrorsFrame:AddMessage(L.CombatBindingsDisabled, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
self.dialog:Show()
end
end
--[[
Notes:
* Switches KeyBound Mode between on and off
Example:
local LibKeyBound = LibStub('LibKeyBound-1.0')
LibKeyBound:Toggle()
--]]
function LibKeyBound:Toggle()
if (LibKeyBound:IsShown()) then
LibKeyBound:Deactivate()
else
LibKeyBound:Activate()
end
end
--[[
Notes:
* Switches KeyBound Mode to on
Example:
local LibKeyBound = LibStub('LibKeyBound-1.0')
LibKeyBound:Activate()
--]]
function LibKeyBound:Activate()
if not self:IsShown() then
if InCombatLockdown() then
UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
else
self.enabled = true
if not self.frame then
self.frame = LibKeyBound.Binder:Create()
end
self:Set(nil)
self.dialog:Show()
self.events:Fire('LIBKEYBOUND_ENABLED')
end
end
end
--[[
Notes:
* Switches KeyBound Mode to off
Example:
local LibKeyBound = LibStub('LibKeyBound-1.0')
LibKeyBound:Deactivate()
--]]
function LibKeyBound:Deactivate()
if self:IsShown() then
self.enabled = nil
self:Set(nil)
self.dialog:Hide()
self.events:Fire('LIBKEYBOUND_DISABLED')
end
end
--[[
Returns:
boolean - true if KeyBound Mode is currently on
Example:
local LibKeyBound = LibStub('LibKeyBound-1.0')
local isKeyBoundMode = LibKeyBound:IsShown()
if (isKeyBoundMode) then
-- Do something
else
-- Do another thing
end
Notes:
* Is KeyBound Mode currently on
--]]
function LibKeyBound:IsShown()
return self.enabled
end
--[[
Arguments:
table - the button frame
Example:
local button = this
LibKeyBound:Set(button)
Notes:
* Sets up button for keybinding
* Call this in your OnEnter script for the button
* Current bindings are shown in the tooltip
* Primary binding is shown in green in the button text
--]]
function LibKeyBound:Set(button)
local bindFrame = self.frame
if button and self:IsShown() and not InCombatLockdown() then
bindFrame.button = button
bindFrame:SetAllPoints(button)
bindFrame.text:SetFontObject('GameFontNormalLarge')
bindFrame.text:SetText(button:GetHotkey())
if bindFrame.text:GetStringWidth() > bindFrame:GetWidth() then
bindFrame.text:SetFontObject('GameFontNormal')
end
bindFrame:Show()
bindFrame:OnEnter()
elseif bindFrame then
bindFrame.button = nil
bindFrame:ClearAllPoints()
bindFrame:Hide()
end
end
--[[
Arguments:
string - the keyString to shorten
Returns:
string - the shortened displayString
Example:
local key1 = GetBindingKey(button:GetName())
local displayKey = LibKeyBound:ToShortKey(key1)
return displayKey
Notes:
* Shortens the key text (returned from GetBindingKey etc.)
* Result is suitable for display on a button
* Can be used for your button:GetHotkey() return value
--]]
function LibKeyBound:ToShortKey(key)
if key then
key = key:upper()
key = key:gsub(' ', '')
key = key:gsub('ALT%-', L['Alt'])
key = key:gsub('CTRL%-', L['Ctrl'])
key = key:gsub('SHIFT%-', L['Shift'])
key = key:gsub('NUMPAD', L['NumPad'])
key = key:gsub('PLUS', '%+')
key = key:gsub('MINUS', '%-')
key = key:gsub('MULTIPLY', '%*')
key = key:gsub('DIVIDE', '%/')
key = key:gsub('BACKSPACE', L['Backspace'])
for i = 1, NUM_MOUSE_BUTTONS do
key = key:gsub('BUTTON' .. i, L['Button' .. i])
end
key = key:gsub('CAPSLOCK', L['Capslock'])
key = key:gsub('CLEAR', L['Clear'])
key = key:gsub('DELETE', L['Delete'])
key = key:gsub('END', L['End'])
key = key:gsub('HOME', L['Home'])
key = key:gsub('INSERT', L['Insert'])
key = key:gsub('MOUSEWHEELDOWN', L['Mouse Wheel Down'])
key = key:gsub('MOUSEWHEELUP', L['Mouse Wheel Up'])
key = key:gsub('NUMLOCK', L['Num Lock'])
key = key:gsub('PAGEDOWN', L['Page Down'])
key = key:gsub('PAGEUP', L['Page Up'])
key = key:gsub('SCROLLLOCK', L['Scroll Lock'])
key = key:gsub('SPACEBAR', L['Spacebar'])
key = key:gsub('TAB', L['Tab'])
key = key:gsub('DOWNARROW', L['Down Arrow'])
key = key:gsub('LEFTARROW', L['Left Arrow'])
key = key:gsub('RIGHTARROW', L['Right Arrow'])
key = key:gsub('UPARROW', L['Up Arrow'])
return key
end
end
--[[ Binder Widget ]]--
function LibKeyBound.Binder:Create()
local binder = CreateFrame('Button')
binder:RegisterForClicks('anyUp')
binder:SetFrameStrata('DIALOG')
binder:EnableKeyboard(true)
binder:EnableMouseWheel(true)
for k,v in pairs(self) do
binder[k] = v
end
local bg = binder:CreateTexture()
bg:SetTexture(0, 0, 0, 0.5)
bg:SetAllPoints(binder)
local text = binder:CreateFontString('OVERLAY')
text:SetFontObject('GameFontNormalLarge')
text:SetTextColor(0, 1, 0)
text:SetAllPoints(binder)
binder.text = text
binder:SetScript('OnClick', self.OnKeyDown)
binder:SetScript('OnKeyDown', self.OnKeyDown)
binder:SetScript('OnMouseWheel', self.OnMouseWheel)
binder:SetScript('OnEnter', self.OnEnter)
binder:SetScript('OnLeave', self.OnLeave)
binder:SetScript('OnHide', self.OnHide)
binder:Hide()
return binder
end
function LibKeyBound.Binder:OnHide()
LibKeyBound:Set(nil)
end
function LibKeyBound.Binder:OnKeyDown(key)
local button = self.button
if not button then return end
if (key == 'UNKNOWN' or key == 'LSHIFT' or key == 'RSHIFT' or
key == 'LCTRL' or key == 'RCTRL' or key == 'LALT' or key == 'RALT') then
return
end
local screenshotKey = GetBindingKey('SCREENSHOT')
if screenshotKey and key == screenshotKey then
Screenshot()
return
end
local openChatKey = GetBindingKey('OPENCHAT')
if openChatKey and key == openChatKey then
ChatFrameEditBox:Show()
return
end
if key == 'ESCAPE' then
self:ClearBindings(button)
LibKeyBound:Set(button)
return
end
-- dont bind unmodified left or right button
if (key == 'LeftButton' or key == 'RightButton') and not IsModifierKeyDown() then
return
end
--handle mouse button substitutions
if key == 'LeftButton' then
key = 'BUTTON1'
elseif key == 'RightButton' then
key = 'BUTTON2'
elseif key == 'MiddleButton' then
key = 'BUTTON3'
elseif key:match('^Button%d+$') then
key = key:upper()
end
--apply modifiers
if IsModifierKeyDown() then
if IsShiftKeyDown() then
key = 'SHIFT-' .. key
end
if IsControlKeyDown() then
key = 'CTRL-' .. key
end
if IsAltKeyDown() then
key = 'ALT-' .. key
end
end
if button:IsMouseOver() then
self:SetKey(button, key)
LibKeyBound:Set(button)
end
end
function LibKeyBound.Binder:OnMouseWheel(arg1)
if arg1 > 0 then
self:OnKeyDown('MOUSEWHEELUP')
else
self:OnKeyDown('MOUSEWHEELDOWN')
end
end
function LibKeyBound.Binder:OnEnter()
local button = self.button
if button and not InCombatLockdown() then
if self:GetRight() >= (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
if button.GetActionName then
GameTooltip:SetText(button:GetActionName(), 1, 1, 1)
else
GameTooltip:SetText(button:GetName(), 1, 1, 1)
end
local bindings = self:GetBindings(button)
if bindings then
GameTooltip:AddLine(bindings, 0, 1, 0)
GameTooltip:AddLine(L.ClearTip)
else
GameTooltip:AddLine(L.NoKeysBoundTip, 0, 1, 0)
end
GameTooltip:Show()
else
GameTooltip:Hide()
end
end
function LibKeyBound.Binder:OnLeave()
LibKeyBound:Set(nil)
GameTooltip:Hide()
end
--[[ Update Functions ]]--
function LibKeyBound.Binder:ToBinding(button)
return format('CLICK %s:LeftButton', button:GetName())
end
function LibKeyBound.Binder:FreeKey(button, key)
local msg
if button.FreeKey then
local action = button:FreeKey(key)
if button:FreeKey(key) then
msg = format(L.UnboundKey, GetBindingText(key, 'KEY_'), action)
end
else
local action = GetBindingAction(key)
if action and action ~= '' and action ~= self:ToBinding(button) then
msg = format(L.UnboundKey, GetBindingText(key, 'KEY_'), action)
end
end
if msg then
UIErrorsFrame:AddMessage(msg, 1, 0.82, 0, 1, UIERRORS_HOLD_TIME)
end
end
function LibKeyBound.Binder:SetKey(button, key)
if InCombatLockdown() then
UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
else
self:FreeKey(button, key)
if button.SetKey then
button:SetKey(key)
else
SetBindingClick(key, button:GetName(), 'LeftButton')
end
local msg
if button.GetActionName then
msg = format(L.BoundKey, GetBindingText(key, 'KEY_'), button:GetActionName())
else
msg = format(L.BoundKey, GetBindingText(key, 'KEY_'), button:GetName())
end
UIErrorsFrame:AddMessage(msg, 1, 1, 1, 1, UIERRORS_HOLD_TIME)
end
end
function LibKeyBound.Binder:ClearBindings(button)
if InCombatLockdown() then
UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
else
if button.ClearBindings then
button:ClearBindings()
else
local binding = self:ToBinding(button)
while (GetBindingKey(binding)) do
SetBinding(GetBindingKey(binding), nil)
end
end
local msg
if button.GetActionName then
msg = format(L.ClearedBindings, button:GetActionName())
else
msg = format(L.ClearedBindings, button:GetName())
end
UIErrorsFrame:AddMessage(msg, 1, 1, 1, 1, UIERRORS_HOLD_TIME)
end
end
function LibKeyBound.Binder:GetBindings(button)
if button.GetBindings then
return button:GetBindings()
end
local keys
local binding = self:ToBinding(button)
for i = 1, select('#', GetBindingKey(binding)) do
local hotKey = select(i, GetBindingKey(binding))
if keys then
keys = keys .. ', ' .. GetBindingText(hotKey, 'KEY_')
else
keys = GetBindingText(hotKey, 'KEY_')
end
end
return keys
end
LibKeyBound.EventButton = LibKeyBound.EventButton or CreateFrame('Frame')
do
local EventButton = LibKeyBound.EventButton
EventButton:UnregisterAllEvents()
EventButton:SetScript('OnEvent', function(self, event, addon)
if (event == 'PLAYER_REGEN_DISABLED') then
LibKeyBound:PLAYER_REGEN_DISABLED()
elseif (event == 'PLAYER_REGEN_ENABLED') then
LibKeyBound:PLAYER_REGEN_ENABLED()
elseif (event == 'PLAYER_LOGIN' and not LibKeyBound.initialized) then
LibKeyBound:Initialize()
EventButton:UnregisterEvent('PLAYER_LOGIN')
end
end)
if IsLoggedIn() and not LibKeyBound.initialized then
LibKeyBound:Initialize()
elseif not LibKeyBound.initialized then
EventButton:RegisterEvent('PLAYER_LOGIN')
end
EventButton:RegisterEvent('PLAYER_REGEN_ENABLED')
EventButton:RegisterEvent('PLAYER_REGEN_DISABLED')
end
+87
View File
@@ -0,0 +1,87 @@
--[[
LibKeyBound-1.0 localization file
Deutch by Gamefaq
--]]
if (GetLocale() ~= "deDE") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
Enabled = "Tastenzuweisung Modus aktiviert";
Disabled = "Tastenzuweisung Modus deaktiviert";
ClearTip = format("Drücke %s um alle Tastenzuweisungen zu löschen", GetBindingText("ESCAPE", "KEY_"));
NoKeysBoundTip = "Keine Tasten zugewiesen";
ClearedBindings = "Entferne alle Zuweisungen von %s";
BoundKey = "Setze %s zu %s";
UnboundKey = "Entferne %s von %s";
CannotBindInCombat = "Kann Tasten nicht im Kampf zuweisen";
CombatBindingsEnabled = "Verlasse Kampf, Tastenzuweisung Modus aktiviert";
CombatBindingsDisabled = "Beginne Kampf, Tastenzuweisung Modus deaktiviert";
BindingsHelp = "Schwebe mit der Maus über einem Schalter. Drück dann eine Taste um sie zuzuweisen. Um die Belegung der Taste wieder zu löschen drück %s.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "S",
["Shift"] = "U",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "En",
["Home"] = "HM",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "WD",
["Mouse Wheel Up"] = "WU",
["Num Lock"] = "NL",
["Page Down"] = "PD",
["Page Up"] = "PU",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "DA",
["Left Arrow"] = "LA",
["Right Arrow"] = "RA",
["Up Arrow"] = "UA",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+157
View File
@@ -0,0 +1,157 @@
--[[
KeyBound localization file
English
--]]
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundBaseLocale10 and REVISION <= LibKeyBoundBaseLocale10.BASEREVISION) then
return
end
LibKeyBoundBaseLocale10 = {
REVISION = 0;
BASEREVISION = REVISION;
BindingMode = "Binding Mode";
Enabled = 'Bindings mode enabled';
Disabled = 'Bindings mode disabled';
ClearTip = format('Press %s to clear all bindings', GetBindingText('ESCAPE', 'KEY_'));
NoKeysBoundTip = 'No current bindings';
ClearedBindings = 'Removed all bindings from %s';
BoundKey = 'Set %s to %s';
UnboundKey = 'Unbound %s from %s';
CannotBindInCombat = 'Cannot bind keys in combat';
CombatBindingsEnabled = 'Exiting combat, keybinding mode enabled';
CombatBindingsDisabled = 'Entering combat, keybinding mode disabled';
BindingsHelp = "Hover over a button, then press a key to set its binding. To clear a button's current keybinding, press %s.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "En",
["Home"] = "HM",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "WD",
["Mouse Wheel Up"] = "WU",
["Num Lock"] = "NL",
["Page Down"] = "PD",
["Page Up"] = "PU",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "Dn",
["Left Arrow"] = "Lf",
["Right Arrow"] = "Rt",
["Up Arrow"] = "Up",
}
if not LibKeyBoundLocale10 then
LibKeyBoundLocale10 = LibKeyBoundBaseLocale10
else
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
end
--[[
World of Warcraft/Blizzard Interface Data (enUS)/FrameXML/GlobalStrings.lua:
KEY_APOSTROPHE = "'";
KEY_BACKSLASH = "\\";
KEY_BACKSPACE = "Backspace";
KEY_BACKSPACE_MAC = "Delete";
KEY_BINDING = "Key Binding";
KEY_BINDINGS = "Key Bindings"; -- Title for the key bindings frame
KEY_BINDINGS_MAC = "Bindings";
KEY_BOUND = "Key Bound Successfully";
KEY_BUTTON1 = "Left Mouse Button";
KEY_BUTTON2 = "Right Mouse Button";
KEY_BUTTON3 = "Middle Mouse";
KEY_BUTTON4 = "Mouse Button 4";
KEY_BUTTON5 = "Mouse Button 5";
KEY_COMMA = ",";
KEY_DELETE = "Delete";
KEY_DELETE_MAC = "Del";
KEY_DOWN = "Down Arrow";
KEY_END = "End";
KEY_HOME = "Home";
KEY_INSERT = "Insert";
KEY_INSERT_MAC = "Help";
KEY_LEFT = "Left Arrow";
KEY_LEFTBRACKET = "[";
KEY_MINUS = "-";
KEY_MOUSEWHEELDOWN = "Mouse Wheel Down";
KEY_MOUSEWHEELUP = "Mouse Wheel Up";
KEY_NUMLOCK = "Num Lock";
KEY_NUMLOCK_MAC = "Clear";
KEY_NUMPAD0 = "Num Pad 0";
KEY_NUMPAD1 = "Num Pad 1";
KEY_NUMPAD2 = "Num Pad 2";
KEY_NUMPAD3 = "Num Pad 3";
KEY_NUMPAD4 = "Num Pad 4";
KEY_NUMPAD5 = "Num Pad 5";
KEY_NUMPAD6 = "Num Pad 6";
KEY_NUMPAD7 = "Num Pad 7";
KEY_NUMPAD8 = "Num Pad 8";
KEY_NUMPAD9 = "Num Pad 9";
KEY_NUMPADDECIMAL = "Num Pad .";
KEY_NUMPADDIVIDE = "Num Pad /";
KEY_NUMPADMINUS = "Num Pad -";
KEY_NUMPADMULTIPLY = "Num Pad *";
KEY_NUMPADPLUS = "Num Pad +";
KEY_PAGEDOWN = "Page Down";
KEY_PAGEUP = "Page Up";
KEY_PAUSE = "Pause";
KEY_PAUSE_MAC = "F15";
KEY_PERIOD = ".";
KEY_PLUS = "+";
KEY_PRINTSCREEN = "Print Screen";
KEY_PRINTSCREEN_MAC = "F13";
KEY_RIGHT = "Right Arrow";
KEY_RIGHTBRACKET = "]";
KEY_SCROLLLOCK = "Scroll Lock";
KEY_SCROLLLOCK_MAC = "F14";
KEY_SEMICOLON = ";";
KEY_SLASH = "/";
KEY_SPACE = "Spacebar"; -- Spacebar
KEY_TAB = "Tab";
KEY_TILDE = "~";
KEY_UNBOUND_ERROR = "|cffff0000%s Function is Now Unbound!|r";
KEY_UP = "Up Arrow";
KEY_ESCAPE = "Escape";
--]]
+87
View File
@@ -0,0 +1,87 @@
--[[
LibKeyBound-1.0 localization file
Spanish by StiviS
--]]
if (GetLocale() ~= "esES") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
Enabled = 'Modo Atajos activado';
Disabled = 'Modo Atajos desactivado';
ClearTip = format('Pulsa %s para limpiar todos los atajos', GetBindingText('ESCAPE', 'KEY_'));
NoKeysBoundTip = 'No existen atajos';
ClearedBindings = 'Eliminados todos los atajos de %s';
BoundKey = 'Establecer %s a %s';
UnboundKey = 'Quitado atajo %s de %s';
CannotBindInCombat = 'No se pueden atajar teclas en combate';
CombatBindingsEnabled = 'Saliendo de combate, modo de Atajos de Teclado activado';
CombatBindingsDisabled = 'Entrando en combate, modo de Atajos de Teclado desactivado';
BindingsHelp = "Sitúese en un botón, entonces pulse una tecla para establecer su atajo. Para limpiar el Atajo del botón actual, pulse %s.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "Fin",
["Home"] = "Ini",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "AW",
["Mouse Wheel Up"] = "RW",
["Num Lock"] = "NL",
["Page Down"] = "AP",
["Page Up"] = "RP",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "Ar",
["Left Arrow"] = "Ab",
["Right Arrow"] = "Iz",
["Up Arrow"] = "De",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+87
View File
@@ -0,0 +1,87 @@
--[[
LibKeyBound-1.0 localization file
Latin America Spanish by ?
--]]
if (GetLocale() ~= "esMX") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
Enabled = 'Modo Atajos activado';
Disabled = 'Modo Atajos desactivado';
ClearTip = format('Pulsa %s para limpiar todos los atajos', GetBindingText('ESCAPE', 'KEY_'));
NoKeysBoundTip = 'No existen atajos';
ClearedBindings = 'Eliminados todos los atajos de %s';
BoundKey = 'Establecer %s a %s';
UnboundKey = 'Quitado atajo %s de %s';
CannotBindInCombat = 'No se pueden atajar teclas en combate';
CombatBindingsEnabled = 'Saliendo de combate, modo de Atajos de Teclado activado';
CombatBindingsDisabled = 'Entrando en combate, modo de Atajos de Teclado desactivado';
BindingsHelp = "Sitúese en un botón, entonces pulse una tecla para establecer su atajo. Para limpiar el Atajo del botón actual, pulse %s.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "Fin",
["Home"] = "Ini",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "AW",
["Mouse Wheel Up"] = "RW",
["Num Lock"] = "NL",
["Page Down"] = "AP",
["Page Up"] = "RP",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "Ar",
["Left Arrow"] = "Ab",
["Right Arrow"] = "Iz",
["Up Arrow"] = "De",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+87
View File
@@ -0,0 +1,87 @@
--[[
LibKeyBound-1.0 localization file
French by ?
--]]
if (GetLocale() ~= "frFR") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
Enabled = "Mode Raccourcis activé";
Disabled = "Mode Raccourcis désactivé";
ClearTip = format("Appuyez sur %s pour effacer tous les raccourcis", GetBindingText("ESCAPE", "KEY_"));
NoKeysBoundTip = "Aucun raccourci";
ClearedBindings = "Suppression de tous les raccourcis de %s";
BoundKey = "%s associé à %s";
UnboundKey = "%s n'est plus associé à %s";
CannotBindInCombat = "Impossible de faire des raccourcis en combat";
CombatBindingsEnabled = "Sortie de combat, mode Raccourcis activé";
CombatBindingsDisabled = "Entrée en combat, mode Raccourcis désactivé";
BindingsHelp = "Survolez un bouton, puis appuyez sur une touche pour définir son raccourci. Pour effacer le raccourci actuel d'un bouton, appuyez sur %s";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "En",
["Home"] = "HM",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "WD",
["Mouse Wheel Up"] = "WU",
["Num Lock"] = "NL",
["Page Down"] = "PD",
["Page Up"] = "PU",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "BA",
["Left Arrow"] = "GA",
["Right Arrow"] = "DA",
["Up Arrow"] = "HA",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+87
View File
@@ -0,0 +1,87 @@
--[[
KeyBound localization file
Korean by damjau
--]]
if (GetLocale() ~= "koKR") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
Enabled = '단축키 설정 기능 사용 가능';
Disabled = '단축키 설정 기능 사용 불가';
ClearTip = format('%s키를 누르면 모든 단축키가 초기화됩니다', GetBindingText('ESCAPE', 'KEY_'));
NoKeysBoundTip = '현재 단축키 없음';
ClearedBindings = '%s의 모든 단축키가 초기화 되었습니다';
BoundKey = '%2$s의 단축키로 %1$s|1을;를; 설정합니다.';
UnboundKey = '%2$s에서 %1$s의 단축키가 삭제되었습니다';
CannotBindInCombat = '전투 중에는 단축키를 지정할 수 없습니다';
CombatBindingsEnabled = '전투 종료. 단축키 설정이 가능해집니다';
CombatBindingsDisabled = '전투 시작. 단축키 설정이 불가능합니다';
BindingsHelp = "버튼 위에 마우스를 올려 놓고 지정할 키를 누르세요. 버튼의 현재 단축키를 삭제하시려면 %s|1을;를; 누르세요.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "En",
["Home"] = "HM",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "WD",
["Mouse Wheel Up"] = "WU",
["Num Lock"] = "NL",
["Page Down"] = "PD",
["Page Up"] = "PU",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "DA",
["Left Arrow"] = "LA",
["Right Arrow"] = "RA",
["Up Arrow"] = "UA",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+87
View File
@@ -0,0 +1,87 @@
--[[
KeyBound localization file
Russian by ?
--]]
if (GetLocale() ~= "ruRU") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
Enabled = 'Режим назначения клавиш включен';
Disabled = 'Режим назначения клавиш отключен';
ClearTip = format('Нажмите %s для сброса всех назначений', GetBindingText('ESCAPE', 'KEY_'));
NoKeysBoundTip = 'Нет текущих назначений';
ClearedBindings = 'Удалить все назначения с %s';
BoundKey = 'Установить %s на %s';
UnboundKey = 'Снять назначение %s с %s';
CannotBindInCombat = 'Невозможно назначить клавишу в бою';
CombatBindingsEnabled = 'Выход из боя, режим назначения клавиш включен';
CombatBindingsDisabled = 'Начало боя, режим назначения клавиш отключен';
BindingsHelp = "Зависните над кнопкой, и тогда нажмите клавишу для установки назначения.  Для очистки текущих назначений клавиш, нажмите %s.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "Ц",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "En",
["Home"] = "HM",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "КМВХ",
["Mouse Wheel Up"] = "КМВЗ",
["Num Lock"] = "NL",
["Page Down"] = "PD",
["Page Up"] = "PU",
["Scroll Lock"] = "SL",
["Spacebar"] = "Прбл",
["Tab"] = "Tb",
["Down Arrow"] = "Dn",
["Left Arrow"] = "Lf",
["Right Arrow"] = "Rt",
["Up Arrow"] = "Up",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+88
View File
@@ -0,0 +1,88 @@
--[[
KeyBound localization file
Chinese Simplified by ondh - http://www.ondh.cn
--]]
if (GetLocale() ~= "zhCN") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
BindingMode = "Binding Mode";
Enabled = "按键绑定模式已启用";
Disabled = "按键绑定模式已禁用";
ClearTip = format("按 %s 清除所有绑定", GetBindingText("ESCAPE", "KEY_"));
NoKeysBoundTip = "当前没有绑定按键";
ClearedBindings = "从 %s 移除按键绑定";
BoundKey = "设置 %s 到 %s";
UnboundKey = "取消绑定 %s 从 %s";
CannotBindInCombat = "不能在战斗状态绑定按键";
CombatBindingsEnabled = "离开战斗状态, 按键绑定模式已启用";
CombatBindingsDisabled = "进入战斗状态, 按键绑定模式已禁用";
BindingsHelp = "将鼠标停留在按钮上, 然后按下欲指定快捷键之后就能绑定。 要清除目前绑定的按钮请按 %s.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "B1",
["Button2"] = "B2",
["Button3"] = "B3",
["Button4"] = "B4",
["Button5"] = "B5",
["Button6"] = "B6",
["Button7"] = "B7",
["Button8"] = "B8",
["Button9"] = "B9",
["Button10"] = "B10",
["Button11"] = "B11",
["Button12"] = "B12",
["Button13"] = "B13",
["Button14"] = "B14",
["Button15"] = "B15",
["Button16"] = "B16",
["Button17"] = "B17",
["Button18"] = "B18",
["Button19"] = "B19",
["Button20"] = "B20",
["Button21"] = "B21",
["Button22"] = "B22",
["Button23"] = "B23",
["Button24"] = "B24",
["Button25"] = "B25",
["Button26"] = "B26",
["Button27"] = "B27",
["Button28"] = "B28",
["Button29"] = "B29",
["Button30"] = "B30",
["Button31"] = "B31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "En",
["Home"] = "HM",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "WD",
["Mouse Wheel Up"] = "WU",
["Num Lock"] = "NL",
["Page Down"] = "PD",
["Page Up"] = "PU",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "DA",
["Left Arrow"] = "LA",
["Right Arrow"] = "RA",
["Up Arrow"] = "UA",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+87
View File
@@ -0,0 +1,87 @@
--[[
KeyBound localization file
Traditional Chinese by ?
--]]
if (GetLocale() ~= "zhTW") then
return
end
local REVISION = 90000 + tonumber(("$Revision: 92 $"):match("%d+"))
if (LibKeyBoundLocale10 and REVISION <= LibKeyBoundLocale10.REVISION) then
return
end
LibKeyBoundLocale10 = {
REVISION = REVISION;
Enabled = "按鍵綁定模式已啟用";
Disabled = "按鍵綁定模式已停用";
ClearTip = format("按 %s 清除所有綁定", GetBindingText("ESCAPE", "KEY_"));
NoKeysBoundTip = "目前沒有綁定按鍵";
ClearedBindings = "從 %s 移除按鍵綁定";
BoundKey = "設定 %s 到 %s";
UnboundKey = "取消綁定 %s 從 %s";
CannotBindInCombat = "無法在戰鬥狀態綁定按鍵";
CombatBindingsEnabled = "離開戰鬥狀態, 按鍵綁定模式已啟用";
CombatBindingsDisabled = "進入戰鬥狀態, 按鍵綁定模式已停用";
BindingsHelp = "將滑鼠停留在按鈕上, 然後按下欲指定快捷鍵之後就能綁定。 要清除目前綁定的按鈕請按 %s.";
-- This is the short display version you see on the Button
["Alt"] = "A",
["Ctrl"] = "C",
["Shift"] = "S",
["NumPad"] = "N",
["Backspace"] = "BS",
["Button1"] = "鼠1",
["Button2"] = "鼠2",
["Button3"] = "鼠3",
["Button4"] = "鼠4",
["Button5"] = "鼠5",
["Button6"] = "鼠6",
["Button7"] = "鼠7",
["Button8"] = "鼠8",
["Button9"] = "鼠9",
["Button10"] = "鼠10",
["Button11"] = "鼠11",
["Button12"] = "鼠12",
["Button13"] = "鼠13",
["Button14"] = "鼠14",
["Button15"] = "鼠15",
["Button16"] = "鼠16",
["Button17"] = "鼠17",
["Button18"] = "鼠18",
["Button19"] = "鼠19",
["Button20"] = "鼠20",
["Button21"] = "鼠21",
["Button22"] = "鼠22",
["Button23"] = "鼠23",
["Button24"] = "鼠24",
["Button25"] = "鼠25",
["Button26"] = "鼠26",
["Button27"] = "鼠27",
["Button28"] = "鼠28",
["Button29"] = "鼠29",
["Button30"] = "鼠30",
["Button31"] = "鼠31",
["Capslock"] = "Cp",
["Clear"] = "Cl",
["Delete"] = "Del",
["End"] = "En",
["Home"] = "HM",
["Insert"] = "Ins",
["Mouse Wheel Down"] = "WD",
["Mouse Wheel Up"] = "WU",
["Num Lock"] = "NL",
["Page Down"] = "PD",
["Page Up"] = "PU",
["Scroll Lock"] = "SL",
["Spacebar"] = "Sp",
["Tab"] = "Tb",
["Down Arrow"] = "",
["Left Arrow"] = "",
["Right Arrow"] = "",
["Up Arrow"] = "",
}
setmetatable(LibKeyBoundLocale10, {__index = LibKeyBoundBaseLocale10})
+13
View File
@@ -0,0 +1,13 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="Locale-deDE.lua"/>
<Script file="Locale-enUS.lua"/>
<Script file="Locale-esES.lua"/>
<Script file="Locale-esMX.lua"/>
<Script file="Locale-frFR.lua"/>
<Script file="Locale-koKR.lua"/>
<Script file="Locale-zhCN.lua"/>
<Script file="Locale-zhTW.lua"/>
<Script file="Locale-ruRU.lua"/>
<Script file="LibKeyBound-1.0.lua"/>
</Ui>
+30
View File
@@ -0,0 +1,30 @@
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
+13
View File
@@ -0,0 +1,13 @@
## Interface: 20400
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS
## X-Category: Library
## X-License: Public Domain
## X-Curse-Packaged-Version: 1.0
## X-Curse-Project-Name: LibStub
## X-Curse-Project-ID: libstub
## X-Curse-Repository-ID: wow/libstub/mainline
LibStub.lua
+317
View File
@@ -0,0 +1,317 @@
--[[
Name: LibWindow-1.1
Revision: $Rev: 5 $
Author(s): Mikk (dpsgnome@mail.com)
Website: http://old.wowace.com/wiki/LibWindow-1.1
Documentation: http://old.wowace.com/wiki/LibWindow-1.1
SVN: http://svn.wowace.com/root/trunk/WindowLib/Window-1.0
Description: A library that handles the basics of "window" style frames: scaling, smart position saving, dragging..
Dependencies: none
License: Public Domain
]]
local MAJOR = "LibWindow-1.1"
local MINOR = tonumber(("$Revision: 5 $"):match("(%d+)"))
local lib = LibStub:NewLibrary(MAJOR,MINOR)
if not lib then return end
local min,max,abs = min,max,abs
local pairs = pairs
local tostring = tostring
local UIParent,GetScreenWidth,GetScreenHeight,IsAltKeyDown = UIParent,GetScreenWidth,GetScreenHeight,IsAltKeyDown
-- GLOBALS: error, ChatFrame1, assert
local function print(msg) ChatFrame1:AddMessage(MAJOR..": "..tostring(msg)) end
lib.utilFrame = lib.utilFrame or CreateFrame("Frame")
lib.delayedSavePosition = lib.delayedSavePosition or {}
lib.windowData = lib.windowData or {}
--[frameref]={
-- names={optional names data from .RegisterConfig()}
-- storage= -- tableref where config data is read/written
-- altEnable=true/false
--}
lib.embeds = lib.embeds or {}
local mixins = {} -- "FuncName"=true
---------------------------------------------------------
-- UTILITIES
---------------------------------------------------------
local function getStorageName(frame, name)
local names = lib.windowData[frame].names
if names then
if names[name] then
return names[name]
end
if names.prefix then
return names.prefix .. name;
end
end
return name;
end
local function setStorage(frame, name, value)
lib.windowData[frame].storage[getStorageName(frame, name)] = value
end
local function getStorage(frame, name)
return lib.windowData[frame].storage[getStorageName(frame, name)]
end
lib.utilFrame:SetScript("OnUpdate", function(this)
this:Hide()
for frame,_ in pairs(lib.delayedSavePosition) do
lib.delayedSavePosition[frame] = nil
lib.SavePosition(frame)
end
end)
local function queueSavePosition(frame)
lib.delayedSavePosition[frame] = true
lib.utilFrame:Show()
end
---------------------------------------------------------
-- IMPORTANT APIS
---------------------------------------------------------
mixins["RegisterConfig"]=true
function lib.RegisterConfig(frame, storage, names)
if not lib.windowData[frame] then
lib.windowData[frame] = {}
end
lib.windowData[frame].names = names
lib.windowData[frame].storage = storage
--[[ debug
frame.tx = frame:CreateTexture()
frame.tx:SetTexture(0,0,0, 0.4)
frame.tx:SetAllPoints(frame)
frame.tx:Show()
]]
end
---------------------------------------------------------
-- POSITIONING AND SCALING
---------------------------------------------------------
local nilParent = {
GetWidth = function()
return GetScreenWidth() * UIParent:GetScale()
end,
GetHeight = function()
return GetScreenHeight() * UIParent:GetScale()
end,
GetScale = function()
return 1
end,
}
mixins["SavePosition"]=true
function lib.SavePosition(frame)
local parent = frame:GetParent() or nilParent
-- No, this won't work very well with frames that aren't parented to nil or UIParent
local s = frame:GetScale()
local left,top = frame:GetLeft()*s, frame:GetTop()*s
local right,bottom = frame:GetRight()*s, frame:GetBottom()*s
local pwidth, pheight = parent:GetWidth(), parent:GetHeight()
local x,y,point;
if left < (pwidth-right) and left < abs((left+right)/2 - pwidth/2) then
x = left;
point="LEFT";
elseif (pwidth-right) < abs((left+right)/2 - pwidth/2) then
x = right-pwidth;
point="RIGHT";
else
x = (left+right)/2 - pwidth/2;
point="";
end
if bottom < (pheight-top) and bottom < abs((bottom+top)/2 - pheight/2) then
y = bottom;
point="BOTTOM"..point;
elseif (pheight-top) < abs((bottom+top)/2 - pheight/2) then
y = top-pheight;
point="TOP"..point;
else
y = (bottom+top)/2 - pheight/2;
-- point=""..point;
end
if point=="" then
point = "CENTER"
end
setStorage(frame, "x", x)
setStorage(frame, "y", y)
setStorage(frame, "point", point)
setStorage(frame, "scale", s)
frame:ClearAllPoints()
frame:SetPoint(point, frame:GetParent(), point, x/s, y/s);
end
mixins["RestorePosition"]=true
function lib.RestorePosition(frame)
local x = getStorage(frame, "x")
local y = getStorage(frame, "y")
local point = getStorage(frame, "point")
local s = getStorage(frame, "scale")
if s then
frame:SetScale(s)
else
s = frame:GetScale()
end
if not x or not y then -- nothing stored in config yet, smack it in the center
x=0; y=0; point="CENTER"
end
x = x/s
y = y/s
frame:ClearAllPoints()
if not point and y==0 then -- errr why did i do this check again? must have been a reason, but i can't remember it =/
point="CENTER"
end
if not point then -- we have position, but no point, which probably means we're going from data stored by the addon itself before LibWindow was added to it. It was PROBABLY topleft->bottomleft anchored. Most do it that way.
frame:SetPoint("TOPLEFT", frame:GetParent(), "BOTTOMLEFT", x, y)
-- make it compute a better attachpoint (on next update)
queueSavePosition(frame)
return
end
frame:SetPoint(point, frame:GetParent(), point, x, y)
end
mixins["SetScale"]=true
function lib.SetScale(frame, scale)
setStorage(frame, "scale", scale)
frame:SetScale(scale)
lib.RestorePosition(frame)
end
---------------------------------------------------------
-- DRAG SUPPORT
---------------------------------------------------------
function lib.OnDragStart(frame)
lib.windowData[frame].isDragging = true
frame:StartMoving()
end
function lib.OnDragStop(frame)
frame:StopMovingOrSizing()
lib.SavePosition(frame)
lib.windowData[frame].isDragging = false
if lib.windowData[frame].altEnable and not IsAltKeyDown() then
frame:EnableMouse(false)
end
end
local function onDragStart(...) return lib.OnDragStart(...) end -- upgradable
local function onDragStop(...) return lib.OnDragStop(...) end -- upgradable
mixins["MakeDraggable"]=true
function lib.MakeDraggable(frame)
assert(lib.windowData[frame])
frame:SetMovable(true)
frame:SetScript("OnDragStart", onDragStart)
frame:SetScript("OnDragStop", onDragStop)
frame:RegisterForDrag("LeftButton")
end
---------------------------------------------------------
-- MOUSEWHEEL
---------------------------------------------------------
function lib.OnMouseWheel(frame, dir)
local scale = getStorage(frame, "scale")
if dir<0 then
scale=max(scale*0.9, 0.1)
else
scale=min(scale/0.9, 3)
end
lib.SetScale(frame, scale)
end
local function onMouseWheel(...) return lib.OnMouseWheel(...) end -- upgradable
mixins["EnableMouseWheelScaling"]=true
function lib.EnableMouseWheelScaling(frame)
frame:SetScript("OnMouseWheel", onMouseWheel)
end
---------------------------------------------------------
-- ENABLEMOUSE-ON-ALT
---------------------------------------------------------
lib.utilFrame:SetScript("OnEvent", function(this, event, key, state)
if event=="MODIFIER_STATE_CHANGED" then
if key == "LALT" or key == "RALT" then
for frame,_ in pairs(lib.altEnabledFrames) do
if not lib.windowData[frame].isDragging then -- if it's already dragging, it'll disable mouse on DragStop instead
frame:EnableMouse(state == 1)
end
end
end
end
end)
mixins["EnableMouseOnAlt"]=true
function lib.EnableMouseOnAlt(frame)
assert(lib.windowData[frame])
lib.windowData[frame].altEnable = true
frame:EnableMouse(not not IsAltKeyDown())
if not lib.altEnabledFrames then
lib.altEnabledFrames = {}
lib.utilFrame:RegisterEvent("MODIFIER_STATE_CHANGED")
end
lib.altEnabledFrames[frame] = true
end
---------------------------------------------------------
-- Embed support (into FRAMES, not addons!)
---------------------------------------------------------
function lib:Embed(target)
if not target or not target[0] or not target.GetObjectType then
error("Usage: LibWindow:Embed(frame)", 1)
end
for name, _ in pairs(mixins) do
target[name] = self[name]
end
lib.embeds[target] = true
return target
end
for target, _ in pairs(lib.embeds) do
lib:Embed(target)
end
+274 -274
View File
@@ -1,274 +1,274 @@
--[[---------------------------------------------------------------------------------
General Library providing an alternate StartMoving() that allows you to
specify a number of frames to snap-to when moving the frame around
Example Usage:
<OnLoad>
this:RegisterForDrag("LeftButton")
</OnLoad>
<OnDragStart>
StickyFrames:StartMoving(this, {WatchDogFrame_player, WatchDogFrame_target, WatchDogFrame_party1, WatchDogFrame_party2, WatchDogFrame_party3, WatchDogFrame_party4},3,3,3,3)
</OnDragStart>
<OnDragStop>
StickyFrames:StopMoving(this)
StickyFrames:AnchorFrame(this)
</OnDragStop>
------------------------------------------------------------------------------------
This is a modified version by Nevcairiel for Bartender4
------------------------------------------------------------------------------------]]
local MAJOR, MINOR = "LibSimpleSticky-1.0", 2
local StickyFrames, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not StickyFrames then return end
--[[---------------------------------------------------------------------------------
Class declaration, along with a temporary table to hold any existing OnUpdate
scripts.
------------------------------------------------------------------------------------]]
StickyFrames.scripts = StickyFrames.scripts or {}
StickyFrames.rangeX = 15
StickyFrames.rangeY = 15
StickyFrames.sticky = StickyFrames.sticky or {}
--[[---------------------------------------------------------------------------------
StickyFrames:StartMoving() - Sets a custom OnUpdate for the frame so it follows
the mouse and snaps to the frames you specify
frame: The frame we want to move. Is typically "this"
frameList: A integer indexed list of frames that the given frame should try to
stick to. These don't have to have anything special done to them,
and they don't really even need to exist. You can inclue the
moving frame in this list, it will be ignored. This helps you
if you have a number of frames, just make ONE list to pass.
{WatchDogFrame_player, WatchDogFrame_party1, .. WatchDogFrame_party4}
left: If your frame has a tranparent border around the entire frame
(think backdrops with borders). This can be used to fine tune the
edges when you're stickying groups. Refers to any offset on the
LEFT edge of the frame being moved.
top: same
right: same
bottom: same
------------------------------------------------------------------------------------]]
function StickyFrames:StartMoving(frame, frameList, left, top, right, bottom)
local x,y = GetCursorPosition()
local aX,aY = frame:GetCenter()
local aS = frame:GetEffectiveScale()
aX,aY = aX*aS,aY*aS
local xoffset,yoffset = (aX - x),(aY - y)
self.scripts[frame] = frame:GetScript("OnUpdate")
frame:SetScript("OnUpdate", self:GetUpdateFunc(frame, frameList, xoffset, yoffset, left, top, right, bottom))
end
--[[---------------------------------------------------------------------------------
This stops the OnUpdate, leaving the frame at its last position. This will
leave it anchored to UIParent. You can call StickyFrames:AnchorFrame() to
anchor it back "TOPLEFT" , "TOPLEFT" to the parent.
------------------------------------------------------------------------------------]]
function StickyFrames:StopMoving(frame)
frame:SetScript("OnUpdate", self.scripts[frame])
self.scripts[frame] = nil
if StickyFrames.sticky[frame] then
local sticky = StickyFrames.sticky[frame]
StickyFrames.sticky[frame] = nil
return true, sticky
else
return false, nil
end
end
--[[---------------------------------------------------------------------------------
This can be called in conjunction with StickyFrames:StopMoving() to anchor the
frame right back to the parent, so you can manipulate its children as a group
(This is useful in WatchDog)
------------------------------------------------------------------------------------]]
function StickyFrames:AnchorFrame(frame)
local xA,yA = frame:GetCenter()
local parent = frame:GetParent() or UIParent
local xP,yP = parent:GetCenter()
local sA,sP = frame:GetEffectiveScale(), parent:GetEffectiveScale()
xP,yP = (xP*sP) / sA, (yP*sP) / sA
local xo,yo = (xP - xA)*-1, (yP - yA)*-1
frame:ClearAllPoints()
frame:SetPoint("CENTER", parent, "CENTER", xo, yo)
end
--[[---------------------------------------------------------------------------------
Internal Functions -- Do not call these.
------------------------------------------------------------------------------------]]
--[[---------------------------------------------------------------------------------
Returns an anonymous OnUpdate function for the frame in question. Need
to provide the frame, frameList along with the x and y offset (difference between
where the mouse picked up the frame, and the insets (left,top,right,bottom) in the
case of borders, etc.w
------------------------------------------------------------------------------------]]
function StickyFrames:GetUpdateFunc(frame, frameList, xoffset, yoffset, left, top, right, bottom)
return function()
local x,y = GetCursorPosition()
local s = frame:GetEffectiveScale()
local sticky = nil
x,y = x/s,y/s
frame:ClearAllPoints()
frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x+xoffset, y+yoffset)
StickyFrames.sticky[frame] = nil
for i = 1, #frameList do
local v = frameList[i]
if frame ~= v and frame ~= v:GetParent() and not IsShiftKeyDown() and v:IsVisible() then
if self:SnapFrame(frame, v, left, top, right, bottom) then
StickyFrames.sticky[frame] = v
break
end
end
end
end
end
--[[---------------------------------------------------------------------------------
Internal debug function.
------------------------------------------------------------------------------------]]
function StickyFrames:debug(msg)
DEFAULT_CHAT_FRAME:AddMessage("|cffffff00StickyFrames: |r"..tostring(msg))
end
--[[---------------------------------------------------------------------------------
This is called when finding an overlap between two sticky frame. If frameA is near
a sticky edge of frameB, then it will snap to that edge and return true. If there
is no sticky edge collision, will return false so we can test other frames for
stickyness.
------------------------------------------------------------------------------------]]
function StickyFrames:SnapFrame(frameA, frameB, left, top, right, bottom)
local sA, sB = frameA:GetEffectiveScale(), frameB:GetEffectiveScale()
local xA, yA = frameA:GetCenter()
local xB, yB = frameB:GetCenter()
local hA, hB = frameA:GetHeight() / 2, ((frameB:GetHeight() * sB) / sA) / 2
local wA, wB = frameA:GetWidth() / 2, ((frameB:GetWidth() * sB) / sA) / 2
local newX, newY = xA, yA
if not left then left = 0 end
if not top then top = 0 end
if not right then right = 0 end
if not bottom then bottom = 0 end
-- Lets translate B's coords into A's scale
xB, yB = (xB*sB) / sA, (yB*sB) / sA
local stickyAx, stickyAy = wA * 0.75, hA * 0.75
local stickyBx, stickyBy = wB * 0.75, hB * 0.75
-- Grab the edges of each frame, for easier comparison
local lA, tA, rA, bA = frameA:GetLeft(), frameA:GetTop(), frameA:GetRight(), frameA:GetBottom()
local lB, tB, rB, bB = frameB:GetLeft(), frameB:GetTop(), frameB:GetRight(), frameB:GetBottom()
local snap = nil
-- Translate into A's scale
lB, tB, rB, bB = (lB * sB) / sA, (tB * sB) / sA, (rB * sB) / sA, (bB * sB) / sA
if (bA <= tB and bB <= tA) then
-- Horizontal Centers
if xA <= (xB + StickyFrames.rangeX) and xA >= (xB - StickyFrames.rangeX) then
newX = xB
snap = true
end
-- Interior Left
if lA <= (lB + StickyFrames.rangeX) and lA >= (lB - StickyFrames.rangeX) then
newX = lB + wA
if frameB == UIParent or frameB == WorldFrame then newX = newX - left/2 end
snap = true
end
-- Interior Right
if rA <= (rB + StickyFrames.rangeX) and rA >= (rB - StickyFrames.rangeX) then
newX = rB - wA
if frameB == UIParent or frameB == WorldFrame then newX = newX + right/2 end
snap = true
end
-- Exterior Left to Right
if lA <= (rB + StickyFrames.rangeX) and lA >= (rB - StickyFrames.rangeX) then
newX = rB + (wA - left)
if frameB == UIParent or frameB == WorldFrame then newX = newX + left/2 end
snap = true
end
-- Exterior Right to Left
if rA <= (lB + StickyFrames.rangeX) and rA >= (lB - StickyFrames.rangeX) then
newX = lB - (wA - right)
if frameB == UIParent or frameB == WorldFrame then newX = newX - right/2 end
snap = true
end
end
if (lA <= rB and lB <= rA) then
-- Vertical Centers
if yA <= (yB + StickyFrames.rangeY) and yA >= (yB - StickyFrames.rangeY) then
newY = yB
snap = true
end
-- Interior Top
if tA <= (tB + StickyFrames.rangeY) and tA >= (tB - StickyFrames.rangeY) then
newY = tB - hA
if frameB == UIParent or frameB == WorldFrame then newY = newY + top/2 end
snap = true
end
-- Interior Bottom
if bA <= (bB + StickyFrames.rangeY) and bA >= (bB - StickyFrames.rangeY) then
newY = bB + hA
if frameB == UIParent or frameB == WorldFrame then newY = newY - bottom/2 end
snap = true
end
-- Exterior Top to Bottom
if tA <= (bB + StickyFrames.rangeY + bottom) and tA >= (bB - StickyFrames.rangeY + bottom) then
newY = bB - (hA - top)
if frameB == UIParent or frameB == WorldFrame then newY = newY - top/2 end
snap = true
end
-- Exterior Bottom to Top
if bA <= (tB + StickyFrames.rangeY - top) and bA >= (tB - StickyFrames.rangeY - top) then
newY = tB + (hA - bottom)
if frameB == UIParent or frameB == WorldFrame then newY = newY + bottom/2 end
snap = true
end
end
if snap then
frameA:ClearAllPoints()
frameA:SetPoint("CENTER", UIParent, "BOTTOMLEFT", newX, newY)
return true
end
end
--[[---------------------------------------------------------------------------------
General Library providing an alternate StartMoving() that allows you to
specify a number of frames to snap-to when moving the frame around
Example Usage:
<OnLoad>
this:RegisterForDrag("LeftButton")
</OnLoad>
<OnDragStart>
StickyFrames:StartMoving(this, {WatchDogFrame_player, WatchDogFrame_target, WatchDogFrame_party1, WatchDogFrame_party2, WatchDogFrame_party3, WatchDogFrame_party4},3,3,3,3)
</OnDragStart>
<OnDragStop>
StickyFrames:StopMoving(this)
StickyFrames:AnchorFrame(this)
</OnDragStop>
------------------------------------------------------------------------------------
This is a modified version by Nevcairiel for Bartender4
------------------------------------------------------------------------------------]]
local MAJOR, MINOR = "LibSimpleSticky-1.0", 2
local StickyFrames, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not StickyFrames then return end
--[[---------------------------------------------------------------------------------
Class declaration, along with a temporary table to hold any existing OnUpdate
scripts.
------------------------------------------------------------------------------------]]
StickyFrames.scripts = StickyFrames.scripts or {}
StickyFrames.rangeX = 15
StickyFrames.rangeY = 15
StickyFrames.sticky = StickyFrames.sticky or {}
--[[---------------------------------------------------------------------------------
StickyFrames:StartMoving() - Sets a custom OnUpdate for the frame so it follows
the mouse and snaps to the frames you specify
frame: The frame we want to move. Is typically "this"
frameList: A integer indexed list of frames that the given frame should try to
stick to. These don't have to have anything special done to them,
and they don't really even need to exist. You can inclue the
moving frame in this list, it will be ignored. This helps you
if you have a number of frames, just make ONE list to pass.
{WatchDogFrame_player, WatchDogFrame_party1, .. WatchDogFrame_party4}
left: If your frame has a tranparent border around the entire frame
(think backdrops with borders). This can be used to fine tune the
edges when you're stickying groups. Refers to any offset on the
LEFT edge of the frame being moved.
top: same
right: same
bottom: same
------------------------------------------------------------------------------------]]
function StickyFrames:StartMoving(frame, frameList, left, top, right, bottom)
local x,y = GetCursorPosition()
local aX,aY = frame:GetCenter()
local aS = frame:GetEffectiveScale()
aX,aY = aX*aS,aY*aS
local xoffset,yoffset = (aX - x),(aY - y)
self.scripts[frame] = frame:GetScript("OnUpdate")
frame:SetScript("OnUpdate", self:GetUpdateFunc(frame, frameList, xoffset, yoffset, left, top, right, bottom))
end
--[[---------------------------------------------------------------------------------
This stops the OnUpdate, leaving the frame at its last position. This will
leave it anchored to UIParent. You can call StickyFrames:AnchorFrame() to
anchor it back "TOPLEFT" , "TOPLEFT" to the parent.
------------------------------------------------------------------------------------]]
function StickyFrames:StopMoving(frame)
frame:SetScript("OnUpdate", self.scripts[frame])
self.scripts[frame] = nil
if StickyFrames.sticky[frame] then
local sticky = StickyFrames.sticky[frame]
StickyFrames.sticky[frame] = nil
return true, sticky
else
return false, nil
end
end
--[[---------------------------------------------------------------------------------
This can be called in conjunction with StickyFrames:StopMoving() to anchor the
frame right back to the parent, so you can manipulate its children as a group
(This is useful in WatchDog)
------------------------------------------------------------------------------------]]
function StickyFrames:AnchorFrame(frame)
local xA,yA = frame:GetCenter()
local parent = frame:GetParent() or UIParent
local xP,yP = parent:GetCenter()
local sA,sP = frame:GetEffectiveScale(), parent:GetEffectiveScale()
xP,yP = (xP*sP) / sA, (yP*sP) / sA
local xo,yo = (xP - xA)*-1, (yP - yA)*-1
frame:ClearAllPoints()
frame:SetPoint("CENTER", parent, "CENTER", xo, yo)
end
--[[---------------------------------------------------------------------------------
Internal Functions -- Do not call these.
------------------------------------------------------------------------------------]]
--[[---------------------------------------------------------------------------------
Returns an anonymous OnUpdate function for the frame in question. Need
to provide the frame, frameList along with the x and y offset (difference between
where the mouse picked up the frame, and the insets (left,top,right,bottom) in the
case of borders, etc.w
------------------------------------------------------------------------------------]]
function StickyFrames:GetUpdateFunc(frame, frameList, xoffset, yoffset, left, top, right, bottom)
return function()
local x,y = GetCursorPosition()
local s = frame:GetEffectiveScale()
local sticky = nil
x,y = x/s,y/s
frame:ClearAllPoints()
frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x+xoffset, y+yoffset)
StickyFrames.sticky[frame] = nil
for i = 1, #frameList do
local v = frameList[i]
if frame ~= v and frame ~= v:GetParent() and not IsShiftKeyDown() and v:IsVisible() then
if self:SnapFrame(frame, v, left, top, right, bottom) then
StickyFrames.sticky[frame] = v
break
end
end
end
end
end
--[[---------------------------------------------------------------------------------
Internal debug function.
------------------------------------------------------------------------------------]]
function StickyFrames:debug(msg)
DEFAULT_CHAT_FRAME:AddMessage("|cffffff00StickyFrames: |r"..tostring(msg))
end
--[[---------------------------------------------------------------------------------
This is called when finding an overlap between two sticky frame. If frameA is near
a sticky edge of frameB, then it will snap to that edge and return true. If there
is no sticky edge collision, will return false so we can test other frames for
stickyness.
------------------------------------------------------------------------------------]]
function StickyFrames:SnapFrame(frameA, frameB, left, top, right, bottom)
local sA, sB = frameA:GetEffectiveScale(), frameB:GetEffectiveScale()
local xA, yA = frameA:GetCenter()
local xB, yB = frameB:GetCenter()
local hA, hB = frameA:GetHeight() / 2, ((frameB:GetHeight() * sB) / sA) / 2
local wA, wB = frameA:GetWidth() / 2, ((frameB:GetWidth() * sB) / sA) / 2
local newX, newY = xA, yA
if not left then left = 0 end
if not top then top = 0 end
if not right then right = 0 end
if not bottom then bottom = 0 end
-- Lets translate B's coords into A's scale
xB, yB = (xB*sB) / sA, (yB*sB) / sA
local stickyAx, stickyAy = wA * 0.75, hA * 0.75
local stickyBx, stickyBy = wB * 0.75, hB * 0.75
-- Grab the edges of each frame, for easier comparison
local lA, tA, rA, bA = frameA:GetLeft(), frameA:GetTop(), frameA:GetRight(), frameA:GetBottom()
local lB, tB, rB, bB = frameB:GetLeft(), frameB:GetTop(), frameB:GetRight(), frameB:GetBottom()
local snap = nil
-- Translate into A's scale
lB, tB, rB, bB = (lB * sB) / sA, (tB * sB) / sA, (rB * sB) / sA, (bB * sB) / sA
if (bA <= tB and bB <= tA) then
-- Horizontal Centers
if xA <= (xB + StickyFrames.rangeX) and xA >= (xB - StickyFrames.rangeX) then
newX = xB
snap = true
end
-- Interior Left
if lA <= (lB + StickyFrames.rangeX) and lA >= (lB - StickyFrames.rangeX) then
newX = lB + wA
if frameB == UIParent or frameB == WorldFrame then newX = newX - left/2 end
snap = true
end
-- Interior Right
if rA <= (rB + StickyFrames.rangeX) and rA >= (rB - StickyFrames.rangeX) then
newX = rB - wA
if frameB == UIParent or frameB == WorldFrame then newX = newX + right/2 end
snap = true
end
-- Exterior Left to Right
if lA <= (rB + StickyFrames.rangeX) and lA >= (rB - StickyFrames.rangeX) then
newX = rB + (wA - left)
if frameB == UIParent or frameB == WorldFrame then newX = newX + left/2 end
snap = true
end
-- Exterior Right to Left
if rA <= (lB + StickyFrames.rangeX) and rA >= (lB - StickyFrames.rangeX) then
newX = lB - (wA - right)
if frameB == UIParent or frameB == WorldFrame then newX = newX - right/2 end
snap = true
end
end
if (lA <= rB and lB <= rA) then
-- Vertical Centers
if yA <= (yB + StickyFrames.rangeY) and yA >= (yB - StickyFrames.rangeY) then
newY = yB
snap = true
end
-- Interior Top
if tA <= (tB + StickyFrames.rangeY) and tA >= (tB - StickyFrames.rangeY) then
newY = tB - hA
if frameB == UIParent or frameB == WorldFrame then newY = newY + top/2 end
snap = true
end
-- Interior Bottom
if bA <= (bB + StickyFrames.rangeY) and bA >= (bB - StickyFrames.rangeY) then
newY = bB + hA
if frameB == UIParent or frameB == WorldFrame then newY = newY - bottom/2 end
snap = true
end
-- Exterior Top to Bottom
if tA <= (bB + StickyFrames.rangeY + bottom) and tA >= (bB - StickyFrames.rangeY + bottom) then
newY = bB - (hA - top)
if frameB == UIParent or frameB == WorldFrame then newY = newY - top/2 end
snap = true
end
-- Exterior Bottom to Top
if bA <= (tB + StickyFrames.rangeY - top) and bA >= (tB - StickyFrames.rangeY - top) then
newY = tB + (hA - bottom)
if frameB == UIParent or frameB == WorldFrame then newY = newY + bottom/2 end
snap = true
end
end
if snap then
frameA:ClearAllPoints()
frameA:SetPoint("CENTER", UIParent, "BOTTOMLEFT", newX, newY)
return true
end
end
+70 -70
View File
@@ -1,70 +1,70 @@
#!/usr/local/bin/lua
-- CONFIG --
--[[
Prefix to all files if this script is run from a subdir, for example
]]
local filePrefix = "../"
--[[
List of all files to parse
]]
local files = {
"ActionBar.lua",
"ActionBars.lua",
"ActionButton.lua",
"BagBar.lua",
"Bar.lua",
"Bartender4.lua",
"ButtonBar.lua",
"MicroMenu.lua",
"MultiCastBar.lua",
"PetBar.lua",
"PetButton.lua",
"RepXPBar.lua",
"StanceBar.lua",
"StateBar.lua",
"VehicleBar.lua",
--
"Options/ActionBar.lua",
"Options/BagBar.lua",
"Options/Bar.lua",
"Options/ButtonBar.lua",
"Options/MicroMenu.lua",
"Options/MultiCastBar.lua",
"Options/Options.lua",
"Options/PetBar.lua",
"Options/RepXPBar.lua",
"Options/StanceBar.lua",
"Options/StateBar.lua",
"Options/VehicleBar.lua",
}
local out = "Strings.lua"
-- CODE --
local strings = {}
-- extract data from specified lua files
for idx,filename in pairs(files) do
local file = io.open(string.format("%s%s", filePrefix or "", filename), "r")
assert(file, "Could not open " .. filename)
local text = file:read("*all")
for match in string.gmatch(text, "L%[\"(.-)\"%]") do
strings[match] = true
end
end
local work = {}
for k,v in pairs(strings) do table.insert(work, k) end
table.sort(work)
-- Write locale files
local file = io.open(out, "w")
for idx, match in ipairs(work) do
file:write(string.format("L[\"%s\"] = true\n", match))
end
file:close()
#!/usr/local/bin/lua
-- CONFIG --
--[[
Prefix to all files if this script is run from a subdir, for example
]]
local filePrefix = "../"
--[[
List of all files to parse
]]
local files = {
"ActionBar.lua",
"ActionBars.lua",
"ActionButton.lua",
"BagBar.lua",
"Bar.lua",
"Bartender4.lua",
"ButtonBar.lua",
"MicroMenu.lua",
"MultiCastBar.lua",
"PetBar.lua",
"PetButton.lua",
"RepXPBar.lua",
"StanceBar.lua",
"StateBar.lua",
"VehicleBar.lua",
--
"Options/ActionBar.lua",
"Options/BagBar.lua",
"Options/Bar.lua",
"Options/ButtonBar.lua",
"Options/MicroMenu.lua",
"Options/MultiCastBar.lua",
"Options/Options.lua",
"Options/PetBar.lua",
"Options/RepXPBar.lua",
"Options/StanceBar.lua",
"Options/StateBar.lua",
"Options/VehicleBar.lua",
}
local out = "Strings.lua"
-- CODE --
local strings = {}
-- extract data from specified lua files
for idx,filename in pairs(files) do
local file = io.open(string.format("%s%s", filePrefix or "", filename), "r")
assert(file, "Could not open " .. filename)
local text = file:read("*all")
for match in string.gmatch(text, "L%[\"(.-)\"%]") do
strings[match] = true
end
end
local work = {}
for k,v in pairs(strings) do table.insert(work, k) end
table.sort(work)
-- Write locale files
local file = io.open(out, "w")
for idx, match in ipairs(work) do
file:write(string.format("L[\"%s\"] = true\n", match))
end
file:close()

Some files were not shown because too many files have changed in this diff Show More