Making draggable frames

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 ). To initiate dragging of a frame, call ; to stop, call. These functions may be called from OnMouseDown/OnMouseUp or OnDragStart/OnDragStop handlers. Use  or   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 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  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.    self:RegisterForDrag("LeftButton")   if not self.isLocked then self:StartMoving end   self:StopMovingOrSizing          <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>  <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", frame.StartMoving) frame:SetScript("OnDragStop", frame.StopMovingOrSizing) -- 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.