Mercurial > wow > whichrankdoeswhat
diff main.lua @ 15:3a2beea01a28
Use a paged window instead of a huge one. Make LoD. Show flag #14 rather than trying to skip it, but override the column header.
| author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
|---|---|
| date | Fri, 03 Aug 2012 03:16:07 -0400 |
| parents | e6382ba088c3 |
| children |
line wrap: on
line diff
--- a/main.lua Wed Aug 01 17:15:51 2012 -0400 +++ b/main.lua Fri Aug 03 03:16:07 2012 -0400 @@ -42,6 +42,7 @@ name = L["Guild Control for non-GMs"], desc = L["Make the grayed-out Guild Control button activate this addon instead."], type = 'toggle', + width = 'double', -- else it gets cut off order = 10, }, break1 = { @@ -74,11 +75,15 @@ local AceGUI = LibStub("AceGUI-3.0") local st_rowheight = 25 local st_displayed_rows = 15 --math.floor(366/st_rowheight) -local st_colwidth = 65 +local st_colwidth = 80 --65 +local cols_per_group = 6 +local num_flagsets local sidetabs local incomplete +local flagmap --- Remove children ST widgets without explicitly Release()'ing them. +-- Remove children ST widgets without explicitly Release()'ing them. As there +-- are no children other than STs, no "normal" widget resources are leaked. local function DisownChildren (container) for i,v in ipairs(container.children) do container.children[i] = nil @@ -87,6 +92,11 @@ end end +local function setstatus(txt) + addon.display:SetStatusText(txt) + addon.tooltip = #txt > 40 and txt or nil +end + ----------------------------------------------------------------------------- addon = LibStub("AceAddon-3.0"):NewAddon(addon, nametag, @@ -140,11 +150,14 @@ if not NUM_RANK_FLAGS then UIParentLoadAddOn("Blizzard_GuildControlUI") end - hooksecurefunc("GuildFrame_CheckPermissions", function() + local function noreallyitsokay() GuildControlButton:Enable() GuildControlButton:SetScript("OnClick", onclick) GuildControlButton:SetScript("OnEnter", onenter) - end) + end + hooksecurefunc("GuildInfoFrame_UpdatePermissions", noreallyitsokay) + -- This doesn't seem to be used anymore...? + hooksecurefunc("GuildFrame_CheckPermissions", noreallyitsokay) end end @@ -180,12 +193,12 @@ -- Something somewhere has changed, redo the cache do - local text = '|cffff1010' .. L["Guild flags have changed!"] .. '|r' .. + local text = '|cffff1010' .. L["Guild flags have changed!"] .. '|r ' .. L["You must close and reopen this window to display the changes."] function addon:GUILD_RANKS_UPDATE() self.perms = nil if (not incomplete) and self.display and self.display:IsVisible() then - self.display:SetStatusText(text) + setstatus(text) end end end @@ -197,28 +210,46 @@ -- http://www.wowace.com/addons/lib-st/pages/set-data/minimal-dataset-format/ local p,v = {}, {} + flagmap = {} + num_flagsets = math.floor(NUM_RANK_FLAGS/cols_per_group + 1) + for flagset = 1, num_flagsets do + p[flagset] = {} + end + for r = 1, GuildControlGetNumRanks() do GuildControlSetRank(r) - -- permissions + -- permissions (most special handling goes here) + -- flag 14 is no longer used + -- flags 15 and 16 may have numeric values not just a boolean + -- flag 21 is... not included yet, apparently local flags = { GuildControlGetRankFlags() } - local row = { GuildControlGetRankName(r) } - for c = 1, NUM_RANK_FLAGS do if c ~= 14 then - local newcol = #row + 1 - if c == 15 or c == 16 then - local val = GetGuildBankWithdrawGoldLimit() - row[newcol] = flags[c] and ((val == -1) and check or val) or "" - else - row[newcol] = flags[c] and check or "" - end - end end - p[r] = row + for flagset = 1, num_flagsets do + local row = { GuildControlGetRankName(r) } + for c_offset = 1, cols_per_group do while true do + local c = (flagset-1) * cols_per_group + c_offset + --if c == 14 or c > NUM_RANK_FLAGS then break end + if c > NUM_RANK_FLAGS then break end + local newcol = #row + 1 + flagmap[flagset..'x'..newcol] = c + if c == 15 or c == 16 then + local val = GetGuildBankWithdrawGoldLimit() + row[newcol] = flags[c] and ((val == -1) and check or val) or "" + elseif c == 14 then + row[newcol] = "" + else + row[newcol] = flags[c] and check or "" + end + break + end end + p[flagset][r] = row + end -- guild vault local banktabs = {} for t = 1, GetNumGuildBankTabs() do -- isViewable, canDeposit, editText, numWithdrawals - banktabs[t] = { row[1], GetGuildBankTabPermissions(t) } + banktabs[t] = { GuildControlGetRankName(r), GetGuildBankTabPermissions(t) } banktabs[t][2] = banktabs[t][2] and check or "" banktabs[t][3] = banktabs[t][3] and check or "" banktabs[t][4] = banktabs[t][4] and check or "" @@ -239,8 +270,6 @@ end -local function setstatus(txt) addon.display:SetStatusText(txt) end - local make_sidetab do local lastclicked @@ -286,6 +315,9 @@ local function pick_a_tab (tab, id) DisownChildren(self.display) self.display:AddChild(self.vault_sts[id-offset]) + local buttons = self.display:GetUserData("extra buttons") + buttons['prev']:Disable() + buttons['next']:Disable() end for t = 1, GetNumGuildBankTabs() do local name, icon = GetGuildBankTabInfo(t) @@ -301,6 +333,86 @@ end +-- The "closebutton" variable isn't accessible through the widget. I should +-- probably just constuct an entire Frame-equse thing by hand instead... gah. +local function FIXFRAME (container, ...) + for i = 1, select('#',...) do + local child = select(i,...) + if child:GetObjectType() == "Button" and child:GetText() == CLOSE then + container:SetUserData("close button", child) + return + end + end +end + +local function adjust_flagset (button) + local key = button.button_key + assert (key == 'prev' or key == 'next') + local flagset = addon.current_main_st + if key == 'prev' then + flagset = flagset - 1 + else + flagset = flagset + 1 + end + return flagset +end + +local function AddedButton_OnEnter (button) + -- not very generic, that's okay until we need to be + local high = adjust_flagset(button) * cols_per_group + local low = high - cols_per_group + 1 + if high > NUM_RANK_FLAGS then high = NUM_RANK_FLAGS end + setstatus(L["Show flag columns %d - %d"]:format(low,high)) +end +local function AddedButton_OnLeave (button) + setstatus("") +end +local function AddedButton_OnClick (button) + addon:DoMainST(adjust_flagset(button)) + -- the buttons may have changed state, adjust their status text + if button:IsEnabled() then + AddedButton_OnEnter (button) + else + AddedButton_OnLeave (button) + end +end + +local function AddButton (container, key, label) + assert(not tonumber(key)) + local all = container:GetUserData("extra buttons") or {} + container:SetUserData("extra buttons", all) + local n = #all + local closebutton = assert(container:GetUserData("close button"), "something horrible") + local b = CreateFrame("Button", nil, container.frame, "UIPanelButtonTemplate") + b.button_key = key + b.obj = self + b:SetScript("OnClick", AddedButton_OnClick) + b:SetScript("OnEnter", AddedButton_OnEnter) + b:SetScript("OnLeave", AddedButton_OnLeave) + b:SetText(label) + b:SetHeight(20) + b:SetWidth(50) -- "Close" is 100 + b:SetPoint("BOTTOMRIGHT", closebutton, "BOTTOMLEFT", -5, 0) + b:Show() + all[n+1] = b + all[key] = b + + for i = n, 1, -1 do + local ob = all[i] + ob:ClearAllPoints() + ob:SetPoint("BOTTOMRIGHT", all[i+1], "BOTTOMLEFT", -5, 0) + end + -- The Frame's statusbar is not accessible via the Frame widget itself. + -- Which is nice and properly encapsulated and all, but also inconvenient. + -- We'll take the long route there. + local sb = container.statustext:GetParent() + assert (sb.obj == container) + sb:ClearAllPoints() + sb:SetPoint("BOTTOMLEFT", 15, 15) -- default + sb:SetPoint("BOTTOMRIGHT", all[1], "BOTTOMLEFT", -5, 0) +end + + local function st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, sttable, button, ...) if (row == nil) or (realrow == nil) then -- mouseover column header setstatus(cellFrame:GetText():gsub('\n',' ')) @@ -319,38 +431,55 @@ end -function addon:BuildMainST (permissions, parent_frame) +local function OnEnterStatusBar (container) + if not addon.tooltip then return end + GameTooltip:SetOwner (container.frame, "ANCHOR_RIGHT") + GameTooltip:ClearLines() + GameTooltip:AddLine (nametag) + GameTooltip:AddLine (addon.tooltip, 0.8, 0.8, 0.8, 1) + GameTooltip:Show() +end + + +function addon:BuildMainSTs (permissions, parent_frame) + local errtxt = "flagset %d, column %d, failed to map to a flag number" -- if this language uses a trailing colon, strip it - local tmp = GUILDCONTROL_RANKLABEL:gsub(":$","") - local cols = {{ - name = tmp, - width = 10 * #tmp, - }} - for i = 1, NUM_RANK_FLAGS do if i ~= 14 then - table.insert(cols,{ - name = _G['GUILDCONTROL_OPTION'..i], - width = st_colwidth, - }) - end end + local ranklabel = GUILDCONTROL_RANKLABEL:gsub(":$","") + self.main_sts = {} - local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, nil, parent_frame) - ST:Hide() + for flagset = 1, #permissions do + local cols = {{ + name = ranklabel, + width = 10 * #ranklabel, + }} + for c = #cols+1, #permissions[flagset][1] do -- all ranks work here + local f = flagmap[flagset..'x'..c] + if not f then error(errtxt:format(flagset, c)) end + table.insert(cols,{ + -- the only special handling outside BuildPerms + name = _G[f == 14 and 'UNUSED' or 'GUILDCONTROL_OPTION'..f], + width = st_colwidth, + }) + end - ST:SetData(permissions, --[[minimal format=]]true) - ST:RegisterEvents{ - OnEnter = st_OnEnter, - OnLeave = st_OnLeave, - OnClick = st_OnClick, - OnDoubleClick = st_OnClick, - } + local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, --[[highlight=]]nil, parent_frame) + ST:Hide() - return ST + ST:SetData(permissions[flagset], --[[minimal format=]]true) + ST:RegisterEvents{ + OnEnter = st_OnEnter, + OnLeave = st_OnLeave, + OnClick = st_OnClick, + OnDoubleClick = st_OnClick, + } + self.main_sts[flagset] = ST + end end function addon:BuildVaultSTs (permissions, parent_frame) self.vault_sts = {} local cols = { - self.main_st.st.cols[1], + self.main_sts[1].st.cols[1], { name = GUILDCONTROL_VIEW_TAB, width = 80 }, { name = GUILDCONTROL_DEPOSIT_ITEMS, width = 80 }, { name = GUILDCONTROL_UPDATE_TEXT, width = 80 }, @@ -358,7 +487,7 @@ } for tab = 1, #permissions do - local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, nil, parent_frame) + local ST = LibStub("ScrollingTable"):CreateST (cols, st_displayed_rows, st_rowheight, --[[highlight=]]nil, parent_frame) ST:Hide() ST:SetData(permissions[tab], --[[minimal format=]]true) ST:RegisterEvents{ @@ -372,6 +501,16 @@ end +function addon:DoMainST (index) + self.current_main_st = index + DisownChildren(self.display) + self.display:AddChild(self.main_sts[index]) + local buttons = self.display:GetUserData("extra buttons") + buttons['prev'][index <= 1 and 'Disable' or 'Enable'](buttons['prev']) + buttons['next'][index >= num_flagsets and 'Disable' or 'Enable'](buttons['next']) +end + + -- Under normal conditions, this massive wodge is built once, and then merely -- :Show'n and :Hide'n. Only if info gets out of date do we release/destroy -- the UI elements and rebuild. @@ -385,11 +524,16 @@ self.display:SetLayout("Fill") self.display:EnableResize(false) self.display:SetStatusTable{ - width = (st_colwidth+4) * (NUM_RANK_FLAGS-1) -- flag columns + width = (st_colwidth+4) * cols_per_group -- flag columns + 105, -- rank label column height = 500, } self.display:ApplyStatus() + FIXFRAME (self.display, self.display.frame:GetChildren()) + AddButton (self.display, 'prev', "<<") + AddButton (self.display, 'next', ">>") + self.display:SetCallback("OnEnterStatusBar", OnEnterStatusBar) + self.display:SetCallback("OnLeaveStatusBar", GameTooltip_Hide) self.display:SetCallback("OnClose", function(_d) if incomplete or (not self.perms) then -- stuff changed while open @@ -401,6 +545,12 @@ s:SetParent(nil) -- Blizzard does this too. Huh. end end sidetabs = nil + for i,b in ipairs(_d:GetUserData("extra buttons")) do + b.obj = nil + b:Hide() + b:ClearAllPoints() + b:SetParent(nil) + end AceGUI:Release(_d) end end) @@ -418,23 +568,26 @@ s:ClearAllPoints() s:SetParent(nil) -- Blizzard does this too. Huh. end end - if self.main_st and self.main_st.st then - self.main_st:Release() - end + if self.main_sts then for i = 1, #self.main_sts do + if self.main_sts[i] and self.main_sts[i].st then + self.main_sts[i]:Release() + end + end end if self.vault_sts then for i = 1, #self.vault_sts do if self.vault_sts[i] and self.vault_sts[i].st then self.vault_sts[i]:Release() end end end - self.main_st = nil + self.main_sts = nil self.vault_sts = nil end - if not self.main_st then - local st = self:BuildMainST (self.perms, self.display.content) - self.main_st = AceGUI:Create("lib-st"):WrapST(st) - self.main_st.head_offset = 20 - --st_widget.tail_offset = 5 - self.display:AddChild(self.main_st) + if not self.main_sts then + self:BuildMainSTs (self.perms, self.display.content) + for i,st in ipairs(self.main_sts) do + self.main_sts[i] = AceGUI:Create("lib-st"):WrapST(st) + self.main_sts[i].head_offset = 20 + end + self:DoMainST(1) self:BuildVaultSTs (self.vault, self.display.content) for i,st in ipairs(self.vault_sts) do @@ -445,8 +598,7 @@ if need_tabs or incomplete then local maintab = make_sidetab(1, function (this, id) - DisownChildren(self.display) - self.display:AddChild(self.main_st) + self:DoMainST(self.current_main_st) end) maintab.tooltip = [[Rank permissions]] maintab:SetChecked(true)
