Quantcast

Updated icons to match in-game faction and role icons

KyrosKrane [05-27-18 - 08:02]
Updated icons to match in-game faction and role icons
Filename
Broker_RaidMakeup.lua
diff --git a/Broker_RaidMakeup.lua b/Broker_RaidMakeup.lua
index b8f4e6f..5ff8ea5 100644
--- a/Broker_RaidMakeup.lua
+++ b/Broker_RaidMakeup.lua
@@ -84,25 +84,134 @@ end -- BRM:DebugPrint


 --#########################################
---# Constants
+--# Icon class setup
 --#########################################

--- Get the main app icon based on the player's faction
-BRM.Faction, _ = UnitFactionGroup("player")
+-- The normal way of handling icons is to create a texture, load the icon file into that, set the region you want, and done.
+-- However, we need to embed icons into a text string for display in the LDB label.
+-- So, we create a custom object to hold icon information, and give it a method to create a text string to display that icon.
+-- That text string can then be embedded in the LDB label to show the icon.
+
+-- Create the object class
+-- Adapted from http://lua-users.org/wiki/ObjectOrientationTutorial
+local IconClass = {}
+IconClass.__index = IconClass
+
+setmetatable(IconClass, {
+	__call = function (cls, ...)
+		return cls.new(...)
+	end,
+})
+
+
+-- Create the constructor
+function IconClass.new(iconfile, IconFileX, IconFileY, StartX, EndX, StartY, EndY)
+	local self = setmetatable({}, IconClass)
+
+	-- The caller has to specify an iconfile before actually using the class, or the results will not be what is expected.
+	self.IconFile = iconfile or ""	-- the game file that has the icon we want
+
+	-- The initial values are sane defaults, but they should be updated for each icon.
+
+	-- These settings control the display of the icon
+	self.SizeOne = 0	-- SizeOne and SizeTwo jointly control the size of the icon. The logic is not intuitive.
+	self.SizeTwo = nil	-- For more details on the SizeOne and SizeTwo parameters, see http://wowwiki.wikia.com/wiki/UI_escape_sequences#Textures
+						-- For the purposes of our icons, they should always be 0 and nil (indicating a square sized to the height of the text).
+
+	self.OffsetX = 0	-- This moves the image n pixels horizontally in the final display. For our icons, it's always 0.
+	self.OffsetY = 0	-- This moves the image n pixels vertically in the final display. For our icons, it's always 0.
+
+	-- These settings control the extraction of the icon from a bigger texture file
+	self.IconFileX = IconFileX or 0	-- the total X (horizontal) pixels in the image file - not just the icon we want
+	self.IconFileY = IconFileY or 0	-- the total Y (vertical) pixels in the image file
+	self.StartX = StartX or 0		-- The starting point in the file where the icon begins, counted from the left border, in pixels
+	self.EndX = EndX or 0			-- The ending point in the file where the icon ends, counted from the left border, in pixels
+	self.StartY = StartY or 0		-- The starting point in the file where the icon begins, counted from the top border, in pixels
+	self.EndY = EndY or 0			-- The ending point in the file where the icon ends, counted from the top border, in pixels
+
+	return self
+end -- IconClass.new()
+
+
+function IconClass:GetIconStringInner()
+	-- Icon strings effectively have to be built right to left, since if the rightmost parameters are required, then the ones to the left are also required.
+
+	-- This function constructs the inner part of the icon string, without the control codes to cause it to display as an actual icon.
+	-- This is mostly useful for debugging. In actual use, you'd want the GetIconString() function.
+
+	local required = false -- tells us whether the remaining parameters are required
+
+	local OutputString = "";
+
+	if required or self.StartX > 0 or self.StartY > 0 or self.EndX > 0 or self.EndY > 0 then
+		required = true
+		OutputString = string.format(":%d:%d:%d:%d", self.StartX, self.EndX, self.StartY, self.EndY)
+	end
+
+	if required or self.IconFileX > 0 or self.IconFileY > 0 then
+		required = true
+		OutputString = string.format(":%d:%d%s", self.IconFileX, self.IconFileY, OutputString)
+	end
+
+	if required or self.OffsetX > 0 or self.OffsetY > 0 then
+		required = true
+		OutputString = string.format(":%d:%d%s", self.OffsetX, self.OffsetY, OutputString)
+	end
+
+	-- Size2 can be nil, so to avoid comparing or concatenating a nil, we have some special handling
+	local localsizetwo = self.SizeTwo or ""
+	if required or (self.SizeTwo and self.SizeTwo >= 0) then
+		OutputString = string.format(":%s%s", localsizetwo, OutputString)
+	end
+
+	-- Size1 and the icon path are required.
+	OutputString = string.format("%s:%d%s", self.IconFile, self.SizeOne, OutputString)
+
+	return OutputString
+end -- IconClass:GetIconStringInner()
+
+
+function IconClass:GetIconString()
+	-- This function wraps the icon string in the control code that causes it to display as an icon
+	return string.format("\124T%s\124t", self:GetIconStringInner())
+end -- IconClass:GetIconString()
+
+
+-- @TODO: Add method to get the TexCoords of an icon for inclusion in the LDB object's iconCoords parameter.
+-- See:
+--	https://wow.gamepedia.com/API_Texture_SetTexCoord
+--	https://github.com/tekkub/libdatabroker-1-1/wiki/Data-Specifications
+
+
+--#########################################
+--# Select the actual icons used
+--#########################################

 -- The icons to use when displaying in the broker display
-BRM.MainIcon = "Interface\\Icons\\Inv_helm_robe_raidpriest_k_01" -- Default icon to use until we determine the faction later.
-BRM.AllianceIcon = "Interface\\Icons\\Inv_tabard_a_78wrynnvanguard"
-BRM.HordeIcon = "Interface\\Icons\\Inv_tabard_a_77voljinsspear"
-BRM.TankIcon = "Interface\\Icons\\Inv_shield_06.blp"
-BRM.HealerIcon = "Interface\\Icons\\spell_chargepositive.blp"
-BRM.DPSIcon = "Interface\\Icons\\Inv_sword_27.blp"
-BRM.UnknownIcon = "Interface\\Icons\\Inv_misc_questionmark.blp"
+BRM.MainIcon = IconClass("Interface\\Icons\\Inv_helm_robe_raidpriest_k_01") -- Default icon to use until we determine the faction later.
+BRM.AllianceIcon = IconClass("Interface\\Calendar\\UI-Calendar-Event-PVP02")
+BRM.HordeIcon = IconClass("Interface\\Calendar\\UI-Calendar-Event-PVP01")
+BRM.TankIcon = IconClass("Interface\\Icons\\Inv_shield_06.blp")
+BRM.HealerIcon = IconClass("Interface\\Icons\\spell_chargepositive.blp")
+BRM.DPSIcon = IconClass("Interface\\Icons\\Inv_sword_27.blp")
+BRM.UnknownIcon = IconClass("Interface\\Icons\\Inv_misc_questionmark.blp")
+
+-- New role icons
+BRM.HealerIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-PORTRAITROLES.blp", 64, 64, 19, 39, 0, 20)
+BRM.TankIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-PORTRAITROLES.blp", 64, 64, 0, 19, 22, 41)
+BRM.DPSIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-PORTRAITROLES.blp", 64, 64, 19, 38, 22, 41)

 -- Icons I considered but didn't like
 --BRM.AllianceIcon = "Interface\\Icons\\Inv_misc_head_human_02"
 --BRM.HordeIcon = "Interface\\Icons\\Achievement_femalegoblinhead"
 --BRM.HealerIcon = "Interface\\Icons\\Spell_holy_flashheal.blp"
+--BRM.AllianceIcon = IconClass("Interface\\Icons\\Inv_tabard_a_78wrynnvanguard")
+--BRM.HordeIcon = IconClass("Interface\\Icons\\Inv_tabard_a_77voljinsspear")
+
+
+--#########################################
+--# Constants
+--#########################################

 -- The strings used by the game to represent the roles. I don't think these are localized in the game.
 BRM.ROLE_HEALER = "HEALER"
@@ -110,6 +219,10 @@ BRM.ROLE_TANK = "TANK"
 BRM.ROLE_DPS = "DAMAGER"
 BRM.ROLE_NONE = "NONE"

+-- The faction strings. Again, probably not localized
+BRM.FACTION_ALLIANCE = "Alliance"
+BRM.FACTION_HORDE = "Horde"
+
 -- The version of this add-on
 BRM.Version = "@project-version@"

@@ -149,16 +262,10 @@ BRM.IsActive = false
 --# Create string for count display
 --#########################################

-function BRM:IconString(icon)
-	local size = 16
-	return string.format("\124T" .. icon .. ":%d:%d\124t", size, size)
-end -- BRM:IconString(icon)
-
-
 function BRM:GetDisplayString()
-	local OutputString = string.format("%d %s %d %s %d %s %d", BRM.TotalCount, BRM:IconString(BRM.TankIcon), BRM.TankCount, BRM:IconString(BRM.HealerIcon), BRM.HealerCount, BRM:IconString(BRM.DPSIcon), BRM.DPSCount)
+	local OutputString = string.format("%d %s %d %s %d %s %d", BRM.TotalCount, BRM.TankIcon:GetIconString(), BRM.TankCount, BRM.HealerIcon:GetIconString(), BRM.HealerCount, BRM.DPSIcon:GetIconString(), BRM.DPSCount)
 	if BRM.UnknownCount > 0 then
-		OutputString = string.format("%s %s %d", OutputString, BRM:IconString(BRM.UnknownIcon), BRM.UnknownCount)
+		OutputString = string.format("%s %s %d", OutputString, BRM.UnknownIcon:GetIconString(), BRM.UnknownCount)
 	end
 	return OutputString
 end -- BRM:GetDisplayString()
@@ -282,7 +389,7 @@ BRM.LDO = _G.LibStub("LibDataBroker-1.1"):NewDataObject("Broker_RaidMakeup", {
 	type = "data source",
 	text = BRM:GetDisplayString(),
 	value = "0",
-	icon = BRM.MainIcon,
+	icon = BRM.MainIcon:GetIconString(),
 	label = "Broker_RaidMakeup",
 	OnTooltipShow = function()end,
 }) -- BRM.LDO creation
@@ -373,12 +480,14 @@ function BRM.Events:PLAYER_ENTERING_WORLD(...)
 		return
 	end

-	if "Horde" == BRM.Faction then
+	if BRM.FACTION_HORDE == BRM.Faction then
 		BRM:DebugPrint("Faction is Horde")
-		BRM.LDO.icon = BRM.HordeIcon
-	elseif "Alliance" == BRM.Faction then
+		BRM:DebugPrint(BRM.HordeIcon:GetIconStringInner())
+		BRM.LDO.icon = BRM.HordeIcon.IconFile
+	elseif BRM.FACTION_ALLIANCE == BRM.Faction then
 		BRM:DebugPrint("Faction is Alliance")
-		BRM.LDO.icon = BRM.AllianceIcon
+		BRM:DebugPrint(BRM.AllianceIcon:GetIconStringInner())
+		BRM.LDO.icon = BRM.AllianceIcon.IconFile
 	else
 		-- What the hell?
 		BRM:DebugPrint("Unknown faction detected - " .. BRM.Faction)