wowpedia
Main Menu


The Interface window includes a tab for third-party AddOns to share a common look and feel. This tutorial expands on instructions in the source code at FrameXML/InterfaceOptionsFrame.lua:483.

Minimum requirements

It is minimally necessary to create a frame (panel), assign the .name field, and pass it to InterfaceOptions_AddCategory():

local panel = CreateFrame("Frame")
panel.name = "MyAddOn"               -- see panel fields
InterfaceOptions_AddCategory(panel)  -- see InterfaceOptions API

-- add widgets to the panel as desired
local title = panel:CreateFontString("ARTWORK", nil, "GameFontNormalLarge")
title:SetPoint("TOP")
title:SetText("MyAddOn")

Panel fields

Fields used when registering a new panel:
name
string - Name in the list of panels (customarily the AddOn name, unless it is a sub-panel).
parent
string? - The name of another panel to appear as a its sub-panel. If omitted, or if the other panel is not found, then this panel remains top-level.
Fields used during user interaction:
refresh
function? - Callback when the panel first appears and also after default().
okay
function? - Callback when the user presses the Okay button to save settings.
cancel
function? - Callback when the user presses the Cancel button to discard changes.
default
function? - Callback when the user presses the Default button to restore default settings; followed by refresh().

InterfaceOptions API

InterfaceOptions_AddCategory(panel [, addOn, position])
Adds a configuration panel.
panel
Frame - A panel with widgets (children) to control an AddOn.
addOn
boolean? - Identifies an AddOn is from a third party; however, the argment has no effect because the function body checks issecure().
position
number? - Position in the list of panels; omitting defaults to alphabetical order.
InterfaceAddOnsList_Update()
Prepares the InterfaceOptionsFrameAddOns buttons list, ensuring future calls to InterfaceOptionsFrame_OpenToCategory() will succeed.[1]
InterfaceOptionsFrame_OpenToCategory(panel) (DEPRECATED, use Settings.OpenToCategory(panel) instead)
Opens the Interface window to the chosen panel; however, this may fail the first time it is called unless preceeded by InterfaceAddOnsList_Update().
panel
Frame|string - The registered panel, or its name.
InterfaceOptionsFrame_Show()
Toggles visibility of the Interface Options frame.

Details

function panel.okay()
	xpcall(function()
		-- your original panel.okay() code goes here
	end, geterrorhandler())
end

Examples

Fitting many options inside the border texture using a ScrollFrame:

local panel = CreateFrame("Frame")
panel.name = "MyAddOn"
InterfaceOptions_AddCategory(panel)

-- Create the scrolling parent frame and size it to fit inside the texture
local scrollFrame = CreateFrame("ScrollFrame", nil, panel, "UIPanelScrollFrameTemplate")
scrollFrame:SetPoint("TOPLEFT", 3, -4)
scrollFrame:SetPoint("BOTTOMRIGHT", -27, 4)

-- Create the scrolling child frame, set its width to fit, and give it an arbitrary minimum height (such as 1)
local scrollChild = CreateFrame("Frame")
scrollFrame:SetScrollChild(scrollChild)
scrollChild:SetWidth(InterfaceOptionsFramePanelContainer:GetWidth()-18)
scrollChild:SetHeight(1) 

-- Add widgets to the scrolling child frame as desired
local title = scrollChild:CreateFontString("ARTWORK", nil, "GameFontNormalLarge")
title:SetPoint("TOP")
title:SetText("MyAddOn")

local footer = scrollChild:CreateFontString("ARTWORK", nil, "GameFontNormal")
footer:SetPoint("TOP", 0, -5000)
footer:SetText("This is 5000 below the top, so the scrollChild automatically expanded.")


HelloWorld example from Create a WoW AddOn in 15 Minutes:

local f = CreateFrame("Frame")

local defaults = {
	someOption = true,
}

function f:OnEvent(event, addOnName)
	if addOnName == "HelloWorld" then
		HelloWorldDB = HelloWorldDB or CopyTable(defaults)
		self.db = HelloWorldDB
		self:InitializeOptions()
		hooksecurefunc("JumpOrAscendStart", function()
			if self.db.someOption then
				print("Your character jumped.")
			end
		end)
	end
end

f:RegisterEvent("ADDON_LOADED")
f:SetScript("OnEvent", f.OnEvent)

function f:InitializeOptions()
	self.panel = CreateFrame("Frame")
	self.panel.name = "HelloWorld"

	local cb = CreateFrame("CheckButton", nil, self.panel, "InterfaceOptionsCheckButtonTemplate")
	cb:SetPoint("TOPLEFT", 20, -20)
	cb.Text:SetText("Print when you jump")
	-- there already is an existing OnClick script that plays a sound, hook it
	cb:HookScript("OnClick", function(_, btn, down)
		self.db.someOption = cb:GetChecked()
	end)
	cb:SetChecked(self.db.someOption)

	local btn = CreateFrame("Button", nil, self.panel, "UIPanelButtonTemplate")
	btn:SetPoint("TOPLEFT", cb, 0, -40)
	btn:SetText("Click me")
	btn:SetWidth(100)
	btn:SetScript("OnClick", function()
		print("You clicked me!")
	end)

	InterfaceOptions_AddCategory(self.panel)
end

SLASH_HELLOW1 = "/hw"
SLASH_HELLOW2 = "/helloworld"

SlashCmdList.HELLOW = function(msg, editBox)
	InterfaceOptionsFrame_OpenToCategory(f.panel)
end

Patch changes

References

 
  1. ^ Daniel Yates (Meorawr) 2021-04-13. InterfaceOptionsFrame_OpenToCategory requires two calls to open addon settings (#89). WoWUIBugs at GitHub.
  2. ^ 2008-10-14, UIOptionsFrame.lua, version 3.0.2.9056, near line 583, archived at Townlong-Yak
  3. ^ Shadnix 2020-11-13. ScrollFrame in the WoW Interface Options AddOn Panel. Cosmo Canyon.