Lore archive · Warcraft Wiki, 2023 dump
Making draggable frames
Last wiki revision 2022-11-23
Frames are made draggable by calling and.
Requires moving the mouse a bit before it starts dragging.
This is more responsive as it immediately starts dragging.
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.
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. <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> <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.
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> <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>
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.
- If you do not wish to allow the user to (accidentally) drag your frame off-screen, you can add the to its XML declaration, or use
- If the frame you intend to move is not the frame you are setting the script on (e.g. ), it is best to use OnMouseDown/Up because OnDragStop will not fire when the mouse button is released which will leave the frame stuck on the cursor. This may be due to the fact that when you start moving a different frame (i.e. the frame's parent frame), the dragging of the source frame stops because either the mouse's focus is shifted to the other frame or the client can only keep track of one moving frame at a time. Either way, this happens before the client even knows it was dragging a frame.
- You cannot use OnMouseDown to move a frame and OnDragStart/Stop at the same time on the same frame. This is because when you click the frame :StartMoving is immediately called and you can't drag a frame that's already moving.
Source
https://warcraft.wiki.gg/wiki/Making_draggable_frames · retrieved 2023-11-13 · CC BY-SA 4.0
Converted from wikitext with templates, tables and images removed, so some sentences may be missing values.
This archive predates WoW: Forever. For collected gameplay facts see the Forever database. Search the archive.