1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/// @docImport 'basic.dart';
6library;
7
8import 'package:flutter/foundation.dart';
9import 'package:flutter/rendering.dart';
10
11import 'framework.dart';
12
13/// Applies a [ColorFilter] to its child.
14///
15/// This widget applies a function independently to each pixel of [child]'s
16/// content, according to the [ColorFilter] specified.
17/// Use the [ColorFilter.mode] constructor to apply a [Color] using a [BlendMode].
18/// Use the [BackdropFilter] widget instead, if the [ColorFilter]
19/// needs to be applied onto the content beneath [child].
20///
21/// {@youtube 560 315 https://www.youtube.com/watch?v=F7Cll22Dno8}
22///
23/// {@tool dartpad}
24/// These two images have two [ColorFilter]s applied with different [BlendMode]s,
25/// one with red color and [BlendMode.modulate] another with a grey color and [BlendMode.saturation].
26///
27/// ** See code in examples/api/lib/widgets/color_filter/color_filtered.0.dart **
28///{@end-tool}
29///
30/// See also:
31///
32/// * [BlendMode], describes how to blend a source image with the destination image.
33/// * [ColorFilter], which describes a function that modify a color to a different color.
34
35@immutable
36class ColorFiltered extends SingleChildRenderObjectWidget {
37 /// Creates a widget that applies a [ColorFilter] to its child.
38 const ColorFiltered({required this.colorFilter, super.child, super.key});
39
40 /// The color filter to apply to the child of this widget.
41 final ColorFilter colorFilter;
42
43 @override
44 RenderObject createRenderObject(BuildContext context) => _ColorFilterRenderObject(colorFilter);
45
46 @override
47 void updateRenderObject(BuildContext context, RenderObject renderObject) {
48 (renderObject as _ColorFilterRenderObject).colorFilter = colorFilter;
49 }
50
51 @override
52 void debugFillProperties(DiagnosticPropertiesBuilder properties) {
53 super.debugFillProperties(properties);
54 properties.add(DiagnosticsProperty<ColorFilter>('colorFilter', colorFilter));
55 }
56}
57
58class _ColorFilterRenderObject extends RenderProxyBox {
59 _ColorFilterRenderObject(this._colorFilter);
60
61 ColorFilter get colorFilter => _colorFilter;
62 ColorFilter _colorFilter;
63 set colorFilter(ColorFilter value) {
64 if (value != _colorFilter) {
65 _colorFilter = value;
66 markNeedsPaint();
67 }
68 }
69
70 @override
71 bool get alwaysNeedsCompositing => child != null;
72
73 @override
74 void paint(PaintingContext context, Offset offset) {
75 layer = context.pushColorFilter(offset, colorFilter, super.paint, oldLayer: layer as ColorFilterLayer?);
76 assert(() {
77 layer!.debugCreator = debugCreator;
78 return true;
79 }());
80 }
81}
82