mirror of
https://github.com/rive-app/rive-flutter
synced 2025-07-05 21:55:58 +00:00
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:
@ -1 +1 @@
|
||||
e66e242c649e3e61f12a3adbd824bcd9a7525a53
|
||||
6f29a9c0c368f94a38e8077343359fdaa97663e6
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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() {
|
||||
|
Reference in New Issue
Block a user