cancel
Showing results for 
Search instead for 
Did you mean: 

Creating TextArea Programmatically With Wildcard and Buffer

ilyus
Senior II

So far, I've been able to create a TextArea with a wildcard in TouchGFX and then edit its buffer via program code - that works. I just edit the array and invalidate. Done.

However, I fail miserably when I try to create Textarea using code only. I have created boxes, for example, and scrollable containers, put stuff inside each other and they work (and many of them in arrays that I loop through when drawing), but textareas are pretty wild and also weirdly (under)documented, and there are pretty much no examples in the internet, I googled my fingers to blood and left almost no links unclicked in google.

My logic was to look at TextAreas created by TouchGFX generator and reproduce the procedure - worked with other things, but doesn't work for TextArea. Here is a WORKING automatically generated by TouchGFX code from ViewBase:

textArea1.setXY(0, 51);
textArea1.setColor(touchgfx::Color::getColorFrom24BitRGB(0, 0, 0));
textArea1.setLinespacing(0);
Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%s", touchgfx::TypedText(T_SINGLEUSEID63).getText());
textArea1.setWildcard(textArea1Buffer);
textArea1.resizeToCurrentText();
textArea1.setTypedText(touchgfx::TypedText(T_SINGLEUSEID62));
scrollableContainerMeasurement.add(textArea1);
scrollableContainerMeasurement.setScrollbarsPermanentlyVisible();

First of all, this function, Unicode::snprintf(), is weirdly documented and I have still no clue how to use it.

More specifically I have no idea what I have to put (when I create my own TextArea) instead of its parameter touchgfx::TypedText(T_SINGLEUSEID63).getText(). Documentation says it's TypedText type - what is it? How do I generate one? From what? What exactly is it? Documentation for it doesn't seem to have any functions that produce object of this obscure type.

Also, if I already do setWildcard(), why do I do setTypedText two lines lower? With some other Single Use ID, whatever that is. Seems like completely useless line of code. I don't understand what it does if I already have a Wildcardbuffer attached to TextArea.

Whenever I manually change the TextArea wildcard with code, I just change the Buffer array and invalidate - I don't need any TypedText or anything. But whenever I just dropped those lines that I don't understand (it doesn't compile with unchanged lines with my own TextAreas - I need to change them somehow, I guess?) and tied wildcardbuffer to the Textarea, it simply didn't show anything on the screen - as if I didn't create anything.

Any hint would be appreciated, thank you!

23 REPLIES 23

testTextArea.setTypedText(touchgfx::TypedText(T_SINGLEUSEID1));

Added #include <texts/TextKeysAndLanguages.hpp> to the View header file.

View.cpp:

void NewScreenView::setupScreen()
{
    NewScreenViewBase::setupScreen();
    testTextArea.setXY(200, 400);
    testTextArea.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 0));
    testTextArea.setLinespacing(0);
    Unicode::snprintf(testTextAreaBuffer, 10, "%s", "meow");
    testTextArea.setWildcard(testTextAreaBuffer);
    testTextArea.resizeToCurrentText();
    //testTextArea.invalidate();
    testTextArea.setTypedText(touchgfx::TypedText(T_SINGLEUSEID1));
    add(testTextArea);
 
 
}

It shows the textarea atthe correct coordinates on the screen! Almost there!

However, it has wrong text. It writes "home" instead of "meow". No idea where it comes from. I mean, it seems like it's from that ID1 thing, which I still have no idea what it is, but that's all I can say. And it's also wrong color and doesn't change color if I change RGB values.

EDIT: tried to move that function with the ID thing earlier, before setting wildcard thing. No changes. Returned to the order presented here (=order in the viewbase)

EDIT 2: if I need another ID for that resource, how do I know which one if I'm not setting a resource in TouchGFX (or do I have to use a resource)? And what exactly does that thing set anyway and how can I edit/change it right in the code?

EDIT 3: don't get me wrong, I appreciate your help, I just really want to understand every line of code I'm using. And there is just one line I don't understand left - the one that actually made the thing show up.

Maybe you understand when see your file TouchGFX\generated\texts\src\Texts.cpp 

And as i write before, in designer open windows TEXTS fonts resources ...

