Baseline support #317

Closed
woehrl01 wants to merge 33 commits from baseline-support into master
woehrl01 commented 2017-01-04 13:26:26 -08:00 (Migrated from github.com)

Added baseline support (see #132)

You have the ability for a custom baseline function (float(*YGBaselineFunc)(YGNodeRef node);) to return whatever baseline you want.

Added baseline support (see #132) You have the ability for a custom baseline function (```float(*YGBaselineFunc)(YGNodeRef node);```) to return whatever baseline you want.
woehrl01 commented 2017-01-04 13:50:57 -08:00 (Migrated from github.com)

Not sure if we should cache the baseline, as we get the baseline twice. First to get the maximum and second to position it.

I'm thinking about something like computedFlexBasisGeneration just named baselineCalculationGeneration and a cached value property.

Not sure if we should cache the baseline, as we get the baseline twice. First to get the maximum and second to position it. I'm thinking about something like ```computedFlexBasisGeneration``` just named ```baselineCalculationGeneration``` and a cached value property.
emilsjolander (Migrated from github.com) reviewed 2017-01-05 02:29:39 -08:00
emilsjolander (Migrated from github.com) left a comment

This is awesome! Thanks! I'll do a more thorough review later this week. Please run format.sh in the mean time.

This is awesome! Thanks! I'll do a more thorough review later this week. Please run format.sh in the mean time.
@@ -334,6 +335,14 @@ YGMeasureFunc YGNodeGetMeasureFunc(const YGNodeRef node) {
return node->measure;
emilsjolander (Migrated from github.com) commented 2017-01-05 02:25:21 -08:00

node->baseline = baselineFunc; is enough

`node->baseline = baselineFunc;` is enough
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
}
emilsjolander (Migrated from github.com) commented 2017-01-05 02:26:21 -08:00

uint32_t

uint32_t
emilsjolander (Migrated from github.com) commented 2017-01-05 02:26:32 -08:00

i++

i++
woehrl01 commented 2017-01-05 02:51:39 -08:00 (Migrated from github.com)

Please run format.sh in the mean time.

I'd love to do this, but the effort to create the environment to run this on windows, is currently too much work for me. As it seems I need a full linux runtime to execute this.

> Please run format.sh in the mean time. I'd love to do this, but the effort to create the environment to run this on windows, is currently too much work for me. As it seems I need a full linux runtime to execute this.
emilsjolander commented 2017-01-05 03:29:26 -08:00 (Migrated from github.com)

@woehrl01 having clang installed should be enough 👍 But that's fine, I can run it before merging. Could you try to adhere to the code style of the rest of the project though?

@woehrl01 having clang installed should be enough 👍 But that's fine, I can run it before merging. Could you try to adhere to the code style of the rest of the project though?
woehrl01 commented 2017-01-05 04:25:26 -08:00 (Migrated from github.com)

@emilsjolander clang to the rescue! 👍 strangely clang-format on windows doesn't allow wildcard. So I hope I haven't missed a file.

@emilsjolander clang to the rescue! 👍 strangely clang-format on windows doesn't allow wildcard. So I hope I haven't missed a file.
emilsjolander commented 2017-01-05 04:55:00 -08:00 (Migrated from github.com)

@woehrl01 That's not clang, most likely your shell is not doing the expansion.

@woehrl01 That's not clang, most likely your shell is not doing the expansion.
woehrl01 commented 2017-01-05 04:57:00 -08:00 (Migrated from github.com)

most likely your shell is not doing the expansion.

true 😄

> most likely your shell is not doing the expansion. true 😄
emilsjolander (Migrated from github.com) reviewed 2017-01-05 05:38:35 -08:00
emilsjolander (Migrated from github.com) left a comment

Please add some tests for column direction as well as row direction. Also please add tests for align-self usage.

Please add some tests for column direction as well as row direction. Also please add tests for align-self usage.
emilsjolander (Migrated from github.com) reviewed 2017-01-05 05:40:40 -08:00
@@ -2426,3 +2490,4 @@
!YGFloatIsUndefined(availableInnerCrossDim)) {
const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;
float crossDimLead = 0;
emilsjolander (Migrated from github.com) commented 2017-01-05 05:40:40 -08:00

performLayout check is not needed here as it is already checked in the containing if statement

`performLayout` check is not needed here as it is already checked in the containing if statement
emilsjolander (Migrated from github.com) reviewed 2017-01-05 05:43:58 -08:00
@@ -933,3 +946,4 @@
return align;
}
static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
emilsjolander (Migrated from github.com) commented 2017-01-05 05:43:58 -08:00

YGNodeBaseline

`YGNodeBaseline`
woehrl01 (Migrated from github.com) reviewed 2017-01-05 05:46:48 -08:00
@@ -2426,3 +2490,4 @@
!YGFloatIsUndefined(availableInnerCrossDim)) {
const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;
float crossDimLead = 0;
woehrl01 (Migrated from github.com) commented 2017-01-05 05:46:48 -08:00

isn't performlayout checked at line 2526 a little bit down below?

isn't performlayout checked at line 2526 a little bit down below?
emilsjolander (Migrated from github.com) reviewed 2017-01-05 07:36:10 -08:00
emilsjolander (Migrated from github.com) left a comment

YGAlignBaselineCustomTest.cpp -> YGBaselineFuncTest.cpp?

`YGAlignBaselineCustomTest.cpp` -> `YGBaselineFuncTest.cpp`?
emilsjolander (Migrated from github.com) reviewed 2017-01-05 07:37:25 -08:00
emilsjolander (Migrated from github.com) commented 2017-01-05 07:37:25 -08:00

please test with different widths on the two items as width is the axis being aligned here

please test with different widths on the two items as width is the axis being aligned here
emilsjolander (Migrated from github.com) reviewed 2017-01-05 07:40:38 -08:00
emilsjolander (Migrated from github.com) commented 2017-01-05 07:39:00 -08:00

indentation

indentation
emilsjolander (Migrated from github.com) commented 2017-01-05 07:39:07 -08:00

indendation

indendation
emilsjolander (Migrated from github.com) commented 2017-01-05 07:39:32 -08:00

please vary the widths as this is a column layout

please vary the widths as this is a column layout
emilsjolander (Migrated from github.com) commented 2017-01-05 07:40:24 -08:00

This whole file would probably make sense to have as part of the YGAlignItems.html + YGAlignSelf.html files which already exist

This whole file would probably make sense to have as part of the YGAlignItems.html + YGAlignSelf.html files which already exist
emilsjolander (Migrated from github.com) reviewed 2017-01-05 11:19:50 -08:00
@@ -929,7 +938,12 @@ static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node,
}
emilsjolander (Migrated from github.com) commented 2017-01-05 11:03:20 -08:00

