- Joined
- Jul 18, 2010
- Messages
- 2,377
Introduction
Warcraft 3 V1.31 provided 3 natives to create Frames.
JASS:
native BlzCreateFrame takes string name, framehandle owner, integer priority, integer createContext returns framehandle
native BlzCreateSimpleFrame takes string name, framehandle owner, integer createContext returns framehandle
native BlzCreateFrameByType takes string typeName, string name, framehandle owner, string inherits, integer createContext returns framehandle
BlzCreateFrame
BlzCreateFrame creates all non SimpleFrames defined in a fdf. Most of this frames allow attaching Frameevents and they can do alot of things. Most times you should use this one.
Lets checkout the arguments
Lets checkout the arguments
string name | this is the name of the frame you want to create, you have to take it from a fdf. Its the 2.word in "" after Frame |
framehandle owner | the owner becoming the new frames parent |
integer priority | No Idea, should not be negative |
createContext | which index in the frame storage the new Frame and its child will take. The frame storage is accessed with BlzGetFrameByName. Can be any integer. |
BlzCreateSimpleFrame
BlzCreateSimpleFrame is used to create simpleFrames defined in a fdf. SimpleFrames have "SIMPLE" in their type name. Most Simpleframes can not have frameevents registered onto them. Creating them is not much different from creating normal Frames.
Arguments are like in BlzCreateFrame but it misses priority
Arguments are like in BlzCreateFrame but it misses priority
BlzCreateFrameByType
BlzCreateFrameByType creates a Frame with a new wanted name. One has to define which Type and from which frame you take data over. The inheriting works for frames beeing createable with BlzCreate(simple)Frame. BlzCreateFrameByType is the best when you want to create an empty frame of type x or want to have frame y (from a fdf) with a different name.
Example:
Example:
Creates a button that behaves like "ScriptDialogButton" but will be named "MyButton".
Looks kinda like a frameHead, if one would write INHERITS instead of the parentFrame.
It can be difficult to access the childrens of such created frames.
JASS:
call BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
It can be difficult to access the childrens of such created frames.
One can only create MainFrames. I call frames MainFrames, if they have a FrameHead outside of any other FrameBody.
(Simple)Frames have to be loaded by tocs (fdf) to be createable.
(Simple)Frames have to be loaded by tocs (fdf) to be createable.
Creating a Text-Button
In this example we create a clickable button which looks like the buttons ingame when one presses menu. We use for the button this framedefinition. The frame we want to create is loaded in on default.
Its name is "ScriptDialogButton", it takes over data from "EscMenuButtonTemplate".
Lets start the creation.
We create a frame based on the name "ScriptDialogButton", say ORIGIN_FRAME_GAME_UI is its parent and it uses createcontext 0.
Also we set the size and the position of that new created frame, beeing a button.
Here it is. No Text, has Textures hoverable and clickable.
Lets give that button a text. We access the child-Frame managing the ButtonText "ScriptDialogButtonText".
Better with the text on the button. But we want that some code runs when the button is clicked.
As one might see in this piece of code one does not access the Textchild still it works, the reason for that is a line in the frame definition 'ButtonText "ScriptDialogButtonText",'. It tells the button uses this Text Frame to manages its text, so that we can read/write the text directly over the mainButton. Simelar lines exist in other cases too, they make the usage between child and parent stronger and more dependent.
This is "EscMenuButtonTemplate", "ScriptDialogButton" INHERITS from it, taking over much data.
Its name is "ScriptDialogButton", it takes over data from "EscMenuButtonTemplate".
Code:
Frame "GLUETEXTBUTTON" "ScriptDialogButton" INHERITS WITHCHILDREN "EscMenuButtonTemplate" {
UseActiveContext,
ButtonText "ScriptDialogButtonText",
Frame "TEXT" "ScriptDialogButtonText" INHERITS "EscMenuButtonTextTemplate" {
Text "",
}
}
Lets start the creation.
We create a frame based on the name "ScriptDialogButton", say ORIGIN_FRAME_GAME_UI is its parent and it uses createcontext 0.
Also we set the size and the position of that new created frame, beeing a button.
JASS:
function CreateButton1 takes nothing returns nothing
local framehandle mainButton = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0,0)
call BlzFrameSetSize(mainButton, 0.12, 0.05)
call BlzFrameSetAbsPoint(mainButton, FRAMEPOINT_CENTER, 0.3,0.3)
endfunction
Here it is. No Text, has Textures hoverable and clickable.
Lets give that button a text. We access the child-Frame managing the ButtonText "ScriptDialogButtonText".
JASS:
function CreateButton2 takes nothing returns nothing
local framehandle mainButton = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), 0,0)
local framehandle buttonText = BlzGetFrameByName("ScriptDialogButtonText",0) //Get The buttons textChild
call BlzFrameSetSize(mainButton, 0.12, 0.05)
call BlzFrameSetAbsPoint(mainButton, FRAMEPOINT_CENTER, 0.3,0.3)
call BlzFrameSetText(buttonText, "My ButtonText")
endfunction
Better with the text on the button. But we want that some code runs when the button is clicked.
JASS:
function ButtonCallBack takes nothing returns nothing
call BJDebugMsg(GetPlayerName(GetTriggerPlayer()) + " pressed: "+ BlzFrameGetText(BlzGetTriggerFrame()))
endfunction
function CreateButton3 takes nothing returns nothing
local trigger trig = CreateTrigger() //The Trigger Handling the Frameevent
local framehandle mainButton = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), 0,0)
call BlzFrameSetSize(mainButton, 0.12, 0.05)
call BlzFrameSetAbsPoint(mainButton, FRAMEPOINT_CENTER, 0.3,0.3)
call BlzFrameSetText(mainButton, "My ButtonText") //Cause of a line in scriptDialogButton 'ButtonText "ScriptDialogButtonText",' one can directly read/write text of the button.
call BlzTriggerRegisterFrameEvent(trig, mainButton, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(trig, function ButtonCallBack) //Function ButtonCallBack will run when mainButton is clicked
endfunction
As one might see in this piece of code one does not access the Textchild still it works, the reason for that is a line in the frame definition 'ButtonText "ScriptDialogButtonText",'. It tells the button uses this Text Frame to manages its text, so that we can read/write the text directly over the mainButton. Simelar lines exist in other cases too, they make the usage between child and parent stronger and more dependent.
This is "EscMenuButtonTemplate", "ScriptDialogButton" INHERITS from it, taking over much data.
Code:
Frame "GLUETEXTBUTTON" "EscMenuButtonTemplate" {
Width 0.228,
Height 0.035,
ControlStyle "AUTOTRACK|HIGHLIGHTONMOUSEOVER",
ButtonPushedTextOffset 0.002f -0.002f,
ControlBackdrop "ButtonBackdropTemplate",
Frame "BACKDROP" "ButtonBackdropTemplate" INHERITS "EscMenuButtonBackdropTemplate" {
}
ControlPushedBackdrop "ButtonPushedBackdropTemplate",
Frame "BACKDROP" "ButtonPushedBackdropTemplate" INHERITS "EscMenuButtonPushedBackdropTemplate" {
}
ControlDisabledBackdrop "ButtonDisabledBackdropTemplate",
Frame "BACKDROP" "ButtonDisabledBackdropTemplate" INHERITS "EscMenuButtonDisabledBackdropTemplate" {
}
ControlDisabledPushedBackdrop "ButtonDisabledPushedBackdropTemplate",
Frame "BACKDROP" "ButtonDisabledPushedBackdropTemplate" INHERITS "EscMenuButtonDisabledPushedBackdropTemplate" {
}
ControlMouseOverHighlight "ButtonMouseOverHighlightTemplate",
Frame "HIGHLIGHT" "ButtonMouseOverHighlightTemplate" INHERITS "EscMenuButtonMouseOverHighlightTemplate" {
}
}
Keyboard Focus
TextButtons have the habit to take control of the keyboard focus as soon they are pressed. When such a button got the keyboard focus hotkeys won't work anymore and pressing return/space will do another control-click. The user can give the focus back to the game by left clicking on the playable world.
As mapper you also have the power to shift the focus. CanFight found a nice, easy way to solve the keyboard focus problem: inside the buttons pressed callback one disables and enables the button, then it counts as clicked and the button loses focus.
Edit: Attached the map with the demo code.
Edit: Added Keyboard Focus.
As mapper you also have the power to shift the focus. CanFight found a nice, easy way to solve the keyboard focus problem: inside the buttons pressed callback one disables and enables the button, then it counts as clicked and the button loses focus.
JASS:
call BlzFrameSetEnable(BlzGetTriggerFrame(), false) //disable the clicked button
call BlzFrameSetEnable(BlzGetTriggerFrame(), true) //enable it again.
Edit: Attached the map with the demo code.
Edit: Added Keyboard Focus.
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)
Attachments
Last edited by a moderator: