annotate Libs/LibWindow-1.1/LibWindow-1.1.lua @ 20:d200c55c85fb v7.3.2.020

- Added demonhunter class detection. - ToC Bump.
author Tercio
date Sat, 09 Dec 2017 11:04:43 -0200
parents f2a55f2d45c8
children fedcd7c21db9
rev   line source
Tercioo@9 1 --[[
Tercioo@9 2 Name: LibWindow-1.1
Tercioo@9 3 Revision: $Rev: 8 $
Tercioo@9 4 Author(s): Mikk (dpsgnome@mail.com)
Tercioo@9 5 Website: http://old.wowace.com/wiki/LibWindow-1.1
Tercioo@9 6 Documentation: http://old.wowace.com/wiki/LibWindow-1.1
Tercioo@9 7 SVN: http://svn.wowace.com/root/trunk/WindowLib/Window-1.0
Tercioo@9 8 Description: A library that handles the basics of "window" style frames: scaling, smart position saving, dragging..
Tercioo@9 9 Dependencies: none
Tercioo@9 10 License: Public Domain
Tercioo@9 11 ]]
Tercioo@9 12
Tercioo@9 13 local MAJOR = "LibWindow-1.1"
Tercioo@9 14 local MINOR = tonumber(("$Revision: 8 $"):match("(%d+)"))
Tercioo@9 15
Tercioo@9 16 local lib = LibStub:NewLibrary(MAJOR,MINOR)
Tercioo@9 17 if not lib then return end
Tercioo@9 18
Tercioo@9 19 local min,max,abs = min,max,abs
Tercioo@9 20 local pairs = pairs
Tercioo@9 21 local tostring = tostring
Tercioo@9 22 local UIParent,GetScreenWidth,GetScreenHeight,IsAltKeyDown = UIParent,GetScreenWidth,GetScreenHeight,IsAltKeyDown
Tercioo@9 23 -- GLOBALS: error, ChatFrame1, assert
Tercioo@9 24
Tercioo@9 25 local function print(msg) ChatFrame1:AddMessage(MAJOR..": "..tostring(msg)) end
Tercioo@9 26
Tercioo@9 27 lib.utilFrame = lib.utilFrame or CreateFrame("Frame")
Tercioo@9 28 lib.delayedSavePosition = lib.delayedSavePosition or {}
Tercioo@9 29 lib.windowData = lib.windowData or {}
Tercioo@9 30 --[frameref]={
Tercioo@9 31 -- names={optional names data from .RegisterConfig()}
Tercioo@9 32 -- storage= -- tableref where config data is read/written
Tercioo@9 33 -- altEnable=true/false
Tercioo@9 34 --}
Tercioo@9 35
Tercioo@9 36
Tercioo@9 37 lib.embeds = lib.embeds or {}
Tercioo@9 38
Tercioo@9 39 local mixins = {} -- "FuncName"=true
Tercioo@9 40
Tercioo@9 41
Tercioo@9 42
Tercioo@9 43 ---------------------------------------------------------
Tercioo@9 44 -- UTILITIES
Tercioo@9 45 ---------------------------------------------------------
Tercioo@9 46
Tercioo@9 47
Tercioo@9 48 local function getStorageName(frame, name)
Tercioo@9 49 local names = lib.windowData[frame].names
Tercioo@9 50 if names then
Tercioo@9 51 if names[name] then
Tercioo@9 52 return names[name]
Tercioo@9 53 end
Tercioo@9 54 if names.prefix then
Tercioo@9 55 return names.prefix .. name;
Tercioo@9 56 end
Tercioo@9 57 end
Tercioo@9 58 return name;
Tercioo@9 59 end
Tercioo@9 60
Tercioo@9 61 local function setStorage(frame, name, value)
Tercioo@9 62 lib.windowData[frame].storage[getStorageName(frame, name)] = value
Tercioo@9 63 end
Tercioo@9 64
Tercioo@9 65 local function getStorage(frame, name)
Tercioo@9 66 return lib.windowData[frame].storage[getStorageName(frame, name)]
Tercioo@9 67 end
Tercioo@9 68
Tercioo@9 69
Tercioo@9 70 lib.utilFrame:SetScript("OnUpdate", function(this)
Tercioo@9 71 this:Hide()
Tercioo@9 72 for frame,_ in pairs(lib.delayedSavePosition) do
Tercioo@9 73 lib.delayedSavePosition[frame] = nil
Tercioo@9 74 lib.SavePosition(frame)
Tercioo@9 75 end
Tercioo@9 76 end)
Tercioo@9 77
Tercioo@9 78 local function queueSavePosition(frame)
Tercioo@9 79 lib.delayedSavePosition[frame] = true
Tercioo@9 80 lib.utilFrame:Show()
Tercioo@9 81 end
Tercioo@9 82
Tercioo@9 83
Tercioo@9 84 ---------------------------------------------------------
Tercioo@9 85 -- IMPORTANT APIS
Tercioo@9 86 ---------------------------------------------------------
Tercioo@9 87
Tercioo@9 88 mixins["RegisterConfig"]=true
Tercioo@9 89 function lib.RegisterConfig(frame, storage, names)
Tercioo@9 90 if not lib.windowData[frame] then
Tercioo@9 91 lib.windowData[frame] = {}
Tercioo@9 92 end
Tercioo@9 93 lib.windowData[frame].names = names
Tercioo@9 94 lib.windowData[frame].storage = storage
Tercioo@9 95
Tercioo@9 96 --[[ debug
Tercioo@9 97 frame.tx = frame:CreateTexture()
Tercioo@9 98 frame.tx:SetTexture(0,0,0, 0.4)
Tercioo@9 99 frame.tx:SetAllPoints(frame)
Tercioo@9 100 frame.tx:Show()
Tercioo@9 101 ]]
Tercioo@9 102 end
Tercioo@9 103
Tercioo@9 104
Tercioo@9 105
Tercioo@9 106
Tercioo@9 107 ---------------------------------------------------------
Tercioo@9 108 -- POSITIONING AND SCALING
Tercioo@9 109 ---------------------------------------------------------
Tercioo@9 110
Tercioo@9 111 local nilParent = {
Tercioo@9 112 GetWidth = function()
Tercioo@9 113 return GetScreenWidth() * UIParent:GetScale()
Tercioo@9 114 end,
Tercioo@9 115 GetHeight = function()
Tercioo@9 116 return GetScreenHeight() * UIParent:GetScale()
Tercioo@9 117 end,
Tercioo@9 118 GetScale = function()
Tercioo@9 119 return 1
Tercioo@9 120 end,
Tercioo@9 121 }
Tercioo@9 122
Tercioo@9 123 mixins["SavePosition"]=true
Tercioo@9 124 function lib.SavePosition(frame)
Tercioo@9 125 local parent = frame:GetParent() or nilParent
Tercioo@9 126 -- No, this won't work very well with frames that aren't parented to nil or UIParent
Tercioo@9 127 local s = frame:GetScale()
Tercioo@9 128 local left,top = frame:GetLeft()*s, frame:GetTop()*s
Tercioo@9 129 local right,bottom = frame:GetRight()*s, frame:GetBottom()*s
Tercioo@9 130 local pwidth, pheight = parent:GetWidth(), parent:GetHeight()
Tercioo@9 131
Tercioo@9 132 local x,y,point;
Tercioo@9 133 if left < (pwidth-right) and left < abs((left+right)/2 - pwidth/2) then
Tercioo@9 134 x = left;
Tercioo@9 135 point="LEFT";
Tercioo@9 136 elseif (pwidth-right) < abs((left+right)/2 - pwidth/2) then
Tercioo@9 137 x = right-pwidth;
Tercioo@9 138 point="RIGHT";
Tercioo@9 139 else
Tercioo@9 140 x = (left+right)/2 - pwidth/2;
Tercioo@9 141 point="";
Tercioo@9 142 end
Tercioo@9 143
Tercioo@9 144 if bottom < (pheight-top) and bottom < abs((bottom+top)/2 - pheight/2) then
Tercioo@9 145 y = bottom;
Tercioo@9 146 point="BOTTOM"..point;
Tercioo@9 147 elseif (pheight-top) < abs((bottom+top)/2 - pheight/2) then
Tercioo@9 148 y = top-pheight;
Tercioo@9 149 point="TOP"..point;
Tercioo@9 150 else
Tercioo@9 151 y = (bottom+top)/2 - pheight/2;
Tercioo@9 152 -- point=""..point;
Tercioo@9 153 end
Tercioo@9 154
Tercioo@9 155 if point=="" then
Tercioo@9 156 point = "CENTER"
Tercioo@9 157 end
Tercioo@9 158
Tercioo@9 159 setStorage(frame, "x", x)
Tercioo@9 160 setStorage(frame, "y", y)
Tercioo@9 161 setStorage(frame, "point", point)
Tercioo@9 162 setStorage(frame, "scale", s)
Tercioo@9 163
Tercioo@9 164 frame:ClearAllPoints()
Tercioo@9 165 frame:SetPoint(point, frame:GetParent(), point, x/s, y/s);
Tercioo@9 166 end
Tercioo@9 167
Tercioo@9 168
Tercioo@9 169 mixins["RestorePosition"]=true
Tercioo@9 170 function lib.RestorePosition(frame)
Tercioo@9 171 local x = getStorage(frame, "x")
Tercioo@9 172 local y = getStorage(frame, "y")
Tercioo@9 173 local point = getStorage(frame, "point")
Tercioo@9 174
Tercioo@9 175 local s = getStorage(frame, "scale")
Tercioo@9 176 if s then
Tercioo@9 177 (frame.lw11origSetScale or frame.SetScale)(frame,s)
Tercioo@9 178 else
Tercioo@9 179 s = frame:GetScale()
Tercioo@9 180 end
Tercioo@9 181
Tercioo@9 182 if not x or not y then -- nothing stored in config yet, smack it in the center
Tercioo@9 183 x=0; y=0; point="CENTER"
Tercioo@9 184 end
Tercioo@9 185
Tercioo@9 186 x = x/s
Tercioo@9 187 y = y/s
Tercioo@9 188
Tercioo@9 189 frame:ClearAllPoints()
Tercioo@9 190 if not point and y==0 then -- errr why did i do this check again? must have been a reason, but i can't remember it =/
Tercioo@9 191 point="CENTER"
Tercioo@9 192 end
Tercioo@9 193
Tercioo@9 194 if not point then -- we have position, but no point, which probably means we're going from data stored by the addon itself before LibWindow was added to it. It was PROBABLY topleft->bottomleft anchored. Most do it that way.
Tercioo@9 195 frame:SetPoint("TOPLEFT", frame:GetParent(), "BOTTOMLEFT", x, y)
Tercioo@9 196 -- make it compute a better attachpoint (on next update)
Tercioo@9 197 queueSavePosition(frame)
Tercioo@9 198 return
Tercioo@9 199 end
Tercioo@9 200
Tercioo@9 201 frame:SetPoint(point, frame:GetParent(), point, x, y)
Tercioo@9 202 end
Tercioo@9 203
Tercioo@9 204
Tercioo@9 205 mixins["SetScale"]=true
Tercioo@9 206 function lib.SetScale(frame, scale)
Tercioo@9 207 setStorage(frame, "scale", scale);
Tercioo@9 208 (frame.lw11origSetScale or frame.SetScale)(frame,scale)
Tercioo@9 209 lib.RestorePosition(frame)
Tercioo@9 210 end
Tercioo@9 211
Tercioo@9 212
Tercioo@9 213
Tercioo@9 214 ---------------------------------------------------------
Tercioo@9 215 -- DRAG SUPPORT
Tercioo@9 216 ---------------------------------------------------------
Tercioo@9 217
Tercioo@9 218
Tercioo@9 219 function lib.OnDragStart(frame)
Tercioo@9 220 lib.windowData[frame].isDragging = true
Tercioo@9 221 frame:StartMoving()
Tercioo@9 222 end
Tercioo@9 223
Tercioo@9 224
Tercioo@9 225 function lib.OnDragStop(frame)
Tercioo@9 226 frame:StopMovingOrSizing()
Tercioo@9 227 lib.SavePosition(frame)
Tercioo@9 228 lib.windowData[frame].isDragging = false
Tercioo@9 229 if lib.windowData[frame].altEnable and not IsAltKeyDown() then
Tercioo@9 230 frame:EnableMouse(false)
Tercioo@9 231 end
Tercioo@9 232 end
Tercioo@9 233
Tercioo@9 234 local function onDragStart(...) return lib.OnDragStart(...) end -- upgradable
Tercioo@9 235 local function onDragStop(...) return lib.OnDragStop(...) end -- upgradable
Tercioo@9 236
Tercioo@9 237 mixins["MakeDraggable"]=true
Tercioo@9 238 function lib.MakeDraggable(frame)
Tercioo@9 239 assert(lib.windowData[frame])
Tercioo@9 240 frame:SetMovable(true)
Tercioo@9 241 frame:SetScript("OnDragStart", onDragStart)
Tercioo@9 242 frame:SetScript("OnDragStop", onDragStop)
Tercioo@9 243 frame:RegisterForDrag("LeftButton")
Tercioo@9 244 end
Tercioo@9 245
Tercioo@9 246
Tercioo@9 247 ---------------------------------------------------------
Tercioo@9 248 -- MOUSEWHEEL
Tercioo@9 249 ---------------------------------------------------------
Tercioo@9 250
Tercioo@9 251 function lib.OnMouseWheel(frame, dir)
Tercioo@9 252 local scale = getStorage(frame, "scale")
Tercioo@9 253 if dir<0 then
Tercioo@9 254 scale=max(scale*0.9, 0.1)
Tercioo@9 255 else
Tercioo@9 256 scale=min(scale/0.9, 3)
Tercioo@9 257 end
Tercioo@9 258 lib.SetScale(frame, scale)
Tercioo@9 259 end
Tercioo@9 260
Tercioo@9 261 local function onMouseWheel(...) return lib.OnMouseWheel(...) end -- upgradable
Tercioo@9 262
Tercioo@9 263 mixins["EnableMouseWheelScaling"]=true
Tercioo@9 264 function lib.EnableMouseWheelScaling(frame)
Tercioo@9 265 frame:SetScript("OnMouseWheel", onMouseWheel)
Tercioo@9 266 end
Tercioo@9 267
Tercioo@9 268
Tercioo@9 269 ---------------------------------------------------------
Tercioo@9 270 -- ENABLEMOUSE-ON-ALT
Tercioo@9 271 ---------------------------------------------------------
Tercioo@9 272
Tercioo@9 273 lib.utilFrame:SetScript("OnEvent", function(this, event, key, state)
Tercioo@9 274 if event=="MODIFIER_STATE_CHANGED" then
Tercioo@9 275 if key == "LALT" or key == "RALT" then
Tercioo@9 276 for frame,_ in pairs(lib.altEnabledFrames) do
Tercioo@9 277 if not lib.windowData[frame].isDragging then -- if it's already dragging, it'll disable mouse on DragStop instead
Tercioo@9 278 frame:EnableMouse(state == 1)
Tercioo@9 279 end
Tercioo@9 280 end
Tercioo@9 281 end
Tercioo@9 282 end
Tercioo@9 283 end)
Tercioo@9 284
Tercioo@9 285 mixins["EnableMouseOnAlt"]=true
Tercioo@9 286 function lib.EnableMouseOnAlt(frame)
Tercioo@9 287 assert(lib.windowData[frame])
Tercioo@9 288 lib.windowData[frame].altEnable = true
Tercioo@9 289 frame:EnableMouse(not not IsAltKeyDown())
Tercioo@9 290 if not lib.altEnabledFrames then
Tercioo@9 291 lib.altEnabledFrames = {}
Tercioo@9 292 lib.utilFrame:RegisterEvent("MODIFIER_STATE_CHANGED")
Tercioo@9 293 end
Tercioo@9 294 lib.altEnabledFrames[frame] = true
Tercioo@9 295 end
Tercioo@9 296
Tercioo@9 297
Tercioo@9 298
Tercioo@9 299 ---------------------------------------------------------
Tercioo@9 300 -- Embed support (into FRAMES, not addons!)
Tercioo@9 301 ---------------------------------------------------------
Tercioo@9 302
Tercioo@9 303 function lib:Embed(target)
Tercioo@9 304 if not target or not target[0] or not target.GetObjectType then
Tercioo@9 305 error("Usage: LibWindow:Embed(frame)", 1)
Tercioo@9 306 end
Tercioo@9 307 target.lw11origSetScale = target.SetScale
Tercioo@9 308 for name, _ in pairs(mixins) do
Tercioo@9 309 target[name] = self[name]
Tercioo@9 310 end
Tercioo@9 311 lib.embeds[target] = true
Tercioo@9 312 return target
Tercioo@9 313 end
Tercioo@9 314
Tercioo@9 315 for target, _ in pairs(lib.embeds) do
Tercioo@9 316 lib:Embed(target)
Tercioo@9 317 end