Correct Way to Resize with Constrained Aspect Ratio

Hey all,

I’d like to make my plugin window resizable, but always conform to a given aspect ratio, and I’m a little confused about the best way to do this.

I have a ComponentBoundsConstrainer member variable on my PluginEditor class, and it seems like I should be able to do this:

    m_constrainer.setSizeLimits(512, 512 / ratio, 4096, 4096 / ratio);

    setResizable(true, true);

But this doesn’t seem to work. So my second approach was to use my own ResizableCornerComponent:

addAndMakeVisible(m_resizableCorner = new ResizableCornerComponent(this, &m_constrainer));

This seems to have done the trick, but I’m not sure exactly how it differs from what I was trying to do beforehand. What is the PluginEditor’s setConstrainer or attachConstrainer method supposed to do?

It also feels wasteful to me to define my own ResizableCornerComponent when the AudioProcessorEditor class has it’s own public ScopedPointer<ResizableCornerComponent> member. That makes me think the ResizableCornerComponent should have a public method which allows me to set a constrainer?

Lastly, and this is a bit of a tangent, why does the AudioProcessorEditor class define its resizable corner member with a ScopedPointer<ResizableCornerComponent> m_corner; where in most other places it seems like the suggestion would be to just use a stack allocated member variable: ResizableCornerComponent m_corner;?

Thank you!

1 Like

Bump? :slight_smile:

Probably this is not going to fully answer your question, but that’s what I do In the editor constructor to fix the aspect ratio, and it seems to be working:

double ratio = 4.0/3.0;
setResizeLimits(400, 400/ratio, 1200, 1200/ratio);

Aha! @fefanto that works great, and I feel much more comfortable with that approach than either of the ones I mentioned above. Thank you.

I think the only real outstanding question for me is the difference between using ScopedPointer<MyComponent> m; vs MyComponent m; and how to decide which approach to use for a given scenario. But that is definitely tangential to the point of the thread.

My opinion on the “tangential topic” is this. Hope some more experienced c++ dev steps in :grin:

I favour stack allocation for my dsp chain objects i.e. Things that get called in the audio thread (obviously excluding large buffers)
For Everything else I favour heap allocation via scoped pointer.

@ncthom Your constrainer approach would work in a standalone app. However, for plug-ins you need to use the provided constrainer as this will have special hooks into the DAW which itself will need to know the types of constraints. Also note, as this requires some host support, not all DAWs will work correctly with all types of constraints. So you should test your plug-in rigorously.

In your specific case with MyComponent, I tend to always go for stack allocation, unless 1) sizeof (MyComponent) is really super-duper large or 2) it’s simply not possible because you are using a) some sort of polymorphism (MyComponent is your base-class) or b) you want to forward declare MyComponent and your actual declaration of MyComponent is somewhere else (like when using Pimpls etc.).

@fabian thank you, that’s very helpful!

However, for plug-ins you need to use the provided constrainer as this will have special hooks into the DAW which itself will need to know the types of constraints.

That part seems like an important candidate for the online documentation.