-
Notifications
You must be signed in to change notification settings - Fork 74
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
Implement ViewBox with manual measurement #2397
Conversation
Previously ViewBox delegated to FrameLayout. This worked okay but it was potentially difficult to track behaviors between View and UIView. This implementation is based on the UIViewBox class implementation. This fixes a bug where layouts incorrectly didn't handle changes when modifiers were removed. This changes how Box's margins are implemented. Previously the margins were external, which required the hosting layout to honor them as layout constraints. That was not supported when the enclosing layout was a Row or Column.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously: the bounds of the Box excluded the margins, and so the background wasn't drawn there
Now: the bounds of the Box include the margins, so the background is drawn there
This should be easier to work with!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FrameLayout and centering worked differently for asymmetric margins. This is now consistent with iOS, and a pretty reasonable behavior.
* | ||
* This class is mutable and reused to avoid object allocation. | ||
*/ | ||
private class Measurer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The iOS implementation doesn’t have a class like this, and I think it’s worked out quite nicely. It makes it easy to share layout logic between measure and layout steps. It also avoids allocations!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one seems broken? The red text box has 30dp of margin:
redwood/redwood-layout-shared-test/src/commonMain/kotlin/app/cash/redwood/layout/AbstractBoxTest.kt
Lines 452 to 453 in f377665
val redColor = widgetFactory.text( | |
modifier = MarginImpl(30.dp), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I get it. This is the "after". The "empty" is misleading because we use that for the initial snapshot in other tests...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Need to remove a modifier!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is also a breakage. If someone creates a widget
@Widget
data class Toolbar(
@Children(1) val left: () -> Unit,
@Children(2) val right: () -> Unit,
)
and then implements those slots with FrameLayout
s, someone putting a Box(modifier = Modifier.margin(30.dp))
would not see their margins reflected.
redwood/redwood-layout-shared-test/src/commonMain/kotlin/app/cash/redwood/layout/AbstractBoxTest.kt
Lines 347 to 348 in f377665
// Ensure Box applies its margins correctly to the parent. | |
margin(asymmetric) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just the padding vs. margin naming thing we talked about yesterday then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, yes exactly.
Box has two kinds of margins:
- the margin property on the Box itself, that works like padding
- the margin modifier on each child, which works like a margin
I think it would be good to rename the margin property to padding.
Previously ViewBox delegated to FrameLayout. This worked okay but it was potentially difficult to track behaviors between View and UIView.
This implementation is based on the UIViewBox class implementation.
This fixes a bug where layouts incorrectly didn't handle changes when modifiers were removed.
This changes how Box's margins are implemented. Previously the margins were external, which required the hosting layout to honor them as layout constraints. That was not supported when the enclosing layout was a Row or Column.
CHANGELOG.md
's "Unreleased" section has been updated, if applicable.