Constrainer left and right limitations, what I don't understand?


#1

Hi, I use animationDemo exemple to help me in the making of “ADSR/envelope” class. I hope limit the left and right drag of my “anchors” component (class Hook), but the constrainer limits don’t make the job ! What can I do ?

class Hook    : public Component, public ChangeBroadcaster

{
public:
Hook()
{
// In your constructor, you should add any child components, and
// initialise any special settings that your component needs.

}

~Hook()
{
}

void paint (Graphics& g) override
{
    auto area = getLocalBounds();
    
    g.setColour (Colour(0xf0ffffff));

    g.drawRoundedRectangle (area.toFloat(), 5.0f, 3.0f);
    g.setColour(Colour(0x20303030));
    g.fillRoundedRectangle(area.toFloat(), 5.0f);

}
void setConstrainer()
{
    
}
void resized() override
{
    // Just set the limits of our constrainer so that we don't drag ourselves off the screen
    constrainer.setMinimumOnscreenAmounts (getHeight(), getWidth(),
                                           getHeight(), getWidth());
}
void setLimit ( int left, int right )
{
    constrainer.setMinimumOnscreenAmounts(0, left, getHeight(), right);
   // constrainer.setSizeLimits(left, 0, right, getHeight());
}
void mouseDown (const MouseEvent& e) override
{
    // Prepares our dragger to drag this Component
    dragger.startDraggingComponent (this, e);
}

void 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);
            sendChangeMessage();
}

private:

ComponentBoundsConstrainer constrainer;
ComponentDragger dragger;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Hook)

};

30


#2

I wanna limit an anchor to never go outside the next one like in this picture.
Have to I encapsuler the component in an other one to fix it limits? Is it the only solution?
33


#3

Yes encapsulate seem’s to be the good way.
10


#4

Couldn’t you just loop through the points and compare mouse x to all points less then dragging point x?

If the mouse is less then the bottom range, hold the x at minimum. (Could also work for max)


#5

You’re right it may be a better way. I don’t know ?


#6

I’m just about to write something similar.
How about adding an updateConstrainer() to your hook, if the hook knows the hook before and the hook after (by calling the owner OwnedArray<Hook>& getHooks(), it could update from the neighbours bounds:

void updateHooks()
{
    const auto& hooks = owner.getHooks();
    const int index = hooks.indexOf (this);

    const int minX = index > 0 ? hooks.getReference (index - 1)->getRight() + 1 : 0;
    const int maxX = index < hooks.getSize() - 1 ? hooks.getReference (index + 1)->getLeft() - 1 : getParentComponent()->getWidth();
    dragger.setBoundsForComponent (this, { minX, maxX-minX, 0, getParentComponent()->getHeight() }, false, false, false, false); 
}

You just need one call from Hook::mouseUp() to it’s neighbours, instead of traversing each movement.


#7

Thanks for your answers.
I join you what I have made with the encapsulate “solution”
ADSR.zip (2,8 Mo)


#8

This really should be a standard widget in JUCE… where we can link it to a parameter and create an OwnedArray of the widgets ordered from left to right of the UI.

Rail