Resizable component with minimum size


#1

While trying to create a component with a minimum size I came up with this:

MainContentComponent::MainContentComponent()
{
    setSize (600, 400);
    slider = new Slider();
    addAndMakeVisible(slider);
    slider->setSliderStyle(juce::Slider::LinearHorizontal);
    slider->setTextBoxStyle(juce::Slider::NoTextBox, true, 110, 110);
    slider->setSize(200, 100);
    slider->setCentreRelative(.5, .5);
    myLayout.setItemLayout (0,          // for item 0
                            50, 300,    // must be between 50 and 100 pixels in size
                            -0.9);      // and its preferred size is 60% of the total available space
    setBounds(0, 0, 300, 300);
    resized();
}

MainContentComponent::~MainContentComponent()
{
    delete slider;
}

void MainContentComponent::resized()
{
    Component* comps[] = { slider };
    myLayout.layOutComponents (comps, 1,
                               50, 50, getWidth()-100, getHeight()-100,
                               false,
                               true);
    int w = getWidth();
    int h = getHeight();
    if (w < 500) w = 500;
    if (h < 500) h = 500;
    if (w != getWidth() || h != getHeight())
        setSize(w, h);
}

A couple of questions:

  • On Mac OS X Yosemite it seems the resizing is not at all fluent. When resizing the window a bit bigger, coming from the minimum size, there is a "snap"-effect that is not desired. Any idea where this comes from?
  • The size on the left of the slider is not the same as the size on the right of the slider? I would expect it to be perfectly symmetrical since in the layOutComponents I ask it to center from the borders. I suspect there is some border for the scroll bars taken into account in the window of the application.
    This is a GUI Application created in the Injuicer, with just one changes: added  setResizable(true,false); on line 73 of Main.cpp
  • Is there another way to do this or overriding the resized() call be the recommended way to do this?

Thanks for any help. Also pointers to documentation of course. In case it wasn't clear already: I am a newbie :)


#2

I think you should be looking at this function:

http://www.juce.com/api/classResizableWindow.html#a6afa3b9ddf1cd9f7fa546692074dd781

 


#3

Not sure how this helps. I am creating a component, not a window. Are you suggesting I should set limits on the window that holds the component?

The window should ideally not be aware of any size limits of the component, but just take them into account via some resizing mechanism, as per my implementation.

Also I don't see how your comment answers any other questions I raised? 


#4

The most obvious problem with the code above is that it calls setSize inside its resize callback, which can get recursive, and is a bad idea.

It's the responsibility of the thing that's changing your component's size to make sure it chooses an appropriate size. Trying to force the size to something else while it's in the middle of being changed it is not wise.

(We may actually add an assertion to alert people when they try to do this)


#5

It’s the responsibility of the thing that’s changing your component’s size to make sure it chooses an appropriate size

Reading this answer, i am still wondering …

How can i actually control limits of the main content component, when resizing main app window with a mouse? From your answer, I understand this should be responsibility of the main app window. But who is controling main app window size when resizing? Sorry for bringing this old topic to life, solution might be obvious, but i still don’t get it :confused:


#6

ComponentBoundsConstrainer is the class you’re looking for, it will enforce size, position, and aspect ratio limitations

You can set a window’s constrainer first and then use setBoundsConstrained() when updating the window size


#7

Thx, i’ll check it out.