1. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  2. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  3. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
Hive 3 Remoosed BETA - NOW LIVE. Go check it out at BETA Hive Workshop! Post your feedback in this new forum BETA Feedback.
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

UI: TEXTAREA the scrolling Text Frame

Discussion in 'JASS/AI Scripts Tutorials' started by Tasyen, Sep 20, 2019.

Tags:
  1. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,723
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37

    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.
    code

    Code (vJASS):

    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 (Text):

    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.
    Code (vJASS):

    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
     

    QuestBackdrop EscMenuBackdrop
    Big Inset Textarea.jpg TextArea 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 (Text):
    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


     

    Attached Files:

    Last edited by a moderator: Oct 5, 2020
  2. lolreported

    lolreported

    Joined:
    Aug 16, 2007
    Messages:
    844
    Resources:
    13
    Tools:
    1
    Maps:
    6
    Spells:
    6
    Resources:
    13
    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.
     
  3. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,723
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    No, I also want to know how to do that.
     
  4. Chaosy

    Chaosy

    Tutorial Reviewer

    Joined:
    Jun 9, 2011
    Messages:
    11,102
    Resources:
    18
    Icons:
    1
    Maps:
    1
    Spells:
    10
    Tutorials:
    6
    Resources:
    18
    Similar structure changes to the other ones.

    Approved.

    edit: I hope I put the right text to the right image in the table, would be nice for you to confirm because I am not sure about the visual difference.
     
  5. Pwnica

    Pwnica

    Joined:
    Mar 13, 2020
    Messages:
    157
    Resources:
    0
    Resources:
    0
    Can this works for each player individually or it’s for all player one text area visible
     
  6. Planetary

    Planetary

    Joined:
    Feb 7, 2020
    Messages:
    291
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    You would need to use GetLocalPlayer() to display/update it for individual players. Frames by default show for everyone.

    e.g.
    Code (vJASS):
    if Player(0) == GetLocalPlayer() then
       // do show stuff for player 1
       // do text update stuff for player 1
    endif
     
  7. Pwnica

    Pwnica

    Joined:
    Mar 13, 2020
    Messages:
    157
    Resources:
    0
    Resources:
    0
    So is it possible and where I set the GetLocalPlayer() before I start to call BlzCreateFrame?

    thx i think I got it..
     
  8. Pwnica

    Pwnica

    Joined:
    Mar 13, 2020
    Messages:
    157
    Resources:
    0
    Resources:
    0
    can this sort of things cause desync? And how I figure it out?
     
  9. Planetary

    Planetary

    Joined:
    Feb 7, 2020
    Messages:
    291
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    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.
    Code (vJASS):
    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
     
     
  10. Pwnica

    Pwnica

    Joined:
    Mar 13, 2020
    Messages:
    157
    Resources:
    0
    Resources:
    0
    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
     
  11. Planetary

    Planetary

    Joined:
    Feb 7, 2020
    Messages:
    291
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    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).
     
  12. Pwnica

    Pwnica

    Joined:
    Mar 13, 2020
    Messages:
    157
    Resources:
    0
    Resources:
    0
    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...
     
  13. Planetary

    Planetary

    Joined:
    Feb 7, 2020
    Messages:
    291
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    It's not really organized anywhere. I'd spend time looking through these, though: ui-fdf | HIVE
     
  14. Pwnica

    Pwnica

    Joined:
    Mar 13, 2020
    Messages:
    157
    Resources:
    0
    Resources:
    0
    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...
     
  15. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,723
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    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.

    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.