farmbuyer@1: local nametag, addon = ... farmbuyer@3: local L = LibStub("AceLocale-3.0"):GetLocale(nametag) farmbuyer@1: farmbuyer@1: addon.defaults = { farmbuyer@1: profile = { farmbuyer@1: enable = true, farmbuyer@1: guildcontrol = true, farmbuyer@1: }, farmbuyer@1: } farmbuyer@1: farmbuyer@1: farmbuyer@1: addon.options = { farmbuyer@1: name = "", farmbuyer@1: type = 'group', farmbuyer@1: childGroups = 'tab', farmbuyer@1: handler = addon, -- functions listed as strings called as addon:func farmbuyer@1: get = "GetOption", farmbuyer@1: set = "SetOption", farmbuyer@1: args = { farmbuyer@1: general = { farmbuyer@3: name = GENERAL, farmbuyer@3: desc = L["General options"], farmbuyer@1: type = 'group', farmbuyer@1: order = 10, farmbuyer@1: args = { farmbuyer@1: version = { farmbuyer@1: --name = filled in during OnInit farmbuyer@1: type = 'description', farmbuyer@1: fontSize = "large", farmbuyer@1: cmdHidden = true, farmbuyer@1: width = 'full', farmbuyer@1: order = 1, farmbuyer@1: }, farmbuyer@1: enable = { farmbuyer@3: name = ENABLE, farmbuyer@3: desc = L["Use this addon"], farmbuyer@1: type = 'toggle', farmbuyer@1: arg = "ToggleEnable", farmbuyer@1: order = 5, farmbuyer@1: }, farmbuyer@1: guildcontrol = { farmbuyer@3: name = L["Guild Control for non-GMs"], farmbuyer@3: desc = L["Make the grayed-out Guild Control button activate this addon instead."], farmbuyer@1: type = 'toggle', farmbuyer@1: order = 10, farmbuyer@1: }, farmbuyer@1: break1 = { farmbuyer@1: name = '', farmbuyer@1: type = 'description', farmbuyer@1: cmdHidden = true, farmbuyer@1: width = 'full', farmbuyer@1: order = 14, farmbuyer@1: }, farmbuyer@1: popup = { farmbuyer@1: name = "/wrdw", farmbuyer@3: desc = L["Toggle WRDW window"], farmbuyer@1: type = 'execute', farmbuyer@1: func = function() farmbuyer@1: InterfaceOptionsFrameCancel:Click() farmbuyer@1: HideUIPanel(GameMenuFrame) farmbuyer@1: addon:BuildWindow() farmbuyer@1: end, farmbuyer@1: order = 15, farmbuyer@1: }, farmbuyer@1: }, farmbuyer@1: }, farmbuyer@1: --profiles = filled in OnInit farmbuyer@1: }, farmbuyer@1: } farmbuyer@1: farmbuyer@1: farmbuyer@1: ----------------------------------------------------------------------------- farmbuyer@1: -- other locals farmbuyer@1: local AceGUI = LibStub("AceGUI-3.0") farmbuyer@1: local st_rowheight = 25 farmbuyer@1: local st_displayed_rows = 15 --math.floor(366/st_rowheight) farmbuyer@4: local st_colwidth = 65 farmbuyer@1: local sidetabs farmbuyer@1: local incomplete farmbuyer@1: farmbuyer@8: -- Remove children ST widgets without explicitly Release()'ing them. farmbuyer@1: local function DisownChildren (container) farmbuyer@1: for i,v in ipairs(container.children) do farmbuyer@1: container.children[i] = nil farmbuyer@1: v.frame:Hide() farmbuyer@1: v.frame:ClearAllPoints() farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: ----------------------------------------------------------------------------- farmbuyer@1: addon = LibStub("AceAddon-3.0"):NewAddon(addon, nametag, farmbuyer@1: "AceConsole-3.0", "AceEvent-3.0") farmbuyer@1: farmbuyer@1: -- Thanks to jerry for the nifty arg idea. farmbuyer@1: function addon:SetOption (info, value) farmbuyer@1: local name = info[#info] farmbuyer@1: self.db.profile[name] = value farmbuyer@1: local arg = info.arg farmbuyer@1: if arg then self[arg](self) end farmbuyer@1: end farmbuyer@1: farmbuyer@1: function addon:GetOption (info) farmbuyer@1: local name = info[#info] farmbuyer@1: return self.db.profile[name] farmbuyer@1: end farmbuyer@1: farmbuyer@1: function addon:OnInitialize() farmbuyer@1: self.db = LibStub("AceDB-3.0"):New("wrdwDB", self.defaults, --[[Default=]]true) farmbuyer@1: farmbuyer@1: local AceDBOptions = LibStub("AceDBOptions-3.0", true) farmbuyer@1: if AceDBOptions then farmbuyer@1: self.options.args.profiles = AceDBOptions:GetOptionsTable(self.db) farmbuyer@1: self.options.args.profiles.order = 200 farmbuyer@1: end farmbuyer@1: farmbuyer@1: self.options.args.general.args.version.name = farmbuyer@1: "|cff30adffVersion " .. (GetAddOnMetadata(nametag, "Version") or "?") .. "|r" farmbuyer@1: LibStub("AceConfig-3.0"):RegisterOptionsTable(nametag, self.options) farmbuyer@1: self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions(nametag, "WhichRankDoesWhat") farmbuyer@1: --self.optionsFrame.okay = function() pattern_editing_safe = false end farmbuyer@1: --self.optionsFrame.refresh = self.optionsFrame.okay farmbuyer@1: --self.optionsFrame.cancel = self.optionsFrame.okay farmbuyer@1: farmbuyer@1: self:SetEnabledState(self.db.profile.enable) farmbuyer@1: self.OnInitialize = nil farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: function addon:OnEnable() farmbuyer@1: self:RegisterEvent("GUILD_RANKS_UPDATE") farmbuyer@8: self:RegisterChatCommand("wrdw", "OnSlashCommand") farmbuyer@1: farmbuyer@7: -- Ideally, most of this stuff wouldn't be done at load time at all; this farmbuyer@7: -- whole addon should be LoD. farmbuyer@1: if (not IsGuildLeader()) and self.db.profile.guildcontrol then farmbuyer@1: local function onclick() addon:BuildWindow() end farmbuyer@1: local function onenter(this) GameTooltip_AddNewbieTip(this, GUILDCONTROL, 1.0, 1.0, 1.0, "/wrdw", 1) end farmbuyer@1: GuildFrame_LoadUI() farmbuyer@4: if not NUM_RANK_FLAGS then farmbuyer@4: UIParentLoadAddOn("Blizzard_GuildControlUI") farmbuyer@4: end farmbuyer@1: hooksecurefunc("GuildFrame_CheckPermissions", function() farmbuyer@1: GuildControlButton:Enable() farmbuyer@1: GuildControlButton:SetScript("OnClick", onclick) farmbuyer@1: GuildControlButton:SetScript("OnEnter", onenter) farmbuyer@1: end) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: function addon:OnDisable() farmbuyer@3: self:Print(L["You will need to relog or /reload to fully disable this addon."]) farmbuyer@1: end farmbuyer@1: farmbuyer@1: function addon:ToggleEnable() farmbuyer@1: if self.db.profile.enable then farmbuyer@1: self:Enable() farmbuyer@1: else farmbuyer@1: self:Disable() farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@8: function addon:OnSlashCommand (input) farmbuyer@7: if not NUM_RANK_FLAGS then -- in case a GM didn't get it loaded earlier farmbuyer@7: GuildFrame_LoadUI() farmbuyer@7: UIParentLoadAddOn("Blizzard_GuildControlUI") farmbuyer@7: end farmbuyer@1: if not input or input:trim() == "" then farmbuyer@1: if self.display and self.display:IsShown() then farmbuyer@1: self.display:Hide() farmbuyer@1: else farmbuyer@1: self:BuildWindow() farmbuyer@1: end farmbuyer@1: else farmbuyer@1: --LibStub("AceConfigCmd-3.0").HandleCommand(self, "wrdw", nametag, input) farmbuyer@1: LibStub("AceConfigDialog-3.0"):Open(nametag) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: -- Something somewhere has changed, redo the cache farmbuyer@3: do farmbuyer@3: local text = '|cffff1010' .. L["Guild flags have changed!"] .. '|r' .. farmbuyer@3: L["You must close and reopen this window to display the changes."] farmbuyer@3: function addon:GUILD_RANKS_UPDATE() farmbuyer@3: self.perms = nil farmbuyer@3: if (not incomplete) and self.display and self.display:IsVisible() then farmbuyer@3: self.display:SetStatusText(text) farmbuyer@3: end farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: function addon:BuildPerms() farmbuyer@1: assert(UIParentLoadAddOn("Blizzard_GuildControlUI")) farmbuyer@2: local check = "|TInterface\\Buttons\\UI-CheckBox-Check:"..(st_rowheight+5).."|t" farmbuyer@1: farmbuyer@1: -- http://www.wowace.com/addons/lib-st/pages/set-data/minimal-dataset-format/ farmbuyer@1: local p,v = {}, {} farmbuyer@1: for r = 1, GuildControlGetNumRanks() do farmbuyer@1: GuildControlSetRank(r) farmbuyer@1: farmbuyer@1: -- permissions farmbuyer@1: local flags = { GuildControlGetRankFlags() } farmbuyer@1: local row = { GuildControlGetRankName(r) } farmbuyer@1: for c = 1, NUM_RANK_FLAGS do if c ~= 14 then farmbuyer@1: local newcol = #row + 1 farmbuyer@1: if c == 15 or c == 16 then farmbuyer@1: local val = GetGuildBankWithdrawGoldLimit() farmbuyer@1: row[newcol] = flags[c] and ((val == -1) and check or val) or "" farmbuyer@1: else farmbuyer@1: row[newcol] = flags[c] and check or "" farmbuyer@1: end farmbuyer@1: end end farmbuyer@1: p[r] = row farmbuyer@1: farmbuyer@1: -- guild vault farmbuyer@1: local banktabs = {} farmbuyer@1: for t = 1, GetNumGuildBankTabs() do farmbuyer@1: -- isViewable, canDeposit, editText, numWithdrawals farmbuyer@1: banktabs[t] = { row[1], GetGuildBankTabPermissions(t) } farmbuyer@1: banktabs[t][2] = banktabs[t][2] and check or "" farmbuyer@1: banktabs[t][3] = banktabs[t][3] and check or "" farmbuyer@1: banktabs[t][4] = banktabs[t][4] and check or "" farmbuyer@1: local withdraw = banktabs[t][5] farmbuyer@1: banktabs[t][5] = (withdraw == -1) and check or (withdraw == 0) and "" or withdraw farmbuyer@1: end farmbuyer@1: v[r] = banktabs farmbuyer@1: end farmbuyer@1: self.perms = p farmbuyer@1: -- This one needs to be turned inside-out to match the data requirements farmbuyer@1: self.vault = {} farmbuyer@1: for t = 1, GetNumGuildBankTabs() do farmbuyer@1: self.vault[t] = {} farmbuyer@1: for r = 1, #v do farmbuyer@1: self.vault[t][r] = v[r][t] farmbuyer@1: end farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: local function setstatus(txt) addon.display:SetStatusText(txt) end farmbuyer@1: farmbuyer@1: local make_sidetab farmbuyer@1: do farmbuyer@1: local lastclicked farmbuyer@1: local function OnClick (thistab) farmbuyer@1: if thistab == lastclicked then return end farmbuyer@1: for i = 1, #sidetabs do farmbuyer@1: sidetabs[i]:SetChecked(false) farmbuyer@1: end farmbuyer@1: thistab:SetChecked(true) -- should be redundant, but just in case farmbuyer@1: lastclicked = thistab farmbuyer@1: if thistab.callback then farmbuyer@1: thistab:callback(thistab:GetID()) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- Some magic numbers here wrt the index farmbuyer@1: function make_sidetab (index, callback) farmbuyer@1: if not sidetabs then farmbuyer@1: sidetabs = {} farmbuyer@1: end farmbuyer@1: farmbuyer@1: local tab = CreateFrame("CheckButton", "WRDWTab"..index, addon.display.frame, "SpellBookSkillLineTabTemplate", index) farmbuyer@1: if index > 1 then farmbuyer@1: tab:SetPoint("TOPLEFT", sidetabs[index-1], "BOTTOMLEFT", 0, -17) farmbuyer@1: else farmbuyer@1: tab:SetNormalTexture("Interface\\SpellBook\\GuildSpellbooktabBG") farmbuyer@1: tab.TabardEmblem:Show() farmbuyer@1: tab.TabardIconFrame:Show() farmbuyer@1: SetLargeGuildTabardTextures("player", tab.TabardEmblem, tab:GetNormalTexture(), tab.TabardIconFrame) farmbuyer@1: tab:SetPoint("TOPLEFT", addon.display.frame, "TOPRIGHT", 0, -17) farmbuyer@1: end farmbuyer@1: tab:SetScript("OnClick", OnClick) farmbuyer@1: --tab:SetChecked(false) -- is default farmbuyer@1: tab:Show() farmbuyer@1: tab.callback = callback farmbuyer@1: sidetabs[index] = tab farmbuyer@1: return tab farmbuyer@1: end farmbuyer@1: farmbuyer@1: function addon:BuildVaultTabs() farmbuyer@1: incomplete = nil farmbuyer@1: local offset = 1 -- number of tabs already made farmbuyer@1: local function pick_a_tab (tab, id) farmbuyer@1: DisownChildren(self.display) farmbuyer@1: self.display:AddChild(self.vault_sts[id-offset]) farmbuyer@1: end farmbuyer@1: for t = 1, GetNumGuildBankTabs() do farmbuyer@1: local name, icon = GetGuildBankTabInfo(t) farmbuyer@1: incomplete = incomplete or icon == [[Interface\Icons\INV_Misc_QuestionMark]] farmbuyer@1: local tab = make_sidetab(t+offset, pick_a_tab) farmbuyer@1: tab:SetNormalTexture(icon) farmbuyer@1: tab.tooltip = name farmbuyer@1: end farmbuyer@1: if incomplete then farmbuyer@3: setstatus(L["Guild vault information is incomplete. Be closer to a vault, and give it some time. You may need to relog and/or open the guild roster/vault to force a client update."]) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: local function st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, sttable, button, ...) farmbuyer@1: if (row == nil) or (realrow == nil) then -- mouseover column header farmbuyer@1: setstatus(cellFrame:GetText():gsub('\n',' ')) farmbuyer@1: return true farmbuyer@1: end farmbuyer@1: return false -- continue with default highlighting behavior farmbuyer@1: end farmbuyer@1: local function st_OnLeave (rowFrame, cellFrame, data, cols, row, realrow, column, sttable, button, ...) farmbuyer@1: setstatus("") farmbuyer@1: return false -- continue with default un-highlighting behavior farmbuyer@1: end farmbuyer@1: local function st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, sttable, button, ...) farmbuyer@1: if (row == nil) or (realrow == nil) then return true end -- click column header, suppress reordering farmbuyer@1: -- more here? farmbuyer@1: return true -- do not do anything further farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: function addon:BuildMainST (permissions, parent_frame) farmbuyer@1: -- if this language uses a trailing colon, strip it farmbuyer@1: local tmp = GUILDCONTROL_RANKLABEL:gsub(":$","") farmbuyer@1: local cols = {{ farmbuyer@1: name = tmp, farmbuyer@1: width = 10 * #tmp, farmbuyer@1: }} farmbuyer@1: for i = 1, NUM_RANK_FLAGS do if i ~= 14 then farmbuyer@1: table.insert(cols,{ farmbuyer@1: name = _G['GUILDCONTROL_OPTION'..i], farmbuyer@4: width = st_colwidth, farmbuyer@1: }) farmbuyer@1: end end farmbuyer@1: farmbuyer@1: local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, nil, parent_frame) farmbuyer@1: ST:Hide() farmbuyer@1: farmbuyer@1: ST:SetData(permissions, --[[minimal format=]]true) farmbuyer@1: ST:RegisterEvents{ farmbuyer@1: OnEnter = st_OnEnter, farmbuyer@1: OnLeave = st_OnLeave, farmbuyer@1: OnClick = st_OnClick, farmbuyer@1: OnDoubleClick = st_OnClick, farmbuyer@1: } farmbuyer@1: farmbuyer@1: return ST farmbuyer@1: end farmbuyer@1: farmbuyer@1: function addon:BuildVaultSTs (permissions, parent_frame) farmbuyer@1: self.vault_sts = {} farmbuyer@1: local cols = { farmbuyer@1: self.main_st.st.cols[1], farmbuyer@1: { name = GUILDCONTROL_VIEW_TAB, width = 80 }, farmbuyer@1: { name = GUILDCONTROL_DEPOSIT_ITEMS, width = 80 }, farmbuyer@1: { name = GUILDCONTROL_UPDATE_TEXT, width = 80 }, farmbuyer@1: { name = GUILDCONTROL_WITHDRAW_ITEMS, width = 150 }, farmbuyer@1: } farmbuyer@1: farmbuyer@1: for tab = 1, #permissions do farmbuyer@1: local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, nil, parent_frame) farmbuyer@1: ST:Hide() farmbuyer@1: ST:SetData(permissions[tab], --[[minimal format=]]true) farmbuyer@1: ST:RegisterEvents{ farmbuyer@1: OnEnter = st_OnEnter, farmbuyer@1: OnLeave = st_OnLeave, farmbuyer@1: OnClick = st_OnClick, farmbuyer@1: OnDoubleClick = st_OnClick, farmbuyer@1: } farmbuyer@1: self.vault_sts[tab] = ST farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@8: -- Under normal conditions, this massive wodge is built once, and then merely farmbuyer@8: -- :Show'n and :Hide'n. Only if info gets out of date do we release/destroy farmbuyer@8: -- the UI elements and rebuild. farmbuyer@1: function addon:BuildWindow() farmbuyer@1: local need_tabs farmbuyer@1: if self.display then farmbuyer@1: self.display:Hide() farmbuyer@1: else farmbuyer@1: self.display = AceGUI:Create("Frame") farmbuyer@1: self.display:SetTitle("Which Rank Does What") farmbuyer@1: self.display:SetLayout("Fill") farmbuyer@8: self.display:EnableResize(false) farmbuyer@1: self.display:SetStatusTable{ farmbuyer@4: width = (st_colwidth+4) * (NUM_RANK_FLAGS-1) -- flag columns farmbuyer@4: + 105, -- rank label column farmbuyer@1: height = 500, farmbuyer@1: } farmbuyer@1: self.display:ApplyStatus() farmbuyer@1: self.display:SetCallback("OnClose", function(_d) farmbuyer@1: if incomplete or (not self.perms) then farmbuyer@1: -- stuff changed while open farmbuyer@1: self.perms = nil farmbuyer@1: self.display = nil farmbuyer@8: if sidetabs then for i,s in ipairs(sidetabs) do farmbuyer@8: s:Hide() farmbuyer@8: s:ClearAllPoints() farmbuyer@8: s:SetParent(nil) -- Blizzard does this too. Huh. farmbuyer@8: end end farmbuyer@1: sidetabs = nil farmbuyer@1: AceGUI:Release(_d) farmbuyer@1: end farmbuyer@1: end) farmbuyer@1: need_tabs = true farmbuyer@1: end farmbuyer@1: farmbuyer@1: if not self.perms then farmbuyer@1: need_tabs = true farmbuyer@1: self:BuildPerms() -- creates self.perms and self.vault farmbuyer@1: DisownChildren(self.display) farmbuyer@1: -- Could be new rows, fewer rows, changed tickboxes... ugh, trying to farmbuyer@1: -- update the scrolltable is a pain. Throw it out and start over. farmbuyer@8: if sidetabs then for i,s in ipairs(sidetabs) do farmbuyer@8: s:Hide() farmbuyer@8: s:ClearAllPoints() farmbuyer@8: s:SetParent(nil) -- Blizzard does this too. Huh. farmbuyer@8: end end farmbuyer@1: if self.main_st and self.main_st.st then farmbuyer@1: self.main_st:Release() farmbuyer@1: end farmbuyer@1: if self.vault_sts then for i = 1, #self.vault_sts do farmbuyer@1: if self.vault_sts[i] and self.vault_sts[i].st then farmbuyer@1: self.vault_sts[i]:Release() farmbuyer@1: end farmbuyer@1: end end farmbuyer@1: self.main_st = nil farmbuyer@1: self.vault_sts = nil farmbuyer@1: end farmbuyer@1: if not self.main_st then farmbuyer@1: local st = self:BuildMainST (self.perms, self.display.content) farmbuyer@1: self.main_st = AceGUI:Create("lib-st"):WrapST(st) farmbuyer@1: self.main_st.head_offset = 20 farmbuyer@1: --st_widget.tail_offset = 5 farmbuyer@1: self.display:AddChild(self.main_st) farmbuyer@1: farmbuyer@1: self:BuildVaultSTs (self.vault, self.display.content) farmbuyer@1: for i,st in ipairs(self.vault_sts) do farmbuyer@1: self.vault_sts[i] = AceGUI:Create("lib-st"):WrapST(st) farmbuyer@1: self.vault_sts[i].head_offset = 20 farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: if need_tabs or incomplete then farmbuyer@1: local maintab = make_sidetab(1, function (this, id) farmbuyer@1: DisownChildren(self.display) farmbuyer@1: self.display:AddChild(self.main_st) farmbuyer@1: end) farmbuyer@1: maintab.tooltip = [[Rank permissions]] farmbuyer@1: maintab:SetChecked(true) farmbuyer@1: self:BuildVaultTabs() farmbuyer@1: end farmbuyer@1: farmbuyer@1: self.display:Show() farmbuyer@1: return self.display farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- vim:noet