Elaboration on ComponentBoundsConstrainer functions for restricting drag area


#1

Hi all,

I’ve been reading through the forums with no luck. I am attempting to restrict a component’s draggable-area and, frankly, I’m confused by the functions within the ComponentBoundsConstrainer class.

Within my custom component class I am using a ComponentDragger and ComponentBoundsConstrainer, similar to the demo app’s draggable classes.

Thanks for any help!


#2

Can you be more specific about what you’re trying to do? Here’s a really simple example of a Component that uses a ComponentDragger and ComponentBoundsConstrainer to ensure that it can’t be dragged offscreen:

class MainContentComponent   : public Component
{
public:
    //==============================================================================
    MainContentComponent()
    {
        addAndMakeVisible (comp);
        setSize (600, 400);
    }
    ~MainContentComponent() {}

    void paint (Graphics&) override    {}
    void resized() override            { comp.centreWithSize (200, 200); }

private:
    //==============================================================================
    struct CustomComp   : public Component
    {
        CustomComp()                                     { constrainer.setMinimumOnscreenAmounts (200, 200, 200, 200); }
        
        void paint (Graphics& g) override                { g.fillAll (Colours::hotpink); }
        
        void mouseDown (const MouseEvent& e) override    { dragger.startDraggingComponent (this, e); }
        void mouseDrag (const MouseEvent& e) override    { dragger.dragComponent (this, e, &constrainer); }
        
        ComponentDragger dragger;
        ComponentBoundsConstrainer constrainer;
    };
    
    CustomComp comp;
    
    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

#3

@ed95, thanks for the response. Apologies on the delay, had to take some time off from this project.

I’m clear on what your code does - I have a similar implementation going on.

To elaborate on what I’m doing:

I have two Components on screen. One is large and takes up most of the window. The second is smaller, draggable and has within its class, a ComponentDragger and a ComponentBoundsConstrainer. I am constraining the dragging bounds of the smaller component to the bounds of the larger component, which works fine. But the larger component gets resized at some point and its bounds change. I have been unable to update those bounds on the draggable object. Does that make sense?


#4

I guess what I’m really looking for is elaboration on the ComponentBoundsConstrainer function checkBounds - this seems like the function I’m looking for but the parameter descriptions are confusing me.


#5

checkBounds() can be used to constrain a given Rectangle to some limits. You’ll probably want to do something like this in your smaller component that contains the constrainer (this will constrain the smaller component to its parents bounds and ensure that it can’t be dragged out of its parent):

void parentSizeChanged() override
{
    auto newBounds = getBoundsInParent();
    
    constrainer.checkBounds (newBounds, getBoundsInParent(),
                             getParentComponent()->getLocalBounds(),
                             false, false, false, false);
    setBounds (newBounds);
    
    constrainer.setMinimumOnscreenAmounts (getHeight(), getWidth(), getHeight(), getWidth());
}

The first argument of checkBounds() is a reference to a Rectangle that will be constrained, the second argument is the current bounds of the component and the third is a Rectangle to which the component should be constrained. After the call to checkBounds() the first Rectangle will have been constrained to the limits so you should set the bounds of your component to this.