const

const
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
emilsjolander (Migrated from github.com) commented 2017-01-05 11:06:20 -08:00

This will always be height as baseline is undefined for column flex direction. right? in that case I think it is better to be clear and use YGDimensionHeight instead of dim[crossAxis]

This will always be height as baseline is undefined for column flex direction. right? in that case I think it is better to be clear and use `YGDimensionHeight` instead of `dim[crossAxis]`
emilsjolander (Migrated from github.com) commented 2017-01-05 11:07:40 -08:00

Is there a good reason to allow undefined return value for baseline? I would prefer asserting and crashing as it would probably indicate a bug. What do you think?

Is there a good reason to allow undefined return value for baseline? I would prefer asserting and crashing as it would probably indicate a bug. What do you think?
emilsjolander (Migrated from github.com) commented 2017-01-05 11:11:39 -08:00

Why child->lineIndex > 0? I understand that it skips multiline children but i'm not sure why.

Why `child->lineIndex > 0`? I understand that it skips multiline children but i'm not sure why.
emilsjolander (Migrated from github.com) commented 2017-01-05 11:12:21 -08:00

same as above regarding dim[crossAxis]

same as above regarding `dim[crossAxis]`
emilsjolander (Migrated from github.com) commented 2017-01-05 11:14:02 -08:00