my T_SINGLEUSEID1 is only example you need use your ID for one wildcards <>.

Alexandre RENOUX
Principal

Hello @ilyus​ ,

Better documentation on Text should be available very soon.

In the meantime, I made a very simple example on how to create Text Areas with a wildcard by code.

It's important to know that you will need the Designer to create your text being used as wildcard.

Hope this simple example will help you understand.

/Alexandre

Sorry, had a lot of work and didn't have any time at all to look at this. I have still no idea what ID I should use. I open Texts.cpp, it has many lines of text there in pragma, but there is no way to find out which ID I should use. There is literally nothing to indicate that. And those text pieces in pragma are not in order too - I changed singleuseid1 to 2 and it showed the word "Execute" instead of "Home", which is not even a neighbor of singleuseid1 in Texts.cpp.

Tbh, I'm totally lost with it now. Gonna try an example from Alexandre Renoux below and give feedback.

Hi! Thanks for the example. It's working the way I want it to work. Wanna make sure I understand it correctly, so I have a few clarifying questions.

  1. First of all, what exactly is TypedText? Can multiple TextAreas use one TypedText? What's the point of having TypedText AND Buffer array (aren't they the same thing?)? Both seem to set text, so what's the point of two things setting text, this question has been lingering me for some time already.
  2. As a follow-up to question 1, I don't understand what function myTextArea.setTypedText(touchgfx::TypedText(T_WIDLCARDID)); does in principle, what is the purpose of that specific line of code. Does it set font/direction of text? If so, I guess it's a reusable thing then? Given all Buffer arrays will be individual for each TextArea of course. If it is just font and text direction etc, then I just need one resource for all my TextAreas (provided they have the same font/direction/whatever else this thing does)

If I have to create a Resouce for each TextArea I wanna create with code, it kinda defeats the whole purpose - I can't and don't want to create 100 Resources for 100 TextAreas - which is actually very realistic in my case, I expect to have no less than 80 TextAreas on a single screen (scrollable) purely code-generated that I will for-loop through to set their values or read values from them.

I appreciate your help and patience. Will try things on my own now, maybe will figure it out myself after some experimenting, but it's still a good idea to ask a knowledgeable person, I think.

If I discover anything worthy that answers my question in any way, I will add it here for the infos. Some day in 2025 someone will find this thread in google and thank all of us haha.

IDs is only enum ordered to array as you can see in TextKeysAndLanguages.hpp here 0-11 and last say 12 texts

typedef enum
{
 T_SINGLEUSEID1,
 T_SINGLEUSEID2,
 T_SINGLEUSEID3,
 T_SINGLEUSEID4,
 T_SINGLEUSEID5,
 T_SINGLEUSEID6,
 T_SINGLEUSEID7,
 T_RESOURCEID1,
 T_RESOURCEID2,
 T_RESOURCEID3,
 T_SINGLEUSEID8,
 T_SINGLEUSEID9,
 NUMBER_OF_TEXT_KEYS
} TEXTS;

then same size array exist in TypedTextDatabase.cpp

and LanguageGb.cpp

TEXT_LOCATION_FLASH_PRAGMA
KEEP extern const uint32_t indicesGb[] TEXT_LOCATION_FLASH_ATTRIBUTE =
{
 38, // T_SingleUseId1
 8, // T_SingleUseId2
 31, // T_SingleUseId3
 10, // T_SingleUseId4
 64, // T_SingleUseId5
 69, // T_SingleUseId6
 58, // T_SingleUseId7
 55, // T_ResourceId1
 38, // T_ResourceId2
 0, // T_ResourceId3
 18, // T_SingleUseId8
 43 // T_SingleUseId9
};

as pointers to strings in Texts.cpp

