VU Meter component update

I’ve updated my VU meter component to now include graphical analog meters. You can now have an image background, an image overlay, and a sizeable, drop-shadowed needle. I’ve also improved the basic analog meters to more efficiently use space. You can download direct from here:

JUCE VU Meters

It includes the source and a modified JUCE Demo executable and source.

Jules? Question: How can one determine if a component has been fully or partially occluded and needs a full repaint? I can’t see any way within the paint() method to determine this.

  • kbj

[quote=“killerbobjr”]
Jules? Question: How can one determine if a component has been fully or partially occluded and needs a full repaint? I can’t see any way within the paint() method to determine this.

  • kbj[/quote]

You can get the bounds of the clipping rectangle from the Graphics object if you need to see which bits will actually get painted.

Ah, okay. For some reason, I kept on thinking of getClipxxx() as a means for determining what the graphics object clips, rather than what gets clipped in the object. It seemed to me rather a bass ackwards way of tracking clipping, so I kind of ignored it. Glad to see it was me who was confused (which I seem to be a lot).

  • kbj

Well, it does specify what the graphics object is clipping, I thought that’s what you were asking. If you need the visible section of the component, try Component::getVisibleArea.

Sounds like you might be barking up the wrong tree though - for meters you need to worry about which areas you call repaint() on, not about what you do in the paint() routine.

[quote=“jules”]
Sounds like you might be barking up the wrong tree though - for meters you need to worry about which areas you call repaint() on, not about what you do in the paint() routine.[/quote]

why is that?

Well you only want to repaint the minimum area that’s changed, so that it’s faster.

I know that! I’m asking how it works. I guess the graphics object would completely ignore any calls to do something outside the clip area. and if your blitting a whole image, it’ll only do the clipped bit?

no time to study the code!

yep, that’s the idea.

There’s a useful flag in juce_Config.h that will make it draw coloured lines around the areas that are getting repainted - very useful for debugging, so you can see if any unnecessary bits are getting drawn.

Hrmm, I guess I’m still confused. What I’m envisioning is something like this (wonky psuedo code):

[code]setValue(v)
{
m_value = v;

// We've updated the position, so flag a repaint
repaint();

}

// Magically called by something else in the JUCE library
callback windowContainingGraphicsObjectIsVisible(bool visible)
{
if(visible)
repaint();
}

paint(g)
{
if(completelyCoveredByAnotherObject())
{
// Update our rectangle list
m_rectRepaintable.add(g.getClipLeft(), g.getClipTop(), g.getClipWidth(), g.getClipHeight());
return;
}

// If partially covered by another object, find out how much
if(g.clipRegionIntersects( m_rectRepaintable.getBounds() ))
{
	// Wave our hands about
	Rectangle rHowMuch( findOutHowMuch(m_rectRepaintable) );
	RectangleList unpainted = ourRepaintRoutine(rHowMuch);
	m_rectRepaintable.add(unpainted);
}
else
{
	ourRepaintRoutine(m_rectRepaintable);
	m_rectRepaintable.clear();
}

}[/code]

Is this concept somewhere near the station platform, or am I on the tracks about to get flattened like a bad penny?

  • kbj

I think you’re waiting for the wrong train.

Your paint() method should be very simple - just paint the whole thing as efficiently as possible. Don’t worry about regions.

Your setValue() method has to be smarter, and call repaint() for only the smallest rectangle that will have changed by the change in value - so if your bar moves up one pixel, just repaint that bit. If it’s a needle, call repaint for only the smallest rectangle that holds the new needle position.

I believe I do have it arse backwards then. I’ll give it a think and have another go at it.

  • kbj