The baseline of a container is defined by its first baseline aligned child, but when there is no baseline aligned child then the container's baseline is defined by it's last child. This seems odd. Are you sure we have test cases covering edge cases here to make sure this is how it works on the web?

The baseline of a container is defined by its first baseline aligned child, but when there is no baseline aligned child then the container's baseline is defined by it's last child. This seems odd. Are you sure we have test cases covering edge cases here to make sure this is how it works on the web?
emilsjolander (Migrated from github.com) commented 2017-01-05 11:14:19 -08:00

same as above regarding pos[crossAxis]

same as above regarding `pos[crossAxis]`
@@ -966,6 +1014,24 @@ static inline bool YGNodeIsFlex(const YGNodeRef node) {
(YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0));
}
emilsjolander (Migrated from github.com) commented 2017-01-05 11:15:01 -08:00

nit: empty line above

nit: empty line above
emilsjolander (Migrated from github.com) commented 2017-01-05 11:19:23 -08:00

same as above. Don't reference crossAxis as it confuses the fact that baseline is only defined for row layouts

same as above. Don't reference `crossAxis` as it confuses the fact that baseline is only defined for row layouts
@@ -49,6 +49,7 @@ typedef YGSize (*YGMeasureFunc)(YGNodeRef node,
YGMeasureMode widthMode,
emilsjolander (Migrated from github.com) commented 2017-01-05 11:18:02 -08:00

nit: remove added empty lines

nit: remove added empty lines
woehrl01 (Migrated from github.com) reviewed 2017-01-05 11:25:14 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
woehrl01 (Migrated from github.com) commented 2017-01-05 11:25:14 -08:00

I'm not sure my self about this. I thought this could be a kind of "feature", so if you return undefined, you simply use the nodes height. But crashing would be fine too for me. What I'm not sure about is if we explicitly add the padding-top here or if the implementation of the custom function needs to consider this.

I'm not sure my self about this. I thought this could be a kind of "feature", so if you return undefined, you simply use the nodes height. But crashing would be fine too for me. What I'm not sure about is if we explicitly add the padding-top here or if the implementation of the custom function needs to consider this.
woehrl01 (Migrated from github.com) reviewed 2017-01-05 11:26:59 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
woehrl01 (Migrated from github.com) commented 2017-01-05 11:26:59 -08:00

we use only the first line of the children for base layout alignment. At least this is how chrome handles it.

we use only the first line of the children for base layout alignment. At least this is how chrome handles it.
woehrl01 (Migrated from github.com) reviewed 2017-01-05 11:27:56 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
woehrl01 (Migrated from github.com) commented 2017-01-05 11:27:56 -08:00

no it's defined by its first child on the first line or the first baseline aligned child if there is one (one the first line). I'll add a test for this.

no it's defined by its first child on the first line or the first baseline aligned child if there is one (one the first line). I'll add a test for this.
emilsjolander (Migrated from github.com) reviewed 2017-01-05 11:40:11 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
emilsjolander (Migrated from github.com) commented 2017-01-05 11:40:10 -08:00

The custom function should not take padding into account. We don't expect this for the measure function so I would like to preserve that here if possible.

Let's crash for now. If we find a valid reason to have this feature we can implement it later.

The custom function should not take padding into account. We don't expect this for the measure function so I would like to preserve that here if possible. Let's crash for now. If we find a valid reason to have this feature we can implement it later.
emilsjolander (Migrated from github.com) reviewed 2017-01-05 11:41:06 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
emilsjolander (Migrated from github.com) commented 2017-01-05 11:41:06 -08:00

yes, but this looks like we are skipping over children with multiple lines instead of just looking at their first line?

yes, but this looks like we are skipping over children with multiple lines instead of just looking at their first line?
emilsjolander (Migrated from github.com) reviewed 2017-01-05 11:43:16 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
emilsjolander (Migrated from github.com) commented 2017-01-05 11:43:16 -08:00

So the current code is wrong i think. Right? As it will pick the last child in the case no child is baseline aligned?

So the current code is wrong i think. Right? As it will pick the last child in the case no child is baseline aligned?
woehrl01 (Migrated from github.com) reviewed 2017-01-05 11:46:36 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
woehrl01 (Migrated from github.com) commented 2017-01-05 11:46:36 -08:00

oh, yep. We should break instead of continue here!

oh, yep. We should break instead of continue here!
woehrl01 (Migrated from github.com) reviewed 2017-01-05 11:47:30 -08:00
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
}
woehrl01 (Migrated from github.com) commented 2017-01-05 11:47:30 -08:00

