wowpedia
Main Menu


Frames are made draggable by calling Frame:SetMovable and Frame:StartMoving.

Example

OnDragStart

Requires moving the mouse a bit before it starts dragging.

local f = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
f:SetPoint("CENTER")
f:SetSize(200, 200)
f:SetBackdrop(BACKDROP_TUTORIAL_16_16)

f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
f:SetScript("OnDragStart", function(self, button)
	self:StartMoving()
	print("OnDragStart", button)
end)
f:SetScript("OnDragStop", function(self)
	self:StopMovingOrSizing()
	print("OnDragStop")
end)

OnMouseDown

This is more responsive as it immediately starts dragging.

local f = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
f:SetPoint("CENTER")
f:SetSize(200, 200)
f:SetBackdrop(BACKDROP_TUTORIAL_16_16)

f:SetMovable(true)
f:SetScript("OnMouseDown", function(self, button)
	self:StartMoving()
	print("OnMouseDown", button)
end)
f:SetScript("OnMouseUp", function(self, button)
	self:StopMovingOrSizing()
	print("OnMouseUp", button)
end)

Outdated section

Draggable frames can be moved by having the user hold down a mouse button over the frame, then move the mouse to reposition the frame. This HOWTO describes how to make a frame draggable.

Summary: Flag a frame as movable (either through the movable XML attribute or frame:SetMovable(isMovable)). To initiate dragging of a frame, call frame:StartMoving(); to stop, call frame:StopMovingOrSizing(). These functions may be called from OnMouseDown/OnMouseUp or OnDragStart/OnDragStop handlers. Use frame:EnableMouse(true) or frame:RegisterForDrag("LeftButton") to activate these widget handlers.

If you want WoW to save the position of your frame between sessions without writing additional code, you'll need to create the frame, using a non-nil name, and flag it as movable before PLAYER_LOGIN fires.

Using XML

The code below creates a draggable Frame widget and uses the OnDrag widget handlers to initiate dragging. Note the use of movable and enableMouse attributes, as well as the OnLoad script allowing the frame to be dragged around using the left mouse button. The self.isLocked check in the OnDragStart handler illustrates that you can easily implement frame locking by not having your widget handlers call :StartMoving() when the frame is locked.

<Frame name="DragFrame1" enableMouse="true" movable="true">
 <Scripts>
  <OnLoad>
   self:RegisterForDrag("LeftButton")
  </OnLoad>
  <OnDragStart>
   if not self.isLocked then
    self:StartMoving()
   end
  </OnDragStart>
  <OnDragStop>
   self:StopMovingOrSizing()
  </OnDragStop>
 </Scripts>
 <!-- Tags below add a visual element to the frame. -->
 <Layers>
  <Layer level="ARTWORK">
   <Texture setAllPoints="true">
    <Color r="1.0" g="0.5" b="0.0" a="0.5" />
   </Texture>
  </Layer>
 </Layers>
 <Size x="64" y="64" />
 <Anchors><Anchor point="CENTER" relativeTo="UIParent"/></Anchors>
</Frame>

While OnDrag* handlers typically require the mouse button to be held down for a small amount of time prior to enabling the mouse behavior, making them well suited for dragging widgets that normally respond to clicks. However, if the frame you wish to make draggable is not normally a button, you can use OnMouseUp/OnMouseDown to provide a more responsive experience. If OnMouseDown/OnMouseUp were used instead of OnDragStart/OnDragStop in the example above, the OnLoad handler could be omitted.

Using TitleRegion

Frames can have a TitleRegion object that handles dragging automatically -- as long as the mouse is held down within the TitleRegion, it'll allow the frame to be dragged.

The frame created below will be draggable by clicking on its top 20 pixels:

<Frame enableMouse="true">
 <Size x="100" y="100"/>
 <TitleRegion>
  <Size x="100" y="20"/>
  <Anchors><Anchor point="TOP"/></Anchors>
 </TitleRegion>
 <!-- Tags below add a visual element to the frame. -->
 <Layers>
  <Layer level="ARTWORK">
   <Texture setAllPoints="true">
    <Color r="1.0" g="0.5" b="0.0" a="0.5" />
   </Texture>
  </Layer>
 </Layers>
 <Anchors><Anchor point="CENTER" relativeTo="UIParent"/></Anchors>
</Frame>

Using Lua

The OnDragStart/OnDragStop and OnMouseDown/OnMouseUp methods translate trivially to an entirely-in-Lua implementation, shown below.

local frame = CreateFrame("Frame", "DragFrame2", UIParent)
frame:SetMovable(true)
frame:EnableMouse(true)
frame:RegisterForDrag("LeftButton")
frame:SetScript("OnDragStart", function(self)
    self:StartMoving()
  end)
frame:SetScript("OnDragStop", function(self)
    self:StopMovingOrSizing()
  end)

-- The code below makes the frame visible, and is not necessary to enable dragging.
frame:SetPoint("CENTER")
frame:SetSize(64, 64)
local tex = frame:CreateTexture("ARTWORK")
tex:SetAllPoints()
tex:SetColorTexture(1.0, 0.5, 0, 0.5)

Note that the StartMoving and StopMovingOrSizing widget methods can be reused as widget handlers in this case, avoiding the creation of additional functions.

Notes