-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslider_theme.dart
2940 lines (2754 loc) · 115 KB
/
slider_theme.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show Path, lerpDouble;
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'theme.dart';
import 'theme_data.dart';
/// {@template flutter.material.slider.seeAlso.sliderComponentShape}
/// * [SliderComponentShape], which can be used to create custom shapes for
/// the [Slider]'s thumb, overlay, and value indicator and the
/// [RangeSlider]'s overlay.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.sliderTrackShape}
/// * [SliderTrackShape], which can be used to create custom shapes for the
/// [Slider]'s track.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.sliderTickMarkShape}
/// * [SliderTickMarkShape], which can be used to create custom shapes for the
/// [Slider]'s tick marks.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.rangeSliderThumbShape}
/// * [RangeSliderThumbShape], which can be used to create custom shapes for
/// the [RangeSlider]'s thumb.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.rangeSliderValueIndicatorShape}
/// * [RangeSliderValueIndicatorShape], which can be used to create custom
/// shapes for the [RangeSlider]'s value indicator.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.rangeSliderTrackShape}
/// * [RangeSliderTrackShape], which can be used to create custom shapes for
/// the [RangeSlider]'s track.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.rangeSliderTickMarkShape}
/// * [RangeSliderTickMarkShape], which can be used to create custom shapes for
/// the [RangeSlider]'s tick marks.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.roundSliderThumbShape}
/// * [RoundSliderThumbShape], which is the default [Slider]'s thumb shape that
/// paints a solid circle.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.roundSliderOverlayShape}
/// * [RoundSliderOverlayShape], which is the default [Slider] and
/// [RangeSlider]'s overlay shape that paints a transparent circle.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.paddleSliderValueIndicatorShape}
/// * [PaddleSliderValueIndicatorShape], which is the default [Slider]'s value
/// indicator shape that paints a custom path with text in it.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.roundSliderTickMarkShape}
/// * [RoundSliderTickMarkShape], which is the default [Slider]'s tick mark
/// shape that paints a solid circle.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.roundedRectSliderTrackShape}
/// * [RoundedRectSliderTrackShape] for the default [Slider]'s track shape that
/// paints a stadium-like track.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.roundRangeSliderThumbShape}
/// * [RoundRangeSliderThumbShape] for the default [RangeSlider]'s thumb shape
/// that paints a solid circle.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.paddleRangeSliderValueIndicatorShape}
/// * [PaddleRangeSliderValueIndicatorShape] for the default [RangeSlider]'s
/// value indicator shape that paints a custom path with text in it.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.roundRangeSliderTickMarkShape}
/// * [RoundRangeSliderTickMarkShape] for the default [RangeSlider]'s tick mark
/// shape that paints a solid circle.
/// {@endtemplate}
///
/// {@template flutter.material.slider.seeAlso.roundedRectRangeSliderTrackShape}
/// * [RoundedRectRangeSliderTrackShape] for the default [RangeSlider]'s track
/// shape that paints a stadium-like track.
/// {@endtemplate}
///
/// {@template flutter.material.slider.trackSegment}
/// The track segment between the start of the slider and the thumb is the
/// active track segment. The track segment between the thumb and the end of the
/// slider is the inactive track segment. In [TextDirection.ltr], the start of
/// the slider is on the left, and in [TextDirection.rtl], the start of the
/// slider is on the right.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.trackSegment}
/// The track segment between the two thumbs is the active track segment. The
/// track segments between the thumb and each end of the slider are the inactive
/// track segments. In [TextDirection.ltr], the start of the slider is on the
/// left, and in [TextDirection.rtl], the start of the slider is on the right.
/// {@endtemplate}
/// Applies a slider theme to descendant [Slider] widgets.
///
/// A slider theme describes the colors and shape choices of the slider
/// components.
///
/// Descendant widgets obtain the current theme's [SliderThemeData] object using
/// [SliderTheme.of]. When a widget uses [SliderTheme.of], it is automatically
/// rebuilt if the theme later changes.
///
/// The slider is as big as the largest of
/// the [SliderComponentShape.getPreferredSize] of the thumb shape,
/// the [SliderComponentShape.getPreferredSize] of the overlay shape,
/// and the [SliderTickMarkShape.getPreferredSize] of the tick mark shape
///
/// See also:
///
/// * [SliderThemeData], which describes the actual configuration of a slider
/// theme.
/// {@macro flutter.material.slider.seeAlso.sliderComponentShape}
/// {@macro flutter.material.slider.seeAlso.sliderTrackShape}
/// {@macro flutter.material.slider.seeAlso.sliderTickMarkShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderThumbShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderValueIndicatorShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderTrackShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderTickMarkShape}
class SliderTheme extends InheritedTheme {
/// Applies the given theme [data] to [child].
///
/// The [data] and [child] arguments must not be null.
const SliderTheme({
Key key,
@required this.data,
@required Widget child,
}) : assert(child != null),
assert(data != null),
super(key: key, child: child);
/// Specifies the color and shape values for descendant slider widgets.
final SliderThemeData data;
/// Returns the data from the closest [SliderTheme] instance that encloses
/// the given context.
///
/// Defaults to the ambient [ThemeData.sliderTheme] if there is no
/// [SliderTheme] in the given build context.
///
/// {@tool snippet}
///
/// ```dart
/// class Launch extends StatefulWidget {
/// @override
/// State createState() => LaunchState();
/// }
///
/// class LaunchState extends State<Launch> {
/// double _rocketThrust;
///
/// @override
/// Widget build(BuildContext context) {
/// return SliderTheme(
/// data: SliderTheme.of(context).copyWith(activeTrackColor: const Color(0xff804040)),
/// child: Slider(
/// onChanged: (double value) { setState(() { _rocketThrust = value; }); },
/// value: _rocketThrust,
/// ),
/// );
/// }
/// }
/// ```
/// {@end-tool}
///
/// See also:
///
/// * [SliderThemeData], which describes the actual configuration of a slider
/// theme.
static SliderThemeData of(BuildContext context) {
final SliderTheme inheritedTheme = context.dependOnInheritedWidgetOfExactType<SliderTheme>();
return inheritedTheme != null ? inheritedTheme.data : Theme.of(context).sliderTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
final SliderTheme ancestorTheme = context.findAncestorWidgetOfExactType<SliderTheme>();
return identical(this, ancestorTheme) ? child : SliderTheme(data: data, child: child);
}
@override
bool updateShouldNotify(SliderTheme oldWidget) => data != oldWidget.data;
}
/// Describes the conditions under which the value indicator on a [Slider]
/// will be shown. Used with [SliderThemeData.showValueIndicator].
///
/// See also:
///
/// * [Slider], a Material Design slider widget.
/// * [SliderThemeData], which describes the actual configuration of a slider
/// theme.
enum ShowValueIndicator {
/// The value indicator will only be shown for discrete sliders (sliders
/// where [Slider.divisions] is non-null).
onlyForDiscrete,
/// The value indicator will only be shown for continuous sliders (sliders
/// where [Slider.divisions] is null).
onlyForContinuous,
/// The value indicator will be shown for all types of sliders.
always,
/// The value indicator will never be shown.
never,
}
/// Identifier for a thumb.
///
/// There are 2 thumbs in a [RangeSlider], [start] and [end].
///
/// For [TextDirection.ltr], the [start] thumb is the left-most thumb and the
/// [end] thumb is the right-most thumb. For [TextDirection.rtl] the [start]
/// thumb is the right-most thumb, and the [end] thumb is the left-most thumb.
enum Thumb {
/// Left-most thumb for [TextDirection.ltr], otherwise, right-most thumb.
start,
/// Right-most thumb for [TextDirection.ltr], otherwise, left-most thumb.
end,
}
/// Holds the color, shape, and typography values for a material design slider
/// theme.
///
/// Use this class to configure a [SliderTheme] widget, or to set the
/// [ThemeData.sliderTheme] for a [Theme] widget.
///
/// To obtain the current ambient slider theme, use [SliderTheme.of].
///
/// This theme is for both the [Slider] and the [RangeSlider]. The properties
/// that are only for the [Slider] are: [tickMarkShape], [thumbShape],
/// [trackShape], and [valueIndicatorShape]. The properties that are only for
/// the [RangeSlider] are [rangeTickMarkShape], [rangeThumbShape],
/// [rangeTrackShape], [rangeValueIndicatorShape],
/// [overlappingShapeStrokeColor], [minThumbSeparation], and [thumbSelector].
/// All other properties are used by both the [Slider] and the [RangeSlider].
///
/// The parts of a slider are:
///
/// * The "thumb", which is a shape that slides horizontally when the user
/// drags it.
/// * The "track", which is the line that the slider thumb slides along.
/// * The "tick marks", which are regularly spaced marks that are drawn when
/// using discrete divisions.
/// * The "value indicator", which appears when the user is dragging the thumb
/// to indicate the value being selected.
/// * The "overlay", which appears around the thumb, and is shown when the
/// thumb is pressed, focused, or hovered. It is painted underneath the
/// thumb, so it must extend beyond the bounds of the thumb itself to
/// actually be visible.
/// * The "active" side of the slider is the side between the thumb and the
/// minimum value.
/// * The "inactive" side of the slider is the side between the thumb and the
/// maximum value.
/// * The [Slider] is disabled when it is not accepting user input. See
/// [Slider] for details on when this happens.
///
/// The thumb, track, tick marks, value indicator, and overlay can be customized
/// by creating subclasses of [SliderTrackShape],
/// [SliderComponentShape], and/or [SliderTickMarkShape]. See
/// [RoundSliderThumbShape], [RectangularSliderTrackShape],
/// [RoundSliderTickMarkShape], [PaddleSliderValueIndicatorShape], and
/// [RoundSliderOverlayShape] for examples.
///
/// The track painting can be skipped by specifying 0 for [trackHeight].
/// The thumb painting can be skipped by specifying
/// [SliderComponentShape.noThumb] for [SliderThemeData.thumbShape].
/// The overlay painting can be skipped by specifying
/// [SliderComponentShape.noOverlay] for [SliderThemeData.overlayShape].
/// The tick mark painting can be skipped by specifying
/// [SliderTickMarkShape.noTickMark] for [SliderThemeData.tickMarkShape].
/// The value indicator painting can be skipped by specifying the
/// appropriate [ShowValueIndicator] for [SliderThemeData.showValueIndicator].
///
/// See also:
///
/// * [SliderTheme] widget, which can override the slider theme of its
/// children.
/// * [Theme] widget, which performs a similar function to [SliderTheme],
/// but for overall themes.
/// * [ThemeData], which has a default [SliderThemeData].
/// {@macro flutter.material.slider.seeAlso.sliderComponentShape}
/// {@macro flutter.material.slider.seeAlso.sliderTrackShape}
/// {@macro flutter.material.slider.seeAlso.sliderTickMarkShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderThumbShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderValueIndicatorShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderTrackShape}
/// {@macro flutter.material.slider.seeAlso.rangeSliderTickMarkShape}
class SliderThemeData extends Diagnosticable {
/// Create a [SliderThemeData] given a set of exact values. All the values
/// must be specified.
///
/// This will rarely be used directly. It is used by [lerp] to
/// create intermediate themes based on two themes.
///
/// The simplest way to create a SliderThemeData is to use
/// [copyWith] on the one you get from [SliderTheme.of], or create an
/// entirely new one with [SliderThemeData.fromPrimaryColors].
///
/// {@tool snippet}
///
/// ```dart
/// class Blissful extends StatefulWidget {
/// @override
/// State createState() => BlissfulState();
/// }
///
/// class BlissfulState extends State<Blissful> {
/// double _bliss;
///
/// @override
/// Widget build(BuildContext context) {
/// return SliderTheme(
/// data: SliderTheme.of(context).copyWith(activeTrackColor: const Color(0xff404080)),
/// child: Slider(
/// onChanged: (double value) { setState(() { _bliss = value; }); },
/// value: _bliss,
/// ),
/// );
/// }
/// }
/// ```
/// {@end-tool}
const SliderThemeData({
this.trackHeight,
this.activeTrackColor,
this.inactiveTrackColor,
this.disabledActiveTrackColor,
this.disabledInactiveTrackColor,
this.activeTickMarkColor,
this.inactiveTickMarkColor,
this.disabledActiveTickMarkColor,
this.disabledInactiveTickMarkColor,
this.thumbColor,
this.overlappingShapeStrokeColor,
this.disabledThumbColor,
this.overlayColor,
this.valueIndicatorColor,
this.overlayShape,
this.tickMarkShape,
this.thumbShape,
this.trackShape,
this.valueIndicatorShape,
this.rangeTickMarkShape,
this.rangeThumbShape,
this.rangeTrackShape,
this.rangeValueIndicatorShape,
this.showValueIndicator,
this.valueIndicatorTextStyle,
this.minThumbSeparation,
this.thumbSelector,
});
/// Generates a SliderThemeData from three main colors.
///
/// Usually these are the primary, dark and light colors from
/// a [ThemeData].
///
/// The opacities of these colors will be overridden with the Material Design
/// defaults when assigning them to the slider theme component colors.
///
/// This is used to generate the default slider theme for a [ThemeData].
factory SliderThemeData.fromPrimaryColors({
@required Color primaryColor,
@required Color primaryColorDark,
@required Color primaryColorLight,
@required TextStyle valueIndicatorTextStyle,
}) {
assert(primaryColor != null);
assert(primaryColorDark != null);
assert(primaryColorLight != null);
assert(valueIndicatorTextStyle != null);
// These are Material Design defaults, and are used to derive
// component Colors (with opacity) from base colors.
const int activeTrackAlpha = 0xff;
const int inactiveTrackAlpha = 0x3d; // 24% opacity
const int disabledActiveTrackAlpha = 0x52; // 32% opacity
const int disabledInactiveTrackAlpha = 0x1f; // 12% opacity
const int activeTickMarkAlpha = 0x8a; // 54% opacity
const int inactiveTickMarkAlpha = 0x8a; // 54% opacity
const int disabledActiveTickMarkAlpha = 0x1f; // 12% opacity
const int disabledInactiveTickMarkAlpha = 0x1f; // 12% opacity
const int thumbAlpha = 0xff;
const int disabledThumbAlpha = 0x52; // 32% opacity
const int overlayAlpha = 0x1f; // 12% opacity
const int valueIndicatorAlpha = 0xff;
return SliderThemeData(
trackHeight: 2.0,
activeTrackColor: primaryColor.withAlpha(activeTrackAlpha),
inactiveTrackColor: primaryColor.withAlpha(inactiveTrackAlpha),
disabledActiveTrackColor: primaryColorDark.withAlpha(disabledActiveTrackAlpha),
disabledInactiveTrackColor: primaryColorDark.withAlpha(disabledInactiveTrackAlpha),
activeTickMarkColor: primaryColorLight.withAlpha(activeTickMarkAlpha),
inactiveTickMarkColor: primaryColor.withAlpha(inactiveTickMarkAlpha),
disabledActiveTickMarkColor: primaryColorLight.withAlpha(disabledActiveTickMarkAlpha),
disabledInactiveTickMarkColor: primaryColorDark.withAlpha(disabledInactiveTickMarkAlpha),
thumbColor: primaryColor.withAlpha(thumbAlpha),
overlappingShapeStrokeColor: Colors.white,
disabledThumbColor: primaryColorDark.withAlpha(disabledThumbAlpha),
overlayColor: primaryColor.withAlpha(overlayAlpha),
valueIndicatorColor: primaryColor.withAlpha(valueIndicatorAlpha),
overlayShape: const RoundSliderOverlayShape(),
tickMarkShape: const RoundSliderTickMarkShape(),
thumbShape: const RoundSliderThumbShape(),
trackShape: const RoundedRectSliderTrackShape(),
valueIndicatorShape: const PaddleSliderValueIndicatorShape(),
rangeTickMarkShape: const RoundRangeSliderTickMarkShape(),
rangeThumbShape: const RoundRangeSliderThumbShape(),
rangeTrackShape: const RoundedRectRangeSliderTrackShape(),
rangeValueIndicatorShape: const PaddleRangeSliderValueIndicatorShape(),
valueIndicatorTextStyle: valueIndicatorTextStyle,
showValueIndicator: ShowValueIndicator.onlyForDiscrete,
);
}
/// The height of the [Slider] track.
final double trackHeight;
/// The color of the [Slider] track between the [Slider.min] position and the
/// current thumb position.
final Color activeTrackColor;
/// The color of the [Slider] track between the current thumb position and the
/// [Slider.max] position.
final Color inactiveTrackColor;
/// The color of the [Slider] track between the [Slider.min] position and the
/// current thumb position when the [Slider] is disabled.
final Color disabledActiveTrackColor;
/// The color of the [Slider] track between the current thumb position and the
/// [Slider.max] position when the [Slider] is disabled.
final Color disabledInactiveTrackColor;
/// The color of the track's tick marks that are drawn between the [Slider.min]
/// position and the current thumb position.
final Color activeTickMarkColor;
/// The color of the track's tick marks that are drawn between the current
/// thumb position and the [Slider.max] position.
final Color inactiveTickMarkColor;
/// The color of the track's tick marks that are drawn between the [Slider.min]
/// position and the current thumb position when the [Slider] is disabled.
final Color disabledActiveTickMarkColor;
/// The color of the track's tick marks that are drawn between the current
/// thumb position and the [Slider.max] position when the [Slider] is
/// disabled.
final Color disabledInactiveTickMarkColor;
/// The color given to the [thumbShape] to draw itself with.
final Color thumbColor;
/// The color given to the perimeter of the top [rangeThumbShape] when the
/// thumbs are overlapping and the top [rangeValueIndicatorShape] when the
/// value indicators are overlapping.
final Color overlappingShapeStrokeColor;
/// The color given to the [thumbShape] to draw itself with when the
/// [Slider] is disabled.
final Color disabledThumbColor;
/// The color of the overlay drawn around the slider thumb when it is pressed.
///
/// This is typically a semi-transparent color.
final Color overlayColor;
/// The color given to the [valueIndicatorShape] to draw itself with.
final Color valueIndicatorColor;
/// The shape that will be used to draw the [Slider]'s overlay.
///
/// Both the [overlayColor] and a non default [overlayShape] may be specified.
/// The default [overlayShape] refers to the [overlayColor].
///
/// The default value is [RoundSliderOverlayShape].
final SliderComponentShape overlayShape;
/// The shape that will be used to draw the [Slider]'s tick marks.
///
/// The [SliderTickMarkShape.getPreferredSize] is used to help determine the
/// location of each tick mark on the track. The slider's minimum size will
/// be at least this big.
///
/// The default value is [RoundSliderTickMarkShape].
///
/// See also:
///
/// * [RoundRangeSliderTickMarkShape], which is the default tick mark
/// shape for the range slider.
final SliderTickMarkShape tickMarkShape;
/// The shape that will be used to draw the [Slider]'s thumb.
///
/// The default value is [RoundSliderThumbShape].
///
/// See also:
///
/// * [RoundRangeSliderThumbShape], which is the default thumb shape for
/// the [RangeSlider].
final SliderComponentShape thumbShape;
/// The shape that will be used to draw the [Slider]'s track.
///
/// The [SliderTrackShape.getPreferredRect] method is used to map
/// slider-relative gesture coordinates to the correct thumb position on the
/// track. It is also used to horizontally position tick marks, when the
/// slider is discrete.
///
/// The default value is [RoundedRectSliderTrackShape].
///
/// See also:
///
/// * [RoundedRectRangeSliderTrackShape], which is the default track
/// shape for the [RangeSlider].
final SliderTrackShape trackShape;
/// The shape that will be used to draw the [Slider]'s value
/// indicator.
///
/// The default value is [PaddleSliderValueIndicatorShape].
///
/// See also:
///
/// * [PaddleRangeSliderValueIndicatorShape], which is the default value
/// indicator shape for the [RangeSlider].
final SliderComponentShape valueIndicatorShape;
/// The shape that will be used to draw the [RangeSlider]'s tick marks.
///
/// The [RangeSliderTickMarkShape.getPreferredSize] is used to help determine
/// the location of each tick mark on the track. The slider's minimum size
/// will be at least this big.
///
/// The default value is [RoundRangeSliderTickMarkShape].
///
/// See also:
///
/// * [RoundSliderTickMarkShape], which is the default tick mark shape
/// for the [Slider].
final RangeSliderTickMarkShape rangeTickMarkShape;
/// The shape that will be used for the [RangeSlider]'s thumbs.
///
/// By default the same shape is used for both thumbs, but strokes the top
/// thumb when it overlaps the bottom thumb. The top thumb is always the last
/// selected thumb.
///
/// The default value is [RoundRangeSliderThumbShape].
///
/// See also:
///
/// * [RoundSliderThumbShape], which is the default thumb shape for the
/// [Slider].
final RangeSliderThumbShape rangeThumbShape;
/// The shape that will be used to draw the [RangeSlider]'s track.
///
/// The [SliderTrackShape.getPreferredRect] method is used to to map
/// slider-relative gesture coordinates to the correct thumb position on the
/// track. It is also used to horizontally position the tick marks, when the
/// slider is discrete.
///
/// The default value is [RoundedRectRangeSliderTrackShape].
///
/// See also:
///
/// * [RoundedRectSliderTrackShape], which is the default track
/// shape for the [Slider].
final RangeSliderTrackShape rangeTrackShape;
/// The shape that will be used for the [RangeSlider]'s value indicators.
///
/// The default shape uses the same value indicator for each thumb, but
/// strokes the top value indicator when it overlaps the bottom value
/// indicator. The top indicator corresponds to the top thumb, which is always
/// the most recently selected thumb.
///
/// The default value is [PaddleRangeSliderValueIndicatorShape].
///
/// See also:
///
/// * [PaddleSliderValueIndicatorShape], which is the default value
/// indicator shape for the [Slider].
final RangeSliderValueIndicatorShape rangeValueIndicatorShape;
/// Whether the value indicator should be shown for different types of
/// sliders.
///
/// By default, [showValueIndicator] is set to
/// [ShowValueIndicator.onlyForDiscrete]. The value indicator is only shown
/// when the thumb is being touched.
final ShowValueIndicator showValueIndicator;
/// The text style for the text on the value indicator.
final TextStyle valueIndicatorTextStyle;
/// Limits the thumb's separation distance.
///
/// Use this only if you want to control the visual appearance of the thumbs
/// in terms of a logical pixel value. This can be done when you want a
/// specific look for thumbs when they are close together. To limit with the
/// real values, rather than logical pixels, the [values] can be restricted by
/// the parent.
final double minThumbSeparation;
/// Determines which thumb should be selected when the slider is interacted
/// with.
///
/// If null, the default thumb selector finds the closest thumb, excluding
/// taps that are between the thumbs and not within any one touch target.
/// When the selection is within the touch target bounds of both thumbs, no
/// thumb is selected until the selection is moved.
///
/// Override this for custom thumb selection.
final RangeThumbSelector thumbSelector;
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
SliderThemeData copyWith({
double trackHeight,
Color activeTrackColor,
Color inactiveTrackColor,
Color disabledActiveTrackColor,
Color disabledInactiveTrackColor,
Color activeTickMarkColor,
Color inactiveTickMarkColor,
Color disabledActiveTickMarkColor,
Color disabledInactiveTickMarkColor,
Color thumbColor,
Color overlappingShapeStrokeColor,
Color disabledThumbColor,
Color overlayColor,
Color valueIndicatorColor,
SliderComponentShape overlayShape,
SliderTickMarkShape tickMarkShape,
SliderComponentShape thumbShape,
SliderTrackShape trackShape,
SliderComponentShape valueIndicatorShape,
RangeSliderTickMarkShape rangeTickMarkShape,
RangeSliderThumbShape rangeThumbShape,
RangeSliderTrackShape rangeTrackShape,
RangeSliderValueIndicatorShape rangeValueIndicatorShape,
ShowValueIndicator showValueIndicator,
TextStyle valueIndicatorTextStyle,
double minThumbSeparation,
RangeThumbSelector thumbSelector,
}) {
return SliderThemeData(
trackHeight: trackHeight ?? this.trackHeight,
activeTrackColor: activeTrackColor ?? this.activeTrackColor,
inactiveTrackColor: inactiveTrackColor ?? this.inactiveTrackColor,
disabledActiveTrackColor: disabledActiveTrackColor ?? this.disabledActiveTrackColor,
disabledInactiveTrackColor: disabledInactiveTrackColor ?? this.disabledInactiveTrackColor,
activeTickMarkColor: activeTickMarkColor ?? this.activeTickMarkColor,
inactiveTickMarkColor: inactiveTickMarkColor ?? this.inactiveTickMarkColor,
disabledActiveTickMarkColor: disabledActiveTickMarkColor ?? this.disabledActiveTickMarkColor,
disabledInactiveTickMarkColor: disabledInactiveTickMarkColor ?? this.disabledInactiveTickMarkColor,
thumbColor: thumbColor ?? this.thumbColor,
overlappingShapeStrokeColor: overlappingShapeStrokeColor ?? this.overlappingShapeStrokeColor,
disabledThumbColor: disabledThumbColor ?? this.disabledThumbColor,
overlayColor: overlayColor ?? this.overlayColor,
valueIndicatorColor: valueIndicatorColor ?? this.valueIndicatorColor,
overlayShape: overlayShape ?? this.overlayShape,
tickMarkShape: tickMarkShape ?? this.tickMarkShape,
thumbShape: thumbShape ?? this.thumbShape,
trackShape: trackShape ?? this.trackShape,
valueIndicatorShape: valueIndicatorShape ?? this.valueIndicatorShape,
rangeTickMarkShape: rangeTickMarkShape ?? this.rangeTickMarkShape,
rangeThumbShape: rangeThumbShape ?? this.rangeThumbShape,
rangeTrackShape: rangeTrackShape ?? this.rangeTrackShape,
rangeValueIndicatorShape: rangeValueIndicatorShape ?? this.rangeValueIndicatorShape,
showValueIndicator: showValueIndicator ?? this.showValueIndicator,
valueIndicatorTextStyle: valueIndicatorTextStyle ?? this.valueIndicatorTextStyle,
minThumbSeparation: minThumbSeparation ?? this.minThumbSeparation,
thumbSelector: thumbSelector ?? this.thumbSelector,
);
}
/// Linearly interpolate between two slider themes.
///
/// The arguments must not be null.
///
/// {@macro dart.ui.shadow.lerp}
static SliderThemeData lerp(SliderThemeData a, SliderThemeData b, double t) {
assert(a != null);
assert(b != null);
assert(t != null);
return SliderThemeData(
trackHeight: lerpDouble(a.trackHeight, b.trackHeight, t),
activeTrackColor: Color.lerp(a.activeTrackColor, b.activeTrackColor, t),
inactiveTrackColor: Color.lerp(a.inactiveTrackColor, b.inactiveTrackColor, t),
disabledActiveTrackColor: Color.lerp(a.disabledActiveTrackColor, b.disabledActiveTrackColor, t),
disabledInactiveTrackColor: Color.lerp(a.disabledInactiveTrackColor, b.disabledInactiveTrackColor, t),
activeTickMarkColor: Color.lerp(a.activeTickMarkColor, b.activeTickMarkColor, t),
inactiveTickMarkColor: Color.lerp(a.inactiveTickMarkColor, b.inactiveTickMarkColor, t),
disabledActiveTickMarkColor: Color.lerp(a.disabledActiveTickMarkColor, b.disabledActiveTickMarkColor, t),
disabledInactiveTickMarkColor: Color.lerp(a.disabledInactiveTickMarkColor, b.disabledInactiveTickMarkColor, t),
thumbColor: Color.lerp(a.thumbColor, b.thumbColor, t),
overlappingShapeStrokeColor: Color.lerp(a.overlappingShapeStrokeColor, b.overlappingShapeStrokeColor, t),
disabledThumbColor: Color.lerp(a.disabledThumbColor, b.disabledThumbColor, t),
overlayColor: Color.lerp(a.overlayColor, b.overlayColor, t),
valueIndicatorColor: Color.lerp(a.valueIndicatorColor, b.valueIndicatorColor, t),
overlayShape: t < 0.5 ? a.overlayShape : b.overlayShape,
tickMarkShape: t < 0.5 ? a.tickMarkShape : b.tickMarkShape,
thumbShape: t < 0.5 ? a.thumbShape : b.thumbShape,
trackShape: t < 0.5 ? a.trackShape : b.trackShape,
valueIndicatorShape: t < 0.5 ? a.valueIndicatorShape : b.valueIndicatorShape,
rangeTickMarkShape: t < 0.5 ? a.rangeTickMarkShape : b.rangeTickMarkShape,
rangeThumbShape: t < 0.5 ? a.rangeThumbShape : b.rangeThumbShape,
rangeTrackShape: t < 0.5 ? a.rangeTrackShape : b.rangeTrackShape,
rangeValueIndicatorShape: t < 0.5 ? a.rangeValueIndicatorShape : b.rangeValueIndicatorShape,
showValueIndicator: t < 0.5 ? a.showValueIndicator : b.showValueIndicator,
valueIndicatorTextStyle: TextStyle.lerp(a.valueIndicatorTextStyle, b.valueIndicatorTextStyle, t),
minThumbSeparation: lerpDouble(a.minThumbSeparation, b.minThumbSeparation, t),
thumbSelector: t < 0.5 ? a.thumbSelector : b.thumbSelector,
);
}
@override
int get hashCode {
return hashList(<Object>[
trackHeight,
activeTrackColor,
inactiveTrackColor,
disabledActiveTrackColor,
disabledInactiveTrackColor,
activeTickMarkColor,
inactiveTickMarkColor,
disabledActiveTickMarkColor,
disabledInactiveTickMarkColor,
thumbColor,
overlappingShapeStrokeColor,
disabledThumbColor,
overlayColor,
valueIndicatorColor,
overlayShape,
tickMarkShape,
thumbShape,
trackShape,
valueIndicatorShape,
rangeTickMarkShape,
rangeThumbShape,
rangeTrackShape,
rangeValueIndicatorShape,
showValueIndicator,
valueIndicatorTextStyle,
minThumbSeparation,
thumbSelector,
]);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (other.runtimeType != runtimeType) {
return false;
}
return other is SliderThemeData
&& other.trackHeight == trackHeight
&& other.activeTrackColor == activeTrackColor
&& other.inactiveTrackColor == inactiveTrackColor
&& other.disabledActiveTrackColor == disabledActiveTrackColor
&& other.disabledInactiveTrackColor == disabledInactiveTrackColor
&& other.activeTickMarkColor == activeTickMarkColor
&& other.inactiveTickMarkColor == inactiveTickMarkColor
&& other.disabledActiveTickMarkColor == disabledActiveTickMarkColor
&& other.disabledInactiveTickMarkColor == disabledInactiveTickMarkColor
&& other.thumbColor == thumbColor
&& other.overlappingShapeStrokeColor == overlappingShapeStrokeColor
&& other.disabledThumbColor == disabledThumbColor
&& other.overlayColor == overlayColor
&& other.valueIndicatorColor == valueIndicatorColor
&& other.overlayShape == overlayShape
&& other.tickMarkShape == tickMarkShape
&& other.thumbShape == thumbShape
&& other.trackShape == trackShape
&& other.valueIndicatorShape == valueIndicatorShape
&& other.rangeTickMarkShape == rangeTickMarkShape
&& other.rangeThumbShape == rangeThumbShape
&& other.rangeTrackShape == rangeTrackShape
&& other.rangeValueIndicatorShape == rangeValueIndicatorShape
&& other.showValueIndicator == showValueIndicator
&& other.valueIndicatorTextStyle == valueIndicatorTextStyle
&& other.minThumbSeparation == minThumbSeparation
&& other.thumbSelector == thumbSelector;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
const SliderThemeData defaultData = SliderThemeData();
properties.add(DoubleProperty('trackHeight', trackHeight, defaultValue: defaultData.trackHeight));
properties.add(ColorProperty('activeTrackColor', activeTrackColor, defaultValue: defaultData.activeTrackColor));
properties.add(ColorProperty('inactiveTrackColor', inactiveTrackColor, defaultValue: defaultData.inactiveTrackColor));
properties.add(ColorProperty('disabledActiveTrackColor', disabledActiveTrackColor, defaultValue: defaultData.disabledActiveTrackColor));
properties.add(ColorProperty('disabledInactiveTrackColor', disabledInactiveTrackColor, defaultValue: defaultData.disabledInactiveTrackColor));
properties.add(ColorProperty('activeTickMarkColor', activeTickMarkColor, defaultValue: defaultData.activeTickMarkColor));
properties.add(ColorProperty('inactiveTickMarkColor', inactiveTickMarkColor, defaultValue: defaultData.inactiveTickMarkColor));
properties.add(ColorProperty('disabledActiveTickMarkColor', disabledActiveTickMarkColor, defaultValue: defaultData.disabledActiveTickMarkColor));
properties.add(ColorProperty('disabledInactiveTickMarkColor', disabledInactiveTickMarkColor, defaultValue: defaultData.disabledInactiveTickMarkColor));
properties.add(ColorProperty('thumbColor', thumbColor, defaultValue: defaultData.thumbColor));
properties.add(ColorProperty('overlappingShapeStrokeColor', overlappingShapeStrokeColor, defaultValue: defaultData.overlappingShapeStrokeColor));
properties.add(ColorProperty('disabledThumbColor', disabledThumbColor, defaultValue: defaultData.disabledThumbColor));
properties.add(ColorProperty('overlayColor', overlayColor, defaultValue: defaultData.overlayColor));
properties.add(ColorProperty('valueIndicatorColor', valueIndicatorColor, defaultValue: defaultData.valueIndicatorColor));
properties.add(DiagnosticsProperty<SliderComponentShape>('overlayShape', overlayShape, defaultValue: defaultData.overlayShape));
properties.add(DiagnosticsProperty<SliderTickMarkShape>('tickMarkShape', tickMarkShape, defaultValue: defaultData.tickMarkShape));
properties.add(DiagnosticsProperty<SliderComponentShape>('thumbShape', thumbShape, defaultValue: defaultData.thumbShape));
properties.add(DiagnosticsProperty<SliderTrackShape>('trackShape', trackShape, defaultValue: defaultData.trackShape));
properties.add(DiagnosticsProperty<SliderComponentShape>('valueIndicatorShape', valueIndicatorShape, defaultValue: defaultData.valueIndicatorShape));
properties.add(DiagnosticsProperty<RangeSliderTickMarkShape>('rangeTickMarkShape', rangeTickMarkShape, defaultValue: defaultData.rangeTickMarkShape));
properties.add(DiagnosticsProperty<RangeSliderThumbShape>('rangeThumbShape', rangeThumbShape, defaultValue: defaultData.rangeThumbShape));
properties.add(DiagnosticsProperty<RangeSliderTrackShape>('rangeTrackShape', rangeTrackShape, defaultValue: defaultData.rangeTrackShape));
properties.add(DiagnosticsProperty<RangeSliderValueIndicatorShape>('rangeValueIndicatorShape', rangeValueIndicatorShape, defaultValue: defaultData.rangeValueIndicatorShape));
properties.add(EnumProperty<ShowValueIndicator>('showValueIndicator', showValueIndicator, defaultValue: defaultData.showValueIndicator));
properties.add(DiagnosticsProperty<TextStyle>('valueIndicatorTextStyle', valueIndicatorTextStyle, defaultValue: defaultData.valueIndicatorTextStyle));
properties.add(DoubleProperty('minThumbSeparation', minThumbSeparation, defaultValue: defaultData.minThumbSeparation));
properties.add(DiagnosticsProperty<RangeThumbSelector>('thumbSelector', thumbSelector, defaultValue: defaultData.thumbSelector));
}
}
/// {@template flutter.material.slider.shape.center}
/// [center] is the offset for where this shape's center should be painted.
/// This offset is relative to the origin of the [context] canvas.
/// {@endtemplate}
///
/// {@template flutter.material.slider.shape.context}
/// [context] is the same as the one that includes the [Slider]'s render box.
/// {@endtemplate}
///
/// {@template flutter.material.slider.shape.enableAnimation}
/// [enableAnimation] is an animation triggered when the [Slider] is enabled,
/// and it reverses when the slider is disabled. Enabled is the
/// [Slider.isInteractive] state. Use this to paint intermediate frames for
/// this shape when the slider changes enabled state.
/// {@endtemplate}
///
/// {@template flutter.material.slider.shape.isDiscrete}
/// [isDiscrete] is true if [Slider.divisions] is non-null. If true, the
/// slider will render tick marks on top of the track.
/// {@endtemplate}
///
/// {@template flutter.material.slider.shape.isEnabled}
/// [isEnabled] has the same value as [Slider.isInteractive]. If true, the
/// slider will respond to input.
/// {@endtemplate}
///
/// {@template flutter.material.slider.shape.parentBox}
/// [parentBox] is the [RenderBox] of the [Slider]. Its attributes, such as
/// size, can be used to assist in painting this shape.
/// {@endtemplate}
//
/// {@template flutter.material.slider.shape.sliderTheme}
/// [sliderTheme] is the theme assigned to the [Slider] that this shape
/// belongs to.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.activationAnimation}
/// [activationAnimation] is an animation triggered when the user begins
/// to interact with the [RangeSlider]. It reverses when the user stops
/// interacting with the slider.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.context}
/// [context] is the same as the one that includes the [RangeSlider]'s render
/// box.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.enableAnimation}
/// [enableAnimation] is an animation triggered when the [RangeSlider] is
/// enabled, and it reverses when the slider is disabled. Enabled is the
/// [RangeSlider.isEnabled] state. Use this to paint intermediate frames for
/// this shape when the slider changes enabled state.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.isDiscrete}
/// [isDiscrete] is true if [RangeSlider.divisions] is non-null. If true, the
/// slider will render tick marks on top of the track.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.isEnabled}
/// [isEnabled] has the same value as [RangeSlider.isEnabled]. If true, the
/// slider will respond to input.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.parentBox}
/// [parentBox] is the [RenderBox] of the [RangeSlider]. Its attributes, such as
/// size, can be used to assist in painting this shape.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.sliderTheme}
/// [sliderTheme] is the theme assigned to the [RangeSlider] that this shape
/// belongs to.
/// {@endtemplate}
///
/// {@template flutter.material.rangeSlider.shape.thumb}
/// [thumb] Is the specifier for which of the two thumbs this method should
/// paint, start or end.
/// {@endtemplate}
/// Base class for slider thumb, thumb overlay, and value indicator shapes.
///
/// Create a subclass of this if you would like a custom shape.
///
/// All shapes are painted to the same canvas and ordering is important.
/// The overlay is painted first, then the value indicator, then the thumb.
///
/// The thumb painting can be skipped by specifying [noThumb] for
/// [SliderThemeData.thumbShape].
///
/// The overlay painting can be skipped by specifying [noOverlay] for
/// [SliderThemeData.overlayShape].
///
/// See also:
///
/// {@macro flutter.material.slider.seeAlso.roundSliderThumbShape}
/// {@macro flutter.material.slider.seeAlso.roundSliderOverlayShape}
/// {@macro flutter.material.slider.seeAlso.paddleSliderValueIndicatorShape}
abstract class SliderComponentShape {
/// This abstract const constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const SliderComponentShape();
/// Returns the preferred size of the shape, based on the given conditions.
Size getPreferredSize(bool isEnabled, bool isDiscrete);
/// Paints the shape, taking into account the state passed to it.
///
/// {@macro flutter.material.slider.shape.context}
///
/// {@macro flutter.material.slider.shape.center}
///
/// [activationAnimation] is an animation triggered when the user begins
/// to interact with the slider. It reverses when the user stops interacting
/// with the slider.
///
/// {@macro flutter.material.slider.shape.enableAnimation}
///
/// {@macro flutter.material.slider.shape.isDiscrete}
///
/// If [labelPainter] is non-null, then [labelPainter.paint] should be
/// called with the location that the label should appear. If the labelPainter
/// parameter is null, then no label was supplied to the [Slider].
///
/// {@macro flutter.material.slider.shape.parentBox}
///
/// {@macro flutter.material.slider.shape.sliderTheme}
///
/// [textDirection] can be used to determine how any extra text or graphics,
/// besides the text painted by the [labelPainter] should be positioned. The
/// [labelPainter] already has the [textDirection] set.
///
/// [value] is the current parametric value (from 0.0 to 1.0) of the slider.
void paint(
PaintingContext context,
Offset center, {
Animation<double> activationAnimation,
Animation<double> enableAnimation,
bool isDiscrete,
TextPainter labelPainter,
RenderBox parentBox,
SliderThemeData sliderTheme,
TextDirection textDirection,
double value,
});
/// Special instance of [SliderComponentShape] to skip the thumb drawing.
///
/// See also:
///
/// * [SliderThemeData.thumbShape], which is the shape that the [Slider]
/// uses when painting the thumb.
static final SliderComponentShape noThumb = _EmptySliderComponentShape();
/// Special instance of [SliderComponentShape] to skip the overlay drawing.