• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

UI: TEXTAREA the scrolling Text Frame

Introduction

TEXTAREA is a frame to display scrollable text. Normaly TextAreas have a BACKDROP showing a box and a Background.
TextAreas require a scrollbar. The scrollbar is at the right side of the TextArea and blocks a part of the space given to the TextArea. If the TextArea is big enough to display the whole text, the scrollbar is not shown. Even when the scrollbar is not shown it takes its space. For not scrollable Text one could simply use a TEXT-Frame.​

Built in TextArea

Warcraft 3 has 2 builtIn TEXTAREA mainframes.
BattleNetTextAreaTemplate
EscMenuTextAreaTemplate
BattleNetTextAreaTemplate.jpg EscMenuTextAreaTemplate.jpg
They are a good base to inherit, copy or one can just create them. If one wants to create one of them one would have to load them first using BlzLoadTOCFile.

The fdfs containing them are located at:
UI\Frames\framedef\glue\battlenettemplates.fdf
UI\Frames\framedef\ui\escmenutemplates.fdf​

Creating builtin TextArea

This jass Code creates both TextAreas set the poistions, the size and fills them with text. It is quite important to give a TEXTAREA a size being big enough to display the scrollbar otherwise the game crashs on the attempt to display the TEXTAREA. The Height of the TextArea should be atleast 0.03. That is quite small, but if one forgets to set the size without having a default size, it will be 0 and the game crashs.

