nc-photos/app/lib/widget/selectable.dart

106 lines
3.2 KiB
Dart
Raw Normal View History

2021-07-05 18:21:58 +02:00
import 'package:flutter/material.dart';
2021-09-28 13:14:47 +02:00
import 'package:nc_photos/k.dart' as k;
2022-11-13 09:16:50 +01:00
import 'package:nc_photos/widget/animated_smooth_clip_r_rect.dart';
2021-07-05 18:21:58 +02:00
// Overlay a check mark if an item is selected
class Selectable extends StatelessWidget {
2021-09-15 08:58:06 +02:00
const Selectable({
2021-07-23 22:05:57 +02:00
Key? key,
required this.child,
2021-07-05 18:21:58 +02:00
this.isSelected = false,
2021-07-23 22:05:57 +02:00
required this.iconSize,
2021-07-05 18:21:58 +02:00
this.borderRadius,
2022-11-13 09:16:50 +01:00
this.childBorderRadius = BorderRadius.zero,
this.indicatorAlignment = Alignment.topLeft,
2021-07-05 18:21:58 +02:00
this.onTap,
this.onLongPress,
}) : super(key: key);
@override
build(BuildContext context) {
return Stack(
fit: StackFit.expand,
children: [
if (isSelected)
Positioned.fill(
child: Container(
decoration: BoxDecoration(
2024-05-16 18:37:33 +02:00
color: Theme.of(context).colorScheme.secondaryContainer,
2021-07-05 18:21:58 +02:00
borderRadius: borderRadius,
),
2021-09-28 13:14:47 +02:00
),
),
AnimatedScale(
scale: isSelected ? .85 : 1,
curve: Curves.easeInOut,
duration: k.animationDurationNormal,
2022-11-13 09:16:50 +01:00
child: childBorderRadius != BorderRadius.zero
? AnimatedSmoothClipRRect(
smoothness: 1,
borderRadius:
isSelected ? childBorderRadius : BorderRadius.zero,
side: BorderSide(
color: isSelected
2024-05-16 18:37:33 +02:00
? Theme.of(context).colorScheme.secondaryContainer
2022-11-13 09:16:50 +01:00
: Theme.of(context)
.colorScheme
2024-05-16 18:37:33 +02:00
.secondaryContainer
2022-11-13 09:16:50 +01:00
.withOpacity(0),
width: isSelected ? 4 : 0,
),
curve: Curves.easeInOut,
duration: k.animationDurationNormal,
child: child,
)
: child,
2021-09-28 13:14:47 +02:00
),
2022-11-13 09:16:50 +01:00
Align(
alignment: indicatorAlignment,
2021-09-28 13:14:47 +02:00
child: AnimatedOpacity(
opacity: isSelected ? 1 : 0,
duration: k.animationDurationNormal,
child: Stack(
2022-11-13 09:16:50 +01:00
alignment: Alignment.center,
2021-09-28 13:14:47 +02:00
children: [
Icon(
Icons.circle,
2022-11-13 09:16:50 +01:00
size: iconSize - 2,
2024-05-16 18:37:33 +02:00
color: Theme.of(context).colorScheme.secondary,
2021-09-28 13:14:47 +02:00
),
Icon(
2021-07-05 18:21:58 +02:00
Icons.check_circle_outlined,
size: iconSize,
2024-05-16 18:37:33 +02:00
color: Theme.of(context).colorScheme.secondaryContainer,
2021-07-05 18:21:58 +02:00
),
2021-09-28 13:14:47 +02:00
],
2021-07-05 18:21:58 +02:00
),
),
2021-09-28 13:14:47 +02:00
),
2021-07-05 18:21:58 +02:00
if (onTap != null || onLongPress != null)
Positioned.fill(
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: onTap,
onLongPress: onLongPress,
borderRadius: borderRadius,
),
),
),
],
);
}
final Widget child;
final bool isSelected;
final double iconSize;
2021-07-23 22:05:57 +02:00
final BorderRadius? borderRadius;
2021-07-05 18:21:58 +02:00
2022-11-13 09:16:50 +01:00
/// Border radius used to clip the child widget when selected
final BorderRadius childBorderRadius;
final Alignment indicatorAlignment;
2021-07-23 22:05:57 +02:00
final VoidCallback? onTap;
final VoidCallback? onLongPress;
2021-07-05 18:21:58 +02:00
}