Skip to content

Commit ea7cf54

Browse files
authored
Introduce WidgetStateBorderSide.lerp (flutter#148122)
fixes [Consolidate `_LerpSides` classes with `WigetStateProperty<BorderSide?>` type into a new `WidgetStateBorderSide.lerp`](flutter#148057)
1 parent 4354835 commit ea7cf54

File tree

5 files changed

+82
-77
lines changed

5 files changed

+82
-77
lines changed

packages/flutter/lib/src/material/button_style.dart

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -603,30 +603,6 @@ class ButtonStyle with Diagnosticable {
603603
if (a == null && b == null) {
604604
return null;
605605
}
606-
return _LerpSides(a, b, t);
607-
}
608-
}
609-
610-
class _LerpSides implements MaterialStateProperty<BorderSide?> {
611-
const _LerpSides(this.a, this.b, this.t);
612-
613-
final MaterialStateProperty<BorderSide?>? a;
614-
final MaterialStateProperty<BorderSide?>? b;
615-
final double t;
616-
617-
@override
618-
BorderSide? resolve(Set<MaterialState> states) {
619-
final BorderSide? resolvedA = a?.resolve(states);
620-
final BorderSide? resolvedB = b?.resolve(states);
621-
if (resolvedA == null && resolvedB == null) {
622-
return null;
623-
}
624-
if (resolvedA == null) {
625-
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
626-
}
627-
if (resolvedB == null) {
628-
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
629-
}
630-
return BorderSide.lerp(resolvedA, resolvedB, t);
606+
return MaterialStateBorderSide.lerp(a, b, t);
631607
}
632608
}

packages/flutter/lib/src/material/menu_style.dart

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class MenuStyle with Diagnosticable {
316316
minimumSize: MaterialStateProperty.lerp<Size?>(a?.minimumSize, b?.minimumSize, t, Size.lerp),
317317
fixedSize: MaterialStateProperty.lerp<Size?>(a?.fixedSize, b?.fixedSize, t, Size.lerp),
318318
maximumSize: MaterialStateProperty.lerp<Size?>(a?.maximumSize, b?.maximumSize, t, Size.lerp),
319-
side: _LerpSides(a?.side, b?.side, t),
319+
side: MaterialStateBorderSide.lerp(a?.side, b?.side, t),
320320
shape: MaterialStateProperty.lerp<OutlinedBorder?>(a?.shape, b?.shape, t, OutlinedBorder.lerp),
321321
mouseCursor: t < 0.5 ? a?.mouseCursor : b?.mouseCursor,
322322
visualDensity: t < 0.5 ? a?.visualDensity : b?.visualDensity,
@@ -342,29 +342,3 @@ class MenuStyle with Diagnosticable {
342342
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
343343
}
344344
}
345-
346-
/// A required helper class because [BorderSide.lerp] doesn't support passing or
347-
/// returning null values.
348-
class _LerpSides implements MaterialStateProperty<BorderSide?> {
349-
const _LerpSides(this.a, this.b, this.t);
350-
351-
final MaterialStateProperty<BorderSide?>? a;
352-
final MaterialStateProperty<BorderSide?>? b;
353-
final double t;
354-
355-
@override
356-
BorderSide? resolve(Set<MaterialState> states) {
357-
final BorderSide? resolvedA = a?.resolve(states);
358-
final BorderSide? resolvedB = b?.resolve(states);
359-
if (resolvedA == null && resolvedB == null) {
360-
return null;
361-
}
362-
if (resolvedA == null) {
363-
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
364-
}
365-
if (resolvedB == null) {
366-
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
367-
}
368-
return BorderSide.lerp(resolvedA, resolvedB, t);
369-
}
370-
}

packages/flutter/lib/src/material/search_bar_theme.dart

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -203,31 +203,7 @@ class SearchBarThemeData with Diagnosticable {
203203
if (identical(a, b)) {
204204
return a;
205205
}
206-
return _LerpSides(a, b, t);
207-
}
208-
}
209-
210-
class _LerpSides implements MaterialStateProperty<BorderSide?> {
211-
const _LerpSides(this.a, this.b, this.t);
212-
213-
final MaterialStateProperty<BorderSide?>? a;
214-
final MaterialStateProperty<BorderSide?>? b;
215-
final double t;
216-
217-
@override
218-
BorderSide? resolve(Set<MaterialState> states) {
219-
final BorderSide? resolvedA = a?.resolve(states);
220-
final BorderSide? resolvedB = b?.resolve(states);
221-
if (identical(resolvedA, resolvedB)) {
222-
return resolvedA;
223-
}
224-
if (resolvedA == null) {
225-
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
226-
}
227-
if (resolvedB == null) {
228-
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
229-
}
230-
return BorderSide.lerp(resolvedA, resolvedB, t);
206+
return MaterialStateBorderSide.lerp(a, b, t);
231207
}
232208
}
233209

