Does Component::repaint() mark as dirty all its children too?

In Juce documentation Component::repaint() there is written:

At some point in the near future the operating system will send a paint message, which will redraw all the dirty regions of all components

And I am not sure what does mean “all the dirty regions of all components”. So which regions will be marked as dirty?

I am asking because I want to use VBlankAttachment on one component, but actually display sync I need only in two components which are children of vblank-attached component. So I want to be sure if children components will be also repainting in sync with display refreshing rate.

Best Regards

I would just make the VBlankAttachment call the repaint() of the children components.

Ok, but as I understand the VBlankAttachment causes repaint() in sync with display only Component which is attached directly. But children of that component are not attached directly to VBlankAttachment so that’s why I wonder if calling repaint() on those children also guarantees to be repainted in sync.

The VBlankAttachment doesn’t directly cause a repaint() to take place. It has a callback function which is called in sync with the vertical blank of the display the component is on. You then use use that callback to call repaint() yourself - or something else if you want. So yes, that callback would also be at the right time for the children components.

The key thing there is “regions” - it’s not the components that are flagged, it’s a certain region of the screen. That region is then reported to the OS which in turn will come back round again and ask for all dirty regions to be painted. JUCE then goes throught the hierarchy to find all components that intersect those regions.

But semantically, yes. When you call repaint() on a component, all of its child components will be (asynchronously) repainted as well.

Side note, although not asked:
repaint() will also mark the parent as dirty, if the opaque flag wasn’t set.
See setOpaque()

Components that always paint all of their contents with solid colour and thus completely cover any components behind them should use this method to tell the repaint system that they are opaque.

This information is used to optimise drawing, because it means that objects underneath opaque windows don’t need to be painted.

By default, components are considered transparent, unless this is used to make it otherwise.

I haven’t checked in detail, if the Graphics clip region is set to the component bounds though.

Except child components which are setBufferedToImage (true)

1 Like

I could’t find this mentioned in the documentation, by the way. Perhaps it should, I don’t think this is very obvious!

Also, I just now ran into the (somewhat) converse situation where calling repaint() on a component would cause it to update only if setBufferedToImage was true. The component was drawing an image which I was altering directly via its BitmapData, but the changes weren’t reflected when I called repaint(). A stale version of the image kept being painted, sometimes only partially. That is, calling repaint() didn’t have the expected effect of marking the component or image as dirty. Creating a copy of the image or setting the component to bufferedToImage finally solved this, but it was quite a head-scratcher! Not sure if this is a bug, but there’s a warning that BitmapData should only be used by “people who really know what they’re doing”, so I guess I’ll just leave this mentioned here.