ML-114 Metering container issues (#116)

* fixed top bar cutout shape

* update closed offset on layout change
This commit is contained in:
Vadim 2023-09-08 23:46:31 +02:00 committed by GitHub
parent cf4373d854
commit 8415f4e515
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 101 deletions

View file

@ -31,10 +31,23 @@ class MeteringTopBarShape extends CustomPainter {
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
final paint = Paint()..color = color; final paint = Paint()..color = color;
final path = Path(); late final Path path;
const circularRadius = Radius.circular(Dimens.borderRadiusL);
if (appendixHeight == 0 || appendixWidth == 0) { if (appendixHeight == 0 || appendixWidth == 0) {
path.addRRect( path = _drawNoAppendix(size, Dimens.borderRadiusL);
} else if (appendixHeight < 0) {
path = _drawAppendixOnLeft(size, Dimens.borderRadiusL);
canvas.scale(-1, 1);
canvas.translate(-size.width, 0);
} else {
path = _drawAppendixOnLeft(size, Dimens.borderRadiusL);
}
canvas.drawPath(path, paint);
}
Path _drawNoAppendix(Size size, double bottomRadius) {
final circularRadius = Radius.circular(bottomRadius);
return Path()
..addRRect(
RRect.fromLTRBAndCorners( RRect.fromLTRBAndCorners(
0, 0,
0, 0,
@ -43,73 +56,51 @@ class MeteringTopBarShape extends CustomPainter {
bottomLeft: circularRadius, bottomLeft: circularRadius,
bottomRight: circularRadius, bottomRight: circularRadius,
), ),
); )
} else if (appendixHeight < 0) { ..close();
// Left side with bottom corner
path.lineTo(0, size.height + appendixHeight - Dimens.borderRadiusL);
path.arcToPoint(
Offset(Dimens.borderRadiusL, size.height + appendixHeight),
radius: circularRadius,
clockwise: false,
);
// Bottom side with step
final allowedRadius = min(appendixHeight.abs() / 2, Dimens.borderRadiusL);
path.lineTo(appendixWidth - allowedRadius, size.height + appendixHeight);
path.arcToPoint(
Offset(appendixWidth, size.height + appendixHeight + allowedRadius),
radius: circularRadius,
);
path.lineTo(appendixWidth, size.height - allowedRadius);
path.arcToPoint(
Offset(appendixWidth + allowedRadius, size.height),
radius: circularRadius,
clockwise: false,
);
// Right side with bottom corner
path.lineTo(size.width - Dimens.borderRadiusL, size.height);
path.arcToPoint(
Offset(size.width, size.height - Dimens.borderRadiusL),
radius: circularRadius,
clockwise: false,
);
} else {
// Left side with bottom corner
path.lineTo(0, size.height - Dimens.borderRadiusL);
path.arcToPoint(
Offset(Dimens.borderRadiusL, size.height),
radius: circularRadius,
clockwise: false,
);
// Bottom side with step
final allowedRadius = min(appendixHeight.abs() / 2, Dimens.borderRadiusL);
path.relativeLineTo(appendixWidth - allowedRadius * 2, 0);
path.relativeArcToPoint(
Offset(allowedRadius, -allowedRadius),
radius: Radius.circular(allowedRadius),
rotation: 90,
clockwise: false,
);
path.relativeLineTo(0, -appendixHeight + allowedRadius * 2);
path.relativeArcToPoint(
Offset(allowedRadius, -allowedRadius),
radius: Radius.circular(allowedRadius),
rotation: 90,
);
// Right side with bottom corner
path.lineTo(size.width - Dimens.borderRadiusL, size.height - appendixHeight);
path.arcToPoint(
Offset(size.width, size.height - appendixHeight - Dimens.borderRadiusL),
radius: circularRadius,
clockwise: false,
);
} }
Path _drawAppendixOnLeft(Size size, double bottomRadius) {
final path = Path();
final circularRadius = Radius.circular(bottomRadius);
final appendixHeight = this.appendixHeight.abs();
// Left side with bottom corner
path.lineTo(0, size.height - bottomRadius);
path.arcToPoint(
Offset(bottomRadius, size.height),
radius: circularRadius,
clockwise: false,
);
// Bottom side with step
final allowedRadius = min(appendixHeight.abs() / 2, bottomRadius);
path.lineTo(appendixWidth - allowedRadius, size.height);
path.arcToPoint(
Offset(appendixWidth, size.height - allowedRadius),
radius: Radius.circular(allowedRadius),
rotation: 90,
clockwise: false,
);
path.lineTo(appendixWidth, size.height - appendixHeight + allowedRadius);
path.arcToPoint(
Offset(appendixWidth + allowedRadius, size.height - appendixHeight),
radius: Radius.circular(allowedRadius),
rotation: 90,
);
// Right side with bottom corner
path.lineTo(size.width - bottomRadius, size.height - appendixHeight);
path.arcToPoint(
Offset(size.width, size.height - appendixHeight - bottomRadius),
radius: circularRadius,
clockwise: false,
);
path.lineTo(size.width, 0); path.lineTo(size.width, 0);
path.close(); path.close();
canvas.drawPath(path, paint);
return path;
} }
@override @override

View file

@ -20,9 +20,7 @@ class MeteringTopBar extends StatelessWidget {
return CustomPaint( return CustomPaint(
painter: MeteringTopBarShape( painter: MeteringTopBarShape(
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
appendixWidth: appendixHeight > 0 appendixWidth: MediaQuery.of(context).size.width / 2 - Dimens.grid8 / 2 + Dimens.paddingM,
? MediaQuery.of(context).size.width / 2 - Dimens.grid8 + Dimens.paddingM
: MediaQuery.of(context).size.width / 2 + Dimens.grid8 - Dimens.paddingM,
appendixHeight: appendixHeight, appendixHeight: appendixHeight,
), ),
child: Padding( child: Padding(

View file

@ -22,15 +22,15 @@ class AnimatedDialog extends StatefulWidget {
class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProviderStateMixin { class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProviderStateMixin {
final GlobalKey _key = GlobalKey(); final GlobalKey _key = GlobalKey();
late final Size _closedSize; late Size _closedSize;
late final Offset _closedOffset; late Offset _closedOffset;
late final AnimationController _animationController; late final AnimationController _animationController;
late final CurvedAnimation _defaultCurvedAnimation; late final CurvedAnimation _defaultCurvedAnimation;
late final Animation<Color?> _barrierColorAnimation; late final Animation<Color?> _barrierColorAnimation;
late final SizeTween _sizeTween; late SizeTween _sizeTween;
late final Animation<Size?> _sizeAnimation; late Animation<Size?> _sizeAnimation;
late final Animation<Size?> _offsetAnimation; late Animation<Size?> _offsetAnimation;
late final Animation<double> _borderRadiusAnimation; late final Animation<double> _borderRadiusAnimation;
late final Animation<double> _closedOpacityAnimation; late final Animation<double> _closedOpacityAnimation;
late final Animation<double> _openedOpacityAnimation; late final Animation<double> _openedOpacityAnimation;
@ -88,35 +88,7 @@ class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProvide
), ),
); );
WidgetsBinding.instance.addPostFrameCallback((_) { _setClosedOffset();
final mediaQuery = MediaQuery.of(context);
_closedSize = _key.currentContext!.size!;
_sizeTween = SizeTween(
begin: _closedSize,
end: widget.openedSize ??
Size(
mediaQuery.size.width -
mediaQuery.padding.horizontal -
Dimens.dialogMargin.horizontal,
mediaQuery.size.height - mediaQuery.padding.vertical - Dimens.dialogMargin.vertical,
),
);
_sizeAnimation = _sizeTween.animate(_defaultCurvedAnimation);
final renderBox = _key.currentContext!.findRenderObject()! as RenderBox;
_closedOffset = renderBox.localToGlobal(Offset.zero);
_offsetAnimation = SizeTween(
begin: Size(
_closedOffset.dx + _closedSize.width / 2,
_closedOffset.dy + _closedSize.height / 2,
),
end: Size(
mediaQuery.size.width / 2,
mediaQuery.size.height / 2 + mediaQuery.padding.top / 2 - mediaQuery.padding.bottom / 2,
),
).animate(_defaultCurvedAnimation);
});
} }
@override @override
@ -133,6 +105,12 @@ class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProvide
).animate(_defaultCurvedAnimation); ).animate(_defaultCurvedAnimation);
} }
@override
void didUpdateWidget(covariant AnimatedDialog oldWidget) {
super.didUpdateWidget(oldWidget);
_setClosedOffset();
}
@override @override
void dispose() { void dispose() {
_animationController.dispose(); _animationController.dispose();
@ -151,6 +129,38 @@ class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProvide
); );
} }
void _setClosedOffset() {
WidgetsBinding.instance.addPostFrameCallback((_) {
final renderBox = _key.currentContext?.findRenderObject()! as RenderBox?;
if (renderBox != null) {
final size = MediaQuery.sizeOf(context);
final padding = MediaQuery.paddingOf(context);
_closedSize = _key.currentContext!.size!;
_sizeTween = SizeTween(
begin: _closedSize,
end: widget.openedSize ??
Size(
size.width - padding.horizontal - Dimens.dialogMargin.horizontal,
size.height - padding.vertical - Dimens.dialogMargin.vertical,
),
);
_sizeAnimation = _sizeTween.animate(_defaultCurvedAnimation);
_closedOffset = renderBox.localToGlobal(Offset.zero);
_offsetAnimation = SizeTween(
begin: Size(
_closedOffset.dx + _closedSize.width / 2,
_closedOffset.dy + _closedSize.height / 2,
),
end: Size(
size.width / 2,
size.height / 2 + padding.top / 2 - padding.bottom / 2,
),
).animate(_defaultCurvedAnimation);
}
});
}
void _openDialog() { void _openDialog() {
Navigator.of(context).push( Navigator.of(context).push(
PageRouteBuilder( PageRouteBuilder(