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