packages/flutter/lib/src/widgets/widget_state.dart

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,43 @@ abstract class WidgetStateBorderSide extends BorderSide implements WidgetStatePr
353353
/// widget or theme.
354354
@override
355355
BorderSide? resolve(Set<WidgetState> states);
356+
357+
/// Linearly interpolate between two [WidgetStateProperty]s of [BorderSide].
358+
static WidgetStateProperty<BorderSide?>? lerp(
359+
WidgetStateProperty<BorderSide?>? a,
360+
WidgetStateProperty<BorderSide?>? b,
361+
double t,
362+
) {
363+
// Avoid creating a _LerpSides object for a common case.
364+
if (a == null && b == null) {
365+
return null;
366+
}
367+
return _LerpSides(a, b, t);
368+
}
369+
}
370+
371+
class _LerpSides implements WidgetStateProperty<BorderSide?> {
372+
const _LerpSides(this.a, this.b, this.t);
373+
374+
final WidgetStateProperty<BorderSide?>? a;
375+
final WidgetStateProperty<BorderSide?>? b;
376+
final double t;
377+
378+
@override
379+
BorderSide? resolve(Set<WidgetState> states) {
380+
final BorderSide? resolvedA = a?.resolve(states);
381+
final BorderSide? resolvedB = b?.resolve(states);
382+
if (resolvedA == null && resolvedB == null) {
383+
return null;
384+
}
385+
if (resolvedA == null) {
386+
return BorderSide.lerp(BorderSide(width: 0, color: resolvedB!.color.withAlpha(0)), resolvedB, t);
387+
}
388+
if (resolvedB == null) {
389+
return BorderSide.lerp(resolvedA, BorderSide(width: 0, color: resolvedA.color.withAlpha(0)), t);
390+
}
391+
return BorderSide.lerp(resolvedA, resolvedB, t);
392+
}
356393
}
357394

358395
class _WidgetStateBorderSide extends WidgetStateBorderSide {

packages/flutter/test/widgets/widget_state_property_test.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,48 @@ void main() {
8686
)!.resolve(enabled)!;
8787
expect(textStyle.fontSize, 20.0);
8888
});
89+
90+
test('WidgetStateBorderSide.lerp()', () {
91+
const WidgetStateProperty<BorderSide?> borderSide1 = WidgetStatePropertyAll<BorderSide?>(
92+
BorderSide(
93+
color: Color(0xffff0000),
94+
width: 4.0,
95+
),
96+
);
97+
const WidgetStateProperty<BorderSide?> borderSide2 = WidgetStatePropertyAll<BorderSide?>(
98+
BorderSide(
99+
color: Color(0xff0000ff),
100+
width: 12.0,
101+
),
102+
);
103+
104+
// Using `0.0` interpolation value.
105+
BorderSide borderSide = WidgetStateBorderSide.lerp(
106+
borderSide1,
107+
borderSide2,
108+
0.0,
109+
)!.resolve(enabled)!;
110+
expect(borderSide.color, const Color(0xffff0000));
111+
expect(borderSide.width, 4.0);
112+
113+
// Using `0.5` interpolation value.
114+
borderSide = WidgetStateBorderSide.lerp(
115+
borderSide1,
116+
borderSide2,
117+
0.5,
118+
)!.resolve(enabled)!;
119+
expect(borderSide.color, const Color(0xff7f007f));
120+
expect(borderSide.width, 8.0);
121+
122+
// Using `1.0` interpolation value.
123+
borderSide = WidgetStateBorderSide.lerp(
124+
borderSide1,
125+
borderSide2,
126+
1.0,
127+
)!.resolve(enabled)!;
128+
expect(borderSide.color, const Color(0xff0000ff));
129+
expect(borderSide.width, 12.0);
130+
});
89131
}
90132

91133
Set<WidgetState> enabled = <WidgetState>{};

0 commit comments

Comments
 (0)