Quantcast

Added minimap icon

KyrosKrane [06-02-18 - 22:08]
Added minimap icon
Filename
Broker_RaidMakeup.lua
Broker_RaidMakeup.toc
Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua
diff --git a/Broker_RaidMakeup.lua b/Broker_RaidMakeup.lua
index f4f17ed..2f364c0 100644
--- a/Broker_RaidMakeup.lua
+++ b/Broker_RaidMakeup.lua
@@ -75,9 +75,9 @@ BRM.DebugMode = true

 -- Print debug output to the chat frame.
 function BRM:DebugPrint(...)
-	if (BRM.DebugMode) then
+	if not BRM.DebugMode then return end
+
 		print ("|cff" .. "a00000" .. "BRM Debug:|r", ...)
-	end
 end -- BRM:DebugPrint


@@ -87,6 +87,50 @@ function BRM:ChatPrint(...)
 end -- BRM:DebugPrint


+-- Debugging code to see what the hell is being passed in...
+function BRM:PrintVarArgs(...)
+	if not BRM.DebugMode then return end
+
+	local n = select('#', ...)
+	BRM:DebugPrint ("There are ", n, " items in varargs.")
+	local msg
+	for i = 1, n do
+		msg = select(i, ...)
+		BRM:DebugPrint ("Item ", i, " is ", msg)
+	end
+end -- BRM:PrintVarArgs()
+
+
+-- Dumps a table into chat. Not intended for production use.
+function BRM:DumpTable(tab, indent)
+	if not BRM.DebugMode then return end
+
+	if not indent then indent = 0 end
+	if indent > 10 then
+		BRM:DebugPrint("Recursion is at 11 already; aborting.")
+		return
+	end
+	for k, v in pairs(tab) do
+		local s = ""
+		if indent > 0 then
+			for i = 0, indent do
+				s = s .. "    "
+			end
+		end
+		if "table" == type(v) then
+			s = s .. "Item " .. k .. " is sub-table."
+			BRM:DebugPrint(s)
+			indent = indent + 1
+			BRM:DumpTable(v, indent)
+			indent = indent - 1
+		else
+			s = s .. "Item " .. k .. " is " .. tostring(v)
+			BRM:DebugPrint(s)
+		end
+	end
+end -- BRM:DumpTable()
+
+
 --#########################################
 --# Icon class setup
 --#########################################
@@ -247,7 +291,7 @@ SlashCmdList.BRM = function (...) BRM:HandleCommandLine(...) end

 function BRM:HandleCommandLine()
 	BRM.DebugMode = not BRM.DebugMode
-	BRM:ChatPrint("Printing debug statements is now " .. (BRM.DebugMode and "on." or "off."))
+	BRM:ChatPrint("Printing debug statements is now " .. (BRM.DebugMode and "on" or "off") .. ".")
 end
 --@end-alpha@

@@ -262,10 +306,10 @@ BRM.DPSCount = 0
 BRM.UnknownCount = 0
 BRM.TotalCount = 0

--- The game is firing the ACTIVE_TALENT_GROUP_CHANGED event before the PLAYER_LOGIN event.
+-- The game is firing the ACTIVE_TALENT_GROUP_CHANGED event before the PLAYER_ENTERING_WORLD event.
 -- Since we're not fully in the world yet at that point, the group and raid query functions are returning unexpected results.
 -- So, we use this variable to track whether the add-on is loaded and active.
--- We turn it on in the PLAYER_LOGIN event.
+-- We turn it on in the PLAYER_ENTERING_WORLD event.
 BRM.IsActive = false

 --#########################################
