Making resizable frames

From Warcraft Wiki
Jump to navigation Jump to search

Resizable frames can be resized by holding down a specified mouse button over a frame and then moving the mouse to resize the frame in a specified direction. This tutorial shows example code to make a resizable window.

Tutorial

Register a frame for dragging and resizing:

frame:RegisterForDrag("LeftButton")
frame:EnableMouse(true)
frame:SetResizable(true)

Set the minimum and maximum size limits:

frame:SetMinResize(300,200)
frame:SetMaxResize(800,500)

Monitor OnDragStart and OnDragStop to trigger the resizing:

frame:SetScript("OnDragStart", function(self)
	self:StartSizing()
end)
frame:SetScript("OnDragStop", function(self)
	self:StopMovingOrSizing()
end)

Alternatively, place buttons in each corner that monitor OnMouseDown and OnMouseUp:

local br = CreateFrame("Button", nil, frame)
br:EnableMouse("true")
br:SetPoint("BOTTOMRIGHT")
br:SetSize(16,16)
br:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
br:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
br:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
br:SetScript("OnMouseDown", function(self)
	self:GetParent():StartSizing("BOTTOMRIGHT") 
end)
br:SetScript("OnMouseUp", function()
	self:GetParent():StopMovingOrSizing("BOTTOMRIGHT")
end)

To create a resizable frame in xml, this is a basic example.

<Frame parentKey="parentFrame" resizable="true">
    <Size x="200" y="400"/>
    <ResizeBounds>
        <minResize x="100" y="300"/>
        <maxResize x="300" y="500"/>
    </ResizeBounds>
    <Frames>
        <Button parentKey="resizer">
            <Size x="16" y="16"/>
            <Anchors>
                <Anchor point="BOTTOMRIGHT" x="0" y="0"/>
            </Anchors>
            <NormalTexture file="Interface/ChatFrame/UI-ChatIM-SizeGrabber-Down"/>
            <PushedTexture file="Interface/ChatFrame/UI-ChatIM-SizeGrabber-Up"/>
            <HighlightTexture file="Interface/ChatFrame/UI-ChatIM-SizeGrabber-Highlight"/>
            <Scripts>
                <OnMouseDown>
                    self:GetParent():StartSizing("BOTTOMRIGHT")
                </OnMouseDown>
                <OnMouseUp>
                    self:GetParent():StopMovingOrSizing("BOTTOMRIGHT")
                </OnMouseUp>
            </Scripts>
        </Button>
    </Frames>    
</Frame>

Details

  • Frame:StartSizing() defaults moving the "BOTTOMRIGHT" point, but accepts an argument to move another instead.
  • Texture:SetRotation() may be used to place similar-looking handles in all corners.

Complete example

local myFrame = CreateFrame("Frame", "MyFrame", UIParent, BackdropTemplateMixin and "BackdropTemplate")
frame:SetWidth(500)
frame:SetHeight(300)
frame:SetPoint("CENTER", UIParent, "CENTER")
backdropInfo = {
	bgFile = "Interface\\Buttons\\WHITE8X8",
	edgeFile = "Interface\\Buttons\\WHITE8X8",
	edgeSize = 1,
	insets = { left = 1, right = 1, top = 1, bottom = 1, },
}
frame:SetBackdrop(backdropInfo)
frame:SetBackdropColor(0,0,0,1) -- Black background
frame:SetBackdropBorderColor(1,1,1,1) -- White border
frame:RegisterForDrag("LeftButton")
frame:EnableMouse(true)
frame:SetResizable(true)
frame:SetMinResize(300,200)
frame:SetMaxResize(800,500)
frame:SetScript("OnDragStart", function(self, button)
	self:StartSizing()
	self.isMoving = true
	self.hasMoved = false
end)
frame:SetScript("OnDragStop", function(self)
	self:StopMovingOrSizing()
	self.isMoving = false
	self.hasMoved = true
end)