annotate libs/LibDBIcon-1.0/LibDBIcon-1.0.lua @ 0:ec731d2fe6ba

Version 1.2.12.0
author Adam tegen <adam.tegen@gmail.com>
date Tue, 20 May 2014 21:43:23 -0500
parents
children
rev   line source
adam@0 1 --[[
adam@0 2 Name: DBIcon-1.0
adam@0 3 Revision: $Rev: 25 $
adam@0 4 Author(s): Rabbit (rabbit.magtheridon@gmail.com)
adam@0 5 Description: Allows addons to register to recieve a lightweight minimap icon as an alternative to more heavy LDB displays.
adam@0 6 Dependencies: LibStub
adam@0 7 License: GPL v2 or later.
adam@0 8 ]]
adam@0 9
adam@0 10 --[[
adam@0 11 Copyright (C) 2008-2011 Rabbit
adam@0 12
adam@0 13 This program is free software; you can redistribute it and/or
adam@0 14 modify it under the terms of the GNU General Public License
adam@0 15 as published by the Free Software Foundation; either version 2
adam@0 16 of the License, or (at your option) any later version.
adam@0 17
adam@0 18 This program is distributed in the hope that it will be useful,
adam@0 19 but WITHOUT ANY WARRANTY; without even the implied warranty of
adam@0 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
adam@0 21 GNU General Public License for more details.
adam@0 22
adam@0 23 You should have received a copy of the GNU General Public License
adam@0 24 along with this program; if not, write to the Free Software
adam@0 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
adam@0 26 ]]
adam@0 27
adam@0 28 -----------------------------------------------------------------------
adam@0 29 -- DBIcon-1.0
adam@0 30 --
adam@0 31 -- Disclaimer: Most of this code was ripped from Barrel but fixed, streamlined
adam@0 32 -- and cleaned up a lot so that it no longer sucks.
adam@0 33 --
adam@0 34
adam@0 35 local DBICON10 = "LibDBIcon-1.0"
adam@0 36 local DBICON10_MINOR = tonumber(("$Rev: 25 $"):match("(%d+)"))
adam@0 37 if not LibStub then error(DBICON10 .. " requires LibStub.") end
adam@0 38 local ldb = LibStub("LibDataBroker-1.1", true)
adam@0 39 if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
adam@0 40 local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR)
adam@0 41 if not lib then return end
adam@0 42
adam@0 43 lib.disabled = lib.disabled or nil
adam@0 44 lib.objects = lib.objects or {}
adam@0 45 lib.callbackRegistered = lib.callbackRegistered or nil
adam@0 46 lib.notCreated = lib.notCreated or {}
adam@0 47
adam@0 48 function lib:IconCallback(event, name, key, value, dataobj)
adam@0 49 if lib.objects[name] then
adam@0 50 if key == "icon" then
adam@0 51 lib.objects[name].icon:SetTexture(value)
adam@0 52 elseif key == "iconCoords" then
adam@0 53 lib.objects[name].icon:UpdateCoord()
adam@0 54 end
adam@0 55 end
adam@0 56 end
adam@0 57 if not lib.callbackRegistered then
adam@0 58 ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
adam@0 59 ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback")
adam@0 60 lib.callbackRegistered = true
adam@0 61 end
adam@0 62
adam@0 63 -- Tooltip code ripped from StatBlockCore by Funkydude
adam@0 64 local function getAnchors(frame)
adam@0 65 local x, y = frame:GetCenter()
adam@0 66 if not x or not y then return "CENTER" end
adam@0 67 local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
adam@0 68 local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
adam@0 69 return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
adam@0 70 end
adam@0 71
adam@0 72 local function onEnter(self)
adam@0 73 if self.isMoving then return end
adam@0 74 local obj = self.dataObject
adam@0 75 if obj.OnTooltipShow then
adam@0 76 GameTooltip:SetOwner(self, "ANCHOR_NONE")
adam@0 77 GameTooltip:SetPoint(getAnchors(self))
adam@0 78 obj.OnTooltipShow(GameTooltip)
adam@0 79 GameTooltip:Show()
adam@0 80 elseif obj.OnEnter then
adam@0 81 obj.OnEnter(self)
adam@0 82 end
adam@0 83 end
adam@0 84
adam@0 85 local function onLeave(self)
adam@0 86 local obj = self.dataObject
adam@0 87 GameTooltip:Hide()
adam@0 88 if obj.OnLeave then obj.OnLeave(self) end
adam@0 89 end
adam@0 90
adam@0 91 --------------------------------------------------------------------------------
adam@0 92
adam@0 93 local onClick, onMouseUp, onMouseDown, onDragStart, onDragEnd, updatePosition
adam@0 94
adam@0 95 do
adam@0 96 local minimapShapes = {
adam@0 97 ["ROUND"] = {true, true, true, true},
adam@0 98 ["SQUARE"] = {false, false, false, false},
adam@0 99 ["CORNER-TOPLEFT"] = {false, false, false, true},
adam@0 100 ["CORNER-TOPRIGHT"] = {false, false, true, false},
adam@0 101 ["CORNER-BOTTOMLEFT"] = {false, true, false, false},
adam@0 102 ["CORNER-BOTTOMRIGHT"] = {true, false, false, false},
adam@0 103 ["SIDE-LEFT"] = {false, true, false, true},
adam@0 104 ["SIDE-RIGHT"] = {true, false, true, false},
adam@0 105 ["SIDE-TOP"] = {false, false, true, true},
adam@0 106 ["SIDE-BOTTOM"] = {true, true, false, false},
adam@0 107 ["TRICORNER-TOPLEFT"] = {false, true, true, true},
adam@0 108 ["TRICORNER-TOPRIGHT"] = {true, false, true, true},
adam@0 109 ["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
adam@0 110 ["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false},
adam@0 111 }
adam@0 112
adam@0 113 function updatePosition(button)
adam@0 114 local angle = math.rad(button.db and button.db.minimapPos or button.minimapPos or 225)
adam@0 115 local x, y, q = math.cos(angle), math.sin(angle), 1
adam@0 116 if x < 0 then q = q + 1 end
adam@0 117 if y > 0 then q = q + 2 end
adam@0 118 local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
adam@0 119 local quadTable = minimapShapes[minimapShape]
adam@0 120 if quadTable[q] then
adam@0 121 x, y = x*80, y*80
adam@0 122 else
adam@0 123 local diagRadius = 103.13708498985 --math.sqrt(2*(80)^2)-10
adam@0 124 x = math.max(-80, math.min(x*diagRadius, 80))
adam@0 125 y = math.max(-80, math.min(y*diagRadius, 80))
adam@0 126 end
adam@0 127 button:SetPoint("CENTER", Minimap, "CENTER", x, y)
adam@0 128 end
adam@0 129 end
adam@0 130
adam@0 131 function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end
adam@0 132 function onMouseDown(self) self.isMouseDown = true; self.icon:UpdateCoord() end
adam@0 133 function onMouseUp(self) self.isMouseDown = false; self.icon:UpdateCoord() end
adam@0 134
adam@0 135 do
adam@0 136 local function onUpdate(self)
adam@0 137 local mx, my = Minimap:GetCenter()
adam@0 138 local px, py = GetCursorPosition()
adam@0 139 local scale = Minimap:GetEffectiveScale()
adam@0 140 px, py = px / scale, py / scale
adam@0 141 if self.db then
adam@0 142 self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
adam@0 143 else
adam@0 144 self.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
adam@0 145 end
adam@0 146 updatePosition(self)
adam@0 147 end
adam@0 148
adam@0 149 function onDragStart(self)
adam@0 150 self:LockHighlight()
adam@0 151 self.isMouseDown = true
adam@0 152 self.icon:UpdateCoord()
adam@0 153 self:SetScript("OnUpdate", onUpdate)
adam@0 154 self.isMoving = true
adam@0 155 GameTooltip:Hide()
adam@0 156 end
adam@0 157 end
adam@0 158
adam@0 159 function onDragStop(self)
adam@0 160 self:SetScript("OnUpdate", nil)
adam@0 161 self.isMouseDown = false
adam@0 162 self.icon:UpdateCoord()
adam@0 163 self:UnlockHighlight()
adam@0 164 self.isMoving = nil
adam@0 165 end
adam@0 166
adam@0 167 local defaultCoords = {0, 1, 0, 1}
adam@0 168 local function updateCoord(self)
adam@0 169 local coords = self:GetParent().dataObject.iconCoords or defaultCoords
adam@0 170 local deltaX, deltaY = 0, 0
adam@0 171 if not self:GetParent().isMouseDown then
adam@0 172 deltaX = (coords[2] - coords[1]) * 0.05
adam@0 173 deltaY = (coords[4] - coords[3]) * 0.05
adam@0 174 end
adam@0 175 self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY)
adam@0 176 end
adam@0 177
adam@0 178 local function createButton(name, object, db)
adam@0 179 local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
adam@0 180 button.dataObject = object
adam@0 181 button.db = db
adam@0 182 button:SetFrameStrata("MEDIUM")
adam@0 183 button:SetWidth(31); button:SetHeight(31)
adam@0 184 button:SetFrameLevel(8)
adam@0 185 button:RegisterForClicks("anyUp")
adam@0 186 button:RegisterForDrag("LeftButton")
adam@0 187 button:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
adam@0 188 local overlay = button:CreateTexture(nil, "OVERLAY")
adam@0 189 overlay:SetWidth(53); overlay:SetHeight(53)
adam@0 190 overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
adam@0 191 overlay:SetPoint("TOPLEFT")
adam@0 192 local background = button:CreateTexture(nil, "BACKGROUND")
adam@0 193 background:SetWidth(20); background:SetHeight(20)
adam@0 194 background:SetTexture("Interface\\Minimap\\UI-Minimap-Background")
adam@0 195 background:SetPoint("TOPLEFT", 7, -5)
adam@0 196 local icon = button:CreateTexture(nil, "ARTWORK")
adam@0 197 icon:SetWidth(17); icon:SetHeight(17)
adam@0 198 icon:SetTexture(object.icon)
adam@0 199 icon:SetPoint("TOPLEFT", 7, -6)
adam@0 200 button.icon = icon
adam@0 201 button.isMouseDown = false
adam@0 202
adam@0 203 icon.UpdateCoord = updateCoord
adam@0 204 icon:UpdateCoord()
adam@0 205
adam@0 206 button:SetScript("OnEnter", onEnter)
adam@0 207 button:SetScript("OnLeave", onLeave)
adam@0 208 button:SetScript("OnClick", onClick)
adam@0 209 if not db or not db.lock then
adam@0 210 button:SetScript("OnDragStart", onDragStart)
adam@0 211 button:SetScript("OnDragStop", onDragStop)
adam@0 212 end
adam@0 213 button:SetScript("OnMouseDown", onMouseDown)
adam@0 214 button:SetScript("OnMouseUp", onMouseUp)
adam@0 215
adam@0 216 lib.objects[name] = button
adam@0 217
adam@0 218 if lib.loggedIn then
adam@0 219 updatePosition(button)
adam@0 220 if not db or not db.hide then button:Show()
adam@0 221 else button:Hide() end
adam@0 222 end
adam@0 223 end
adam@0 224
adam@0 225 -- We could use a metatable.__index on lib.objects, but then we'd create
adam@0 226 -- the icons when checking things like :IsRegistered, which is not necessary.
adam@0 227 local function check(name)
adam@0 228 if lib.notCreated[name] then
adam@0 229 createButton(name, lib.notCreated[name][1], lib.notCreated[name][2])
adam@0 230 lib.notCreated[name] = nil
adam@0 231 end
adam@0 232 end
adam@0 233
adam@0 234 lib.loggedIn = lib.loggedIn or false
adam@0 235 -- Wait a bit with the initial positioning to let any GetMinimapShape addons
adam@0 236 -- load up.
adam@0 237 if not lib.loggedIn then
adam@0 238 local f = CreateFrame("Frame")
adam@0 239 f:SetScript("OnEvent", function()
adam@0 240 for _, object in pairs(lib.objects) do
adam@0 241 updatePosition(object)
adam@0 242 if not lib.disabled and (not object.db or not object.db.hide) then object:Show()
adam@0 243 else object:Hide() end
adam@0 244 end
adam@0 245 lib.loggedIn = true
adam@0 246 f:SetScript("OnEvent", nil)
adam@0 247 f = nil
adam@0 248 end)
adam@0 249 f:RegisterEvent("PLAYER_LOGIN")
adam@0 250 end
adam@0 251
adam@0 252 local function getDatabase(name)
adam@0 253 return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db
adam@0 254 end
adam@0 255
adam@0 256 function lib:Register(name, object, db)
adam@0 257 if not object.icon then error("Can't register LDB objects without icons set!") end
adam@0 258 if lib.objects[name] or lib.notCreated[name] then error("Already registered, nubcake.") end
adam@0 259 if not lib.disabled and (not db or not db.hide) then
adam@0 260 createButton(name, object, db)
adam@0 261 else
adam@0 262 lib.notCreated[name] = {object, db}
adam@0 263 end
adam@0 264 end
adam@0 265
adam@0 266 function lib:Lock(name)
adam@0 267 if not lib:IsRegistered(name) then return end
adam@0 268 if lib.objects[name] then
adam@0 269 lib.objects[name]:SetScript("OnDragStart", nil)
adam@0 270 lib.objects[name]:SetScript("OnDragStop", nil)
adam@0 271 end
adam@0 272 local db = getDatabase(name)
adam@0 273 if db then db.lock = true end
adam@0 274 end
adam@0 275
adam@0 276 function lib:Unlock(name)
adam@0 277 if not lib:IsRegistered(name) then return end
adam@0 278 if lib.objects[name] then
adam@0 279 lib.objects[name]:SetScript("OnDragStart", onDragStart)
adam@0 280 lib.objects[name]:SetScript("OnDragStop", onDragStop)
adam@0 281 end
adam@0 282 local db = getDatabase(name)
adam@0 283 if db then db.lock = nil end
adam@0 284 end
adam@0 285
adam@0 286 function lib:Hide(name)
adam@0 287 if not lib.objects[name] then return end
adam@0 288 lib.objects[name]:Hide()
adam@0 289 end
adam@0 290 function lib:Show(name)
adam@0 291 if lib.disabled then return end
adam@0 292 check(name)
adam@0 293 lib.objects[name]:Show()
adam@0 294 updatePosition(lib.objects[name])
adam@0 295 end
adam@0 296 function lib:IsRegistered(name)
adam@0 297 return (lib.objects[name] or lib.notCreated[name]) and true or false
adam@0 298 end
adam@0 299 function lib:Refresh(name, db)
adam@0 300 if lib.disabled then return end
adam@0 301 check(name)
adam@0 302 local button = lib.objects[name]
adam@0 303 if db then button.db = db end
adam@0 304 updatePosition(button)
adam@0 305 if not button.db or not button.db.hide then
adam@0 306 button:Show()
adam@0 307 else
adam@0 308 button:Hide()
adam@0 309 end
adam@0 310 if not button.db or not button.db.lock then
adam@0 311 button:SetScript("OnDragStart", onDragStart)
adam@0 312 button:SetScript("OnDragStop", onDragStop)
adam@0 313 else
adam@0 314 button:SetScript("OnDragStart", nil)
adam@0 315 button:SetScript("OnDragStop", nil)
adam@0 316 end
adam@0 317 end
adam@0 318 function lib:GetMinimapButton(name)
adam@0 319 return lib.objects[name]
adam@0 320 end
adam@0 321
adam@0 322 function lib:EnableLibrary()
adam@0 323 lib.disabled = nil
adam@0 324 for name, object in pairs(lib.objects) do
adam@0 325 if not object.db or not object.db.hide then
adam@0 326 object:Show()
adam@0 327 updatePosition(object)
adam@0 328 end
adam@0 329 end
adam@0 330 for name, data in pairs(lib.notCreated) do
adam@0 331 if not data.db or not data.db.hide then
adam@0 332 createButton(name, data[1], data[2])
adam@0 333 lib.notCreated[name] = nil
adam@0 334 end
adam@0 335 end
adam@0 336 end
adam@0 337
adam@0 338 function lib:DisableLibrary()
adam@0 339 lib.disabled = true
adam@0 340 for name, object in pairs(lib.objects) do
adam@0 341 object:Hide()
adam@0 342 end
adam@0 343 end
adam@0 344