no as we only use the child if baselineChild is still NULL. Which is false as seen as we find the first one. We still need to iterate to take any baseline aligned child into account.

no as we only use the child if ```baselineChild``` is still ```NULL```. Which is false as seen as we find the first one. We still need to iterate to take any baseline aligned child into account.
emilsjolander commented 2017-01-05 11:55:55 -08:00 (Migrated from github.com)

@woehrl01 If you push all updates in one go (Ok if they are different commits) that would make it more clear to me and others when you are finished addressing comments so we can have another look 👍

@woehrl01 If you push all updates in one go (Ok if they are different commits) that would make it more clear to me and others when you are finished addressing comments so we can have another look 👍
woehrl01 (Migrated from github.com) reviewed 2017-01-05 11:57:02 -08:00
woehrl01 (Migrated from github.com) commented 2017-01-05 11:57:02 -08:00

should I use YGFlexDirectionColumn here on the YGNodeLeadingMargin and YGNodeMarginForAxis calls?

should I use ```YGFlexDirectionColumn``` here on the ```YGNodeLeadingMargin``` and ```YGNodeMarginForAxis``` calls?
woehrl01 commented 2017-01-05 11:57:58 -08:00 (Migrated from github.com)

@emilsjolander sorry, will do next time!

@emilsjolander sorry, will do next time!
emilsjolander (Migrated from github.com) reviewed 2017-01-05 11:59:28 -08:00
emilsjolander (Migrated from github.com) commented 2017-01-05 11:59:28 -08:00

yes :) and replace dim[crossAxis]

yes :) and replace `dim[crossAxis]`
woehrl01 commented 2017-01-05 12:04:31 -08:00 (Migrated from github.com)

I think I got all your points, please have a look 😄

I think I got all your points, please have a look 😄
emilsjolander (Migrated from github.com) reviewed 2017-01-05 12:10:17 -08:00
emilsjolander (Migrated from github.com) commented 2017-01-05 12:09:44 -08:00

not quite sure why we break if a child has more than one line. That would mean if the first child of this node has two lines then the baseline would default to the height of the node. I'm not sure why that would be correct.

not quite sure why we break if a child has more than one line. That would mean if the first child of this node has two lines then the baseline would default to the height of the node. I'm not sure why that would be correct.
@@ -966,6 +1014,24 @@ static inline bool YGNodeIsFlex(const YGNodeRef node) {
(YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0));
}
emilsjolander (Migrated from github.com) commented 2017-01-05 12:07:59 -08:00

Please add this 👍

Please add this 👍
emilsjolander (Migrated from github.com) commented 2017-01-05 12:07:18 -08:00

Could pos[crossAxis] be hardcoded? Same with crossAxis a couple lines below

Could `pos[crossAxis]` be hardcoded? Same with `crossAxis` a couple lines below
@@ -49,6 +49,7 @@ typedef YGSize (*YGMeasureFunc)(YGNodeRef node,
YGMeasureMode widthMode,
emilsjolander (Migrated from github.com) commented 2017-01-05 12:05:26 -08:00

nit: remove added empty line

nit: remove added empty line
woehrl01 (Migrated from github.com) reviewed 2017-01-05 12:15:22 -08:00
woehrl01 (Migrated from github.com) commented 2017-01-05 12:15:22 -08:00

we break as only childs on the first line which have align baseline are taken into account. I already added a testcase for this.

we break as only childs on the first line which have align baseline are taken into account. I already added a testcase for this.
woehrl01 (Migrated from github.com) reviewed 2017-01-05 12:18:27 -08:00
@@ -966,6 +1014,24 @@ static inline bool YGNodeIsFlex(const YGNodeRef node) {
(YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0));
}
woehrl01 (Migrated from github.com) commented 2017-01-05 12:18:27 -08:00

