FlexBox problem with negative margins (bug?)

I just spend 4 hours of debugging this, and finally found the problem :face_with_spiral_eyes:

In my layout I use negative margins in a flex box, to overdraw some GUI elements, which is perfectly working in all my plugins.

But after I changed a margin to “-2” the layout fails.

The reasons for this is:

static bool isAuto (Coord value) noexcept { return value == FlexItem::autoValue; }

evaluate in resolveAutoMarginsOnCrossAxis() falsely to true, because a negative margin is interpreted as auto.

static const int autoValue = -2;

A quick fix is to use other “magic” numbers, like the highest possible integer which can be a float, something like “-1000002”, but I guess its better not to rely on magic numbers especially in coordinates which are also stored as float values, which tend to be “floating”.

As I understand the css box model, margins are allowed to be negative. Even if the behaviour in juce is undefined, the result of a calculation of coordinates should maybe result in a “wrong” coordinate, but not how the coordinate is interpreted.

Could, at least in the first step, higher magic numbers can be used, or better add auto (and also notAssigned) attributes to margin?

2 Likes

There’s a few places in the code base where some magic number like -1 or -2 is used as an “auto” value.

It’d be really neat to have something similar to std::optional but it’s juce::Auto so the value can be represented separately to whether or not it should use an “auto” default.

1 Like

Does juce::Optional not fit the bill? This could be used over the mentioned magic numbers.

juce::Optional would probably get the job done, yeah. IMO Auto and Optional are two different concepts but it would maybe be a little overkill to add an entirely new type.

I think I see what you mean; a variable being “optional” is a cryptic way of indicating “auto”.

On the other hand, optional is a perfect class for holding a value that may be left unspecified, and it’s a small step from “unspecified” → “without a constrained value” → “determined automatically”.

FlexItem::autoValue could also become an alias for a default-constructed such optional that doesn’t hold a value, so that semantic of existing code is preserved.

1 Like