- Joined
- Jul 18, 2010
- Messages
- 2,377
Introduction
Frame - Parent is a powerful and useful concept of warcraft 3's UI-Frame System.
Every frame we can create has a parent frame. Any frame can have any amount of child frames. In the same time any child frame also can have any amount of child frames.
natives provided to get and set the current parent of a frame during the game.
A parent is also set when creating a new frame, as all create frame natives require an owner/parent.
In many examples custom Frames are created as child of GAME_UI which is done to simple down the example. But it is ineffective to create all custom Frames for GAME_UI, if one has Frames that are logical connected it would make more sense to collecte them as childs of one Frame.
FrameA child of Game_UI
FrameB child of FrameA
Every frame we can create has a parent frame. Any frame can have any amount of child frames. In the same time any child frame also can have any amount of child frames.
natives provided to get and set the current parent of a frame during the game.
native BlzFrameSetParent takes framehandle frame, framehandle parent returns nothing
native BlzFrameGetParent takes framehandle frame returns framehandle
A parent is also set when creating a new frame, as all create frame natives require an owner/parent.
In many examples custom Frames are created as child of GAME_UI which is done to simple down the example. But it is ineffective to create all custom Frames for GAME_UI, if one has Frames that are logical connected it would make more sense to collecte them as childs of one Frame.
FrameA child of Game_UI
FrameB child of FrameA
FrameC child of FrameA
FrameD child of FrameA
FrameA is the parent an logical container of FrameB, FrameC and FrameD.
For Frames "FRAME" could be used.
For SimpleFrames "SIMPLEFRAME".
Both can be created with BlzCreateFrameByType
FrameD child of FrameA
FrameA is the parent an logical container of FrameB, FrameC and FrameD.
For Frames "FRAME" could be used.
For SimpleFrames "SIMPLEFRAME".
Both can be created with BlzCreateFrameByType
Why I should bother this concept?
The FrameParent concept simples down a lot of stuff you might want to accomplish. Want to create a new option in menu, create your Frame for ("EscMenuMainPanel", 0). Now the frame requires the visibility of ("EscMenuMainPanel", 0) and you can focus on the behaviour of the frame itself instead of handling the visiblity which can be quite complicated when injecting into the normal warcraft 3 UI. In my opinion the most powerful effect of frame-parentship.
Want to add a new UnitInfo (if you find a place for it on the screen) create it for ("SimpleInfoPanelUnitDetail", 0) then it only will be visible when the local player has only one unit selected. Through this is a bit nah, cause you need to know the selected unit to update the displayed data (in such unit cases).
If you wouldn't use this parent concept for visibility you would have to find out with triggers/code that the local player has only one unit selected, or is inside the menu for the example and also not in cinematic mode.
Want to add a new UnitInfo (if you find a place for it on the screen) create it for ("SimpleInfoPanelUnitDetail", 0) then it only will be visible when the local player has only one unit selected. Through this is a bit nah, cause you need to know the selected unit to update the displayed data (in such unit cases).
If you wouldn't use this parent concept for visibility you would have to find out with triggers/code that the local player has only one unit selected, or is inside the menu for the example and also not in cinematic mode.
What are the Effects of Parent-Child
A child frame can only be visible when it's parent frame is visible. BlzFrameIsVisible also checks for the visibility of the parent frame. New created frames copy scale and alpha from their parent on default. This values can differ for the children when they are set (for the child frame) after the child frame was added to /created for the parent frame.
BlzFrameSetScale
BlzFrameSetAlpha
A child tends to be visible above and is prefered by mouse events over its parent. SimpleFrames can break this rule with BlzFrameSetLevel.
BlzFrameSetScale
BlzFrameSetAlpha
When changing Parents the alpha value of the new Parent is copied.
BlzFrameSetLevelFrames created for a parent frame also have the same Level.
A child tends to be visible above and is prefered by mouse events over its parent. SimpleFrames can break this rule with BlzFrameSetLevel.
2 Types of children
I split childFrames in 2 Types loose children and functional children.
Functional child frames can only be defined and created inside fdf such children have a strong connection to their parent and perform some functionality for the parentFrame hence the name. Although earlier I had no good name for them, I called them strong binded/linked/connected child. An example of such functional child frame is
This childFrame styles the text for it's parent frame "ScriptDialogButton". Functional childFrames copy even more from the ParentFrame, their position is automatically handled and they copy the enable state.
Loose childFrames do not perform any functionality for their parent. This children can be created in fdf or with code. This code creates a new loose child frame for parentFrame.
That behaviour can be used to create Frames with a higher FrameLevel then their type supports: Create A BUTTON set its FrameLevel and create the wanted Frames using him as parent for example TEXT-Frames.
Want to show/hide a whole bunch of Frames collect them under one ParentFrame and change the ParentFrame's visibility. Now it only takes one line to toggle the visibility.
Functional child frames can only be defined and created inside fdf such children have a strong connection to their parent and perform some functionality for the parentFrame hence the name. Although earlier I had no good name for them, I called them strong binded/linked/connected child. An example of such functional child frame is
ButtonText "ScriptDialogButtonText",
This childFrame styles the text for it's parent frame "ScriptDialogButton". Functional childFrames copy even more from the ParentFrame, their position is automatically handled and they copy the enable state.
Loose childFrames do not perform any functionality for their parent. This children can be created in fdf or with code. This code creates a new loose child frame for parentFrame.
BlzCreateFrame("frameName", parentFrame, 0, 0)
The position of a loose childFrame is on default independent from it's parent, it does not even require the parent frame to be placed on the screen at all.That behaviour can be used to create Frames with a higher FrameLevel then their type supports: Create A BUTTON set its FrameLevel and create the wanted Frames using him as parent for example TEXT-Frames.
Want to show/hide a whole bunch of Frames collect them under one ParentFrame and change the ParentFrame's visibility. Now it only takes one line to toggle the visibility.
Parent Limitations?
SimpleFrames can not be children nor parent of Frames. Frames can not be Children/Parent of SimpleFrames. Some might now say: "but I created a BUTTON for SIMPLEFRAME in fdf or, I created SIMPLEFRAME for a BUTTON during the game."
Yes, you did but on a more accurate inspection, by comparing HandleIds of the parent of the new frame and the wanted/should be parent one might see they do not match, in both cases you see the handleId of another frame, I call that a substitute parent.
When that happens one might at first wonder why visibility and other parent behaviours do not apply. But the reason: the wanted parent is not the real parent and so it does not copy the visibility/alpha... .
In 1.31 BlzFrameSetParent can bug sometimes (it speeds up the animation of "SPRITE" and can empower the glowing of "HIGHLIGHT" when changing the parent for this frames directly).
Yes, you did but on a more accurate inspection, by comparing HandleIds of the parent of the new frame and the wanted/should be parent one might see they do not match, in both cases you see the handleId of another frame, I call that a substitute parent.
When that happens one might at first wonder why visibility and other parent behaviours do not apply. But the reason: the wanted parent is not the real parent and so it does not copy the visibility/alpha... .
In 1.31 BlzFrameSetParent can bug sometimes (it speeds up the animation of "SPRITE" and can empower the glowing of "HIGHLIGHT" when changing the parent for this frames directly).
Example
This is a Lua code creating a clickable Button that is only visible while the player is inside the Menu (F10), the code executes itself when insert into a map in Lua mode.
When the button is clicked the message "action in Menu" is printed onto the screen.
Although this is a bit vague cause currently it also is visible while choosing to end game and not visible while being inside options. If you plan on doing something like that you have to find out more about that frames in detail and which is the one suited for your wanted goal. This menu frames are in "ui/framedef/ui" when looking with cascview.

