Кратко: данная подстатья рассказывает о важности связи родитель-ребенок между фреймами. Вы можете ваш созданный самодельный фрейм привязать к определенной группе фреймов. Помните, вся группа привязана к предку.
Еще одна важная инфа, некоторые потомки копируют параметры родителя. Обычно при создании они копируют данные родителя. Если в качестве родителя использовать станд для всех фреймов gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), то используются ограничения, к примеру фреймы не могут существовать за пределами 4:3 в широкоформатных мониторах. Игра просто не рассчитывала на такое. Большинство фреймов очень похожи на gameUI, отличаются они тем, что gameUI - общий фрейм всех фреймов, отключаешь его, и все остальные отключаются. Это фрейм всего интерфейса. Остальные станд фреймы варика отличаются уровнями, кто-то находится выше, а кто-то ниже. Когда создается фрейм, он берет уровень родителя и располагается выше родителя на 1 уровень. Но они все похожи по характеристикам на gameUI. Есть одно НО!!! Не все стандартные фреймы могут быть родителями, т.к. у вас потом не создаются/не показываются фреймы, возможно, указанные вами родители скрытны или не существуют в данный момент. Поэтому они у вас не могут создаться, или могут быть скрытыми (напомню: когда фрейм создается, мы указываем родителя. У них есть связь. Когда родитель скрыт, то скрыты все его потомки. Когда родитель выключен, то выключены все его потомки. Потомок четко копирует данные родителя). А также возможны какие то системные фреймы, то есть их нельзя использовать в качестве родителей. Поэтому надо подбирать родителя - смотреть. ORIGIN_FRAME_WORLD_FRAME - отвечает за игровую область. Это самый-самый нижний фрейм, за ним вроде объекты на карте лежат, короче сама карта (юниты, декор, итем и пр). Ну конечно можно обойти ограничение экрана 4:3, это использовать в качестве родителя BlzGetFrameByName("ConsoleUIBackdrop", 0) - у него сбрасываются все ограничения на fullscreen. Однако, этот родитель находится на самой низшем уровне после ORIGIN_FRAME_WORLD_FRAME. По характеристикам можно использовать в качестве родителей фреймы мультиборда или leaderboard, которые находятся выше всех. Но их нужно создать.
Frame - Parent - это мощная и полезная концепция UI-Frame System в warcraft 3. Каждый фрейм, который мы можем создать, может иметь Parent-Frame. Любой фрейм может иметь любое количество дочерних фреймов. В то же время любой дочерний фрейм также может иметь любое количество дочерних фреймов.
У функциональных фреймов древовидная структура:
natives позволяют получить родителя-фрейма (parent) фрейма (frame), так и задать родителя-фрейма (parent) для фрейма (frame) во время игры.
native BlzFrameSetParent takes framehandle frame, framehandle parent returns nothing
native BlzFrameGetParent takes framehandle frame returns framehandle
Родитель также устанавливается при создании нового фрейма, так как для всех исходных фреймов требуется владелец / родитель. Посмотрите на нативки в lua внизу, при создании нужно задать родителя owner framehandle
---@param name string
---@param owner framehandle
---@param priority integer
---@param createContext integer
---@return framehandle
function BlzCreateFrame(name, owner, priority, createContext) end    -- (native)

---@param name string
---@param owner framehandle
---@param createContext integer
---@return framehandle
function BlzCreateSimpleFrame(name, owner, createContext) end    -- (native)

---@param typeName string
---@param name string
---@param owner framehandle
---@param inherits string
---@param createContext integer
---@return framehandle
function BlzCreateFrameByType(typeName, name, owner, inherits, createContext) end    -- (native)
Во многих примерах пользовательские фреймы создаются как дочерние по отношению к GAME_UI, что упрощает пример. Но неэффективно создавать все пользовательские фреймы для GAME_UI, допустим у кого-то есть фреймы, которые логически связаны, было бы разумнее собирать их как дочерние элементы одного фрейма.

