Deriving parameter value from Editor Child position


#1

Hi everyone,

Apologies if the answer is obvious, my C++ skills aren't the best one ever but I'm sure you're going to be able to help me strengthen them :D

I am trying to make a VST plugin.

I have a component "Graphique" which draws a curve. It contains itself a draggable "handle", which controls the shape of the curve (think : photoshop curves). See the enclosed picture.

Depending on the position of this handle in the "Graphique" component, I am willing to control a parameter which I will use in the Processor. But I can't seem to understand clearly what is the "standard" way to do this.

Here is my code for the handle :


class Poignee    : public Component
{
public:
    Poignee()
    {
        setSize(10, 10);
    }
    ~Poignee()
    {
    }
    void paint (Graphics& g)
    {
        Rectangle<float> area(getLocalBounds().toFloat());
        g.setColour(Colours::darkblue);
        g.fillEllipse(area);
    }
    void resized()
    {
        constrainer.setMinimumOnscreenAmounts(getHeight(), getWidth(), getHeight(), getWidth());
    }
    void Poignee::mouseDown(const MouseEvent& e) override
    {
        // Prepares our dragger to drag this Component
        dragger.startDraggingComponent(this, e);
    }
    void Poignee::mouseDrag(const MouseEvent& e) override
    {
        // Moves this Component according to the mouse drag event and applies our constraints to it
        dragger.dragComponent(this, e, &constrainer);
    }
    void Poignee::mouseUp(const MouseEvent& e) override
    {
    }
private:
    ComponentBoundsConstrainer constrainer;
    ComponentDragger dragger;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Poignee)
};

Here is my code for the Graphique component which contains the handle :


class Graphique    : public Component, private Timer
{
public:
    Graphique()
    {
        setSize(300, 300);
        addAndMakeVisible(maPoignee); // adding the handle
        maPoignee.addMouseListener(this, false);
        maPoignee.setCentrePosition(150, 150);

        startTimerHz(60); // timer to repaint()
    }
    ~Graphique()
    {
    }
    void paint (Graphics& g)
    {
        g.fillAll(Colours::white);   // clear the background
        g.setColour(Colours::black);

        myPath.startNewSubPath(0, 300);
        myPath.lineTo(maPoignee.getX()+5, maPoignee.getY()+5);
        myPath.lineTo(300, 0);

        g.strokePath(myPath, PathStrokeType(2.0f));
    }
    void resized()
    {
    }
    void timerCallback() override
    {        
        myPath.clear();
        repaint();
    }

private:
    Path myPath;
    Poignee maPoignee;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Graphique)
};

#endif  // GRAPHIQUE_H_INCLUDED

And my Editor is so far just doing "addAndMakeVisible()" for the Graphique instance.

So, yeah, I have seen many things about the listeners, about the possibility to use Values, and also about the AudioParameters option, but I am really confused about all of this :)

I have been thinking of using a Value. When the Graphique drag callback is sending information, I would update this value (like, myValue = myHandle.getX() ). But after, I am not sure how to access it from the Processor.

If anyone had some pointers (no pun intended) it would be much appreciated.

All the best,

A.


#2

Okay so I've been working on that and I came up with a working object-oriented solution, partly thanks to this topic :

http://www.juce.com/forum/topic/how-make-parent-component-listener-its-children

However, based on what I read on the forum, it seems to me that there are some "Juce" solutions, which may be more adapted/ faster to implement.

Basically, I moved the timer for repainting in the Editor component. In the callback, I am getting the handle's position parameters through specific get methods I implemented in my Graphique component. (just to clarify, graphique would be the French for Graph or Plot, in case the name is misleading).

After, I am using the method explained in the juce tutorial (http://www.juce.com/doc/tutorial_code_basic_plugin) to pass that value to the processor, thanks to a public attribute of the processor.

Is it a decent solution ? Can I make it better ? more JUCE-compliant maybe ?

Thanks a lot by advance,

A.