Is it possible to write C++ functions that include Juce paint() method statements?

Hi everybody. I can write simple C++ functions that are called from within the paint() method code block. But… what if your function must contain exclusive paint statements? - I mean, those statements starting with g. ? You can certainly not define a function inside paint(). So, what is the solution? Is there a way to do this? Thank you (!)

Maybe I’m misunderstanding the question but you can just pass g as a reference to the functions like so…

void paintSomething (Graphics& g)
{
    ...
}

void paintSomethingElse (Graphics& g)
{
    ...
}


void paint (Graphics& g)
{
    paintSomething (g);
    paintSomethingElse (g);
}

Also if you do want to define functions inside the paint method…

 void paint (Graphics& g)
{
    auto paintSomething [&]()
    {
        ...
    };

    auto paintSomethingElse [&]()
    {
        ...
    };

    paintSomething();
    paintSomethingElse();
}
1 Like

The paint is a so called callback, so you define what should happen, if the OS needs to paint the component’s content.
If you want to trigger a paint (i.e. letting the OS know, that it needs to paint), you do so by calling repaint().

If you want the paint to end up somewhere else, you can either use

auto image = component.createSnapshot();

or you can call methods to paint on a background image:

Image image (Image::ARGB, 600, 400, true);
Graphics g (image);
g.fillAll (Colours::green);

But you cannot paint directly on the screen, the OS will decide, when it wants to call paint.

Hello Anthony Nicholls,

thank you for your valuable answer (!) You certainly understood my question. I will try out your suggestions.

By the way, I am developing an app which takes advantage of a 10-point touch display. The idea is to play musical instruments by way of playing two hands and ten fingers on a large touch screen monitor. What type of apps do you develop?

Greetings from Germany,

Hugo

Hello Daniel,

thank you for your valuable answer (!)

By the way, I am developing an app which takes advantage of a 10-point touch display. The idea is to play musical instruments by way of playing two hands and ten fingers on a large touch screen monitor. What type of apps do you develop?

Greetings from Germany,

Hugo

If you click on a users icon, you get often a link this user identifies themselves with. I don’t want to spam other readers with my personal history.

But be invited to some discord chats, where people are sharing their personal stories and give each other help, quite juce-relevant even though not exclusively:

discord: theAudioProgrammer and discord: JUCE

Greetings to my home country :slight_smile:

1 Like

Hello, was just trying to implement a custom function outside the Void::paint and call it (custom function) inside. It’s not working.
What I’m trying to do is to apply loops over multiple drawings made, without creating multiple components for each drawing. I’m new to Juce and C++, learning thru creative coding (Javascript tutorials but applying the concepts in Juce ).

How did you try to implement it? How exactly it isn’t working?

I’ve tried starting initialising the function like this:
void MainComponent::myPaint (Graphics &g) but then I get an error telling me that function definition are not allowed. I do not know where I am mistaken.

By looking at this image attached here(from the tutorial) there is a function with passing attributes where all the drawings are made(“function bubble”) , then in the main function above (“function Draw”) the bubble has been called 200 times (loop) using a random number generator to place the xy coordinates. I’m wondering if this is possible without creating 200 components.

Is there a reason you couldn’t just do that code in the paint() method?

Something like :

void MainComponent::paint (juce::Graphics& g)
{
    auto& rng = juce::Random::getSystemRandom();
    g.fillAll(juce::Colours::black);
    g.setColour(juce::Colours::white);
    for (int i = 0; i < 200; ++i)
    {
        int x = rng.nextInt(juce::Range<int>(100, 700));
        int y = rng.nextInt(juce::Range<int>(100, 500));
        int size = rng.nextInt(juce::Range<int>(1,25));
        g.drawEllipse(x, y, size, size, 1.0f);
    }
}

Of course you can also separate that into a method or function :

void MainComponent::paintBubbles(juce::Graphics& g)
{
    auto& rng = juce::Random::getSystemRandom();
    g.saveState(); // in case we want to keep the original Graphics state
    g.setColour(juce::Colours::white);
    for (int i = 0; i < 200; ++i)
    {
        int x = rng.nextInt(juce::Range<int>(100, 700));
        int y = rng.nextInt(juce::Range<int>(100, 500));
        int size = rng.nextInt(juce::Range<int>(1, 25));
        g.drawEllipse(x, y, size, size, 1.0f);
    }
    g.restoreState(); // restore the Graphics state before returning
}

void MainComponent::paint (juce::Graphics& g)
{
    g.fillAll(juce::Colours::black);
    paintBubbles(g);
}

Note that in that case the paintBubbles method also has to be declared in the MainComponent class.

1 Like

Thanks man. Really appreciate, learned something new. I thought that by setting a random value to the xy coordinates, the loop will paint 200 times in the same position, forgetting that the loop is re-iterating and by that generating new coordinates numbers.