TEXT_LOCATION_FLASH_PRAGMA
KEEP extern const touchgfx::Unicode::UnicodeChar texts_all_languages[] TEXT_LOCATION_FLASH_ATTRIBUTE =
{
 0x44, 0x49, 0x53, 0x50, 0x4c, 0x41, 0x59, 0x20, 0x2, 0x0, // @0 "DISPLAY <>"
 0x4c, 0x49, 0x47, 0x48, 0x54, 0x20, 0x2, 0x0, // @10 "LIGHT <>"
 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x20, 0x36, 0x30, 0x30, 0x0, // @18 "NNNNNNNN 600"
 0x53, 0x57, 0x3a, 0x20, 0x56, 0x2, 0x0, // @31 "SW: V<>"
 0x2, 0x20, 0x64, 0x42, 0x0, // @38 "<> dB"
 0x41, 0x55, 0x58, 0x49, 0x4c, 0x49, 0x41, 0x52, 0x59, 0x20, 0x32, 0x0, // @43 "AUXILIARY 2"
 0x2, 0x20, 0x0, // @55 "<> "
 0x2d, 0x33, 0x35, 0x2e, 0x35, 0x0, // @58 "-35.5"
 0x31, 0x2e, 0x31, 0x32, 0x0, // @64 "1.12"
 0x31, 0x34, 0x0 // @69 "14"
};

and in may example is for you interest @55 “<> �? that mean only wildcard defined, then back to id 55 is used for

T_ResourceId1.

That’s all, and you can reuse it as many as font align and ... equal.

And for example my T_SingleUseId3 used in your code context produce on display SW: Vmeow

.

I'll be honest. I didn't understand anything at all from this message. And your reply looks like barely connected set of sentences that lacks logical connections between them. Could you maybe rephrase what you mean with all that above and make logical connections between things? I understood literally nothing of it although I understand every word of it separately.

I know what enum is (but I have no idea why it's needed there at all), I have read through TextKeysAndLanguages.hpp and Texts.cpp long ago (and I have them open), and it didn't make anything clearer. I have still no idea how it works and what exactly it does.

Sorry ¯\_(ツ)_/¯

Progress so far: I've created another TextArea to see what happens if I share a Resource between them.

I have 2 TextAreas with 2 different Buffer arrays but they both have 1 Resouce.

Answer: they have the same font and font size, same direction, but they can have different texts like no problem (I redrew .invalidate() both of them at the end, and both of them kept their unique text).

So yes, you CAN use one resource for multiple TextAreas with different texts. Resouce is basically a set of text formatting features, as far as I understand.

I feel like I'm ALMOST there. Literally one step away. Because...

Here's my entire NewScreenView.cpp: (deleted commented lines, kept strictly what's necessary to do the job)

#include 
 
NewScreenView::NewScreenView()
{
 
}
 
void NewScreenView::setupScreen()
{
    NewScreenViewBase::setupScreen();
 
    //CREATING ONE TEXTAREA
    testTextArea.setXY(200, 400);
    testTextArea.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 0));
    testTextArea.setLinespacing(0);
    testTextArea.setWildcard(testTextAreaBuffer);
    testTextArea.setTypedText(touchgfx::TypedText(T_RESOURCEID3));
    Unicode::snprintf(testTextAreaBuffer, 10, "Meow meow");
    testTextArea.resizeToCurrentText();
    add(testTextArea);
    testTextArea.invalidate();
 
    //CREATING SECOND TEXTAREA with the same resource
    testTextArea2.setXY(500, 400);
    testTextArea2.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 0));
    testTextArea2.setLinespacing(0);
    testTextArea2.setWildcard(testTextAreaBuffer2);
    testTextArea2.setTypedText(touchgfx::TypedText(T_RESOURCEID3)); //Same resource as the first TextArea. EXPERIMENT!
    Unicode::snprintf(testTextAreaBuffer2, 10, "Woof woof");
    testTextArea2.resizeToCurrentText();
    add(testTextArea2);
    //testTextArea.invalidate(); //Check if TextArea 1 text changed after my manipulations ANSWER: IT DID NOT CHANGE
    testTextArea2.invalidate();
}
 
void NewScreenView::tearDownScreen()
{
    NewScreenViewBase::tearDownScreen();
}

The output produces two textAreas with the correct font and locations. The first one shows "Meo? meo?", the other one says "Woo? ?oo?".

Seems to me like a glyph generation problem. Wondering what happens if I create a textArea in TouchGFX Designer with the same resource and just all letters and numbers, so that it would have to generate all glyphs of the font I need. Will edit this reply after trying.

