Let your addon register its own settings panel inside GW2_UI’s Settings UI. This gives you search integration, 2-column layout, dependencies and consistent look & feel.
-
Acquire the main Settings tab frame
local settingsTab = GW2_ADDON.GetSettingsTabFrame()
-
Create your panel using the built-in template
local panel = CreateFrame("Frame", "GwYourAddonPanel", settingsTab, "GwSettingsPanelTmpl") panel.panelId = "Unique Addon ID" -- required panel.header:SetFont(DAMAGE_TEXT_FONT, 20) panel.header:SetTextColor(GW.Colors.TextColors.LightHeader:GetRGB()) panel.header:SetText("YOUR ADDON SETTINGS") panel.sub:SetFont(UNIT_NAME_FONT, 12) panel.sub:SetTextColor(181/255, 160/255, 128/255) panel.sub:SetText("Description of your panel.")
-
Add controls (see API below)
panel:AddGroupHeader("General") panel:AddOption("Enable Feature", "Toggles the main feature", { getter = function() return "opt" end, setter = function(value) print(value) end, getDefault = function() return "opt1" end }) panel:AddOptionDropdown("Mode", "Choose a mode", { getterSetter = "mode", optionsList = {"opt1", "opt2"}, optionNames = {"Option 1", "Option 2"} }) panel:AddOptionSlider("Opacity", nil, { getter = function() return 2 end, setter = function(value) print(value) end, getDefault = function() return 1 end, min = 0, max = 1, step = 0.01, decimalNumbers = 2, dependence = { enableFeature = true }, -- shown/enabled only if enableFeature is true }) panel:AddOptionSortableList("Priority", "Move entries up or down", { getterSetter = "priorityOrder", optionsList = {"interrupts", "dispels", "cooldowns"}, optionNames = {"Interrupts", "Dispels", "Cooldowns"}, maxVisibleRows = 6, callback = function(order) print(table.concat(order, ", ")) end })
-
Register the panel with namespace support, returnes the namespace DB object
-- AddSettingsPanel(basePanel, name, desc, subFramesOrNil, isAddon) local db = settingsTab:AddSettingsPanel(panel, "YOUR ADDON SETTINGS", "Description of your addon.", nil, -- no sub-panels true, -- isAddon )
Each method creates a widget and returns its option object. The final layout is handled by GW2_UI (two columns where possible, full row if forced).
-
panel:AddOption(name, desc, values)Creates a boolean toggle (checkbox). General
valueskeys (apply to all API calls; listed later in detail):getter,setter,getDefault,callback,dependence,forceNewLine,incompatibleAddons,groupHeaderName,optionUpdateFuncNo type-specific keys for
AddOption. -
panel:AddOptionButton(name, desc, values)Creates a button row (non-toggle action). Uses the general keys. The action is typically handled via
values.callback. -
panel:AddGroupHeader(name, values)Creates a section/header row. Uses the general keys (commonly
groupHeaderNamefor search grouping is unnecessary here, as the header itself acts as a group label). -
panel:AddOptionColorPicker(name, desc, values)Creates a color picker. Uses the general keys. No additional type-specific keys.
-
panel:AddOptionSlider(name, desc, values)Creates a slider. Type-specific keys (required/optional):
min(number, required) — Minimum valuemax(number, required) — Maximum valuestep(number, required) — Step sizedecimalNumbers(number, optional, default 0) — Digits to display after decimal The function reads these fromvaluesand applies them to the option.
-
panel:AddOptionText(name, desc, values)Creates a text input. Type-specific keys:
multiline(boolean, optional) — If true, uses a multiline input.
-
panel:AddOptionDropdown(name, desc, values)Creates a dropdown (single-select by default; multi-select when
checkbox = trueis supported by template). Type-specific keys:optionsList(table, required) — Array of choice values (e.g.,{"opt1","opt2"})optionNames(table, required) — Array of display labels (e.g.,"Option 1","Option 2"})checkbox(boolean, optional) — Show a checkbox list (multi-select) if supported by your data bindingtooltipType(any, optional) — Custom tooltip type hook used by your templatehasSound(boolean, optional) — Play a click sound on changenoNewLine(boolean, optional) — When set, try to keep dropdown in a half-width column (overrides template default)
-
panel:AddOptionSortableList(name, desc, values)Creates a sortable list with drag-and-drop rows and up/down buttons for each entry. The stored value is an ordered array. Type-specific keys:
optionsList(table, required) — Array of values that can be orderedoptionNames(table, required) — Display labels matchingoptionsListentryHeight(number, optional, default 24) — Row height for each list entrymaxVisibleRows(number, optional) — Maximum visible rows before the list scrolls internallycallback(function(order, movedValue, oldIndex, newIndex)) — Called after an entry was moved
These keys are available on every API method:
-
getter,setter,getDefault(string, recommended)The storage key for this option within your namespace (e.g., "enableFeature"). GW2_UI binds this to a proxy (via CreateSettingProxy) so get()/set() use your addon's namespace.
-
callback(function(value))Called after the value is set. Use this to apply live changes.
-
dependence(table)Conditional visibility/enabling based on other option keys. Example:
{ enableFeature = true }— only show/enable whenenableFeatureistrue. When you register viaAddSettingsPanel(..., isAddon=true, addonName=...), your dependence keys are auto-resolved inside your namespace (no prefix needed). -
forceNewLine(boolean)Forces the widget to take a full row (instead of sharing a row in the 2-column layout).
-
incompatibleAddons(table of strings)If any listed addon is detected, the option may be hidden/disabled. (Behavior depends on the skin; keep as a safety gate.)
-
groupHeaderName(string)Logical group name. Used by the search UI to group results and draw section headers for hits.
-
optionUpdateFunc(function(widget))Hook for dynamic updates when the panel relayouts or dependencies change (advanced use).
-
Widgets are automatically placed in two columns when possible. Use
forceNewLine = trueto make a control span the full width. For dropdowns,noNewLine = true(type-specific) can force half-width placement when the template would otherwise span full width. -
Group headers created via
AddGroupHeader()visually separate sections and are considered by the search.
All titles (name), group headers (groupHeaderName), and descriptions (desc) are indexed for the global settings search.
Results are shown by panel and in on-screen order.
If your addon has multiple sections, you can pass a list of subframes to AddSettingsPanel (as subFramesOrNil).
Each subframe should be created with the same "GwSettingsPanelTmpl" and populated with the APIs above.
Structure =
{{frame = subMenuOne, name = "Panel 1"}, {frame = subMenuTwo, name = "Panel 2"}, ...}if you use sub frames the base panel need only works as a container:
local container = CreateFrame("Frame", nil, GW2_ADDON.GetSettingsTabFrame(), "GwSettingsPanelTmpl")
local subMenuOne = CreateFrame("Frame", nil, container, "GwSettingsPanelTmpl")
local subMenuTwo = CreateFrame("Frame", nil, container, "GwSettingsPanelTmpl")You can directly open the settings panel with a simple api call. The panel id needs to be set for every panel and must be unique.
function OpenSettingsPanel()
local frame = GW2_ADDON.GetSettingsTabFrame()
frame:OpenSettingsToPanel("MyAddon_General")
endfunction AddSettingsPanel()
local frame = GW2_ADDON.GetSettingsTabFrame()
local basePanel = CreateFrame("Frame", nil, frame, "GwSettingsPanelTmpl")
basePanel.panelId = "MyAddon_General"
basePanel.header:SetFont(DAMAGE_TEXT_FONT, 20)
basePanel.header:SetTextColor(GW2_ADDON.TextColors.LIGHT_HEADER.r, GW2_ADDON.TextColors.LIGHT_HEADER.g, GW2_ADDON.TextColors.LIGHT_HEADER.b)
basePanel.header:SetText("TEST ADDON SETTINGS")
basePanel.sub:SetFont(UNIT_NAME_FONT, 12)
basePanel.sub:SetTextColor(181 / 255, 160 / 255, 128 / 255)
basePanel.sub:SetText("External added settings panel for testing purposes.")
basePanel:AddGroupHeader("Group Header")
basePanel:AddOption("Checkbox", "Setting description", { getter = function() return true end, setter = function(value) print(value) end, getDefault = function() return false end, callback = function(value) print("Checkbox set to value:", value) end })
basePanel:AddOptionDropdown(GW.NewSign .. "Dropdown", "Description", { getter = function() return "opt1" end, setter = function(value) print(value) end, getDefault = function() return "opt1" end, callback = function(value) print("Dropdown set to value:", value) end, optionsList = {"opt1", "opt2"}, optionNames = {"Option 1", "Option 2"}, dependence = {settingCheckbox = true, }, checkbox = false, groupHeaderName = "Group Header"})
basePanel:AddOptionSlider(GW.NewSign .. "Slider", nil, { getter = function() return 1 end, setter = function(value) print(value) end, getDefault = function() return 2 end, callback = function(value) print("Slider set to value:", value) end, min = 0, max = 3, decimalNumbers = 2, step = 0.01, dependence = {XPBAR_ENABLED = true}, groupHeaderName = "Group Header"})
frame:AddSettingsPanel(basePanel, "TEST ADDON SETTINGS", "External added settings panel for testing purposes.", nil, true)
end