FlexItem with dynamic width


#1

I have a resizable Component with 3 children (also extensions of Component).
When applying a FlexBox layout i would like that the 3 children do adjust their widths to the current width of the container (each 33%). Can this be done? When defining the 3 FlexItem objects i either define a fixed width which stays the same or i do not define a size then the item has zero size and is not visible.

With StretchableLayoutManager this would be possible but what i’ve read using that class is not recommended to use anymore. So how to solve that?


#2

That sounds like a trivial thing for flexbox to handle, if it’s not working then you’ve probably just done something silly… Maybe play with the flexbox example to figure out the correct settings.


#3

Hi there,
Here’s a boilerplate “Component Group” class that I use to stack controls inside an area using flexbox.
It started from a juce talk about juce UI implementation (don’t remember if it was this year or last year - but it’s on youtube).
It does exactly what you mean to do.
PS: there is also a “GroupComponent” class in Juce, that I admit I never studied in depth…also that might be useful if it uses flexbox JUCE API page

   #pragma once

class ControlGroupPanel    : public Component
{

public:
ControlGroupPanel(const String & name):
Component(name){};

~ControlGroupPanel(){};

void addControl(Component* control){
  controls_.add(control);
  addAndMakeVisible(control);
}

void paint (Graphics&) override{
  // omitted: draw outline & name
}


void resized() override{
  Rectangle<float> r = getLocalBounds().toFloat();

  bool isPortrait = r.getHeight()>r.getWidth();
  
  float reduce = isPortrait ? r.getWidth()*0.05f : r.getHeight()*0.05f;
  r.reduce(reduce,reduce);

  FlexBox masterBox;
  masterBox.flexDirection = isPortrait?FlexBox::Direction::column:FlexBox::Direction::row;
  masterBox.alignItems = FlexBox::AlignItems::stretch;
  masterBox.alignContent = FlexBox::AlignContent::stretch;
  masterBox.flexWrap= FlexBox::Wrap::noWrap;
  masterBox.justifyContent = FlexBox::JustifyContent::center ;

  for(int i = 0; i < controls_.size();i++){
    masterBox.items.add (FlexItem (1, 1).withFlex(1));
    auto& flexItem = masterBox.items.getReference (masterBox.items.size() - 1);
    flexItem.associatedComponent = controls_[i];
  }
  masterBox.performLayout (r);

}


private:
Array<Component*> controls_; // it's not owned since my parent will create the components and own them...

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ControlGroupPanel)
};

Nested FlexBox items?
#4

Thank you very much, fefanto!
I will definitely have a look at your solution, which looks promising :slight_smile: