Skip to content

Commit fd58d45

Browse files
chrisbobbegnprice
authored andcommitted
model: Implement StreamColorSwatch.lerp, copying ColorSwatch.lerp
It's convenient in this method to access the colors as they're stored in a Map, like the superclass ColorSwatch does. So, in our own private field, we save the same Map that we pass along to the superclass constructor. As Greg says at zulip#642 (comment) : > The redundancy is mildly annoying, but it's only duplicating one > pointer, so it's not a material cost at runtime.
1 parent e7de8ec commit fd58d45

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

lib/api/model/model.dart

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,17 @@ class Subscription extends ZulipStream {
463463
/// Use this in UI code for colors related to [Subscription.color],
464464
/// such as the background of an unread count badge.
465465
class StreamColorSwatch extends ColorSwatch<StreamColorVariant> {
466-
StreamColorSwatch(int base) : super(base, _compute(base));
466+
StreamColorSwatch(int base) : this._(base, _compute(base));
467+
468+
const StreamColorSwatch._(int base, this._swatch) : super(base, _swatch);
469+
470+
/// A [StreamColorSwatch], from a [Map<_StreamColorVariant, Color>]
471+
/// written manually.
472+
@visibleForTesting
473+
const StreamColorSwatch.debugFromBaseAndSwatch(int base, swatch)
474+
: this._(base, swatch);
475+
476+
final Map<StreamColorVariant, Color> _swatch;
467477

468478
/// The [Subscription.color] int that the swatch is based on.
469479
Color get base => this[StreamColorVariant.base]!;
@@ -536,6 +546,24 @@ class StreamColorSwatch extends ColorSwatch<StreamColorVariant> {
536546
.toColor(),
537547
};
538548
}
549+
550+
/// Copied from [ColorSwatch.lerp].
551+
static StreamColorSwatch? lerp(StreamColorSwatch? a, StreamColorSwatch? b, double t) {
552+
if (identical(a, b)) {
553+
return a;
554+
}
555+
final Map<StreamColorVariant, Color> swatch;
556+
if (b == null) {
557+
swatch = a!._swatch.map((key, color) => MapEntry(key, Color.lerp(color, null, t)!));
558+
} else {
559+
if (a == null) {
560+
swatch = b._swatch.map((key, color) => MapEntry(key, Color.lerp(null, color, t)!));
561+
} else {
562+
swatch = a._swatch.map((key, color) => MapEntry(key, Color.lerp(color, b[key], t)!));
563+
}
564+
}
565+
return StreamColorSwatch._(Color.lerp(a, b, t)!.value, swatch);
566+
}
539567
}
540568

541569
@visibleForTesting

test/api/model/model_test.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,48 @@ void main() {
316316
runCheck(0xffa47462, const Color(0xffe7dad6));
317317
runCheck(0xffacc25d, const Color(0xffe9edd6));
318318
});
319+
320+
test('lerp (different a, b)', () {
321+
final swatchA = StreamColorSwatch(0xff76ce90);
322+
323+
// TODO(#95) use something like StreamColorSwatch.dark(), once
324+
// implemented, and remove debugFromBaseAndSwatch
325+
const swatchB = StreamColorSwatch.debugFromBaseAndSwatch(0xff76ce90, <StreamColorVariant, Color>{
326+
StreamColorVariant.base: Color(0xff76ce90),
327+
StreamColorVariant.unreadCountBadgeBackground: Color(0x4d65bd80),
328+
StreamColorVariant.iconOnPlainBackground: Color(0xff73cb8d),
329+
StreamColorVariant.iconOnBarBackground: Color(0xff73cb8d),
330+
StreamColorVariant.barBackground: Color(0xff2e4935),
331+
});
332+
333+
for (final t in [0.0, 0.5, 1.0, -0.1, 1.1]) {
334+
final result = StreamColorSwatch.lerp(swatchA, swatchB, t)!;
335+
for (final variant in StreamColorVariant.values) {
336+
final (subject, expected) = switch (variant) {
337+
StreamColorVariant.base => (check(result).base,
338+
Color.lerp(swatchA.base, swatchB.base, t)!),
339+
StreamColorVariant.unreadCountBadgeBackground => (check(result).unreadCountBadgeBackground,
340+
Color.lerp(swatchA.unreadCountBadgeBackground, swatchB.unreadCountBadgeBackground, t)!),
341+
StreamColorVariant.iconOnPlainBackground => (check(result).iconOnPlainBackground,
342+
Color.lerp(swatchA.iconOnPlainBackground, swatchB.iconOnPlainBackground, t)!),
343+
StreamColorVariant.iconOnBarBackground => (check(result).iconOnBarBackground,
344+
Color.lerp(swatchA.iconOnBarBackground, swatchB.iconOnBarBackground, t)!),
345+
StreamColorVariant.barBackground => (check(result).barBackground,
346+
Color.lerp(swatchA.barBackground, swatchB.barBackground, t)!),
347+
};
348+
subject.equals(expected);
349+
}
350+
}
351+
});
352+
353+
test('lerp (identical a, b)', () {
354+
check(StreamColorSwatch.lerp(null, null, 0.0)).isNull();
355+
356+
final swatch = StreamColorSwatch(0xff76ce90);
357+
check(StreamColorSwatch.lerp(swatch, swatch, 0.5)).isNotNull()
358+
..identicalTo(swatch)
359+
..base.equals(const Color(0xff76ce90));
360+
});
319361
});
320362
});
321363

0 commit comments

Comments
 (0)