EDIT

Experiment notes: It's impossible to create a TextArea in with Resouce AND custom text in TouchGFX designer. Resource is basically a fixed piece of text for it, not only formatting. So I used a single-use field with the same Typography that I used for my Resource (same font, font size, direction). It is default black color, unlike my other TextAreas The text of TextArea that I created in Designer is "f" (just one letter to see if this glyph gets added).

Results: "Woo? ?oo?" turned into "Woof ?oof". My plan worked. TouchGFX generated glyph of letter "f", and now the letter shows in my custom created fields too.

Important note: I deleted this "f" TextArea in TouchGFX Designer to see if the glyph stays. It did NOT. When I delete TextArea with "f", I get Woo? ?oo? again. Which means I either need to tell TouchGFX to generate all alphanumerics for me (somehow; I think it's possible somewhere in Resource tab? will google it), or I need to create an invisible TextArea with all alphanumerics so that I have all glyphs generated.

EDIT 2

I went to TouchGFX Designer, "Texts" tab, "Typographies", found there the font that I'm using (in my case it's Typography named "Large", Verdana 40px). In "Wildcard Ranges" I entered "0-9,A-Z,a-z" (without quote marks). Now I have "Meow meow" and "Woof woof"! (source: "Texts View" page of TouchGFX documentation)

EVERYTHING WORKS

I think I have finally figured it out. ALL OF IT.

I guess I should make an entire post of what needs to be done to generate a TextArea with a changeable wildcard purely by code. Maybe I'm the only ****** who needed help of multiple people and several days to figure it out, but it's all as usual pretty easy when you know it. Now I'm looking at it and like "pfff it was 10 minutes of work". Except I didn't know what exactly and how exactly to do.

ilyus
Senior II

FULL SOLUTION TO CREATING CUSTOM TEXTAREA WITH CODE

With the help of everyone participating in this post and some other people in other threads (and, of course, my own undeniable genius *chuckle*), here is a summary of how you can create a textArea purely (99%) with code. Step by step from zero:

Open TouchGFX Designer. In the upper tabs, go to "Texts"->Typographies. Make sure there is a font you are going to use (or add another one), you need to generate letter glyphs using TouchGFX Designer. In my case, I did this:0693W00000BcRuBQAV.pngI'm using Verdana 40px font; In "Wildcard ranges" I have written 0-9,A-Z,a-z; this will force TouchGFX to generate glyphs for all letters and numbers even if no TextAreas created natively in TouchGFX Designer use them. Otherwise, you can miss a few letters of that font (and will see "?"). If you need other characters, such as commas and stuff, there is "wildcard characters" section for it.

Next, go to "Resources" tab. "Resource" is a set of formatting rules that we associate with every TextArea. Font size, font direction, Alignment and content. Add new resource to use with the new TextAreas that we will create with the code. You can use one Resource with multiple TextAreas. It's just a formatting feature, not the text itself. I am going to use "ResourceId3" for my custom TextAreas. Set the Typography of the Resource to the one you used in 1.In Resource text, write "<>" (means "wildcard"), If you write some text in there except "<>", it will be visible in all TextAreas using that resource. Wildcards, however, are individual for every TextArea. Personally, I want all TextAreas to have completely different content, so I do the following:0693W00000BcS0JQAV.png 

Now we have forced TouchGFX to generate all characters' glyphs for the font we're going to use and we have created text formatting rules, also known as Resource (Rules are: use that font with glyphs, align left, text direction left to right, text is entirely wildcard). So we finally get to generating stuff with the code.

Create the screen where you want to create your custom TextAreas. The screen can be empty, we just need the files for the screen to be generated to put our stuff into them. "Generate the code".

