feat(ui): make gradient as component
continuous-integration/drone/pr Build is failing

This commit is contained in:
2023-04-26 18:15:47 +02:00
parent 3fb4020594
commit 0d5109fc77
13 changed files with 569 additions and 65 deletions
@@ -14,17 +14,18 @@
// 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/widgets.dart';
import 'package:flutter/material.dart';
import 'package:wyatt_component_copy_with_extension/wyatt_component_copy_with_extension.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
extension GradientIconExtension on Icon {
GradientIcon toGradient(Gradient? gradient) =>
GradientIcon.from(this, gradient);
}
part 'gradient_icon.g.dart';
class GradientIcon extends Icon {
const GradientIcon(
super.icon, {
this.gradient,
@ComponentCopyWithExtension()
class GradientIcon extends GradientIconComponent with $GradientIconCWMixin {
GradientIcon(
{
required super.icon,
required super.gradientColors,
super.key,
super.size,
super.fill,
@@ -35,11 +36,34 @@ class GradientIcon extends Icon {
super.shadows,
super.semanticLabel,
super.textDirection,
});
}) : widgetIcon = null;
factory GradientIcon.from(Icon icon, Gradient? gradient) => GradientIcon(
icon.icon,
gradient: gradient,
GradientIcon.fromWidget(
Widget icon, {
MultiColor? gradientColors,
super.key,
super.size,
super.fill,
super.weight,
super.grade,
super.opticalSize,
super.color,
super.shadows,
super.semanticLabel,
super.textDirection,
}) : widgetIcon = icon,
super(
icon: null,
gradientColors: gradientColors ?? const MultiColor([]),
);
factory GradientIcon.fromIcon(
Icon icon, {
MultiColor? gradientColors,
}) =>
GradientIcon(
icon: icon.icon,
gradientColors: gradientColors ?? const MultiColor([]),
key: icon.key,
size: icon.size,
fill: icon.fill,
@@ -52,20 +76,76 @@ class GradientIcon extends Icon {
textDirection: icon.textDirection,
);
final Gradient? gradient;
/// Creates a [GradientIcon] from a [Widget].
///
/// Use [GradientIcon.fromWidget] to set this widget as the icon.
final Widget? widgetIcon;
@override
Widget build(BuildContext context) {
if (gradient != null) {
if (widgetIcon != null) {
// Return the widget icon colorized with the super.color.
if (super.color != null) {
return ColorFiltered(
colorFilter: ColorFilter.mode(
super.color!,
BlendMode.srcIn,
),
child: widgetIcon,
);
}
// else, return the widget icon with the gradient.
final Gradient? linearGradient =
GradientHelper.linearFromMultiColor(gradientColors);
if (linearGradient != null) {
return ShaderMask(
blendMode: BlendMode.srcIn,
shaderCallback: (bounds) => linearGradient.createShader(
Rect.fromLTWH(0, 0, bounds.width, bounds.height),
),
child: widgetIcon,
);
}
if (gradientColors.colors.isNotEmpty) {
// if multicolor has only one color, return the widget icon with the
// color.
return ColorFiltered(
colorFilter: ColorFilter.mode(
gradientColors.color,
BlendMode.srcIn,
),
child: widgetIcon,
);
}
// If there is no gradient and no color, just build the widget icon.
return widgetIcon!;
}
// if no widgetIcon, work with the icon.
if (super.color != null) {
return super.copyWith.call(color: super.color).build(context);
}
final Gradient? linearGradient =
GradientHelper.linearFromMultiColor(gradientColors);
if (linearGradient != null) {
return ShaderMask(
blendMode: BlendMode.srcIn,
shaderCallback: (bounds) => gradient!.createShader(
shaderCallback: (bounds) => linearGradient.createShader(
Rect.fromLTWH(0, 0, bounds.width, bounds.height),
),
child: super.build(context),
);
} else {
return super.build(context);
}
if (gradientColors.colors.isNotEmpty) {
return super.copyWith.call(color: gradientColors.color).build(context);
}
// If there is no gradient and no color, just build the icon.
return super.build(context);
}
}
@@ -0,0 +1,74 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'gradient_icon.dart';
// **************************************************************************
// ComponentCopyWithGenerator
// **************************************************************************
class $GradientIconCWProxyImpl implements $GradientIconComponentCWProxy {
const $GradientIconCWProxyImpl(this._value);
final GradientIcon _value;
@override
GradientIcon icon(IconData? icon) => this(icon: icon);
@override
GradientIcon gradientColors(MultiColor? gradientColors) =>
this(gradientColors: gradientColors);
@override
GradientIcon key(Key? key) => this(key: key);
@override
GradientIcon size(double? size) => this(size: size);
@override
GradientIcon fill(double? fill) => this(fill: fill);
@override
GradientIcon weight(double? weight) => this(weight: weight);
@override
GradientIcon grade(double? grade) => this(grade: grade);
@override
GradientIcon opticalSize(double? opticalSize) =>
this(opticalSize: opticalSize);
@override
GradientIcon color(Color? color) => this(color: color);
@override
GradientIcon shadows(List<Shadow>? shadows) => this(shadows: shadows);
@override
GradientIcon semanticLabel(String? semanticLabel) =>
this(semanticLabel: semanticLabel);
@override
GradientIcon textDirection(TextDirection? textDirection) =>
this(textDirection: textDirection);
@override
GradientIcon call({
IconData? icon,
MultiColor? gradientColors,
Key? key,
double? size,
double? fill,
double? weight,
double? grade,
double? opticalSize,
Color? color,
List<Shadow>? shadows,
String? semanticLabel,
TextDirection? textDirection,
}) =>
GradientIcon(
icon: icon ?? _value.icon,
gradientColors: gradientColors ?? _value.gradientColors,
key: key ?? _value.key,
size: size ?? _value.size,
fill: fill ?? _value.fill,
weight: weight ?? _value.weight,
grade: grade ?? _value.grade,
opticalSize: opticalSize ?? _value.opticalSize,
color: color ?? _value.color,
shadows: shadows ?? _value.shadows,
semanticLabel: semanticLabel ?? _value.semanticLabel,
textDirection: textDirection ?? _value.textDirection,
);
}
mixin $GradientIconCWMixin on Component {
$GradientIconComponentCWProxy get copyWith =>
$GradientIconCWProxyImpl(this as GradientIcon);
}
@@ -17,30 +17,19 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/widgets.dart';
import 'package:wyatt_component_copy_with_extension/wyatt_component_copy_with_extension.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
import 'package:wyatt_ui_kit/src/components/gradients/gradient_text_style.dart';
extension GradientTextExtension on Text {
/// If this text contains a [GradientTextStyle] it simply transforms it in
/// [GradientText], if not it needs a [MultiColor].
GradientText toGradient({MultiColor? gradientColors}) {
if (style is GradientTextStyle?) {
// Gradient
final gradientStyle = (style as GradientTextStyle?)?.gradientColors;
return GradientText.from(this, gradientStyle ?? gradientColors);
}
part 'gradient_text.g.dart';
return GradientText.from(this, gradientColors);
}
GradientText toFlutterGradient(Gradient? gradient) =>
GradientText.from(this, MultiColor(gradient?.colors));
}
class GradientText extends Text {
const GradientText(
super.data, {
@ComponentCopyWithExtension()
class GradientText extends GradientTextComponent with $GradientTextCWMixin {
const GradientText({
required super.data,
required super.gradientColors,
super.style,
super.key,
super.strutStyle,
super.textAlign,
super.textDirection,
@@ -53,46 +42,79 @@ class GradientText extends Text {
super.textWidthBasis,
super.textHeightBehavior,
super.selectionColor,
super.key,
});
factory GradientText.from(Text text, MultiColor? gradientColors) =>
/// Creates a [GradientText] from a [TextWrapper].
///
/// You can pass a gradient in case the [TextWrapper] doesn't have one.
/// You can also pass a style in case the [TextWrapper] doesn't have one.
factory GradientText.fromWrapper(
TextWrapper wrapper, {
MultiColor? gradientColors,
TextStyle? style,
}) =>
GradientText(
text.data ?? '',
style: GradientTextStyle.from(text.style, gradientColors),
strutStyle: text.strutStyle,
textAlign: text.textAlign,
textDirection: text.textDirection,
locale: text.locale,
softWrap: text.softWrap,
overflow: text.overflow,
textScaleFactor: text.textScaleFactor,
maxLines: text.maxLines,
semanticsLabel: text.semanticsLabel,
textWidthBasis: text.textWidthBasis,
textHeightBehavior: text.textHeightBehavior,
selectionColor: text.selectionColor,
key: text.key,
data: wrapper.data,
gradientColors:
wrapper.gradientColors ?? gradientColors ?? const MultiColor([]),
style: wrapper.style ?? style,
textAlign: wrapper.textAlign,
textDirection: wrapper.textDirection,
softWrap: wrapper.softWrap,
overflow: wrapper.overflow,
maxLines: wrapper.maxLines,
selectionColor: wrapper.selectionColor,
);
factory GradientText.fromGradientStyle(
String data, {
required GradientTextStyle style,
}) =>
GradientText(
data: data,
gradientColors: style.gradientColors ?? const MultiColor([]),
style: style,
);
@override
Widget build(BuildContext context) {
if (style is GradientTextStyle?) {
// Gradient
final gradientStyle = (style as GradientTextStyle?)?.gradientColors;
final gradient = (gradientStyle?.isGradient ?? false)
? LinearGradientHelper.fromMultiColor(gradientStyle!)
: null;
if (gradient != null) {
if (super.style is GradientTextStyle) {
// If the style is a gradient style, create a gradient text from it.
final Gradient? linearGradient = GradientHelper.linearFromMultiColor(
(super.style as GradientTextStyle?)?.gradientColors ??
const MultiColor([]),
);
if (linearGradient != null) {
return ShaderMask(
blendMode: BlendMode.srcIn,
shaderCallback: (bounds) => gradient.createShader(
shaderCallback: (bounds) => linearGradient.createShader(
Rect.fromLTWH(0, 0, bounds.width, bounds.height),
),
child: super.build(context),
);
}
}
final Gradient? linearGradient =
GradientHelper.linearFromMultiColor(gradientColors);
if (linearGradient != null) {
return ShaderMask(
blendMode: BlendMode.srcIn,
shaderCallback: (bounds) => linearGradient.createShader(
Rect.fromLTWH(0, 0, bounds.width, bounds.height),
),
child: super.build(context),
);
}
if (gradientColors.colors.isNotEmpty) {
return super
.copyWith
.call(style: style?.copyWith(color: gradientColors.color))
.build(context);
}
// If there is no gradient and no color, just build the text.
return super.build(context);
}
}
@@ -0,0 +1,94 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'gradient_text.dart';
// **************************************************************************
// ComponentCopyWithGenerator
// **************************************************************************
class $GradientTextCWProxyImpl implements $GradientTextComponentCWProxy {
const $GradientTextCWProxyImpl(this._value);
final GradientText _value;
@override
GradientText data(String? data) => this(data: data);
@override
GradientText gradientColors(MultiColor? gradientColors) =>
this(gradientColors: gradientColors);
@override
GradientText style(TextStyle? style) => this(style: style);
@override
GradientText key(Key? key) => this(key: key);
@override
GradientText strutStyle(StrutStyle? strutStyle) =>
this(strutStyle: strutStyle);
@override
GradientText textAlign(TextAlign? textAlign) => this(textAlign: textAlign);
@override
GradientText textDirection(TextDirection? textDirection) =>
this(textDirection: textDirection);
@override
GradientText locale(Locale? locale) => this(locale: locale);
@override
GradientText softWrap(bool? softWrap) => this(softWrap: softWrap);
@override
GradientText overflow(TextOverflow? overflow) => this(overflow: overflow);
@override
GradientText textScaleFactor(double? textScaleFactor) =>
this(textScaleFactor: textScaleFactor);
@override
GradientText maxLines(int? maxLines) => this(maxLines: maxLines);
@override
GradientText semanticsLabel(String? semanticsLabel) =>
this(semanticsLabel: semanticsLabel);
@override
GradientText textWidthBasis(TextWidthBasis? textWidthBasis) =>
this(textWidthBasis: textWidthBasis);
@override
GradientText textHeightBehavior(TextHeightBehavior? textHeightBehavior) =>
this(textHeightBehavior: textHeightBehavior);
@override
GradientText selectionColor(Color? selectionColor) =>
this(selectionColor: selectionColor);
@override
GradientText call({
String? data,
MultiColor? gradientColors,
TextStyle? style,
Key? key,
StrutStyle? strutStyle,
TextAlign? textAlign,
TextDirection? textDirection,
Locale? locale,
bool? softWrap,
TextOverflow? overflow,
double? textScaleFactor,
int? maxLines,
String? semanticsLabel,
TextWidthBasis? textWidthBasis,
TextHeightBehavior? textHeightBehavior,
Color? selectionColor,
}) =>
GradientText(
data: data ?? _value.data,
gradientColors: gradientColors ?? _value.gradientColors,
style: style ?? _value.style,
key: key ?? _value.key,
strutStyle: strutStyle ?? _value.strutStyle,
textAlign: textAlign ?? _value.textAlign,
textDirection: textDirection ?? _value.textDirection,
locale: locale ?? _value.locale,
softWrap: softWrap ?? _value.softWrap,
overflow: overflow ?? _value.overflow,
textScaleFactor: textScaleFactor ?? _value.textScaleFactor,
maxLines: maxLines ?? _value.maxLines,
semanticsLabel: semanticsLabel ?? _value.semanticsLabel,
textWidthBasis: textWidthBasis ?? _value.textWidthBasis,
textHeightBehavior: textHeightBehavior ?? _value.textHeightBehavior,
selectionColor: selectionColor ?? _value.selectionColor,
);
}
mixin $GradientTextCWMixin on Component {
$GradientTextComponentCWProxy get copyWith =>
$GradientTextCWProxyImpl(this as GradientText);
}