ScrollTextComponent with good performance


#1
#include "juce.h"

class ScrollTextComponent:public Component,
							public Timer
{
public:
	ScrollTextComponent()
	{
		image=0;
		font.setBold(true);	
		startTimer(20);
	}

	~ScrollTextComponent()
	{
		stopTimer();
		if (image) deleteAndZero(image);
	}

	void setText(String t)
	{
		cs.enter();	// paint() forbidden!

		baseText=t;
		
		t=String("  ")+t;	// add some empty space behind the text so it's width cannot be 0
							// and so there is spacing between repeating
		text=String::empty;

		int btw=font.getStringWidth(t);
		int w2=2*getWidth();
		int n=w2/btw + 1;	// how often the text needs to be repeated itself to at least fit in width

		for (int i=0; i<n; i++) text+=t;
		minX=-btw;

		// --- create image ---
		if (image) deleteAndZero(image);
		int iw=font.getStringWidth(text); // image width
		image=new Image(Image::ARGB,iw,getHeight(),true);
		if (image)
		{
			Graphics g(*image);
			g.setFont(font);
			g.fillAll(Colour(0x80808080));
			g.setColour(Colours::white.withAlpha(0.5f));
		
			g.drawText(text,0,1,iw,getHeight(),Justification::centredLeft,false);
			g.setColour(Colours::black);
			g.drawText(text,0,0,iw,getHeight(),Justification::centredLeft,false);
		}

		cs.exit(); // paint() allowed!
	}
private:
	void paint(Graphics &g)
	{
		cs.enter(); // setText() forbidden!!

		if (image) // blit image
			g.drawImage(image,0,0,getWidth(),getHeight(),-xpos,0,getWidth(),getHeight());
		
		cs.exit(); // setText() allowed!!
	}

	void timerCallback()
	{
		xpos--;
		if (xpos<=minX) xpos=0;
		repaint();
	}

	void resized()
	{
		setText(baseText);	// recompute image
	}

	CriticalSection cs;
	Image *image;
	Font font;
	int xpos;
	int minX;
	String baseText,text;
};

#2

Good stuff. You might want to use the “code” button when you’re pasting stuff like that, to make it a bit more legible!


#3

Have done so now :slight_smile: