cancel
Showing results for 
Search instead for 
Did you mean: 

old text stuck in other frame buffer when updating text of textArea with wild card

unsigned_char_array
Senior III

I'm updating a text field (textArea with wild card) every tick (only for testing, in practice it will be updated less, and only when invalidated when changed). It updates the field just fine, however the old value remains in the other frame buffer. So the value alternates between the new value and the old value. But only if new text is smaller than old text.

Here was my initial code:

 

 

void Screen1View::updatePowerState(const char* str)
{
	touchgfx::Unicode::strncpy(textAreaPowerControlStateBuffer, str, TEXTAREAPOWERCONTROLSTATE_SIZE -1);
	textAreaPowerControlState.resizeToCurrentText();
	textAreaPowerControlState.invalidate()
}

 

 

But this code didn't work when increasing the size. So I tried to invalidate by rectangle instead:

 

 

void Screen1View::updatePowerState(const char* str)
{
	Rect invalidatedArea = textAreaPowerControlState.getRect();
	invalidatedArea.x=0; // convert to relative rect
	invalidatedArea.y=0; // convert to relative rect


	touchgfx::Unicode::strncpy(textAreaPowerControlStateBuffer, str, TEXTAREAPOWERCONTROLSTATE_SIZE -1);
	textAreaPowerControlState.resizeToCurrentText();

	Rect invalidatedArea2 = textAreaPowerControlState.getRect();
	invalidatedArea2.x=0; // convert to relative rect
	invalidatedArea2.y=0; // convert to relative rect

	invalidatedArea.expandToFit(invalidatedArea2);
	textAreaPowerControlState.invalidateRect(invalidatedArea);
}

 

 

Even invalidating a very large size doesn't work:

 

void Screen1View::updatePowerState(const char* str)
{
	touchgfx::Unicode::strncpy(textAreaPowerControlStateBuffer, str, TEXTAREAPOWERCONTROLSTATE_SIZE -1);
	textAreaPowerControlState.resizeToCurrentText();
	//textAreaPowerControlState.invalidate();

	Rect invalidatedArea;
	invalidatedArea.width = 500;
	invalidatedArea.height = 24;
	invalidatedArea.x=0;
	invalidatedArea.y=0;

	textAreaPowerControlState.invalidateRect(invalidatedArea);
}

 

 

This does expand, but when shrinking the older text that was to the right of the newer text remains in the other frame buffer.

I invalidate the d-cache by address and use the address of the current frame buffer and the area that has changed. This works flawlessly with animations and clock widget etc. So I don't know why it is not working with a text field.

I was wondering if it is also possible to invalidate only the wildcard area without too much work? It seems pointless to invalidate the entire text when only the wildcard part is updated.

I'm using TouchGFX 4.23.2

I've attached a video.

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.
1 ACCEPTED SOLUTION

Accepted Solutions
GaetanGodart
ST Employee

Hello @unsigned_char_array ,

 

When changing the content of the textArea, the content might be bigger or smaller.
In the case it is smaller, the invalidated area will be smaller, so you won't invalidate the very right part of the text area.

This issue can also happen when moving widgets.
For instance, if you have a box and every ticks you move it down by 1 pixel and then invalidate, the invalidate area will be the new position of the box so the pixel above won't disappear.

To fix the wildcard issue, try to invalidate the textArea before changing the content as well as after invalidating the content like so :

void Screen1View::updatePowerState(const char* str)
{
    textAreaPowerControlState.invalidate()
	touchgfx::Unicode::strncpy(textAreaPowerControlStateBuffer, str, TEXTAREAPOWERCONTROLSTATE_SIZE -1);
	textAreaPowerControlState.resizeToCurrentText();
	textAreaPowerControlState.invalidate()
}

 

If this solves your issue, I invite you to select this comment as "best answer".

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

View solution in original post

6 REPLIES 6
unsigned_char_array
Senior III

