Skip to content
R41z0r edited this page Mar 8, 2026 · 16 revisions

Edit Mode API reference

Native module loading

  • Default behavior is unchanged: LibEQOL.xml loads LibEQOLEditMode-1.0.
  • To use the optional native flow, additionally include LibEQOLNativeEditMode.xml and fetch LibStub("LibEQOLNativeEditMode-1.0").

Native control API

  • EnterEditMode() – shows the native manager and enters edit mode.
  • ExitEditMode() – hides the native manager and exits edit mode.
  • ToggleEditMode() – toggles native edit mode.
  • SetSnapEnabled(enabled) / GetSnapEnabled() – toggle/query native snap behavior.
  • SetGridEnabled(enabled) / GetGridEnabled() – toggle/query native grid visibility.
  • SetGridSize(size) / GetGridSize() – set/query native grid density.

Core

  • AddFrame(frame, callback, defaultPosition) – registers a frame for Edit Mode. callback(frame, layoutName, point, x, y) runs on move/reset; anchors stay relative to the frame’s current parent (or its existing relative frame when nudging). defaultPosition defaults to { point = "CENTER", x = 0, y = 0 } relative to the parent. Opt-in overlay/label toggle via defaultPosition.enableOverlayToggle = true (alias overlayToggleEnabled = true). Control drag via defaultPosition.allowDrag/dragEnabled (boolean or function(layoutName, layoutIndex)). Control built-ins via defaultPosition.showReset = false (hide Reset Position) and defaultPosition.showSettingsReset = false (hide Settings Reset). Settings layout overrides: defaultPosition.settingsSpacing, defaultPosition.settingsMaxHeight (alias defaultPosition.maxSettingsHeight), defaultPosition.sliderHeight, defaultPosition.dropdownHeight, defaultPosition.multiDropdownHeight, defaultPosition.multiDropdownSummaryHeight, defaultPosition.checkboxHeight, defaultPosition.colorHeight, defaultPosition.checkboxColorHeight, defaultPosition.dropdownColorHeight, defaultPosition.inputHeight, defaultPosition.dividerHeight, defaultPosition.collapsibleHeight.
  • GetFrameDefaultPosition(frame) – returns the default position for a registered frame.
  • SetFrameResetVisible(frame, showReset) – hide or re-show the automatic "Reset Position" button.
  • SetFrameSettingsResetVisible(frame, showReset) – hide or re-show the Settings-side "Reset to Default" button for that frame.
  • SetFrameSettingsMaxHeight(frame, height) – set a max height (in pixels) for the settings list only (the button bar is excluded); nil clears the override.
  • SetFrameOverlayToggleEnabled(frame, enabled) – allow or hide the eye-button that toggles the selection label/overlay; default is disabled until you opt-in.
  • SetFrameDragEnabled(frame, enabledOrPredicate) – allow/deny drag + keyboard nudging; accepts boolean or function(layoutName, layoutIndex); nil clears the override.
  • SetFrameCollapseExclusive(frame, enabled) – when enabled, expanding one collapsible header on that frame will collapse the others. defaultPosition.collapseExclusive / exclusiveCollapse does the same at registration time.
  • Reset behavior: the Reset button sets each setting to its default (and colorDefault for color-enabled rows) if provided; settings without a default are skipped.

Settings dialog

  • AddFrameSettings(frame, settingsTable) – adds setting rows. See widget pages for schemas.
  • AddFrameSettingsButton(frame, data) – adds a custom button under the settings list. data needs text and click handler.
  • ShowStandaloneSettingsDialog(frame, options?) – opt-in entry point that opens the shared settings dialog outside Edit Mode and returns dialog, or nil, err on failure. Existing Edit Mode behavior is unchanged unless this is called. By default it reuses rows/buttons/default position registered for that frame. options may override title, settings, buttons, defaultPosition, showReset, showSettingsReset, settingsSpacing, settingsMaxHeight/maxSettingsHeight, dialog anchor (point, relativePoint, relativeTo, x, y, plus anchor*/offset* aliases), and onHide(dialog, frame). This fails while Edit Mode is active, and also fails if no settings, buttons, or reset position resolve for the target frame.
  • HideStandaloneSettingsDialog(frame?) – hides the active standalone dialog and returns true when it closed. If frame is provided, it only closes when that frame owns the active standalone dialog.
  • IsStandaloneSettingsDialogShown(frame?) – returns whether the shared dialog is currently shown in standalone mode; optional frame filters by owner.
  • internal:RefreshSettings() – re-evaluates isEnabled/disabled predicates on visible rows.
  • internal:RefreshSettingValues(targetSettings?) – re-runs Setup on visible rows so their displayed values match changes you applied in another setting’s set(...). Optionally pass a table of setting row tables to refresh only those rows; by default all visible rows refresh.
  • Settings rows support tooltip = "..." to show a GameTooltip on hover.

Standalone dialog notes

  • The standalone dialog reuses the same pooled widget system and row schema as AddFrameSettings.
  • Only one shared dialog exists for both Edit Mode and standalone usage.
  • Omitting options.settings / options.buttons reuses data previously registered for that frame.
  • The built-in "Reset Position" button can also work for unregistered frames when options.defaultPosition is provided; it resets the frame anchor directly, but only registered frames fire the normal move callback.

Edit Mode manager toggle panel

Adds a simple checkbox list under EditModeManagerFrame to show/hide addon frames (or anything you want).

  • AddManagerToggle(data) / AddManagerCheckbox(data) – registers a checkbox row in the manager panel.
  • AddManagerCategory(data) – registers a category header with optional sorting.
  • RemoveManagerToggle(id) – removes a row and forgets its saved state.
  • RefreshManagerToggles() – rebuilds the list + current values (use after mutating toggle specs).
  • SetManagerTogglePanelMaxHeight(height) – clamp panel height before the scrollbar appears.

Toggle schema

Minimal fields:

  • id (string, required) – unique id. If omitted, label is used.
  • label (string, required) – visible text.
  • frames or frame – a frame, global name (string), or a list of them. A function is also accepted and should return any of the above.
  • category – string (e.g. "Enhance QoL" or a category id) or a table { id, label, sort }. If the string matches an existing category id, its label/sort are reused; otherwise a new category with that label is created. If omitted, the row goes into the default "Other" category.

Optional fields:

  • get(layoutName, layoutIndex) – returns true/false for current value (e.g. from saved variables).
  • set(layoutName, value, layoutIndex) – applies the new value. Return false to reject the toggle.
  • isEnabled(layoutName, layoutIndex) / disabled(layoutName, layoutIndex) – enable/disable the checkbox.
  • default – initial value if no saved state exists.
  • applyDefault – set to false to prevent the default from being applied immediately.
  • allowInCombat – set to true to allow toggling while in combat (default is disabled in combat).

Notes

  • If you omit id, the label becomes the internal id (use that same string with RemoveManagerToggle).
  • Categories disappear automatically once they have no visible toggles.

Category schema

  • label (string, required) – visible header text.
  • id (string, optional) – internal key; defaults to label.
  • sort (optional) – "label" or a comparator function(a, b). The comparator receives entries { id, label, data, order }.

Example

EditMode:AddManagerCheckbox({
  id = "MyAddon_All",
  label = "My Addon (alles)",
  category = { id = "EnhanceQoL", label = "Enhance QoL", sort = "label" },
  frames = { MyFrame, MyOtherFrame },
})

More examples

Basic toggle (label becomes id):

EditMode:AddManagerCheckbox({
  label = "Player Frame",
  frames = PlayerFrame,
})

Multiple frames at once:

EditMode:AddManagerCheckbox({
  id = "EQOL_All",
  label = "Enhance QoL (all)",
  frames = { MyFrame, MyOtherFrame, MyThirdFrame },
})

Category by string (auto-creates category with same label):

EditMode:AddManagerCheckbox({
  label = "Focus Frame",
  category = "Enhance QoL",
  frames = FocusFrame,
})

Category by id (label/sort defined earlier):

EditMode:AddManagerCategory({
  id = "EQOL",
  label = "Enhance QoL",
  sort = "label",
})

EditMode:AddManagerCheckbox({
  label = "Pet Frame",
  category = "EQOL", -- uses existing label/sort
  frames = PetFrame,
})

Category + label sort:

EditMode:AddManagerCategory({
  label = "Enhance QoL",
  sort = "label",
})

EditMode:AddManagerCheckbox({
  id = "EQOL_Target",
  label = "Target Frame",
  category = "Enhance QoL",
  frames = TargetFrame,
})

Custom sort comparator:

EditMode:AddManagerCategory({
  id = "EQOL",
  label = "Enhance QoL",
  sort = function(a, b)
    return (a.order or 0) < (b.order or 0) -- keep original registration order
  end,
})

Stored state (SavedVariables):

EditMode:AddManagerCheckbox({
  id = "EQOL_Player",
  label = "Player Frame",
  category = "Enhance QoL",
  get = function()
    return not MyDB.hidePlayerFrame
  end,
  set = function(_, value)
    MyDB.hidePlayerFrame = not value
    PlayerFrame:SetShown(value)
  end,
})

Allow toggling in combat:

EditMode:AddManagerCheckbox({
  label = "Small Helper Frame",
  frames = MyHelperFrame,
  allowInCombat = true,
})

Default state without applying immediately:

EditMode:AddManagerCheckbox({
  label = "Debug Overlay",
  frames = MyDebugFrame,
  default = false,
  applyDefault = false,
})

Remove a toggle (use id or label if id omitted):

EditMode:RemoveManagerToggle("Player Frame")
EditMode:RemoveManagerToggle("EQOL_Player")

After changing data on existing toggles:

EditMode:RefreshManagerToggles()

Callbacks

  • RegisterCallback(event, callback)event is "enter", "exit", "layout", "layoutadded", "layoutdeleted", "layoutrenamed", "layoutduplicate", "spec", or "selectionchanged" (also accepts "SelectionChanged").
    • layout callback receives (layoutName, layoutIndex).
    • layoutadded receives (addedLayoutIndex, activateNewLayout, isLayoutImported, layoutType, layoutName); activateNewLayout=true means the new layout was activated immediately; isLayoutImported=true distinguishes imports from copy/new; layoutType is Enum.EditModeLayoutType.
    • layoutdeleted receives (deletedLayoutIndex, deletedLayoutName); the name is pulled from the cached snapshot before refreshing layouts from the API.
    • layoutrenamed receives (oldName, newName, layoutIndex) where layoutIndex is the UI index (custom layouts are offset by +2); this only fires for actual rename operations, not for index shifts caused by deleting a layout.
    • layoutduplicate receives (addedLayoutIndex, duplicateIndices, isLayoutImported, layoutType, layoutName) when the added layout matches existing ones (uses C_EditMode.ConvertLayoutInfoToString; indices are UI indices, i.e. offset by +2 relative to GetLayouts().layouts; the name is the new layout’s name once, not per duplicate).
    • spec receives (specIndex) from GetSpecialization() (or nil if unavailable).
    • selectionchanged receives (frame) for the currently selected registered frame, or nil when selection is cleared.
  • GetActiveLayoutName() – returns the active Edit Mode layout.
  • GetActiveLayoutIndex() – returns the active layout index.
  • IsInEditMode() – returns true when Edit Mode is open.
  • GetSelectedFrame() – returns the currently selected registered frame, or nil when nothing is selected.
  • GetLayouts() – returns an array of { index, name, layoutType, isActive } for UI indices (1/2 use LAYOUT_STYLE_MODERN / LAYOUT_STYLE_CLASSIC and Enum.EditModeLayoutType.Modern / Enum.EditModeLayoutType.Classic when available). isActive is 1 for the active layout, else 0.

SettingType values

Available via EditMode.SettingType:

  • Checkbox
  • Dropdown
  • MultiDropdown
  • Slider
  • Input
  • Color
  • CheckboxColor
  • DropdownColor
  • Divider
  • Collapsible

Clone this wiki locally