57a5cdabdf
Imported from /srv/add01/wow-ascension/Interface/AddOns/Bartender4 — the build Ascension's WotLK 3.3.5 client ships. Single vendored drop: Ascension's build process bundles their custom patches with the standard CurseForge packager output (embedded libs), and the individual patches aren't published separately. Net delta vs Nevcairiel 4.4.2, excluding bundled libs and CRLF normalization: 21 files, 2213+/52- — the Ascension-specific adaptations for WotLK 3.3.5 hero classes / custom action systems. License: All rights reserved (per .toc).
318 lines
8.3 KiB
Lua
318 lines
8.3 KiB
Lua
--[[
|
|
Name: LibWindow-1.1
|
|
Revision: $Rev: 5 $
|
|
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: 5 $"):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:SetScale(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:SetScale(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
|
|
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
|