Using the following CSS, I can get the pictures result:
#main {
width: 200px;
height: 200px;
border: 1px solid black;
display: flex;
align-items: flex-end;
}
#main div {
width:50px;
height:50px;
}
https://www.w3schools.com/code/tryit.asp?filename=GVMGC4XFHAIX
However, doing the equivalent in JUCE, doesn’t give the expected result:
juce::FlexBox flex;
flex.alignItems = juce::FlexBox::AlignItems::flexEnd;
flex.items = {
juce::FlexItem{ b1 }.withWidth(50.f).withHeight(50.f),
juce::FlexItem{ b2 }.withWidth(50.f).withHeight(50.f)
};
auto bounds = getLocalBounds().withSizeKeepingCentre(200, 200);
flex.performLayout(bounds);
Am I missing something, or does juce::FlexBox not implement the align-items property properly?
Full Component to reproduce:
class MainComponent : public juce::Component
{
public:
MainComponent()
{
addAndMakeVisible(b1);
addAndMakeVisible(b2);
setSize (600, 400);
}
void paint (juce::Graphics& g) override
{
g.fillAll (findColour (juce::ResizableWindow::backgroundColourId));
auto bounds = getLocalBounds().withSizeKeepingCentre(200, 200);
g.setColour(juce::Colours::white);
g.drawRect(bounds);
}
void resized() override
{
juce::FlexBox flex;
flex.alignItems = juce::FlexBox::AlignItems::flexEnd;
flex.items = {
juce::FlexItem{ b1 }.withWidth(50.f).withHeight(50.f),
juce::FlexItem{ b2 }.withWidth(50.f).withHeight(50.f)
};
auto bounds = getLocalBounds().withSizeKeepingCentre(200, 200);
flex.performLayout(bounds);
}
private:
juce::TextButton b1, b2;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
what exactly is your problem? is it that the boxes dont look aligned correctly? if so, its because of the rectangle stroke. is that the issue?
Using CSS, the boxes are positioned at the bottom of the container as I would expect when using flex-end. However in JUCE, the boxes are positioned at the top.
Well I personally don’t use FlexBox but from the docs I can see you should set a “main axis” and you have not done so.
Direction
You’re trying to set at the end of an axis but you have not told your flexbox where the end is.
I think the specific one you’re looking for is
FlexBox::Direction::column
The default direction is Direction::row, the same as in CSS where the direction will be row if you don’t specify one.
align-items should change the way items are aligned on the cross-axis (so the Y axis, when the direction is row). In the CSS example, the items are positioned at the end of the cross-axis (bottom), whereas in JUCE, changing the alignment doesn’t appear to have any effect
MBO
October 21, 2021, 2:41pm
7
This will work as you need:
juce::FlexBox flex;
flex.items = {
juce::FlexItem { b1 }.withWidth (50.f).withHeight (50.f).withAlignSelf (juce::FlexItem::AlignSelf::flexEnd),
juce::FlexItem { b2 }.withWidth (50.f).withHeight (50.f).withAlignSelf (juce::FlexItem::AlignSelf::flexEnd)
};
auto bounds = getLocalBounds().withSizeKeepingCentre(200, 200);
flex.performLayout(bounds);
But I don’t know if it is correct behaviour.
I don’t really need the behaviour, I’m more concerned about juce::FlexBox using the alignment properly which it doesn’t current seem to.
reuk
October 21, 2021, 3:04pm
9
This looks like a bug. FlexItem::alignSelf is currently defaulting to stretch, whereas I think it should default to autoAlign. When I modify the default value of alignSelf, I see the expected result with the buttons in the bottom left corner of the container.
ImJimmi
October 23, 2021, 9:23pm
10
Ahh yeah, that seems to be it!
Adding withAlignSelf (juce::FlexItem::AlignSelf::autoAlign) to each item aligns them properly at the bottom of the parent.
ImJimmi
October 25, 2021, 3:08pm
11
Seems to have introduced another issue however… Changing the default to autoAlign seems to now ignore any specific height that’s set (using a row direction). I’ll try to find time to put together an example.
ImJimmi
October 27, 2021, 10:51am
12
Here’s an example showing how a FlexItem's height isn’t taken into account when it has autoAlign and the flex box’s align-items is stretch:
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: FlexItemHeightBug
dependencies: juce_core, juce_data_structures, juce_events, juce_graphics, juce_gui_basics
exporters: XCODE_MAC
moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1
type: Component
mainClass: MainComponent
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
#include <JuceHeader.h>
class MainComponent : public juce::Component
{
public:
MainComponent()
{
addAndMakeVisible (button);
setSize (600, 400);
}
void paint (juce::Graphics& g) override
{
g.fillAll (findColour (juce::ResizableWindow::backgroundColourId));
g.setColour (juce::Colours::white);
g.drawRect (getLocalBounds().withSizeKeepingCentre (200, 200));
}
void resized() override
{
juce::FlexBox flex;
flex.alignItems = juce::FlexBox::AlignItems::stretch;
flex.items = {
juce::FlexItem {button}
.withAlignSelf (juce::FlexItem::AlignSelf::autoAlign)
.withWidth (50.f)
.withHeight (50.f)
};
flex.performLayout (getLocalBounds().withSizeKeepingCentre (200, 200));
}
private:
juce::TextButton button;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
(This works as expected if the item’s alignSelf is also set to stretch).
Expected result using CSS:
https://jsfiddle.net/nak6obye/
reuk
October 28, 2021, 9:29am
13
The default value of alignSelf is fixed on develop now:
committed 03:19PM - 21 Oct 21 UTC
The newest issue you’ve raised looks a bit more involved to fix, so I’m still working on a solution to that.
1 Like
reuk
November 22, 2021, 12:40pm
14
I’ve just pushed some changes that should hopefully fix the additional alignment issues you were seeing:
committed 04:54PM - 27 Oct 21 UTC
Please try this out and let us know if you find any further problems.