Find the screen view file. It should be located in "/gui/" folder (exact location differs depending on whether you created project in Cube or TouchGFX first, but it's always in the folder named "gui/" or "gui/src/screenname_screen/", "gui/included/..." for its header file). Look for "gui" folder (not gui_generated!). My screen is called "NewScreen", and my project was first created in TouchGFX Designer and later imported into CubeIDE, where I'm working on it. If you 're curious about how to import it there, there is a video on "EE by Karl" youtube channel that does just that.

I open "NewScreenView.cpp" and "NewScreenView.hpp". In the header file, we need to include TouchGFX components that we're going to use. If you're not sure what to add, create a widget in TouchGFX designer, generate code and go to "NewScreenViewBase.cpp/hpp" in gui_generated. That hpp will include stuff necessary to generate those specific widgets. Copy those includes to your NewScreenView.hpp. My NewScreenView.hpp has these includes:

#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/Button.hpp>
#include <touchgfx/containers/ScrollableContainer.hpp>
#include <touchgfx/widgets/TextAreaWithWildcard.hpp>
#include <touchgfx/Color.hpp>
#include <texts/TextKeysAndLanguages.hpp>

Color and TextKeysAndLanguages are a must - you will haveto set color and you will need to connect your font/resource to the TextArea, those do exactly that. Others - whatever you want to create with your own code, should be there. My "includes" allow me to create Boxes (color fills), buttons, scrollable containers and TextAreas with a wildcard.

Next, let's declare our new custom TextArea in the header file.

My entire header file looks like this:

#ifndef NEWSCREENVIEW_HPP
#define NEWSCREENVIEW_HPP
 
#include <gui_generated/newscreen_screen/NewScreenViewBase.hpp>
#include <gui/newscreen_screen/NewScreenPresenter.hpp>
#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/Button.hpp>
#include <touchgfx/containers/ScrollableContainer.hpp>
#include <touchgfx/widgets/TextAreaWithWildcard.hpp>
#include <touchgfx/Color.hpp>
#include <texts/TextKeysAndLanguages.hpp>
 
 
class NewScreenView : public NewScreenViewBase
{
public:
    NewScreenView();
    virtual ~NewScreenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    touchgfx::TextAreaWithOneWildcard testTextArea;
    touchgfx::Unicode::UnicodeChar testTextAreaBuffer[10];
    touchgfx::TextAreaWithOneWildcard testTextArea2;
    touchgfx::Unicode::UnicodeChar testTextAreaBuffer2[10];
protected:
};
 
#endif // NEWSCREENVIEW_HPP

In "Public" section, I have created two textAreas and two buffer arrays for them so that they can hold different stuff. As far as I remember, buffers are maximum 10 places long (haven't tried longer to be honest, feel free to try, I expect it to trim the text which is too long), and one last character has to be reserved for end of line character when it's put into the TextArea. so if you need 4 places for your text, you'll need an array of length 5.

Nothing stops you from declaring an array of boxes or array of buttons or array of textAreas. I had no problem creating an array of boxes that way,

What's left is to actually add stuff to our NewScreen.cpp, which in my hands looks like this:

#include <gui/newscreen_screen/NewScreenView.hpp>
 
NewScreenView::NewScreenView()
{
 
}
 
void NewScreenView::setupScreen()
{
    NewScreenViewBase::setupScreen();
 
    //CREATING ONE TEXTAREA
    testTextArea.setXY(200, 400);
    testTextArea.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 0));
    testTextArea.setLinespacing(0);
    testTextArea.setWildcard(testTextAreaBuffer);
    testTextArea.setTypedText(touchgfx::TypedText(T_RESOURCEID3));
    Unicode::snprintf(testTextAreaBuffer, 10, "Meow meow");
    testTextArea.resizeToCurrentText();
    add(testTextArea);
    testTextArea.invalidate();
 
    //CREATING SECOND TEXTAREA with the same resource
    testTextArea2.setXY(500, 400);
    testTextArea2.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 255, 0));
    testTextArea2.setLinespacing(0);
    testTextArea2.setWildcard(testTextAreaBuffer2);
    testTextArea2.setTypedText(touchgfx::TypedText(T_RESOURCEID3)); //Same resource as the first TextArea. EXPERIMENT!
    Unicode::snprintf(testTextAreaBuffer2, 10, "Woof woof");
    testTextArea2.resizeToCurrentText();
    add(testTextArea2);
    testTextArea2.invalidate();
}
 
void NewScreenView::tearDownScreen()
{
    NewScreenViewBase::tearDownScreen();
}

 CONTINUES IN REPLY!