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


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

// In your constructor, you should add any child components, and
// initialise any special settings that your component needs.



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

    g.drawRoundedRectangle (area.toFloat(), 5.0f, 3.0f);
    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);


ComponentBoundsConstrainer constrainer;
ComponentDragger dragger;





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?


Yes encapsulate seem’s to be the good way.


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)


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


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.


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


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.