--[[ KLH Threatmeter KLHTM_SelfGui.lua Lukon Mod 2: Part of the replacement for Gui.lua and Tables.lua. Controls the GUI for the personal threat details section of KLH ThreatMeter. See also KTM_Gui.xml, KTM_Gui.lua. --]] local mod = klhtm local me = { } mod.guiself = me -- The number of rows defined in New_Frame.xml local Max_Rows = 15; -- Local references to some Gui variables local options = KLHTM_GuiOptions; local gui = KLHTM_Gui; local sizes = KLHTM_GuiSizes; local state = KLHTM_GuiState; local heights = KLHTM_GuiHeights; ------------------------------------------------------------------------------ -- Sets up the instance variable "gui.self". It contains data on the GUI -- components in the personal threat details frame. ------------------------------------------------------------------------------ function KLHTM_CreateSelfTable() gui.self = { ["frame"] = KLHTM_SelfFrame, ["line"] = KLHTM_SelfFrameLine, -- dividing line between title bar and frame ["head"] = { -- column headers ["name"] = { ["frame"] = KLHTM_SelfFrameHeaderName, ["text"] = KLHTM_SelfFrameHeaderNameText, ["width"] = 90, ["colour"] = {["r"] = 1.0, ["g"] = 1.0, ["b"] = 1.0}, ["vis"] = function() return (options.self.columnVis.name) end, }, ["hits"] = { ["frame"] = KLHTM_SelfFrameHeaderHits, ["text"] = KLHTM_SelfFrameHeaderHitsText, ["width"] = 35, ["colour"] = {["r"] = 0.5, ["g"] = 0.9, ["b"] = 0.5}, ["vis"] = function() return (options.self.columnVis.hits) end, }, ["rage"] = { ["frame"] = KLHTM_SelfFrameHeaderRage, ["text"] = KLHTM_SelfFrameHeaderRageText, ["width"] = 35, ["colour"] = {["r"] = 0.9, ["g"] = 0.5, ["b"] = 0.5}, ["vis"] = function() return (options.self.columnVis.rage) end, }, ["dam"] = { ["frame"] = KLHTM_SelfFrameHeaderDamage, ["text"] = KLHTM_SelfFrameHeaderDamageText, ["width"] = 55, ["colour"] = {["r"] = 0.9, ["g"] = 0.9, ["b"] = 0.3}, ["vis"] = function() return (options.self.columnVis.dam) end, }, ["threat"] = { ["frame"] = KLHTM_SelfFrameHeaderThreat, ["text"] = KLHTM_SelfFrameHeaderThreatText, ["width"] = 50, ["colour"] = {["r"] = 0.9, ["g"] = 0.5, ["b"] = 0.9}, ["vis"] = function() return (options.self.columnVis.threat) end, }, ["pc"] = { ["frame"] = KLHTM_SelfFrameHeaderPercentThreat, ["text"] = KLHTM_SelfFrameHeaderPercentThreatText, ["width"] = 30, ["colour"] = {["r"] = 0.9, ["g"] = 0.5, ["b"] = 0.9}, ["vis"] = function() return (options.self.columnVis.pc) end, }, }, ["rows"] = {}, ["bottom"] = { -- self totals ["frame"] = KLHTM_SelfFrameBottom, ["line"] = KLHTM_SelfFrameBottomLine, -- dividing line between frame and bottom bar ["reset"] = { -- a dummy frame used to align the bottom bar strings with the Name header ["frame"] = KLHTM_SelfFrameBottomName, -- a dummy element. Referenced here only to be hidden ["bar"] = KLHTM_SelfFrameBottomBar, ["but"] = KLHTM_SelfFrameBottomReset, ["text"] = KLHTM_SelfFrameBottomResetText, ["width"] = 70, }, ["string"] = { ["hits"] = { ["frame"] = KLHTM_SelfFrameBottomHits, ["text"] = KLHTM_SelfFrameBottomHitsText, }, ["rage"] = { ["frame"] = KLHTM_SelfFrameBottomRage, ["text"] = KLHTM_SelfFrameBottomRageText, }, ["dam"] = { ["frame"] = KLHTM_SelfFrameBottomDamage, ["text"] = KLHTM_SelfFrameBottomDamageText, }, ["threat"] = { ["frame"] = KLHTM_SelfFrameBottomThreat, ["text"] = KLHTM_SelfFrameBottomThreatText, }, }, }, }; for x = 1, Max_Rows do gui.self.rows[x] = { ["frame"] = getglobal("KLHTM_SelfFrameRow" .. x); ["name"] = { ["frame"] = getglobal("KLHTM_SelfFrameRow" .. x .. "Name"), ["text"] = getglobal("KLHTM_SelfFrameRow" .. x .. "NameText"), }, ["hits"] = { ["frame"] = getglobal("KLHTM_SelfFrameRow" .. x .. "Hits"), ["text"] = getglobal("KLHTM_SelfFrameRow" .. x .. "HitsText"), }, ["rage"] = { ["frame"] = getglobal("KLHTM_SelfFrameRow" .. x .. "Rage"), ["text"] = getglobal("KLHTM_SelfFrameRow" .. x .. "RageText"), }, ["dam"] = { ["frame"] = getglobal("KLHTM_SelfFrameRow" .. x .. "Damage"), ["text"] = getglobal("KLHTM_SelfFrameRow" .. x .. "DamageText"), }, ["threat"] = { ["frame"] = getglobal("KLHTM_SelfFrameRow" .. x .. "Threat"), ["text"] = getglobal("KLHTM_SelfFrameRow" .. x .. "ThreatText"), }, ["pc"] = { ["frame"] = getglobal("KLHTM_SelfFrameRow" .. x .. "PercentThreat"), ["text"] = getglobal("KLHTM_SelfFrameRow" .. x .. "PercentThreatText"), }, ["bar"] = getglobal("KLHTM_SelfFrameRow" .. x .. "Bar"), }; end end ------------------------------------------------------------------------------ -- Applies Gui component properties that are not specified in the XML. ------------------------------------------------------------------------------ function KLHTM_SetupSelfGui() -- headers and data for index, header in gui.self.head do header.text:SetText(mod.string.get("gui", "self", "head", index)); header.frame:SetHeight(heights.header); header.text:SetHeight(heights.header); KLHTM_AddOutline(header.text); KLHTM_LocaliseStringWidth(header); for _, row in gui.self.rows do row[index].text:SetTextColor(header.colour.r, header.colour.g, header.colour.b); row[index].frame:SetHeight(heights.data); KLHTM_AddOutline(row[index].text); end end -- rows for _, row in gui.self.rows do row.frame:SetHeight(heights.data); end -- bottom gui.self.bottom.frame:SetHeight(heights.button); for _, string in gui.self.bottom.string do string.frame:SetHeight(heights.data); KLHTM_AddOutline(string.text); end gui.self.bottom.reset.bar:Hide(); gui.self.bottom.reset.but:SetHeight(heights.button); gui.self.bottom.reset.frame:SetHeight(heights.button); gui.self.bottom.reset.but:SetText(mod.string.get("gui", "self", "reset")); local width = gui.self.bottom.reset.text:GetStringWidth(); if (width + 10 > gui.self.bottom.reset.width) then gui.self.bottom.reset.width = width + 10; end gui.self.bottom.reset.but:SetWidth(gui.self.bottom.reset.width); end ------------------------------------------------------------------------------ -- Sets the default options for displaying the main window and title bar strings -- when the self view is selected. ------------------------------------------------------------------------------ function KLHTM_SetDefaultSelfOptions() options.self = { -- column visibility ["columnVis"] = { ["name"] = true, ["hits"] = true, ["rage"] = false, ["dam"] = true, ["threat"] = true, ["pc"] = true, }, -- title bar string visibility ["stringVis"] = { ["threat"] = true, }, -- if true, rows with 0 threat are not shown ["hideZeroRows"] = true, -- if true, values of at least 10,000 are abbreviate with "k" ["abbreviate"] = false, -- the column used to sort data rows ["sortColumn"] = "threat", -- if true, values increase towards the bottom of the table ["sortDown"] = true, }; -- rage column local class; _, class = UnitClass("player"); if ((class == "WARRIOR") or (class == "DRUID")) then options.self.columnVis.rage = true; end end ------------------------------------------------------------------------------ -- Updates the visibility of columns the self table and the bottom bar. The -- contents are not rendered here. The frame width is stored in sizes.self.x. -- Should be called whenever the column visibility changes. ------------------------------------------------------------------------------ function KLHTM_UpdateSelfFrame() sizes.self.x = 0; for column, header in gui.self.head do -- header if (header.vis()) then header.frame:SetWidth(header.width); header.text:SetWidth(header.width); sizes.self.x = sizes.self.x + header.width; header.frame:Show(); else header.frame:Hide(); header.frame:SetWidth(0.1); end -- rows for index, row in gui.self.rows do if (header.vis()) then row[column].frame:SetWidth(header.width); row[column].frame:Show(); else row[column].frame:Hide(); row[column].frame:SetWidth(0.1); end end end -- bottom bar for name, string in gui.self.bottom.string do if (gui.self.head[name].vis()) then string.frame:SetWidth(gui.self.head[name].width); string.frame:Show(); else string.frame:Hide(); string.frame:SetWidth(0.1); end end -- a dummy frame used to align the bottom bar strings with -- the Name header gui.self.bottom.reset.frame:SetWidth(gui.self.head.name.width); for _, row in gui.self.rows do row.frame:SetWidth(sizes.self.x); end end ------------------------------------------------------------------------------ -- Draws the minimised title bar strings present in the self view. ------------------------------------------------------------------------------ function KLHTM_DrawSelfStrings() local threat = mod.table.mydata[mod.string.get("threatsource", "total")].threat; threat = math.floor(threat + 0.5); if (options.self.abbreviate) then threat = KLHTM_Abbreviate(threat); end gui.title.string.threat.text:SetText(threat); end -- used by GetSelfData(). Defined at the class level to reduce memory use. local GetSelfData_data; local GetSelfData_totals; ------------------------------------------------------------------------------ -- Makes a copy of the personal threat data in KLHTM_MyData for use by -- KLHTM_DrawSelfFrame(). KLHTM_MyData contains some non-integers created -- by the heroic strike approximations - these are rounded off. ------------------------------------------------------------------------------ function KLHTM_GetSelfData() local data = GetSelfData_data; local totals = GetSelfData_totals; if (data == nil) then data = {}; totals = {}; for x = 1, 20 do -- 20: needs to be large enough to fit all the threat sources -- that can be added to mod.table.mydata data[x] = {["name"] = "", ["dam"] = 0, ["hits"] = 0, ["rage"] = 0, ["threat"] = 0, ["pc"] = 0,}; end end local totalData = mod.table.mydata[mod.string.get("threatsource", "total")]; totals.hits = totalData.hits; totals.rage = math.floor(totalData.rage + 0.5); -- nb different index names totals.dam = math.floor(totalData.damage + 0.5); totals.threat = math.floor(totalData.threat + 0.5); -- copy the personal threat data local rowCount = 0; for ability, info in mod.table.mydata do -- omit "zero rows" if necessary if (not (options.self.hideZeroRows and (info.threat == 0))) then if (ability ~= mod.string.get("threatsource", "total")) then rowCount = rowCount + 1; data[rowCount].name = ability; data[rowCount].hits = info.hits; data[rowCount].threat = math.floor(info.threat + 0.5); data[rowCount].dam = math.floor(info.damage + 0.5); data[rowCount].rage = math.floor(info.rage + 0.5); if (totals.threat == 0) then data[rowCount].pc = 0; else data[rowCount].pc = math.floor(data[rowCount].threat / totals.threat * 100); end end end end table.setn(data, rowCount); return data, totals end ------------------------------------------------------------------------------ -- Updates the personal threat details. If the frame is minimised, only a -- brief call to KLHTM_DrawSelfStrings() is made. Otherwise a copy of -- KLHTM_MyData is made, processed, and used to redraw all the strings in the -- Self frame. ------------------------------------------------------------------------------ function KLHTM_DrawSelfFrame() if (state.min) then KLHTM_DrawSelfStrings(); return; end local data, totals = KLHTM_GetSelfData(); table.sort(data, KLHTM_CompareSelfRows); -- bar reference value local barRef; if (table.getn(data) == 0) then barRef = 0; elseif (options.self.sortDown) then -- set the largest value to 100% barRef = data[table.getn(data)][options.self.sortColumn]; else barRef = data[1][options.self.sortColumn]; end if ((barRef == nil) or (tonumber(barRef) == nil)) then barRef = 0; else barRef = sizes.self.x / barRef; end local barColours = gui.self.head[options.self.sortColumn].colour; -- truncate excess rows if (table.getn(data) > Max_Rows) then table.setn(data, Max_Rows); end -- render the rows for row = 1, table.getn(data) do for index, value in data[row] do if (options.self.abbreviate) then gui.self.rows[row][index].text:SetText(KLHTM_Abbreviate(value)); else gui.self.rows[row][index].text:SetText(value); end end -- bars if ((barRef == 0) or (data[row][options.self.sortColumn] == 0)) then gui.self.rows[row].bar:Hide(); else gui.self.rows[row].bar:SetWidth(data[row][options.self.sortColumn] * barRef); gui.self.rows[row].bar:SetVertexColor(barColours.r, barColours.g, barColours.b); gui.self.rows[row].bar:Show(); end gui.self.rows[row].frame:Show(); end -- bottom bar for index, string in gui.self.bottom.string do if (totals[index] == 0) then string.text:SetText(""); else if (options.self.abbreviate) then string.text:SetText(KLHTM_Abbreviate(totals[index])); else string.text:SetText(totals[index]); end end end -- hide empty rows for row = table.getn(data) + 1, Max_Rows do gui.self.rows[row].frame:Hide(); end -- resize the frame sizes.self.y = heights.header + heights.button + heights.data * table.getn(data); -- 5 * 2 insets. 1 title gap, 1 row gap, 1 bottom gap sizes.frame.y = sizes.self.y + sizes.title.y + 13; gui.frame:SetHeight(sizes.frame.y); end ------------------------------------------------------------------------------ -- Sorts two rows in the self data table according to the sorting options ------------------------------------------------------------------------------ function KLHTM_CompareSelfRows(row1, row2) -- todo: confirm the sign of these comparisoms if (options.self.sortDown) then return row1[options.self.sortColumn] < row2[options.self.sortColumn]; else return row1[options.self.sortColumn] > row2[options.self.sortColumn]; end end ------------------------------------------------------------------------------ -- Changes the column used to sort personal threat data ------------------------------------------------------------------------------ function KLHTM_SelfHeader_OnClick(name) if (name == nil) then if mod.out.checktrace("warning", me, "invalidargument") then mod.out.printtrace(string.format("The argument '%s' to SelfHeader_OnClick is unrecognised.", tostring(name))); end return; end if (name == "pc") then -- due to a quirk in the way percent threat is calculated, sorting by threat -- should be done via the threat column (see DrawSelfFrame()) name = "threat"; end if (options.self.sortColumn == name) then options.self.sortDown = not options.self.sortDown; else options.self.sortColumn = name; options.self.sortDown = true; end KLHTM_Redraw(true); end ------------------------------------------------------------------------------ -- Called when the used clicks a button in the self view ------------------------------------------------------------------------------ function KLHTM_SelfButton_OnClick(name) if (name == "reset") then mod.table.resetmytable(); KLHTM_Redraw(true); else if mod.out.checktrace("warning", me, "invalidargument") then mod.out.printtrace(string.format("The argument '%s' to SelfButton_OnClick is unrecognised.", tostring(name))); end end end