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

[Merged by Bors] - Document how padding and margin behave with percentage values #7785

Closed
wants to merge 4 commits into from

Conversation

ickshonpe
Copy link
Contributor

Objective

Add a comment explaining that percentage padding is calculated based on the width of the parent node.

@ickshonpe ickshonpe changed the title Expanded the doc comment for the padding field of Style. Document padding's behaviour with percentage values Feb 22, 2023
@ickshonpe ickshonpe changed the title Document padding's behaviour with percentage values Comment explaining how padding behaves with percentage values Feb 22, 2023
@ickshonpe ickshonpe changed the title Comment explaining how padding behaves with percentage values Document how padding behaves with percentage values Feb 22, 2023
Copy link
Contributor

@nicoburns nicoburns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks good, but:

  • I think it would be good to explicitly write out that this applies to even top/bottom padding
  • It would be good to add the same note to margin and border

@ickshonpe ickshonpe changed the title Document how padding behaves with percentage values Document how padding and margin behave with percentage values Feb 22, 2023
@ickshonpe
Copy link
Contributor Author

ickshonpe commented Feb 22, 2023

I thought borders were implemented in Bevy and occupied space around a node but just weren't rendered, but that doesn't seem to be right like in this example:

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_startup_system(setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());
    let root = commands.spawn(NodeBundle {
        style: Style {
            flex_direction: FlexDirection::Column,
            flex_basis: Val::Percent(100.0),
            margin: UiRect::all(Val::Px(25.0)),
            flex_wrap: FlexWrap::Wrap,
            justify_content: JustifyContent::FlexStart,
            align_items: AlignItems::FlexStart,
            align_content: AlignContent::FlexStart,
            ..Default::default()
        },
        background_color: BackgroundColor(Color::BLACK),
        ..Default::default()
    }).id();

    let borders = [
        UiRect::all(Val::Auto),
        UiRect::all(Val::Px(0.)),
        UiRect::all(Val::Px(25.0)),
        UiRect::all(Val::Px(250.0)),
        UiRect::all(Val::Undefined),
        UiRect::all(Val::Percent(25.0)),
        UiRect::all(Val::Percent(100.0)),
        UiRect::all(Val::Percent(1000.0)),
        UiRect::left(Val::Px(25.0)),
        UiRect::right(Val::Px(25.0)),
        UiRect::top(Val::Px(25.0)),
        UiRect::bottom(Val::Px(25.0)),
        UiRect::left(Val::Percent(25.0)),
        UiRect::right(Val::Percent(25.0)),
        UiRect::top(Val::Percent(25.0)),
        UiRect::bottom(Val::Percent(25.0)),
        UiRect::left(Val::Percent(1000.0)),
        UiRect::vertical(Val::Percent(200.0)),
        UiRect::vertical(Val::Px(200.0)),
        UiRect::horizontal(Val::Px(200.0)),
        UiRect::vertical(Val::Percent(200.0)),
    ];

    for border in borders.into_iter().cycle().take(400) { 
        let b = commands.spawn(NodeBundle {
            style: Style {
                size: Size::all(Val::Px(50.)),
                border,
                margin: UiRect::all(Val::Px(5.)),
                ..Default::default()
            },
            background_color: BackgroundColor(Color::BLUE),
            ..Default::default()
        }).id();
        commands.entity(root).add_child(b);    
    }
}

Draws the squares in a regular grid pattern, even with all the different border values. Am I missing something?

@ickshonpe
Copy link
Contributor Author

oh this one is fine though:

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_startup_system(setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());
    let root = commands.spawn(NodeBundle {
        style: Style {
            border: UiRect::all(Val::Px(25.0)),
            align_self: AlignSelf::FlexStart,
            ..Default::default()
        },
        background_color: BackgroundColor(Color::BLACK),
        ..Default::default()
    }).id();
    
    let square = commands.spawn(NodeBundle {
        style: Style {
            size: Size::all(Val::Px(200.0)),
            border: UiRect::all(Val::Px(50.0)),
            ..Default::default()
        },
        background_color: BackgroundColor(Color::RED),
        ..Default::default()
    }).id();

    let inner = commands.spawn(NodeBundle {
        style: Style {
            size: Size::all(Val::Px(100.0)),
            ..Default::default()
        },
        background_color: BackgroundColor(Color::BLACK),
        ..Default::default()
    }).id();

    commands.entity(root).add_child(square);
    commands.entity(square).add_child(inner);
}

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Feb 23, 2023