FrameA является потомком Game_UI
FrameB является потомком FrameA
FrameC является потомком FrameA
FrameD является потомком FrameA
FrameA - это родительский логический контейнер для FrameB, FrameC и FrameD.
Для фреймов можно использовать "FRAME". Для простых фреймов «SIMPLEFRAME». Оба могут быть созданы с помощью BlzCreateFrameByType.
В fdf файлах можно заметить связи родителей-детей. Там код разделен на блоки. Когда начинается один блок кода - это код родителя, а внутри могут быть записаны другие настройки. А также внутри могут лежать другие фреймы. Пример:
Frame "FRAME" "Frame A" { //заголовок главного фрейма

    Frame "TEXT" "Frame B" INHERITS "EscMenuButtonTextTemplate" { //дочерний фрейм типа TEXT используя шаблон EscMenuButtonTextTemplate
     ....
   }
}

Почему я должен заморачиваться с этой концепцией?

Концепция FrameParent упрощает многие вещи, которые вы, возможно, захотите выполнить.
Хотите создать новую опцию в меню, создайте свой фрейм для ("EscMenuMainPanel", 0). Теперь для фрейма требуется видимость ("EscMenuMainPanel", 0), и вы можете сосредоточиться на поведении самого фрейма вместо того, чтобы обрабатывать видимость, что может быть довольно сложно при внедрении в обычный пользовательский интерфейс Warcraft 3. На мой взгляд, это самый мощный эффект фреймового родительства.
Хотите добавить новый UnitInfo (если вы найдете для него место на экране) создайте его для ("SimpleInfoPanelUnitDetail", 0), тогда он будет виден только тогда, когда у локального игрока выбран только один объект. Это немного осложняется, потому что вам нужно знать каждый выбранный блок, чтобы обновить отображаемые данные (в таких случаях).
Если вы не будете использовать эту родительскую концепцию для видимости, вам придется с помощью триггеров / кода выяснить, что у локального игрока выбран только один юнит или он находится внутри меню для примера, а также не в кинематографическом режиме.

Каковы эффекты от пары родитель-ребенок?

Ребенок может быть видим только тогда, когда виден его родитель. Если родитель скрыт, то и все связанные с ним потомки исчезают.
BlzFrameIsVisible - эта функция проверяет видимость родителя. Новые созданные фреймы по умолчанию копируют масштаб и альфа-канал своих родительских. Эти значения могут различаться у потомков, если их принято считать как фрейм-ребенок после того, как дочерний кадр был добавлен / создан для родителя.
BlzFrameSetScale
BlzFrameSetAlpha
При изменении Родителя альфа-значение нового Родителя копируется.
BlzFrameSetLevel
Фреймы, созданные для родителя, также имеют одинаковый уровень.
Дочерний элемент обычно виден сверху, и события мыши предпочитают его родителю. SimpleFrames может нарушить это правило с помощью BlzFrameSetLevel

2 Types of children (2 типа потомка)

Я разделил childFrames на 2 типа: свободные потомки и функциональные потомки.
Функциональные дочерние фреймы могут быть определены и созданы только внутри fdf, такие дочерние элементы имеют прочную связь со своими родителями и выполняют некоторые функции для parentFrame, отсюда и название. Хотя раньше у меня не было для них хорошего названия, я называл их сильно привязанными / связанными / связанными дочерними элементами. Примером такого функционального дочернего фрейма является
ButtonText "ScriptDialogButtonText".
Этот childFrame стилизует текст для своего родительского фрейма «ScriptDialogButton». Функциональные дочерние фреймы еще больше копируют из ParentFrame, их положение автоматически обрабатывается, и они копируют состояние включения.
Свободные дочерние фреймы не выполняют никаких функций для своих родителей. Эти дочерние элементы могут быть созданы в формате fdf или с помощью кода. Этот код создает новый свободный дочерний фрейм для parentFrame.BlzCreateFrame ("frameName", parentFrame, 0, 0) Положение свободного дочернего кадра по умолчанию не зависит от его родительского кадра, для него даже не требуется, чтобы родительский фрейм был размещен. Это поведение можно использовать для создания фреймов с более высоким FrameLevel, чем поддерживает их тип: Create A BUTTON устанавливает свой FrameLevel и создает требуемые фреймы, используя его в качестве родительского, например TEXT-Frames.
Хотите показать / скрыть целую кучу фреймов, соберите их под одним ParentFrame и измените видимость ParentFrame. Теперь для переключения видимости достаточно одной строчки.

