feathersui / feathersui-starling

User interface components for Starling Framework and Adobe AIR

Home Page:https://feathersui.com/learn/as3-starling/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

extending the Label class

raresn opened this issue · comments

Hello,
We have extended the label class, but in order to get the text to actually update on the stage, we have to do some extra steps, that i think are time consuming.

this.textRenderer.text = Info.minutesToText(_minutesInt);

And then we need to call:
this.createTextRenderer(); this.refreshTextRendererData(); this.refreshEnabled(); this.refreshTextRendererStyles(); this.layoutChildren();
Without these last 5 lines, we can't be sure that the text actually changes on the stage.
Wondering if we can do it in a smarter way. Any help is appreciated.
Thank you.

The whole class looks like this:
`public class TimeTextLabel extends Label
{
private var _minutes:Number;
private var _minutesInt:int;

	public function TimeTextLabel()
	{
		super();
		minutes = 0;
		_minutesInt = 0;
		this.text = "00:00";
		this.backgroundSkin = new Quad(16, 16, 0xFFFFFF);
		this.styleName = AppTheme.TEXT_TIME_LABEL_STYLE;
	}
	override public function dispose():void
	{
		if(this.backgroundSkin) {
			this.backgroundSkin.dispose();
			this.backgroundSkin = null;
		}

		super.dispose();
	}
	
	public function get minutes():Number
	{
		return _minutes;
	}

	public function set minutes(value:Number):void
	{
		_minutes = value;
		if(_minutesInt != (value | 0)) {
			// trace("[TimeTextLabel] - update text", value);
			_minutesInt = value | 0;
			this.text = Info.minutesToText(_minutesInt);
			
			/* must have for texture generation */
			this.textRenderer.text = Info.minutesToText(_minutesInt);
			this.createTextRenderer();
			this.refreshTextRendererData();
			this.refreshEnabled();
			this.refreshTextRendererStyles();
			this.layoutChildren();
		}
	}`

We are using this code to generate a list of labels containg the hours of the day, that we then convert to a texture and use when needed.

You don't need to call all of those other methods after setting the text property. You can, in fact, be sure that the rendered text will change when the text setter is called. The text setter calls invalidate(), which will cause the Label to update itself before the next time that Starling renders.

public function set minutes(value:Number):void
{
	_minutes = value;
	if(_minutesInt != (value | 0)) {
		// trace("[TimeTextLabel] - update text", value);
		_minutesInt = value | 0;
		this.text = Info.minutesToText(_minutesInt);
	}
}

The problem is a bit more complex.

We are trying to draw on a RenderTexture the same Object, that extends a Sprite, containing this extended Label, multiple times. This is done only once on first run and texture is saved to png.

So rather than creating multiple objects, we try to create one, and draw it in different positions and with different text, and we do this in a for loop. We were not able to validate it and force it to show. If we don’t add that extra code it will render a texture with 00:00 only. We need to force it to paint on each update.

Maybe there is a better way to fill the texture with numbers. Any sugestion is appriciated.

The other issue here is this error:

Uncaught Error // Error // Error: Error #3768 // Error: Error #3768
	at starling.textures::ConcreteTexture/dispose()
	at feathers.controls.text::TextBlockTextRenderer/dispose()
	at starling.display::DisplayObjectContainer/removeChildAt()
	at starling.display::DisplayObjectContainer/removeChild()
	at feathers.controls::Label/createTextRenderer()
	at ro.app.items::TimeTextLabel/set minutes()

One sollution would be to add a condition and stop calling createTextRenderer(), since it's only required for texture generation. Out of the errors I've read, they were not in the texture generation part. I think error is given when probably app is in background. This might not be the most elegant fix.

Since February we had about 1000 errors related to this. Same object class is used multiple times, during the normal usage of the app, but I don't have a statistic for that. So 1000 errors could be low, or coult be high, but it's certanly enough to demand a patch.

Maybe in the future we will skip this dynamic generation and have all textures stored on a server based on DPI and download after install. Right now it's like a procedural texture, and saves the app 1-2Mb. For 3x resolution, this code generates 4 textures of 2048x2048px. But this is also a perfect copy of what air will render for text, and this was the main goal when we created this monster.

After the text gets set, the Label will be invalid, and it will need to update. Normally, this would happen before Starling renders the next frame. However, you can force it to happen immediately, like this:

label.minutes = newMinutes;
label.validate();