Miscellaneous Layout UX Fixes

- Fixes issues with edge constraints UX not updating
- Fixes issue with absolute/relative toggle not updating
- Fixes bug with incorrect point value when moving edge constraints to Left+Right and Top+Bottom
- Fix getting into bad state with inherited interpolator
- Fix layout animation advance bug
- Force layout bounds to be updated when parent changes (fixes a bug where relative layoutcomponents weren't updating because left/top value doesnt change when reparenting)

Diffs=
6f29a9c0c Miscellaneous Layout UX Fixes (#7491)
09ccc9ebb Add yoga to thumbnail generator build (#7494)
aa390d5dc change how viewmodel instances target their viewmodel (#7468)

Co-authored-by: Philip Chung <philterdesign@gmail.com>
This commit is contained in:
philter
2024-06-27 19:37:49 +00:00
parent 90b8c81f0e
commit 21bd3765dd
4 changed files with 39 additions and 23 deletions

View File

@ -1 +1 @@
e66e242c649e3e61f12a3adbd824bcd9a7525a53
6f29a9c0c368f94a38e8077343359fdaa97663e6

View File

@ -40,6 +40,19 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
_dirtyLayout.add(layoutComponent);
}
@override
AABB get layoutBounds {
if (!hasLayoutMeasurements()) {
return AABB.fromValues(
x,
y,
x + width,
y + height,
);
}
return super.layoutBounds;
}
bool _frameOrigin = true;
bool hasChangedDrawOrderInLastUpdate = false;
@ -250,17 +263,15 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
}
layoutNode.calculateLayout(width, height, LayoutDirection.ltr);
if (dirt & ComponentDirt.layoutStyle != 0) {
// Maybe we can genericize this to pass all styles to children if
// the child should inherit
cascadeAnimationStyle(interpolation, interpolator, interpolationTime);
}
// Need to sync all layout positions.
for (final layout in _dependencyOrder
.whereType<LayoutComponent>()
.where((layout) => layout != this)) {
// Maybe we can genericize this to pass all styles to children if
// the child should inherit
for (final layout in _dependencyOrder.whereType<LayoutComponent>()) {
layout.updateLayoutBounds();
if ((layout == this && super.advance(elapsedSeconds)) ||
layout.advance(elapsedSeconds)) {
(layout != this && layout.advance(elapsedSeconds))) {
didUpdate = true;
}
}

View File

@ -17,7 +17,7 @@ enum ScaleType {
String get label => name[0].toUpperCase() + name.substring(1);
}
enum LayoutAnimationStyle { none, custom, inherit }
enum LayoutAnimationStyle { none, inherit, custom }
enum LayoutStyleInterpolation { hold, linear, cubic, elastic }

View File

@ -37,6 +37,8 @@ class LayoutAnimationData {
}
class LayoutComponent extends LayoutComponentBase {
bool _forceUpdateLayoutBounds = false;
LayoutComponentStyle? _style;
LayoutComponentStyle? get style => _style;
set style(LayoutComponentStyle? style) {
@ -143,6 +145,7 @@ class LayoutComponent extends LayoutComponentBase {
}
void markLayoutStyleDirty() {
clearInheritedInterpolation();
addDirt(ComponentDirt.layoutStyle);
if (this != artboard) {
artboard?.markLayoutStyleDirty();
@ -483,6 +486,10 @@ class LayoutComponent extends LayoutComponentBase {
Offset _layoutLocation = Offset.zero;
Size _layoutSize = Size.zero;
bool hasLayoutMeasurements() {
return _layoutLocation != Offset.zero || _layoutSize != Size.zero;
}
AABB get localBounds {
return AABB.fromValues(
0,
@ -534,31 +541,29 @@ class LayoutComponent extends LayoutComponentBase {
}
void updateLayoutBounds() {
final layout = layoutNode.layout;
final newLayoutBounds = AABB.fromValues(
layoutNode.layout.left,
layoutNode.layout.top,
layoutNode.layout.left + layoutNode.layout.width,
layoutNode.layout.top + layoutNode.layout.height);
if (animates) {
if (animationData.toBounds.left != layout.left ||
animationData.toBounds.top != layout.top ||
animationData.toBounds.width != layout.width ||
animationData.toBounds.height != layout.height) {
if (!AABB.areEqual(animationData.toBounds, newLayoutBounds) ||
_forceUpdateLayoutBounds) {
// This is where we want to set the start/end data for the animation
// As we advance the animation, update _layoutLocation and _layoutSize
animationData.elapsedSeconds = 0;
animationData.fromBounds = layoutBounds;
animationData.toBounds = AABB.fromValues(layout.left, layout.top,
layout.left + layout.width, layout.top + layout.height);
animationData.toBounds = newLayoutBounds;
propagateSize();
markWorldTransformDirty();
}
} else if (_layoutLocation.dx != layout.left ||
_layoutLocation.dy != layout.top ||
_layoutSize.width != layout.width ||
_layoutSize.height != layout.height) {
_layoutLocation = Offset(layout.left, layout.top);
_layoutSize = Size(layout.width, layout.height);
} else if (!AABB.areEqual(layoutBounds, newLayoutBounds) ||
_forceUpdateLayoutBounds) {
_layoutLocation = Offset(newLayoutBounds.left, newLayoutBounds.top);
_layoutSize = Size(newLayoutBounds.width, newLayoutBounds.height);
propagateSize();
markWorldTransformDirty();
}
_forceUpdateLayoutBounds = false;
}
void styleValueChanged() {