Mercurial > wow > hotcorners
comparison Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua @ 0:fc346da3afd9
First commit Hot Corners standalone.
| author | tercio |
|---|---|
| date | Fri, 08 Aug 2014 12:35:17 -0300 |
| parents | |
| children | 371e14cd2feb |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:fc346da3afd9 |
|---|---|
| 1 --[[ | |
| 2 Name: DBIcon-1.0 | |
| 3 Revision: $Rev: 34 $ | |
| 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: 34 $"):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.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib) | |
| 47 lib.notCreated = lib.notCreated or {} | |
| 48 | |
| 49 function lib:IconCallback(event, name, key, value, dataobj) | |
| 50 if lib.objects[name] then | |
| 51 if key == "icon" then | |
| 52 lib.objects[name].icon:SetTexture(value) | |
| 53 elseif key == "iconCoords" then | |
| 54 lib.objects[name].icon:UpdateCoord() | |
| 55 elseif key == "iconR" then | |
| 56 local _, g, b = lib.objects[name].icon:GetVertexColor() | |
| 57 lib.objects[name].icon:SetVertexColor(value, g, b) | |
| 58 elseif key == "iconG" then | |
| 59 local r, _, b = lib.objects[name].icon:GetVertexColor() | |
| 60 lib.objects[name].icon:SetVertexColor(r, value, b) | |
| 61 elseif key == "iconB" then | |
| 62 local r, g = lib.objects[name].icon:GetVertexColor() | |
| 63 lib.objects[name].icon:SetVertexColor(r, g, value) | |
| 64 end | |
| 65 end | |
| 66 end | |
| 67 if not lib.callbackRegistered then | |
| 68 ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback") | |
| 69 ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback") | |
| 70 ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconR", "IconCallback") | |
| 71 ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconG", "IconCallback") | |
| 72 ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconB", "IconCallback") | |
| 73 lib.callbackRegistered = true | |
| 74 end | |
| 75 | |
| 76 -- Tooltip code ripped from StatBlockCore by Funkydude | |
| 77 local function getAnchors(frame) | |
| 78 local x, y = frame:GetCenter() | |
| 79 if not x or not y then return "CENTER" end | |
| 80 local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or "" | |
| 81 local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM" | |
| 82 return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf | |
| 83 end | |
| 84 | |
| 85 local function onEnter(self) | |
| 86 if self.isMoving then return end | |
| 87 local obj = self.dataObject | |
| 88 if obj.OnTooltipShow then | |
| 89 GameTooltip:SetOwner(self, "ANCHOR_NONE") | |
| 90 GameTooltip:SetPoint(getAnchors(self)) | |
| 91 obj.OnTooltipShow(GameTooltip) | |
| 92 GameTooltip:Show() | |
| 93 elseif obj.OnEnter then | |
| 94 obj.OnEnter(self) | |
| 95 end | |
| 96 end | |
| 97 | |
| 98 local function onLeave(self) | |
| 99 local obj = self.dataObject | |
| 100 GameTooltip:Hide() | |
| 101 if obj.OnLeave then obj.OnLeave(self) end | |
| 102 end | |
| 103 | |
| 104 -------------------------------------------------------------------------------- | |
| 105 | |
| 106 local onClick, onMouseUp, onMouseDown, onDragStart, onDragStop, onDragEnd, updatePosition | |
| 107 | |
| 108 do | |
| 109 local minimapShapes = { | |
| 110 ["ROUND"] = {true, true, true, true}, | |
| 111 ["SQUARE"] = {false, false, false, false}, | |
| 112 ["CORNER-TOPLEFT"] = {false, false, false, true}, | |
| 113 ["CORNER-TOPRIGHT"] = {false, false, true, false}, | |
| 114 ["CORNER-BOTTOMLEFT"] = {false, true, false, false}, | |
| 115 ["CORNER-BOTTOMRIGHT"] = {true, false, false, false}, | |
| 116 ["SIDE-LEFT"] = {false, true, false, true}, | |
| 117 ["SIDE-RIGHT"] = {true, false, true, false}, | |
| 118 ["SIDE-TOP"] = {false, false, true, true}, | |
| 119 ["SIDE-BOTTOM"] = {true, true, false, false}, | |
| 120 ["TRICORNER-TOPLEFT"] = {false, true, true, true}, | |
| 121 ["TRICORNER-TOPRIGHT"] = {true, false, true, true}, | |
| 122 ["TRICORNER-BOTTOMLEFT"] = {true, true, false, true}, | |
| 123 ["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false}, | |
| 124 } | |
| 125 | |
| 126 function updatePosition(button) | |
| 127 local angle = math.rad(button.db and button.db.minimapPos or button.minimapPos or 225) | |
| 128 local x, y, q = math.cos(angle), math.sin(angle), 1 | |
| 129 if x < 0 then q = q + 1 end | |
| 130 if y > 0 then q = q + 2 end | |
| 131 local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND" | |
| 132 local quadTable = minimapShapes[minimapShape] | |
| 133 if quadTable[q] then | |
| 134 x, y = x*80, y*80 | |
| 135 else | |
| 136 local diagRadius = 103.13708498985 --math.sqrt(2*(80)^2)-10 | |
| 137 x = math.max(-80, math.min(x*diagRadius, 80)) | |
| 138 y = math.max(-80, math.min(y*diagRadius, 80)) | |
| 139 end | |
| 140 button:SetPoint("CENTER", Minimap, "CENTER", x, y) | |
| 141 end | |
| 142 end | |
| 143 | |
| 144 function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end | |
| 145 function onMouseDown(self) self.isMouseDown = true; self.icon:UpdateCoord() end | |
| 146 function onMouseUp(self) self.isMouseDown = false; self.icon:UpdateCoord() end | |
| 147 | |
| 148 do | |
| 149 local function onUpdate(self) | |
| 150 local mx, my = Minimap:GetCenter() | |
| 151 local px, py = GetCursorPosition() | |
| 152 local scale = Minimap:GetEffectiveScale() | |
| 153 px, py = px / scale, py / scale | |
| 154 if self.db then | |
| 155 self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360 | |
| 156 else | |
| 157 self.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360 | |
| 158 end | |
| 159 updatePosition(self) | |
| 160 end | |
| 161 | |
| 162 function onDragStart(self) | |
| 163 self:LockHighlight() | |
| 164 self.isMouseDown = true | |
| 165 self.icon:UpdateCoord() | |
| 166 self:SetScript("OnUpdate", onUpdate) | |
| 167 self.isMoving = true | |
| 168 GameTooltip:Hide() | |
| 169 end | |
| 170 end | |
| 171 | |
| 172 function onDragStop(self) | |
| 173 self:SetScript("OnUpdate", nil) | |
| 174 self.isMouseDown = false | |
| 175 self.icon:UpdateCoord() | |
| 176 self:UnlockHighlight() | |
| 177 self.isMoving = nil | |
| 178 end | |
| 179 | |
| 180 local defaultCoords = {0, 1, 0, 1} | |
| 181 local function updateCoord(self) | |
| 182 local coords = self:GetParent().dataObject.iconCoords or defaultCoords | |
| 183 local deltaX, deltaY = 0, 0 | |
| 184 if not self:GetParent().isMouseDown then | |
| 185 deltaX = (coords[2] - coords[1]) * 0.05 | |
| 186 deltaY = (coords[4] - coords[3]) * 0.05 | |
| 187 end | |
| 188 self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY) | |
| 189 end | |
| 190 | |
| 191 local function createButton(name, object, db) | |
| 192 local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap) | |
| 193 button.dataObject = object | |
| 194 button.db = db | |
| 195 button:SetFrameStrata("MEDIUM") | |
| 196 button:SetSize(31, 31) | |
| 197 button:SetFrameLevel(8) | |
| 198 button:RegisterForClicks("anyUp") | |
| 199 button:RegisterForDrag("LeftButton") | |
| 200 button:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight") | |
| 201 local overlay = button:CreateTexture(nil, "OVERLAY") | |
| 202 overlay:SetSize(53, 53) | |
| 203 overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder") | |
| 204 overlay:SetPoint("TOPLEFT") | |
| 205 local background = button:CreateTexture(nil, "BACKGROUND") | |
| 206 background:SetSize(20, 20) | |
| 207 background:SetTexture("Interface\\Minimap\\UI-Minimap-Background") | |
| 208 background:SetPoint("TOPLEFT", 7, -5) | |
| 209 local icon = button:CreateTexture(nil, "ARTWORK") | |
| 210 icon:SetSize(17, 17) | |
| 211 icon:SetTexture(object.icon) | |
| 212 icon:SetPoint("TOPLEFT", 7, -6) | |
| 213 button.icon = icon | |
| 214 button.isMouseDown = false | |
| 215 | |
| 216 local r, g, b = icon:GetVertexColor() | |
| 217 icon:SetVertexColor(object.iconR or r, object.iconG or g, object.iconB or b) | |
| 218 | |
| 219 icon.UpdateCoord = updateCoord | |
| 220 icon:UpdateCoord() | |
| 221 | |
| 222 button:SetScript("OnEnter", onEnter) | |
| 223 button:SetScript("OnLeave", onLeave) | |
| 224 button:SetScript("OnClick", onClick) | |
| 225 if not db or not db.lock then | |
| 226 button:SetScript("OnDragStart", onDragStart) | |
| 227 button:SetScript("OnDragStop", onDragStop) | |
| 228 end | |
| 229 button:SetScript("OnMouseDown", onMouseDown) | |
| 230 button:SetScript("OnMouseUp", onMouseUp) | |
| 231 | |
| 232 lib.objects[name] = button | |
| 233 | |
| 234 if lib.loggedIn then | |
| 235 updatePosition(button) | |
| 236 if not db or not db.hide then button:Show() | |
| 237 else button:Hide() end | |
| 238 end | |
| 239 lib.callbacks:Fire("LibDBIcon_IconCreated", button, name) -- Fire 'Icon Created' callback | |
| 240 end | |
| 241 | |
| 242 -- We could use a metatable.__index on lib.objects, but then we'd create | |
| 243 -- the icons when checking things like :IsRegistered, which is not necessary. | |
| 244 local function check(name) | |
| 245 if lib.notCreated[name] then | |
| 246 createButton(name, lib.notCreated[name][1], lib.notCreated[name][2]) | |
| 247 lib.notCreated[name] = nil | |
| 248 end | |
| 249 end | |
| 250 | |
| 251 lib.loggedIn = lib.loggedIn or false | |
| 252 -- Wait a bit with the initial positioning to let any GetMinimapShape addons | |
| 253 -- load up. | |
| 254 if not lib.loggedIn then | |
| 255 local f = CreateFrame("Frame") | |
| 256 f:SetScript("OnEvent", function() | |
| 257 for _, object in pairs(lib.objects) do | |
| 258 updatePosition(object) | |
| 259 if not lib.disabled and (not object.db or not object.db.hide) then object:Show() | |
| 260 else object:Hide() end | |
| 261 end | |
| 262 lib.loggedIn = true | |
| 263 f:SetScript("OnEvent", nil) | |
| 264 f = nil | |
| 265 end) | |
| 266 f:RegisterEvent("PLAYER_LOGIN") | |
| 267 end | |
| 268 | |
| 269 local function getDatabase(name) | |
| 270 return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db | |
| 271 end | |
| 272 | |
| 273 function lib:Register(name, object, db) | |
| 274 if not object.icon then error("Can't register LDB objects without icons set!") end | |
| 275 if lib.objects[name] or lib.notCreated[name] then error("Already registered, nubcake.") end | |
| 276 if not lib.disabled and (not db or not db.hide) then | |
| 277 createButton(name, object, db) | |
| 278 else | |
| 279 lib.notCreated[name] = {object, db} | |
| 280 end | |
| 281 end | |
| 282 | |
| 283 function lib:Lock(name) | |
| 284 if not lib:IsRegistered(name) then return end | |
| 285 if lib.objects[name] then | |
| 286 lib.objects[name]:SetScript("OnDragStart", nil) | |
| 287 lib.objects[name]:SetScript("OnDragStop", nil) | |
| 288 end | |
| 289 local db = getDatabase(name) | |
| 290 if db then db.lock = true end | |
| 291 end | |
| 292 | |
| 293 function lib:Unlock(name) | |
| 294 if not lib:IsRegistered(name) then return end | |
| 295 if lib.objects[name] then | |
| 296 lib.objects[name]:SetScript("OnDragStart", onDragStart) | |
| 297 lib.objects[name]:SetScript("OnDragStop", onDragStop) | |
| 298 end | |
| 299 local db = getDatabase(name) | |
| 300 if db then db.lock = nil end | |
| 301 end | |
| 302 | |
| 303 function lib:Hide(name) | |
| 304 if not lib.objects[name] then return end | |
| 305 lib.objects[name]:Hide() | |
| 306 end | |
| 307 function lib:Show(name) | |
| 308 if lib.disabled then return end | |
| 309 check(name) | |
| 310 lib.objects[name]:Show() | |
| 311 updatePosition(lib.objects[name]) | |
| 312 end | |
| 313 function lib:IsRegistered(name) | |
| 314 return (lib.objects[name] or lib.notCreated[name]) and true or false | |
| 315 end | |
| 316 function lib:Refresh(name, db) | |
| 317 if lib.disabled then return end | |
| 318 check(name) | |
| 319 local button = lib.objects[name] | |
| 320 if db then button.db = db end | |
| 321 updatePosition(button) | |
| 322 if not button.db or not button.db.hide then | |
| 323 button:Show() | |
| 324 else | |
| 325 button:Hide() | |
| 326 end | |
| 327 if not button.db or not button.db.lock then | |
| 328 button:SetScript("OnDragStart", onDragStart) | |
| 329 button:SetScript("OnDragStop", onDragStop) | |
| 330 else | |
| 331 button:SetScript("OnDragStart", nil) | |
| 332 button:SetScript("OnDragStop", nil) | |
| 333 end | |
| 334 end | |
| 335 function lib:GetMinimapButton(name) | |
| 336 return lib.objects[name] | |
| 337 end | |
| 338 | |
| 339 function lib:EnableLibrary() | |
| 340 lib.disabled = nil | |
| 341 for name, object in pairs(lib.objects) do | |
| 342 if not object.db or not object.db.hide then | |
| 343 object:Show() | |
| 344 updatePosition(object) | |
| 345 end | |
| 346 end | |
| 347 for name, data in pairs(lib.notCreated) do | |
| 348 if not data.db or not data.db.hide then | |
| 349 createButton(name, data[1], data[2]) | |
| 350 lib.notCreated[name] = nil | |
| 351 end | |
| 352 end | |
| 353 end | |
| 354 | |
| 355 function lib:DisableLibrary() | |
| 356 lib.disabled = true | |
| 357 for name, object in pairs(lib.objects) do | |
| 358 object:Hide() | |
| 359 end | |
| 360 end | |
| 361 |
