Mercurial > wow > pvpscan
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Libs/LibWindow-1.1/LibWindow-1.1.lua Fri Feb 12 14:11:13 2016 -0200 @@ -0,0 +1,317 @@ +--[[ +Name: LibWindow-1.1 +Revision: $Rev: 8 $ +Author(s): Mikk (dpsgnome@mail.com) +Website: http://old.wowace.com/wiki/LibWindow-1.1 +Documentation: http://old.wowace.com/wiki/LibWindow-1.1 +SVN: http://svn.wowace.com/root/trunk/WindowLib/Window-1.0 +Description: A library that handles the basics of "window" style frames: scaling, smart position saving, dragging.. +Dependencies: none +License: Public Domain +]] + +local MAJOR = "LibWindow-1.1" +local MINOR = tonumber(("$Revision: 8 $"):match("(%d+)")) + +local lib = LibStub:NewLibrary(MAJOR,MINOR) +if not lib then return end + +local min,max,abs = min,max,abs +local pairs = pairs +local tostring = tostring +local UIParent,GetScreenWidth,GetScreenHeight,IsAltKeyDown = UIParent,GetScreenWidth,GetScreenHeight,IsAltKeyDown +-- GLOBALS: error, ChatFrame1, assert + +local function print(msg) ChatFrame1:AddMessage(MAJOR..": "..tostring(msg)) end + +lib.utilFrame = lib.utilFrame or CreateFrame("Frame") +lib.delayedSavePosition = lib.delayedSavePosition or {} +lib.windowData = lib.windowData or {} + --[frameref]={ + -- names={optional names data from .RegisterConfig()} + -- storage= -- tableref where config data is read/written + -- altEnable=true/false + --} + + +lib.embeds = lib.embeds or {} + +local mixins = {} -- "FuncName"=true + + + +--------------------------------------------------------- +-- UTILITIES +--------------------------------------------------------- + + +local function getStorageName(frame, name) + local names = lib.windowData[frame].names + if names then + if names[name] then + return names[name] + end + if names.prefix then + return names.prefix .. name; + end + end + return name; +end + +local function setStorage(frame, name, value) + lib.windowData[frame].storage[getStorageName(frame, name)] = value +end + +local function getStorage(frame, name) + return lib.windowData[frame].storage[getStorageName(frame, name)] +end + + +lib.utilFrame:SetScript("OnUpdate", function(this) + this:Hide() + for frame,_ in pairs(lib.delayedSavePosition) do + lib.delayedSavePosition[frame] = nil + lib.SavePosition(frame) + end +end) + +local function queueSavePosition(frame) + lib.delayedSavePosition[frame] = true + lib.utilFrame:Show() +end + + +--------------------------------------------------------- +-- IMPORTANT APIS +--------------------------------------------------------- + +mixins["RegisterConfig"]=true +function lib.RegisterConfig(frame, storage, names) + if not lib.windowData[frame] then + lib.windowData[frame] = {} + end + lib.windowData[frame].names = names + lib.windowData[frame].storage = storage + + --[[ debug + frame.tx = frame:CreateTexture() + frame.tx:SetTexture(0,0,0, 0.4) + frame.tx:SetAllPoints(frame) + frame.tx:Show() + ]] +end + + + + +--------------------------------------------------------- +-- POSITIONING AND SCALING +--------------------------------------------------------- + +local nilParent = { + GetWidth = function() + return GetScreenWidth() * UIParent:GetScale() + end, + GetHeight = function() + return GetScreenHeight() * UIParent:GetScale() + end, + GetScale = function() + return 1 + end, +} + +mixins["SavePosition"]=true +function lib.SavePosition(frame) + local parent = frame:GetParent() or nilParent + -- No, this won't work very well with frames that aren't parented to nil or UIParent + local s = frame:GetScale() + local left,top = frame:GetLeft()*s, frame:GetTop()*s + local right,bottom = frame:GetRight()*s, frame:GetBottom()*s + local pwidth, pheight = parent:GetWidth(), parent:GetHeight() + + local x,y,point; + if left < (pwidth-right) and left < abs((left+right)/2 - pwidth/2) then + x = left; + point="LEFT"; + elseif (pwidth-right) < abs((left+right)/2 - pwidth/2) then + x = right-pwidth; + point="RIGHT"; + else + x = (left+right)/2 - pwidth/2; + point=""; + end + + if bottom < (pheight-top) and bottom < abs((bottom+top)/2 - pheight/2) then + y = bottom; + point="BOTTOM"..point; + elseif (pheight-top) < abs((bottom+top)/2 - pheight/2) then + y = top-pheight; + point="TOP"..point; + else + y = (bottom+top)/2 - pheight/2; + -- point=""..point; + end + + if point=="" then + point = "CENTER" + end + + setStorage(frame, "x", x) + setStorage(frame, "y", y) + setStorage(frame, "point", point) + setStorage(frame, "scale", s) + + frame:ClearAllPoints() + frame:SetPoint(point, frame:GetParent(), point, x/s, y/s); +end + + +mixins["RestorePosition"]=true +function lib.RestorePosition(frame) + local x = getStorage(frame, "x") + local y = getStorage(frame, "y") + local point = getStorage(frame, "point") + + local s = getStorage(frame, "scale") + if s then + (frame.lw11origSetScale or frame.SetScale)(frame,s) + else + s = frame:GetScale() + end + + if not x or not y then -- nothing stored in config yet, smack it in the center + x=0; y=0; point="CENTER" + end + + x = x/s + y = y/s + + frame:ClearAllPoints() + 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 =/ + point="CENTER" + end + + 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. + frame:SetPoint("TOPLEFT", frame:GetParent(), "BOTTOMLEFT", x, y) + -- make it compute a better attachpoint (on next update) + queueSavePosition(frame) + return + end + + frame:SetPoint(point, frame:GetParent(), point, x, y) +end + + +mixins["SetScale"]=true +function lib.SetScale(frame, scale) + setStorage(frame, "scale", scale); + (frame.lw11origSetScale or frame.SetScale)(frame,scale) + lib.RestorePosition(frame) +end + + + +--------------------------------------------------------- +-- DRAG SUPPORT +--------------------------------------------------------- + + +function lib.OnDragStart(frame) + lib.windowData[frame].isDragging = true + frame:StartMoving() +end + + +function lib.OnDragStop(frame) + frame:StopMovingOrSizing() + lib.SavePosition(frame) + lib.windowData[frame].isDragging = false + if lib.windowData[frame].altEnable and not IsAltKeyDown() then + frame:EnableMouse(false) + end +end + +local function onDragStart(...) return lib.OnDragStart(...) end -- upgradable +local function onDragStop(...) return lib.OnDragStop(...) end -- upgradable + +mixins["MakeDraggable"]=true +function lib.MakeDraggable(frame) + assert(lib.windowData[frame]) + frame:SetMovable(true) + frame:SetScript("OnDragStart", onDragStart) + frame:SetScript("OnDragStop", onDragStop) + frame:RegisterForDrag("LeftButton") +end + + +--------------------------------------------------------- +-- MOUSEWHEEL +--------------------------------------------------------- + +function lib.OnMouseWheel(frame, dir) + local scale = getStorage(frame, "scale") + if dir<0 then + scale=max(scale*0.9, 0.1) + else + scale=min(scale/0.9, 3) + end + lib.SetScale(frame, scale) +end + +local function onMouseWheel(...) return lib.OnMouseWheel(...) end -- upgradable + +mixins["EnableMouseWheelScaling"]=true +function lib.EnableMouseWheelScaling(frame) + frame:SetScript("OnMouseWheel", onMouseWheel) +end + + +--------------------------------------------------------- +-- ENABLEMOUSE-ON-ALT +--------------------------------------------------------- + +lib.utilFrame:SetScript("OnEvent", function(this, event, key, state) + if event=="MODIFIER_STATE_CHANGED" then + if key == "LALT" or key == "RALT" then + for frame,_ in pairs(lib.altEnabledFrames) do + if not lib.windowData[frame].isDragging then -- if it's already dragging, it'll disable mouse on DragStop instead + frame:EnableMouse(state == 1) + end + end + end + end +end) + +mixins["EnableMouseOnAlt"]=true +function lib.EnableMouseOnAlt(frame) + assert(lib.windowData[frame]) + lib.windowData[frame].altEnable = true + frame:EnableMouse(not not IsAltKeyDown()) + if not lib.altEnabledFrames then + lib.altEnabledFrames = {} + lib.utilFrame:RegisterEvent("MODIFIER_STATE_CHANGED") + end + lib.altEnabledFrames[frame] = true +end + + + +--------------------------------------------------------- +-- Embed support (into FRAMES, not addons!) +--------------------------------------------------------- + +function lib:Embed(target) + if not target or not target[0] or not target.GetObjectType then + error("Usage: LibWindow:Embed(frame)", 1) + end + target.lw11origSetScale = target.SetScale + for name, _ in pairs(mixins) do + target[name] = self[name] + end + lib.embeds[target] = true + return target +end + +for target, _ in pairs(lib.embeds) do + lib:Embed(target) +end
