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!

1 ACCEPTED SOLUTION

Accepted Solutions
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!

View solution in original post

23 REPLIES 23
ktrofimo
Senior III

Hello!

You can threat Unicode::snprintf( str, N, format, variables) as regular snprintf - printf limited to N characters. It is used just to make sure not to overwrite bytes after end of the buffer. I found it difficult to use for non-Latin characters and finally using now Unicode::fromUTF8( text, str, N );

Also you need to add all characters you are going to use with this font to Texts / Typographies otherwise you will get string of "?" (fallback characters)

Yeah, I figured this one (snprintf) out about now. I'm sitting here experimenting and stuff, ***** to be mere mortal; but hat's not the main source of the problem. What is the TypedText thing? The documentation has literally zero information on what exactly it is, what it does and what it exists for. It just says "TypedText is an object", and it doesn't describe anything nor does it list any function to create one - only read from TypedText, but not create one. There are functinos that require that thing as a parameter, and I can't do it, because there is no way to create object of this type - there is no function, no constructor. Only to get text back from it (and it even doesn't specify return data type, it simply says "returns text" - last time I checked there was no datatype "text", so I have actually no clue what it returns, how to use it and why do I need it at all). That's all I could get from the TouchGFX documentation.

I would still prefer if someone just wrote 10 lines of code that create a TextArea (given definitions in header) that I can control. I'm pretty sure I'll understand what's what if I just see some code of creating a TextArea from scratch

touchgfx::TypedText(T_SINGLEUSEID63).getText()... Look for T_SINGLEUSEID63. This is an ID of text string you typed in designer and this function simply returns actual text. Put your own string instead:

Unicode::snprintf(textArea1Buffer, sizeof(textArea1Buffer), "My string with value %d", intVal);

Since you do not use designer to make your strings, do not use TypedText​

I tried it. Here is the code:

testTextArea.setXY(200, 200);
    testTextArea.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 0, 192));
    testTextArea.setLinespacing(0);
    Unicode::snprintf(testTextAreaBuffer, 10, "%s", "meow");
    testTextArea.setWildcard(testTextAreaBuffer);
    testTextArea.resizeToCurrentText();
    testTextArea.invalidate();
    add(testTextArea);

Everything except "add" and "invalidate" is copied from TouchGFX generated code (with appropriate adjustments). Nothing showing up. Ideas?

Created new screen. The screen has 1 TouchGFX-generated Textarea with 1 wildcard and 1 semi-opaque 100%-screen-box for background. Nothing else. In View file (user-side), I create another TextArea. Original shows on screen, mine does not. As I mentioned before, I can create containers and boxes no problem and put them into each other. Text doesn't work.

This is what TouchGFX-generated code is for the TextArea with 1 Wildcard. And it shows:

//From ViewBase.cpp, auto-generated
//Works!
 
textArea1.setXY(16, 216);
textArea1.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 0, 0));
textArea1.setLinespacing(0);
Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%s", touchgfx::TypedText(T_SINGLEUSEID65).getText());
textArea1.setWildcard(textArea1Buffer);
textArea1.resizeToCurrentText();
textArea1.setTypedText(touchgfx::TypedText(T_SINGLEUSEID64));
 
    add(__background);
    add(box1);
    add(textArea1);

This is my user-created TextArea in View.cpp, and it does NOT show up

//Manually created in View.cpp
//DOES NOT WORK
//Header file has declarations 
/*
touchgfx::TextAreaWithOneWildcard testTextArea;
touchgfx::Unicode::UnicodeChar testTextAreaBuffer[10];
*/
 
testTextArea.setXY(200, 200);
testTextArea.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 0, 192));
testTextArea.setLinespacing(0);
Unicode::snprintf(testTextAreaBuffer, 10, "%s", "meow");
testTextArea.setWildcard(testTextAreaBuffer);
testTextArea.resizeToCurrentText();
testTextArea.invalidate(); //out of desperation
add(testTextArea);
testTextArea.invalidate(); //out of desperation
box1.invalidate(); //out of desperation

Again, this kind of procedure creates other elements like no problem. TextArea just won't show.

please show full view.cpp setupscreen code, order of commands and objects is important

What I posted is literally all the code.

Here is NewScreenView.cpp

#include <gui/newscreen_screen/NewScreenView.hpp>
 
NewScreenView::NewScreenView()
{
 
}
 
void NewScreenView::setupScreen()
{
    NewScreenViewBase::setupScreen();
    testTextArea.setXY(200, 400);
    testTextArea.setColor(touchgfx::Color::getColorFrom24BitRGB(255, 0, 192));
    testTextArea.setLinespacing(0);
    Unicode::snprintf(testTextAreaBuffer, 10, "%s", "meow");
    testTextArea.setWildcard(testTextAreaBuffer);
    testTextArea.resizeToCurrentText();
    testTextArea.invalidate();
    testTextArea.invalidate();
    box1.invalidate();
    add(testTextArea);
 
 
}
 
void NewScreenView::tearDownScreen()
{
    NewScreenViewBase::tearDownScreen();
}

And the NewScreenView.hpp is

#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>
 
 
class NewScreenView : public NewScreenViewBase
{
public:
    NewScreenView();
    virtual ~NewScreenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    touchgfx::TextAreaWithOneWildcard testTextArea;
    touchgfx::Unicode::UnicodeChar testTextAreaBuffer[10];
protected:
};
 
#endif // NEWSCREENVIEW_HPP

 (repeating lines are leftovers from debugging attempt, I will clean it up once it works, or, more likely, will delete the screen completely anyway since it's only for testing and trying)

Your area dont have defined font and orientation, for every font size and type you need create in designer one resource with only wildcard

And use same lines as in base

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

 and in header place objects to protected area...

I don't understand. I'm actually USING Base code. I copy-pasted base code and replaced stuff I need. So what exactly should I change? Original TextArea generated in ViewBase does exactly what I do and nothing more - there is nothing about font or orientation in the Base. Your reply was as welcome as it was...kinda uninformative. Could you clarify/provide example?

Box1 invalidate was my attempt to make it show by trying to redraw stuff. Unrelated to the problem in question.