This was written in mind for warcraft 3 V1.31.1.
Edited: Replaced selfexecution with a less problematic approach
When the button is clicked the message "action in Menu" is printed onto the screen.
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

This was written in mind for warcraft 3 V1.31.1.
Edited: Replaced selfexecution with a less problematic approach
Other UI-Frame Tutorials
The following links might provide more insight into this subject.
UI: Change Lumber Text
[JASS/AI] - UI: Create a TextButton
[JASS/AI] - UI: Positionate Frames (important)
UI: toc-Files
UI: Reading a FDF
UI - The concept of Parent-Frames
[JASS/AI] - UI: FrameEvents and FrameTypes
UI: Frames and Tooltips
[JASS/AI] - UI: Creating a Bar
UI - Simpleframes
UI: What are BACKDROPs?
UI: GLUEBUTTON
UI: TEXTAREA the scrolling Text Frame
UI: EditBox - Text Input
[JASS/AI] - UI: Creating a Cam control
UI: Showing 3 Multiboards
UI: OriginFrames
Default Names for BlzGetFrameByName (Access to Existing game-Frames)
[JASS/AI] - UI: List - Default MainFrames (built in CreateAble)
UI: Change Lumber Text
[JASS/AI] - UI: Create a TextButton
[JASS/AI] - UI: Positionate Frames (important)
UI: toc-Files
UI: Reading a FDF
UI - The concept of Parent-Frames
[JASS/AI] - UI: FrameEvents and FrameTypes
UI: Frames and Tooltips
[JASS/AI] - UI: Creating a Bar
UI - Simpleframes
UI: What are BACKDROPs?
UI: GLUEBUTTON
UI: TEXTAREA the scrolling Text Frame
UI: EditBox - Text Input
[JASS/AI] - UI: Creating a Cam control
UI: Showing 3 Multiboards
UI: OriginFrames
Default Names for BlzGetFrameByName (Access to Existing game-Frames)
[JASS/AI] - UI: List - Default MainFrames (built in CreateAble)
Last edited by a moderator: