fix: format flutter_colorpicker to fix CI failure, update the android example project to use latest version of Kotlin, fix AndroidManifest string resources

pull/1874/head
Ellet 11 months ago
parent bd2b3a2b4c
commit 7aa261a746
  1. 4
      example/android/app/build.gradle
  2. 2
      example/android/app/src/main/AndroidManifest.xml
  3. 3
      example/android/settings.gradle
  4. 1
      example/devtools_options.yaml
  5. 41
      lib/src/packages/flutter_colorpicker/src/block_picker.dart
  6. 289
      lib/src/packages/flutter_colorpicker/src/colorpicker.dart
  7. 3
      lib/src/packages/flutter_colorpicker/src/colors.dart
  8. 230
      lib/src/packages/flutter_colorpicker/src/material_picker.dart
  9. 274
      lib/src/packages/flutter_colorpicker/src/palette.dart
  10. 15
      lib/src/packages/flutter_colorpicker/src/utils.dart
  11. 3
      lib/src/widgets/toolbar/buttons/color/color_dialog.dart

@ -35,7 +35,7 @@ android {
defaultConfig {
applicationId = "com.example.example"
minSdk = flutter.minSdkVersion
minSdk = 23
targetSdk = flutter.targetSdkVersion
versionCode = flutterVersionCode.toInteger()
versionName = flutterVersionName
@ -43,8 +43,6 @@ android {
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.debug
}
}

@ -23,7 +23,7 @@
<application
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
android:label="Flutter Quill Example">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"

@ -19,7 +19,8 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
// TODO: We should update the project to not require higher version of Kotlin
id "org.jetbrains.kotlin.android" version "1.9.24" apply false
}
include ":app"

@ -11,10 +11,12 @@ import 'utils.dart';
typedef PickerItem = Widget Function(Color color);
/// Customize the layout.
typedef PickerLayoutBuilder = Widget Function(BuildContext context, List<Color> colors, PickerItem child);
typedef PickerLayoutBuilder = Widget Function(
BuildContext context, List<Color> colors, PickerItem child);
/// Customize the item shape.
typedef PickerItemBuilder = Widget Function(Color color, bool isCurrentColor, void Function() changeColor);
typedef PickerItemBuilder = Widget Function(
Color color, bool isCurrentColor, void Function() changeColor);
// Provide a list of colors for block color picker.
const List<Color> _defaultColors = [
@ -41,7 +43,8 @@ const List<Color> _defaultColors = [
];
// Provide a layout for [BlockPicker].
Widget _defaultLayoutBuilder(BuildContext context, List<Color> colors, PickerItem child) {
Widget _defaultLayoutBuilder(
BuildContext context, List<Color> colors, PickerItem child) {
Orientation orientation = MediaQuery.of(context).orientation;
return SizedBox(
@ -57,13 +60,19 @@ Widget _defaultLayoutBuilder(BuildContext context, List<Color> colors, PickerIte
}
// Provide a shape for [BlockPicker].
Widget _defaultItemBuilder(Color color, bool isCurrentColor, void Function() changeColor) {
Widget _defaultItemBuilder(
Color color, bool isCurrentColor, void Function() changeColor) {
return Container(
margin: const EdgeInsets.all(7),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color,
boxShadow: [BoxShadow(color: color.withOpacity(0.8), offset: const Offset(1, 2), blurRadius: 5)],
boxShadow: [
BoxShadow(
color: color.withOpacity(0.8),
offset: const Offset(1, 2),
blurRadius: 5)
],
),
child: Material(
color: Colors.transparent,
@ -73,7 +82,8 @@ Widget _defaultItemBuilder(Color color, bool isCurrentColor, void Function() cha
child: AnimatedOpacity(
duration: const Duration(milliseconds: 210),
opacity: isCurrentColor ? 1 : 0,
child: Icon(Icons.done, color: useWhiteForeground(color) ? Colors.white : Colors.black),
child: Icon(Icons.done,
color: useWhiteForeground(color) ? Colors.white : Colors.black),
),
),
),
@ -124,9 +134,12 @@ class _BlockPickerState extends State<BlockPicker> {
widget.availableColors,
(Color color) => widget.itemBuilder(
color,
(_currentColor != null && (widget.useInShowDialog ? true : widget.pickerColor != null))
(_currentColor != null &&
(widget.useInShowDialog ? true : widget.pickerColor != null))
? (_currentColor?.value == color.value) &&
(widget.useInShowDialog ? true : widget.pickerColor?.value == color.value)
(widget.useInShowDialog
? true
: widget.pickerColor?.value == color.value)
: false,
() => changeColor(color),
),
@ -169,7 +182,9 @@ class _MultipleChoiceBlockPickerState extends State<MultipleChoiceBlockPicker> {
void toggleColor(Color color) {
setState(() {
if (_currentColors != null) {
_currentColors!.contains(color) ? _currentColors!.remove(color) : _currentColors!.add(color);
_currentColors!.contains(color)
? _currentColors!.remove(color)
: _currentColors!.add(color);
}
});
widget.onColorsChanged(_currentColors ?? []);
@ -182,8 +197,12 @@ class _MultipleChoiceBlockPickerState extends State<MultipleChoiceBlockPicker> {
widget.availableColors,
(Color color) => widget.itemBuilder(
color,
(_currentColors != null && (widget.useInShowDialog ? true : widget.pickerColors != null))
? _currentColors!.contains(color) && (widget.useInShowDialog ? true : widget.pickerColors!.contains(color))
(_currentColors != null &&
(widget.useInShowDialog ? true : widget.pickerColors != null))
? _currentColors!.contains(color) &&
(widget.useInShowDialog
? true
: widget.pickerColors!.contains(color))
: false,
() => toggleColor(color),
),

@ -20,9 +20,16 @@ class ColorPicker extends StatefulWidget {
this.onHsvColorChanged,
this.paletteType = PaletteType.hsvWithHue,
this.enableAlpha = true,
@Deprecated('Use empty list in [labelTypes] to disable label.') this.showLabel = true,
this.labelTypes = const [ColorLabelType.rgb, ColorLabelType.hsv, ColorLabelType.hsl],
@Deprecated('Use Theme.of(context).textTheme.bodyText1 & 2 to alter text style.') this.labelTextStyle,
@Deprecated('Use empty list in [labelTypes] to disable label.')
this.showLabel = true,
this.labelTypes = const [
ColorLabelType.rgb,
ColorLabelType.hsv,
ColorLabelType.hsl
],
@Deprecated(
'Use Theme.of(context).textTheme.bodyText1 & 2 to alter text style.')
this.labelTextStyle,
this.displayThumbColor = false,
this.portraitOnly = false,
this.colorPickerWidth = 300.0,
@ -168,8 +175,9 @@ class _ColorPickerState extends State<ColorPicker> {
@override
void initState() {
currentHsvColor =
(widget.pickerHsvColor != null) ? widget.pickerHsvColor as HSVColor : HSVColor.fromColor(widget.pickerColor);
currentHsvColor = (widget.pickerHsvColor != null)
? widget.pickerHsvColor as HSVColor
: HSVColor.fromColor(widget.pickerColor);
// If there's no initial text in `hexInputController`,
if (widget.hexInputController?.text.isEmpty == true) {
// set it to the current's color HEX value.
@ -189,8 +197,9 @@ class _ColorPickerState extends State<ColorPicker> {
@override
void didUpdateWidget(ColorPicker oldWidget) {
super.didUpdateWidget(oldWidget);
currentHsvColor =
(widget.pickerHsvColor != null) ? widget.pickerHsvColor as HSVColor : HSVColor.fromColor(widget.pickerColor);
currentHsvColor = (widget.pickerHsvColor != null)
? widget.pickerHsvColor as HSVColor
: HSVColor.fromColor(widget.pickerColor);
}
void colorPickerTextInputListener() {
@ -199,14 +208,16 @@ class _ColorPickerState extends State<ColorPicker> {
if (widget.hexInputController == null) return;
// If a user is inserting/typing any text try to get the color value from it,
// and interpret its transparency, dependent on the widget's settings.
final Color? color = colorFromHex(widget.hexInputController!.text, enableAlpha: widget.enableAlpha);
final Color? color = colorFromHex(widget.hexInputController!.text,
enableAlpha: widget.enableAlpha);
// If it's the valid color:
if (color != null) {
// set it as the current color and
setState(() => currentHsvColor = HSVColor.fromColor(color));
// notify with a callback.
widget.onColorChanged(color);
if (widget.onHsvColorChanged != null) widget.onHsvColorChanged!(currentHsvColor);
if (widget.onHsvColorChanged != null)
widget.onHsvColorChanged!(currentHsvColor);
}
}
@ -222,10 +233,12 @@ class _ColorPickerState extends State<ColorPicker> {
currentHsvColor,
(HSVColor color) {
// Update text in `hexInputController` if provided.
widget.hexInputController?.text = colorToHex(color.toColor(), enableAlpha: widget.enableAlpha);
widget.hexInputController?.text =
colorToHex(color.toColor(), enableAlpha: widget.enableAlpha);
setState(() => currentHsvColor = color);
widget.onColorChanged(currentHsvColor.toColor());
if (widget.onHsvColorChanged != null) widget.onHsvColorChanged!(currentHsvColor);
if (widget.onHsvColorChanged != null)
widget.onHsvColorChanged!(currentHsvColor);
},
displayThumbColor: widget.displayThumbColor,
);
@ -233,18 +246,22 @@ class _ColorPickerState extends State<ColorPicker> {
void onColorChanging(HSVColor color) {
// Update text in `hexInputController` if provided.
widget.hexInputController?.text = colorToHex(color.toColor(), enableAlpha: widget.enableAlpha);
widget.hexInputController?.text =
colorToHex(color.toColor(), enableAlpha: widget.enableAlpha);
setState(() => currentHsvColor = color);
widget.onColorChanged(currentHsvColor.toColor());
if (widget.onHsvColorChanged != null) widget.onHsvColorChanged!(currentHsvColor);
if (widget.onHsvColorChanged != null)
widget.onHsvColorChanged!(currentHsvColor);
}
Widget colorPicker() {
return ClipRRect(
borderRadius: widget.pickerAreaBorderRadius,
child: Padding(
padding: EdgeInsets.all(widget.paletteType == PaletteType.hueWheel ? 10 : 0),
child: ColorPickerArea(currentHsvColor, onColorChanging, widget.paletteType),
padding:
EdgeInsets.all(widget.paletteType == PaletteType.hueWheel ? 10 : 0),
child: ColorPickerArea(
currentHsvColor, onColorChanging, widget.paletteType),
),
);
}
@ -278,7 +295,8 @@ class _ColorPickerState extends State<ColorPicker> {
@override
Widget build(BuildContext context) {
if (MediaQuery.of(context).orientation == Orientation.portrait || widget.portraitOnly) {
if (MediaQuery.of(context).orientation == Orientation.portrait ||
widget.portraitOnly) {
return Column(
children: <Widget>[
SizedBox(
@ -293,7 +311,8 @@ class _ColorPickerState extends State<ColorPicker> {
children: <Widget>[
GestureDetector(
onTap: () => setState(() {
if (widget.onHistoryChanged != null && !colorHistory.contains(currentHsvColor.toColor())) {
if (widget.onHistoryChanged != null &&
!colorHistory.contains(currentHsvColor.toColor())) {
colorHistory.add(currentHsvColor.toColor());
widget.onHistoryChanged!(colorHistory);
}
@ -303,7 +322,10 @@ class _ColorPickerState extends State<ColorPicker> {
Expanded(
child: Column(
children: <Widget>[
SizedBox(height: 40.0, width: widget.colorPickerWidth - 75.0, child: sliderByPaletteType()),
SizedBox(
height: 40.0,
width: widget.colorPickerWidth - 75.0,
child: sliderByPaletteType()),
if (widget.enableAlpha)
SizedBox(
height: 40.0,
@ -320,7 +342,8 @@ class _ColorPickerState extends State<ColorPicker> {
SizedBox(
width: widget.colorPickerWidth,
height: 50,
child: ListView(scrollDirection: Axis.horizontal, children: <Widget>[
child:
ListView(scrollDirection: Axis.horizontal, children: <Widget>[
for (Color color in colorHistory)
Padding(
key: Key(color.hashCode.toString()),
@ -328,7 +351,8 @@ class _ColorPickerState extends State<ColorPicker> {
child: Center(
child: GestureDetector(
onTap: () => onColorChanging(HSVColor.fromColor(color)),
child: ColorIndicator(HSVColor.fromColor(color), width: 30, height: 30),
child: ColorIndicator(HSVColor.fromColor(color),
width: 30, height: 30),
),
),
),
@ -350,7 +374,8 @@ class _ColorPickerState extends State<ColorPicker> {
(Color color) {
setState(() => currentHsvColor = HSVColor.fromColor(color));
widget.onColorChanged(currentHsvColor.toColor());
if (widget.onHsvColorChanged != null) widget.onHsvColorChanged!(currentHsvColor);
if (widget.onHsvColorChanged != null)
widget.onHsvColorChanged!(currentHsvColor);
},
enableAlpha: widget.enableAlpha,
embeddedText: false,
@ -372,7 +397,8 @@ class _ColorPickerState extends State<ColorPicker> {
const SizedBox(width: 20.0),
GestureDetector(
onTap: () => setState(() {
if (widget.onHistoryChanged != null && !colorHistory.contains(currentHsvColor.toColor())) {
if (widget.onHistoryChanged != null &&
!colorHistory.contains(currentHsvColor.toColor())) {
colorHistory.add(currentHsvColor.toColor());
widget.onHistoryChanged!(colorHistory);
}
@ -381,9 +407,15 @@ class _ColorPickerState extends State<ColorPicker> {
),
Column(
children: <Widget>[
SizedBox(height: 40.0, width: 260.0, child: sliderByPaletteType()),
SizedBox(
height: 40.0,
width: 260.0,
child: sliderByPaletteType()),
if (widget.enableAlpha)
SizedBox(height: 40.0, width: 260.0, child: colorPickerSlider(TrackType.alpha)),
SizedBox(
height: 40.0,
width: 260.0,
child: colorPickerSlider(TrackType.alpha)),
],
),
const SizedBox(width: 10.0),
@ -393,26 +425,30 @@ class _ColorPickerState extends State<ColorPicker> {
SizedBox(
width: widget.colorPickerWidth,
height: 50,
child: ListView(scrollDirection: Axis.horizontal, children: <Widget>[
for (Color color in colorHistory)
Padding(
key: Key(color.hashCode.toString()),
padding: const EdgeInsets.fromLTRB(15, 18, 0, 0),
child: Center(
child: GestureDetector(
onTap: () => onColorChanging(HSVColor.fromColor(color)),
onLongPress: () {
if (colorHistory.remove(color)) {
widget.onHistoryChanged!(colorHistory);
setState(() {});
}
},
child: ColorIndicator(HSVColor.fromColor(color), width: 30, height: 30),
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
for (Color color in colorHistory)
Padding(
key: Key(color.hashCode.toString()),
padding: const EdgeInsets.fromLTRB(15, 18, 0, 0),
child: Center(
child: GestureDetector(
onTap: () =>
onColorChanging(HSVColor.fromColor(color)),
onLongPress: () {
if (colorHistory.remove(color)) {
widget.onHistoryChanged!(colorHistory);
setState(() {});
}
},
child: ColorIndicator(HSVColor.fromColor(color),
width: 30, height: 30),
),
),
),
),
),
const SizedBox(width: 15),
]),
const SizedBox(width: 15),
]),
),
const SizedBox(height: 20.0),
if (widget.showLabel && widget.labelTypes.isNotEmpty)
@ -430,7 +466,8 @@ class _ColorPickerState extends State<ColorPicker> {
(Color color) {
setState(() => currentHsvColor = HSVColor.fromColor(color));
widget.onColorChanged(currentHsvColor.toColor());
if (widget.onHsvColorChanged != null) widget.onHsvColorChanged!(currentHsvColor);
if (widget.onHsvColorChanged != null)
widget.onHsvColorChanged!(currentHsvColor);
},
enableAlpha: widget.enableAlpha,
embeddedText: false,
@ -454,11 +491,16 @@ class SlidePicker extends StatefulWidget {
this.enableAlpha = true,
this.sliderSize = const Size(260, 40),
this.showSliderText = true,
@Deprecated('Use Theme.of(context).textTheme.bodyText1 & 2 to alter text style.') this.sliderTextStyle,
@Deprecated(
'Use Theme.of(context).textTheme.bodyText1 & 2 to alter text style.')
this.sliderTextStyle,
this.showParams = true,
@Deprecated('Use empty list in [labelTypes] to disable label.') this.showLabel = true,
@Deprecated('Use empty list in [labelTypes] to disable label.')
this.showLabel = true,
this.labelTypes = const [],
@Deprecated('Use Theme.of(context).textTheme.bodyText1 & 2 to alter text style.') this.labelTextStyle,
@Deprecated(
'Use Theme.of(context).textTheme.bodyText1 & 2 to alter text style.')
this.labelTextStyle,
this.showIndicator = true,
this.indicatorSize = const Size(280, 50),
this.indicatorAlignmentBegin = const Alignment(-1.0, -3.0),
@ -523,7 +565,8 @@ class _SlidePickerState extends State<SlidePicker> {
clipBehavior: Clip.antiAliasWithSaveLayer,
child: GestureDetector(
onTap: () {
setState(() => currentHsvColor = HSVColor.fromColor(widget.pickerColor));
setState(
() => currentHsvColor = HSVColor.fromColor(widget.pickerColor));
widget.onColorChanged(currentHsvColor.toColor());
},
child: Container(
@ -582,13 +625,26 @@ class _SlidePickerState extends State<SlidePicker> {
@override
Widget build(BuildContext context) {
double fontSize = 14;
if (widget.labelTextStyle != null && widget.labelTextStyle?.fontSize != null) {
if (widget.labelTextStyle != null &&
widget.labelTextStyle?.fontSize != null) {
fontSize = widget.labelTextStyle?.fontSize ?? 14;
}
final List<TrackType> trackTypes = [
if (widget.colorModel == ColorModel.hsv) ...[TrackType.hue, TrackType.saturation, TrackType.value],
if (widget.colorModel == ColorModel.hsl) ...[TrackType.hue, TrackType.saturationForHSL, TrackType.lightness],
if (widget.colorModel == ColorModel.rgb) ...[TrackType.red, TrackType.green, TrackType.blue],
if (widget.colorModel == ColorModel.hsv) ...[
TrackType.hue,
TrackType.saturation,
TrackType.value
],
if (widget.colorModel == ColorModel.hsl) ...[
TrackType.hue,
TrackType.saturationForHSL,
TrackType.lightness
],
if (widget.colorModel == ColorModel.rgb) ...[
TrackType.red,
TrackType.green,
TrackType.blue
],
if (widget.enableAlpha) ...[TrackType.alpha],
];
List<SizedBox> sliders = [
@ -603,7 +659,8 @@ class _SlidePickerState extends State<SlidePicker> {
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Text(
trackType.toString().split('.').last[0].toUpperCase(),
style: widget.sliderTextStyle ?? Theme.of(context).textTheme.bodyLarge,
style: widget.sliderTextStyle ??
Theme.of(context).textTheme.bodyLarge,
),
),
Expanded(child: colorPickerSlider(trackType)),
@ -612,7 +669,8 @@ class _SlidePickerState extends State<SlidePicker> {
constraints: BoxConstraints(minWidth: fontSize * 2 + 5),
child: Text(
getColorParams(trackTypes.indexOf(trackType)),
style: widget.sliderTextStyle ?? Theme.of(context).textTheme.bodyMedium,
style: widget.sliderTextStyle ??
Theme.of(context).textTheme.bodyMedium,
textAlign: TextAlign.right,
),
),
@ -693,30 +751,34 @@ class _HueRingPickerState extends State<HueRingPicker> {
@override
Widget build(BuildContext context) {
if (MediaQuery.of(context).orientation == Orientation.portrait || widget.portraitOnly) {
if (MediaQuery.of(context).orientation == Orientation.portrait ||
widget.portraitOnly) {
return Column(
children: <Widget>[
ClipRRect(
borderRadius: widget.pickerAreaBorderRadius,
child: Padding(
padding: const EdgeInsets.all(15),
child: Stack(alignment: AlignmentDirectional.center, children: <Widget>[
SizedBox(
width: widget.colorPickerHeight,
height: widget.colorPickerHeight,
child: ColorPickerHueRing(
currentHsvColor,
onColorChanging,
displayThumbColor: widget.displayThumbColor,
strokeWidth: widget.hueRingStrokeWidth,
),
),
SizedBox(
width: widget.colorPickerHeight / 1.6,
height: widget.colorPickerHeight / 1.6,
child: ColorPickerArea(currentHsvColor, onColorChanging, PaletteType.hsv),
)
]),
child: Stack(
alignment: AlignmentDirectional.center,
children: <Widget>[
SizedBox(
width: widget.colorPickerHeight,
height: widget.colorPickerHeight,
child: ColorPickerHueRing(
currentHsvColor,
onColorChanging,
displayThumbColor: widget.displayThumbColor,
strokeWidth: widget.hueRingStrokeWidth,
),
),
SizedBox(
width: widget.colorPickerHeight / 1.6,
height: widget.colorPickerHeight / 1.6,
child: ColorPickerArea(
currentHsvColor, onColorChanging, PaletteType.hsv),
)
]),
),
),
if (widget.enableAlpha)
@ -743,7 +805,8 @@ class _HueRingPickerState extends State<HueRingPicker> {
child: ColorPickerInput(
currentHsvColor.toColor(),
(Color color) {
setState(() => currentHsvColor = HSVColor.fromColor(color));
setState(
() => currentHsvColor = HSVColor.fromColor(color));
widget.onColorChanged(currentHsvColor.toColor());
},
enableAlpha: widget.enableAlpha,
@ -765,7 +828,8 @@ class _HueRingPickerState extends State<HueRingPicker> {
height: widget.colorPickerHeight,
child: ClipRRect(
borderRadius: widget.pickerAreaBorderRadius,
child: ColorPickerArea(currentHsvColor, onColorChanging, PaletteType.hsv),
child: ColorPickerArea(
currentHsvColor, onColorChanging, PaletteType.hsv),
),
),
),
@ -773,42 +837,51 @@ class _HueRingPickerState extends State<HueRingPicker> {
borderRadius: widget.pickerAreaBorderRadius,
child: Padding(
padding: const EdgeInsets.all(15),
child: Stack(alignment: AlignmentDirectional.topCenter, children: <Widget>[
SizedBox(
width: widget.colorPickerHeight - widget.hueRingStrokeWidth * 2,
height: widget.colorPickerHeight - widget.hueRingStrokeWidth * 2,
child: ColorPickerHueRing(currentHsvColor, onColorChanging, strokeWidth: widget.hueRingStrokeWidth),
),
Column(
children: [
SizedBox(height: widget.colorPickerHeight / 8.5),
ColorIndicator(currentHsvColor),
const SizedBox(height: 10),
ColorPickerInput(
currentHsvColor.toColor(),
(Color color) {
setState(() => currentHsvColor = HSVColor.fromColor(color));
widget.onColorChanged(currentHsvColor.toColor());
},
enableAlpha: widget.enableAlpha,
embeddedText: true,
disable: true,
child: Stack(
alignment: AlignmentDirectional.topCenter,
children: <Widget>[
SizedBox(
width: widget.colorPickerHeight -
widget.hueRingStrokeWidth * 2,
height: widget.colorPickerHeight -
widget.hueRingStrokeWidth * 2,
child: ColorPickerHueRing(
currentHsvColor, onColorChanging,
strokeWidth: widget.hueRingStrokeWidth),
),
if (widget.enableAlpha) const SizedBox(height: 5),
if (widget.enableAlpha)
SizedBox(
height: 40.0,
width: (widget.colorPickerHeight - widget.hueRingStrokeWidth * 2) / 2,
child: ColorPickerSlider(
TrackType.alpha,
currentHsvColor,
onColorChanging,
displayThumbColor: true,
Column(
children: [
SizedBox(height: widget.colorPickerHeight / 8.5),
ColorIndicator(currentHsvColor),
const SizedBox(height: 10),
ColorPickerInput(
currentHsvColor.toColor(),
(Color color) {
setState(() =>
currentHsvColor = HSVColor.fromColor(color));
widget.onColorChanged(currentHsvColor.toColor());
},
enableAlpha: widget.enableAlpha,
embeddedText: true,
disable: true,
),
),
],
),
]),
if (widget.enableAlpha) const SizedBox(height: 5),
if (widget.enableAlpha)
SizedBox(
height: 40.0,
width: (widget.colorPickerHeight -
widget.hueRingStrokeWidth * 2) /
2,
child: ColorPickerSlider(
TrackType.alpha,
currentHsvColor,
onColorChanging,
displayThumbColor: true,
),
),
],
),
]),
),
),
],

@ -164,7 +164,8 @@ const Map<String, Color> x11Colors = {
'yellowgreen': Color(0xff9acd32),
};
Color? colorFromName(String val) => x11Colors[val.trim().replaceAll(' ', '').toLowerCase()];
Color? colorFromName(String val) =>
x11Colors[val.trim().replaceAll(' ', '').toLowerCase()];
extension ColorExtension on String {
Color? toColor() => colorFromName(this);

@ -61,16 +61,29 @@ class _MaterialPickerState extends State<MaterialPicker> {
for (Color colorType in colors) {
if (colorType == Colors.grey) {
result.addAll([50, 100, 200, 300, 350, 400, 500, 600, 700, 800, 850, 900]
.map((int shade) => {Colors.grey[shade]!: shade.toString()})
.toList());
result.addAll([
50,
100,
200,
300,
350,
400,
500,
600,
700,
800,
850,
900
].map((int shade) => {Colors.grey[shade]!: shade.toString()}).toList());
} else if (colorType == Colors.black || colorType == Colors.white) {
result.addAll([
{Colors.black: ''},
{Colors.white: ''}
]);
} else if (colorType is MaterialAccentColor) {
result.addAll([100, 200, 400, 700].map((int shade) => {colorType[shade]!: 'A$shade'}).toList());
result.addAll([100, 200, 400, 700]
.map((int shade) => {colorType[shade]!: 'A$shade'})
.toList());
} else if (colorType is MaterialColor) {
result.addAll([50, 100, 200, 300, 400, 500, 600, 700, 800, 900]
.map((int shade) => {colorType[shade]!: shade.toString()})
@ -100,25 +113,50 @@ class _MaterialPickerState extends State<MaterialPicker> {
@override
Widget build(BuildContext context) {
bool _isPortrait = MediaQuery.of(context).orientation == Orientation.portrait || widget.portraitOnly;
bool _isPortrait =
MediaQuery.of(context).orientation == Orientation.portrait ||
widget.portraitOnly;
Widget _colorList() {
return Container(
clipBehavior: Clip.hardEdge,
decoration: const BoxDecoration(),
child: Container(
margin: _isPortrait ? const EdgeInsets.only(right: 10) : const EdgeInsets.only(bottom: 10),
margin: _isPortrait
? const EdgeInsets.only(right: 10)
: const EdgeInsets.only(bottom: 10),
width: _isPortrait ? 60 : null,
height: _isPortrait ? null : 60,
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
boxShadow: [BoxShadow(color: (Theme.of(context).brightness == Brightness.light) ? (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38 : Colors.black38, blurRadius: 10)],
boxShadow: [
BoxShadow(
color: (Theme.of(context).brightness == Brightness.light)
? (Theme.of(context).brightness == Brightness.light)
? Colors.grey[300]!
: Colors.black38
: Colors.black38,
blurRadius: 10)
],
border: _isPortrait
? Border(right: BorderSide(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1))
: Border(top: BorderSide(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1)),
? Border(
right: BorderSide(
color:
(Theme.of(context).brightness == Brightness.light)
? Colors.grey[300]!
: Colors.black38,
width: 1))
: Border(
top: BorderSide(
color:
(Theme.of(context).brightness == Brightness.light)
? Colors.grey[300]!
: Colors.black38,
width: 1)),
),
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(dragDevices: PointerDeviceKind.values.toSet()),
behavior: ScrollConfiguration.of(context)
.copyWith(dragDevices: PointerDeviceKind.values.toSet()),
child: ListView(
scrollDirection: _isPortrait ? Axis.vertical : Axis.horizontal,
children: [
@ -129,13 +167,15 @@ class _MaterialPickerState extends State<MaterialPicker> {
Color _colorType = _colors[0];
return GestureDetector(
onTap: () {
if (widget.onPrimaryChanged != null) widget.onPrimaryChanged!(_colorType);
if (widget.onPrimaryChanged != null)
widget.onPrimaryChanged!(_colorType);
setState(() => _currentColorType = _colors);
},
child: Container(
color: const Color(0x00000000),
padding:
_isPortrait ? const EdgeInsets.fromLTRB(0, 7, 0, 7) : const EdgeInsets.fromLTRB(7, 0, 7, 0),
padding: _isPortrait
? const EdgeInsets.fromLTRB(0, 7, 0, 7)
: const EdgeInsets.fromLTRB(7, 0, 7, 0),
child: Align(
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
@ -146,19 +186,28 @@ class _MaterialPickerState extends State<MaterialPicker> {
shape: BoxShape.circle,
boxShadow: _currentColorType == _colors
? [
_colorType == Theme.of(context).cardColor
? BoxShadow(
color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38,
blurRadius: 10,
)
: BoxShadow(
color: _colorType,
blurRadius: 10,
),
]
_colorType == Theme.of(context).cardColor
? BoxShadow(
color:
(Theme.of(context).brightness ==
Brightness.light)
? Colors.grey[300]!
: Colors.black38,
blurRadius: 10,
)
: BoxShadow(
color: _colorType,
blurRadius: 10,
),
]
: null,
border: _colorType == Theme.of(context).cardColor
? Border.all(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1)
? Border.all(
color: (Theme.of(context).brightness ==
Brightness.light)
? Colors.grey[300]!
: Colors.black38,
width: 1)
: null,
),
),
@ -178,7 +227,8 @@ class _MaterialPickerState extends State<MaterialPicker> {
Widget _shadingList() {
return ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(dragDevices: PointerDeviceKind.values.toSet()),
behavior: ScrollConfiguration.of(context)
.copyWith(dragDevices: PointerDeviceKind.values.toSet()),
child: ListView(
scrollDirection: _isPortrait ? Axis.vertical : Axis.horizontal,
children: [
@ -194,73 +244,95 @@ class _MaterialPickerState extends State<MaterialPicker> {
},
child: Container(
color: const Color(0x00000000),
margin: _isPortrait ? const EdgeInsets.only(right: 10) : const EdgeInsets.only(bottom: 10),
padding: _isPortrait ? const EdgeInsets.fromLTRB(0, 7, 0, 7) : const EdgeInsets.fromLTRB(7, 0, 7, 0),
margin: _isPortrait
? const EdgeInsets.only(right: 10)
: const EdgeInsets.only(bottom: 10),
padding: _isPortrait
? const EdgeInsets.fromLTRB(0, 7, 0, 7)
: const EdgeInsets.fromLTRB(7, 0, 7, 0),
child: Align(
child: AnimatedContainer(
curve: Curves.fastOutSlowIn,
duration: const Duration(milliseconds: 500),
width:
_isPortrait ? (_currentShading == _color ? 250 : 230) : (_currentShading == _color ? 50 : 30),
width: _isPortrait
? (_currentShading == _color ? 250 : 230)
: (_currentShading == _color ? 50 : 30),
height: _isPortrait ? 50 : 220,
decoration: BoxDecoration(
color: _color,
boxShadow: _currentShading == _color
? [
(_color == Colors.white) || (_color == Colors.black)
? BoxShadow(
color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38,
blurRadius: 10,
)
: BoxShadow(
color: _color,
blurRadius: 10,
),
]
: null,
border: (_color == Colors.white) || (_color == Colors.black)
? Border.all(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1)
(_color == Colors.white) ||
(_color == Colors.black)
? BoxShadow(
color: (Theme.of(context).brightness ==
Brightness.light)
? Colors.grey[300]!
: Colors.black38,
blurRadius: 10,
)
: BoxShadow(
color: _color,
blurRadius: 10,
),
]
: null,
border:
(_color == Colors.white) || (_color == Colors.black)
? Border.all(
color: (Theme.of(context).brightness ==
Brightness.light)
? Colors.grey[300]!
: Colors.black38,
width: 1)
: null,
),
child: widget.enableLabel
? _isPortrait
? Row(
children: [
Text(
' ${color.values.first}',
style: TextStyle(color: useWhiteForeground(_color) ? Colors.white : Colors.black),
),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Text(
'#${(_color.toString().replaceFirst('Color(0xff', '').replaceFirst(')', '')).toUpperCase()} ',
style: TextStyle(
color: useWhiteForeground(_color) ? Colors.white : Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
],
)
: AnimatedOpacity(
duration: const Duration(milliseconds: 300),
opacity: _currentShading == _color ? 1 : 0,
child: Container(
padding: const EdgeInsets.only(top: 16),
alignment: Alignment.topCenter,
child: Text(
color.values.first,
style: TextStyle(
color: useWhiteForeground(_color) ? Colors.white : Colors.black,
fontWeight: FontWeight.bold,
fontSize: 14,
),
softWrap: false,
),
),
)
? Row(
children: [
Text(
' ${color.values.first}',
style: TextStyle(
color: useWhiteForeground(_color)
? Colors.white
: Colors.black),
),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Text(
'#${(_color.toString().replaceFirst('Color(0xff', '').replaceFirst(')', '')).toUpperCase()} ',
style: TextStyle(
color: useWhiteForeground(_color)
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
],
)
: AnimatedOpacity(
duration: const Duration(milliseconds: 300),
opacity: _currentShading == _color ? 1 : 0,
child: Container(
padding: const EdgeInsets.only(top: 16),
alignment: Alignment.topCenter,
child: Text(
color.values.first,
style: TextStyle(
color: useWhiteForeground(_color)
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 14,
),
softWrap: false,
),
),
)
: const SizedBox(),
),
),

@ -76,10 +76,14 @@ class HSVWithHueColorPainter extends CustomPainter {
);
canvas.drawCircle(
Offset(size.width * hsvColor.saturation, size.height * (1 - hsvColor.value)),
Offset(
size.width * hsvColor.saturation, size.height * (1 - hsvColor.value)),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(hsvColor.toColor()) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(hsvColor.toColor())
? Colors.white
: Colors.black)
..strokeWidth = 1.5
..blendMode = BlendMode.luminosity
..style = PaintingStyle.stroke,
@ -125,7 +129,10 @@ class HSVWithSaturationColorPainter extends CustomPainter {
),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(hsvColor.toColor()) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(hsvColor.toColor())
? Colors.white
: Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -174,7 +181,10 @@ class HSVWithValueColorPainter extends CustomPainter {
),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(hsvColor.toColor()) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(hsvColor.toColor())
? Colors.white
: Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -215,10 +225,14 @@ class HSLWithHueColorPainter extends CustomPainter {
canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect));
canvas.drawCircle(
Offset(size.width * hslColor.saturation, size.height * (1 - hslColor.lightness)),
Offset(size.width * hslColor.saturation,
size.height * (1 - hslColor.lightness)),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(hslColor.toColor()) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(hslColor.toColor())
? Colors.white
: Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -263,10 +277,14 @@ class HSLWithSaturationColorPainter extends CustomPainter {
canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect));
canvas.drawCircle(
Offset(size.width * hslColor.hue / 360, size.height * (1 - hslColor.lightness)),
Offset(size.width * hslColor.hue / 360,
size.height * (1 - hslColor.lightness)),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(hslColor.toColor()) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(hslColor.toColor())
? Colors.white
: Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -308,18 +326,26 @@ class HSLWithLightnessColorPainter extends CustomPainter {
canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect));
canvas.drawRect(
rect,
Paint()..color = Colors.black.withOpacity((1 - hslColor.lightness * 2).clamp(0, 1)),
Paint()
..color =
Colors.black.withOpacity((1 - hslColor.lightness * 2).clamp(0, 1)),
);
canvas.drawRect(
rect,
Paint()..color = Colors.white.withOpacity(((hslColor.lightness - 0.5) * 2).clamp(0, 1)),
Paint()
..color = Colors.white
.withOpacity(((hslColor.lightness - 0.5) * 2).clamp(0, 1)),
);
canvas.drawCircle(
Offset(size.width * hslColor.hue / 360, size.height * (1 - hslColor.saturation)),
Offset(size.width * hslColor.hue / 360,
size.height * (1 - hslColor.saturation)),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(hslColor.toColor()) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(hslColor.toColor())
? Colors.white
: Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -362,10 +388,12 @@ class RGBWithRedColorPainter extends CustomPainter {
);
canvas.drawCircle(
Offset(size.width * color.blue / 255, size.height * (1 - color.green / 255)),
Offset(
size.width * color.blue / 255, size.height * (1 - color.green / 255)),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(color) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(color) ? Colors.white : Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -408,10 +436,12 @@ class RGBWithGreenColorPainter extends CustomPainter {
);
canvas.drawCircle(
Offset(size.width * color.blue / 255, size.height * (1 - color.red / 255)),
Offset(
size.width * color.blue / 255, size.height * (1 - color.red / 255)),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(color) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(color) ? Colors.white : Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -454,10 +484,12 @@ class RGBWithBlueColorPainter extends CustomPainter {
);
canvas.drawCircle(
Offset(size.width * color.red / 255, size.height * (1 - color.green / 255)),
Offset(
size.width * color.red / 255, size.height * (1 - color.green / 255)),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(color) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(color) ? Colors.white : Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -496,18 +528,26 @@ class HUEColorWheelPainter extends CustomPainter {
Color(0x00FFFFFF),
],
);
canvas.drawCircle(center, radio, Paint()..shader = gradientS.createShader(rect));
canvas.drawCircle(center, radio, Paint()..shader = gradientR.createShader(rect));
canvas.drawCircle(center, radio, Paint()..color = Colors.black.withOpacity(1 - hsvColor.value));
canvas.drawCircle(
center, radio, Paint()..shader = gradientS.createShader(rect));
canvas.drawCircle(
center, radio, Paint()..shader = gradientR.createShader(rect));
canvas.drawCircle(center, radio,
Paint()..color = Colors.black.withOpacity(1 - hsvColor.value));
canvas.drawCircle(
Offset(
center.dx + hsvColor.saturation * radio * cos((hsvColor.hue * pi / 180)),
center.dy - hsvColor.saturation * radio * sin((hsvColor.hue * pi / 180)),
center.dx +
hsvColor.saturation * radio * cos((hsvColor.hue * pi / 180)),
center.dy -
hsvColor.saturation * radio * sin((hsvColor.hue * pi / 180)),
),
size.height * 0.04,
Paint()
..color = pointerColor ?? (useWhiteForeground(hsvColor.toColor()) ? Colors.white : Colors.black)
..color = pointerColor ??
(useWhiteForeground(hsvColor.toColor())
? Colors.white
: Colors.black)
..strokeWidth = 1.5
..style = PaintingStyle.stroke,
);
@ -519,7 +559,8 @@ class HUEColorWheelPainter extends CustomPainter {
/// Painter for hue ring.
class HueRingPainter extends CustomPainter {
const HueRingPainter(this.hsvColor, {this.displayThumbColor = true, this.strokeWidth = 5});
const HueRingPainter(this.hsvColor,
{this.displayThumbColor = true, this.strokeWidth = 5});
final HSVColor hsvColor;
final bool displayThumbColor;
@ -553,7 +594,11 @@ class HueRingPainter extends CustomPainter {
center.dx + radio * cos((hsvColor.hue * pi / 180)),
center.dy - radio * sin((hsvColor.hue * pi / 180)),
);
canvas.drawShadow(Path()..addOval(Rect.fromCircle(center: offset, radius: 12)), Colors.black, 3.0, true);
canvas.drawShadow(
Path()..addOval(Rect.fromCircle(center: offset, radius: 12)),
Colors.black,
3.0,
true);
canvas.drawCircle(
offset,
size.height * 0.04,
@ -729,7 +774,8 @@ class ThumbPainter extends CustomPainter {
canvas.drawShadow(
Path()
..addOval(
Rect.fromCircle(center: const Offset(0.5, 2.0), radius: size.width * 1.8),
Rect.fromCircle(
center: const Offset(0.5, 2.0), radius: size.width * 1.8),
),
Colors.black,
3.0,
@ -816,7 +862,11 @@ class ColorPickerLabel extends StatefulWidget {
this.hsvColor, {
Key? key,
this.enableAlpha = true,
this.colorLabelTypes = const [ColorLabelType.rgb, ColorLabelType.hsv, ColorLabelType.hsl],
this.colorLabelTypes = const [
ColorLabelType.rgb,
ColorLabelType.hsv,
ColorLabelType.hsl
],
this.textStyle,
}) : assert(colorLabelTypes.length > 0),
super(key: key);
@ -885,7 +935,8 @@ class _ColorPickerLabelState extends State<ColorPickerLabel> {
List<Widget> colorValueLabels() {
double fontSize = 14;
if (widget.textStyle != null && widget.textStyle?.fontSize != null) fontSize = widget.textStyle?.fontSize ?? 14;
if (widget.textStyle != null && widget.textStyle?.fontSize != null)
fontSize = widget.textStyle?.fontSize ?? 14;
return [
for (String item in _colorTypes[_colorType] ?? [])
@ -899,14 +950,17 @@ class _ColorPickerLabelState extends State<ColorPickerLabel> {
children: <Widget>[
Text(
item,
style: widget.textStyle ?? Theme.of(context).textTheme.bodyLarge,
style: widget.textStyle ??
Theme.of(context).textTheme.bodyLarge,
),
const SizedBox(height: 10.0),
Expanded(
child: Text(
colorValue(widget.hsvColor, _colorType)[_colorTypes[_colorType]!.indexOf(item)],
colorValue(widget.hsvColor, _colorType)[
_colorTypes[_colorType]!.indexOf(item)],
overflow: TextOverflow.ellipsis,
style: widget.textStyle ?? Theme.of(context).textTheme.bodyMedium,
style: widget.textStyle ??
Theme.of(context).textTheme.bodyMedium,
),
),
],
@ -977,12 +1031,18 @@ class _ColorPickerInputState extends State<ColorPickerInput> {
widget.color.red.toRadixString(16).toUpperCase().padLeft(2, '0') +
widget.color.green.toRadixString(16).toUpperCase().padLeft(2, '0') +
widget.color.blue.toRadixString(16).toUpperCase().padLeft(2, '0') +
(widget.enableAlpha ? widget.color.alpha.toRadixString(16).toUpperCase().padLeft(2, '0') : '');
(widget.enableAlpha
? widget.color.alpha
.toRadixString(16)
.toUpperCase()
.padLeft(2, '0')
: '');
}
return Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
if (!widget.embeddedText) Text('Hex', style: Theme.of(context).textTheme.bodyLarge),
if (!widget.embeddedText)
Text('Hex', style: Theme.of(context).textTheme.bodyLarge),
const SizedBox(width: 10),
SizedBox(
width: (Theme.of(context).textTheme.bodyMedium?.fontSize ?? 14) * 10,
@ -1001,7 +1061,8 @@ class _ColorPickerInputState extends State<ColorPickerInput> {
onChanged: (String value) {
String input = value;
if (value.length == 9) {
input = value.split('').getRange(7, 9).join() + value.split('').getRange(1, 7).join();
input = value.split('').getRange(7, 9).join() +
value.split('').getRange(1, 7).join();
}
final Color? color = colorFromHex(input);
if (color != null) {
@ -1035,7 +1096,8 @@ class ColorPickerSlider extends StatelessWidget {
void slideEvent(RenderBox getBox, BoxConstraints box, Offset globalPosition) {
double localDx = getBox.globalToLocal(globalPosition).dx - 15.0;
double progress = localDx.clamp(0.0, box.maxWidth - 30.0) / (box.maxWidth - 30.0);
double progress =
localDx.clamp(0.0, box.maxWidth - 30.0) / (box.maxWidth - 30.0);
switch (trackType) {
case TrackType.hue:
// 360 is the same as zero
@ -1055,16 +1117,20 @@ class ColorPickerSlider extends StatelessWidget {
onColorChanged(hslToHsv(hsvToHsl(hsvColor).withLightness(progress)));
break;
case TrackType.red:
onColorChanged(HSVColor.fromColor(hsvColor.toColor().withRed((progress * 0xff).round())));
onColorChanged(HSVColor.fromColor(
hsvColor.toColor().withRed((progress * 0xff).round())));
break;
case TrackType.green:
onColorChanged(HSVColor.fromColor(hsvColor.toColor().withGreen((progress * 0xff).round())));
onColorChanged(HSVColor.fromColor(
hsvColor.toColor().withGreen((progress * 0xff).round())));
break;
case TrackType.blue:
onColorChanged(HSVColor.fromColor(hsvColor.toColor().withBlue((progress * 0xff).round())));
onColorChanged(HSVColor.fromColor(
hsvColor.toColor().withBlue((progress * 0xff).round())));
break;
case TrackType.alpha:
onColorChanged(hsvColor.withAlpha(localDx.clamp(0.0, box.maxWidth - 30.0) / (box.maxWidth - 30.0)));
onColorChanged(hsvColor.withAlpha(
localDx.clamp(0.0, box.maxWidth - 30.0) / (box.maxWidth - 30.0)));
break;
}
}
@ -1081,26 +1147,34 @@ class ColorPickerSlider extends StatelessWidget {
break;
case TrackType.saturation:
thumbOffset += (box.maxWidth - 30.0) * hsvColor.saturation;
thumbColor = HSVColor.fromAHSV(1.0, hsvColor.hue, hsvColor.saturation, 1.0).toColor();
thumbColor =
HSVColor.fromAHSV(1.0, hsvColor.hue, hsvColor.saturation, 1.0)
.toColor();
break;
case TrackType.saturationForHSL:
thumbOffset += (box.maxWidth - 30.0) * hsvToHsl(hsvColor).saturation;
thumbColor = HSLColor.fromAHSL(1.0, hsvColor.hue, hsvToHsl(hsvColor).saturation, 0.5).toColor();
thumbColor = HSLColor.fromAHSL(
1.0, hsvColor.hue, hsvToHsl(hsvColor).saturation, 0.5)
.toColor();
break;
case TrackType.value:
thumbOffset += (box.maxWidth - 30.0) * hsvColor.value;
thumbColor = HSVColor.fromAHSV(1.0, hsvColor.hue, 1.0, hsvColor.value).toColor();
thumbColor = HSVColor.fromAHSV(1.0, hsvColor.hue, 1.0, hsvColor.value)
.toColor();
break;
case TrackType.lightness:
thumbOffset += (box.maxWidth - 30.0) * hsvToHsl(hsvColor).lightness;
thumbColor = HSLColor.fromAHSL(1.0, hsvColor.hue, 1.0, hsvToHsl(hsvColor).lightness).toColor();
thumbColor = HSLColor.fromAHSL(
1.0, hsvColor.hue, 1.0, hsvToHsl(hsvColor).lightness)
.toColor();
break;
case TrackType.red:
thumbOffset += (box.maxWidth - 30.0) * hsvColor.toColor().red / 0xff;
thumbColor = hsvColor.toColor().withOpacity(1.0);
break;
case TrackType.green:
thumbOffset += (box.maxWidth - 30.0) * hsvColor.toColor().green / 0xff;
thumbOffset +=
(box.maxWidth - 30.0) * hsvColor.toColor().green / 0xff;
thumbColor = hsvColor.toColor().withOpacity(1.0);
break;
case TrackType.blue:
@ -1145,10 +1219,12 @@ class ColorPickerSlider extends StatelessWidget {
builder: (BuildContext context, BoxConstraints box) {
RenderBox? getBox = context.findRenderObject() as RenderBox?;
return GestureDetector(
onPanDown: (DragDownDetails details) =>
getBox != null ? slideEvent(getBox, box, details.globalPosition) : null,
onPanUpdate: (DragUpdateDetails details) =>
getBox != null ? slideEvent(getBox, box, details.globalPosition) : null,
onPanDown: (DragDownDetails details) => getBox != null
? slideEvent(getBox, box, details.globalPosition)
: null,
onPanUpdate: (DragUpdateDetails details) => getBox != null
? slideEvent(getBox, box, details.globalPosition)
: null,
);
},
),
@ -1212,7 +1288,8 @@ class ColorPickerArea extends StatelessWidget {
onColorChanged(hsvColor.withHue(horizontal * 360).withValue(vertical));
break;
case PaletteType.hsvWithValue:
onColorChanged(hsvColor.withHue(horizontal * 360).withSaturation(vertical));
onColorChanged(
hsvColor.withHue(horizontal * 360).withSaturation(vertical));
break;
case PaletteType.hsl:
case PaletteType.hslWithHue:
@ -1232,17 +1309,26 @@ class ColorPickerArea extends StatelessWidget {
break;
case PaletteType.rgbWithRed:
onColorChanged(HSVColor.fromColor(
hsvColor.toColor().withBlue((horizontal * 255).round()).withGreen((vertical * 255).round()),
hsvColor
.toColor()
.withBlue((horizontal * 255).round())
.withGreen((vertical * 255).round()),
));
break;
case PaletteType.rgbWithGreen:
onColorChanged(HSVColor.fromColor(
hsvColor.toColor().withBlue((horizontal * 255).round()).withRed((vertical * 255).round()),
hsvColor
.toColor()
.withBlue((horizontal * 255).round())
.withRed((vertical * 255).round()),
));
break;
case PaletteType.rgbWithBlue:
onColorChanged(HSVColor.fromColor(
hsvColor.toColor().withRed((horizontal * 255).round()).withGreen((vertical * 255).round()),
hsvColor
.toColor()
.withRed((horizontal * 255).round())
.withGreen((vertical * 255).round()),
));
break;
default:
@ -1254,7 +1340,8 @@ class ColorPickerArea extends StatelessWidget {
onColorChanged(hsvColor.withHue(hue).withSaturation(radio));
}
void _handleGesture(Offset position, BuildContext context, double height, double width) {
void _handleGesture(
Offset position, BuildContext context, double height, double width) {
RenderBox? getBox = context.findRenderObject() as RenderBox?;
if (getBox == null) return;
@ -1265,9 +1352,15 @@ class ColorPickerArea extends StatelessWidget {
if (paletteType == PaletteType.hueWheel) {
Offset center = Offset(width / 2, height / 2);
double radio = width <= height ? width / 2 : height / 2;
double dist = sqrt(pow(horizontal - center.dx, 2) + pow(vertical - center.dy, 2)) / radio;
double rad = (atan2(horizontal - center.dx, vertical - center.dy) / pi + 1) / 2 * 360;
_handleColorWheelChange(((rad + 90) % 360).clamp(0, 360), dist.clamp(0, 1));
double dist =
sqrt(pow(horizontal - center.dx, 2) + pow(vertical - center.dy, 2)) /
radio;
double rad =
(atan2(horizontal - center.dx, vertical - center.dy) / pi + 1) /
2 *
360;
_handleColorWheelChange(
((rad + 90) % 360).clamp(0, 360), dist.clamp(0, 1));
} else {
_handleColorRectChange(horizontal / width, 1 - vertical / height);
}
@ -1282,12 +1375,16 @@ class ColorPickerArea extends StatelessWidget {
return RawGestureDetector(
gestures: {
_AlwaysWinPanGestureRecognizer: GestureRecognizerFactoryWithHandlers<_AlwaysWinPanGestureRecognizer>(
_AlwaysWinPanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<
_AlwaysWinPanGestureRecognizer>(
() => _AlwaysWinPanGestureRecognizer(),
(_AlwaysWinPanGestureRecognizer instance) {
instance
..onDown = ((details) => _handleGesture(details.globalPosition, context, height, width))
..onUpdate = ((details) => _handleGesture(details.globalPosition, context, height, width));
..onDown = ((details) => _handleGesture(
details.globalPosition, context, height, width))
..onUpdate = ((details) => _handleGesture(
details.globalPosition, context, height, width));
},
),
},
@ -1298,22 +1395,32 @@ class ColorPickerArea extends StatelessWidget {
case PaletteType.hsvWithHue:
return CustomPaint(painter: HSVWithHueColorPainter(hsvColor));
case PaletteType.hsvWithSaturation:
return CustomPaint(painter: HSVWithSaturationColorPainter(hsvColor));
return CustomPaint(
painter: HSVWithSaturationColorPainter(hsvColor));
case PaletteType.hsvWithValue:
return CustomPaint(painter: HSVWithValueColorPainter(hsvColor));
return CustomPaint(
painter: HSVWithValueColorPainter(hsvColor));
case PaletteType.hsl:
case PaletteType.hslWithHue:
return CustomPaint(painter: HSLWithHueColorPainter(hsvToHsl(hsvColor)));
return CustomPaint(
painter: HSLWithHueColorPainter(hsvToHsl(hsvColor)));
case PaletteType.hslWithSaturation:
return CustomPaint(painter: HSLWithSaturationColorPainter(hsvToHsl(hsvColor)));
return CustomPaint(
painter:
HSLWithSaturationColorPainter(hsvToHsl(hsvColor)));
case PaletteType.hslWithLightness:
return CustomPaint(painter: HSLWithLightnessColorPainter(hsvToHsl(hsvColor)));
return CustomPaint(
painter:
HSLWithLightnessColorPainter(hsvToHsl(hsvColor)));
case PaletteType.rgbWithRed:
return CustomPaint(painter: RGBWithRedColorPainter(hsvColor.toColor()));
return CustomPaint(
painter: RGBWithRedColorPainter(hsvColor.toColor()));
case PaletteType.rgbWithGreen:
return CustomPaint(painter: RGBWithGreenColorPainter(hsvColor.toColor()));
return CustomPaint(
painter: RGBWithGreenColorPainter(hsvColor.toColor()));
case PaletteType.rgbWithBlue:
return CustomPaint(painter: RGBWithBlueColorPainter(hsvColor.toColor()));
return CustomPaint(
painter: RGBWithBlueColorPainter(hsvColor.toColor()));
case PaletteType.hueWheel:
return CustomPaint(painter: HUEColorWheelPainter(hsvColor));
default:
@ -1342,7 +1449,8 @@ class ColorPickerHueRing extends StatelessWidget {
final bool displayThumbColor;
final double strokeWidth;
void _handleGesture(Offset position, BuildContext context, double height, double width) {
void _handleGesture(
Offset position, BuildContext context, double height, double width) {
RenderBox? getBox = context.findRenderObject() as RenderBox?;
if (getBox == null) return;
@ -1352,9 +1460,15 @@ class ColorPickerHueRing extends StatelessWidget {
Offset center = Offset(width / 2, height / 2);
double radio = width <= height ? width / 2 : height / 2;
double dist = sqrt(pow(horizontal - center.dx, 2) + pow(vertical - center.dy, 2)) / radio;
double rad = (atan2(horizontal - center.dx, vertical - center.dy) / pi + 1) / 2 * 360;
if (dist > 0.7 && dist < 1.3) onColorChanged(hsvColor.withHue(((rad + 90) % 360).clamp(0, 360)));
double dist =
sqrt(pow(horizontal - center.dx, 2) + pow(vertical - center.dy, 2)) /
radio;
double rad =
(atan2(horizontal - center.dx, vertical - center.dy) / pi + 1) /
2 *
360;
if (dist > 0.7 && dist < 1.3)
onColorChanged(hsvColor.withHue(((rad + 90) % 360).clamp(0, 360)));
}
@override
@ -1366,17 +1480,22 @@ class ColorPickerHueRing extends StatelessWidget {
return RawGestureDetector(
gestures: {
_AlwaysWinPanGestureRecognizer: GestureRecognizerFactoryWithHandlers<_AlwaysWinPanGestureRecognizer>(
_AlwaysWinPanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<
_AlwaysWinPanGestureRecognizer>(
() => _AlwaysWinPanGestureRecognizer(),
(_AlwaysWinPanGestureRecognizer instance) {
instance
..onDown = ((details) => _handleGesture(details.globalPosition, context, height, width))
..onUpdate = ((details) => _handleGesture(details.globalPosition, context, height, width));
..onDown = ((details) => _handleGesture(
details.globalPosition, context, height, width))
..onUpdate = ((details) => _handleGesture(
details.globalPosition, context, height, width));
},
),
},
child: CustomPaint(
painter: HueRingPainter(hsvColor, displayThumbColor: displayThumbColor, strokeWidth: strokeWidth),
painter: HueRingPainter(hsvColor,
displayThumbColor: displayThumbColor, strokeWidth: strokeWidth),
),
);
},
@ -1399,5 +1518,6 @@ class _AlwaysWinPanGestureRecognizer extends PanGestureRecognizer {
class UpperCaseTextFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(oldValue, TextEditingValue newValue) =>
TextEditingValue(text: newValue.text.toUpperCase(), selection: newValue.selection);
TextEditingValue(
text: newValue.text.toUpperCase(), selection: newValue.selection);
}

@ -57,7 +57,9 @@ HSVColor hslToHsv(HSLColor color) {
double s = 0.0;
double v = 0.0;
v = color.lightness + color.saturation * (color.lightness < 0.5 ? color.lightness : 1 - color.lightness);
v = color.lightness +
color.saturation *
(color.lightness < 0.5 ? color.lightness : 1 - color.lightness);
if (v != 0) s = 2 - 2 * color.lightness / v;
return HSVColor.fromAHSV(
@ -94,7 +96,8 @@ const String kValidHexPattern = r'^#?[0-9a-fA-F]{1,8}';
/// if (hexCompleteValidator.hasMatch(hex)) print('$hex is valid HEX color');
/// ```
/// Reference: https://en.wikipedia.org/wiki/Web_colors#Hex_triplet
const String kCompleteValidHexPattern = r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$';
const String kCompleteValidHexPattern =
r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$';
/// Try to convert text input or any [String] to valid [Color].
/// The [String] must be provided in one of those formats:
@ -212,6 +215,10 @@ extension ColorExtension1 on String {
// Extension from Color
extension ColorExtension2 on Color {
String toHexString({bool includeHashSign = false, bool enableAlpha = true, bool toUpperCase = true}) =>
colorToHex(this, includeHashSign: false, enableAlpha: true, toUpperCase: true);
String toHexString(
{bool includeHashSign = false,
bool enableAlpha = true,
bool toUpperCase = true}) =>
colorToHex(this,
includeHashSign: false, enableAlpha: true, toUpperCase: true);
}

@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
import '../../../../../translations.dart';
import '../../../../models/documents/style.dart';
import '../../../../packages/flutter_colorpicker/flutter_colorpicker.dart' show ColorPicker, MaterialPicker, colorToHex;
import '../../../../packages/flutter_colorpicker/flutter_colorpicker.dart'
show ColorPicker, MaterialPicker, colorToHex;
import 'color_button.dart' show hexToColor;
enum _PickerType {

Loading…
Cancel
Save