mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-25 00:40:39 +00:00
ML-114 Metering container issues (#116)
* fixed top bar cutout shape * update closed offset on layout change
This commit is contained in:
parent
cf4373d854
commit
8415f4e515
3 changed files with 100 additions and 101 deletions
|
@ -31,10 +31,23 @@ class MeteringTopBarShape extends CustomPainter {
|
|||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()..color = color;
|
||||
final path = Path();
|
||||
const circularRadius = Radius.circular(Dimens.borderRadiusL);
|
||||
late final Path path;
|
||||
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(
|
||||
0,
|
||||
0,
|
||||
|
@ -43,73 +56,51 @@ class MeteringTopBarShape extends CustomPainter {
|
|||
bottomLeft: circularRadius,
|
||||
bottomRight: circularRadius,
|
||||
),
|
||||
);
|
||||
} else if (appendixHeight < 0) {
|
||||
// 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,
|
||||
);
|
||||
)
|
||||
..close();
|
||||
}
|
||||
|
||||
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.close();
|
||||
canvas.drawPath(path, paint);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -20,9 +20,7 @@ class MeteringTopBar extends StatelessWidget {
|
|||
return CustomPaint(
|
||||
painter: MeteringTopBarShape(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
appendixWidth: appendixHeight > 0
|
||||
? MediaQuery.of(context).size.width / 2 - Dimens.grid8 + Dimens.paddingM
|
||||
: MediaQuery.of(context).size.width / 2 + Dimens.grid8 - Dimens.paddingM,
|
||||
appendixWidth: MediaQuery.of(context).size.width / 2 - Dimens.grid8 / 2 + Dimens.paddingM,
|
||||
appendixHeight: appendixHeight,
|
||||
),
|
||||
child: Padding(
|
||||
|
|
|
@ -22,15 +22,15 @@ class AnimatedDialog extends StatefulWidget {
|
|||
class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProviderStateMixin {
|
||||
final GlobalKey _key = GlobalKey();
|
||||
|
||||
late final Size _closedSize;
|
||||
late final Offset _closedOffset;
|
||||
late Size _closedSize;
|
||||
late Offset _closedOffset;
|
||||
|
||||
late final AnimationController _animationController;
|
||||
late final CurvedAnimation _defaultCurvedAnimation;
|
||||
late final Animation<Color?> _barrierColorAnimation;
|
||||
late final SizeTween _sizeTween;
|
||||
late final Animation<Size?> _sizeAnimation;
|
||||
late final Animation<Size?> _offsetAnimation;
|
||||
late SizeTween _sizeTween;
|
||||
late Animation<Size?> _sizeAnimation;
|
||||
late Animation<Size?> _offsetAnimation;
|
||||
late final Animation<double> _borderRadiusAnimation;
|
||||
late final Animation<double> _closedOpacityAnimation;
|
||||
late final Animation<double> _openedOpacityAnimation;
|
||||
|
@ -88,35 +88,7 @@ class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProvide
|
|||
),
|
||||
);
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
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);
|
||||
});
|
||||
_setClosedOffset();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -133,6 +105,12 @@ class AnimatedDialogState extends State<AnimatedDialog> with SingleTickerProvide
|
|||
).animate(_defaultCurvedAnimation);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant AnimatedDialog oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
_setClosedOffset();
|
||||
}
|
||||
|
||||
@override
|
||||
void 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() {
|
||||
Navigator.of(context).push(
|
||||
PageRouteBuilder(
|
||||
|
|
Loading…
Reference in a new issue