annotate Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua @ 3:e75889a45130

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