JASS:
function CreateDefaultTextAreas takes nothing returns nothing
    local framehandle textArea = BlzCreateFrame("BattleNetTextAreaTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),0,0)
    local framehandle textArea2 = BlzCreateFrame("EscMenuTextAreaTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),0,0)
    local integer index = 1
    call BlzFrameSetAbsPoint(textArea, FRAMEPOINT_TOPLEFT, 0.1, 0.5)
    call BlzFrameSetAbsPoint(textArea2, FRAMEPOINT_TOPLEFT, 0.5, 0.5)
    call BlzFrameSetSize(textArea, 0.25, 0.25)
    call BlzFrameSetSize(textArea2, 0.25, 0.25)
    loop
        exitwhen index == 120
        call BlzFrameAddText(textArea, I2S(index)+": Test Text")
        call BlzFrameAddText(textArea2, I2S(index)+": Test Text")
        set index = index + 1
    endloop
endfunction

//===========================================================================
function InitTrig_Create_TextAreaTemplates takes nothing returns nothing
    call BlzLoadTOCFile( "war3mapImported\\Templates.toc" )
    call TimerStart(CreateTimer(), 0.0, false, function CreateDefaultTextAreas)
endfunction

Seting text of a TextArea

To set the text of a textarea one uses BlzFrameAddText(textArea, newLine) or BlzFrameSetText(textArea, totalText). BlzFrameAddText adds a line Seperator before the new added text, if the TextArea already contained text.
For a TextArea BlzFrameGetText seems to be quite fugitive, after 1 second it returned null, while it was returning the total text in the same function as the text was set. I didn't tested this much.
TextArea can display colored Text using warcraft colorformat |cffff0000.​

Screen-Space and Scrolling

On Default a TextArea will catch the screen-space given to it, making it unclickable for the playable world and sending mousewhell rolls to its scrollbar. One could disable the TextArea to stop the TextArea from taking the mouse Input which would make the screenspace useable by the playable game again, but that would also disable the mouse whell roll sending. One could still scroll when the mouse points directly to the scrollbar.
Disabling is done with:
call BlzFrameSetEnable(textArea, false)

TEXTAREA-FDF

This is a custom TEXTAREA named MyTextArea which has some comments describing the result of fields of TEXTAREA inside fdf:
TEXTAREA rejects most TEXT font Settings one might know when one used TEXT-Frame. Hence the text appereance can't be changed much.
Code:
IncludeFile "UI\FrameDef\UI\EscMenuTemplates.fdf", //Frames from that fdf can be inherited in this file
IncludeFile "UI\FrameDef\UI\QuestDialog.fdf",

Frame "TEXTAREA" "MyTextArea" {
    DecorateFileNames,
    FrameFont "InfoPanelTextFont", 0.020, "",

    TextAreaLineHeight 0.018, //Should fit used font Size, a high difference shows no text or much space between lines.

    TextAreaLineGap 0.00,     //adds that much space between 2 Lines, addtional to TextAreaLineHeight.

    TextAreaInset 0.035,      //Moves the Text and the scrollbar into the middle from all sides by this amount. This increases the min size for game crash.

    TextAreaMaxLines 20,      //Only that amount of lines are displayed, if more lines are added oldest are removed.

    TextAreaScrollBar "MyTextAreaScrollBar",
    Frame "SCROLLBAR" "MyTextAreaScrollBar" INHERITS WITHCHILDREN "EscMenuScrollBarTemplate" {
    }

    ControlBackdrop "MyTextAreaBackdrop",
    Frame "BACKDROP" "MyTextAreaBackdrop" INHERITS "QuestButtonBaseTemplate" {
    }
}

jass Code creating MyTextArea from above.
JASS:
function CreateMyTextArea takes nothing returns nothing
    local framehandle textArea = BlzCreateFrame("MyTextArea", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),0,0)
    local integer index = 1
    call BlzFrameSetAbsPoint(textArea, FRAMEPOINT_CENTER, 0.4, 0.3)
    call BlzFrameSetSize(textArea, 0.25, 0.25)
    loop
        exitwhen index == 120
        call BlzFrameAddText(textArea, I2S(index)+": Test Text")
        set index = index + 1
    endloop
endfunction
//===========================================================================
function InitTrig_Create_MyTextArea takes nothing returns nothing
    call BlzLoadTOCFile( "war3mapImported\\MyTextArea.toc" )
    call TimerStart(CreateTimer(), 0.0, false, function CreateMyTextArea)
endfunction
QuestBackdropEscMenuBackdrop
Big Inset Textarea.jpgTextArea QuestDialog BackDrop.jpg

Inherited TextArea

If one is overall fine with a TextArea and only wants some small changes, like a different textsize. Then one could inherit from the wanted TextArea and mention only the changed textsize. That way one can have small (in definition) , powerful and still valid frames.
That could look like this
Code:
IncludeFile "UI\FrameDef\glue\battlenettemplates.fdf",  //Frames from that fdf can be inherited in this file

Frame "TEXTAREA" "BigBnetTextArea" INHERITS WITHCHILDREN "BattleNetTextAreaTemplate" {
    DecorateFileNames,
    FrameFont "MasterFont", 0.020, "",
    TextAreaLineHeight 0.015,
}
BigBnetTextArea.jpg
"BigBnetTextArea" is basicly "BattleNetTextAreaTemplate" but has a bigger TextSize and the lines are bigger, to fit better with the increased textsize.
To inherit a Frame's childFrames, one adds WITHCHILDREN after INHERITS.

BlzGetFrameByName is not able to return inherited childFrames. With the release of the native BlzFrameGetChild in V1.32.6, one is able to get the inherited childFrames during the runtime, in 1.32.6 this native ignores String&Texture childFrames.​

Other UI-Frame Tutorials

 

Attachments

  • TextArea Tutorial.w3x
    17.8 KB · Views: 340
Last edited by a moderator:
Level 19
Joined
Aug 16, 2007
Messages
881
Thanks for all the tutorials and script templates, very helpful!

You wouldn't happen to know how to manually set the current scroll value? Whenever I update the text in the text area the scroll wheel always starts at the bottom.

I've tried experimenting with these natives, but with with no success:
native BlzFrameSetValue takes framehandle frame, real value returns nothing
native BlzFrameSetStepSize takes framehandle frame, real stepSize returns nothing

I'm using "HeroSelectorTextArea" from HeroSelector.fdf in your Hero Selection Template if that matter.
 
Level 14
Joined
Feb 7, 2020
Messages
386
Can this works for each player individually or it’s for all player one text area visible
You would need to use GetLocalPlayer() to display/update it for individual players. Frames by default show for everyone.

e.g.
JASS:
if Player(0) == GetLocalPlayer() then
   // do show stuff for player 1
   // do text update stuff for player 1
endif
 
Level 14
Joined
Feb 7, 2020
Messages
386
So is it possible and where I set the GetLocalPlayer() before I start to call BlzCreateFrame?
You don't want to create frames for local player, only hide/show/update them.

I can give you a rudimentary example, but if you don't know about GetLocalPlayer() you can read through something like this: GetLocalPlayer

And if you use it incorrectly on data that requires net code, it can desync.
JASS:
function CreateDefaultTextAreas takes nothing returns nothing
    local framehandle textArea = BlzCreateFrame("BattleNetTextAreaTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),0,0)
    local framehandle textArea2 = BlzCreateFrame("EscMenuTextAreaTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),0,0)
    local integer index = 1
    call BlzFrameSetAbsPoint(textArea, FRAMEPOINT_TOPLEFT, 0.1, 0.5)
    call BlzFrameSetAbsPoint(textArea2, FRAMEPOINT_TOPLEFT, 0.5, 0.5)
    call BlzFrameSetSize(textArea, 0.25, 0.25)
    call BlzFrameSetSize(textArea2, 0.25, 0.25)
    loop
        exitwhen index == 120
        call BlzFrameAddText(textArea, I2S(index)+": Test Text")
        call BlzFrameAddText(textArea2, I2S(index)+": Test Text")
        set index = index + 1
    endloop
    // example: leave it shown for Player 1 (do nothing), hide for Player 2 and 3:
    if Player(1) == GetLocalPlayer() or Player(2) == GetLocalPlayer() then
        call BlzFrameSetVisible(textArea, false)
        call BlzFrameSetVisible(textArea2, false)
    endif
    // end example
endfunction

//===========================================================================
function InitTrig_Create_TextAreaTemplates takes nothing returns nothing
    call BlzLoadTOCFile( "war3mapImported\\Templates.toc" )
    call TimerStart(CreateTimer(), 0.0, false, function CreateDefaultTextAreas)
endfunction
 
Level 12
Joined
Mar 13, 2020
Messages
421
Damn, wanted to use this text area for each player to show some stats like



Armor

Health Points

Mana Points

Power

Spelldamage

Spellcrit/Crit Chance %

Spellcrit/Crit %

Dodge Chance %

Block Chance %

Block %

Spell Lifesteal/Lifesteal

Magical Damage Reduction %

Health Regeneration

Mana Regeneration %

Movementspeed

so that’s not an option
 
Level 14
Joined
Feb 7, 2020
Messages
386
Damn, wanted to use this text area for each player to show some stats like



Armor

Health Points

Mana Points

Power

Spelldamage

Spellcrit/Crit Chance %

Spellcrit/Crit %

Dodge Chance %

Block Chance %

Block %

Spell Lifesteal/Lifesteal

Magical Damage Reduction %

Health Regeneration

Mana Regeneration %

Movementspeed

so that’s not an option
No, that is an option. You can read from data and update the text for the local player, you just cannot set data that requires synchronization (e.g. make a frame locally which creates a framehandle).
 
Level 12
Joined
Mar 13, 2020
Messages
421
No, that is an option. You can read from data and update the text for the local player, you just cannot set data that requires synchronization (e.g. make a frame locally which creates a framehandle).

but if I use this like a spell that turns it visible for the local player would this sort of things cause a desync?
And where I can find a framehandle tutorial I started jass some days ago and im still a noob it would be my skill level of jass to update the stats when clicking on the spell and showing the stats but never heard of framehandles...
 
Level 14
Joined
Feb 7, 2020
Messages
386
but if I use this like a spell that turns it visible for the local player would this sort of things cause a desync?
And where I can find a framehandle tutorial I started jass some days ago and im still a noob it would be my skill level of jass to update the stats when clicking on the spell and showing the stats but never heard of framehandles...
It's not really organized anywhere. I'd spend time looking through these, though: ui-fdf | HIVE
 
Level 12
Joined
Mar 13, 2020
Messages
421
It's not really organized anywhere. I'd spend time looking through these, though: ui-fdf | HIVE

brother I know you are some skilled person in Lua/Jass but you have a conversation with a new noob mapper so what is ui fdf? And what means it’s not really organized?

Sorry for wasting your time but I don’t know this sort of things and want to understand it a bit...
 
UI-fdf is a tag under which most of my tutorials are collected and can be found. This tags are a feature of hiveworkshop.com. Tags used by a thread, can be seen right under the Title name. You can click such a tag to get a List of Threads using the tag.

And where I can find a framehandle tutorial
At the end of the tutorials you find links to other such tutorials, this is a newer edit. Chaosy told me it would link them better than the tag.
Or you could open the Tutorial Pastebin link in my signatur which opens a big (incomplete) info book about warcraft 3 UI-Frames, mostly a collection of the tutorials.
 
Level 12
Joined
Mar 13, 2020
Messages
421
Is there any way to clear a TextArea?

For now I'm destroying and recreating the framehandle whenever I want to reset it.
question can you update it? if yes you can also clear it... using a variable string as text and if you clear the variable before updating again you clear it... if im not wrong.. same i did with custom info panel from tasyen...
 
Level 3
Joined
May 31, 2019
Messages
30
Thanks for all the tutorials and script templates, very helpful!

You wouldn't happen to know how to manually set the current scroll value? Whenever I update the text in the text area the scroll wheel always starts at the bottom.

I've tried experimenting with these natives, but with with no success:
native BlzFrameSetValue takes framehandle frame, real value returns nothing
native BlzFrameSetStepSize takes framehandle frame, real stepSize returns nothing

I'm using "HeroSelectorTextArea" from HeroSelector.fdf in your Hero Selection Template if that matter.

No, I also want to know how to do that.

Years passed, I wonder if there is a way now.
I don't need to set the scroll value, all I need is to set the textarea at top (instead of bottom) each time I update the text.

Anyone knows how to do it?
 
Level 1
Joined
Jan 19, 2014
Messages
1
thank you for your tutorials very much.
i didn't realize i'm just a beginner until my friend recommened them to me.
 
Top