From 4e1d8475eee152ffb66629d92fd9a958e02c5da8 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+ellet0@users.noreply.github.com> Date: Sun, 19 May 2024 16:35:09 +0300 Subject: [PATCH] Chore/use pub.dev color picker package (#1877) * chore: restore flutter_colorpicker and update to the latest compatible stable flutter sdk * revert: remove cloned flutter_colorpicker package * chore: update import of flutter_colorpicker package in color_dialog.dart --- .../flutter_colorpicker.dart | 9 - .../flutter_colorpicker/src/block_picker.dart | 211 --- .../flutter_colorpicker/src/colorpicker.dart | 891 ---------- .../flutter_colorpicker/src/colors.dart | 172 -- .../src/material_picker.dart | 384 ----- .../flutter_colorpicker/src/palette.dart | 1523 ----------------- .../flutter_colorpicker/src/utils.dart | 224 --- .../toolbar/buttons/color/color_dialog.dart | 4 +- pubspec.yaml | 3 +- 9 files changed, 3 insertions(+), 3418 deletions(-) delete mode 100644 lib/src/packages/flutter_colorpicker/flutter_colorpicker.dart delete mode 100644 lib/src/packages/flutter_colorpicker/src/block_picker.dart delete mode 100644 lib/src/packages/flutter_colorpicker/src/colorpicker.dart delete mode 100644 lib/src/packages/flutter_colorpicker/src/colors.dart delete mode 100644 lib/src/packages/flutter_colorpicker/src/material_picker.dart delete mode 100644 lib/src/packages/flutter_colorpicker/src/palette.dart delete mode 100644 lib/src/packages/flutter_colorpicker/src/utils.dart diff --git a/lib/src/packages/flutter_colorpicker/flutter_colorpicker.dart b/lib/src/packages/flutter_colorpicker/flutter_colorpicker.dart deleted file mode 100644 index fee43157..00000000 --- a/lib/src/packages/flutter_colorpicker/flutter_colorpicker.dart +++ /dev/null @@ -1,9 +0,0 @@ -library flutter_colorpicker; - -// TODO: temporarily clone https://pub.dev/packages/flutter_colorpicker as it's hasn't been published on pub.dev for a while - -export 'src/block_picker.dart'; -export 'src/colorpicker.dart'; -export 'src/material_picker.dart'; -export 'src/palette.dart'; -export 'src/utils.dart'; diff --git a/lib/src/packages/flutter_colorpicker/src/block_picker.dart b/lib/src/packages/flutter_colorpicker/src/block_picker.dart deleted file mode 100644 index fd6c488b..00000000 --- a/lib/src/packages/flutter_colorpicker/src/block_picker.dart +++ /dev/null @@ -1,211 +0,0 @@ -// ignore_for_file: type=lint - -/// Blocky Color Picker - -library block_colorpicker; - -import 'package:flutter/material.dart'; -import 'utils.dart'; - -/// Child widget for layout builder. -typedef PickerItem = Widget Function(Color color); - -/// Customize the layout. -typedef PickerLayoutBuilder = Widget Function( - BuildContext context, List colors, PickerItem child); - -/// Customize the item shape. -typedef PickerItemBuilder = Widget Function( - Color color, bool isCurrentColor, void Function() changeColor); - -// Provide a list of colors for block color picker. -const List _defaultColors = [ - Colors.red, - Colors.pink, - Colors.purple, - Colors.deepPurple, - Colors.indigo, - Colors.blue, - Colors.lightBlue, - Colors.cyan, - Colors.teal, - Colors.green, - Colors.lightGreen, - Colors.lime, - Colors.yellow, - Colors.amber, - Colors.orange, - Colors.deepOrange, - Colors.brown, - Colors.grey, - Colors.blueGrey, - Colors.black, -]; - -// Provide a layout for [BlockPicker]. -Widget _defaultLayoutBuilder( - BuildContext context, List colors, PickerItem child) { - Orientation orientation = MediaQuery.of(context).orientation; - - return SizedBox( - width: 300, - height: orientation == Orientation.portrait ? 360 : 200, - child: GridView.count( - crossAxisCount: orientation == Orientation.portrait ? 4 : 6, - crossAxisSpacing: 5, - mainAxisSpacing: 5, - children: [for (Color color in colors) child(color)], - ), - ); -} - -// Provide a shape for [BlockPicker]. -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) - ], - ), - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: changeColor, - borderRadius: BorderRadius.circular(50), - child: AnimatedOpacity( - duration: const Duration(milliseconds: 210), - opacity: isCurrentColor ? 1 : 0, - child: Icon(Icons.done, - color: useWhiteForeground(color) ? Colors.white : Colors.black), - ), - ), - ), - ); -} - -// The blocky color picker you can alter the layout and shape. -class BlockPicker extends StatefulWidget { - const BlockPicker({ - Key? key, - required this.pickerColor, - required this.onColorChanged, - this.availableColors = _defaultColors, - this.useInShowDialog = true, - this.layoutBuilder = _defaultLayoutBuilder, - this.itemBuilder = _defaultItemBuilder, - }) : super(key: key); - - final Color? pickerColor; - final ValueChanged onColorChanged; - final List availableColors; - final bool useInShowDialog; - final PickerLayoutBuilder layoutBuilder; - final PickerItemBuilder itemBuilder; - - @override - State createState() => _BlockPickerState(); -} - -class _BlockPickerState extends State { - Color? _currentColor; - - @override - void initState() { - _currentColor = widget.pickerColor; - super.initState(); - } - - void changeColor(Color color) { - setState(() => _currentColor = color); - widget.onColorChanged(color); - } - - @override - Widget build(BuildContext context) { - return widget.layoutBuilder( - context, - widget.availableColors, - (Color color) => widget.itemBuilder( - color, - (_currentColor != null && - (widget.useInShowDialog ? true : widget.pickerColor != null)) - ? (_currentColor?.value == color.value) && - (widget.useInShowDialog - ? true - : widget.pickerColor?.value == color.value) - : false, - () => changeColor(color), - ), - ); - } -} - -// The blocky color picker you can alter the layout and shape with multiple choice. -class MultipleChoiceBlockPicker extends StatefulWidget { - const MultipleChoiceBlockPicker({ - Key? key, - required this.pickerColors, - required this.onColorsChanged, - this.availableColors = _defaultColors, - this.useInShowDialog = true, - this.layoutBuilder = _defaultLayoutBuilder, - this.itemBuilder = _defaultItemBuilder, - }) : super(key: key); - - final List? pickerColors; - final ValueChanged> onColorsChanged; - final List availableColors; - final bool useInShowDialog; - final PickerLayoutBuilder layoutBuilder; - final PickerItemBuilder itemBuilder; - - @override - State createState() => _MultipleChoiceBlockPickerState(); -} - -class _MultipleChoiceBlockPickerState extends State { - List? _currentColors; - - @override - void initState() { - _currentColors = widget.pickerColors; - super.initState(); - } - - void toggleColor(Color color) { - setState(() { - if (_currentColors != null) { - _currentColors!.contains(color) - ? _currentColors!.remove(color) - : _currentColors!.add(color); - } - }); - widget.onColorsChanged(_currentColors ?? []); - } - - @override - Widget build(BuildContext context) { - return widget.layoutBuilder( - context, - 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)) - : false, - () => toggleColor(color), - ), - ); - } -} diff --git a/lib/src/packages/flutter_colorpicker/src/colorpicker.dart b/lib/src/packages/flutter_colorpicker/src/colorpicker.dart deleted file mode 100644 index 68c8f649..00000000 --- a/lib/src/packages/flutter_colorpicker/src/colorpicker.dart +++ /dev/null @@ -1,891 +0,0 @@ -// ignore_for_file: type=lint - -/// HSV(HSB)/HSL Color Picker example -/// -/// You can create your own layout by importing `picker.dart`. - -library hsv_picker; - -import 'package:flutter/material.dart'; -import 'palette.dart'; -import 'utils.dart'; - -/// The default layout of Color Picker. -class ColorPicker extends StatefulWidget { - const ColorPicker({ - Key? key, - required this.pickerColor, - required this.onColorChanged, - this.pickerHsvColor, - 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, - this.displayThumbColor = false, - this.portraitOnly = false, - this.colorPickerWidth = 300.0, - this.pickerAreaHeightPercent = 1.0, - this.pickerAreaBorderRadius = const BorderRadius.all(Radius.zero), - this.hexInputBar = false, - this.hexInputController, - this.colorHistory, - this.onHistoryChanged, - }) : super(key: key); - - final Color pickerColor; - final ValueChanged onColorChanged; - final HSVColor? pickerHsvColor; - final ValueChanged? onHsvColorChanged; - final PaletteType paletteType; - final bool enableAlpha; - final bool showLabel; - final List labelTypes; - final TextStyle? labelTextStyle; - final bool displayThumbColor; - final bool portraitOnly; - final double colorPickerWidth; - final double pickerAreaHeightPercent; - final BorderRadius pickerAreaBorderRadius; - final bool hexInputBar; - - /// Allows setting the color using text input, via [TextEditingController]. - /// - /// Listens to [String] input and trying to convert it to the valid [Color]. - /// Contains basic validator, that requires final input to be provided - /// in one of those formats: - /// - /// * RGB - /// * #RGB - /// * RRGGBB - /// * #RRGGBB - /// * AARRGGBB - /// * #AARRGGBB - /// - /// Where: A stands for Alpha, R for Red, G for Green, and B for blue color. - /// It will only accept 3/6/8 long HEXs with an optional hash (`#`) at the beginning. - /// Allowed characters are Latin A-F case insensitive and numbers 0-9. - /// It does respect the [enableAlpha] flag, so if alpha is disabled, all inputs - /// with transparency are also converted to non-transparent color values. - /// ```dart - /// MaterialButton( - /// elevation: 3.0, - /// onPressed: () { - /// // The initial value can be provided directly to the controller. - /// final textController = - /// TextEditingController(text: '#2F19DB'); - /// showDialog( - /// context: context, - /// builder: (BuildContext context) { - /// return AlertDialog( - /// scrollable: true, - /// titlePadding: const EdgeInsets.all(0.0), - /// contentPadding: const EdgeInsets.all(0.0), - /// content: Column( - /// children: [ - /// ColorPicker( - /// pickerColor: currentColor, - /// onColorChanged: changeColor, - /// colorPickerWidth: 300.0, - /// pickerAreaHeightPercent: 0.7, - /// enableAlpha: - /// true, // hexInputController will respect it too. - /// displayThumbColor: true, - /// showLabel: true, - /// paletteType: PaletteType.hsv, - /// pickerAreaBorderRadius: const BorderRadius.only( - /// topLeft: const Radius.circular(2.0), - /// topRight: const Radius.circular(2.0), - /// ), - /// hexInputController: textController, // <- here - /// portraitOnly: true, - /// ), - /// Padding( - /// padding: const EdgeInsets.all(16), - /// /* It can be any text field, for example: - /// * TextField - /// * TextFormField - /// * CupertinoTextField - /// * EditableText - /// * any text field from 3-rd party package - /// * your own text field - /// so basically anything that supports/uses - /// a TextEditingController for an editable text. - /// */ - /// child: CupertinoTextField( - /// controller: textController, - /// // Everything below is purely optional. - /// prefix: Padding( - /// padding: const EdgeInsets.only(left: 8), - /// child: const Icon(Icons.tag), - /// ), - /// suffix: IconButton( - /// icon: - /// const Icon(Icons.content_paste_rounded), - /// onPressed: () async => - /// copyToClipboard(textController.text), - /// ), - /// autofocus: true, - /// maxLength: 9, - /// inputFormatters: [ - /// // Any custom input formatter can be passed - /// // here or use any Form validator you want. - /// UpperCaseTextFormatter(), - /// FilteringTextInputFormatter.allow( - /// RegExp(kValidHexPattern)), - /// ], - /// ), - /// ) - /// ], - /// ), - /// ); - /// }, - /// ); - /// }, - /// child: const Text('Change me via text input'), - /// color: currentColor, - /// textColor: useWhiteForeground(currentColor) - /// ? const Color(0xffffffff) - /// : const Color(0xff000000), - /// ), - /// ``` - /// - /// Do not forget to `dispose()` your [TextEditingController] if you creating - /// it inside any kind of [StatefulWidget]'s [State]. - /// Reference: https://en.wikipedia.org/wiki/Web_colors#Hex_triplet - final TextEditingController? hexInputController; - final List? colorHistory; - final ValueChanged>? onHistoryChanged; - - @override - _ColorPickerState createState() => _ColorPickerState(); -} - -class _ColorPickerState extends State { - HSVColor currentHsvColor = const HSVColor.fromAHSV(0.0, 0.0, 0.0, 0.0); - List colorHistory = []; - - @override - void initState() { - 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. - widget.hexInputController?.text = colorToHex( - currentHsvColor.toColor(), - enableAlpha: widget.enableAlpha, - ); - } - // Listen to the text input, If there is an `hexInputController` provided. - widget.hexInputController?.addListener(colorPickerTextInputListener); - if (widget.colorHistory != null && widget.onHistoryChanged != null) { - colorHistory = widget.colorHistory ?? []; - } - super.initState(); - } - - @override - void didUpdateWidget(ColorPicker oldWidget) { - super.didUpdateWidget(oldWidget); - currentHsvColor = (widget.pickerHsvColor != null) - ? widget.pickerHsvColor as HSVColor - : HSVColor.fromColor(widget.pickerColor); - } - - void colorPickerTextInputListener() { - // It can't be null really, since it's only listening if the controller - // is provided, but it may help to calm the Dart analyzer in the future. - 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); - // 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); - } - } - - @override - void dispose() { - widget.hexInputController?.removeListener(colorPickerTextInputListener); - super.dispose(); - } - - Widget colorPickerSlider(TrackType trackType) { - return ColorPickerSlider( - trackType, - currentHsvColor, - (HSVColor color) { - // Update text in `hexInputController` if provided. - widget.hexInputController?.text = - colorToHex(color.toColor(), enableAlpha: widget.enableAlpha); - setState(() => currentHsvColor = color); - widget.onColorChanged(currentHsvColor.toColor()); - if (widget.onHsvColorChanged != null) - widget.onHsvColorChanged!(currentHsvColor); - }, - displayThumbColor: widget.displayThumbColor, - ); - } - - void onColorChanging(HSVColor color) { - // Update text in `hexInputController` if provided. - widget.hexInputController?.text = - colorToHex(color.toColor(), enableAlpha: widget.enableAlpha); - setState(() => currentHsvColor = color); - widget.onColorChanged(currentHsvColor.toColor()); - 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), - ), - ); - } - - Widget sliderByPaletteType() { - switch (widget.paletteType) { - case PaletteType.hsv: - case PaletteType.hsvWithHue: - case PaletteType.hsl: - case PaletteType.hslWithHue: - return colorPickerSlider(TrackType.hue); - case PaletteType.hsvWithValue: - case PaletteType.hueWheel: - return colorPickerSlider(TrackType.value); - case PaletteType.hsvWithSaturation: - return colorPickerSlider(TrackType.saturation); - case PaletteType.hslWithLightness: - return colorPickerSlider(TrackType.lightness); - case PaletteType.hslWithSaturation: - return colorPickerSlider(TrackType.saturationForHSL); - case PaletteType.rgbWithBlue: - return colorPickerSlider(TrackType.blue); - case PaletteType.rgbWithGreen: - return colorPickerSlider(TrackType.green); - case PaletteType.rgbWithRed: - return colorPickerSlider(TrackType.red); - default: - return const SizedBox(); - } - } - - @override - Widget build(BuildContext context) { - if (MediaQuery.of(context).orientation == Orientation.portrait || - widget.portraitOnly) { - return Column( - children: [ - SizedBox( - width: widget.colorPickerWidth, - height: widget.colorPickerWidth * widget.pickerAreaHeightPercent, - child: colorPicker(), - ), - Padding( - padding: const EdgeInsets.fromLTRB(15.0, 5.0, 10.0, 5.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - GestureDetector( - onTap: () => setState(() { - if (widget.onHistoryChanged != null && - !colorHistory.contains(currentHsvColor.toColor())) { - colorHistory.add(currentHsvColor.toColor()); - widget.onHistoryChanged!(colorHistory); - } - }), - child: ColorIndicator(currentHsvColor), - ), - Expanded( - child: Column( - children: [ - SizedBox( - height: 40.0, - width: widget.colorPickerWidth - 75.0, - child: sliderByPaletteType()), - if (widget.enableAlpha) - SizedBox( - height: 40.0, - width: widget.colorPickerWidth - 75.0, - child: colorPickerSlider(TrackType.alpha), - ), - ], - ), - ), - ], - ), - ), - if (colorHistory.isNotEmpty) - SizedBox( - width: widget.colorPickerWidth, - height: 50, - child: - ListView(scrollDirection: Axis.horizontal, children: [ - for (Color color in colorHistory) - Padding( - key: Key(color.hashCode.toString()), - padding: const EdgeInsets.fromLTRB(15, 0, 0, 10), - child: Center( - child: GestureDetector( - onTap: () => onColorChanging(HSVColor.fromColor(color)), - child: ColorIndicator(HSVColor.fromColor(color), - width: 30, height: 30), - ), - ), - ), - const SizedBox(width: 15), - ]), - ), - if (widget.showLabel && widget.labelTypes.isNotEmpty) - FittedBox( - child: ColorPickerLabel( - currentHsvColor, - enableAlpha: widget.enableAlpha, - textStyle: widget.labelTextStyle, - colorLabelTypes: widget.labelTypes, - ), - ), - if (widget.hexInputBar) - ColorPickerInput( - currentHsvColor.toColor(), - (Color color) { - setState(() => currentHsvColor = HSVColor.fromColor(color)); - widget.onColorChanged(currentHsvColor.toColor()); - if (widget.onHsvColorChanged != null) - widget.onHsvColorChanged!(currentHsvColor); - }, - enableAlpha: widget.enableAlpha, - embeddedText: false, - ), - const SizedBox(height: 20.0), - ], - ); - } else { - return Row( - children: [ - SizedBox( - width: widget.colorPickerWidth, - height: widget.colorPickerWidth * widget.pickerAreaHeightPercent, - child: colorPicker()), - Column( - children: [ - Row( - children: [ - const SizedBox(width: 20.0), - GestureDetector( - onTap: () => setState(() { - if (widget.onHistoryChanged != null && - !colorHistory.contains(currentHsvColor.toColor())) { - colorHistory.add(currentHsvColor.toColor()); - widget.onHistoryChanged!(colorHistory); - } - }), - child: ColorIndicator(currentHsvColor), - ), - Column( - children: [ - SizedBox( - height: 40.0, - width: 260.0, - child: sliderByPaletteType()), - if (widget.enableAlpha) - SizedBox( - height: 40.0, - width: 260.0, - child: colorPickerSlider(TrackType.alpha)), - ], - ), - const SizedBox(width: 10.0), - ], - ), - if (colorHistory.isNotEmpty) - SizedBox( - width: widget.colorPickerWidth, - height: 50, - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - 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(height: 20.0), - if (widget.showLabel && widget.labelTypes.isNotEmpty) - FittedBox( - child: ColorPickerLabel( - currentHsvColor, - enableAlpha: widget.enableAlpha, - textStyle: widget.labelTextStyle, - colorLabelTypes: widget.labelTypes, - ), - ), - if (widget.hexInputBar) - ColorPickerInput( - currentHsvColor.toColor(), - (Color color) { - setState(() => currentHsvColor = HSVColor.fromColor(color)); - widget.onColorChanged(currentHsvColor.toColor()); - if (widget.onHsvColorChanged != null) - widget.onHsvColorChanged!(currentHsvColor); - }, - enableAlpha: widget.enableAlpha, - embeddedText: false, - ), - const SizedBox(height: 5), - ], - ), - ], - ); - } - } -} - -/// The Color Picker with sliders only. Support HSV, HSL and RGB color model. -class SlidePicker extends StatefulWidget { - const SlidePicker({ - Key? key, - required this.pickerColor, - required this.onColorChanged, - this.colorModel = ColorModel.rgb, - 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, - this.showParams = 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, - this.showIndicator = true, - this.indicatorSize = const Size(280, 50), - this.indicatorAlignmentBegin = const Alignment(-1.0, -3.0), - this.indicatorAlignmentEnd = const Alignment(1.0, 3.0), - this.displayThumbColor = true, - this.indicatorBorderRadius = const BorderRadius.all(Radius.zero), - }) : super(key: key); - - final Color pickerColor; - final ValueChanged onColorChanged; - final ColorModel colorModel; - final bool enableAlpha; - final Size sliderSize; - final bool showSliderText; - final TextStyle? sliderTextStyle; - final bool showLabel; - final bool showParams; - final List labelTypes; - final TextStyle? labelTextStyle; - final bool showIndicator; - final Size indicatorSize; - final AlignmentGeometry indicatorAlignmentBegin; - final AlignmentGeometry indicatorAlignmentEnd; - final bool displayThumbColor; - final BorderRadius indicatorBorderRadius; - - @override - State createState() => _SlidePickerState(); -} - -class _SlidePickerState extends State { - HSVColor currentHsvColor = const HSVColor.fromAHSV(0.0, 0.0, 0.0, 0.0); - - @override - void initState() { - super.initState(); - currentHsvColor = HSVColor.fromColor(widget.pickerColor); - } - - @override - void didUpdateWidget(SlidePicker oldWidget) { - super.didUpdateWidget(oldWidget); - currentHsvColor = HSVColor.fromColor(widget.pickerColor); - } - - Widget colorPickerSlider(TrackType trackType) { - return ColorPickerSlider( - trackType, - currentHsvColor, - (HSVColor color) { - setState(() => currentHsvColor = color); - widget.onColorChanged(currentHsvColor.toColor()); - }, - displayThumbColor: widget.displayThumbColor, - fullThumbColor: true, - ); - } - - Widget indicator() { - return ClipRRect( - borderRadius: widget.indicatorBorderRadius, - clipBehavior: Clip.antiAliasWithSaveLayer, - child: GestureDetector( - onTap: () { - setState( - () => currentHsvColor = HSVColor.fromColor(widget.pickerColor)); - widget.onColorChanged(currentHsvColor.toColor()); - }, - child: Container( - width: widget.indicatorSize.width, - height: widget.indicatorSize.height, - margin: const EdgeInsets.only(bottom: 15.0), - foregroundDecoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - widget.pickerColor, - widget.pickerColor, - currentHsvColor.toColor(), - currentHsvColor.toColor(), - ], - begin: widget.indicatorAlignmentBegin, - end: widget.indicatorAlignmentEnd, - stops: const [0.0, 0.5, 0.5, 1.0], - ), - ), - child: const CustomPaint(painter: CheckerPainter()), - ), - ), - ); - } - - String getColorParams(int pos) { - assert(pos >= 0 && pos < 4); - if (widget.colorModel == ColorModel.rgb) { - final Color color = currentHsvColor.toColor(); - return [ - color.red.toString(), - color.green.toString(), - color.blue.toString(), - '${(color.opacity * 100).round()}', - ][pos]; - } else if (widget.colorModel == ColorModel.hsv) { - return [ - currentHsvColor.hue.round().toString(), - (currentHsvColor.saturation * 100).round().toString(), - (currentHsvColor.value * 100).round().toString(), - (currentHsvColor.alpha * 100).round().toString(), - ][pos]; - } else if (widget.colorModel == ColorModel.hsl) { - HSLColor hslColor = hsvToHsl(currentHsvColor); - return [ - hslColor.hue.round().toString(), - (hslColor.saturation * 100).round().toString(), - (hslColor.lightness * 100).round().toString(), - (currentHsvColor.alpha * 100).round().toString(), - ][pos]; - } else { - return '??'; - } - } - - @override - Widget build(BuildContext context) { - double fontSize = 14; - if (widget.labelTextStyle != null && - widget.labelTextStyle?.fontSize != null) { - fontSize = widget.labelTextStyle?.fontSize ?? 14; - } - final List 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.enableAlpha) ...[TrackType.alpha], - ]; - List sliders = [ - for (TrackType trackType in trackTypes) - SizedBox( - width: widget.sliderSize.width, - height: widget.sliderSize.height, - child: Row( - children: [ - if (widget.showSliderText) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: Text( - trackType.toString().split('.').last[0].toUpperCase(), - style: widget.sliderTextStyle ?? - Theme.of(context).textTheme.bodyLarge, - ), - ), - Expanded(child: colorPickerSlider(trackType)), - if (widget.showParams) - ConstrainedBox( - constraints: BoxConstraints(minWidth: fontSize * 2 + 5), - child: Text( - getColorParams(trackTypes.indexOf(trackType)), - style: widget.sliderTextStyle ?? - Theme.of(context).textTheme.bodyMedium, - textAlign: TextAlign.right, - ), - ), - ], - ), - ), - ]; - - return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (widget.showIndicator) indicator(), - if (!widget.showIndicator) const SizedBox(height: 20), - ...sliders, - const SizedBox(height: 20.0), - if (widget.showLabel && widget.labelTypes.isNotEmpty) - Padding( - padding: const EdgeInsets.only(bottom: 20.0), - child: ColorPickerLabel( - currentHsvColor, - enableAlpha: widget.enableAlpha, - textStyle: widget.labelTextStyle, - colorLabelTypes: widget.labelTypes, - ), - ), - ], - ); - } -} - -/// The Color Picker with HUE Ring & HSV model. -class HueRingPicker extends StatefulWidget { - const HueRingPicker({ - Key? key, - required this.pickerColor, - required this.onColorChanged, - this.portraitOnly = false, - this.colorPickerHeight = 250.0, - this.hueRingStrokeWidth = 20.0, - this.enableAlpha = false, - this.displayThumbColor = true, - this.pickerAreaBorderRadius = const BorderRadius.all(Radius.zero), - }) : super(key: key); - - final Color pickerColor; - final ValueChanged onColorChanged; - final bool portraitOnly; - final double colorPickerHeight; - final double hueRingStrokeWidth; - final bool enableAlpha; - final bool displayThumbColor; - final BorderRadius pickerAreaBorderRadius; - - @override - _HueRingPickerState createState() => _HueRingPickerState(); -} - -class _HueRingPickerState extends State { - HSVColor currentHsvColor = const HSVColor.fromAHSV(0.0, 0.0, 0.0, 0.0); - - @override - void initState() { - currentHsvColor = HSVColor.fromColor(widget.pickerColor); - super.initState(); - } - - @override - void didUpdateWidget(HueRingPicker oldWidget) { - super.didUpdateWidget(oldWidget); - currentHsvColor = HSVColor.fromColor(widget.pickerColor); - } - - void onColorChanging(HSVColor color) { - setState(() => currentHsvColor = color); - widget.onColorChanged(currentHsvColor.toColor()); - } - - @override - Widget build(BuildContext context) { - if (MediaQuery.of(context).orientation == Orientation.portrait || - widget.portraitOnly) { - return Column( - children: [ - ClipRRect( - borderRadius: widget.pickerAreaBorderRadius, - child: Padding( - padding: const EdgeInsets.all(15), - child: Stack( - alignment: AlignmentDirectional.center, - children: [ - 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) - SizedBox( - height: 40.0, - width: widget.colorPickerHeight, - child: ColorPickerSlider( - TrackType.alpha, - currentHsvColor, - onColorChanging, - displayThumbColor: widget.displayThumbColor, - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(15.0, 5.0, 10.0, 5.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const SizedBox(width: 10), - ColorIndicator(currentHsvColor), - Expanded( - child: Padding( - padding: const EdgeInsets.fromLTRB(0, 5, 0, 20), - child: ColorPickerInput( - currentHsvColor.toColor(), - (Color color) { - setState( - () => currentHsvColor = HSVColor.fromColor(color)); - widget.onColorChanged(currentHsvColor.toColor()); - }, - enableAlpha: widget.enableAlpha, - embeddedText: true, - ), - ), - ), - ], - ), - ), - ], - ); - } else { - return Row( - children: [ - Expanded( - child: SizedBox( - width: 300.0, - height: widget.colorPickerHeight, - child: ClipRRect( - borderRadius: widget.pickerAreaBorderRadius, - child: ColorPickerArea( - currentHsvColor, onColorChanging, PaletteType.hsv), - ), - ), - ), - ClipRRect( - borderRadius: widget.pickerAreaBorderRadius, - child: Padding( - padding: const EdgeInsets.all(15), - child: Stack( - alignment: AlignmentDirectional.topCenter, - children: [ - 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, - ), - 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, - ), - ), - ], - ), - ]), - ), - ), - ], - ); - } - } -} diff --git a/lib/src/packages/flutter_colorpicker/src/colors.dart b/lib/src/packages/flutter_colorpicker/src/colors.dart deleted file mode 100644 index 041a1f20..00000000 --- a/lib/src/packages/flutter_colorpicker/src/colors.dart +++ /dev/null @@ -1,172 +0,0 @@ -// ignore_for_file: type=lint - -import 'dart:ui'; - -/// X11 Colors -/// -/// https://en.wikipedia.org/wiki/X11_color_names - -const Map x11Colors = { - 'aliceblue': Color(0xfff0f8ff), - 'antiquewhite': Color(0xfffaebd7), - 'aqua': Color(0xff00ffff), - 'aquamarine': Color(0xff7fffd4), - 'azure': Color(0xfff0ffff), - 'beige': Color(0xfff5f5dc), - 'bisque': Color(0xffffe4c4), - 'black': Color(0xff000000), - 'blanchedalmond': Color(0xffffebcd), - 'blue': Color(0xff0000ff), - 'blueviolet': Color(0xff8a2be2), - 'brown': Color(0xffa52a2a), - 'burlywood': Color(0xffdeb887), - 'cadetblue': Color(0xff5f9ea0), - 'chartreuse': Color(0xff7fff00), - 'chocolate': Color(0xffd2691e), - 'coral': Color(0xffff7f50), - 'cornflower': Color(0xff6495ed), - 'cornflowerblue': Color(0xff6495ed), - 'cornsilk': Color(0xfffff8dc), - 'crimson': Color(0xffdc143c), - 'cyan': Color(0xff00ffff), - 'darkblue': Color(0xff00008b), - 'darkcyan': Color(0xff008b8b), - 'darkgoldenrod': Color(0xffb8860b), - 'darkgray': Color(0xffa9a9a9), - 'darkgreen': Color(0xff006400), - 'darkgrey': Color(0xffa9a9a9), - 'darkkhaki': Color(0xffbdb76b), - 'darkmagenta': Color(0xff8b008b), - 'darkolivegreen': Color(0xff556b2f), - 'darkorange': Color(0xffff8c00), - 'darkorchid': Color(0xff9932cc), - 'darkred': Color(0xff8b0000), - 'darksalmon': Color(0xffe9967a), - 'darkseagreen': Color(0xff8fbc8f), - 'darkslateblue': Color(0xff483d8b), - 'darkslategray': Color(0xff2f4f4f), - 'darkslategrey': Color(0xff2f4f4f), - 'darkturquoise': Color(0xff00ced1), - 'darkviolet': Color(0xff9400d3), - 'deeppink': Color(0xffff1493), - 'deepskyblue': Color(0xff00bfff), - 'dimgray': Color(0xff696969), - 'dimgrey': Color(0xff696969), - 'dodgerblue': Color(0xff1e90ff), - 'firebrick': Color(0xffb22222), - 'floralwhite': Color(0xfffffaf0), - 'forestgreen': Color(0xff228b22), - 'fuchsia': Color(0xffff00ff), - 'gainsboro': Color(0xffdcdcdc), - 'ghostwhite': Color(0xfff8f8ff), - 'gold': Color(0xffffd700), - 'goldenrod': Color(0xffdaa520), - 'gray': Color(0xff808080), - 'green': Color(0xff008000), - 'greenyellow': Color(0xffadff2f), - 'grey': Color(0xff808080), - 'honeydew': Color(0xfff0fff0), - 'hotpink': Color(0xffff69b4), - 'indianred': Color(0xffcd5c5c), - 'indigo': Color(0xff4b0082), - 'ivory': Color(0xfffffff0), - 'khaki': Color(0xfff0e68c), - 'laserlemon': Color(0xffffff54), - 'lavender': Color(0xffe6e6fa), - 'lavenderblush': Color(0xfffff0f5), - 'lawngreen': Color(0xff7cfc00), - 'lemonchiffon': Color(0xfffffacd), - 'lightblue': Color(0xffadd8e6), - 'lightcoral': Color(0xfff08080), - 'lightcyan': Color(0xffe0ffff), - 'lightgoldenrod': Color(0xfffafad2), - 'lightgoldenrodyellow': Color(0xfffafad2), - 'lightgray': Color(0xffd3d3d3), - 'lightgreen': Color(0xff90ee90), - 'lightgrey': Color(0xffd3d3d3), - 'lightpink': Color(0xffffb6c1), - 'lightsalmon': Color(0xffffa07a), - 'lightseagreen': Color(0xff20b2aa), - 'lightskyblue': Color(0xff87cefa), - 'lightslategray': Color(0xff778899), - 'lightslategrey': Color(0xff778899), - 'lightsteelblue': Color(0xffb0c4de), - 'lightyellow': Color(0xffffffe0), - 'lime': Color(0xff00ff00), - 'limegreen': Color(0xff32cd32), - 'linen': Color(0xfffaf0e6), - 'magenta': Color(0xffff00ff), - 'maroon': Color(0xff800000), - 'maroon2': Color(0xff7f0000), - 'maroon3': Color(0xffb03060), - 'mediumaquamarine': Color(0xff66cdaa), - 'mediumblue': Color(0xff0000cd), - 'mediumorchid': Color(0xffba55d3), - 'mediumpurple': Color(0xff9370db), - 'mediumseagreen': Color(0xff3cb371), - 'mediumslateblue': Color(0xff7b68ee), - 'mediumspringgreen': Color(0xff00fa9a), - 'mediumturquoise': Color(0xff48d1cc), - 'mediumvioletred': Color(0xffc71585), - 'midnightblue': Color(0xff191970), - 'mintcream': Color(0xfff5fffa), - 'mistyrose': Color(0xffffe4e1), - 'moccasin': Color(0xffffe4b5), - 'navajowhite': Color(0xffffdead), - 'navy': Color(0xff000080), - 'oldlace': Color(0xfffdf5e6), - 'olive': Color(0xff808000), - 'olivedrab': Color(0xff6b8e23), - 'orange': Color(0xffffa500), - 'orangered': Color(0xffff4500), - 'orchid': Color(0xffda70d6), - 'palegoldenrod': Color(0xffeee8aa), - 'palegreen': Color(0xff98fb98), - 'paleturquoise': Color(0xffafeeee), - 'palevioletred': Color(0xffdb7093), - 'papayawhip': Color(0xffffefd5), - 'peachpuff': Color(0xffffdab9), - 'peru': Color(0xffcd853f), - 'pink': Color(0xffffc0cb), - 'plum': Color(0xffdda0dd), - 'powderblue': Color(0xffb0e0e6), - 'purple': Color(0xff800080), - 'purple2': Color(0xff7f007f), - 'purple3': Color(0xffa020f0), - 'rebeccapurple': Color(0xff663399), - 'red': Color(0xffff0000), - 'rosybrown': Color(0xffbc8f8f), - 'royalblue': Color(0xff4169e1), - 'saddlebrown': Color(0xff8b4513), - 'salmon': Color(0xfffa8072), - 'sandybrown': Color(0xfff4a460), - 'seagreen': Color(0xff2e8b57), - 'seashell': Color(0xfffff5ee), - 'sienna': Color(0xffa0522d), - 'silver': Color(0xffc0c0c0), - 'skyblue': Color(0xff87ceeb), - 'slateblue': Color(0xff6a5acd), - 'slategray': Color(0xff708090), - 'slategrey': Color(0xff708090), - 'snow': Color(0xfffffafa), - 'springgreen': Color(0xff00ff7f), - 'steelblue': Color(0xff4682b4), - 'tan': Color(0xffd2b48c), - 'teal': Color(0xff008080), - 'thistle': Color(0xffd8bfd8), - 'tomato': Color(0xffff6347), - 'turquoise': Color(0xff40e0d0), - 'violet': Color(0xffee82ee), - 'wheat': Color(0xfff5deb3), - 'white': Color(0xffffffff), - 'whitesmoke': Color(0xfff5f5f5), - 'yellow': Color(0xffffff00), - 'yellowgreen': Color(0xff9acd32), -}; - -Color? colorFromName(String val) => - x11Colors[val.trim().replaceAll(' ', '').toLowerCase()]; - -extension ColorExtension on String { - Color? toColor() => colorFromName(this); -} diff --git a/lib/src/packages/flutter_colorpicker/src/material_picker.dart b/lib/src/packages/flutter_colorpicker/src/material_picker.dart deleted file mode 100644 index b9d5d8c2..00000000 --- a/lib/src/packages/flutter_colorpicker/src/material_picker.dart +++ /dev/null @@ -1,384 +0,0 @@ -// ignore_for_file: type=lint - -/// Material Color Picker - -library material_colorpicker; - -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'utils.dart'; - -// The Color Picker which contains Material Design Color Palette. -class MaterialPicker extends StatefulWidget { - const MaterialPicker({ - Key? key, - required this.pickerColor, - required this.onColorChanged, - this.onPrimaryChanged, - this.enableLabel = false, - this.portraitOnly = false, - }) : super(key: key); - - final Color pickerColor; - final ValueChanged onColorChanged; - final ValueChanged? onPrimaryChanged; - final bool enableLabel; - final bool portraitOnly; - - @override - State createState() => _MaterialPickerState(); -} - -class _MaterialPickerState extends State { - final List> _colorTypes = [ - [Colors.red, Colors.redAccent], - [Colors.pink, Colors.pinkAccent], - [Colors.purple, Colors.purpleAccent], - [Colors.deepPurple, Colors.deepPurpleAccent], - [Colors.indigo, Colors.indigoAccent], - [Colors.blue, Colors.blueAccent], - [Colors.lightBlue, Colors.lightBlueAccent], - [Colors.cyan, Colors.cyanAccent], - [Colors.teal, Colors.tealAccent], - [Colors.green, Colors.greenAccent], - [Colors.lightGreen, Colors.lightGreenAccent], - [Colors.lime, Colors.limeAccent], - [Colors.yellow, Colors.yellowAccent], - [Colors.amber, Colors.amberAccent], - [Colors.orange, Colors.orangeAccent], - [Colors.deepOrange, Colors.deepOrangeAccent], - [Colors.brown], - [Colors.grey], - [Colors.blueGrey], - [Colors.black], - ]; - - List _currentColorType = [Colors.red, Colors.redAccent]; - Color _currentShading = Colors.transparent; - - List> _shadingTypes(List colors) { - List> result = []; - - 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()); - } 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()); - } else if (colorType is MaterialColor) { - result.addAll([50, 100, 200, 300, 400, 500, 600, 700, 800, 900] - .map((int shade) => {colorType[shade]!: shade.toString()}) - .toList()); - } else { - result.add({const Color(0x00000000): ''}); - } - } - - return result; - } - - @override - void initState() { - for (List _colors in _colorTypes) { - _shadingTypes(_colors).forEach((Map color) { - if (widget.pickerColor.value == color.keys.first.value) { - return setState(() { - _currentColorType = _colors; - _currentShading = color.keys.first; - }); - } - }); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - 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), - 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) - ], - 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)), - ), - child: ScrollConfiguration( - behavior: ScrollConfiguration.of(context) - .copyWith(dragDevices: PointerDeviceKind.values.toSet()), - child: ListView( - scrollDirection: _isPortrait ? Axis.vertical : Axis.horizontal, - children: [ - _isPortrait - ? const Padding(padding: EdgeInsets.only(top: 7)) - : const Padding(padding: EdgeInsets.only(left: 7)), - ..._colorTypes.map((List _colors) { - Color _colorType = _colors[0]; - return GestureDetector( - onTap: () { - 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), - child: Align( - child: AnimatedContainer( - duration: const Duration(milliseconds: 300), - width: 25, - height: 25, - decoration: BoxDecoration( - color: _colorType, - 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, - ), - ] - : null, - border: _colorType == Theme.of(context).cardColor - ? Border.all( - color: (Theme.of(context).brightness == - Brightness.light) - ? Colors.grey[300]! - : Colors.black38, - width: 1) - : null, - ), - ), - ), - ), - ); - }), - _isPortrait - ? const Padding(padding: EdgeInsets.only(top: 5)) - : const Padding(padding: EdgeInsets.only(left: 5)), - ], - ), - ), - ), - ); - } - - Widget _shadingList() { - return ScrollConfiguration( - behavior: ScrollConfiguration.of(context) - .copyWith(dragDevices: PointerDeviceKind.values.toSet()), - child: ListView( - scrollDirection: _isPortrait ? Axis.vertical : Axis.horizontal, - children: [ - _isPortrait - ? const Padding(padding: EdgeInsets.only(top: 15)) - : const Padding(padding: EdgeInsets.only(left: 15)), - ..._shadingTypes(_currentColorType).map((Map color) { - final Color _color = color.keys.first; - return GestureDetector( - onTap: () { - setState(() => _currentShading = _color); - widget.onColorChanged(_color); - }, - 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), - child: Align( - child: AnimatedContainer( - curve: Curves.fastOutSlowIn, - duration: const Duration(milliseconds: 500), - 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) - : 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, - ), - ), - ) - : const SizedBox(), - ), - ), - ), - ); - }), - _isPortrait - ? const Padding(padding: EdgeInsets.only(top: 15)) - : const Padding(padding: EdgeInsets.only(left: 15)), - ], - ), - ); - } - - if (_isPortrait) { - return SizedBox( - width: 350, - height: 500, - child: Row( - children: [ - _colorList(), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: _shadingList(), - ), - ), - ], - ), - ); - } else { - return SizedBox( - width: 500, - height: 300, - child: Column( - children: [ - _colorList(), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 12), - child: _shadingList(), - ), - ), - ], - ), - ); - } - } -} diff --git a/lib/src/packages/flutter_colorpicker/src/palette.dart b/lib/src/packages/flutter_colorpicker/src/palette.dart deleted file mode 100644 index 5dc7c4ec..00000000 --- a/lib/src/packages/flutter_colorpicker/src/palette.dart +++ /dev/null @@ -1,1523 +0,0 @@ -// ignore_for_file: type=lint - -/// The components of HSV Color Picker -/// -/// Try to create a Color Picker with other layout on your own :) - -import 'dart:math'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'utils.dart'; - -/// Palette types for color picker area widget. -enum PaletteType { - hsv, - hsvWithHue, - hsvWithValue, - hsvWithSaturation, - hsl, - hslWithHue, - hslWithLightness, - hslWithSaturation, - rgbWithBlue, - rgbWithGreen, - rgbWithRed, - hueWheel, -} - -/// Track types for slider picker. -enum TrackType { - hue, - saturation, - saturationForHSL, - value, - lightness, - red, - green, - blue, - alpha, -} - -/// Color information label type. -enum ColorLabelType { hex, rgb, hsv, hsl } - -/// Types for slider picker widget. -enum ColorModel { rgb, hsv, hsl } -// enum ColorSpace { rgb, hsv, hsl, hsp, okhsv, okhsl, xyz, yuv, lab, lch, cmyk } - -/// Painter for SV mixture. -class HSVWithHueColorPainter extends CustomPainter { - const HSVWithHueColorPainter(this.hsvColor, {this.pointerColor}); - - final HSVColor hsvColor; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - const Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [Colors.white, Colors.black], - ); - final Gradient gradientH = LinearGradient( - colors: [ - Colors.white, - HSVColor.fromAHSV(1.0, hsvColor.hue, 1.0, 1.0).toColor(), - ], - ); - canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect)); - canvas.drawRect( - rect, - Paint() - ..blendMode = BlendMode.multiply - ..shader = gradientH.createShader(rect), - ); - - canvas.drawCircle( - Offset( - size.width * hsvColor.saturation, size.height * (1 - hsvColor.value)), - size.height * 0.04, - Paint() - ..color = pointerColor ?? - (useWhiteForeground(hsvColor.toColor()) - ? Colors.white - : Colors.black) - ..strokeWidth = 1.5 - ..blendMode = BlendMode.luminosity - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for HV mixture. -class HSVWithSaturationColorPainter extends CustomPainter { - const HSVWithSaturationColorPainter(this.hsvColor, {this.pointerColor}); - - final HSVColor hsvColor; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - const Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [Colors.transparent, Colors.black], - ); - final List colors = [ - HSVColor.fromAHSV(1.0, 0.0, hsvColor.saturation, 1.0).toColor(), - HSVColor.fromAHSV(1.0, 60.0, hsvColor.saturation, 1.0).toColor(), - HSVColor.fromAHSV(1.0, 120.0, hsvColor.saturation, 1.0).toColor(), - HSVColor.fromAHSV(1.0, 180.0, hsvColor.saturation, 1.0).toColor(), - HSVColor.fromAHSV(1.0, 240.0, hsvColor.saturation, 1.0).toColor(), - HSVColor.fromAHSV(1.0, 300.0, hsvColor.saturation, 1.0).toColor(), - HSVColor.fromAHSV(1.0, 360.0, hsvColor.saturation, 1.0).toColor(), - ]; - final Gradient gradientH = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect)); - - canvas.drawCircle( - Offset( - size.width * hsvColor.hue / 360, - size.height * (1 - hsvColor.value), - ), - size.height * 0.04, - Paint() - ..color = pointerColor ?? - (useWhiteForeground(hsvColor.toColor()) - ? Colors.white - : Colors.black) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for HS mixture. -class HSVWithValueColorPainter extends CustomPainter { - const HSVWithValueColorPainter(this.hsvColor, {this.pointerColor}); - - final HSVColor hsvColor; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - const Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [Colors.transparent, Colors.white], - ); - final List colors = [ - const HSVColor.fromAHSV(1.0, 0.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 60.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 120.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 180.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 240.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 300.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 360.0, 1.0, 1.0).toColor(), - ]; - final Gradient gradientH = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect)); - canvas.drawRect( - rect, - Paint()..color = Colors.black.withOpacity(1 - hsvColor.value), - ); - - canvas.drawCircle( - Offset( - size.width * hsvColor.hue / 360, - size.height * (1 - hsvColor.saturation), - ), - size.height * 0.04, - Paint() - ..color = pointerColor ?? - (useWhiteForeground(hsvColor.toColor()) - ? Colors.white - : Colors.black) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for SL mixture. -class HSLWithHueColorPainter extends CustomPainter { - const HSLWithHueColorPainter(this.hslColor, {this.pointerColor}); - - final HSLColor hslColor; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - final Gradient gradientH = LinearGradient( - colors: [ - const Color(0xff808080), - HSLColor.fromAHSL(1.0, hslColor.hue, 1.0, 0.5).toColor(), - ], - ); - const Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - stops: [0.0, 0.5, 0.5, 1], - colors: [ - Colors.white, - Color(0x00ffffff), - Colors.transparent, - Colors.black, - ], - ); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect)); - - canvas.drawCircle( - Offset(size.width * hslColor.saturation, - size.height * (1 - hslColor.lightness)), - size.height * 0.04, - Paint() - ..color = pointerColor ?? - (useWhiteForeground(hslColor.toColor()) - ? Colors.white - : Colors.black) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for HL mixture. -class HSLWithSaturationColorPainter extends CustomPainter { - const HSLWithSaturationColorPainter(this.hslColor, {this.pointerColor}); - - final HSLColor hslColor; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - final List colors = [ - HSLColor.fromAHSL(1.0, 0.0, hslColor.saturation, 0.5).toColor(), - HSLColor.fromAHSL(1.0, 60.0, hslColor.saturation, 0.5).toColor(), - HSLColor.fromAHSL(1.0, 120.0, hslColor.saturation, 0.5).toColor(), - HSLColor.fromAHSL(1.0, 180.0, hslColor.saturation, 0.5).toColor(), - HSLColor.fromAHSL(1.0, 240.0, hslColor.saturation, 0.5).toColor(), - HSLColor.fromAHSL(1.0, 300.0, hslColor.saturation, 0.5).toColor(), - HSLColor.fromAHSL(1.0, 360.0, hslColor.saturation, 0.5).toColor(), - ]; - final Gradient gradientH = LinearGradient(colors: colors); - const Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - stops: [0.0, 0.5, 0.5, 1], - colors: [ - Colors.white, - Color(0x00ffffff), - Colors.transparent, - Colors.black, - ], - ); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect)); - - canvas.drawCircle( - 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) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for HS mixture. -class HSLWithLightnessColorPainter extends CustomPainter { - const HSLWithLightnessColorPainter(this.hslColor, {this.pointerColor}); - - final HSLColor hslColor; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - final List colors = [ - const HSLColor.fromAHSL(1.0, 0.0, 1.0, 0.5).toColor(), - const HSLColor.fromAHSL(1.0, 60.0, 1.0, 0.5).toColor(), - const HSLColor.fromAHSL(1.0, 120.0, 1.0, 0.5).toColor(), - const HSLColor.fromAHSL(1.0, 180.0, 1.0, 0.5).toColor(), - const HSLColor.fromAHSL(1.0, 240.0, 1.0, 0.5).toColor(), - const HSLColor.fromAHSL(1.0, 300.0, 1.0, 0.5).toColor(), - const HSLColor.fromAHSL(1.0, 360.0, 1.0, 0.5).toColor(), - ]; - final Gradient gradientH = LinearGradient(colors: colors); - const Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Colors.transparent, - Color(0xFF808080), - ], - ); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect(rect, Paint()..shader = gradientV.createShader(rect)); - canvas.drawRect( - rect, - 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)), - ); - - canvas.drawCircle( - 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) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for GB mixture. -class RGBWithRedColorPainter extends CustomPainter { - const RGBWithRedColorPainter(this.color, {this.pointerColor}); - - final Color color; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - final Gradient gradientH = LinearGradient( - colors: [ - Color.fromRGBO(color.red, 255, 0, 1.0), - Color.fromRGBO(color.red, 255, 255, 1.0), - ], - ); - final Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color.fromRGBO(color.red, 255, 255, 1.0), - Color.fromRGBO(color.red, 0, 255, 1.0), - ], - ); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect( - rect, - Paint() - ..shader = gradientV.createShader(rect) - ..blendMode = BlendMode.multiply, - ); - - canvas.drawCircle( - 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) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for RB mixture. -class RGBWithGreenColorPainter extends CustomPainter { - const RGBWithGreenColorPainter(this.color, {this.pointerColor}); - - final Color color; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - final Gradient gradientH = LinearGradient( - colors: [ - Color.fromRGBO(255, color.green, 0, 1.0), - Color.fromRGBO(255, color.green, 255, 1.0), - ], - ); - final Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color.fromRGBO(255, color.green, 255, 1.0), - Color.fromRGBO(0, color.green, 255, 1.0), - ], - ); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect( - rect, - Paint() - ..shader = gradientV.createShader(rect) - ..blendMode = BlendMode.multiply, - ); - - canvas.drawCircle( - 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) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for RG mixture. -class RGBWithBlueColorPainter extends CustomPainter { - const RGBWithBlueColorPainter(this.color, {this.pointerColor}); - - final Color color; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - final Gradient gradientH = LinearGradient( - colors: [ - Color.fromRGBO(0, 255, color.blue, 1.0), - Color.fromRGBO(255, 255, color.blue, 1.0), - ], - ); - final Gradient gradientV = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color.fromRGBO(255, 255, color.blue, 1.0), - Color.fromRGBO(255, 0, color.blue, 1.0), - ], - ); - canvas.drawRect(rect, Paint()..shader = gradientH.createShader(rect)); - canvas.drawRect( - rect, - Paint() - ..shader = gradientV.createShader(rect) - ..blendMode = BlendMode.multiply, - ); - - canvas.drawCircle( - 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) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for hue color wheel. -class HUEColorWheelPainter extends CustomPainter { - const HUEColorWheelPainter(this.hsvColor, {this.pointerColor}); - - final HSVColor hsvColor; - final Color? pointerColor; - - @override - void paint(Canvas canvas, Size size) { - Rect rect = Offset.zero & size; - Offset center = Offset(size.width / 2, size.height / 2); - double radio = size.width <= size.height ? size.width / 2 : size.height / 2; - - final List colors = [ - const HSVColor.fromAHSV(1.0, 360.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 300.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 240.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 180.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 120.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 60.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 0.0, 1.0, 1.0).toColor(), - ]; - final Gradient gradientS = SweepGradient(colors: colors); - const Gradient gradientR = RadialGradient( - colors: [ - Colors.white, - 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( - Offset( - 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) - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke, - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for hue ring. -class HueRingPainter extends CustomPainter { - const HueRingPainter(this.hsvColor, - {this.displayThumbColor = true, this.strokeWidth = 5}); - - final HSVColor hsvColor; - final bool displayThumbColor; - final double strokeWidth; - - @override - void paint(Canvas canvas, Size size) { - Rect rect = Offset.zero & size; - Offset center = Offset(size.width / 2, size.height / 2); - double radio = size.width <= size.height ? size.width / 2 : size.height / 2; - - final List colors = [ - const HSVColor.fromAHSV(1.0, 360.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 300.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 240.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 180.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 120.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 60.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 0.0, 1.0, 1.0).toColor(), - ]; - canvas.drawCircle( - center, - radio, - Paint() - ..shader = SweepGradient(colors: colors).createShader(rect) - ..style = PaintingStyle.stroke - ..strokeWidth = strokeWidth, - ); - - final Offset offset = Offset( - 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.drawCircle( - offset, - size.height * 0.04, - Paint() - ..color = Colors.white - ..style = PaintingStyle.fill, - ); - if (displayThumbColor) { - canvas.drawCircle( - offset, - size.height * 0.03, - Paint() - ..color = hsvColor.toColor() - ..style = PaintingStyle.fill, - ); - } - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -class _SliderLayout extends MultiChildLayoutDelegate { - static const String track = 'track'; - static const String thumb = 'thumb'; - static const String gestureContainer = 'gesturecontainer'; - - @override - void performLayout(Size size) { - layoutChild( - track, - BoxConstraints.tightFor( - width: size.width - 30.0, - height: size.height / 5, - ), - ); - positionChild(track, Offset(15.0, size.height * 0.4)); - layoutChild( - thumb, - BoxConstraints.tightFor(width: 5.0, height: size.height / 4), - ); - positionChild(thumb, Offset(0.0, size.height * 0.4)); - layoutChild( - gestureContainer, - BoxConstraints.tightFor(width: size.width, height: size.height), - ); - positionChild(gestureContainer, Offset.zero); - } - - @override - bool shouldRelayout(_SliderLayout oldDelegate) => false; -} - -/// Painter for all kinds of track types. -class TrackPainter extends CustomPainter { - const TrackPainter(this.trackType, this.hsvColor); - - final TrackType trackType; - final HSVColor hsvColor; - - @override - void paint(Canvas canvas, Size size) { - final Rect rect = Offset.zero & size; - if (trackType == TrackType.alpha) { - final Size chessSize = Size(size.height / 2, size.height / 2); - Paint chessPaintB = Paint()..color = const Color(0xffcccccc); - Paint chessPaintW = Paint()..color = Colors.white; - List.generate((size.height / chessSize.height).round(), (int y) { - List.generate((size.width / chessSize.width).round(), (int x) { - canvas.drawRect( - Offset(chessSize.width * x, chessSize.width * y) & chessSize, - (x + y) % 2 != 0 ? chessPaintW : chessPaintB, - ); - }); - }); - } - - switch (trackType) { - case TrackType.hue: - final List colors = [ - const HSVColor.fromAHSV(1.0, 0.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 60.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 120.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 180.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 240.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 300.0, 1.0, 1.0).toColor(), - const HSVColor.fromAHSV(1.0, 360.0, 1.0, 1.0).toColor(), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.saturation: - final List colors = [ - HSVColor.fromAHSV(1.0, hsvColor.hue, 0.0, 1.0).toColor(), - HSVColor.fromAHSV(1.0, hsvColor.hue, 1.0, 1.0).toColor(), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.saturationForHSL: - final List colors = [ - HSLColor.fromAHSL(1.0, hsvColor.hue, 0.0, 0.5).toColor(), - HSLColor.fromAHSL(1.0, hsvColor.hue, 1.0, 0.5).toColor(), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.value: - final List colors = [ - HSVColor.fromAHSV(1.0, hsvColor.hue, 1.0, 0.0).toColor(), - HSVColor.fromAHSV(1.0, hsvColor.hue, 1.0, 1.0).toColor(), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.lightness: - final List colors = [ - HSLColor.fromAHSL(1.0, hsvColor.hue, 1.0, 0.0).toColor(), - HSLColor.fromAHSL(1.0, hsvColor.hue, 1.0, 0.5).toColor(), - HSLColor.fromAHSL(1.0, hsvColor.hue, 1.0, 1.0).toColor(), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.red: - final List colors = [ - hsvColor.toColor().withRed(0).withOpacity(1.0), - hsvColor.toColor().withRed(255).withOpacity(1.0), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.green: - final List colors = [ - hsvColor.toColor().withGreen(0).withOpacity(1.0), - hsvColor.toColor().withGreen(255).withOpacity(1.0), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.blue: - final List colors = [ - hsvColor.toColor().withBlue(0).withOpacity(1.0), - hsvColor.toColor().withBlue(255).withOpacity(1.0), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - case TrackType.alpha: - final List colors = [ - hsvColor.toColor().withOpacity(0.0), - hsvColor.toColor().withOpacity(1.0), - ]; - Gradient gradient = LinearGradient(colors: colors); - canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); - break; - } - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for thumb of slider. -class ThumbPainter extends CustomPainter { - const ThumbPainter({this.thumbColor, this.fullThumbColor = false}); - - final Color? thumbColor; - final bool fullThumbColor; - - @override - void paint(Canvas canvas, Size size) { - canvas.drawShadow( - Path() - ..addOval( - Rect.fromCircle( - center: const Offset(0.5, 2.0), radius: size.width * 1.8), - ), - Colors.black, - 3.0, - true, - ); - canvas.drawCircle( - Offset(0.0, size.height * 0.4), - size.height, - Paint() - ..color = Colors.white - ..style = PaintingStyle.fill); - if (thumbColor != null) { - canvas.drawCircle( - Offset(0.0, size.height * 0.4), - size.height * (fullThumbColor ? 1.0 : 0.65), - Paint() - ..color = thumbColor! - ..style = PaintingStyle.fill); - } - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for chess type alpha background in color indicator widget. -class IndicatorPainter extends CustomPainter { - const IndicatorPainter(this.color); - - final Color color; - - @override - void paint(Canvas canvas, Size size) { - final Size chessSize = Size(size.width / 10, size.height / 10); - final Paint chessPaintB = Paint()..color = const Color(0xFFCCCCCC); - final Paint chessPaintW = Paint()..color = Colors.white; - List.generate((size.height / chessSize.height).round(), (int y) { - List.generate((size.width / chessSize.width).round(), (int x) { - canvas.drawRect( - Offset(chessSize.width * x, chessSize.height * y) & chessSize, - (x + y) % 2 != 0 ? chessPaintW : chessPaintB, - ); - }); - }); - - canvas.drawCircle( - Offset(size.width / 2, size.height / 2), - size.height / 2, - Paint() - ..color = color - ..style = PaintingStyle.fill); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Painter for chess type alpha background in slider track widget. -class CheckerPainter extends CustomPainter { - const CheckerPainter(); - - @override - void paint(Canvas canvas, Size size) { - final Size chessSize = Size(size.height / 6, size.height / 6); - Paint chessPaintB = Paint()..color = const Color(0xffcccccc); - Paint chessPaintW = Paint()..color = Colors.white; - List.generate((size.height / chessSize.height).round(), (int y) { - List.generate((size.width / chessSize.width).round(), (int x) { - canvas.drawRect( - Offset(chessSize.width * x, chessSize.width * y) & chessSize, - (x + y) % 2 != 0 ? chessPaintW : chessPaintB, - ); - }); - }); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -/// Provide label for color information. -class ColorPickerLabel extends StatefulWidget { - const ColorPickerLabel( - this.hsvColor, { - Key? key, - this.enableAlpha = true, - this.colorLabelTypes = const [ - ColorLabelType.rgb, - ColorLabelType.hsv, - ColorLabelType.hsl - ], - this.textStyle, - }) : assert(colorLabelTypes.length > 0), - super(key: key); - - final HSVColor hsvColor; - final bool enableAlpha; - final TextStyle? textStyle; - final List colorLabelTypes; - - @override - _ColorPickerLabelState createState() => _ColorPickerLabelState(); -} - -class _ColorPickerLabelState extends State { - final Map> _colorTypes = const { - ColorLabelType.hex: ['R', 'G', 'B', 'A'], - ColorLabelType.rgb: ['R', 'G', 'B', 'A'], - ColorLabelType.hsv: ['H', 'S', 'V', 'A'], - ColorLabelType.hsl: ['H', 'S', 'L', 'A'], - }; - - late ColorLabelType _colorType; - - @override - void initState() { - super.initState(); - _colorType = widget.colorLabelTypes[0]; - } - - List colorValue(HSVColor hsvColor, ColorLabelType colorLabelType) { - if (colorLabelType == ColorLabelType.hex) { - final Color color = hsvColor.toColor(); - return [ - color.red.toRadixString(16).toUpperCase().padLeft(2, '0'), - color.green.toRadixString(16).toUpperCase().padLeft(2, '0'), - color.blue.toRadixString(16).toUpperCase().padLeft(2, '0'), - color.alpha.toRadixString(16).toUpperCase().padLeft(2, '0'), - ]; - } else if (colorLabelType == ColorLabelType.rgb) { - final Color color = hsvColor.toColor(); - return [ - color.red.toString(), - color.green.toString(), - color.blue.toString(), - '${(color.opacity * 100).round()}%', - ]; - } else if (colorLabelType == ColorLabelType.hsv) { - return [ - '${hsvColor.hue.round()}°', - '${(hsvColor.saturation * 100).round()}%', - '${(hsvColor.value * 100).round()}%', - '${(hsvColor.alpha * 100).round()}%', - ]; - } else if (colorLabelType == ColorLabelType.hsl) { - HSLColor hslColor = hsvToHsl(hsvColor); - return [ - '${hslColor.hue.round()}°', - '${(hslColor.saturation * 100).round()}%', - '${(hslColor.lightness * 100).round()}%', - '${(hsvColor.alpha * 100).round()}%', - ]; - } else { - return ['??', '??', '??', '??']; - } - } - - List colorValueLabels() { - double fontSize = 14; - if (widget.textStyle != null && widget.textStyle?.fontSize != null) - fontSize = widget.textStyle?.fontSize ?? 14; - - return [ - for (String item in _colorTypes[_colorType] ?? []) - if (widget.enableAlpha || item != 'A') - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4.0), - child: ConstrainedBox( - constraints: BoxConstraints(minWidth: fontSize * 2), - child: IntrinsicHeight( - child: Column( - children: [ - Text( - item, - style: widget.textStyle ?? - Theme.of(context).textTheme.bodyLarge, - ), - const SizedBox(height: 10.0), - Expanded( - child: Text( - colorValue(widget.hsvColor, _colorType)[ - _colorTypes[_colorType]!.indexOf(item)], - overflow: TextOverflow.ellipsis, - style: widget.textStyle ?? - Theme.of(context).textTheme.bodyMedium, - ), - ), - ], - ), - ), - ), - ) - ]; - } - - @override - Widget build(BuildContext context) { - return Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - DropdownButton( - value: _colorType, - onChanged: (ColorLabelType? type) { - if (type != null) setState(() => _colorType = type); - }, - items: [ - for (ColorLabelType type in widget.colorLabelTypes) - DropdownMenuItem( - value: type, - child: Text(type.toString().split('.').last.toUpperCase()), - ) - ], - ), - const SizedBox(width: 10.0), - ...colorValueLabels(), - ]); - } -} - -/// Provide hex input wiget for 3/6/8 digits. -class ColorPickerInput extends StatefulWidget { - const ColorPickerInput( - this.color, - this.onColorChanged, { - Key? key, - this.enableAlpha = true, - this.embeddedText = false, - this.disable = false, - }) : super(key: key); - - final Color color; - final ValueChanged onColorChanged; - final bool enableAlpha; - final bool embeddedText; - final bool disable; - - @override - _ColorPickerInputState createState() => _ColorPickerInputState(); -} - -class _ColorPickerInputState extends State { - TextEditingController textEditingController = TextEditingController(); - int inputColor = 0; - - @override - void dispose() { - textEditingController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if (inputColor != widget.color.value) { - textEditingController.text = '#' + - 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') - : ''); - } - 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), - const SizedBox(width: 10), - SizedBox( - width: (Theme.of(context).textTheme.bodyMedium?.fontSize ?? 14) * 10, - child: TextField( - enabled: !widget.disable, - controller: textEditingController, - inputFormatters: [ - UpperCaseTextFormatter(), - FilteringTextInputFormatter.allow(RegExp(kValidHexPattern)), - ], - decoration: InputDecoration( - isDense: true, - label: widget.embeddedText ? const Text('Hex') : null, - contentPadding: const EdgeInsets.symmetric(vertical: 5), - ), - onChanged: (String value) { - String input = value; - if (value.length == 9) { - input = value.split('').getRange(7, 9).join() + - value.split('').getRange(1, 7).join(); - } - final Color? color = colorFromHex(input); - if (color != null) { - widget.onColorChanged(color); - inputColor = color.value; - } - }, - ), - ), - ]), - ); - } -} - -/// 9 track types for slider picker widget. -class ColorPickerSlider extends StatelessWidget { - const ColorPickerSlider( - this.trackType, - this.hsvColor, - this.onColorChanged, { - Key? key, - this.displayThumbColor = false, - this.fullThumbColor = false, - }) : super(key: key); - - final TrackType trackType; - final HSVColor hsvColor; - final ValueChanged onColorChanged; - final bool displayThumbColor; - final bool fullThumbColor; - - 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); - switch (trackType) { - case TrackType.hue: - // 360 is the same as zero - // if set to 360, sliding to end goes to zero - onColorChanged(hsvColor.withHue(progress * 359)); - break; - case TrackType.saturation: - onColorChanged(hsvColor.withSaturation(progress)); - break; - case TrackType.saturationForHSL: - onColorChanged(hslToHsv(hsvToHsl(hsvColor).withSaturation(progress))); - break; - case TrackType.value: - onColorChanged(hsvColor.withValue(progress)); - break; - case TrackType.lightness: - onColorChanged(hslToHsv(hsvToHsl(hsvColor).withLightness(progress))); - break; - case TrackType.red: - onColorChanged(HSVColor.fromColor( - hsvColor.toColor().withRed((progress * 0xff).round()))); - break; - case TrackType.green: - onColorChanged(HSVColor.fromColor( - hsvColor.toColor().withGreen((progress * 0xff).round()))); - break; - case TrackType.blue: - 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))); - break; - } - } - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (BuildContext context, BoxConstraints box) { - double thumbOffset = 15.0; - Color thumbColor; - switch (trackType) { - case TrackType.hue: - thumbOffset += (box.maxWidth - 30.0) * hsvColor.hue / 360; - thumbColor = HSVColor.fromAHSV(1.0, hsvColor.hue, 1.0, 1.0).toColor(); - break; - case TrackType.saturation: - thumbOffset += (box.maxWidth - 30.0) * hsvColor.saturation; - 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(); - break; - case TrackType.value: - thumbOffset += (box.maxWidth - 30.0) * hsvColor.value; - 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(); - 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; - thumbColor = hsvColor.toColor().withOpacity(1.0); - break; - case TrackType.blue: - thumbOffset += (box.maxWidth - 30.0) * hsvColor.toColor().blue / 0xff; - thumbColor = hsvColor.toColor().withOpacity(1.0); - break; - case TrackType.alpha: - thumbOffset += (box.maxWidth - 30.0) * hsvColor.toColor().opacity; - thumbColor = hsvColor.toColor().withOpacity(hsvColor.alpha); - break; - } - - return CustomMultiChildLayout( - delegate: _SliderLayout(), - children: [ - LayoutId( - id: _SliderLayout.track, - child: ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(50.0)), - child: CustomPaint( - painter: TrackPainter( - trackType, - hsvColor, - )), - ), - ), - LayoutId( - id: _SliderLayout.thumb, - child: Transform.translate( - offset: Offset(thumbOffset, 0.0), - child: CustomPaint( - painter: ThumbPainter( - thumbColor: displayThumbColor ? thumbColor : null, - fullThumbColor: fullThumbColor, - ), - ), - ), - ), - LayoutId( - id: _SliderLayout.gestureContainer, - child: LayoutBuilder( - 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, - ); - }, - ), - ), - ], - ); - }); - } -} - -/// Simple round color indicator. -class ColorIndicator extends StatelessWidget { - const ColorIndicator( - this.hsvColor, { - Key? key, - this.width = 50.0, - this.height = 50.0, - }) : super(key: key); - - final HSVColor hsvColor; - final double width; - final double height; - - @override - Widget build(BuildContext context) { - return Container( - width: width, - height: height, - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(1000.0)), - border: Border.all(color: const Color(0xffdddddd)), - ), - child: ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(1000.0)), - child: CustomPaint(painter: IndicatorPainter(hsvColor.toColor())), - ), - ); - } -} - -/// Provide Rectangle & Circle 2 categories, 10 variations of palette widget. -class ColorPickerArea extends StatelessWidget { - const ColorPickerArea( - this.hsvColor, - this.onColorChanged, - this.paletteType, { - Key? key, - }) : super(key: key); - - final HSVColor hsvColor; - final ValueChanged onColorChanged; - final PaletteType paletteType; - - void _handleColorRectChange(double horizontal, double vertical) { - switch (paletteType) { - case PaletteType.hsv: - case PaletteType.hsvWithHue: - onColorChanged(hsvColor.withSaturation(horizontal).withValue(vertical)); - break; - case PaletteType.hsvWithSaturation: - onColorChanged(hsvColor.withHue(horizontal * 360).withValue(vertical)); - break; - case PaletteType.hsvWithValue: - onColorChanged( - hsvColor.withHue(horizontal * 360).withSaturation(vertical)); - break; - case PaletteType.hsl: - case PaletteType.hslWithHue: - onColorChanged(hslToHsv( - hsvToHsl(hsvColor).withSaturation(horizontal).withLightness(vertical), - )); - break; - case PaletteType.hslWithSaturation: - onColorChanged(hslToHsv( - hsvToHsl(hsvColor).withHue(horizontal * 360).withLightness(vertical), - )); - break; - case PaletteType.hslWithLightness: - onColorChanged(hslToHsv( - hsvToHsl(hsvColor).withHue(horizontal * 360).withSaturation(vertical), - )); - break; - case PaletteType.rgbWithRed: - onColorChanged(HSVColor.fromColor( - 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()), - )); - break; - case PaletteType.rgbWithBlue: - onColorChanged(HSVColor.fromColor( - hsvColor - .toColor() - .withRed((horizontal * 255).round()) - .withGreen((vertical * 255).round()), - )); - break; - default: - break; - } - } - - void _handleColorWheelChange(double hue, double radio) { - onColorChanged(hsvColor.withHue(hue).withSaturation(radio)); - } - - void _handleGesture( - Offset position, BuildContext context, double height, double width) { - RenderBox? getBox = context.findRenderObject() as RenderBox?; - if (getBox == null) return; - - Offset localOffset = getBox.globalToLocal(position); - double horizontal = localOffset.dx.clamp(0.0, width); - double vertical = localOffset.dy.clamp(0.0, height); - - 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)); - } else { - _handleColorRectChange(horizontal / width, 1 - vertical / height); - } - } - - @override - Widget build(BuildContext context) { - return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - double width = constraints.maxWidth; - double height = constraints.maxHeight; - - return RawGestureDetector( - gestures: { - _AlwaysWinPanGestureRecognizer: - GestureRecognizerFactoryWithHandlers< - _AlwaysWinPanGestureRecognizer>( - () => _AlwaysWinPanGestureRecognizer(), - (_AlwaysWinPanGestureRecognizer instance) { - instance - ..onDown = ((details) => _handleGesture( - details.globalPosition, context, height, width)) - ..onUpdate = ((details) => _handleGesture( - details.globalPosition, context, height, width)); - }, - ), - }, - child: Builder( - builder: (BuildContext _) { - switch (paletteType) { - case PaletteType.hsv: - case PaletteType.hsvWithHue: - return CustomPaint(painter: HSVWithHueColorPainter(hsvColor)); - case PaletteType.hsvWithSaturation: - return CustomPaint( - painter: HSVWithSaturationColorPainter(hsvColor)); - case PaletteType.hsvWithValue: - return CustomPaint( - painter: HSVWithValueColorPainter(hsvColor)); - case PaletteType.hsl: - case PaletteType.hslWithHue: - return CustomPaint( - painter: HSLWithHueColorPainter(hsvToHsl(hsvColor))); - case PaletteType.hslWithSaturation: - return CustomPaint( - painter: - HSLWithSaturationColorPainter(hsvToHsl(hsvColor))); - case PaletteType.hslWithLightness: - return CustomPaint( - painter: - HSLWithLightnessColorPainter(hsvToHsl(hsvColor))); - case PaletteType.rgbWithRed: - return CustomPaint( - painter: RGBWithRedColorPainter(hsvColor.toColor())); - case PaletteType.rgbWithGreen: - return CustomPaint( - painter: RGBWithGreenColorPainter(hsvColor.toColor())); - case PaletteType.rgbWithBlue: - return CustomPaint( - painter: RGBWithBlueColorPainter(hsvColor.toColor())); - case PaletteType.hueWheel: - return CustomPaint(painter: HUEColorWheelPainter(hsvColor)); - default: - return const CustomPaint(); - } - }, - ), - ); - }, - ); - } -} - -/// Provide Hue Ring with HSV Rectangle of palette widget. -class ColorPickerHueRing extends StatelessWidget { - const ColorPickerHueRing( - this.hsvColor, - this.onColorChanged, { - Key? key, - this.displayThumbColor = true, - this.strokeWidth = 5.0, - }) : super(key: key); - - final HSVColor hsvColor; - final ValueChanged onColorChanged; - final bool displayThumbColor; - final double strokeWidth; - - void _handleGesture( - Offset position, BuildContext context, double height, double width) { - RenderBox? getBox = context.findRenderObject() as RenderBox?; - if (getBox == null) return; - - Offset localOffset = getBox.globalToLocal(position); - double horizontal = localOffset.dx.clamp(0.0, width); - double vertical = localOffset.dy.clamp(0.0, height); - - 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))); - } - - @override - Widget build(BuildContext context) { - return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - double width = constraints.maxWidth; - double height = constraints.maxHeight; - - return RawGestureDetector( - gestures: { - _AlwaysWinPanGestureRecognizer: - GestureRecognizerFactoryWithHandlers< - _AlwaysWinPanGestureRecognizer>( - () => _AlwaysWinPanGestureRecognizer(), - (_AlwaysWinPanGestureRecognizer instance) { - instance - ..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), - ), - ); - }, - ); - } -} - -class _AlwaysWinPanGestureRecognizer extends PanGestureRecognizer { - @override - void addAllowedPointer(event) { - super.addAllowedPointer(event); - resolve(GestureDisposition.accepted); - } - - @override - String get debugDescription => 'alwaysWin'; -} - -/// Uppercase text formater -class UpperCaseTextFormatter extends TextInputFormatter { - @override - TextEditingValue formatEditUpdate(oldValue, TextEditingValue newValue) => - TextEditingValue( - text: newValue.text.toUpperCase(), selection: newValue.selection); -} diff --git a/lib/src/packages/flutter_colorpicker/src/utils.dart b/lib/src/packages/flutter_colorpicker/src/utils.dart deleted file mode 100644 index bba99353..00000000 --- a/lib/src/packages/flutter_colorpicker/src/utils.dart +++ /dev/null @@ -1,224 +0,0 @@ -// ignore_for_file: type=lint - -/// Common function lib - -import 'dart:math'; -import 'package:flutter/painting.dart'; -import 'colors.dart'; - -/// Check if is good condition to use white foreground color by passing -/// the background color, and optional bias. -/// -/// Reference: -/// -/// Old: https://www.w3.org/TR/WCAG20-TECHS/G18.html -/// -/// New: https://github.com/mchome/flutter_statusbarcolor/issues/40 -bool useWhiteForeground(Color backgroundColor, {double bias = 0.0}) { - // Old: - // return 1.05 / (color.computeLuminance() + 0.05) > 4.5; - - // New: - int v = sqrt(pow(backgroundColor.red, 2) * 0.299 + - pow(backgroundColor.green, 2) * 0.587 + - pow(backgroundColor.blue, 2) * 0.114) - .round(); - return v < 130 + bias ? true : false; -} - -/// Convert HSV to HSL -/// -/// Reference: https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_HSL -HSLColor hsvToHsl(HSVColor color) { - double s = 0.0; - double l = 0.0; - l = (2 - color.saturation) * color.value / 2; - if (l != 0) { - if (l == 1) { - s = 0.0; - } else if (l < 0.5) { - s = color.saturation * color.value / (l * 2); - } else { - s = color.saturation * color.value / (2 - l * 2); - } - } - return HSLColor.fromAHSL( - color.alpha, - color.hue, - s.clamp(0.0, 1.0), - l.clamp(0.0, 1.0), - ); -} - -/// Convert HSL to HSV -/// -/// Reference: https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_HSV -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); - if (v != 0) s = 2 - 2 * color.lightness / v; - - return HSVColor.fromAHSV( - color.alpha, - color.hue, - s.clamp(0.0, 1.0), - v.clamp(0.0, 1.0), - ); -} - -/// [RegExp] pattern for validation HEX color [String] inputs, allows only: -/// -/// * exactly 1 to 8 digits in HEX format, -/// * only Latin A-F characters, case insensitive, -/// * and integer numbers 0,1,2,3,4,5,6,7,8,9, -/// * with optional hash (`#`) symbol at the beginning (not calculated in length). -/// -/// ```dart -/// final RegExp hexInputValidator = RegExp(kValidHexPattern); -/// if (hexInputValidator.hasMatch(hex)) print('$hex might be a valid HEX color'); -/// ``` -/// Reference: https://en.wikipedia.org/wiki/Web_colors#Hex_triplet -const String kValidHexPattern = r'^#?[0-9a-fA-F]{1,8}'; - -/// [RegExp] pattern for validation complete HEX color [String], allows only: -/// -/// * exactly 6 or 8 digits in HEX format, -/// * only Latin A-F characters, case insensitive, -/// * and integer numbers 0,1,2,3,4,5,6,7,8,9, -/// * with optional hash (`#`) symbol at the beginning (not calculated in length). -/// -/// ```dart -/// final RegExp hexCompleteValidator = RegExp(kCompleteValidHexPattern); -/// 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})$'; - -/// Try to convert text input or any [String] to valid [Color]. -/// The [String] must be provided in one of those formats: -/// -/// * RGB -/// * #RGB -/// * RRGGBB -/// * #RRGGBB -/// * AARRGGBB -/// * #AARRGGBB -/// -/// Where: A stands for Alpha, R for Red, G for Green, and B for blue color. -/// It will only accept 3/6/8 long HEXs with an optional hash (`#`) at the beginning. -/// Allowed characters are Latin A-F case insensitive and numbers 0-9. -/// Optional [enableAlpha] can be provided (it's `true` by default). If it's set -/// to `false` transparency information (alpha channel) will be removed. -/// ```dart -/// /// // Valid 3 digit HEXs: -/// colorFromHex('abc') == Color(0xffaabbcc) -/// colorFromHex('ABc') == Color(0xffaabbcc) -/// colorFromHex('ABC') == Color(0xffaabbcc) -/// colorFromHex('#Abc') == Color(0xffaabbcc) -/// colorFromHex('#abc') == Color(0xffaabbcc) -/// colorFromHex('#ABC') == Color(0xffaabbcc) -/// // Valid 6 digit HEXs: -/// colorFromHex('aabbcc') == Color(0xffaabbcc) -/// colorFromHex('AABbcc') == Color(0xffaabbcc) -/// colorFromHex('AABBCC') == Color(0xffaabbcc) -/// colorFromHex('#AABbcc') == Color(0xffaabbcc) -/// colorFromHex('#aabbcc') == Color(0xffaabbcc) -/// colorFromHex('#AABBCC') == Color(0xffaabbcc) -/// // Valid 8 digit HEXs: -/// colorFromHex('ffaabbcc') == Color(0xffaabbcc) -/// colorFromHex('ffAABbcc') == Color(0xffaabbcc) -/// colorFromHex('ffAABBCC') == Color(0xffaabbcc) -/// colorFromHex('ffaabbcc', enableAlpha: true) == Color(0xffaabbcc) -/// colorFromHex('FFAAbbcc', enableAlpha: true) == Color(0xffaabbcc) -/// colorFromHex('ffAABBCC', enableAlpha: true) == Color(0xffaabbcc) -/// colorFromHex('FFaabbcc', enableAlpha: true) == Color(0xffaabbcc) -/// colorFromHex('#ffaabbcc') == Color(0xffaabbcc) -/// colorFromHex('#ffAABbcc') == Color(0xffaabbcc) -/// colorFromHex('#FFAABBCC') == Color(0xffaabbcc) -/// colorFromHex('#ffaabbcc', enableAlpha: true) == Color(0xffaabbcc) -/// colorFromHex('#FFAAbbcc', enableAlpha: true) == Color(0xffaabbcc) -/// colorFromHex('#ffAABBCC', enableAlpha: true) == Color(0xffaabbcc) -/// colorFromHex('#FFaabbcc', enableAlpha: true) == Color(0xffaabbcc) -/// // Invalid HEXs: -/// colorFromHex('bc') == null // length 2 -/// colorFromHex('aabbc') == null // length 5 -/// colorFromHex('#ffaabbccd') == null // length 9 (+#) -/// colorFromHex('aabbcx') == null // x character -/// colorFromHex('#aabbвв') == null // в non-latin character -/// colorFromHex('') == null // empty -/// ``` -/// Reference: https://en.wikipedia.org/wiki/Web_colors#Hex_triplet -Color? colorFromHex(String inputString, {bool enableAlpha = true}) { - // Registers validator for exactly 6 or 8 digits long HEX (with optional #). - final RegExp hexValidator = RegExp(kCompleteValidHexPattern); - // Validating input, if it does not match — it's not proper HEX. - if (!hexValidator.hasMatch(inputString)) return null; - // Remove optional hash if exists and convert HEX to UPPER CASE. - String hexToParse = inputString.replaceFirst('#', '').toUpperCase(); - // It may allow HEXs with transparency information even if alpha is disabled, - if (!enableAlpha && hexToParse.length == 8) { - // but it will replace this info with 100% non-transparent value (FF). - hexToParse = 'FF${hexToParse.substring(2)}'; - } - // HEX may be provided in 3-digits format, let's just duplicate each letter. - if (hexToParse.length == 3) { - hexToParse = hexToParse.split('').expand((i) => [i * 2]).join(); - } - // We will need 8 digits to parse the color, let's add missing digits. - if (hexToParse.length == 6) hexToParse = 'FF$hexToParse'; - // HEX must be valid now, but as a precaution, it will just "try" to parse it. - final intColorValue = int.tryParse(hexToParse, radix: 16); - // If for some reason HEX is not valid — abort the operation, return nothing. - if (intColorValue == null) return null; - // Register output color for the last step. - final color = Color(intColorValue); - // Decide to return color with transparency information or not. - return enableAlpha ? color : color.withAlpha(255); -} - -/// Converts `dart:ui` [Color] to the 6/8 digits HEX [String]. -/// -/// Prefixes a hash (`#`) sign if [includeHashSign] is set to `true`. -/// The result will be provided as UPPER CASE, it can be changed via [toUpperCase] -/// flag set to `false` (default is `true`). Hex can be returned without alpha -/// channel information (transparency), with the [enableAlpha] flag set to `false`. -String colorToHex( - Color color, { - bool includeHashSign = false, - bool enableAlpha = true, - bool toUpperCase = true, -}) { - final String hex = (includeHashSign ? '#' : '') + - (enableAlpha ? _padRadix(color.alpha) : '') + - _padRadix(color.red) + - _padRadix(color.green) + - _padRadix(color.blue); - return toUpperCase ? hex.toUpperCase() : hex; -} - -// Shorthand for padLeft of RadixString, DRY. -String _padRadix(int value) => value.toRadixString(16).padLeft(2, '0'); - -// Extension for String -extension ColorExtension1 on String { - Color? toColor() { - Color? color = colorFromName(this); - if (color != null) return color; - return colorFromHex(this); - } -} - -// 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); -} diff --git a/lib/src/widgets/toolbar/buttons/color/color_dialog.dart b/lib/src/widgets/toolbar/buttons/color/color_dialog.dart index fc336932..e7d65800 100644 --- a/lib/src/widgets/toolbar/buttons/color/color_dialog.dart +++ b/lib/src/widgets/toolbar/buttons/color/color_dialog.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart' + show ColorPicker, MaterialPicker, colorToHex; import '../../../../../translations.dart'; import '../../../../models/documents/style.dart'; -import '../../../../packages/flutter_colorpicker/flutter_colorpicker.dart' - show ColorPicker, MaterialPicker, colorToHex; import 'color_button.dart' show hexToColor; enum _PickerType { diff --git a/pubspec.yaml b/pubspec.yaml index 6197a663..1e0b17da 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -51,8 +51,7 @@ dependencies: meta: ^1.10.0 html: ^0.15.4 - # TODO: temporarily disable from https://pub.dev/packages/flutter_colorpicker and clone it in the `lib/src/packages/flutter_colorpicker` as it's hasn't been published on pub.dev for a while - # flutter_colorpicker: ^1.0.3 + flutter_colorpicker: ^1.1.0 # For converting HTML to Quill delta markdown: ^7.2.1