I reviewed my code.
Now we have a dedicated dragframe that sits on top of the anchored frame.
The dragframe receives the drag event and delegates the mouse move event to the anchored frame.
Additionally lock/unlock and reset function can be anchored directly on the frame.
lua Code:
--apply drag functionality to any frame
local applyDragFunctionality = function(self)
--save the default position
local getPoint = function(self)
local pos = {}
pos.a1, pos.af, pos.a2, pos.x, pos.y = self:GetPoint()
if pos.af and pos.af:GetName() then pos.af = pos.af:GetName() end
return pos
end
self.defaultPosition = getPoint(self)
--the drag frame
local df = CreateFrame("Frame",nil,self)
df:SetAllPoints(self)
df:SetFrameStrata("HIGH")
df:SetHitRectInsets(0,0,0,0)
df:SetScript("OnDragStart", function(self) if IsAltKeyDown() and IsShiftKeyDown() then self:GetParent():StartMoving() end end)
df:SetScript("OnDragStop", function(self) self:GetParent():StopMovingOrSizing() end)
--dragframe texture
local t = df:CreateTexture(nil,"OVERLAY",nil,6)
t:SetAllPoints(df)
t:SetTexture(0,1,0)
t:SetAlpha(0.2)
--stuff
df.texture = t
df:Hide()
self.dragframe = df
self:SetClampedToScreen(true)
self:SetMovable(true)
self:SetUserPlaced(true)
--helper functions
--unlock
local unlock = function(self)
if not self:IsUserPlaced() then return end
self.dragframe:Show()
self.dragframe:EnableMouse(true)
self.dragframe:RegisterForDrag("LeftButton")
self.dragframe:SetScript("OnEnter", function(self)
GameTooltip:SetOwner(self, "ANCHOR_TOP")
GameTooltip:AddLine(self:GetParent():GetName(), 0, 1, 0.5, 1, 1, 1)
GameTooltip:AddLine("Hold down ALT+SHIFT to drag!", 1, 1, 1, 1, 1, 1)
GameTooltip:Show()
end)
self.dragframe:SetScript("OnLeave", function() GameTooltip:Hide() end)
end
--lock
local lock = function(self)
if not self:IsUserPlaced() then return end
self.dragframe:Hide()
self.dragframe:EnableMouse(false)
self.dragframe:RegisterForDrag(nil)
self.dragframe:SetScript("OnEnter", nil)
self.dragframe:SetScript("OnLeave", nil)
end
--reset position
local reset = function(self)
if self.defaultPosition then
self:ClearAllPoints()
local pos = self.defaultPosition
if pos.af and pos.a2 then
self:SetPoint(pos.a1 or "CENTER", pos.af, pos.a2, pos.x or 0, pos.y or 0)
elseif pos.af then
self:SetPoint(pos.a1 or "CENTER", pos.af, pos.x or 0, pos.y or 0)
else
self:SetPoint(pos.a1 or "CENTER", pos.x or 0, pos.y or 0)
end
else
self:SetPoint("CENTER",0,0)
end
end
self.unlock = unlock
self.lock = lock
self.reset = reset
end
If you want to call the function you can make use of the global frame name and slash commands.
lua Code:
--CALL
local function SlashCmd(cmd)
if (cmd:match"unlock") then
myFrame.unlock(myFrame)
elseif (cmd:match"lock") then
myFrame.lock(myFrame)
elseif (cmd:match"reset") then
myFrame.reset(myFrame)
end
end
SlashCmdList["mymod"] = SlashCmd;
SLASH_mymod1 = "/mymod";
The most important part is that the drag function gets called on code init. It must not be called on events like PLAYER_LOGIN. That will reset the values that Blizzard read from the layout-local.txt file.
Example implementations:
http://code.google.com/p/rothui/source/detail?r=841