Visual artifacts when moving a Component

I’m making some Components draggable, using ComponentDragger. When I move the Component, it leaves behind a trail like this:

image

What is the recommended way of eliminating this? Of course if I call repaint() on the parent it goes away, but that seems a bit heavy handed.

I’m surprised that I can’t find any mention of this on the forum already–it seems like it would be a common issue…

So I’ve started using the repaint(Rectangle<int>) method to solve this, by repainting a small area around the moving Component. It works, but I can’t help feeling like it’s a bit of a hack. I’d still love to know how the pro’s approach this problem.

class MoveableObject : public Component
{
    void paint(Graphics& g) override { g.fillAll(Colours::aqua); }
};


class MainComponent  : public Component
{
public:

    MainComponent()
    {
        setBounds(100, 100, 500, 500);
        object.setBounds(10, 10, 50, 50);
        addAndMakeVisible(object);
    }


    void mouseDown(const MouseEvent& e) override
    {
        dragger.startDraggingComponent(&object, e);
    }

    void mouseDrag(const MouseEvent& e) override
    {
        dragger.dragComponent(&object, e, nullptr);

        repaint(object.getBoundsInParent().expanded(25)); // <<< whenever the Component is dragged, the parent is repaints 25 pixels around it.
    }


private:
    ComponentDragger dragger;
    MoveableObject object;
};

Question, is your MoveableObject setOpaque (true) by any chance?

I think if you keep it non opaque, it will trigger a repaint of the parent when being moved, so the background should be ok.
But needs to be tested to verify…

I’ve tried setOpaique(), and it doesn’t alter the behavior. If I compile the above code without the repaint(object.getBoundsInParent().expanded(25)) line, I get this when I drag the object:

I’m surprised that I still haven’t found a robust solution to this issue. Every time I move a component, it leaves behind a mark. Do other people not experience this? I’ve grown so used to this in debug code that I don’t notice it any more, but I’m still very curious to know what others do to solve the issue of visual artifacts when Components move.

I never have had such an issue, I also tried to reconstruct based on your code but it works.

Does you parent-Component use setOpaque(true) but doesn’t repaint its whole area? That might create this effect.

Also manually calling repaint shouldn’t be necessary at all.

Maybe you post the (whole) minimal source-code to reproduce the problem so we can have look at it.

Sure. This code gives me artifacts when I click on the blue box to drag it, just like in the screenshot above.

class MoveableObject : public Component
{
    void paint(Graphics& g) override              { g.fillAll(Colours::aqua); }
    void mouseDown(const MouseEvent& e) override  { dragger.startDraggingComponent(this, e); }
    void mouseDrag(const MouseEvent& e) override  { dragger.dragComponent(this, e, nullptr); }

    ComponentDragger dragger;
};


class MainComponent : public Component
{
public:

    MainComponent()
    {
        setBounds(100, 100, 500, 500);
        object.setBounds(10, 10, 50, 50);
        addAndMakeVisible(object);

        setOpaque(false);
        object.setOpaque(false);
    }


private:
    MoveableObject object;
};

What platform? Which Juce version?
What is the underlying object? A window?

I’m on Windows 10, using Juce 5. (I’m trying to upgrade to Juce 6 right now, so will have more feedback there).

The underlying object is a window. Is there a way of retrieving that so I can set it to setOpaque(false)?

setOpaque is false by default, you don’t have to set it. Because I don’t have access to you whole code, I don’t see what exactly you are doing, I guess if you a using a DocumentWindow with no other modifications, normally is filled with a background colour and should be repainted correctly.
I suggest updating JUCE first. If this doesn’t help, maybe post the whole example.

OK, upgrading to Juce 6 has fixed the problem. I guess that’s all there was to it!