# WoW 3.3.5a — Виджеты, события и Blizzard API ## Создание фреймов через Lua ### CreateFrame ```lua -- 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` | Видео | --- ## Текстуры ```lua 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 (текст) ```lua 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 ```lua 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 ```lua 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 ```lua 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 ```lua 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) ``` --- ## Скрипты-события ```lua 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 — таймер ```lua 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 ```lua -- В 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) ```lua _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"` | Добавить атрибут |