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