not sure what you mean, should I add a empty line above return false?

not sure what you mean, should I add a empty line above ```return false```?
woehrl01 (Migrated from github.com) reviewed 2017-01-05 12:19:27 -08:00
woehrl01 (Migrated from github.com) commented 2017-01-05 12:19:27 -08:00

sure, I just wanted to be the same like the others, to not cause confusion. But I'll replace them, to be explicit that it is only used on YGEdgeTop

sure, I just wanted to be the same like the others, to not cause confusion. But I'll replace them, to be explicit that it is only used on ```YGEdgeTop```
woehrl01 (Migrated from github.com) reviewed 2017-01-05 12:21:22 -08:00
woehrl01 (Migrated from github.com) commented 2017-01-05 12:21:22 -08:00

oh, I see the confusion, child->lineIndex does not mean that it has more than one line. It means it is itself on the seconds (or later) line.

oh, I see the confusion, ```child->lineIndex``` does not mean that it has more than one line. It means it is itself on the seconds (or later) line.
emilsjolander (Migrated from github.com) reviewed 2017-01-05 12:45:58 -08:00
emilsjolander (Migrated from github.com) commented 2017-01-05 12:45:58 -08:00

@woehrl01 yeah that was my confusion, i'm not super familiar with the multi line code and read it too quickly 🐱

@woehrl01 yeah that was my confusion, i'm not super familiar with the multi line code and read it too quickly 🐱
woehrl01 commented 2017-01-05 13:08:51 -08:00 (Migrated from github.com)

@emilsjolander I additionally modified YGIsBaselineLayout to shortcut to false if it's a column layout.

@emilsjolander I additionally modified ```YGIsBaselineLayout``` to shortcut to false if it's a column layout.
facebook-github-bot commented 2017-01-05 14:10:32 -08:00 (Migrated from github.com)

@emilsjolander has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@emilsjolander has imported this pull request. If you are a Facebook employee, you can view this diff [on Phabricator](https://phabricator.intern.facebook.com/D4385061).
anql commented 2017-02-24 03:21:53 -08:00 (Migrated from github.com)

@woehrl01 The baseline feature is really awesome, but I'm not sure how to implement the function correctly. Would you give me some suggestions? Thanks.

@woehrl01 The baseline feature is really awesome, but I'm not sure how to implement the function correctly. Would you give me some suggestions? Thanks.
woehrl01 commented 2017-02-24 04:00:50 -08:00 (Migrated from github.com)

@anql: Sure! You must return the vertical position inside the node you want to align.

If you do not have a baseline function set, it uses the nodes height. That means that all the nodes are align at their bottom line.

If you have a text node where you want to align your nodes across each others, you need to return the position of the baseline of the firstline inside the node.

I unpacked my "awesome" paint skills 😂, to make this a bit clearer:

image

If the black numbers are the height of the nodes, you need to return the red values, to align the nodes across. If you have multiline text you need to return the value of the first line.

@anql: Sure! You must return the vertical position inside the node you want to align. If you do not have a baseline function set, it uses the nodes height. That means that all the nodes are align at their bottom line. If you have a text node where you want to align your nodes across each others, you need to return the position of the baseline of the firstline inside the node. I unpacked my "awesome" paint skills 😂, to make this a bit clearer: ![image](https://cloud.githubusercontent.com/assets/2535856/23302812/c00f0274-fa90-11e6-8d77-948402cc65fd.png) If the black numbers are the height of the nodes, you need to return the red values, to align the nodes across. If you have multiline text you need to return the value of the first line.
anql commented 2017-02-24 05:23:55 -08:00 (Migrated from github.com)

The paint is so clearer, it's very helpful for me. 👍 @woehrl01

The paint is so clearer, it's very helpful for me. 👍 @woehrl01

Pull request closed

Sign in to join this conversation.
No description provided.