Introduction
In this tutorial, I will explain how to create a draggable component using ComponentDragger and ComponentBoundsConstrainer classes. As shown below, the blue rectangle can be dragged inside the grey rectangle.
The source code is available from the repository below:
Prerequisites
Create a project named DraggableComponent.
Create a new header file named GreyRect.
Add the following code to GreyRect.h
#pragma once
#include <JuceHeader.h>
class GreyRect : public juce::Component
{
public:
GreyRect()
{
addAndMakeVisible (blueRect);
};
void paint (juce::Graphics& g) override
{
auto grey = juce::Colour::fromFloatRGBA (0.28f, 0.28f, 0.28f, 1.0f);
g.fillAll (grey.withAlpha (0.1f));
g.setColour (grey);
g.drawRect (getLocalBounds(), 2);
}
void resized () override
{
blueRect.setBounds (getLocalBounds().withSizeKeepingCentre (40, 40));
}
private:
struct DraggableComp : public juce::Component
{
void paint (juce::Graphics& g) override
{
auto bounds = getLocalBounds().reduced (1);
auto blue = juce::Colour::fromFloatRGBA (0.42f, 0.83f, 1.0f, 1.0f);
g.setColour (blue.withAlpha (0.2f));
g.fillRect (bounds);
g.setColour (blue);
g.drawRect (bounds, 2);
}
};
DraggableComp blueRect;
};
In MainComponent.h, include this header file and create an object of GreyRect class.
#include "GreyRect.h"
class MainComponent : public juce::Component
{
・・・
private:
GreyRect greyRect;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
Add the following code in MainComponent.cpp and build this project.
MainComponent::MainComponent()
{
setSize (600, 400);
addAndMakeVisible (greyRect);
}
void MainComponent::paint (juce::Graphics& g)
{
auto black = juce::Colour::fromFloatRGBA (0.08f, 0.08f, 0.08f, 1.0f);
g.fillAll (black);
}
void MainComponent::resized()
{
greyRect.setBounds (getLocalBounds().withSizeKeepingCentre (400, 250));
}
As shown below, a gray rectangle and a blue rectangle are drawn, and the blue one cannot be dragged yet.
ComponentDragger
In this chapter, we will make the blue rectangle draggable.
Creating the object
Create an object of ComponentDragger class in DraggableComp struct.
struct DraggableComp : public juce::Component
{
juce::ComponentDragger dragger;
・・・
};
startDraggingComponent()
In mouseDown() callback, call startDraggingComponent() to prepare for dragging.
・・・
struct DraggableComp : public juce::Component
{
・・・
void mouseDown (const juce::MouseEvent& event) override
{
dragger.startDraggingComponent (this, event);
}
};
dragComponent()
In mouseDrag() callback, call dragComponent() to move the component.
struct DraggableComp : public juce::Component
{
・・・
void mouseDrag (const juce::MouseEvent& event) override
{
dragger.dragComponent (this, event, nullptr);
}
};
Building
As shown below, you can drag the blue rectangle.
However, you would be able to drag this to outside the border of the gray rectangle.
ComponentBoundsConstrainer
In this chapter, we will limit the blue rectangle's position and keep it on-screen.
Creating the object
Create an object of ComponentBoundsConstrainer class in DraggableComp struct, and pass this object to dragComponent().
struct DraggableComp : public juce::Component
{
juce::ComponentDragger dragger;
juce::ComponentBoundsConstrainer constrainer;
・・・
void mouseDrag (const juce::MouseEvent& event) override
{
dragger.dragComponent (this, event, &constrainer);
}
};
setMinimumOnscreenAmounts()
In the constructor, call setMinimumOnscreenAmounts() to set the amount by which the blue rectangle is allowed to go off-screen.
struct DraggableComp : public juce::Component
{
juce::ComponentDragger dragger;
juce::ComponentBoundsConstrainer constrainer;
DraggableComp()
{
constrainer.setMinimumOnscreenAmounts (20, 20, 20, 20);
}
・・・
};
In this case, we will allow the blue rectangle to go off-screen up to half its length.
Therefore, by passing the length of the width of the blue rectangle to this function, we can restrict the position to within the gray rectangle.
・・・
DraggableComp()
{
constrainer.setMinimumOnscreenAmounts (40, 40, 40, 40);
}
・・・
Building
Summary
In this tutorial, I explained the following:
- how to use ComponentDragger class
- how to use ComponentBoundsConstrainer class
By applying these, you can create a filter plugin UI as shown below.