Improved the examples a bit but they aren't great without the option to test them against a generated layout.
It would be nice to be able to generate layouts for tests without having to go through the flex_node_system machinery.

As for borders, I'm not sure I understand how borders work. I had thought borders followed mostly the same rules as margins, except for having no automatic determination and being drawn.

As the rendering isn't implemented, they aren't useful anyway at the moment, so should we just have a comment saying "not implemented yet, don't use"? Or even remove the field until the implementation is ready.

@nicoburns
Copy link
Contributor

Should we just have a comment saying "not implemented yet, don't use"? Or even remove the field until the implementation is ready.

IMO it ought to be removed entirely if borders aren't actually drawn. Looks like there's already an issue for actual border support #5924

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Feb 23, 2023

I could implement basic solid coloured border support myself just quickly, but I'm not quite sure where to get the border geometry.
Is it just that the node size is increased by the size of the border, and you just go inwards from each edge by the border value?

edit: oh. that wouldn't work with percentages though.

@nicoburns
Copy link
Contributor

Is it just that the node size is increased by the size of the border, and you just go inwards from each edge by the border value?

You go inwards from each edge by the border value (in CSS varies depending on the box-sizing property. We assume box-sizing: border-box which is basically what "everyone" on the web uses too (it's not the default for historical reasons but the vast majority of websites are using a CSS reset which sets border-box) See: https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing

Percentage borders are not a thing on web (they are a taffy/bevy proprietary extension). They are resolved against the computed width of the parent node by analogy with padding/margin.

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Feb 23, 2023

Ah, I think I understand borders after hacking out this implementation.

What I was missing is that the size of the node only needs to be expanded by the size of the border if there are constraints that prevent the layout algorithm from placing the border within the existing node boundary.

@alice-i-cecile alice-i-cecile added C-Docs An addition or correction to our documentation A-UI Graphical user interfaces, styles, layouts, and widgets labels Feb 23, 2023
@nicoburns
Copy link
Contributor

nicoburns commented Feb 23, 2023

What I was missing is that the size of the node only needs to be expanded by the size of the border if there are constraints that prevent the layout algorithm from placing the border within the existing node boundary.

I believe this is correct, but that even if it does "need" to be expanded, a node won't necessarily be expanded just to accommodate a border. It's also entirely possible that the border is just clipped. An example would a node with a fixed width which is smaller than the size needed to accommodate the border

EDIT: Nope. I tested this and it seems that nodes are always expanded to accommodate borders if necessary.

@ickshonpe ickshonpe mentioned this pull request Feb 23, 2023
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very helpful.

bors r+

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Feb 25, 2023
bors bot pushed a commit that referenced this pull request Feb 25, 2023
)

# Objective

Add a comment explaining that percentage padding is calculated based on the width of the parent node.
@bors bors bot changed the title Document how padding and margin behave with percentage values [Merged by Bors] - Document how padding and margin behave with percentage values Feb 25, 2023
@bors bors bot closed this Feb 25, 2023
Shfty pushed a commit to shfty-rust/bevy that referenced this pull request Mar 19, 2023
…vyengine#7785)

# Objective

Add a comment explaining that percentage padding is calculated based on the width of the parent node.
mockersf pushed a commit that referenced this pull request Jun 14, 2023
# Objective

Implement borders for UI nodes.

Relevant discussion: #7785
Related: #5924, #3991

<img width="283" alt="borders"
src="https://user-images.githubusercontent.com/27962798/220968899-7661d5ec-6f5b-4b0f-af29-bf9af02259b5.PNG">

## Solution

Add an extraction function to draw the borders.

---

Can only do one colour rectangular borders due to the limitations of the
Bevy UI renderer.

Maybe it can be combined with #3991 eventually to add curved border
support.

## Changelog
* Added a component `BorderColor`.
* Added the `extract_uinode_borders` system to the UI Render App.
* Added the UI example `borders`

---------

Co-authored-by: Nico Burns <nico@nicoburns.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Docs An addition or correction to our documentation S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants