Files
moonwell-client/ai-skills/ui/widgets-and-api.md
2026-06-13 11:51:05 +04:00

7.4 KiB
Raw Permalink Blame History

WoW 3.3.5a — Виджеты, события и Blizzard API

Создание фреймов через Lua

CreateFrame

-- CreateFrame(frameType, name, parent, template)
local f = CreateFrame("Frame", "MyAddon_MainFrame", UIParent)
f:SetWidth(300)
f:SetHeight(200)
f:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
f:SetFrameStrata("DIALOG")
f:SetBackdrop({
    bgFile   = "Interface\\DialogFrame\\UI-DialogBox-Background",
    edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
    tile     = true, tileSize = 32, edgeSize = 32,
    insets   = { left = 11, right = 12, top = 12, bottom = 11 }
})
f:SetBackdropColor(0, 0, 0, 0.8)

Типы фреймов (frameType)

Тип Назначение
Frame Базовый контейнер
Button Кнопка
EditBox Поле ввода текста
ScrollFrame Прокручиваемая область
StatusBar Полоска (HP, мана, XP)
Cooldown Кулдаун-свип на иконке
GameTooltip Тултип
MessageFrame Прокручиваемые сообщения
Model 3D-модель
MovieFrame Видео

Текстуры

local tex = frame:CreateTexture(nil, "ARTWORK")
tex:SetTexture("Interface\\AddOns\\MyAddon\\images\\icon")
tex:SetAllPoints(frame)
tex:SetWidth(32)
tex:SetHeight(32)
tex:SetPoint("CENTER", frame, "CENTER")
tex:SetVertexColor(1, 0.5, 0, 1)
tex:SetAlpha(0.8)

-- Вырезка части текстуры
tex:SetTexCoord(0, 0.5, 0, 0.5)

FontString (текст)

local fs = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
fs:SetPoint("CENTER", frame, "CENTER")
fs:SetText("Привет, Азерот!")
fs:SetTextColor(1, 1, 0, 1)
fs:SetFont("Fonts\\FRIZQT__.TTF", 14, "OUTLINE")

Стандартные шаблоны шрифтов

Шаблон Применение
GameFontNormal Обычный текст интерфейса
GameFontNormalLarge Заголовки
GameFontNormalSmall Мелкий текст
GameFontHighlight Подсвеченный
GameFontDisable Неактивный (серый)
NumberFontNormal Числа
ChatFontNormal Чат

Button

local btn = CreateFrame("Button", "MyAddon_Btn", frame, "UIPanelButtonTemplate")
btn:SetWidth(80)
btn:SetHeight(22)
btn:SetPoint("BOTTOM", frame, "BOTTOM", 0, 10)
btn:SetText("Нажми")
btn:SetScript("OnClick", function(self)
    print("Нажато!")
end)

btn:SetNormalTexture("Interface\\Buttons\\UI-Panel-Button-Up")
btn:SetPushedTexture("Interface\\Buttons\\UI-Panel-Button-Down")
btn:SetHighlightTexture("Interface\\Buttons\\UI-Panel-Button-Highlight")

Шаблоны кнопок

Шаблон Вид
UIPanelButtonTemplate Стандартная кнопка интерфейса
UIPanelCloseButton Крестик закрытия окна
UIMenuButtonStretchTemplate Растягиваемая кнопка меню
SecureActionButtonTemplate Для действий в бою (protected)

ScrollFrame

local scroll = CreateFrame("ScrollFrame", "MyAddon_Scroll", frame, "UIPanelScrollFrameTemplate")
scroll:SetPoint("TOPLEFT", frame, "TOPLEFT", 8, -30)
scroll:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -26, 8)

local child = CreateFrame("Frame", "MyAddon_ScrollChild", scroll)
child:SetWidth(scroll:GetWidth())
child:SetHeight(400)
scroll:SetScrollChild(child)

EditBox

local eb = CreateFrame("EditBox", "MyAddon_Input", frame, "InputBoxTemplate")
eb:SetWidth(200)
eb:SetHeight(20)
eb:SetPoint("CENTER", frame, "CENTER")
eb:SetAutoFocus(false)
eb:SetMaxLetters(255)
eb:SetScript("OnEnterPressed", function(self)
    local text = self:GetText()
    self:ClearFocus()
end)

StatusBar

local bar = CreateFrame("StatusBar", nil, frame)
bar:SetWidth(200)
bar:SetHeight(16)
bar:SetPoint("CENTER", frame, "CENTER")
bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
bar:SetStatusBarColor(0, 1, 0, 1)
bar:SetMinMaxValues(0, 100)
bar:SetValue(75)

Скрипты-события

frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("CHAT_MSG_SAY")

frame:SetScript("OnEvent", function(self, event, ...)
    if event == "PLAYER_ENTERING_WORLD" then
        -- вход в мир
    elseif event == "CHAT_MSG_SAY" then
        local msg, author = ...
    end
end)

Ключевые события

Событие Когда
PLAYER_ENTERING_WORLD Вход в мир / reload
ADDON_LOADED Аддон загружен (arg1 == имя)
PLAYER_LOGIN После входа
PLAYER_LOGOUT При выходе
VARIABLES_LOADED SavedVariables загружены
UI_ERROR_MESSAGE Ошибка интерфейса

OnUpdate — таймер

local elapsed_total = 0
frame:SetScript("OnUpdate", function(self, elapsed)
    elapsed_total = elapsed_total + elapsed
    if elapsed_total >= 1.0 then
        elapsed_total = 0
        -- действие каждую секунду
    end
end)

SavedVariables

-- В TOC: ## SavedVariables: MyAddonDB
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(self, event, addonName)
    if event == "ADDON_LOADED" and addonName == "MyAddon" then
        MyAddonDB = MyAddonDB or { position = { "CENTER", 0, 0 } }
        local p = MyAddonDB.position
        self:ClearAllPoints()
        self:SetPoint(p[1], UIParent, p[1], p[2], p[3])
    end
end)

frame:SetScript("OnMouseUp", function(self)
    self:StopMovingOrSizing()
    local point, _, _, x, y = self:GetPoint()
    MyAddonDB.position = { point, x, y }
end)

Полезные Blizzard-утилиты (3.3.5a)

_G["MyAddon_Frame"]:Show()
IsAddOnLoaded("MyAddon")
UnitName("player")
UnitClass("target")
UnitHealth("player"), UnitHealthMax("player")
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000Красный текст|r")
print("Белый текст")
UnitAffectingCombat("player")

Часто используемые пути к текстурам Blizzard

Interface\DialogFrame\UI-DialogBox-Background
Interface\DialogFrame\UI-DialogBox-Border
Interface\DialogFrame\UI-DialogBox-Gold-Background
Interface\Tooltips\UI-Tooltip-Background
Interface\Tooltips\UI-Tooltip-Border
Interface\Buttons\UI-Panel-Button-Up
Interface\Buttons\UI-Panel-Button-Down
Interface\Icons\INV_Misc_QuestionMark
Interface\TargetingFrame\UI-StatusBar
Interface\ChatFrame\UI-ChatIcon-ScrollDown-Up

Типичные ошибки и решения

Ошибка Причина Решение
attempt to index global 'X' (nil) Фрейм не создан Проверь порядок файлов в TOC
SetPoint anchor family connection Циклические якоря Переписать цепочку якорей
Script ran too long Бесконечный цикл OnUpdate Early return или счётчик
Текстура не отображается Размер не кратен 2 / >512px Пересохрани в TGA/BLP
bad argument #1 (string expected) nil вместо строки if val then
Frame не кликается Нет enableMouse="true" Добавить атрибут