Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to work with leaf nodes? #50

Open
yawor opened this issue Sep 3, 2019 · 3 comments
Open

How to work with leaf nodes? #50

yawor opened this issue Sep 3, 2019 · 3 comments

Comments

@yawor
Copy link
Contributor

yawor commented Sep 3, 2019

Hi,

I've been wondering how to work with leaf nodes. I have following code:

use stretch::Stretch;
use stretch::style::{Style, Dimension};
use stretch::geometry::Size;
use stretch::number::Number;

fn main() {
    let mut stretch = Stretch::new();

    let leaf1 = stretch.new_leaf(Style::default(), Box::new(|_| {
        Ok(Size {
            width: 75.0,
            height: 30.0,
        })
    })).unwrap();

    let node1 = stretch.new_node(Style {
        flex_grow: 1.0,
        ..Default::default()
    }, vec![leaf1]).unwrap();

    let leaf2 = stretch.new_leaf(Style::default(), Box::new(|_| {
        Ok(Size {
            width: 75.0,
            height: 30.0,
        })
    })).unwrap();

    let node2 = stretch.new_node(Style {
        flex_grow: 1.0,
        ..Default::default()
    }, vec![leaf2]).unwrap();

    let root = stretch.new_node(Style {
        size: Size {
            width: Dimension::Percent(1.0),
            height: Dimension::Percent(1.0),
        },
        ..Default::default()
    }, vec![node1, node2]).unwrap();

    stretch.compute_layout(root, Size {
        width: Number::Defined(100.0),
        height: Number::Defined(50.0),
    }).unwrap();

    println!("root:  {:?}", stretch.layout(root).unwrap());
    println!("node1: {:?}", stretch.layout(node1).unwrap());
    println!("leaf1: {:?}", stretch.layout(leaf1).unwrap());
    println!("node2: {:?}", stretch.layout(node2).unwrap());
    println!("leaf2: {:?}", stretch.layout(leaf2).unwrap());
}

which results in following output:

root:  Layout { order: 0, size: Size { width: 100.0, height: 50.0 }, location: Point { x: 0.0, y: 0.0 } }
node1: Layout { order: 0, size: Size { width: 75.0, height: 50.0 }, location: Point { x: 0.0, y: 0.0 } }
leaf1: Layout { order: 0, size: Size { width: 75.0, height: 50.0 }, location: Point { x: 0.0, y: 0.0 } }
node2: Layout { order: 1, size: Size { width: 75.0, height: 50.0 }, location: Point { x: 75.0, y: 0.0 } }
leaf2: Layout { order: 0, size: Size { width: 75.0, height: 50.0 }, location: Point { x: 0.0, y: 0.0 } }

I'm scratching my head here. Why the sum of widths of node1 and node2 are greater than the number passed to compute_layout?
If I understand this correctly, leaf nodes should represent a content inside a flexbox container (which is represented by a normal node). The leaf requests some size, which is returned by the MeasureFunc passed to the leaf.
Why node1 and node2 grow beyond the size of the root? Shouldn't they shrink to 50 points each? Should the leaf nodes shrink too?
Am I misunderstanding something?
Would the overflow property fix this if it were implemented?

I also don't understand the meaning of the Size argument which is passed into the MeasureFunc. It's not explained in the documentation in any way. In above program, if I print the argument of the MeasureFunc I see it's called multiple times (which is understandable - the layout engine probably does multiple passes), but the width and height properties make no sense to me. The width is always Undefined.

@msiglreith
Copy link
Contributor

Hey!
I'm not fully into the guts of the flexbox algorithm but the argument of the measure functions indicates a constraint IIRC. The size of the item is then on the user to decide. As far as I know nothing prohibits nodes from escaping their container, at least I have seen this behavior on yoga as well.

Beside that the lib author probably has more insight into this!

@TheNeikos
Copy link

I encounter a similar issue, where I have a setup like this:

| <content> <flexible> <content> |

and the flexible part can grow to a very large size. It's measuring function tries to respect that it may not have enough space to fit, but it never actually gets the bounds as they are being given as 'undefined'. This means that it always returns its maximum width, pushing off the right content into oblivion. This makes it very inconvenient to use, as it IMO throws out the idea behind Flexbox (which is to dynamically use existing space, and not 'make up' new space by pushing items off.)

@nemosupremo
Copy link

nemosupremo commented Jan 7, 2021

I am also hitting this issue - are there any workarounds?

Edit: Returning 0/0 if the constraints are undefined seems to work.

Edit: Actually I put my node tree in Chrome, and it seems the behavior is the same.

Edit: Looking at what Chrome does, it looks like the overflow property is what is needed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants