Introduce WidgetStateBorderSide.lerp (#148122)

fixes [Consolidate `_LerpSides` classes with `WigetStateProperty<BorderSide?>` type  into a new `WidgetStateBorderSide.lerp`](https://github.com/flutter/flutter/issues/148057)
This commit is contained in:
Taha Tesser 2024-05-22 10:11:07 +03:00 committed by GitHub
parent 43548359c9
commit ea7cf54b42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 82 additions and 77 deletions

View file

@ -603,30 +603,6 @@ class ButtonStyle with Diagnosticable {
if (a == null && b == null) {
return null;
}
return _LerpSides(a, b, t);
}
}
class _LerpSides implements MaterialStateProperty<BorderSide?> {
const _LerpSides(this.a, this.b, this.t);
final MaterialStateProperty<BorderSide?>? a;
final MaterialStateProperty<BorderSide?>? b;
final double t;
@override
BorderSide? resolve(Set<MaterialState> states) {
final BorderSide? resolvedA = a?.resolve(states);
final BorderSide? resolvedB = b?.resolve(states);
if (resolvedA == null && resolvedB == null) {
return null;
}
if (resolvedA == null) {
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
}
if (resolvedB == null) {
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
}
return BorderSide.lerp(resolvedA, resolvedB, t);
return MaterialStateBorderSide.lerp(a, b, t);
}
}

View file

@ -316,7 +316,7 @@ class MenuStyle with Diagnosticable {
minimumSize: MaterialStateProperty.lerp<Size?>(a?.minimumSize, b?.minimumSize, t, Size.lerp),
fixedSize: MaterialStateProperty.lerp<Size?>(a?.fixedSize, b?.fixedSize, t, Size.lerp),
maximumSize: MaterialStateProperty.lerp<Size?>(a?.maximumSize, b?.maximumSize, t, Size.lerp),
side: _LerpSides(a?.side, b?.side, t),
side: MaterialStateBorderSide.lerp(a?.side, b?.side, t),
shape: MaterialStateProperty.lerp<OutlinedBorder?>(a?.shape, b?.shape, t, OutlinedBorder.lerp),
mouseCursor: t < 0.5 ? a?.mouseCursor : b?.mouseCursor,
visualDensity: t < 0.5 ? a?.visualDensity : b?.visualDensity,
@ -342,29 +342,3 @@ class MenuStyle with Diagnosticable {
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
}
}
/// A required helper class because [BorderSide.lerp] doesn't support passing or
/// returning null values.
class _LerpSides implements MaterialStateProperty<BorderSide?> {
const _LerpSides(this.a, this.b, this.t);
final MaterialStateProperty<BorderSide?>? a;
final MaterialStateProperty<BorderSide?>? b;
final double t;
@override
BorderSide? resolve(Set<MaterialState> states) {
final BorderSide? resolvedA = a?.resolve(states);
final BorderSide? resolvedB = b?.resolve(states);
if (resolvedA == null && resolvedB == null) {
return null;
}
if (resolvedA == null) {
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
}
if (resolvedB == null) {
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
}
return BorderSide.lerp(resolvedA, resolvedB, t);
}
}

View file

@ -203,31 +203,7 @@ class SearchBarThemeData with Diagnosticable {
if (identical(a, b)) {
return a;
}
return _LerpSides(a, b, t);
}
}
class _LerpSides implements MaterialStateProperty<BorderSide?> {
const _LerpSides(this.a, this.b, this.t);
final MaterialStateProperty<BorderSide?>? a;
final MaterialStateProperty<BorderSide?>? b;
final double t;
@override
BorderSide? resolve(Set<MaterialState> states) {
final BorderSide? resolvedA = a?.resolve(states);
final BorderSide? resolvedB = b?.resolve(states);
if (identical(resolvedA, resolvedB)) {
return resolvedA;
}
if (resolvedA == null) {
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
}
if (resolvedB == null) {
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
}
return BorderSide.lerp(resolvedA, resolvedB, t);
return MaterialStateBorderSide.lerp(a, b, t);
}
}

View file

@ -353,6 +353,43 @@ abstract class WidgetStateBorderSide extends BorderSide implements WidgetStatePr
/// widget or theme.
@override
BorderSide? resolve(Set<WidgetState> states);
/// Linearly interpolate between two [WidgetStateProperty]s of [BorderSide].
static WidgetStateProperty<BorderSide?>? lerp(
WidgetStateProperty<BorderSide?>? a,
WidgetStateProperty<BorderSide?>? b,
double t,
) {
// Avoid creating a _LerpSides object for a common case.
if (a == null && b == null) {
return null;
}
return _LerpSides(a, b, t);
}
}
class _LerpSides implements WidgetStateProperty<BorderSide?> {
const _LerpSides(this.a, this.b, this.t);
final WidgetStateProperty<BorderSide?>? a;
final WidgetStateProperty<BorderSide?>? b;
final double t;
@override
BorderSide? resolve(Set<WidgetState> states) {
final BorderSide? resolvedA = a?.resolve(states);
final BorderSide? resolvedB = b?.resolve(states);
if (resolvedA == null && resolvedB == null) {
return null;
}
if (resolvedA == null) {
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
}
if (resolvedB == null) {
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
}
return BorderSide.lerp(resolvedA, resolvedB, t);
}
}
class _WidgetStateBorderSide extends WidgetStateBorderSide {

View file

@ -86,6 +86,48 @@ void main() {
)!.resolve(enabled)!;
expect(textStyle.fontSize, 20.0);
});
test('WidgetStateBorderSide.lerp()', () {
const WidgetStateProperty<BorderSide?> borderSide1 = WidgetStatePropertyAll<BorderSide?>(
BorderSide(
color: Color(0xffff0000),
width: 4.0,
),
);
const WidgetStateProperty<BorderSide?> borderSide2 = WidgetStatePropertyAll<BorderSide?>(
BorderSide(
color: Color(0xff0000ff),
width: 12.0,
),
);
// Using `0.0` interpolation value.
BorderSide borderSide = WidgetStateBorderSide.lerp(
borderSide1,
borderSide2,
0.0,
)!.resolve(enabled)!;
expect(borderSide.color, const Color(0xffff0000));
expect(borderSide.width, 4.0);
// Using `0.5` interpolation value.
borderSide = WidgetStateBorderSide.lerp(
borderSide1,
borderSide2,
0.5,
)!.resolve(enabled)!;
expect(borderSide.color, const Color(0xff7f007f));
expect(borderSide.width, 8.0);
// Using `1.0` interpolation value.
borderSide = WidgetStateBorderSide.lerp(
borderSide1,
borderSide2,
1.0,
)!.resolve(enabled)!;
expect(borderSide.color, const Color(0xff0000ff));
expect(borderSide.width, 12.0);
});
}
Set<WidgetState> enabled = <WidgetState>{};