Repaint / setOpaque


#1

Hi Jules,

I've been experiencing something rather unusual related to opaque widget on top of constantly repainted widget.

I would like to have your opinion on in order to know if this is a bug or rather a missing feature.

You can easily reproduce this using the Hello World example

Just add the following classes definitions

class RepaintComponent : public juce::Component, public juce::Timer
{
public:
  RepaintComponent()
  {
    startTimer(20);
  }
  virtual void timerCallback()
  {
    repaint();
  }
  virtual void paint(juce::Graphics &g)
  {
    g.fillAll(juce::Colours::black);
  }
};
class OtherComponent : public juce::Component
{
public:
  OtherComponent()
  {
    setOpaque(true);
  }
   virtual void paint(juce::Graphics &g)
  {
    g.fillAll(juce::Colours::red);
  }
};

Then in MainComponent ctor, the following code

RepaintComponent *pRepaintComponent =  new RepaintComponent();
pRepaintComponent->setBounds(20, 100, 200, 30);
addAndMakeVisible (pRepaintComponent);

OtherComponent *pOtherComponent =  new OtherComponent();
pOtherComponent->setBounds(0, 0, 600, 300);
addAndMakeVisible (pOtherComponent);

What I'm seeing in that the OtherComponent component is repainted even though it's opaque and overlap the timer repainted component.

 

Thanks,


#2

It'd be very expensive for each repaint() call to check the obscured regions of any sibling component hierarchies (of which there may be a huge number), so it doesn't.

If you think in your case it could be helpful to check before repainting, you could call Component::getVisibleArea and only do the repaint if the result is non-empty. But I think in 99.9% of normal use, doing such an costly test would be counterproductive.


#3

Component::getVisibleArea does not the trick in my case as I got an almost transparent widget which covers it as well (for a reflection effect) so it's always empty.

Or it would require an onlyOpaque flag

 

Thanks,