@@ -410,9 +454,17 @@ BRM.LDO = _G.LibStub("LibDataBroker-1.1"):NewDataObject("Broker_RaidMakeup", {


 -- Handler for if user clicks on the display
-function BRM.LDO:OnClick(...)
+function BRM.LDO:OnClick(button)
 	BRM:DebugPrint("Got click on LDB object")

+	if button == "LeftButton" then
+		BRM:DebugPrint("Got left button")
+	elseif button == "RightButton" then
+		BRM:DebugPrint("Got right button")
+	else
+		BRM:DebugPrint("Got some other button")
+	end
+
 	-- I'm trying to capture which situations don't result in an automatic update.
 	-- That essentially indicates either an event I missed coding for, or some kind of bug that resulted in invalid role counts.
 	local old_TankCount = BRM.TankCount
@@ -447,6 +499,7 @@ function BRM.LDO:OnClick(...)
 end -- BRM.LDO:OnClick()


+
 --#########################################
 --# Events to register and handle
 --#########################################
@@ -457,26 +510,64 @@ function BRM.Events:PLAYER_LOGIN(...)
 	BRM:DebugPrint("Got PLAYER_LOGIN event")
 end -- BRM.Events:PLAYER_LOGIN()

--- This event is only for debugging.
+
+-- This event is for loading our saved settings.
 function BRM.Events:ADDON_LOADED(addon)
 	BRM:DebugPrint("Got ADDON_LOADED for " .. addon)
-	if addon == "Broker_RaidMakeup" then
-		BRM:DebugPrint("Now processing stuff for this addon")
-	end -- if Broker_RaidMakeup
+	if addon ~= "Broker_RaidMakeup" then return end
+
+
+	--#########################################
+	--# Load saved settings
+	--#########################################
+
+	BRM:DebugPrint("Loading or creating DB")
+	if BRM_DB then
+		-- Load the settings saved by the game.
+		BRM:DebugPrint ("Restoring existing BRM DB")
+		BRM.DB = BRM_DB
+
+		-- This situation should only occur during development, but just in case, let's handle it.
+		if not BRM.DB.MinimapSettings then BRM.DB.MinimapSettings = {} end
+	else
+		-- Initialize settings on first use
+		BRM:DebugPrint ("Creating new BRM DB")
+		BRM.DB = {}
+		BRM.DB.Version = 1
+		BRM.DB.MinimapSettings = {}
+	end
+
+	BRM:DebugPrint ("DB contents follow")
+	BRM:DumpTable(BRM.DB)
+	BRM:DebugPrint ("End DB contents")
+
+	--#########################################
+	--# Minimap button for LDB object
+	--#########################################
+
+	-- Creating the minimap icon requires somewhere to save the data.
+	-- We don't load that until this event.
+	-- So, this is the earliest point we can create the minimap icon.
+
+	BRM.MinimapIcon = LibStub("LibDBIcon-1.0")
+	BRM.MinimapIcon:Register("Broker_RaidMakeup", BRM.LDO, BRM.DB.MinimapSettings)
 end -- BRM.Events:ADDON_LOADED()

+
 -- This triggers when someone joins or leaves a group, or changes their spec or role in the group.
 function BRM.Events:GROUP_ROSTER_UPDATE(...)
 	BRM:DebugPrint("Got GROUP_ROSTER_UPDATE")
 	BRM:UpdateComposition()
 end -- BRM.Events:GROUP_ROSTER_UPDATE()

+
 -- This triggers when the player changes their talent spec.
 function BRM.Events:ACTIVE_TALENT_GROUP_CHANGED(...)
 	BRM:DebugPrint("Got ACTIVE_TALENT_GROUP_CHANGED")
 	BRM:UpdateComposition()
 end -- BRM.Events:ACTIVE_TALENT_GROUP_CHANGED()

+
 -- On-load handler for addon initialization.
 function BRM.Events:PLAYER_ENTERING_WORLD(...)
 	-- Announce our load.
@@ -496,11 +587,11 @@ function BRM.Events:PLAYER_ENTERING_WORLD(...)

 	if BRM.FACTION_HORDE == BRM.Faction then
 		BRM:DebugPrint("Faction is Horde")
-		BRM:DebugPrint(BRM.HordeIcon:GetIconStringInner())
+		BRM:DebugPrint("Inner string is " .. BRM.HordeIcon:GetIconStringInner())
 		BRM.LDO.icon = BRM.HordeIcon.IconFile
 	elseif BRM.FACTION_ALLIANCE == BRM.Faction then
 		BRM:DebugPrint("Faction is Alliance")
-		BRM:DebugPrint(BRM.AllianceIcon:GetIconStringInner())
+		BRM:DebugPrint("Inner string is " .. BRM.AllianceIcon:GetIconStringInner())
 		BRM.LDO.icon = BRM.AllianceIcon.IconFile
 	else
 		-- What the hell?
@@ -510,6 +601,13 @@ function BRM.Events:PLAYER_ENTERING_WORLD(...)
 end -- BRM.Events:PLAYER_ENTERING_WORLD()


+-- Save the db on logout.
+function BRM.Events:PLAYER_LOGOUT(...)
+	BRM:DebugPrint ("In PLAYER_LOGOUT, saving DB.")
+	BRM_DB = BRM.DB
+end -- BRM.Events:PLAYER_LOGOUT()
+
+
 --#########################################
 --# Implement the event handlers
 --#########################################
diff --git a/Broker_RaidMakeup.toc b/Broker_RaidMakeup.toc
index 984ccf5..0b0e0b3 100644
--- a/Broker_RaidMakeup.toc
+++ b/Broker_RaidMakeup.toc
@@ -7,8 +7,14 @@
 ## X-Curse-Project-ID: 294431
 ## X-WoWI-ID: 24656

-libs\LibStub\LibStub.lua
-libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
-libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
+## SavedVariablesPerCharacter: BRM_DB
+
+
+#@no-lib-strip@
+Libs\LibStub\LibStub.lua
+Libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
+Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
+Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
+#@end-no-lib-strip@

 Broker_RaidMakeup.lua
diff --git a/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua b/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua
new file mode 100644
index 0000000..00925ec
--- /dev/null
+++ b/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua
@@ -0,0 +1,334 @@
+
+-----------------------------------------------------------------------
+-- LibDBIcon-1.0
+--
+-- Allows addons to easily create a lightweight minimap icon as an alternative to heavier LDB displays.
+--
+
+local DBICON10 = "LibDBIcon-1.0"
+local DBICON10_MINOR = 36 -- Bump on changes
+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.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
+lib.notCreated = lib.notCreated or {}
+lib.tooltip = lib.tooltip or CreateFrame("GameTooltip", "LibDBIconTooltip", UIParent, "GameTooltipTemplate")
+
+function lib:IconCallback(event, name, key, value)
+	if lib.objects[name] then
+		if key == "icon" then
+			lib.objects[name].icon:SetTexture(value)
+		elseif key == "iconCoords" then
+			lib.objects[name].icon:UpdateCoord()
+		elseif key == "iconR" then
+			local _, g, b = lib.objects[name].icon:GetVertexColor()
+			lib.objects[name].icon:SetVertexColor(value, g, b)
+		elseif key == "iconG" then
+			local r, _, b = lib.objects[name].icon:GetVertexColor()
+			lib.objects[name].icon:SetVertexColor(r, value, b)
+		elseif key == "iconB" then
+			local r, g = lib.objects[name].icon:GetVertexColor()
+			lib.objects[name].icon:SetVertexColor(r, g, value)
+		end
+	end
+end
+if not lib.callbackRegistered then
+	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
+	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback")
+	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconR", "IconCallback")
+	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconG", "IconCallback")
+	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconB", "IconCallback")
+	lib.callbackRegistered = true
+end
+
+local function getAnchors(frame)
+	local x, y = frame:GetCenter()
+	if not x or not y then return "CENTER" 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
+		lib.tooltip:SetOwner(self, "ANCHOR_NONE")
+		lib.tooltip:SetPoint(getAnchors(self))
+		obj.OnTooltipShow(lib.tooltip)
+		lib.tooltip:Show()
+	elseif obj.OnEnter then
+		obj.OnEnter(self)
+	end
+end
+
+local function onLeave(self)
+	local obj = self.dataObject
+	lib.tooltip:Hide()
+	if obj.OnLeave then obj.OnLeave(self) end
+end
+
+--------------------------------------------------------------------------------
+
+local onClick, onMouseUp, onMouseDown, onDragStart, onDragStop, updatePosition
+
+do
+	local minimapShapes = {
+		["ROUND"] = {true, true, true, true},
+		["SQUARE"] = {false, false, false, false},
+		["CORNER-TOPLEFT"] = {false, false, false, true},
+		["CORNER-TOPRIGHT"] = {false, false, true, false},
+		["CORNER-BOTTOMLEFT"] = {false, true, false, false},
+		["CORNER-BOTTOMRIGHT"] = {true, false, false, false},
+		["SIDE-LEFT"] = {false, true, false, true},
+		["SIDE-RIGHT"] = {true, false, true, false},
+		["SIDE-TOP"] = {false, false, true, true},
+		["SIDE-BOTTOM"] = {true, true, false, false},
+		["TRICORNER-TOPLEFT"] = {false, true, true, true},
+		["TRICORNER-TOPRIGHT"] = {true, false, true, true},
+		["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
+		["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false},
+	}
+
+	function updatePosition(button)
+		local angle = math.rad(button.db and button.db.minimapPos or button.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
+end
+
+function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end
+function onMouseDown(self) self.isMouseDown = true; self.icon:UpdateCoord() end
+function onMouseUp(self) self.isMouseDown = false; self.icon:UpdateCoord() end
+
+do
+	local function onUpdate(self)
+		local mx, my = Minimap:GetCenter()
+		local px, py = GetCursorPosition()
+		local scale = Minimap:GetEffectiveScale()
+		px, py = px / scale, py / scale
+		if self.db then
+			self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
+		else
+			self.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
+		end
+		updatePosition(self)
+	end
+
+	function onDragStart(self)
+		self:LockHighlight()
+		self.isMouseDown = true
+		self.icon:UpdateCoord()
+		self:SetScript("OnUpdate", onUpdate)
+		self.isMoving = true
+		lib.tooltip:Hide()
+	end
+end
+
+function onDragStop(self)
+	self:SetScript("OnUpdate", nil)
+	self.isMouseDown = false
+	self.icon:UpdateCoord()
+	self:UnlockHighlight()
+	self.isMoving = nil
+end
+
+local defaultCoords = {0, 1, 0, 1}
+local function updateCoord(self)
+	local coords = self:GetParent().dataObject.iconCoords or defaultCoords
+	local deltaX, deltaY = 0, 0
+	if not self:GetParent().isMouseDown then
+		deltaX = (coords[2] - coords[1]) * 0.05
+		deltaY = (coords[4] - coords[3]) * 0.05
+	end
+	self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY)
+end
+
+local function createButton(name, object, db)
+	local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
+	button.dataObject = object
+	button.db = db
+	button:SetFrameStrata("MEDIUM")
+	button:SetSize(31, 31)
+	button:SetFrameLevel(8)
+	button:RegisterForClicks("anyUp")
+	button:RegisterForDrag("LeftButton")
+	button:SetHighlightTexture(136477) --"Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight"
+	local overlay = button:CreateTexture(nil, "OVERLAY")
+	overlay:SetSize(53, 53)
+	overlay:SetTexture(136430) --"Interface\\Minimap\\MiniMap-TrackingBorder"
+	overlay:SetPoint("TOPLEFT")
+	local background = button:CreateTexture(nil, "BACKGROUND")
+	background:SetSize(20, 20)
+	background:SetTexture(136467) --"Interface\\Minimap\\UI-Minimap-Background"
+	background:SetPoint("TOPLEFT", 7, -5)
+	local icon = button:CreateTexture(nil, "ARTWORK")
+	icon:SetSize(17, 17)
+	icon:SetTexture(object.icon)
+	icon:SetPoint("TOPLEFT", 7, -6)
+	button.icon = icon
+	button.isMouseDown = false
+
+	local r, g, b = icon:GetVertexColor()
+	icon:SetVertexColor(object.iconR or r, object.iconG or g, object.iconB or b)
+
+	icon.UpdateCoord = updateCoord
+	icon:UpdateCoord()
+
+	button:SetScript("OnEnter", onEnter)
+	button:SetScript("OnLeave", onLeave)
+	button:SetScript("OnClick", onClick)
+	if not db or not db.lock then
+		button:SetScript("OnDragStart", onDragStart)
+		button:SetScript("OnDragStop", onDragStop)
+	end
+	button:SetScript("OnMouseDown", onMouseDown)
+	button:SetScript("OnMouseUp", onMouseUp)
+
+	lib.objects[name] = button
+
+	if lib.loggedIn then
+		updatePosition(button)
+		if not db or not db.hide then button:Show()
+		else button:Hide() end
+	end
+	lib.callbacks:Fire("LibDBIcon_IconCreated", button, name) -- Fire 'Icon Created' callback
+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 or 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
+
+local function getDatabase(name)
+	return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db
+end
+
+function lib:Register(name, object, db)
+	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 lib.disabled and (not db or not db.hide) then
+		createButton(name, object, db)
+	else
+		lib.notCreated[name] = {object, db}
+	end
+end
+
+function lib:Lock(name)
+	if not lib:IsRegistered(name) then return end
+	if lib.objects[name] then
+		lib.objects[name]:SetScript("OnDragStart", nil)
+		lib.objects[name]:SetScript("OnDragStop", nil)
+	end
+	local db = getDatabase(name)
+	if db then db.lock = true end
+end
+
+function lib:Unlock(name)
+	if not lib:IsRegistered(name) then return end
+	if lib.objects[name] then
+		lib.objects[name]:SetScript("OnDragStart", onDragStart)
+		lib.objects[name]:SetScript("OnDragStop", onDragStop)
+	end
+	local db = getDatabase(name)
+	if db then db.lock = nil 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)
+	if not button.db or not button.db.hide then
+		button:Show()
+	else
+		button:Hide()
+	end
+	if not button.db or not button.db.lock then
+		button:SetScript("OnDragStart", onDragStart)
+		button:SetScript("OnDragStop", onDragStop)
+	else
+		button:SetScript("OnDragStart", nil)
+		button:SetScript("OnDragStop", nil)
+	end
+end
+function lib:GetMinimapButton(name)
+	return lib.objects[name]
+end
+
+function lib:EnableLibrary()
+	lib.disabled = nil
+	for name, object in pairs(lib.objects) do
+		if not object.db or not object.db.hide then
+			object:Show()
+			updatePosition(object)
+		end
+	end
+	for name, data in pairs(lib.notCreated) do
+		if not data.db or not data.db.hide then
+			createButton(name, data[1], data[2])
+			lib.notCreated[name] = nil
+		end
+	end
+end
+
+function lib:DisableLibrary()
+	lib.disabled = true
+	for name, object in pairs(lib.objects) do
+		object:Hide()
+	end
+end
+