Родительские ограничения?

Таким фреймам как SimpleFrames нельзя задать родителя или ребенка. Аналогично, и другие фреймы не могут быть детьми/родителями для SimpleFrames. Кто-то теперь может сказать: «но я создал КНОПКУ для SIMPLEFRAME в формате fdf или я создал КНОПКУ для КНОПКИ во время игры». Да, вы это сделали, но при более точной проверке, сравнив HandleIds родителей нового фрейма и выбранного, можно увидеть, что они не совпадают, в обоих случаях вы видите handleIds разных фреймов, я называю это замещающий родитель. Когда это происходит, сначала можно задаться вопросом, почему не применяются видимость и другое поведение родителей. Но причина: желаемый родитель не является настоящим родителем, поэтому он не копирует видимость, альфа и т.д.
В 1.31 BlzFrameSetParent может иногда ошибаться (он ускоряет анимацию «SPRITE» и может усилить свечение «HIGHLIGHT» при изменении родительского элемента для этого кадра напрямую).
Example (Пример)
Это код Lua, создающий интерактивную кнопку, которая видна только тогда, когда игрок находится внутри меню (F10), код выполняется сам при вставке на карту в режиме Lua. При нажатии кнопки появляется сообщение «действие в меню». напечатаны на экране.
do
    local real = MarkGameStarted
  function MarkGameStarted()
        real()
    local buttonFrame = BlzCreateFrameByType("BUTTON", "", BlzGetFrameByName("EscMenuMainPanel", 0), "ScoreScreenTabButtonTemplate", 0)
    local iconFrame = BlzCreateFrameByType("BACKDROP", "", buttonFrame, "", 0)
    BlzFrameSetAllPoints(iconFrame, buttonFrame)
    BlzFrameSetSize(buttonFrame, 0.03, 0.03)
    BlzFrameSetAbsPoint(buttonFrame, FRAMEPOINT_TOPLEFT, 0.1, 0.45)
    BlzFrameSetTexture(iconFrame, "ReplaceableTextures\\WorldEditUI\\Doodad-Cinematic.blp", 0, true)
    local trigger = CreateTrigger()
    TriggerAddAction(trigger, function()
        print("action in Menu")
    end)
    BlzTriggerRegisterFrameEvent(trigger, buttonFrame, FRAMEEVENT_CONTROL_CLICK)
  end
end
Этот код lua создает кнопку с иконкой камеры, как на скрине, когда я захожу в Меню. При создании этой кнопки в функции указывают родителя EscMenuMainPanel. EscMenuMainPanel не видима, когда я открываю, нам становится видна панель меню с кнопками. Когда я открывают F10, вместе с этим становятся видимы другие фреймы-потомки. Когда я закрываю панель меню F10, наша кнопка исчезает вместе с ним.
Если разобраться подробнее с фреймами, вы можете встроить эту кнопку внутрь панели.
Если вы планируете сделать что-то подобное, вам нужно подробнее узнать об этих фреймах и о том, какой из них подходит для вашей желаемой цели. Эти фреймы меню находятся в "ui/framedef/ui" при просмотре с помощью cascview.
`
ОЖИДАНИЕ РЕКЛАМЫ...