I've found a half working work around. If I append the string with spaces it clears most of the old text. However since the font is not monospaced it sometimes doesn't clear part of the last character. Obviously not the solution.

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.
GaetanGodart
ST Employee

Hello @unsigned_char_array ,

 

When changing the content of the textArea, the content might be bigger or smaller.
In the case it is smaller, the invalidated area will be smaller, so you won't invalidate the very right part of the text area.

This issue can also happen when moving widgets.
For instance, if you have a box and every ticks you move it down by 1 pixel and then invalidate, the invalidate area will be the new position of the box so the pixel above won't disappear.

To fix the wildcard issue, try to invalidate the textArea before changing the content as well as after invalidating the content like so :

void Screen1View::updatePowerState(const char* str)
{
    textAreaPowerControlState.invalidate()
	touchgfx::Unicode::strncpy(textAreaPowerControlStateBuffer, str, TEXTAREAPOWERCONTROLSTATE_SIZE -1);
	textAreaPowerControlState.resizeToCurrentText();
	textAreaPowerControlState.invalidate()
}

 

If this solves your issue, I invite you to select this comment as "best answer".

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

I swear I tried that before, but it wasn't working then (I think I had a typo then and accidentally invalidated a different text field). Now it works! Thanks! I modified your code a bit and use invalidateContent() instead of invalidate() and it still works:

void Screen1View::updatePowerState(const char* str)
{
    textAreaPowerControlState.invalidateContent()
	touchgfx::Unicode::strncpy(textAreaPowerControlStateBuffer, str, TEXTAREAPOWERCONTROLSTATE_SIZE -1);
	textAreaPowerControlState.resizeToCurrentText();
	textAreaPowerControlState.invalidateContent()
}

 

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.
GaetanGodart
ST Employee

It happens to the best of us! 😉

Gaetan Godart
Software engineer at ST (TouchGFX)
unsigned_char_array
Senior III

@GaetanGodart I've made an improvement. I learned a trick from @Martin KJELDSEN of pressing F2 while in the simulator to visualize areas that are invalidated. This showed me the entire text area was invalidated, not just the wildcard part. I actually expected only the wildcard to be updated. I modified the code so it only refreshes the part that changed:

 

 

 

void Screen1View::updatePowerState(const char* str)
{
	static int16_t xOffset = -1;
	if (xOffset < 0) //first time
	{
		auto wildcardTemp = textAreaPowerControlState.getWildcard1();
		textAreaPowerControlState.setWildcard1(nullptr);
		xOffset = textAreaPowerControlState.getTextWidth();
		textAreaPowerControlState.setWildcard1(wildcardTemp);
	}


	Rect invalidatedArea;

	invalidatedArea = textAreaPowerControlState.getRect();
	invalidatedArea.x = xOffset;
	invalidatedArea.y = 0;
	invalidatedArea.width -= xOffset;

	textAreaPowerControlState.invalidateRect(invalidatedArea);

	touchgfx::Unicode::strncpy(textAreaPowerControlStateBuffer, str, TEXTAREAPOWERCONTROLSTATE_SIZE -1);
	textAreaPowerControlState.resizeToCurrentText();

	invalidatedArea = textAreaPowerControlState.getRect();
	invalidatedArea.x = xOffset;
	invalidatedArea.y = 0;
	invalidatedArea.width -= xOffset;

	textAreaPowerControlState.invalidateRect(invalidatedArea);
}

 

 

 

Should be easy to add a method invalidateWildcard() to textArea. If saves redrawing an entire fixed text field when only a small part has actually changed. This is a suggestion for a new feature.

EDIT: invalidateWildcard() would only be simple if the wildcard is the last part of the string and there is only one wildcard. Otherwise the length of the area before and after the wildcard(s) is hard to determine. If it is a multi line string it won't work at all. Better to use fixed strings for fixed parts.

 

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.
GaetanGodart
ST Employee

That is a great solution indeed.

Here you can find all the features of the simulator : simulator-features 

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)