# 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"` | Добавить атрибут |
