master #81
@ -16,3 +16,4 @@
|
|||||||
|
|
||||||
export './buttons/buttons.dart';
|
export './buttons/buttons.dart';
|
||||||
export './cards/cards.dart';
|
export './cards/cards.dart';
|
||||||
|
export './loader/loader.dart';
|
||||||
|
145
packages/wyatt_ui_kit/lib/src/components/loader/loader.dart
Normal file
145
packages/wyatt_ui_kit/lib/src/components/loader/loader.dart
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
|
import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
|
||||||
|
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
|
||||||
|
import 'package:wyatt_ui_kit/src/components/loader/loader_theme_resolver.dart';
|
||||||
|
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||||
|
|
||||||
|
part 'loader.g.dart';
|
||||||
|
|
||||||
|
@ComponentCopyWithExtension()
|
||||||
|
class Loader extends LoaderComponent with $LoaderCWMixin {
|
||||||
|
const Loader({
|
||||||
|
super.colors,
|
||||||
|
super.radius,
|
||||||
|
super.stroke,
|
||||||
|
super.duration,
|
||||||
|
super.flip,
|
||||||
|
super.themeResolver,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
LoaderThemeResolver? get themeResolver =>
|
||||||
|
super.themeResolver as LoaderThemeResolver?;
|
||||||
|
|
||||||
|
/// Negotiate the theme to get a complete style.
|
||||||
|
LoaderStyle _resolve(BuildContext context) {
|
||||||
|
final LoaderThemeResolver resolver = themeResolver ??
|
||||||
|
LoaderThemeResolver(
|
||||||
|
computeExtensionValueFn: (
|
||||||
|
context,
|
||||||
|
defaultValue,
|
||||||
|
themeExtension, {
|
||||||
|
extra,
|
||||||
|
}) =>
|
||||||
|
LoaderStyle(
|
||||||
|
colors: themeExtension.colors,
|
||||||
|
stroke: themeExtension.stroke,
|
||||||
|
),
|
||||||
|
customStyleFn: (context, {extra}) => LoaderStyle(
|
||||||
|
colors: colors,
|
||||||
|
stroke: stroke,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return resolver.negotiate(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final style = _resolve(context);
|
||||||
|
final dimension =
|
||||||
|
(radius != null) ? radius! * 2 : context.buttonTheme.height;
|
||||||
|
|
||||||
|
return SizedBox.square(
|
||||||
|
dimension: dimension,
|
||||||
|
child: RepaintBoundary(
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: _LoaderPainter(
|
||||||
|
style.colors!,
|
||||||
|
dimension / 2,
|
||||||
|
style.stroke!,
|
||||||
|
flip: flip ?? false,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.animate(
|
||||||
|
onPlay: (controller) => controller.repeat(),
|
||||||
|
)
|
||||||
|
.rotate(
|
||||||
|
duration: duration ?? 900.ms,
|
||||||
|
begin: (flip ?? false) ? 0 : 1,
|
||||||
|
end: (flip ?? false) ? 1 : 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LoaderPainter extends CustomPainter {
|
||||||
|
_LoaderPainter(
|
||||||
|
this.colors,
|
||||||
|
this.radius,
|
||||||
|
this.stroke, {
|
||||||
|
required this.flip,
|
||||||
|
});
|
||||||
|
|
||||||
|
final MultiColor colors;
|
||||||
|
final double radius;
|
||||||
|
final double stroke;
|
||||||
|
final bool flip;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final center = Offset(size.width / 2, size.height / 2);
|
||||||
|
final circleSurface = Rect.fromCircle(center: center, radius: radius);
|
||||||
|
|
||||||
|
final dotColor = colors.color;
|
||||||
|
final dotCenter =
|
||||||
|
Offset(size.width / 2 + (flip ? -radius : radius), size.height / 2);
|
||||||
|
final gradient =
|
||||||
|
colors.isGradient ? colors.colors : [colors.color, colors.color];
|
||||||
|
|
||||||
|
final gradientCirclePainter = Paint()
|
||||||
|
..shader = SweepGradient(
|
||||||
|
colors: (flip ? gradient.reversed : gradient).toList(),
|
||||||
|
transform: flip ? const GradientRotation(pi) : null,
|
||||||
|
).createShader(circleSurface)
|
||||||
|
..strokeWidth = stroke
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeCap = StrokeCap.round;
|
||||||
|
|
||||||
|
final dotPainter = Paint()
|
||||||
|
..color = dotColor
|
||||||
|
..style = PaintingStyle.fill
|
||||||
|
..strokeCap = StrokeCap.round;
|
||||||
|
|
||||||
|
canvas
|
||||||
|
..drawCircle(center, radius, gradientCirclePainter)
|
||||||
|
..drawCircle(dotCenter, stroke / 2, dotPainter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(_LoaderPainter oldDelegate) => false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRebuildSemantics(_LoaderPainter oldDelegate) => false;
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'loader.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// ComponentCopyWithGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class $LoaderCWProxyImpl implements $LoaderComponentCWProxy {
|
||||||
|
const $LoaderCWProxyImpl(this._value);
|
||||||
|
final Loader _value;
|
||||||
|
@override
|
||||||
|
Loader colors(MultiColor? colors) => this(colors: colors);
|
||||||
|
@override
|
||||||
|
Loader radius(double? radius) => this(radius: radius);
|
||||||
|
@override
|
||||||
|
Loader stroke(double? stroke) => this(stroke: stroke);
|
||||||
|
@override
|
||||||
|
Loader duration(Duration? duration) => this(duration: duration);
|
||||||
|
@override
|
||||||
|
Loader flip(bool? flip) => this(flip: flip);
|
||||||
|
@override
|
||||||
|
Loader themeResolver(
|
||||||
|
ThemeResolver<dynamic, dynamic, dynamic>? themeResolver) =>
|
||||||
|
this(themeResolver: themeResolver);
|
||||||
|
@override
|
||||||
|
Loader key(Key? key) => this(key: key);
|
||||||
|
@override
|
||||||
|
Loader call({
|
||||||
|
MultiColor? colors,
|
||||||
|
double? radius,
|
||||||
|
double? stroke,
|
||||||
|
Duration? duration,
|
||||||
|
bool? flip,
|
||||||
|
ThemeResolver<dynamic, dynamic, dynamic>? themeResolver,
|
||||||
|
Key? key,
|
||||||
|
}) =>
|
||||||
|
Loader(
|
||||||
|
colors: colors ?? _value.colors,
|
||||||
|
radius: radius ?? _value.radius,
|
||||||
|
stroke: stroke ?? _value.stroke,
|
||||||
|
duration: duration ?? _value.duration,
|
||||||
|
flip: flip ?? _value.flip,
|
||||||
|
themeResolver: themeResolver ?? _value.themeResolver,
|
||||||
|
key: key ?? _value.key,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin $LoaderCWMixin on Component {
|
||||||
|
$LoaderComponentCWProxy get copyWith => $LoaderCWProxyImpl(this as Loader);
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
|
||||||
|
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||||
|
|
||||||
|
class LoaderThemeResolver
|
||||||
|
extends ThemeResolver<LoaderStyle, LoaderThemeExtension, void> {
|
||||||
|
const LoaderThemeResolver({
|
||||||
|
required this.computeExtensionValueFn,
|
||||||
|
required this.customStyleFn,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Values taken from <https://api.flutter.dev/flutter/material/ElevatedButton/defaultStyleOf.html>
|
||||||
|
@override
|
||||||
|
LoaderStyle computeDefaultValue(
|
||||||
|
BuildContext context, {
|
||||||
|
void extra,
|
||||||
|
}) =>
|
||||||
|
LoaderStyle(
|
||||||
|
colors: MultiColor([
|
||||||
|
Theme.of(context).progressIndicatorTheme.color ??
|
||||||
|
context.colorScheme.primary,
|
||||||
|
context.colorScheme.onPrimary,
|
||||||
|
]),
|
||||||
|
stroke: 4,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final LoaderStyle? Function(
|
||||||
|
BuildContext context,
|
||||||
|
LoaderStyle defaultValue,
|
||||||
|
LoaderThemeExtension themeExtension, {
|
||||||
|
void extra,
|
||||||
|
}) computeExtensionValueFn;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final LoaderStyle? Function(BuildContext context, {void extra}) customStyleFn;
|
||||||
|
}
|
@ -14,5 +14,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
export 'button_theme_extension/button_theme_extension.dart';
|
export './button_theme_extension/button_theme_extension.dart';
|
||||||
|
export './loader_theme_extension.dart';
|
||||||
export 'card_theme_extension.dart';
|
export 'card_theme_extension.dart';
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
|
||||||
|
|
||||||
|
abstract class LoaderThemeExtension
|
||||||
|
extends ThemeExtension<LoaderThemeExtension> {
|
||||||
|
const LoaderThemeExtension({
|
||||||
|
this.colors,
|
||||||
|
this.stroke,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Gradient colors from start to end.
|
||||||
|
final MultiColor? colors;
|
||||||
|
|
||||||
|
/// Loader stroke width
|
||||||
|
final double? stroke;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user