Question about graphics / drawing


#1

Hello all.

I'm rather confused about the graphics class, drawing and the roles of the different classes.

I've successfully created a Path which the graphics within the paint function of a component draws using PathStroke as a multisegment line. However, when I update the nature of the line, I cannot clear what has been drawn. Therefore the new line is drawn over the top. I've tried creating an image, clearing the image each time the line is altered, but that doesn;t work either. I'm sure I just don't understand the rhyme of reason, but I cannot fathom whay you simply cannot clear what has been drawn by the graphics within paint and paint a new line.

Can anyone step me through this please?

 

Thank you.


#2

Is your Path a member variable? If so, you need to call clear() on that before adding your new line.


#3

Show code!

π


#4

@widdershins: My Path is indeed cleared!

@ Pi: It's all a bit mental as I've been moving it about, will try and clear it up for you. There's been lots of incarnations so far...

 


#include "EnvelopeLine.h"
EnvelopeLine::EnvelopeLine (int a, int b) :  thisWidth (a), thisHeight (b)
{
    imagePtr = new Image (Image::RGB, thisWidth, thisHeight, true);
}


void EnvelopeLine::paint (Graphics& g)
{
    g.setOpacity (0.0);
    g.fillAll (Colours::white);  
    g.setOpacity (1.0);
    //Image image (Image::RGB, thisWidth, thisHeight, true);
    //drawLineImage();
    g.drawImageAt(*imagePtr, 0, 0, false);
    
}
void EnvelopeLine::makeLine(OwnedArray<EnvelopePoint>& a)
{
    numPoints = a.size();
    makePath(a);
    drawLineImage();
    repaint();
}
void EnvelopeLine::makePath(OwnedArray<EnvelopePoint>& a)
{
    path.clear();
    path.startNewSubPath(0, a.getUnchecked (0)->getPosY());
    for (int i = 1; i < numPoints; ++i)
    {
        path.quadraticTo    (   0.0f, 
                                           0.0f, 
                                           a.getUnchecked (i)->getPosX(),
                                           a.getUnchecked (i)->getPosY()
                            );
    }
    
}
void EnvelopeLine::drawLineImage()
{
    //a.clear(Rectangle(0, 0, a.getWidth(), a.getHeight()), Colours::white);
    imagePtr->clear(imagePtr->getBounds());
    Graphics i (*imagePtr);
    i.setColour (Colours::darkgrey);
    i.strokePath (path, PathStrokeType (0.5f));
}
 


#5

Forget the Image altogether, you're overcomplicating:

void paint (Graphics& g)
{
    g.setColour (Colours::darkgrey);
    g.strokePath (path, 0.5f);
}

 


#6

Thank you Widdershins, but I don;t think you're understanding the problem. The issue is that when redrawing a new line, the old one remains, and wiping the component for a clear slate before I do so is the issue.


#7

You're totally misunderstanding how graphics is done nowadays - you never "clear" things, you just redraw everything on each paint call!


#8

Haha! Yes indeed as a beginner I probably think about it very much in an MSPaint kind of way. However, if the screen is redrawn every time, why does the follow code note redraw the screen with white ready for the next line to be drawn?

void EnvelopeLine::paint (Graphics& g)
{
    g.setOpacity (1.0);
    g.fillAll (Colours::white); 
    g.setColour(Colours::darkgrey);
    g.strokePath(path, PathStrokeType (0.5f));
    
}
void EnvelopeLine::makeLine(OwnedArray<EnvelopePoint>& a)
{
    numPoints = a.size();
    makePath(a);
    repaint();
}